]> git.sur5r.net Git - cc65/blob - libsrc/c64/c64-ramcart.s
Use the .max function to calculate the backup space.
[cc65] / libsrc / c64 / c64-ramcart.s
1 ;
2 ; Extended memory driver for the RamCart 64/128KB cartridge. Driver works
3 ; without problems when statically linked.
4 ; Code is based on GEORAM code by Ullrich von Bassewitz.
5 ; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
6 ; 06,22.12.2002
7 ;
8
9
10         .include        "zeropage.inc"
11
12         .include        "em-kernel.inc"
13         .include        "em-error.inc"
14
15
16         .macpack        generic
17
18
19 ; ------------------------------------------------------------------------
20 ; Header. Includes jump table
21
22 .segment        "JUMPTABLE"
23
24 ; Driver signature
25
26         .byte   $65, $6d, $64           ; "emd"
27         .byte   EMD_API_VERSION         ; EM API version number
28
29 ; Jump table.
30
31         .word   INSTALL
32         .word   UNINSTALL
33         .word   PAGECOUNT
34         .word   MAP
35         .word   USE
36         .word   COMMIT
37         .word   COPYFROM
38         .word   COPYTO
39
40 ; ------------------------------------------------------------------------
41 ; Constants
42
43 RAMC_WINDOW       = $DF00                 ; Address of RamCart window
44 RAMC_PAGE_LO      = $DE00                 ; Page register low
45 RAMC_PAGE_HI      = $DE01                 ; Page register high (only for RC128)
46
47 ; ------------------------------------------------------------------------
48 ; Data.
49
50 .bss
51
52 pagecount:      .res    2               ; Number of available pages
53
54 .code
55
56 ; ------------------------------------------------------------------------
57 ; INSTALL routine. Is called after the driver is loaded into memory. If
58 ; possible, check if the hardware is present and determine the amount of
59 ; memory available.
60 ; Must return an EM_ERR_xx code in a/x.
61 ;
62
63 INSTALL:
64         ldx     RAMC_WINDOW
65         cpx     RAMC_WINDOW
66         bne     @notpresent
67
68         lda     #0
69         sta     RAMC_PAGE_LO
70         sta     RAMC_PAGE_HI
71         ldx     RAMC_WINDOW
72         cpx     RAMC_WINDOW
73         bne     @notpresent
74         lda     #2
75         sta     RAMC_WINDOW
76         cmp     RAMC_WINDOW
77         beq     @cont
78         cpx     RAMC_WINDOW
79         beq     @readonly
80 @cont:  ldy     #1
81         sty     RAMC_PAGE_HI
82         sty     RAMC_WINDOW
83         dey
84         sty     RAMC_PAGE_HI
85         iny
86         cpy     RAMC_WINDOW
87         beq     @rc64
88         ; we're on rc128
89         ldx     #>512
90         bne     @setsize
91 @rc64:  ldx     #>256
92 @setsize:
93         lda     #0
94         sta     pagecount
95         stx     pagecount+1
96         lda     #<EM_ERR_OK
97         ldx     #>EM_ERR_OK
98         rts
99 @notpresent:
100 @readonly:
101         lda     #<EM_ERR_NO_DEVICE
102         ldx     #>EM_ERR_NO_DEVICE
103 ;       rts                             ; Run into UNINSTALL instead
104
105 ; ------------------------------------------------------------------------
106 ; UNINSTALL routine. Is called before the driver is removed from memory.
107 ; Can do cleanup or whatever. Must not return anything.
108 ;
109
110 UNINSTALL:
111         rts
112
113
114 ; ------------------------------------------------------------------------
115 ; PAGECOUNT: Return the total number of available pages in a/x.
116 ;
117
118 PAGECOUNT:
119         lda     pagecount
120         ldx     pagecount+1
121         rts
122
123 ; ------------------------------------------------------------------------
124 ; USE: Tell the driver that the window is now associated with a given page.
125 ; The RamCart cartridge does not copy but actually map the window, so USE is
126 ; identical to MAP.
127
128 USE     = MAP
129
130
131 ; ------------------------------------------------------------------------
132 ; MAP: Map the page in a/x into memory and return a pointer to the page in
133 ; a/x. The contents of the currently mapped page (if any) may be discarded
134 ; by the driver.
135 ;
136
137 MAP:    sta     RAMC_PAGE_LO
138         stx     RAMC_PAGE_HI
139         lda     #<RAMC_WINDOW
140         ldx     #>RAMC_WINDOW
141
142 ; Use the RTS from COMMIT below to save a precious byte of storage
143
144 ; ------------------------------------------------------------------------
145 ; COMMIT: Commit changes in the memory window to extended storage.
146
147 COMMIT: rts
148
149 ; ------------------------------------------------------------------------
150 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
151 ; describing the request is passed in a/x.
152 ; The function must not return anything.
153 ;
154
155 COPYFROM:
156         jsr     setup
157
158 ; Setup is:
159 ;
160 ;   - ptr1 contains the struct pointer
161 ;   - ptr2 contains the linear memory buffer
162 ;   - ptr3 contains -(count-1)
163 ;   - tmp1 contains the low page register value
164 ;   - tmp2 contains the high page register value
165 ;   - X contains the page offset
166 ;   - Y contains zero
167
168         jmp     @L5
169
170 @L1:    lda     RAMC_WINDOW,x
171         sta     (ptr2),y
172         iny
173         bne     @L2
174         inc     ptr2+1
175 @L2:    inx
176         beq     @L4
177
178 ; Bump count and repeat
179
180 @L3:    inc     ptr3
181         bne     @L1
182         inc     ptr3+1
183         bne     @L1
184         rts
185
186 ; Bump page register
187
188 @L4:    inc     tmp1
189         bne     @L5
190         inc     tmp2
191 @L5:    lda     tmp1
192         sta     RAMC_PAGE_LO
193         lda     tmp2
194         sta     RAMC_PAGE_HI
195         jmp     @L3
196
197 ; ------------------------------------------------------------------------
198 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
199 ; describing the request is passed in a/x.
200 ; The function must not return anything.
201 ;
202
203 COPYTO:
204         jsr     setup
205
206 ; Setup is:
207 ;
208 ;   - ptr1 contains the struct pointer
209 ;   - ptr2 contains the linear memory buffer
210 ;   - ptr3 contains -(count-1)
211 ;   - tmp1 contains the low page register value
212 ;   - tmp2 contains the high page register value
213 ;   - X contains the page offset
214 ;   - Y contains zero
215
216         jmp     @L5
217
218 @L1:    lda     (ptr2),y
219         sta     RAMC_WINDOW,x
220         iny
221         bne     @L2
222         inc     ptr2+1
223 @L2:    inx
224         beq     @L4
225
226 ; Bump count and repeat
227
228 @L3:    inc     ptr3
229         bne     @L1
230         inc     ptr3+1
231         bne     @L1
232         rts
233
234 ; Bump page register
235
236 @L4:    inc     tmp1
237         bne     @L5
238         inc     tmp2
239 @L5:    lda     tmp1
240         sta     RAMC_PAGE_LO
241         lda     tmp2
242         sta     RAMC_PAGE_HI
243         jmp     @L3
244
245 ; ------------------------------------------------------------------------
246 ; Helper function for COPYFROM and COPYTO: Store the pointer to the request
247 ; structure and prepare data for the copy
248
249 setup:  sta     ptr1
250         stx     ptr1+1          ; Save passed pointer
251
252 ; Get the page number from the struct and adjust it so that it may be used
253 ; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
254
255         ldy     #EM_COPY::PAGE+1
256         lda     (ptr1),y
257         sta     tmp2
258         dey
259         lda     (ptr1),y
260         sta     tmp1
261
262 ; Get the buffer pointer into ptr2
263
264         ldy     #EM_COPY::BUF
265         lda     (ptr1),y
266         sta     ptr2
267         iny
268         lda     (ptr1),y
269         sta     ptr2+1
270
271 ; Get the count, calculate -(count-1) and store it into ptr3
272
273         ldy     #EM_COPY::COUNT
274         lda     (ptr1),y
275         eor     #$FF
276         sta     ptr3
277         iny
278         lda     (ptr1),y
279         eor     #$FF
280         sta     ptr3+1
281
282 ; Get the page offset into X and clear Y
283
284         ldy     #EM_COPY::OFFS
285         lda     (ptr1),y
286         tax
287         ldy     #$00
288
289 ; Done
290
291         rts
292