]> git.sur5r.net Git - cc65/blob - libsrc/c128/emd/c128-georam.s
Fixed _textcolor definition.
[cc65] / libsrc / c128 / emd / c128-georam.s
1 ;
2 ; Extended memory driver for the GEORAM cartridge. Driver works without
3 ; problems when statically linked.
4 ;
5 ; Ullrich von Bassewitz, 2002-11-29
6 ;
7 ; GEORAM page size checking routine by
8 ; Marco van den Heuvel, 2010-01-21
9 ;
10
11         .include        "zeropage.inc"
12
13         .include        "em-kernel.inc"
14         .include        "em-error.inc"
15
16         .macpack        generic
17         .macpack        module
18
19
20 ; ------------------------------------------------------------------------
21 ; Header. Includes jump table
22
23         module_header   _c128_georam_emd
24
25 ; Driver signature
26
27         .byte   $65, $6d, $64           ; "emd"
28         .byte   EMD_API_VERSION         ; EM API version number
29
30 ; Library reference
31
32         .addr   $0000
33
34 ; Jump table
35
36         .addr   INSTALL
37         .addr   UNINSTALL
38         .addr   PAGECOUNT
39         .addr   MAP
40         .addr   USE
41         .addr   COMMIT
42         .addr   COPYFROM
43         .addr   COPYTO
44
45 ; ------------------------------------------------------------------------
46 ; Constants
47
48 GR_WINDOW       = $DE00                 ; Address of GEORAM window
49 GR_PAGE_LO      = $DFFE                 ; Page register low
50 GR_PAGE_HI      = $DFFF                 ; Page register high
51
52 ; ------------------------------------------------------------------------
53 ; Data.
54
55 .data
56
57 pagecount:      .res    2               ; Number of available pages
58
59 .code
60
61 ; ------------------------------------------------------------------------
62 ; INSTALL routine. Is called after the driver is loaded into memory. If
63 ; possible, check if the hardware is present and determine the amount of
64 ; memory available.
65 ; Must return an EM_ERR_xx code in a/x.
66 ;
67
68 INSTALL:
69         ldx     GR_WINDOW
70         cpx     GR_WINDOW
71         bne     @notpresent
72         inc     GR_WINDOW
73         cpx     GR_WINDOW
74         beq     @notpresent
75
76         lda     #4
77         jsr     check
78         cpy     GR_WINDOW
79         beq     @has64k
80         lda     #8
81         jsr     check
82         cpy     GR_WINDOW
83         beq     @has128k
84         lda     #16
85         jsr     check
86         cpy     GR_WINDOW
87         beq     @has256k
88         lda     #32
89         jsr     check
90         cpy     GR_WINDOW
91         beq     @has512k
92         lda     #64
93         jsr     check
94         cpy     GR_WINDOW
95         beq     @has1024k
96         lda     #128
97         jsr     check
98         cpy     GR_WINDOW
99         beq     @has2048k
100         ldx     #>16384
101         bne     @setok
102
103 @has64k:
104         ldx     #>256
105         bne     @setok
106 @has128k:
107         ldx     #>512
108         bne     @setok
109 @has256k:
110         ldx     #>1024
111         bne     @setok
112 @has512k:
113         ldx     #>2048
114         bne     @setok
115 @has1024k:
116         ldx     #>4096
117         bne     @setok
118 @has2048k:
119         ldx     #>8192
120         bne     @setok
121
122 @notpresent:
123         lda     #<EM_ERR_NO_DEVICE
124         ldx     #>EM_ERR_NO_DEVICE
125         rts
126
127 @setok:
128         lda     #0
129         sta     pagecount
130         stx     pagecount+1
131         lda     #<EM_ERR_OK
132         ldx     #>EM_ERR_OK
133         rts
134
135 check:
136         ldx     #0
137         stx     GR_PAGE_LO
138         stx     GR_PAGE_HI
139         ldy     GR_WINDOW
140         iny
141         sta     GR_PAGE_HI
142         sty     GR_WINDOW
143         ldx     #0
144         stx     GR_PAGE_HI
145 ;       rts                     ; Run into UNINSTALL instead
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         rts
154
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 ; USE: Tell the driver that the window is now associated with a given page.
167 ; The GeoRAM cartridge does not copy but actually map the window, so USE is
168 ; identical to MAP.
169
170 USE     = MAP
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     tmp1
179         txa
180         asl     tmp1
181         rol     a
182         asl     tmp1
183         rol     a
184
185         sta     GR_PAGE_HI
186         lda     tmp1
187         lsr     a
188         lsr     a
189         sta     GR_PAGE_LO
190
191         lda     #<GR_WINDOW
192         ldx     #>GR_WINDOW
193
194 ; Use the RTS from COMMIT below to save a precious byte of storage
195
196 ; ------------------------------------------------------------------------
197 ; COMMIT: Commit changes in the memory window to extended storage.
198
199 COMMIT: rts
200
201 ; ------------------------------------------------------------------------
202 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
203 ; describing the request is passed in a/x.
204 ; The function must not return anything.
205 ;
206
207 COPYFROM:
208         jsr     setup
209
210 ; Setup is:
211 ;
212 ;   - ptr1 contains the struct pointer
213 ;   - ptr2 contains the linear memory buffer
214 ;   - ptr3 contains -(count-1)
215 ;   - tmp1 contains the low page register value
216 ;   - tmp2 contains the high page register value
217 ;   - X contains the page offset
218 ;   - Y contains zero
219
220         jmp     @L5
221
222 @L1:    lda     GR_WINDOW,x
223         sta     (ptr2),y
224         iny
225         bne     @L2
226         inc     ptr2+1
227 @L2:    inx
228         beq     @L4
229
230 ; Bump count and repeat
231
232 @L3:    inc     ptr3
233         bne     @L1
234         inc     ptr3+1
235         bne     @L1
236         rts
237
238 ; Bump page register
239
240 @L4:    inc     tmp1            ; Bump low page register
241         bit     tmp1            ; Check for overflow in bit 6
242         bvc     @L6             ; Jump if no overflow
243         inc     tmp2
244 @L5:    lda     tmp2
245         sta     GR_PAGE_HI
246 @L6:    lda     tmp1
247         sta     GR_PAGE_LO
248         jmp     @L3
249
250 ; ------------------------------------------------------------------------
251 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
252 ; describing the request is passed in a/x.
253 ; The function must not return anything.
254 ;
255
256 COPYTO:
257         jsr     setup
258
259 ; Setup is:
260 ;
261 ;   - ptr1 contains the struct pointer
262 ;   - ptr2 contains the linear memory buffer
263 ;   - ptr3 contains -(count-1)
264 ;   - tmp1 contains the low page register value
265 ;   - tmp2 contains the high page register value
266 ;   - X contains the page offset
267 ;   - Y contains zero
268
269         jmp     @L5
270
271 @L1:    lda     (ptr2),y
272         sta     GR_WINDOW,x
273         iny
274         bne     @L2
275         inc     ptr2+1
276 @L2:    inx
277         beq     @L4
278
279 ; Bump count and repeat
280
281 @L3:    inc     ptr3
282         bne     @L1
283         inc     ptr3+1
284         bne     @L1
285         rts
286
287 ; Bump page register
288
289 @L4:    inc     tmp1            ; Bump low page register
290         bit     tmp1            ; Check for overflow in bit 6
291         bvc     @L6             ; Jump if no overflow
292         inc     tmp2
293 @L5:    lda     tmp2
294         sta     GR_PAGE_HI
295 @L6:    lda     tmp1
296         sta     GR_PAGE_LO
297         jmp     @L3
298
299 ; ------------------------------------------------------------------------
300 ; Helper function for COPYFROM and COPYTO: Store the pointer to the request
301 ; structure and prepare data for the copy
302
303 setup:  sta     ptr1
304         stx     ptr1+1          ; Save passed pointer
305
306 ; Get the page number from the struct and adjust it so that it may be used
307 ; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
308
309         ldy     #EM_COPY::PAGE+1
310         lda     (ptr1),y
311         sta     tmp2
312         dey
313         lda     (ptr1),y
314         asl     a
315         rol     tmp2
316         asl     a
317         rol     tmp2
318         lsr     a
319         lsr     a
320         sta     tmp1
321
322 ; Get the buffer pointer into ptr2
323
324         ldy     #EM_COPY::BUF
325         lda     (ptr1),y
326         sta     ptr2
327         iny
328         lda     (ptr1),y
329         sta     ptr2+1
330
331 ; Get the count, calculate -(count-1) and store it into ptr3
332
333         ldy     #EM_COPY::COUNT
334         lda     (ptr1),y
335         eor     #$FF
336         sta     ptr3
337         iny
338         lda     (ptr1),y
339         eor     #$FF
340         sta     ptr3+1
341
342 ; Get the page offset into X and clear Y
343
344         ldy     #EM_COPY::OFFS
345         lda     (ptr1),y
346         tax
347         ldy     #$00
348
349 ; Done
350
351         rts
352
353