]> git.sur5r.net Git - cc65/blob - libsrc/c64/emd/dtv-himem.s
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / libsrc / c64 / emd / dtv-himem.s
1 ;
2 ; Extended memory driver for the C64 D2TV (the second or PAL version).
3 ; Driver works without problems when statically linked.
4 ;
5 ; Ullrich von Bassewitz, 2005-11-27
6 ;
7
8
9         .include        "zeropage.inc"
10
11         .include        "em-kernel.inc"
12         .include        "em-error.inc"
13         .import _get_ostype
14
15
16         .macpack        generic
17
18
19 ; ------------------------------------------------------------------------
20 ; Header. Includes jump table
21
22 .segment        "JUMPTABLE"
23
24 ; Driver signature
25
26         .byte   $65, $6d, $64           ; "emd"
27         .byte   EMD_API_VERSION         ; EM API version number
28
29 ; Jump table.
30
31         .word   INSTALL
32         .word   UNINSTALL
33         .word   PAGECOUNT
34         .word   MAP
35         .word   USE
36         .word   COMMIT
37         .word   COPYFROM
38         .word   COPYTO
39
40 ; ------------------------------------------------------------------------
41 ; Constants
42
43 OP_COPYFROM     = %00001101
44 OP_COPYTO       = %00001111
45
46 START_BANK      = 2                     ; Start at $20000
47 PAGES           = (2048 - 128) * 4
48
49
50 ; ------------------------------------------------------------------------
51 ; Data.
52
53 .bss
54 window:         .res    256             ; Memory "window"
55
56 .data
57
58 ; The MAP and COMMIT entries will actually call COPYFROM/COPYTO with
59 ; a pointer to the following data structure:
60
61 dma_params:     .word   window          ; Host address
62                 .byte   0               ; Offset in page
63 curpage:        .word   $0000           ; Page
64                 .word   .sizeof (window); # bytes to move, lo, hi
65
66 .code
67
68 ; ------------------------------------------------------------------------
69 ; INSTALL routine. Is called after the driver is loaded into memory. If
70 ; possible, check if the hardware is present and determine the amount of
71 ; memory available.
72 ; Must return an EM_ERR_xx code in a/x.
73 ;
74
75 INSTALL:
76
77 ; Check for a DTV
78
79         ldx     #1
80         stx     $d03f
81         ldx     $d040
82         cpx     $d000
83         bne     @present
84         inc     $d000
85         cpx     $d040
86         beq     @present
87         dec     $d000
88
89 ; DTV not found
90
91         lda     #<EM_ERR_NO_DEVICE
92         ldx     #>EM_ERR_NO_DEVICE
93         rts
94
95 @present:
96         ldx     #$FF
97         stx     curpage+1               ; Invalidate curpage
98         inx                             ; X = 0
99         txa                             ; A/X = EM_ERR_OK
100
101 ;       rts                             ; Run into UNINSTALL instead
102
103 ; ------------------------------------------------------------------------
104 ; UNINSTALL routine. Is called before the driver is removed from memory.
105 ; Can do cleanup or whatever. Must not return anything.
106 ;
107
108 UNINSTALL:
109         rts
110
111 ; ------------------------------------------------------------------------
112 ; PAGECOUNT: Return the total number of available pages in a/x.
113 ;
114
115 PAGECOUNT:
116         lda     #<PAGES
117         ldx     #>PAGES
118         rts
119
120 ; ------------------------------------------------------------------------
121 ; MAP: Map the page in a/x into memory and return a pointer to the page in
122 ; a/x.  The contents of the currently mapped page (if any) may be discarded
123 ; by the driver.
124 ;
125
126 MAP:    sta     curpage
127         stx     curpage+1               ; Remember the new page
128
129         lda     #<dma_params
130         ldx     #>dma_params
131         jsr     COPYFROM                ; Copy data into the window
132
133         lda     #<window
134         ldx     #>window                ; Return the window address
135 done:   rts
136
137 ; ------------------------------------------------------------------------
138 ; USE: Tell the driver that the window is now associated with a given page.
139
140 USE:    sta     curpage
141         stx     curpage+1               ; Remember the page
142         lda     #<window
143         ldx     #>window                ; Return the window
144         rts
145
146 ; ------------------------------------------------------------------------
147 ; COMMIT: Commit changes in the memory window to extended storage.
148
149 COMMIT: lda     curpage+1               ; Do we have a page mapped?
150         bmi     done                    ; Jump if no page mapped
151
152         lda     #<dma_params
153         ldx     #>dma_params
154
155 ; Run into COPYTO
156
157 ; ------------------------------------------------------------------------
158 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
159 ; describing the request is passed in a/x.
160 ; The function must not return anything.
161 ;
162
163 COPYTO: sta     ptr1
164         stx     ptr1+1                  ; Save the pointer
165
166         ldx     #OP_COPYTO              ; Load the command
167         bne     transfer
168
169 ; ------------------------------------------------------------------------
170 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
171 ; describing the request is passed in a/x.
172 ; The function must not return anything.
173 ;
174
175 COPYFROM:
176         sta     ptr1
177         stx     ptr1+1                  ; Save the pointer
178
179         ldx     #OP_COPYFROM
180
181 ; DTV DMA transfer routine. Expects the command in X.
182 ; NOTE: We're using knowledge about field order in the EM_COPY struct here!
183
184 transfer:
185         jsr     WAIT                    ; Wait until DMA is finished
186
187 ; Modulo disable
188
189         ldy     #$00
190         sty     $d31e
191
192 ; Setup the target address and the source and target steps. Y contains zero,
193 ; which is EM_COPY::BUF.
194
195         sty     $d307                   ; Source step high = 0
196         sty     $d309                   ; Dest step high = 0
197         lda     (ptr1),y
198         sta     $d303                   ; Dest address low
199         iny                             ; Y = 1
200         sty     $d306                   ; Source step low = 1
201         sty     $d308                   ; Dest step low = 1
202         lda     (ptr1),y
203         sta     $d304
204         lda     #$40                    ; Dest is always RAM, start at $00000
205         sta     $d305
206
207 ; Setup the source address. Incrementing Y will make it point to EM_COPY::OFFS.
208 ; We will allow page numbers higher than PAGES and map them to ROM. This will
209 ; allow reading the ROM by specifying a page starting with PAGES.
210
211         iny                             ; EM_COPY::OFFS
212         lda     (ptr1),y
213         sta     $d300
214         iny                             ; EM_COPY::PAGE
215         lda     (ptr1),y
216         sta     $d301
217         iny
218         lda     (ptr1),y
219         adc     #START_BANK             ; Carry clear here from WAIT
220         and     #$3f
221         cmp     #>PAGES+START_BANK      ; Valid range?
222         bcs     @L1                     ; Jump if no
223         ora     #$40                    ; Address RAM
224 @L1:    sta     $d302
225
226 ; Length
227
228         iny                             ; EM_COPY::COUNT
229         lda     (ptr1),y
230         sta     $d30a
231         iny
232         lda     (ptr1),y
233         sta     $d30b
234
235 ; Start DMA
236
237         stx     $d31f
238
239 ; Wait until DMA is done
240
241 WAIT:   lda     $d31f
242         lsr     a
243         bcs     WAIT
244         rts
245