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