]> git.sur5r.net Git - cc65/blob - libsrc/c128/emd/c128-ifnram.s
Merge pull request #7 from cvemu/master
[cc65] / libsrc / c128 / emd / c128-ifnram.s
1 ;
2 ; Extended memory driver for the C128 Internal Function RAM. Driver works
3 ; without problems when statically linked.
4 ;
5 ; Marco van den Heuvel, 2015-11-30
6 ;
7
8         .include        "zeropage.inc"
9
10         .include        "em-kernel.inc"
11         .include        "em-error.inc"
12         .include        "c128.inc"
13
14         .macpack        generic
15         .macpack        module
16
17
18 ; ------------------------------------------------------------------------
19 ; Header. Includes jump table
20
21         module_header   _c128_ifnram_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    = $8000
47 PAGES   = 127      ; Do not touch MMU
48
49 ; ------------------------------------------------------------------------
50 ; Data.
51
52 .bss
53 curpage:        .res    2               ; Current page number
54
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         ldx     #0
68         stx     ptr1
69         ldx     #$80
70         stx     ptr1+1
71         ldx     #<ptr1
72         stx     FETVEC
73         stx     STAVEC
74         ldy     #0
75         ldx     #MMU_CFG_IFROM
76         sei
77         jsr     FETCH
78         tax
79         inx
80         txa
81         sta     tmp1
82         ldx     #MMU_CFG_IFROM
83         sei
84         jsr     STASH
85         ldx     #MMU_CFG_IFROM
86         jsr     FETCH
87         cli
88         cmp     tmp1
89         beq     @ram_present
90         lda     #<EM_ERR_NO_DEVICE
91         ldx     #>EM_ERR_NO_DEVICE
92         rts
93
94 @ram_present:
95         ldx     #$FF
96         stx     curpage
97         stx     curpage+1               ; Invalidate the current page
98         inx
99         txa                             ; A = X = EM_ERR_OK
100 ;       rts                             ; Run into UNINSTALL instead
101
102 ; ------------------------------------------------------------------------
103 ; UNINSTALL routine. Is called before the driver is removed from memory.
104 ; Can do cleanup or whatever. Must not return anything.
105 ;
106
107 UNINSTALL:
108         rts
109
110
111 ; ------------------------------------------------------------------------
112 ; PAGECOUNT: Return the total number of available pages in a/x.
113 ;
114
115 PAGECOUNT:
116         lda     #<PAGES
117         ldx     #>PAGES
118         rts
119
120 ; ------------------------------------------------------------------------
121 ; MAP: Map the page in a/x into memory and return a pointer to the page in
122 ; a/x. The contents of the currently mapped page (if any) may be discarded
123 ; by the driver.
124 ;
125
126 MAP:    sta     curpage
127         stx     curpage+1               ; Remember the new page
128
129         clc
130         adc     #>BASE
131         sta     ptr1+1
132         ldy     #$00
133         sty     ptr1
134
135         lda     #<ptr1
136         sta     FETVEC
137         sei
138
139 ; Transfer one page
140
141 @L1:    ldx     #MMU_CFG_IFROM
142         jsr     FETCH
143         sta     window,y
144         iny
145         bne     @L1
146
147 ; Return the memory window
148
149         cli
150         lda     #<window
151         ldx     #>window                ; Return the window address
152         rts
153
154 ; ------------------------------------------------------------------------
155 ; USE: Tell the driver that the window is now associated with a given page.
156
157 USE:    sta     curpage
158         stx     curpage+1               ; Remember the page
159         lda     #<window
160         ldx     #>window                ; Return the window
161         rts
162
163 ; ------------------------------------------------------------------------
164 ; COMMIT: Commit changes in the memory window to extended storage.
165
166 COMMIT: lda     curpage                 ; Get the current page
167         ldx     curpage+1
168         bmi     done                    ; Jump if no page mapped
169
170         clc
171         adc     #>BASE
172         sta     ptr1+1
173         ldy     #$00
174         sty     ptr1
175
176         lda     #<ptr1
177         sta     STAVEC
178         sei
179
180 ; Transfer one page. Y must be zero on entry
181
182 @L1:    lda     window,y
183         ldx     #MMU_CFG_IFROM
184         jsr     STASH
185         iny
186         bne     @L1
187         cli
188
189 ; Done
190
191 done:   rts
192
193 ; ------------------------------------------------------------------------
194 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
195 ; describing the request is passed in a/x.
196 ; The function must not return anything.
197 ;
198
199 COPYFROM:
200         sta     ptr3
201         stx     ptr3+1                  ; Save the passed em_copy pointer
202
203         ldy     #EM_COPY::OFFS
204         lda     (ptr3),y
205         sta     ptr1
206         ldy     #EM_COPY::PAGE
207         lda     (ptr3),y
208         clc
209         adc     #>BASE
210         sta     ptr1+1                  ; From
211
212         ldy     #EM_COPY::BUF
213         lda     (ptr3),y
214         sta     ptr2
215         iny
216         lda     (ptr3),y
217         sta     ptr2+1                  ; To
218
219         lda     #<ptr1
220         sta     FETVEC
221
222         ldy     #EM_COPY::COUNT+1
223         lda     (ptr3),y                ; Get number of pages
224         beq     @L2                     ; Skip if no full pages
225         sta     tmp1
226
227 ; Copy full pages
228
229         ldy     #$00
230         sei
231 @L1:    ldx     #MMU_CFG_IFROM
232         jsr     FETCH
233         sta     (ptr2),y
234         iny
235         bne     @L1
236         inc     ptr1+1
237         inc     ptr2+1
238         dec     tmp1
239         bne     @L1
240
241 ; Copy the remainder of the page
242
243 @L2:    ldy     #EM_COPY::COUNT
244         lda     (ptr3),y                ; Get bytes in last page
245         beq     @L4
246         sta     tmp1
247
248         ldy     #$00
249 @L3:    ldx     #MMU_CFG_IFROM
250         jsr     FETCH
251         sta     (ptr2),y
252         iny
253         dec     tmp1
254         bne     @L3
255 ; Done
256
257 @L4:    cli
258         rts
259
260 ; ------------------------------------------------------------------------
261 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
262 ; describing the request is passed in a/x.
263 ; The function must not return anything.
264 ;
265
266 COPYTO: sta     ptr3
267         stx     ptr3+1                  ; Save the passed em_copy pointer
268
269         ldy     #EM_COPY::OFFS
270         lda     (ptr3),y
271         sta     ptr1
272         ldy     #EM_COPY::PAGE
273         lda     (ptr3),y
274         clc
275         adc     #>BASE
276         sta     ptr1+1                  ; To
277
278         ldy     #EM_COPY::BUF
279         lda     (ptr3),y
280         sta     ptr2
281         iny
282         lda     (ptr3),y
283         sta     ptr2+1                  ; From
284
285         lda     #<ptr1
286         sta     STAVEC
287
288         ldy     #EM_COPY::COUNT+1
289         lda     (ptr3),y                ; Get number of pages
290         beq     @L2                     ; Skip if no full pages
291         sta     tmp1
292
293 ; Copy full pages
294
295         sei
296         ldy     #$00
297 @L1:    lda     (ptr2),y
298         ldx     #MMU_CFG_IFROM
299         jsr     STASH
300         iny
301         bne     @L1
302         inc     ptr1+1
303         inc     ptr2+1
304         dec     tmp1
305         bne     @L1
306
307 ; Copy the remainder of the page
308
309 @L2:    ldy     #EM_COPY::COUNT
310         lda     (ptr3),y                ; Get bytes in last page
311         beq     @L4
312         sta     tmp1
313
314         ldy     #$00
315 @L3:    lda     (ptr2),y
316         ldx     #MMU_CFG_IFROM
317         jsr     STASH
318         iny
319         dec     tmp1
320         bne     @L3
321
322 ; Done
323
324 @L4:    cli
325         rts