]> git.sur5r.net Git - cc65/blob - libsrc/atari/emd/atr130xe.s
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / libsrc / atari / emd / atr130xe.s
1 ;
2 ; Extended memory driver for the Atari 130XE memory standard
3 ; Shawn Jefferson, 2012-08-11
4 ;
5 ; Banking Register $D301:
6 ; Bit 7: Self-Test on/off
7 ; Bit 6: Unused
8 ; Bit 5: Antic sees bank
9 ; Bit 4: CPU sees bank
10 ; Bit 3: bank control
11 ; Bit 2: bank control
12 ; Bit 1: BASIC on/off
13 ; Bit 0: OS RAM on/off
14
15 ; Masks: %11100011  $E3     Bank 0
16 ;        %11100111  $E7     Bank 1
17 ;        %11101011  $EB     Bank 2
18 ;        %11101111  $EF     Bank 3
19 ;        %11111111  $FF     Off
20 ;
21 ; Based on the Extended memory driver for the Apple II auxiliary memory
22 ;  by
23 ; Stefan Haubenthal, 2003-12-12
24 ; Ullrich von Bassewitz, 2002-12-02
25 ;
26
27         .include        "zeropage.inc"
28
29         .include        "em-kernel.inc"
30         .include        "em-error.inc"
31
32
33         .macpack        generic
34
35
36 ; ------------------------------------------------------------------------
37 ; Header. Includes jump table
38
39 .segment        "JUMPTABLE"
40
41 ; Driver signature
42
43         .byte   $65, $6d, $64           ; "emd"
44         .byte   EMD_API_VERSION         ; EM API version number
45
46 ; Jump table.
47
48         .word   INSTALL
49         .word   DEINSTALL
50         .word   PAGECOUNT
51         .word   MAP
52         .word   USE
53         .word   COMMIT
54         .word   COPYFROM
55         .word   COPYTO
56
57 ; ------------------------------------------------------------------------
58 ; Constants
59
60 BANK    = $4000                         ; bank window
61 STACK   = $0100                         ; stack location 
62 PAGES   = 256                           ; 4 x 16k banks
63
64
65 ; ------------------------------------------------------------------------
66 ; Data.
67
68 .rodata
69 banks:          .byte $E3,$E7,$EB,$EF   ; 130XE banks for cpu banking
70
71 stacktest:      sei
72                 ldy banks
73                 sty $D301
74                 tax                     ; A is set by caller
75                 inx
76                 stx $4000               ; change $4000
77                 ldy #$FF                ; STACK+13
78                 sty $D301
79                 cmp $4000               ; changed?
80                 beq @1
81                 sec                     ; error
82                 bcs @2
83 @1:             clc
84 @2:             sta $4000               ; restore
85                 cli
86                 rts
87 stacktest_end: 
88
89 stackcopy:      sei                     ; disable interrupts
90 @1:             dex                     ; pre-decrement (full page x=0)
91                 ldy #$FF                ; this will be replaced  STACK+3
92                 sty $D301               ; set bank 
93                 lda $FF00,x             ; address to copy from   STACK+8,+9
94                 ldy #$FF                ; this will be replaced  STACK+11
95                 sty $D301 
96                 sta $FF00,x             ; address to copy to     STACK+16,+17
97                 cpx #0 
98                 bne @1
99                 ldy #$FF                ; portb_save             STACK+23
100                 sty $D301
101                 cli                     ; enable interrupts
102                 rts
103 stackcopy_end:
104
105 stackcopy_byte: sei
106                 ldy #$FF                ; STACK+2
107                 sty $D301
108                 lda $FFFF               ; STACK+7 +8
109                 ldy #$FF                ; STACK+10
110                 sty $D301
111                 sta $FFFF               ; STACK+15 +16
112                 ldy #$FF                ; STACK+18
113                 sty $D301
114                 cli
115                 rts
116 stackcopy_byte_end: 
117
118
119 .data
120 curpage:        .byte   $FF             ; Current page number in bank (invalid)
121 curbank:        .byte   $FF             ; Current bank number
122
123 .bss
124 window:         .res    256             ; Memory "window"
125 portb_save:     .res    1               ; portb state
126
127 .code
128
129 install_transfer:
130                 ldx #stackcopy_end - stackcopy - 1
131 @1:             lda stackcopy,x
132                 sta STACK,x
133                 dex
134                 bpl @1
135                 rts
136
137 install_byte_transfer:
138                 ldx #stackcopy_byte_end - stackcopy_byte - 1
139 @2:             lda stackcopy_byte,x
140                 sta STACK,x
141                 dex
142                 bpl @2
143                 rts
144
145 install_test:
146                 ldx #stacktest_end - stacktest - 1
147 @3:             lda stacktest,x
148                 sta STACK,x
149                 dex
150                 bpl @3
151                 rts
152
153 setpage:
154                 tax                             ; save page
155                 and     #$C0                    ; mask out bank
156                 clc
157                 ror
158                 ror                             ; divide by 64
159                 ror                             ; 64 pages in each bank
160                 ror
161                 ror
162                 ror
163                 sta     curbank                 ; Remember the new bank
164                 txa                             ; bring back page
165                 and     #$3F                    ; mask out page
166                 sta     curpage                 ; curpage in bank
167                 rts
168
169
170 ; ------------------------------------------------------------------------
171 ; INSTALL routine. Is called after the driver is loaded into memory. If
172 ; possible, check if the hardware is present and determine the amount of
173 ; memory available.
174 ; Must return an EM_ERR_xx code in a/x.
175 ;
176
177 INSTALL:
178         lda     $D301                   ; save state of portb
179         sta     portb_save
180         tay 
181
182         jsr     install_test            ; doesn't touch Y
183         sty     STACK+13
184
185         lda     $4000                   ; test for extended memory
186         jsr     STACK
187         bcs     @1 
188         lda     #EM_ERR_OK
189         rts
190 @1:     lda     #EM_ERR_NO_DEVICE
191         rts
192
193 ; ------------------------------------------------------------------------
194 ; DEINSTALL routine. Is called before the driver is removed from memory.
195 ; Can do cleanup or whatever. Must not return anything.
196 ;
197
198 DEINSTALL:
199         rts
200
201
202 ; ------------------------------------------------------------------------
203 ; PAGECOUNT: Return the total number of available pages in a/x.
204 ;
205
206 PAGECOUNT:
207         lda     #<PAGES
208         ldx     #>PAGES
209         rts
210
211 ; ------------------------------------------------------------------------
212 ; MAP: Map the page in a/x into memory and return a pointer to the page in
213 ; a/x. The contents of the currently mapped page (if any) may be discarded
214 ; by the driver.
215 ;
216
217 MAP:    jsr setpage                     ; extract the bank/page
218         add     #>BANK                  ; $4000 + page  (carry is cleared)
219         sta     ptr1+1
220         ;ldy     #$00
221         ;sty     ptr1
222
223         lda     #<window
224         sta     ptr2
225         lda     #>window
226         sta     ptr2+1
227
228 ; Transfer one page
229
230         jsr     install_transfer        ; Transfer one page
231
232         ldx     curbank
233         lda     banks,x
234         sta     STACK+3                 ; set bank to copy from
235 ;        lda     ptr1
236 ;        sta     STACK+8 
237         lda     ptr1+1
238         sta     STACK+9                 ; set copy from address
239         lda     portb_save
240         sta     STACK+11                ; set portb restore
241         sta     STACK+23                ; set final portb restore
242         lda     ptr2
243         sta     STACK+16
244         lda     ptr2+1
245         sta     STACK+17                ; set copy to address 
246
247         ldx     #0                      ; full page copy
248         jsr     STACK                   ; do the copy! 
249
250 ; Return the memory window
251
252         lda     #<window
253         ldx     #>window                ; Return the window address
254
255         rts
256
257 ; ------------------------------------------------------------------------
258 ; USE: Tell the driver that the window is now associated with a given page.
259
260 USE:    ;sta     curpage                 ; Remember the page
261         jsr setpage                     ; extract bank/page
262         lda     #<window
263         ldx     #>window                ; Return the window
264         rts
265
266 ; ------------------------------------------------------------------------
267 ; COMMIT: Commit changes in the memory window to extended storage.
268
269 COMMIT: lda     curpage                 ; Get the current page
270         cmp     #$FF
271         beq     commit_done             ; Jump if no page mapped
272
273         clc
274         add     #>BANK
275         sta     ptr2+1
276         ;ldy     #$00
277         ;sty     ptr2
278
279         lda     #<window
280         sta     ptr1
281         lda     #>window
282         sta     ptr1+1
283
284 ; Transfer one page/all bytes
285
286         jsr     install_transfer        ; Transfer one page
287
288         lda     portb_save
289         sta     STACK+3                 ; set bank to copy from
290         sta     STACK+23                ; set final portb restore
291         lda     ptr1
292         sta     STACK+8 
293         lda     ptr1+1
294         sta     STACK+9                 ; set copy from address
295         ldx     curbank
296         lda     banks,x
297         sta     STACK+11                ; set bank to copy to
298         ;lda     ptr2
299         ;sta     STACK+16
300         lda     ptr2+1
301         sta     STACK+17                ; set copy to address 
302
303         ldx     #0                      ; full page copy
304         jsr     STACK                   ; do the copy! 
305
306 commit_done:
307         rts
308
309
310 ; ------------------------------------------------------------------------
311 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
312 ; describing the request is passed in a/x.
313 ; The function must not return anything.
314 ;
315 COPYFROM:
316         sta     ptr3
317         stx     ptr3+1                  ; Save the passed em_copy pointer
318
319         jsr     install_byte_transfer   ; install the stack copy routine
320
321         ldy     #EM_COPY::OFFS
322         lda     (ptr3),y
323         sta     STACK+7                 ; offset goes into BANK low 
324
325         ldy     #EM_COPY::PAGE
326         lda     (ptr3),y
327         sta     tmp1                    ; save page for later
328         ;add     #>BANK
329         ;sta     STACK+8                 ; BANK + page goes into BANK high
330
331         ldy     #EM_COPY::BUF
332         lda     (ptr3),y
333         sta     STACK+15                ; buffer goes into dest low
334         iny
335         lda     (ptr3),y
336         sta     STACK+16                ; buffer goes into dest high
337
338         ldy     #EM_COPY::COUNT
339         lda     (ptr3),y                ; Get bytes in last page
340         sta     ptr4
341         iny
342         lda     (ptr3),y                ; Get number of pages
343         sta     ptr4+1
344
345         lda     tmp1                    ; extract bank/page
346         jsr     setpage                 ; sets curbank/curpage
347         lda     curpage
348         add     #>BANK                  ; add to BANK address
349         sta     STACK+8                 ; current page in bank
350         ldx     curbank
351         lda     banks,x 
352         sta     STACK+2                 ; set bank in stack 
353         lda     portb_save 
354         sta     STACK+10                ; set bank restore in stack
355         sta     STACK+18                ; set final restore too
356
357 copyfrom_copy:
358         lda     ptr4                    ; check if count is zero
359         bne     @4
360         lda     ptr4+1
361         beq     done
362
363 @4:     jsr     STACK                   ; copy one byte
364
365         sec
366         lda     ptr4
367         sub     #1
368         sta     ptr4
369         bcs     @1
370         lda     ptr4+1
371         beq     @1
372         sub     #1
373         sta     ptr4+1
374
375 @1:     inc     STACK+7                 ; increment address in BANK
376         bne     @2
377         inc     STACK+8
378         lda     STACK+8
379         cmp     #$80                    ; we stepped outside bank
380         bne     @2
381
382         inc     curbank                 ; get next bank
383         ldx     curbank
384         lda     banks,x
385         sta     STACK+2                 ; set new bank
386         lda     #$40                    ; set address back to $4000
387         sta     STACK+8
388
389 @2:     inc     STACK+15                ; increment buffer address
390         bne     @3
391         inc     STACK+16
392
393 @3:     jmp     copyfrom_copy           ; copy another byte 
394
395 done:
396         rts
397
398 ; ------------------------------------------------------------------------
399 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
400 ; describing the request is passed in a/x.
401 ; The function must not return anything.
402 ;
403
404 COPYTO:
405         sta     ptr3
406         stx     ptr3+1                  ; Save the passed em_copy pointer
407
408         jsr     install_byte_transfer   ; install the stack copy routine
409
410         ldy     #EM_COPY::OFFS
411         lda     (ptr3),y
412         sta     STACK+15                 ; offset goes into BANK low 
413
414         ldy     #EM_COPY::PAGE
415         lda     (ptr3),y
416         sta     tmp1                    ; save page for later
417         ;add     #>BANK
418         ;sta     STACK+16                ; BANK + page goes into BANK high
419
420         ldy     #EM_COPY::BUF
421         lda     (ptr3),y
422         sta     STACK+7                ; buffer goes into dest low
423         iny
424         lda     (ptr3),y
425         sta     STACK+8                ; buffer goes into dest high
426
427         ldy     #EM_COPY::COUNT
428         lda     (ptr3),y                ; Get bytes in last page
429         sta     ptr4
430         iny
431         lda     (ptr3),y                ; Get number of pages
432         sta     ptr4+1
433
434         lda     tmp1                    ; extract bank/page
435         jsr     setpage                 ; sets curbank/curpage
436         lda     curpage
437         add     #>BANK                  ; add to BANK address
438         sta     STACK+16                ; current page in bank
439         ldx     curbank
440         lda     banks,x 
441         sta     STACK+10                ; set bank in stack 
442         lda     portb_save 
443         sta     STACK+2                 ; set bank restore in stack
444         sta     STACK+18                ; set final restore too
445
446 copyto_copy:
447         lda     ptr4                    ; check if count is zero
448         bne     @4
449         lda     ptr4+1
450         beq     done
451
452 @4:     jsr     STACK                   ; copy one byte
453
454         sec
455         lda     ptr4
456         sub     #1
457         sta     ptr4
458         bcs     @1
459         lda     ptr4+1
460         beq     @1
461         sub     #1
462         sta     ptr4+1
463
464 @1:     inc     STACK+15               ; increment address in BANK
465         bne     @2
466         inc     STACK+16
467         lda     STACK+16
468         cmp     #$80                    ; we stepped outside bank
469         bne     @2
470
471         inc     curbank                 ; get next bank
472         ldx     curbank
473         lda     banks,x
474         sta     STACK+10                ; set new bank
475         lda     #$40                    ; set address back to $4000
476         sta     STACK+16
477
478 @2:     inc     STACK+7                ; increment buffer address
479         bne     @3
480         inc     STACK+8
481
482 @3:     jmp     copyto_copy           ; copy another byte 
483