]> git.sur5r.net Git - cc65/blob - libsrc/c64/emd/c64-reu.s
Merge pull request #504 from jedeoric/master
[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
59 ; ------------------------------------------------------------------------
60 ; Data.
61
62 .bss
63 pagecount:      .res    2               ; Number of pages available
64 curpage:        .res    2               ; Current page number
65
66 window:         .res    256             ; Memory "window"
67
68 reu_params:     .word   $0000           ; Host address, lo, hi
69                 .word   $0000           ; Exp  address, lo, hi
70                 .byte   $00             ; Expansion  bank no.
71                 .word   $0000           ; # bytes to move, lo, hi
72                 .byte   $00             ; Interrupt mask reg.
73                 .byte   $00             ; Adress control reg.
74
75 .code
76
77 ; ------------------------------------------------------------------------
78 ; INSTALL routine. Is called after the driver is loaded into memory. If
79 ; possible, check if the hardware is present and determine the amount of
80 ; memory available.
81 ; Must return an EM_ERR_xx code in a/x.
82 ;
83
84 INSTALL:
85         ldx     #$00                    ; High byte of return code
86         lda     #$55
87         sta     REU_REUADDR
88         cmp     REU_REUADDR             ; Check for presence of REU
89         bne     nodevice
90         asl     a                       ; A = $AA
91         sta     REU_REUADDR
92         cmp     REU_REUADDR             ; Check for presence of REU
93         bne     nodevice
94
95         ldy     #>(128*4)               ; Assume 128KB
96         lda     REU_STATUS
97         and     #$10                    ; Check size bit
98         beq     @L1
99         ldy     #>(256*4)               ; 256KB when size bit is set
100 @L1:    sty     pagecount+1
101
102         ldy     #$FF
103         sty     curpage
104         sty     curpage+1               ; Invalidate the current page
105         txa                             ; X = A = EM_ERR_OK
106         rts
107
108 ; No REU found
109
110 nodevice:
111         lda     #EM_ERR_NO_DEVICE
112 ;       rts                             ; Run into UNINSTALL instead
113
114 ; ------------------------------------------------------------------------
115 ; UNINSTALL routine. Is called before the driver is removed from memory.
116 ; Can do cleanup or whatever. Must not return anything.
117 ;
118
119 UNINSTALL:
120         rts
121
122
123 ; ------------------------------------------------------------------------
124 ; PAGECOUNT: Return the total number of available pages in a/x.
125 ;
126
127 PAGECOUNT:
128         lda     pagecount
129         ldx     pagecount+1
130         rts
131
132 ; ------------------------------------------------------------------------
133 ; MAP: Map the page in a/x into memory and return a pointer to the page in
134 ; a/x.  The contents of the currently mapped page (if any) may be discarded
135 ; by the driver.
136 ;
137
138 MAP:    sta     curpage
139         stx     curpage+1               ; Remember the new page
140
141         ldy     #OP_COPYFROM
142         jsr     common                  ; Copy the window
143
144         lda     #<window
145         ldx     #>window                ; Return the window address
146 done:   rts
147
148 ; ------------------------------------------------------------------------
149 ; USE: Tell the driver that the window is now associated with a given page.
150                                         
151 USE:    sta     curpage
152         stx     curpage+1               ; Remember the page
153         lda     #<window
154         ldx     #>window                ; Return the window
155         rts
156
157 ; ------------------------------------------------------------------------
158 ; COMMIT: Commit changes in the memory window to extended storage.
159
160 COMMIT: lda     curpage
161         ldx     curpage+1               ; Do we have a page mapped?
162         bmi     done                    ; Jump if no page mapped
163
164         ldy     #OP_COPYTO
165 common: sty     tmp1
166
167         ldy     #<window
168         sty     REU_C64ADDR
169         ldy     #>window
170         sty     REU_C64ADDR+1
171
172         ldy     #0
173         sty     REU_REUADDR+0
174         sta     REU_REUADDR+1
175         stx     REU_REUADDR+2
176
177         sty     REU_COUNT+0
178         ldy     #1
179         sty     REU_COUNT+1             ; Move 256 bytes
180         bne     transfer1               ; Transfer 256 bytes into REU
181
182 ; ------------------------------------------------------------------------
183 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
184 ; describing the request is passed in a/x.
185 ; The function must not return anything.
186 ;
187
188 COPYFROM:
189         ldy     #OP_COPYFROM
190         .byte   $2C
191
192 ; ------------------------------------------------------------------------
193 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
194 ; describing the request is passed in a/x.
195 ; The function must not return anything.
196 ;
197
198 COPYTO:
199         ldy     #OP_COPYTO
200         sty     tmp1
201
202 ; Remember the passed pointer
203
204         sta     ptr1
205         stx     ptr1+1          ; Save the pointer
206
207 ; The structure passed to the functions has the same layout as the registers
208 ; of the Commodore REU, so register programming is easy.
209
210         ldy     #7-1
211 @L1:    lda     (ptr1),y
212         sta     REU_C64ADDR,y
213         dey
214         bpl     @L1
215
216 ; Invalidate the page in the memory window
217
218         sty     curpage+1       ; Y = $FF
219
220 ; Reload the REU command and start the transfer
221
222 transfer1:
223         ldy     tmp1
224
225 ; Transfer subroutine for the REU. Expects command in Y.
226
227 transfer:
228         sty     REU_COMMAND     ; Issue command
229
230         ldy     $01             ; Save the value of the c64 control port...
231         tya                     ;
232         and     #$F8            ; Disable ROMs and I/O.
233         sei                     ;
234         sta     $01
235         lda     REU_TRIGGER     ; Don't change $FF00
236         sta     REU_TRIGGER     ; Start the transfer...
237
238         sty     $01             ; Restore the old configuration
239         cli
240         rts
241