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