]> git.sur5r.net Git - cc65/blob - libsrc/vic20/emd/vic20-rama.s
Merge branch 'master' into popptr1
[cc65] / libsrc / vic20 / emd / vic20-rama.s
1 ;
2 ; Extended memory driver for the VIC20 $A000-$BFFF RAM. Driver works without
3 ; problems when statically linked.
4 ;
5 ; Marco van den Heuvel, 2018-03-16
6 ;
7
8         .include        "zeropage.inc"
9
10         .include        "em-kernel.inc"
11         .include        "em-error.inc"
12
13
14         .macpack        generic
15         .macpack        module
16
17
18 ; ------------------------------------------------------------------------
19 ; Header. Includes jump table
20
21         module_header   _vic20_rama_emd
22
23 ; Driver signature
24
25         .byte   $65, $6d, $64           ; "emd"
26         .byte   EMD_API_VERSION         ; EM API version number
27
28 ; Library reference
29
30         .addr   $0000
31
32 ; Jump table
33
34         .addr   INSTALL
35         .addr   UNINSTALL
36         .addr   PAGECOUNT
37         .addr   MAP
38         .addr   USE
39         .addr   COMMIT
40         .addr   COPYFROM
41         .addr   COPYTO
42
43 ; ------------------------------------------------------------------------
44 ; Constants
45
46 BASE    = $A000
47 PAGES   = ($C000 - BASE) / 256
48
49 ; ------------------------------------------------------------------------
50 ; Data.
51
52 .bss
53 curpage:        .res    1               ; Current page number
54 window:         .res    256             ; Memory "window"
55
56 .code
57
58 ; ------------------------------------------------------------------------
59 ; INSTALL routine. Is called after the driver is loaded into memory. If
60 ; possible, check if the hardware is present and determine the amount of
61 ; memory available.
62 ; Must return an EM_ERR_xx code in a/x.
63 ;
64
65 INSTALL:
66         lda     $A000                   ; see what is at address $A000
67         inc     $A000                   ; see if it can be changed
68         cmp     $A000                   ; did it stick ?
69         beq     nomem
70         dec     $A000
71
72         ldx     #$FF
73         stx     curpage                 ; Invalidate the current page
74         inx                             ; X = 0
75         txa                             ; A = X = EM_ERR_OK
76         rts
77
78 nomem:  ldx     #>EM_ERR_NO_DEVICE
79         lda     #<EM_ERR_NO_DEVICE
80 ;       rts                             ; Run into UNINSTALL instead
81
82 ; ------------------------------------------------------------------------
83 ; UNINSTALL routine. Is called before the driver is removed from memory.
84 ; Can do cleanup or whatever. Must not return anything.
85 ;
86
87 UNINSTALL:
88         rts
89
90
91 ; ------------------------------------------------------------------------
92 ; PAGECOUNT: Return the total number of available pages in a/x.
93 ;
94
95 PAGECOUNT:
96         lda     #<PAGES
97         ldx     #>PAGES
98         rts
99
100 ; ------------------------------------------------------------------------
101 ; MAP: Map the page in a/x into memory and return a pointer to the page in
102 ; a/x. The contents of the currently mapped page (if any) may be discarded
103 ; by the driver.
104 ;
105
106 MAP:    sta     curpage                 ; Remember the new page
107
108         clc
109         adc     #>BASE
110         sta     ptr1+1
111         ldy     #$00
112         sty     ptr1
113
114         lda     #<window
115         sta     ptr2
116         lda     #>window
117         sta     ptr2+1
118
119 ; Transfer one page
120
121         jsr     transfer                ; Transfer one page
122
123 ; Return the memory window
124
125         lda     #<window
126         ldx     #>window                ; Return the window address
127         rts
128
129 ; ------------------------------------------------------------------------
130 ; USE: Tell the driver that the window is now associated with a given page.
131
132 USE:    sta     curpage                 ; Remember the page
133         lda     #<window
134         ldx     #>window                ; Return the window
135         rts
136
137 ; ------------------------------------------------------------------------
138 ; COMMIT: Commit changes in the memory window to extended storage.
139
140 COMMIT: lda     curpage                 ; Get the current page
141         bmi     done                    ; Jump if no page mapped
142
143         clc
144         adc     #>BASE
145         sta     ptr2+1
146         ldy     #$00
147         sty     ptr2
148
149         lda     #<window
150         sta     ptr1
151         lda     #>window
152         sta     ptr1+1
153
154 ; Transfer one page. Y must be zero on entry
155
156 transfer:
157
158 ; Unroll the following loop
159
160 loop:   .repeat 8
161         lda     (ptr1),y
162         sta     (ptr2),y
163         iny
164         .endrepeat
165
166         bne     loop
167
168 ; Done
169
170 done:   rts               
171
172 ; ------------------------------------------------------------------------
173 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
174 ; describing the request is passed in a/x.
175 ; The function must not return anything.
176 ;
177
178 COPYFROM:
179         sta     ptr3
180         stx     ptr3+1                  ; Save the passed em_copy pointer
181                        
182         ldy     #EM_COPY::OFFS
183         lda     (ptr3),y
184         sta     ptr1
185         ldy     #EM_COPY::PAGE
186         lda     (ptr3),y
187         clc
188         adc     #>BASE
189         sta     ptr1+1                  ; From
190
191         ldy     #EM_COPY::BUF
192         lda     (ptr3),y
193         sta     ptr2
194         iny
195         lda     (ptr3),y
196         sta     ptr2+1                  ; To
197
198 common: ldy     #EM_COPY::COUNT+1
199         lda     (ptr3),y                ; Get number of pages
200         beq     @L2                     ; Skip if no full pages
201         sta     tmp1
202
203 ; Copy full pages allowing interrupts after each page copied
204
205         ldy     #$00
206 @L1:    jsr     transfer
207         inc     ptr1+1
208         inc     ptr2+1
209         dec     tmp1
210         bne     @L1
211
212 ; Copy the remainder of the page
213
214 @L2:    ldy     #EM_COPY::COUNT
215         lda     (ptr3),y                ; Get bytes in last page
216         beq     @L4
217         tax
218
219 ; Transfer the bytes in the last page
220
221         ldy     #$00
222 @L3:    lda     (ptr1),y
223         sta     (ptr2),y
224         iny
225         dex
226         bne     @L3
227
228 ; Done
229
230 @L4:    rts
231
232 ; ------------------------------------------------------------------------
233 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
234 ; describing the request is passed in a/x.
235 ; The function must not return anything.
236 ;
237
238 COPYTO: sta     ptr3
239         stx     ptr3+1                  ; Save the passed em_copy pointer
240
241         ldy     #EM_COPY::OFFS
242         lda     (ptr3),y
243         sta     ptr2
244         ldy     #EM_COPY::PAGE
245         lda     (ptr3),y
246         clc
247         adc     #>BASE
248         sta     ptr2+1                  ; To
249
250         ldy     #EM_COPY::BUF
251         lda     (ptr3),y
252         sta     ptr1
253         iny
254         lda     (ptr3),y
255         sta     ptr1+1                  ; From
256
257         jmp     common
258