]> git.sur5r.net Git - cc65/blob - libsrc/geos-cbm/devel/geos-vdc.s
'setoserror' is used by routines residing both 'disk' and 'file'. Therefore move...
[cc65] / libsrc / geos-cbm / devel / geos-vdc.s
1 ;
2 ; Extended memory driver for the VDC RAM available on all C128 machines
3 ; version for GEOS enters safe I/O config on C64 (transparent on C128)
4 ;
5 ; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
6 ; 06,20,25.12.2002
7
8         .include        "zeropage.inc"
9
10         .include        "em-kernel.inc"
11         .include        "em-error.inc"
12
13
14         .macpack        generic
15
16
17 ; ------------------------------------------------------------------------
18 ; Header. Includes jump table
19
20 .segment        "JUMPTABLE"
21
22 ; Driver signature
23
24         .byte   $65, $6d, $64           ; "emd"
25         .byte   EMD_API_VERSION         ; EM API version number
26
27 ; Jump table.
28
29         .word   INSTALL
30         .word   UNINSTALL
31         .word   PAGECOUNT
32         .word   MAP
33         .word   USE
34         .word   COMMIT
35         .word   COPYFROM
36         .word   COPYTO
37
38 ; ------------------------------------------------------------------------
39 ; Constants
40
41 VDC_ADDR_REG      = $D600                 ; VDC address
42 VDC_DATA_REG      = $D601                 ; VDC data
43
44 VDC_DATA_HI       = 18                    ; used registers
45 VDC_DATA_LO       = 19
46 VDC_CSET          = 28
47 VDC_DATA          = 31
48
49 ; ------------------------------------------------------------------------
50 ; Data.
51
52 .data
53
54 pagecount:      .word  64                  ; $0000-$3fff as 16k default
55 curpage:        .word  $ffff               ; currently mapped-in page (invalid)
56
57 .bss
58
59 window:         .res    256                ; memory window
60
61 .code
62
63 ; ------------------------------------------------------------------------
64 ; INSTALL routine. Is called after the driver is loaded into memory. If
65 ; possible, check if the hardware is present and determine the amount of
66 ; memory available.
67 ; Must return an EM_ERR_xx code in a/x.
68 ;
69
70 INSTALL:
71         ; do test for VDC presence here???
72
73         php
74         sei
75         lda     $01
76         pha
77         lda     #$35
78         sta     $01
79
80         ldx     #VDC_CSET       ; determine size of RAM...
81         jsr     vdcgetreg
82         sta     tmp1
83         ora     #%00010000
84         jsr     vdcputreg       ; turn on 64k
85
86         jsr     settestadr1     ; save original value of test byte
87         jsr     vdcgetbyte
88         sta     tmp2
89
90         lda     #$55            ; write $55 here
91         ldy     #ptr1
92         jsr     test64k         ; read it here and there
93         lda     #$aa            ; write $aa here
94         ldy     #ptr2
95         jsr     test64k         ; read it here and there
96
97         jsr     settestadr1
98         lda     tmp2
99         jsr     vdcputbyte      ; restore original value of test byte
100
101         lda     ptr1            ; do bytes match?
102         cmp     ptr1+1
103         bne     @have64k
104         lda     ptr2
105         cmp     ptr2+1
106         bne     @have64k
107
108         ldx     #VDC_CSET
109         lda     tmp1
110         jsr     vdcputreg       ; restore 16/64k flag
111         jmp     @endok          ; and leave default values for 16k
112
113 @have64k:
114         lda     #<256
115         ldx     #>256
116         sta     pagecount
117         stx     pagecount+1
118 @endok:
119         pla
120         sta     $01
121         plp
122         lda     #<EM_ERR_OK
123         ldx     #>EM_ERR_OK
124         rts
125
126 test64k:
127         sta     tmp1
128         sty     ptr3
129         lda     #0
130         sta     ptr3+1
131         jsr     settestadr1
132         lda     tmp1
133         jsr     vdcputbyte              ; write $55
134         jsr     settestadr1
135         jsr     vdcgetbyte              ; read here
136         pha
137         jsr     settestadr2
138         jsr     vdcgetbyte              ; and there
139         ldy     #1
140         sta     (ptr3),y
141         pla
142         dey
143         sta     (ptr3),y
144         rts
145
146 settestadr1:
147         ldy     #$02                    ; test page 2 (here)
148         .byte   $2c
149 settestadr2:
150         ldy     #$42                    ; or page 64+2 (there)
151         lda     #0
152         jmp     vdcsetsrcaddr
153
154 ; ------------------------------------------------------------------------
155 ; UNINSTALL routine. Is called before the driver is removed from memory.
156 ; Can do cleanup or whatever. Must not return anything.
157 ;
158
159 UNINSTALL:
160         ;on C128 restore font and clear the screen?
161         rts
162
163 ; ------------------------------------------------------------------------
164 ; PAGECOUNT: Return the total number of available pages in a/x.
165 ;
166
167 PAGECOUNT:
168         lda     pagecount
169         ldx     pagecount+1
170         rts
171
172 ; ------------------------------------------------------------------------
173 ; MAP: Map the page in a/x into memory and return a pointer to the page in
174 ; a/x. The contents of the currently mapped page (if any) may be discarded
175 ; by the driver.
176 ;
177
178 MAP:    sta     curpage
179         stx     curpage+1
180         sta     ptr1+1
181         ldy     #0
182         sty     ptr1
183
184         lda     #<window
185         sta     ptr2
186         lda     #>window
187         sta     ptr2+1
188
189         jsr     transferin
190
191         lda     #<window
192         ldx     #>window
193         rts
194
195 ; copy a single page from (ptr1):VDCRAM to (ptr2):RAM
196
197 transferin:
198         php
199         sei
200         lda     $01
201         pha
202         lda     #$35
203         sta     $01
204         lda     ptr1
205         ldy     ptr1+1
206         jsr     vdcsetsrcaddr           ; set source address in VDC
207         ldy     #0
208         ldx     #VDC_DATA
209         stx     VDC_ADDR_REG
210 @L0:    bit     VDC_ADDR_REG
211         bpl     @L0
212         lda     VDC_DATA_REG            ; get 2 bytes at a time to speed-up
213         sta     (ptr2),y                ; (in fact up to 8 bytes could be fetched with special VDC config)
214         iny
215         lda     VDC_DATA_REG
216         sta     (ptr2),y
217         iny
218         bne     @L0
219         pla
220         sta     $01
221         plp
222         rts
223
224 ; ------------------------------------------------------------------------
225 ; USE: Tell the driver that the window is now associated with a given page.
226
227 USE:    sta     curpage
228         stx     curpage+1               ; Remember the page
229         lda     #<window
230         ldx     #>window                ; Return the window
231 done:   rts
232
233 ; ------------------------------------------------------------------------
234 ; COMMIT: Commit changes in the memory window to extended storage.
235
236 COMMIT:
237         lda     curpage                 ; jump if no page mapped
238         ldx     curpage+1
239         bmi     done
240         sta     ptr1+1
241         ldy     #0
242         sty     ptr1
243
244         lda     #<window
245         sta     ptr2
246         lda     #>window
247         sta     ptr2+1
248
249 ; fall through to transferout
250
251 ; copy a single page from (ptr2):RAM to (ptr1):VDCRAM
252
253 transferout:
254         php
255         sei
256         lda     $01
257         pha
258         lda     #$35
259         sta     $01
260         lda     ptr1
261         ldy     ptr1+1
262         jsr     vdcsetsrcaddr           ; set source address in VDC
263         ldy     #0
264         ldx     #VDC_DATA
265         stx     VDC_ADDR_REG
266 @L0:    bit     VDC_ADDR_REG
267         bpl     @L0
268         lda     (ptr2),y                ; speedup does not work for writing
269         sta     VDC_DATA_REG
270         iny
271         bne     @L0
272         pla
273         sta     $01
274         plp
275         rts
276
277 ; ------------------------------------------------------------------------
278 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
279 ; describing the request is passed in a/x.
280 ; The function must not return anything.
281 ;
282
283 COPYFROM:
284         jsr     setup
285         beq     @L2                     ; Skip if no full pages
286
287 ; Copy full pages
288
289 @L1:    jsr     transferin
290         inc     ptr1+1
291         inc     ptr2+1
292         dec     tmp1
293         bne     @L1
294
295 ; Copy the remainder of the page
296                  
297 @L2:    ldy     #EM_COPY::COUNT
298         lda     (ptr3),y                ; Get bytes in last page
299         beq     @L4
300         sta     tmp1
301
302 ; Transfer the bytes in the last page
303         php
304         sei
305         lda     $01
306         pha
307         lda     #$35
308         sta     $01
309         ldy     #0
310 @L3:    jsr     vdcgetbyte
311         sta     (ptr2),y
312         iny
313         dec     tmp1
314         lda     tmp1
315         bne     @L3
316         pla
317         sta     $01
318         plp
319 @L4:    rts
320
321 ; ------------------------------------------------------------------------
322 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
323 ; describing the request is passed in a/x.
324 ; The function must not return anything.
325 ;
326
327 COPYTO:
328         jsr     setup
329         beq     @L2                     ; Skip if no full pages
330
331 ; Copy full pages
332
333 @L1:    jsr     transferout
334         inc     ptr1+1
335         inc     ptr2+1
336         dec     tmp1
337         bne     @L1
338
339 ; Copy the remainder of the page
340
341 @L2:    ldy     #EM_COPY::COUNT
342         lda     (ptr3),y                ; Get bytes in last page
343         beq     @L4
344         sta     tmp1
345
346 ; Transfer the bytes in the last page
347         php
348         sei
349         lda     $01
350         pha
351         lda     #$35
352         sta     $01
353         ldy     #0
354 @L3:    lda     (ptr2),y
355         jsr     vdcputbyte
356         iny
357         dec     tmp1
358         lda     tmp1
359         bne     @L3
360         pla
361         sta     $01
362         plp
363 @L4:    rts
364
365 ;-------------------------------------------------------------------------
366 ; Helper functions to handle VDC ram
367 ;
368
369 vdcsetsrcaddr:
370         ldx     #VDC_DATA_LO
371         stx     VDC_ADDR_REG
372 @L0:    bit     VDC_ADDR_REG
373         bpl     @L0
374         sta     VDC_DATA_REG
375         dex
376         tya
377         stx     VDC_ADDR_REG
378         sta     VDC_DATA_REG
379         rts
380
381 vdcgetbyte:
382         ldx     #VDC_DATA
383 vdcgetreg:
384         stx     VDC_ADDR_REG
385 @L0:    bit     VDC_ADDR_REG
386         bpl     @L0
387         lda     VDC_DATA_REG
388         rts
389
390 vdcputbyte:
391         ldx     #VDC_DATA
392 vdcputreg:
393         stx     VDC_ADDR_REG
394 @L0:    bit     VDC_ADDR_REG
395         bpl     @L0
396         sta     VDC_DATA_REG
397         rts
398
399 ; ------------------------------------------------------------------------
400 ; Helper function for COPYFROM and COPYTO: Store the pointer to the request
401 ; structure and prepare data for the copy
402 ;
403
404 setup:
405         sta     ptr3
406         stx     ptr3+1                  ; Save the passed em_copy pointer
407
408         ldy     #EM_COPY::OFFS
409         lda     (ptr3),y
410         sta     ptr1
411         ldy     #EM_COPY::PAGE
412         lda     (ptr3),y
413         sta     ptr1+1                  ; From
414
415         ldy     #EM_COPY::BUF
416         lda     (ptr3),y
417         sta     ptr2
418         iny
419         lda     (ptr3),y
420         sta     ptr2+1                  ; To
421
422         ldy     #EM_COPY::COUNT+1
423         lda     (ptr3),y                ; Get number of pages
424         sta     tmp1      
425         rts
426