]> git.sur5r.net Git - cc65/blob - libsrc/apple2/apple2-lc.s
Call interrupt handlers with carry clear
[cc65] / libsrc / apple2 / apple2-lc.s
1 ;
2 ; Extended memory driver for the Apple II language card
3 ;
4 ; Stefan Haubenthal, 2003-12-13
5 ; Ullrich von Bassewitz, 2002-12-02,2003-12-21
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                         ; $Cxxx -> $Dxxx bank 1
42 BASE2   = $D000
43 PAGES   = ($10000 - BASE) / 256
44 ROMONLY2= $C082
45 LC2RW   = $C083
46 LC1RW   = $C08B
47
48 ; ------------------------------------------------------------------------
49 ; Data.
50
51 .bss
52 curpage:        .res    1               ; Current page number
53
54 .bss
55 window:         .res    256             ; Memory "window"
56
57 .code
58
59 ; ------------------------------------------------------------------------
60 ; INSTALL routine. Is called after the driver is loaded into memory. If
61 ; possible, check if the hardware is present and determine the amount of
62 ; memory available.
63 ; Must return an EM_ERR_xx code in a/x.
64 ;
65
66 INSTALL:
67         lda     #$FF
68         sta     curpage                 ; Invalidate the current page
69         lda     #EM_ERR_OK
70         ldx     #$00
71 ;       rts                             ; Run into UNINSTALL instead
72
73 ; ------------------------------------------------------------------------
74 ; UNINSTALL routine. Is called before the driver is removed from memory.
75 ; Can do cleanup or whatever. Must not return anything.
76 ;
77
78 UNINSTALL:
79         rts
80
81
82 ; ------------------------------------------------------------------------
83 ; PAGECOUNT: Return the total number of available pages in a/x.
84 ;
85
86 PAGECOUNT:
87         lda     #<PAGES
88         ldx     #>PAGES
89         rts
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     curpage                 ; Remember the new page
98
99         add     #>BASE
100         sta     ptr1+1
101         ldy     #$00
102         sty     ptr1
103
104         lda     #<window
105         sta     ptr2
106         lda     #>window
107         sta     ptr2+1
108
109 ; Transfer one page
110
111         jsr     transfer                ; Transfer one page
112
113 ; Return the memory window
114
115         lda     #<window
116         ldx     #>window                ; Return the window address
117         rts
118
119 ; ------------------------------------------------------------------------
120 ; USE: Tell the driver that the window is now associated with a given page.
121
122 USE:    sta     curpage                 ; Remember the page
123         lda     #<window
124         ldx     #>window                ; Return the window
125         rts
126
127 ; ------------------------------------------------------------------------
128 ; COMMIT: Commit changes in the memory window to extended storage.
129
130 COMMIT: lda     curpage                 ; Get the current page
131         bmi     done                    ; Jump if no page mapped
132
133         add     #>BASE
134         sta     ptr2+1
135         ldy     #$00
136         sty     ptr2
137
138         lda     #<window
139         sta     ptr1
140         lda     #>window
141         sta     ptr1+1
142
143 ; Transfer one page. Y must be zero on entry
144
145 transfer:
146         ldx     #$00
147         lda     ptr2+1
148         cmp     #>BASE
149         bcc     @L1
150         cmp     #>BASE2
151         bcs     @L1
152         adc     #>(BASE2-BASE)
153         sta     ptr2+1
154         ldx     #LC1RW-LC2RW
155 @L1:    lda     ptr1+1
156         cmp     #>BASE
157         bcc     @L2
158         cmp     #>BASE2
159         bcs     @L2
160         adc     #>(BASE2-BASE)
161         sta     ptr1+1
162         ldx     #LC1RW-LC2RW
163 @L2:    sei
164         lda     LC2RW,x                 ; Bank out ROMs
165         lda     LC2RW,x
166
167 ; Unroll the following loop
168
169 loop:   .repeat 8
170         lda     (ptr1),y
171         sta     (ptr2),y
172         iny
173         .endrep
174
175         bne     loop
176
177 ; Restore the old memory configuration, allow interrupts
178
179         lda     ROMONLY2                ; Bank in ROMs
180         cli
181
182 ; Done
183
184 done:   rts
185
186 ; ------------------------------------------------------------------------
187 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
188 ; describing the request is passed in a/x.
189 ; The function must not return anything.
190 ;
191
192 COPYFROM:
193         sta     ptr3
194         stx     ptr3+1                  ; Save the passed em_copy pointer
195
196         ldy     #EM_COPY::OFFS
197         lda     (ptr3),y
198         sta     ptr1
199         ldy     #EM_COPY::PAGE
200         lda     (ptr3),y
201         add     #>BASE
202         sta     ptr1+1                  ; From
203
204         ldy     #EM_COPY::BUF
205         lda     (ptr3),y
206         sta     ptr2
207         iny
208         lda     (ptr3),y
209         sta     ptr2+1                  ; To
210
211 common: ldy     #EM_COPY::COUNT+1
212         lda     (ptr3),y                ; Get number of pages
213         beq     @L2                     ; Skip if no full pages
214         sta     tmp1
215
216 ; Copy full pages allowing interrupts after each page copied
217
218         ldy     #$00
219 @L1:    jsr     transfer
220         inc     ptr1+1
221         inc     ptr2+1
222         dec     tmp1
223         bne     @L1
224
225 ; Copy the remainder of the page
226
227 @L2:    ldy     #EM_COPY::COUNT
228         lda     (ptr3),y                ; Get bytes in last page
229         beq     @L4
230         pha
231
232         sei
233         lda     LC2RW,x                 ; Bank out ROMs
234         lda     LC2RW,x
235         pla
236         tax
237
238 ; Transfer the bytes in the last page
239
240         ldy     #$00
241 @L3:    lda     (ptr1),y
242         sta     (ptr2),y
243         iny
244         dex
245         bne     @L3
246
247 ; Restore the old memory configuration, allow interrupts
248
249         lda     ROMONLY2                ; Bank in ROMs
250         cli
251
252 ; Done
253
254 @L4:    rts
255
256 ; ------------------------------------------------------------------------
257 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
258 ; describing the request is passed in a/x.
259 ; The function must not return anything.
260 ;
261
262 COPYTO: sta     ptr3
263         stx     ptr3+1                  ; Save the passed em_copy pointer
264
265         ldy     #EM_COPY::OFFS
266         lda     (ptr3),y
267         sta     ptr2
268         ldy     #EM_COPY::PAGE
269         lda     (ptr3),y
270         add     #>BASE
271         sta     ptr2+1                  ; To
272
273         ldy     #EM_COPY::BUF
274         lda     (ptr3),y
275         sta     ptr1
276         iny
277         lda     (ptr3),y
278         sta     ptr1+1                  ; From
279
280         jmp     common
281
282