]> git.sur5r.net Git - cc65/blob - libsrc/c64/c64-georam.s
Don't hardcode the address of the SYS call for the startup code of the
[cc65] / libsrc / c64 / c64-georam.s
1 ;
2 ; Extended memory driver for the GEORAM cartridge. Driver works without
3 ; problems when statically linked.
4 ;
5 ; Ullrich von Bassewitz, 2002-11-29
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 GR_WINDOW       = $DE00                 ; Address of GEORAM window
42 GR_PAGE_LO      = $DFFE                 ; Page register low
43 GR_PAGE_HI      = $DFFF                 ; Page register high
44
45 ; ------------------------------------------------------------------------
46 ; Data.
47
48 .data
49
50 pagecount:      .word   2048            ; Currently fixed
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                     ; Run into UNINSTALL instead
65
66 ; ------------------------------------------------------------------------
67 ; UNINSTALL routine. Is called before the driver is removed from memory.
68 ; Can do cleanup or whatever. Must not return anything.
69 ;
70
71 UNINSTALL:
72         rts
73
74
75 ; ------------------------------------------------------------------------
76 ; PAGECOUNT: Return the total number of available pages in a/x.
77 ;
78
79 PAGECOUNT:
80         lda     pagecount
81         ldx     pagecount+1
82         rts
83
84 ; ------------------------------------------------------------------------
85 ; USE: Tell the driver that the window is now associated with a given page.
86 ; The GeoRAM cartridge does not copy but actually map the window, so USE is
87 ; identical to MAP.
88
89 USE     = MAP             
90
91 ; ------------------------------------------------------------------------
92 ; MAP: Map the page in a/x into memory and return a pointer to the page in
93 ; a/x. The contents of the currently mapped page (if any) may be discarded
94 ; by the driver.
95 ;
96
97 MAP:    sta     tmp1
98         txa
99         asl     tmp1
100         rol     a
101         asl     tmp1
102         rol     a
103
104         sta     GR_PAGE_HI
105         lda     tmp1
106         lsr     a
107         lsr     a
108         sta     GR_PAGE_LO
109
110         lda     #<GR_WINDOW
111         ldx     #>GR_WINDOW
112
113 ; Use the RTS from COMMIT below to save a precious byte of storage
114
115 ; ------------------------------------------------------------------------
116 ; COMMIT: Commit changes in the memory window to extended storage.
117
118 COMMIT: rts
119
120 ; ------------------------------------------------------------------------
121 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
122 ; describing the request is passed in a/x.
123 ; The function must not return anything.
124 ;
125
126 COPYFROM:
127         jsr     setup
128
129 ; Setup is:
130 ;
131 ;   - ptr1 contains the struct pointer
132 ;   - ptr2 contains the linear memory buffer
133 ;   - ptr3 contains -(count-1)
134 ;   - tmp1 contains the low page register value
135 ;   - tmp2 contains the high page register value
136 ;   - X contains the page offset
137 ;   - Y contains zero
138
139         jmp     @L5
140
141 @L1:    lda     GR_WINDOW,x
142         sta     (ptr2),y
143         iny
144         bne     @L2
145         inc     ptr2+1
146 @L2:    inx
147         beq     @L4
148
149 ; Bump count and repeat
150
151 @L3:    inc     ptr3
152         bne     @L1
153         inc     ptr3+1
154         bne     @L1
155         rts
156
157 ; Bump page register
158
159 @L4:    inc     tmp1            ; Bump low page register
160         bit     tmp1            ; Check for overflow in bit 6
161         bvc     @L6             ; Jump if no overflow
162         inc     tmp2
163 @L5:    lda     tmp2
164         sta     GR_PAGE_HI
165 @L6:    lda     tmp1
166         sta     GR_PAGE_LO
167         jmp     @L3
168
169 ; ------------------------------------------------------------------------
170 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
171 ; describing the request is passed in a/x.
172 ; The function must not return anything.
173 ;
174
175 COPYTO:
176         jsr     setup
177
178 ; Setup is:
179 ;
180 ;   - ptr1 contains the struct pointer
181 ;   - ptr2 contains the linear memory buffer
182 ;   - ptr3 contains -(count-1)
183 ;   - tmp1 contains the low page register value
184 ;   - tmp2 contains the high page register value
185 ;   - X contains the page offset
186 ;   - Y contains zero
187
188         jmp     @L5
189
190 @L1:    lda     (ptr2),y
191         sta     GR_WINDOW,x
192         iny
193         bne     @L2
194         inc     ptr2+1
195 @L2:    inx
196         beq     @L4
197
198 ; Bump count and repeat
199
200 @L3:    inc     ptr3
201         bne     @L1
202         inc     ptr3+1
203         bne     @L1
204         rts
205
206 ; Bump page register
207
208 @L4:    inc     tmp1            ; Bump low page register
209         bit     tmp1            ; Check for overflow in bit 6
210         bvc     @L6             ; Jump if no overflow
211         inc     tmp2
212 @L5:    lda     tmp2
213         sta     GR_PAGE_HI
214 @L6:    lda     tmp1
215         sta     GR_PAGE_LO
216         jmp     @L3
217
218 ; ------------------------------------------------------------------------
219 ; Helper function for COPYFROM and COPYTO: Store the pointer to the request
220 ; structure and prepare data for the copy
221
222 setup:  sta     ptr1
223         stx     ptr1+1          ; Save passed pointer
224
225 ; Get the page number from the struct and adjust it so that it may be used
226 ; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
227
228         ldy     #EM_COPY::PAGE+1
229         lda     (ptr1),y
230         sta     tmp2
231         dey
232         lda     (ptr1),y
233         asl     a
234         rol     tmp2
235         asl     a
236         rol     tmp2
237         lsr     a
238         lsr     a
239         sta     tmp1
240
241 ; Get the buffer pointer into ptr2
242
243         ldy     #EM_COPY::BUF
244         lda     (ptr1),y
245         sta     ptr2
246         iny
247         lda     (ptr1),y
248         sta     ptr2+1
249
250 ; Get the count, calculate -(count-1) and store it into ptr3
251
252         ldy     #EM_COPY::COUNT
253         lda     (ptr1),y
254         eor     #$FF
255         sta     ptr3
256         iny
257         lda     (ptr1),y
258         eor     #$FF
259         sta     ptr3+1
260
261 ; Get the page offset into X and clear Y
262
263         ldy     #EM_COPY::OFFS
264         lda     (ptr1),y
265         tax
266         ldy     #$00
267
268 ; Done
269
270         rts
271
272