]> git.sur5r.net Git - cc65/blob - libsrc/c64/c64-ram.s
Added C64 RAM driver, fixed bug in REU driver
[cc65] / libsrc / c64 / c64-ram.s
1 ;
2 ; Extended memory driver for the C64 hidden RAM
3 ;
4 ; Ullrich von Bassewitz, 2002-12-02
5 ;
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   $00                     ; EM API version number
25
26 ; Jump table.
27
28         .word   INSTALL
29         .word   DEINSTALL
30         .word   PAGECOUNT
31         .word   MAP
32         .word   COMMIT
33         .word   COPYFROM
34         .word   COPYTO
35
36 ; ------------------------------------------------------------------------
37 ; Constants
38
39 BASE    = $D000
40 PAGES   = ($10000 - BASE) / 256
41
42 ; ------------------------------------------------------------------------
43 ; Data.
44
45 .data
46 curpage:        .byte   $FF             ; Current page number (invalid)
47
48 .bss
49 window:         .res    256             ; Memory "window"
50
51 .code
52
53 ; ------------------------------------------------------------------------
54 ; INSTALL routine. Is called after the driver is loaded into memory. If
55 ; possible, check if the hardware is present and determine the amount of
56 ; memory available.
57 ; Must return an EM_ERR_xx code in a/x.
58 ;
59
60 INSTALL:
61         lda     #<EM_ERR_OK
62         ldx     #>EM_ERR_OK
63         rts
64
65 ; ------------------------------------------------------------------------
66 ; DEINSTALL routine. Is called before the driver is removed from memory.
67 ; Can do cleanup or whatever. Must not return anything.
68 ;
69
70 DEINSTALL:
71         rts
72
73
74 ; ------------------------------------------------------------------------
75 ; PAGECOUNT: Return the total number of available pages in a/x.
76 ;
77
78 PAGECOUNT:
79         lda     #<PAGES
80         ldx     #>PAGES
81         rts
82
83 ; ------------------------------------------------------------------------
84 ; MAP: Map the page in a/x into memory and return a pointer to the page in
85 ; a/x. The contents of the currently mapped page (if any) may be discarded
86 ; by the driver.
87 ;
88
89 MAP:    sta     curpage                 ; Remember the new page
90
91         clc
92         adc     #>BASE
93         sta     ptr1+1
94         ldy     #$00
95         sty     ptr1
96
97         lda     #<window
98         sta     ptr2
99         lda     #>window
100         sta     ptr2+1
101
102 ; Transfer one page
103
104         jsr     transfer                ; Transfer one page
105
106 ; Return the memory window
107
108         lda     #<window
109         ldx     #>window                ; Return the window address
110         rts
111
112 ; ------------------------------------------------------------------------
113 ; COMMIT: Commit changes in the memory window to extended storage.
114
115 COMMIT: lda     curpage                 ; Get the current page
116         bmi     done                    ; Jump if no page mapped
117
118         clc
119         adc     #>BASE
120         sta     ptr2+1
121         ldy     #$00
122         sty     ptr2
123
124         lda     #<window
125         sta     ptr1
126         lda     #>window
127         sta     ptr1+1
128
129 ; Transfer one page. Y must be zero on entry
130
131 transfer:
132         ldx     $01                     ; Remember c64 control port
133         txa
134         and     #$F8                    ; Bank out ROMs, I/O
135         sei
136         sta     $01
137
138 ; Unroll the following loop
139
140 loop:   lda     (ptr1),y
141         sta     (ptr2),y
142         iny
143
144         lda     (ptr1),y
145         sta     (ptr2),y
146         iny
147
148         lda     (ptr1),y
149         sta     (ptr2),y
150         iny
151
152         lda     (ptr1),y
153         sta     (ptr2),y
154         iny
155
156         lda     (ptr1),y
157         sta     (ptr2),y
158         iny
159
160         lda     (ptr1),y
161         sta     (ptr2),y
162         iny
163
164         lda     (ptr1),y
165         sta     (ptr2),y
166         iny
167
168         lda     (ptr1),y
169         sta     (ptr2),y
170         iny
171
172         bne     loop
173
174 ; Restore the old memory configuration, allow interrupts
175
176         stx     $01                     ; Restore the old configuration
177         cli
178
179 ; Done
180
181 done:   rts
182
183 ; ------------------------------------------------------------------------
184 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
185 ; describing the request is passed in a/x.
186 ; The function must not return anything.
187 ;
188
189 COPYFROM:
190         sta     ptr3
191         stx     ptr3+1                  ; Save the passed em_copy pointer
192
193         ldy     #EM_COPY_OFFS
194         lda     (ptr3),y
195         sta     ptr1
196         ldy     #EM_COPY_PAGE
197         lda     (ptr3),y
198         clc
199         adc     #>BASE
200         sta     ptr1+1                  ; From
201
202         ldy     #EM_COPY_BUF
203         lda     (ptr3),y
204         sta     ptr2
205         iny
206         lda     (ptr3),y
207         sta     ptr2+1                  ; To
208
209 common: ldy     #EM_COPY_COUNT+1
210         lda     (ptr3),y                ; Get number of pages
211         beq     @L2                     ; Skip if no full pages
212         sta     tmp1
213
214 ; Copy full pages allowing interrupts after each page copied
215
216         ldy     #$00
217 @L1:    jsr     transfer
218         inc     ptr1+1
219         inc     ptr2+1
220         dec     tmp1
221         bne     @L1
222
223 ; Copy the remainder of the page
224
225 @L2:    ldy     #EM_COPY_COUNT
226         lda     (ptr3),y                ; Get bytes in last page
227         beq     @L4
228         tax
229
230         lda     $01                     ; Remember c64 control port
231         pha
232         and     #$F8                    ; Bank out ROMs, I/O
233         sei
234         sta     $01
235
236 ; Transfer the bytes in the last page
237
238 @L3:    lda     (ptr1),y
239         sta     (ptr2),y
240         iny
241         dex
242         bne     @L3
243
244 ; Restore the old memory configuration, allow interrupts
245
246         pla
247         sta     $01                     ; Restore the old configuration
248         cli
249
250 ; Done
251
252 @L4:    rts          
253
254 ; ------------------------------------------------------------------------
255 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
256 ; describing the request is passed in a/x.
257 ; The function must not return anything.
258 ;
259
260 COPYTO: sta     ptr3
261         stx     ptr3+1                  ; Save the passed em_copy pointer
262
263         ldy     #EM_COPY_OFFS
264         lda     (ptr3),y
265         sta     ptr2
266         ldy     #EM_COPY_PAGE
267         lda     (ptr3),y
268         clc
269         adc     #>BASE
270         sta     ptr2+1                  ; To
271
272         ldy     #EM_COPY_BUF
273         lda     (ptr3),y
274         sta     ptr1
275         iny
276         lda     (ptr3),y
277         sta     ptr1+1                  ; From
278
279         jmp     common
280
281