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