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