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