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