]> git.sur5r.net Git - cc65/blob - libsrc/c128/emd/c128-ifnram.s
Finished adding c128 internal/external function ram emd's.
[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         sei
68         ldx     #0
69         stx     ptr1
70         ldx     #$80
71         stx     ptr1+1
72         ldx     #<ptr1
73         stx     FETVEC
74         stx     STAVEC
75         ldy     #0
76         ldx     #MMU_CFG_INT_FROM
77         jsr     FETCH
78         tax
79         inx
80         txa
81         sta     tmp1
82         ldx     #MMU_CFG_INT_FROM
83         jsr     STASH
84         ldx     #MMU_CFG_INT_FROM
85         jsr     FETCH
86         cmp     tmp1
87         beq     @ram_present
88         lda     #<EM_ERR_NO_DEVICE
89         ldx     #>EM_ERR_NO_DEVICE
90         cli
91         rts
92
93 @ram_present:
94         ldx     #$FF
95         stx     curpage
96         stx     curpage+1               ; Invalidate the current page
97         inx
98         txa                             ; A = X = EM_ERR_OK
99         cli
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:    sei
127         sta     curpage
128         stx     curpage+1               ; Remember the new page
129
130         clc
131         adc     #>BASE
132         sta     ptr1+1
133         ldy     #$00
134         sty     ptr1
135
136         lda     #<ptr1
137         sta     FETVEC
138
139 ; Transfer one page
140
141 @L1:    ldx     #MMU_CFG_INT_FROM
142         jsr     FETCH
143         sta     window,y
144         iny
145         bne     @L1
146
147 ; Return the memory window
148
149         lda     #<window
150         ldx     #>window                ; Return the window address
151         cli
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: sei
167         lda     curpage                 ; Get the current page
168         ldx     curpage+1
169         bmi     done                    ; Jump if no page mapped
170
171         clc
172         adc     #>BASE
173         sta     ptr1+1
174         ldy     #$00
175         sty     ptr1
176
177         lda     #<ptr1
178         sta     STAVEC
179
180 ; Transfer one page. Y must be zero on entry
181
182 @L1:    lda     window,y
183         ldx     #MMU_CFG_INT_FROM
184         jsr     STASH
185         iny
186         bne     @L1
187
188 ; Done
189
190 done:   cli
191         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         sei
201         sta     ptr3
202         stx     ptr3+1                  ; Save the passed em_copy pointer
203
204         ldy     #EM_COPY::OFFS
205         lda     (ptr3),y
206         sta     ptr1
207         ldy     #EM_COPY::PAGE
208         lda     (ptr3),y
209         clc
210         adc     #>BASE
211         sta     ptr1+1                  ; From
212
213         ldy     #EM_COPY::BUF
214         lda     (ptr3),y
215         sta     ptr2
216         iny
217         lda     (ptr3),y
218         sta     ptr2+1                  ; To
219
220         lda     #<ptr1
221         sta     FETVEC
222
223         ldy     #EM_COPY::COUNT+1
224         lda     (ptr3),y                ; Get number of pages
225         beq     @L2                     ; Skip if no full pages
226         sta     tmp1
227
228 ; Copy full pages
229
230         ldy     #$00
231 @L1:    ldx     #MMU_CFG_INT_FROM
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_INT_FROM
250         jsr     FETCH
251         sta     (ptr2),y
252         iny
253         dec     tmp1
254         bne     @L3
255
256 ; Done
257
258 @L4:    cli
259         rts
260
261 ; ------------------------------------------------------------------------
262 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
263 ; describing the request is passed in a/x.
264 ; The function must not return anything.
265 ;
266
267 COPYTO: sei
268         sta     ptr3
269         stx     ptr3+1                  ; Save the passed em_copy pointer
270
271         ldy     #EM_COPY::OFFS
272         lda     (ptr3),y
273         sta     ptr1
274         ldy     #EM_COPY::PAGE
275         lda     (ptr3),y
276         clc
277         adc     #>BASE
278         sta     ptr1+1                  ; To
279
280         ldy     #EM_COPY::BUF
281         lda     (ptr3),y
282         sta     ptr2
283         iny
284         lda     (ptr3),y
285         sta     ptr2+1                  ; From
286
287         lda     #<ptr1
288         sta     STAVEC
289
290         ldy     #EM_COPY::COUNT+1
291         lda     (ptr3),y                ; Get number of pages
292         beq     @L2                     ; Skip if no full pages
293         sta     tmp1
294
295 ; Copy full pages
296
297         ldy     #$00
298 @L1:    lda     (ptr2),y
299         ldx     #MMU_CFG_INT_FROM
300         jsr     STASH
301         iny
302         bne     @L1
303         inc     ptr1+1
304         inc     ptr2+1
305         dec     tmp1
306         bne     @L1
307
308 ; Copy the remainder of the page
309
310 @L2:    ldy     #EM_COPY::COUNT
311         lda     (ptr3),y                ; Get bytes in last page
312         beq     @L4
313         sta     tmp1
314
315         ldy     #$00
316 @L3:    lda     (ptr2),y
317         ldx     #MMU_CFG_INT_FROM
318         jsr     STASH
319         iny
320         dec     tmp1
321         bne     @L3
322
323 ; Done
324
325 @L4:    cli
326         rts