]> git.sur5r.net Git - cc65/blob - libsrc/c128/emd/c128-ram2.s
Create static drivers directly from source files.
[cc65] / libsrc / c128 / emd / c128-ram2.s
1 ;
2 ; Extended memory driver for the C128 RAM in banks #1, #2 and #3. Driver works without
3 ; problems when statically linked.
4 ;
5 ; Ullrich von Bassewitz, 2002-12-04
6 ;
7 ; Updated to use banks 2 and 3 as well 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         .include        "c128.inc"
16
17         .macpack        generic
18         .macpack        module
19
20
21 ; ------------------------------------------------------------------------
22 ; Header. Includes jump table
23
24         module_header   _c128_ram2_emd
25
26 ; Driver signature
27
28         .byte   $65, $6d, $64           ; "emd"
29         .byte   EMD_API_VERSION         ; EM API version number
30
31 ; Library reference
32
33         .addr   $0000
34
35 ; Jump table
36
37         .addr   INSTALL
38         .addr   UNINSTALL
39         .addr   PAGECOUNT
40         .addr   MAP
41         .addr   USE
42         .addr   COMMIT
43         .addr   COPYFROM
44         .addr   COPYTO
45
46 ; ------------------------------------------------------------------------
47 ; Constants
48
49 BASE    = $400
50
51 ; ------------------------------------------------------------------------
52 ; Data.
53
54 .bss
55 curpage:        .res    2               ; Current page number
56 curbank:        .res    1               ; Current bank number
57 copybank:       .res    2               ; temp bank number
58
59 window:         .res    256             ; Memory "window"
60
61 pagecount:      .res    2               ; Number of available pages
62
63 .code
64
65 ; ------------------------------------------------------------------------
66 ; INSTALL routine. Is called after the driver is loaded into memory. If
67 ; possible, check if the hardware is present and determine the amount of
68 ; memory available.
69 ; Must return an EM_ERR_xx code in a/x.
70 ;
71
72 INSTALL:
73         ldx     #0
74         stx     ptr1
75         ldx     #4
76         stx     ptr1+1
77         ldx     #<ptr1
78         stx     FETVEC
79         stx     STAVEC
80         ldy     #0
81         ldx     #MMU_CFG_RAM1
82         jsr     FETCH
83         sta     tmp1
84         ldx     #MMU_CFG_RAM3
85         jsr     FETCH
86         cmp     tmp1
87         bne     @has_4_banks
88         tax
89         inx
90         txa
91         ldx     #MMU_CFG_RAM1
92         jsr     STASH
93         ldx     #MMU_CFG_RAM3
94         jsr     FETCH
95         cmp     tmp1
96         beq     @has_4_banks
97         ldx     #0
98         lda     #251
99         bne     @setok
100
101 @has_4_banks:
102         ldx     #2
103         lda     #241
104 @setok:
105         sta     pagecount
106         stx     pagecount+1
107         ldx     #$FF
108         stx     curpage
109         stx     curpage+1       ; Invalidate the current page
110         inx
111         txa                     ; A = X = EM_ERR_OK
112 ;       rts                     ; Run into UNINSTALL instead
113
114 ; ------------------------------------------------------------------------
115 ; UNINSTALL routine. Is called before the driver is removed from memory.
116 ; Can do cleanup or whatever. Must not return anything.
117 ;
118
119 UNINSTALL:
120         rts
121
122
123 ; ------------------------------------------------------------------------
124 ; PAGECOUNT: Return the total number of available pages in a/x.
125 ;
126
127 PAGECOUNT:
128         lda     pagecount
129         ldx     pagecount+1
130         rts
131
132 ; ------------------------------------------------------------------------
133 ; MAP: Map the page in a/x into memory and return a pointer to the page in
134 ; a/x. The contents of the currently mapped page (if any) may be discarded
135 ; by the driver.
136 ;
137
138 MAP:    sei
139         sta     curpage
140         stx     curpage+1               ; Remember the new page
141
142         jsr     calculate_bank_and_correct_page
143         stx     curbank
144
145         clc
146         adc     #>BASE
147         sta     ptr1+1
148         ldy     #$00
149         sty     ptr1
150         lda     #<ptr1
151         sta     FETVEC
152
153 ; Transfer one page
154
155 @L1:    ldx     curbank
156         jsr     getcurbankmmu
157         jsr     FETCH
158         sta     window,y
159         iny
160         bne     @L1
161
162 ; Return the memory window
163
164         lda     #<window
165         ldx     #>window                ; Return the window address
166         cli
167         rts
168
169 ; ------------------------------------------------------------------------
170 ; USE: Tell the driver that the window is now associated with a given page.
171
172 USE:    sta     curpage
173         stx     curpage+1               ; Remember the page
174         lda     #<window
175         ldx     #>window                ; Return the window
176         rts
177
178 ; ------------------------------------------------------------------------
179 ; COMMIT: Commit changes in the memory window to extended storage.
180
181 COMMIT: sei
182         lda     curpage                 ; Get the current page
183         ldx     curpage+1
184         bmi     done                    ; Jump if no page mapped
185
186         jsr     calculate_bank_and_correct_page
187         stx     curbank
188
189         clc
190         adc     #>BASE
191         sta     ptr1+1
192         ldy     #$00
193         sty     ptr1
194
195         lda     #<ptr1
196         sta     STAVEC
197
198 ; Transfer one page. Y must be zero on entry
199
200 @L1:    lda     window,y
201         ldx     curbank
202         jsr     getcurbankmmu
203         jsr     STASH
204         iny
205         bne     @L1
206         cli
207
208 ; Done
209
210 done:   rts
211
212 ; ------------------------------------------------------------------------
213 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
214 ; describing the request is passed in a/x.
215 ; The function must not return anything.
216 ;
217
218 COPYFROM:
219         sei
220         jsr     setup
221
222 ; Setup is:
223 ;
224 ;   - ptr1 contains the struct pointer
225 ;   - ptr2 contains the linear memory buffer
226 ;   - ptr3 contains -(count-1)
227 ;   - ptr4 contains the page buffer and offset
228 ;   - tmp1 contains the bank
229 ;   - tmp2 contains zero (used for linear memory buffer offset)
230
231         lda     #<ptr4
232         sta     FETVEC
233         jmp     @L3
234
235 @L1:    ldx     tmp1
236         jsr     getcurbankmmu
237         ldy     #0
238         jsr     FETCH
239         ldy     tmp2
240         sta     (ptr2),y
241         inc     tmp2
242         bne     @L2
243         inc     ptr2+1
244 @L2:    inc     ptr4
245         beq     @L4
246
247 ; Bump count and repeat
248
249 @L3:    inc     ptr3
250         bne     @L1
251         inc     ptr3+1
252         bne     @L1
253         cli
254         rts
255
256 ; Bump page register
257
258 @L4:    inc     ptr4+1
259         lda     ptr4+1
260         cmp     #$ff
261         bne     @L3
262         lda     #4
263         sta     ptr4+1
264         inc     tmp1
265 @L5:
266         jmp     @L3
267
268
269 ; ------------------------------------------------------------------------
270 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
271 ; describing the request is passed in a/x.
272 ; The function must not return anything.
273 ;
274
275 COPYTO:
276         sei
277         jsr     setup
278
279 ; Setup is:
280 ;
281 ;   - ptr1 contains the struct pointer
282 ;   - ptr2 contains the linear memory buffer
283 ;   - ptr3 contains -(count-1)
284 ;   - ptr4 contains the page buffer and offset
285 ;   - tmp1 contains the bank
286 ;   - tmp2 contains zero (used for linear memory buffer offset)
287
288         lda     #<ptr4
289         sta     STAVEC
290         jmp     @L3
291
292 @L1:
293         ldy     tmp2
294         lda     (ptr2),y
295         ldx     tmp1
296         jsr     getcurbankmmu
297         ldy     #0
298         jsr     STASH
299         inc     tmp2
300         bne     @L2
301         inc     ptr2+1
302 @L2:    inc     ptr4
303         beq     @L4
304
305 ; Bump count and repeat
306
307 @L3:    inc     ptr3
308         bne     @L1
309         inc     ptr3+1
310         bne     @L1
311         cli
312         rts
313
314 ; Bump page register
315
316 @L4:    inc     ptr4+1
317         lda     ptr4+1
318         cmp     #$ff
319         bne     @L3
320         inc     tmp1
321         lda     #4
322         sta     ptr4+1
323 @L5:
324         jmp     @L3
325
326 ; ------------------------------------------------------------------------
327 ; Helper function to calculate the correct bank and page
328 ; when addressing bank 2 or 3
329
330 calculate_bank_and_correct_page:
331         cpx     #2
332         beq     @calculate_bank_3_with_2
333         cpx     #1
334         beq     @calculate_bank_2_or_3_with_1
335         sec
336         sbc     #251
337         bcs     @calculate_bank_2_with_0
338         ldx     #1
339         lda     curpage
340         rts
341
342 @calculate_bank_3_with_2:
343         lda     curpage
344         clc
345         adc     #10
346 @calculate_bank_3_with_1:
347         ldx     #3
348         rts
349
350 @calculate_bank_2_or_3_with_1:
351         sec
352         sbc     #246
353         bcs     @calculate_bank_3_with_1
354         lda     curpage
355         clc
356         adc     #5
357 @calculate_bank_2_with_0:
358         ldx     #2
359         rts
360
361 ; ------------------------------------------------------------------------
362 ; Helper function to get the correct mmu value in x
363
364 getcurbankmmu:
365         cpx     #1
366         beq     @bank1
367         cpx     #2
368         beq     @bank2
369         ldx     #MMU_CFG_RAM3
370         rts
371 @bank2:
372         ldx     #MMU_CFG_RAM2
373         rts
374 @bank1:
375         ldx     #MMU_CFG_RAM1
376         rts
377
378 ; ------------------------------------------------------------------------
379 ; Helper function for COPYFROM and COPYTO: Store the pointer to the request
380 ; structure and prepare data for the copy
381
382 setup:  sta     ptr1
383         stx     ptr1+1          ; Save passed pointer
384
385 ; Get the page number from the struct and adjust it so that it may be used
386 ; with the hardware. That is: page pointer in ptr4 and bank in tmp1
387
388         ldy     #EM_COPY::PAGE+1
389         lda     (ptr1),y
390         tax
391         dey
392         lda     (ptr1),y
393         sta     curpage
394         jsr     calculate_bank_and_correct_page
395         clc
396         adc     #4
397         sta     ptr4+1
398         stx     tmp1
399
400 ; Get the buffer pointer into ptr2
401
402         ldy     #EM_COPY::BUF
403         lda     (ptr1),y
404         sta     ptr2
405         iny
406         lda     (ptr1),y
407         sta     ptr2+1
408
409 ; Get the count, calculate -(count-1) and store it into ptr3
410
411         ldy     #EM_COPY::COUNT
412         lda     (ptr1),y
413         eor     #$FF
414         sta     ptr3
415         iny
416         lda     (ptr1),y
417         eor     #$FF
418         sta     ptr3+1
419
420 ; Get the page offset into the low byte of ptr4 clear tmp2
421
422         ldy     #EM_COPY::OFFS
423         lda     (ptr1),y
424         sta     ptr4
425         lda     #0
426         sta     tmp2
427
428 ; Done
429
430         rts