]> git.sur5r.net Git - cc65/blob - libsrc/c64/c64-ram.s
Ignore only top level directories.
[cc65] / libsrc / c64 / c64-ram.s
1 ;
2 ; Extended memory driver for the C64 hidden RAM. Driver works without
3 ; problems when statically linked.
4 ;
5 ; Ullrich von Bassewitz, 2002-12-02
6 ;
7
8         .include        "zeropage.inc"
9
10         .include        "em-kernel.inc"
11         .include        "em-error.inc"
12
13
14         .macpack        generic
15
16
17 ; ------------------------------------------------------------------------
18 ; Header. Includes jump table
19
20 .segment        "JUMPTABLE"
21
22 ; Driver signature
23
24         .byte   $65, $6d, $64           ; "emd"
25         .byte   EMD_API_VERSION         ; EM API version number
26
27 ; Jump table.
28
29         .word   INSTALL
30         .word   UNINSTALL
31         .word   PAGECOUNT
32         .word   MAP
33         .word   USE
34         .word   COMMIT
35         .word   COPYFROM
36         .word   COPYTO
37
38 ; ------------------------------------------------------------------------
39 ; Constants
40
41 BASE    = $D000
42 PAGES   = ($10000 - BASE) / 256
43
44 ; ------------------------------------------------------------------------
45 ; Data.
46
47 .bss
48 curpage:        .res    1               ; Current page number
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         ldx     #$FF
62         stx     curpage                 ; Invalidate the current page
63         inx                             ; X = 0
64         txa                             ; A = X = EM_ERR_OK
65 ;       rts                             ; Run into UNINSTALL instead
66
67 ; ------------------------------------------------------------------------
68 ; UNINSTALL routine. Is called before the driver is removed from memory.
69 ; Can do cleanup or whatever. Must not return anything.
70 ;
71
72 UNINSTALL:
73         rts
74
75
76 ; ------------------------------------------------------------------------
77 ; PAGECOUNT: Return the total number of available pages in a/x.
78 ;
79
80 PAGECOUNT:
81         lda     #<PAGES
82         ldx     #>PAGES
83         rts
84
85 ; ------------------------------------------------------------------------
86 ; MAP: Map the page in a/x into memory and return a pointer to the page in
87 ; a/x. The contents of the currently mapped page (if any) may be discarded
88 ; by the driver.
89 ;
90
91 MAP:    sta     curpage                 ; Remember the new page
92
93         clc
94         adc     #>BASE
95         sta     ptr1+1
96         ldy     #$00
97         sty     ptr1
98
99         lda     #<window
100         sta     ptr2
101         lda     #>window
102         sta     ptr2+1
103
104 ; Transfer one page
105
106         jsr     transfer                ; Transfer one page
107
108 ; Return the memory window
109
110         lda     #<window
111         ldx     #>window                ; Return the window address
112         rts
113
114 ; ------------------------------------------------------------------------
115 ; USE: Tell the driver that the window is now associated with a given page.
116
117 USE:    sta     curpage                 ; Remember the page
118         lda     #<window
119         ldx     #>window                ; Return the window
120         rts
121
122 ; ------------------------------------------------------------------------
123 ; COMMIT: Commit changes in the memory window to extended storage.
124
125 COMMIT: lda     curpage                 ; Get the current page
126         bmi     done                    ; Jump if no page mapped
127
128         clc
129         adc     #>BASE
130         sta     ptr2+1
131         ldy     #$00
132         sty     ptr2
133
134         lda     #<window
135         sta     ptr1
136         lda     #>window
137         sta     ptr1+1
138
139 ; Transfer one page. Y must be zero on entry
140
141 transfer:
142         ldx     $01                     ; Remember c64 control port
143         txa
144         and     #$F8                    ; Bank out ROMs, I/O
145         sei
146         sta     $01
147
148 ; Unroll the following loop
149
150 loop:   .repeat 8
151         lda     (ptr1),y
152         sta     (ptr2),y
153         iny
154         .endrepeat
155
156         bne     loop
157
158 ; Restore the old memory configuration, allow interrupts
159
160         stx     $01                     ; Restore the old configuration
161         cli
162
163 ; Done
164
165 done:   rts               
166
167 ; ------------------------------------------------------------------------
168 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
169 ; describing the request is passed in a/x.
170 ; The function must not return anything.
171 ;
172
173 COPYFROM:
174         sta     ptr3
175         stx     ptr3+1                  ; Save the passed em_copy pointer
176                        
177         ldy     #EM_COPY::OFFS
178         lda     (ptr3),y
179         sta     ptr1
180         ldy     #EM_COPY::PAGE
181         lda     (ptr3),y
182         clc
183         adc     #>BASE
184         sta     ptr1+1                  ; From
185
186         ldy     #EM_COPY::BUF
187         lda     (ptr3),y
188         sta     ptr2
189         iny
190         lda     (ptr3),y
191         sta     ptr2+1                  ; To
192
193 common: ldy     #EM_COPY::COUNT+1
194         lda     (ptr3),y                ; Get number of pages
195         beq     @L2                     ; Skip if no full pages
196         sta     tmp1
197
198 ; Copy full pages allowing interrupts after each page copied
199
200         ldy     #$00
201 @L1:    jsr     transfer
202         inc     ptr1+1
203         inc     ptr2+1
204         dec     tmp1
205         bne     @L1
206
207 ; Copy the remainder of the page
208
209 @L2:    ldy     #EM_COPY::COUNT
210         lda     (ptr3),y                ; Get bytes in last page
211         beq     @L4
212         tax
213
214         lda     $01                     ; Remember c64 control port
215         pha
216         and     #$F8                    ; Bank out ROMs, I/O
217         sei
218         sta     $01
219
220 ; Transfer the bytes in the last page
221
222         ldy     #$00
223 @L3:    lda     (ptr1),y
224         sta     (ptr2),y
225         iny
226         dex
227         bne     @L3
228
229 ; Restore the old memory configuration, allow interrupts
230
231         pla
232         sta     $01                     ; Restore the old configuration
233         cli
234
235 ; Done
236
237 @L4:    rts
238
239 ; ------------------------------------------------------------------------
240 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
241 ; describing the request is passed in a/x.
242 ; The function must not return anything.
243 ;
244
245 COPYTO: sta     ptr3
246         stx     ptr3+1                  ; Save the passed em_copy pointer
247
248         ldy     #EM_COPY::OFFS
249         lda     (ptr3),y
250         sta     ptr2
251         ldy     #EM_COPY::PAGE
252         lda     (ptr3),y
253         clc
254         adc     #>BASE
255         sta     ptr2+1                  ; To
256
257         ldy     #EM_COPY::BUF
258         lda     (ptr3),y
259         sta     ptr1
260         iny
261         lda     (ptr3),y
262         sta     ptr1+1                  ; From
263
264         jmp     common
265
266