]> git.sur5r.net Git - cc65/blob - libsrc/c16/c16-ram.s
8f879095cc9ac94ab0126134b17a136eee365ff4
[cc65] / libsrc / c16 / 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        "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    = $8000
42
43 ; ------------------------------------------------------------------------
44 ; Data.
45
46 .bss
47 pages:          .res    1               ; Number of pages
48 curpage:        .res    1               ; Current page number
49 window:         .res    256             ; Memory "window"
50
51 .code
52
53 ; ------------------------------------------------------------------------
54 ; INSTALL routine. Is called after the driver is loaded into memory. If
55 ; possible, check if the hardware is present and determine the amount of
56 ; memory available.
57 ; Must return an EM_ERR_xx code in a/x.
58 ;
59
60 INSTALL:
61
62 ; Determine how much memory is available. We will use all memory above
63 ; $8000 up to MEMTOP
64
65         sec
66         jsr     $FF99                   ; MEMTOP: Get top memory into Y/X
67         tya
68         sub     #>BASE                  ; Low 32 K are used
69         bcc     nomem
70         beq     nomem                   ; Offering zero pages is a bad idea
71         sta     pages
72
73         ldx     #$FF
74         stx     curpage                 ; Invalidate the current page
75         inx                             ; X = 0
76         txa                             ; A = X = EM_ERR_OK
77         rts
78
79 nomem:  ldx     #>EM_ERR_NO_DEVICE
80         lda     #<EM_ERR_NO_DEVICE
81 ;       rts                             ; Run into UNINSTALL instead
82
83 ; ------------------------------------------------------------------------
84 ; UNINSTALL routine. Is called before the driver is removed from memory.
85 ; Can do cleanup or whatever. Must not return anything.
86 ;
87
88 UNINSTALL:
89         rts
90
91
92 ; ------------------------------------------------------------------------
93 ; PAGECOUNT: Return the total number of available pages in a/x.
94 ;
95
96 PAGECOUNT:
97         lda     pages
98         ldx     #$00                    ; 128 pages max
99         rts
100
101 ; ------------------------------------------------------------------------
102 ; MAP: Map the page in a/x into memory and return a pointer to the page in
103 ; a/x. The contents of the currently mapped page (if any) may be discarded
104 ; by the driver.
105 ;
106
107 MAP:    sta     curpage                 ; Remember the new page
108
109         add     #>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         add     #>BASE
144         sta     ptr2+1
145         ldy     #$00
146         sty     ptr2
147
148         lda     #<window
149         sta     ptr1
150         lda     #>window
151         sta     ptr1+1
152
153 ; Transfer one page. Y must be zero on entry. Because we bank out the
154 ; kernal, we will run the routine with interrupts disabled but leave
155 ; short breath times. Unroll the following loop to make it somewhat faster.
156
157 transfer:
158         sei
159         sta     ENABLE_RAM
160
161         .repeat 8
162         lda     (ptr1),y
163         sta     (ptr2),y
164         iny
165         .endrepeat
166
167         sta     ENABLE_ROM
168         cli
169
170         bne     transfer
171
172 ; Done
173
174 done:   rts
175
176 ; ------------------------------------------------------------------------
177 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
178 ; describing the request is passed in a/x.
179 ; The function must not return anything.
180 ;
181
182 COPYFROM:
183         sta     ptr3
184         stx     ptr3+1                  ; Save the passed em_copy pointer
185
186         ldy     #EM_COPY::OFFS
187         lda     (ptr3),y
188         sta     ptr1
189         ldy     #EM_COPY::PAGE
190         lda     (ptr3),y
191         add     #>BASE
192         sta     ptr1+1                  ; From
193
194         ldy     #EM_COPY::BUF
195         lda     (ptr3),y
196         sta     ptr2
197         iny
198         lda     (ptr3),y
199         sta     ptr2+1                  ; To
200
201 common: ldy     #EM_COPY::COUNT+1
202         lda     (ptr3),y                ; Get number of pages
203         beq     @L2                     ; Skip if no full pages
204         sta     tmp1
205
206 ; Copy full pages allowing interrupts after each page copied
207
208         ldy     #$00
209 @L1:    jsr     transfer
210         inc     ptr1+1
211         inc     ptr2+1
212         dec     tmp1
213         bne     @L1
214
215 ; Copy the remainder of the page
216
217 @L2:    ldy     #EM_COPY::COUNT
218         lda     (ptr3),y                ; Get bytes in last page
219         beq     @L4
220         tax
221
222         sei                             ; Disable ints
223         sta     ENABLE_RAM              ; Bank out the ROM
224
225 ; Transfer the bytes in the last page
226
227         ldy     #$00
228 @L3:    lda     (ptr1),y
229         sta     (ptr2),y
230         iny
231         dex
232         bne     @L3
233
234 ; Restore the old memory configuration, allow interrupts
235
236         sta     ENABLE_ROM
237         cli
238
239 ; Done
240
241 @L4:    rts
242
243 ; ------------------------------------------------------------------------
244 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
245 ; describing the request is passed in a/x.
246 ; The function must not return anything.
247 ;
248
249 COPYTO: sta     ptr3
250         stx     ptr3+1                  ; Save the passed em_copy pointer
251
252         ldy     #EM_COPY::OFFS
253         lda     (ptr3),y
254         sta     ptr2
255         ldy     #EM_COPY::PAGE
256         lda     (ptr3),y
257         add     #>BASE
258         sta     ptr2+1                  ; To
259
260         ldy     #EM_COPY::BUF
261         lda     (ptr3),y
262         sta     ptr1
263         iny
264         lda     (ptr3),y
265         sta     ptr1+1                  ; From
266
267         jmp     common
268
269