]> git.sur5r.net Git - cc65/blob - libsrc/c64/emd/c64-reu.s
bf7bb4fb0cb6f02d732bb7553d4d2401e116b571
[cc65] / libsrc / c64 / emd / c64-reu.s
1 ;
2 ; Extended memory driver for the Commodore REU. Driver works without
3 ; problems when statically linked.
4 ;
5 ; Ullrich von Bassewitz, 2002-11-29
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   _c64_reu_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 REU_STATUS      = $DF00                 ; Status register
47 REU_COMMAND     = $DF01                 ; Command register
48 REU_C64ADDR     = $DF02                 ; C64 base address register
49 REU_REUADDR     = $DF04                 ; REU base address register
50 REU_COUNT       = $DF07                 ; Transfer count register
51 REU_IRQMASK     = $DF09                 ; IRQ mask register
52 REU_CONTROL     = $DF0A                 ; Control register
53 REU_TRIGGER     = $FF00                 ; REU command trigger
54
55 OP_COPYFROM     = $ED
56 OP_COPYTO       = $EC
57
58 OP_COPYFROM_ALOAD = $B1
59 OP_COPYTO_ALOAD   = $B0
60
61
62 ; ------------------------------------------------------------------------
63 ; Data.
64
65 .bss
66 pagecount:      .res    2               ; Number of pages available
67 curpage:        .res    2               ; Current page number
68
69 window:         .res    256             ; Memory "window"
70
71 reu_params:     .word   $0000           ; Host address, lo, hi
72                 .word   $0000           ; Exp  address, lo, hi
73                 .byte   $00             ; Expansion  bank no.
74                 .word   $0000           ; # bytes to move, lo, hi
75                 .byte   $00             ; Interrupt mask reg.
76                 .byte   $00             ; Adress control reg.
77
78 .code
79
80 ; ------------------------------------------------------------------------
81 ; INSTALL routine. Is called after the driver is loaded into memory. If
82 ; possible, check if the hardware is present and determine the amount of
83 ; memory available.
84 ; Must return an EM_ERR_xx code in a/x.
85 ;
86
87 INSTALL:
88         ldx     #$00                    ; High byte of return code
89         lda     #$55
90         sta     REU_REUADDR
91         cmp     REU_REUADDR             ; Check for presence of REU
92         bne     nodevice
93         asl     a                       ; A = $AA
94         sta     REU_REUADDR
95         cmp     REU_REUADDR             ; Check for presence of REU
96         bne     nodevice
97
98 ; determine the size
99         php
100         sei
101         ldy     #$FF
102 loop:
103         sty     window
104         jsr     reu_size_check_common
105         ldx     #OP_COPYTO_ALOAD
106         stx     REU_COMMAND
107         dey
108         cpy     #$FF
109         bne     loop
110         iny
111 size_loop:
112         jsr     reu_size_check_common
113         ldx     #OP_COPYFROM_ALOAD
114         stx     REU_COMMAND
115         cpy     window
116         bne     size_found
117         iny
118         bne     size_loop
119 size_found:
120         plp
121         ldx     #$00
122         cpy     #$00                    ; too many pages, shave off 2
123         bne     pagecount_ok
124         dex
125         dex
126         dey
127 pagecount_ok:
128         stx     pagecount
129         sty     pagecount+1
130         lda     #<EM_ERR_OK
131         ldx     #>EM_ERR_OK
132         rts
133
134 ; common REU setup for size check
135 reu_size_check_common:
136         sty     REU_REUADDR+2
137         ldx     #<window
138         stx     REU_C64ADDR
139         ldx     #>window
140         stx     REU_C64ADDR+1
141         ldx     #$00
142         stx     REU_REUADDR
143         stx     REU_REUADDR+1
144         stx     REU_COUNT+1
145         stx     REU_CONTROL
146         inx
147         stx     REU_COUNT
148         rts
149
150
151 ; No REU found
152
153 nodevice:
154         lda     #EM_ERR_NO_DEVICE
155 ;       rts                             ; Run into UNINSTALL instead
156
157 ; ------------------------------------------------------------------------
158 ; UNINSTALL routine. Is called before the driver is removed from memory.
159 ; Can do cleanup or whatever. Must not return anything.
160 ;
161
162 UNINSTALL:
163         rts
164
165
166 ; ------------------------------------------------------------------------
167 ; PAGECOUNT: Return the total number of available pages in a/x.
168 ;
169
170 PAGECOUNT:
171         lda     pagecount
172         ldx     pagecount+1
173         rts
174
175 ; ------------------------------------------------------------------------
176 ; MAP: Map the page in a/x into memory and return a pointer to the page in
177 ; a/x.  The contents of the currently mapped page (if any) may be discarded
178 ; by the driver.
179 ;
180
181 MAP:    sta     curpage
182         stx     curpage+1               ; Remember the new page
183
184         ldy     #OP_COPYFROM
185         jsr     common                  ; Copy the window
186
187         lda     #<window
188         ldx     #>window                ; Return the window address
189 done:   rts
190
191 ; ------------------------------------------------------------------------
192 ; USE: Tell the driver that the window is now associated with a given page.
193                                         
194 USE:    sta     curpage
195         stx     curpage+1               ; Remember the page
196         lda     #<window
197         ldx     #>window                ; Return the window
198         rts
199
200 ; ------------------------------------------------------------------------
201 ; COMMIT: Commit changes in the memory window to extended storage.
202
203 COMMIT: lda     curpage
204         ldx     curpage+1               ; Do we have a page mapped?
205         bmi     done                    ; Jump if no page mapped
206
207         ldy     #OP_COPYTO
208 common: sty     tmp1
209
210         ldy     #<window
211         sty     REU_C64ADDR
212         ldy     #>window
213         sty     REU_C64ADDR+1
214
215         ldy     #0
216         sty     REU_REUADDR+0
217         sta     REU_REUADDR+1
218         stx     REU_REUADDR+2
219
220         sty     REU_COUNT+0
221         ldy     #1
222         sty     REU_COUNT+1             ; Move 256 bytes
223         bne     transfer1               ; Transfer 256 bytes into REU
224
225 ; ------------------------------------------------------------------------
226 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
227 ; describing the request is passed in a/x.
228 ; The function must not return anything.
229 ;
230
231 COPYFROM:
232         ldy     #OP_COPYFROM
233         .byte   $2C
234
235 ; ------------------------------------------------------------------------
236 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
237 ; describing the request is passed in a/x.
238 ; The function must not return anything.
239 ;
240
241 COPYTO:
242         ldy     #OP_COPYTO
243         sty     tmp1
244
245 ; Remember the passed pointer
246
247         sta     ptr1
248         stx     ptr1+1          ; Save the pointer
249
250 ; The structure passed to the functions has the same layout as the registers
251 ; of the Commodore REU, so register programming is easy.
252
253         ldy     #7-1
254 @L1:    lda     (ptr1),y
255         sta     REU_C64ADDR,y
256         dey
257         bpl     @L1
258
259 ; Invalidate the page in the memory window
260
261         sty     curpage+1       ; Y = $FF
262
263 ; Reload the REU command and start the transfer
264
265 transfer1:
266         ldy     tmp1
267
268 ; Transfer subroutine for the REU. Expects command in Y.
269
270 transfer:
271         sty     REU_COMMAND     ; Issue command
272
273         ldy     $01             ; Save the value of the c64 control port...
274         tya                     ;
275         and     #$F8            ; Disable ROMs and I/O.
276         sei                     ;
277         sta     $01
278         lda     REU_TRIGGER     ; Don't change $FF00
279         sta     REU_TRIGGER     ; Start the transfer...
280
281         sty     $01             ; Restore the old configuration
282         cli
283         rts
284