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