]> git.sur5r.net Git - cc65/blob - libsrc/c64/emd/c64-isepic.s
Merge remote-tracking branch 'refs/remotes/cc65/master' into doc-cc65-intern
[cc65] / libsrc / c64 / emd / c64-isepic.s
1 ;
2 ; Extended memory driver for the ISEPIC cartridge.
3 ; Marco van den Heuvel, 2010-01-24
4 ;
5
6         .include        "zeropage.inc"
7
8         .include        "em-kernel.inc"
9         .include        "em-error.inc"
10
11
12         .macpack        generic
13         .macpack        module
14
15
16 ; ------------------------------------------------------------------------
17 ; Header. Includes jump table
18
19         module_header   _c64_isepic_emd
20
21 ; Driver signature
22
23         .byte   $65, $6d, $64           ; "emd"
24         .byte   EMD_API_VERSION         ; EM API version number
25
26 ; Library reference
27
28         .addr   $0000
29
30 ; Jump table
31
32         .addr   INSTALL
33         .addr   UNINSTALL
34         .addr   PAGECOUNT
35         .addr   MAP
36         .addr   USE
37         .addr   COMMIT
38         .addr   COPYFROM
39         .addr   COPYTO
40
41 ; ------------------------------------------------------------------------
42 ; Constants
43
44 IP_WINDOW       = $DF00         ; Address of ISEPIC window
45 IP_CTRL_BASE    = $DE00
46 PAGES           = 8
47
48 ; ------------------------------------------------------------------------
49 ; Code.
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     #0
62         sta     IP_CTRL_BASE
63         ldx     IP_WINDOW
64         cpx     IP_WINDOW
65         bne     @notpresent
66         inc     IP_WINDOW
67         cpx     IP_WINDOW
68         beq     @notpresent
69         ldx     IP_WINDOW
70         sta     IP_CTRL_BASE+1
71         inx
72         stx     IP_WINDOW
73         dex
74         sta     IP_CTRL_BASE
75         cpx     IP_WINDOW
76         beq     @setok
77
78 @notpresent:
79         lda     #<EM_ERR_NO_DEVICE
80         ldx     #>EM_ERR_NO_DEVICE
81         rts
82
83 @setok:
84         lda     #<EM_ERR_OK
85         ldx     #>EM_ERR_OK
86 ;       rts                             ; Run into UNINSTALL instead
87
88 ; ------------------------------------------------------------------------
89 ; UNINSTALL routine. Is called before the driver is removed from memory.
90 ; Can do cleanup or whatever. Must not return anything.
91 ;
92
93 UNINSTALL:
94         rts
95
96 ; ------------------------------------------------------------------------
97 ; PAGECOUNT: Return the total number of available pages in a/x.
98 ;
99
100 PAGECOUNT:
101         lda     #<PAGES
102         ldx     #>PAGES
103         rts
104
105 ; ------------------------------------------------------------------------
106 ; USE: Tell the driver that the window is now associated with a given page.
107 ; The Isepic cartridge does not copy but actually map the window, so USE is
108 ; identical to MAP.
109
110 USE     := MAP
111
112 ; ------------------------------------------------------------------------
113 ; MAP: Map the page in a/x into memory and return a pointer to the page in
114 ; a/x. The contents of the currently mapped page (if any) may be discarded
115 ; by the driver.
116 ;
117
118 MAP:
119         tax
120         sta     IP_CTRL_BASE,x
121         lda     #<IP_WINDOW
122         ldx     #>IP_WINDOW
123
124 ; Use the RTS from COMMIT below to save a precious byte of storage
125
126 ; ------------------------------------------------------------------------
127 ; COMMIT: Commit changes in the memory window to extended storage.
128
129 COMMIT:
130         rts
131
132 ; ------------------------------------------------------------------------
133 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
134 ; describing the request is passed in a/x.
135 ; The function must not return anything.
136 ;
137
138 COPYFROM:
139         jsr     setup
140
141 ; Setup is:
142 ;
143 ;   - ptr1 contains the struct pointer
144 ;   - ptr2 contains the linear memory buffer
145 ;   - ptr3 contains -(count-1)
146 ;   - tmp1 contains the low page register value
147 ;   - X contains the page offset
148 ;   - Y contains zero
149
150         jmp     @L5
151
152 @L1:
153         lda     IP_WINDOW,x
154         sta     (ptr2),y
155         iny
156         bne     @L2
157         inc     ptr2+1
158 @L2:
159         inx
160         beq     @L4
161
162 ; Bump count and repeat
163
164 @L3:
165         inc     ptr3
166         bne     @L1
167         inc     ptr3+1
168         bne     @L1
169         rts
170
171 ; Bump page register
172
173 @L4:
174         inc     tmp1            ; Bump low page register
175 @L5:
176         stx     tmp2
177         ldx     tmp1
178         sta     IP_CTRL_BASE,x
179         ldx     tmp2
180         jmp     @L3
181
182 ; ------------------------------------------------------------------------
183 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
184 ; describing the request is passed in a/x.
185 ; The function must not return anything.
186 ;
187
188 COPYTO:
189         jsr     setup
190
191 ; Setup is:
192 ;
193 ;   - ptr1 contains the struct pointer
194 ;   - ptr2 contains the linear memory buffer
195 ;   - ptr3 contains -(count-1)
196 ;   - tmp1 contains the low page register value
197 ;   - X contains the page offset
198 ;   - Y contains zero
199
200         jmp     @L5
201
202 @L1:
203         lda     (ptr2),y
204         sta     IP_WINDOW,x
205         iny
206         bne     @L2
207         inc     ptr2+1
208 @L2:
209         inx
210         beq     @L4
211
212 ; Bump count and repeat
213
214 @L3:
215         inc     ptr3
216         bne     @L1
217         inc     ptr3+1
218         bne     @L1
219         rts
220
221 ; Bump page register
222
223 @L4:
224         inc     tmp1            ; Bump page register
225 @L5:
226         stx     tmp2
227         ldx     tmp1
228         sta     IP_CTRL_BASE,x
229         ldx     tmp2
230         jmp     @L3
231
232 ; ------------------------------------------------------------------------
233 ; Helper function for COPYFROM and COPYTO: Store the pointer to the request
234 ; structure and prepare data for the copy
235
236 setup:
237         sta     ptr1
238         stx     ptr1+1          ; Save passed pointer
239
240 ; Get the page number from the struct and remember it.
241
242         ldy     #EM_COPY::PAGE
243         lda     (ptr1),y
244         sta     tmp1
245
246 ; Get the buffer pointer into ptr2
247
248         ldy     #EM_COPY::BUF
249         lda     (ptr1),y
250         sta     ptr2
251         iny
252         lda     (ptr1),y
253         sta     ptr2+1
254
255 ; Get the count, calculate -(count-1) and store it into ptr3
256
257         ldy     #EM_COPY::COUNT
258         lda     (ptr1),y
259         eor     #$FF
260         sta     ptr3
261         iny
262         lda     (ptr1),y
263         eor     #$FF
264         sta     ptr3+1
265
266 ; Get the page offset into X and clear Y
267
268         ldy     #EM_COPY::OFFS
269         lda     (ptr1),y
270         tax
271         ldy     #0
272
273 ; Done
274
275         rts