]> git.sur5r.net Git - cc65/blob - libsrc/c16/emd/c16-ram.s
Renamed JUMPTABLE and cleaned up module.cfg.
[cc65] / libsrc / c16 / emd / c16-ram.s
1 ;
2 ; Extended memory driver for the C16 hidden RAM. Driver works without
3 ; problems when statically linked.
4 ;
5 ; Ullrich von Bassewitz, 2003-12-15
6 ;
7
8         .include        "zeropage.inc"
9
10         .include        "em-kernel.inc"
11         .include        "em-error.inc"
12         .include        "plus4.inc"
13
14         .macpack        generic
15
16
17 ; ------------------------------------------------------------------------
18 ; Header. Includes jump table
19
20 .segment        "HEADER"
21
22 ; Driver signature
23
24         .byte   $65, $6d, $64           ; "emd"
25         .byte   EMD_API_VERSION         ; EM API version number
26
27 ; Library reference
28
29         .addr   $0000
30
31 ; Jump table
32
33         .addr   INSTALL
34         .addr   UNINSTALL
35         .addr   PAGECOUNT
36         .addr   MAP
37         .addr   USE
38         .addr   COMMIT
39         .addr   COPYFROM
40         .addr   COPYTO
41
42 ; ------------------------------------------------------------------------
43 ; Constants
44
45 BASE    = $8000
46
47 ; ------------------------------------------------------------------------
48 ; Data.
49
50 .bss
51 pages:          .res    1               ; Number of pages
52 curpage:        .res    1               ; Current page number
53 window:         .res    256             ; Memory "window"
54
55 .code
56
57 ; ------------------------------------------------------------------------
58 ; INSTALL routine. Is called after the driver is loaded into memory. If
59 ; possible, check if the hardware is present and determine the amount of
60 ; memory available.
61 ; Must return an EM_ERR_xx code in a/x.
62 ;
63
64 INSTALL:
65
66 ; Determine how much memory is available. We will use all memory above
67 ; $8000 up to MEMTOP
68
69         sec
70         jsr     $FF99                   ; MEMTOP: Get top memory into Y/X
71         tya
72         sub     #>BASE                  ; Low 32 K are used
73         bcc     nomem
74         beq     nomem                   ; Offering zero pages is a bad idea
75         sta     pages
76
77         ldx     #$FF
78         stx     curpage                 ; Invalidate the current page
79         inx                             ; X = 0
80         txa                             ; A = X = EM_ERR_OK
81         rts
82
83 nomem:  ldx     #>EM_ERR_NO_DEVICE
84         lda     #<EM_ERR_NO_DEVICE
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 ; ------------------------------------------------------------------------
97 ; PAGECOUNT: Return the total number of available pages in a/x.
98 ;
99
100 PAGECOUNT:
101         lda     pages
102         ldx     #$00                    ; 128 pages max
103         rts
104
105 ; ------------------------------------------------------------------------
106 ; MAP: Map the page in a/x into memory and return a pointer to the page in
107 ; a/x. The contents of the currently mapped page (if any) may be discarded
108 ; by the driver.
109 ;
110
111 MAP:    sta     curpage                 ; Remember the new page
112
113         add     #>BASE
114         sta     ptr1+1
115         ldy     #$00
116         sty     ptr1
117
118         lda     #<window
119         sta     ptr2
120         lda     #>window
121         sta     ptr2+1
122
123 ; Transfer one page
124
125         jsr     transfer                ; Transfer one page
126
127 ; Return the memory window
128
129         lda     #<window
130         ldx     #>window                ; Return the window address
131         rts
132
133 ; ------------------------------------------------------------------------
134 ; USE: Tell the driver that the window is now associated with a given page.
135
136 USE:    sta     curpage                 ; Remember the page
137         lda     #<window
138         ldx     #>window                ; Return the window
139         rts
140
141 ; ------------------------------------------------------------------------
142 ; COMMIT: Commit changes in the memory window to extended storage.
143
144 COMMIT: lda     curpage                 ; Get the current page
145         bmi     done                    ; Jump if no page mapped
146
147         add     #>BASE
148         sta     ptr2+1
149         ldy     #$00
150         sty     ptr2
151
152         lda     #<window
153         sta     ptr1
154         lda     #>window
155         sta     ptr1+1
156
157 ; Transfer one page. Y must be zero on entry. Because we bank out the
158 ; kernal, we will run the routine with interrupts disabled but leave
159 ; short breath times. Unroll the following loop to make it somewhat faster.
160
161 transfer:
162         sei
163         sta     ENABLE_RAM
164
165         .repeat 8
166         lda     (ptr1),y
167         sta     (ptr2),y
168         iny
169         .endrepeat
170
171         sta     ENABLE_ROM
172         cli
173
174         bne     transfer
175
176 ; Done
177
178 done:   rts
179
180 ; ------------------------------------------------------------------------
181 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
182 ; describing the request is passed in a/x.
183 ; The function must not return anything.
184 ;
185
186 COPYFROM:
187         sta     ptr3
188         stx     ptr3+1                  ; Save the passed em_copy pointer
189
190         ldy     #EM_COPY::OFFS
191         lda     (ptr3),y
192         sta     ptr1
193         ldy     #EM_COPY::PAGE
194         lda     (ptr3),y
195         add     #>BASE
196         sta     ptr1+1                  ; From
197
198         ldy     #EM_COPY::BUF
199         lda     (ptr3),y
200         sta     ptr2
201         iny
202         lda     (ptr3),y
203         sta     ptr2+1                  ; To
204
205 common: ldy     #EM_COPY::COUNT+1
206         lda     (ptr3),y                ; Get number of pages
207         beq     @L2                     ; Skip if no full pages
208         sta     tmp1
209
210 ; Copy full pages allowing interrupts after each page copied
211
212         ldy     #$00
213 @L1:    jsr     transfer
214         inc     ptr1+1
215         inc     ptr2+1
216         dec     tmp1
217         bne     @L1
218
219 ; Copy the remainder of the page
220
221 @L2:    ldy     #EM_COPY::COUNT
222         lda     (ptr3),y                ; Get bytes in last page
223         beq     @L4
224         tax
225
226         sei                             ; Disable ints
227         sta     ENABLE_RAM              ; Bank out the ROM
228
229 ; Transfer the bytes in the last page
230
231         ldy     #$00
232 @L3:    lda     (ptr1),y
233         sta     (ptr2),y
234         iny
235         dex
236         bne     @L3
237
238 ; Restore the old memory configuration, allow interrupts
239
240         sta     ENABLE_ROM
241         cli
242
243 ; Done
244
245 @L4:    rts
246
247 ; ------------------------------------------------------------------------
248 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
249 ; describing the request is passed in a/x.
250 ; The function must not return anything.
251 ;
252
253 COPYTO: sta     ptr3
254         stx     ptr3+1                  ; Save the passed em_copy pointer
255
256         ldy     #EM_COPY::OFFS
257         lda     (ptr3),y
258         sta     ptr2
259         ldy     #EM_COPY::PAGE
260         lda     (ptr3),y
261         add     #>BASE
262         sta     ptr2+1                  ; To
263
264         ldy     #EM_COPY::BUF
265         lda     (ptr3),y
266         sta     ptr1
267         iny
268         lda     (ptr3),y
269         sta     ptr1+1                  ; From
270
271         jmp     common
272
273