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