]> git.sur5r.net Git - cc65/blob - libsrc/geos-cbm/drivers/geos-vdc.s
Ignore only top level directories.
[cc65] / libsrc / geos-cbm / drivers / 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             .include "em-kernel.inc"
10             .include "em-error.inc"
11
12             .macpack generic
13
14 ; ------------------------------------------------------------------------
15 ; Header. Includes jump table
16
17 .segment        "JUMPTABLE"
18
19 ; Driver signature
20
21         .byte $65, $6d, $64     ; "emd"
22         .byte EMD_API_VERSION   ; EM API version number
23
24 ; Jump table.
25
26         .word INSTALL
27         .word UNINSTALL
28         .word PAGECOUNT
29         .word MAP
30         .word USE
31         .word COMMIT
32         .word COPYFROM
33         .word COPYTO
34
35 ; ------------------------------------------------------------------------
36 ; Constants
37
38 VDC_ADDR_REG    = $D600         ; VDC address
39 VDC_DATA_REG    = $D601         ; VDC data
40
41 VDC_DATA_HI     = 18            ; used registers
42 VDC_DATA_LO     = 19
43 VDC_CSET        = 28
44 VDC_DATA        = 31
45
46 ; ------------------------------------------------------------------------
47 ; Data.
48
49 .data
50
51 pagecount:
52         .word 64                ; $0000-$3fff as 16k default
53 curpage:
54         .word $ffff             ; currently mapped-in page (invalid)
55
56 .bss
57
58 window:
59         .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