]> git.sur5r.net Git - cc65/blob - libsrc/c64/dtv-himem.s
Added an extended memory driver for the DTV.
[cc65] / libsrc / c64 / 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         .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 OP_COPYFROM     = %00001101
42 OP_COPYTO       = %00001111
43
44 PAGES           = (2048 - 128) * 4
45
46
47 ; ------------------------------------------------------------------------
48 ; Data.
49
50 .bss
51 window:         .res    256             ; Memory "window"
52
53 .data
54
55 ; The MAP and COMMIT entries will actually call COPYFROM/COPYTO with
56 ; a pointer to the following data structure:
57
58 dma_params:     .word   window          ; Host address
59                 .byte   0               ; Offset in page
60 curpage:        .word   $0000           ; Page
61                 .word   .sizeof (window); # bytes to move, lo, hi
62
63 .code
64
65 ; ------------------------------------------------------------------------
66 ; INSTALL routine. Is called after the driver is loaded into memory. If
67 ; possible, check if the hardware is present and determine the amount of
68 ; memory available.
69 ; Must return an EM_ERR_xx code in a/x.
70 ;
71
72 INSTALL:
73         ldx     #$FF
74         stx     curpage+1               ; Invalidate curpage
75         inx                             ; X = 0
76         txa                             ; A/X = EM_ERR_OK
77         rts
78
79 ; ------------------------------------------------------------------------
80 ; UNINSTALL routine. Is called before the driver is removed from memory.
81 ; Can do cleanup or whatever. Must not return anything.
82 ;
83
84 UNINSTALL:
85         rts
86
87
88 ; ------------------------------------------------------------------------
89 ; PAGECOUNT: Return the total number of available pages in a/x.
90 ;
91
92 PAGECOUNT:
93         lda     #<PAGES
94         ldx     #>PAGES
95         rts
96
97 ; ------------------------------------------------------------------------
98 ; MAP: Map the page in a/x into memory and return a pointer to the page in
99 ; a/x.  The contents of the currently mapped page (if any) may be discarded
100 ; by the driver.
101 ;
102
103 MAP:    sta     curpage
104         stx     curpage+1               ; Remember the new page
105
106         lda     #<dma_params
107         ldx     #>dma_params
108         jsr     COPYFROM                ; Copy data into the window
109
110         lda     #<window
111         ldx     #>window                ; Return the window address
112 done:   rts
113
114 ; ------------------------------------------------------------------------
115 ; USE: Tell the driver that the window is now associated with a given page.
116
117 USE:    sta     curpage
118         stx     curpage+1               ; Remember the page
119         lda     #<window
120         ldx     #>window                ; Return the window
121         rts
122
123 ; ------------------------------------------------------------------------
124 ; COMMIT: Commit changes in the memory window to extended storage.
125
126 COMMIT: lda     curpage+1               ; Do we have a page mapped?
127         bmi     done                    ; Jump if no page mapped
128
129         lda     #<dma_params
130         ldx     #>dma_params
131
132 ; Run into COPYTO
133
134 ; ------------------------------------------------------------------------
135 ; COPYTO: Copy from linear into extended memory. A pointer to a structure
136 ; describing the request is passed in a/x.
137 ; The function must not return anything.
138 ;
139
140 COPYTO: sta     ptr1
141         stx     ptr1+1                  ; Save the pointer
142
143         ldx     #OP_COPYTO              ; Load the command
144         bne     transfer
145
146 ; ------------------------------------------------------------------------
147 ; COPYFROM: Copy from extended into linear memory. A pointer to a structure
148 ; describing the request is passed in a/x.
149 ; The function must not return anything.
150 ;
151
152 COPYFROM:
153         sta     ptr1
154         stx     ptr1+1                  ; Save the pointer
155
156         ldx     #OP_COPYFROM
157
158 ; DTV DMA transfer routine. Expects the command in X.
159
160 transfer:
161         lda     #$01            ; Enable extended features
162         sta     $d03f
163
164 ; Wait until the current DMA operation is finished
165
166         jsr     WAIT
167
168 ; Setup the source address. Carry is clear.
169
170         ldy     #EM_COPY::OFFS
171         lda     (ptr1),y
172         sta     $d300
173         ldy     #EM_COPY::PAGE
174         lda     (ptr1),y
175         sta     $d301
176         iny
177         lda     (ptr1),y
178         adc     #$42            ; Always RAM, start at $20000
179         sta     $d302
180
181 ; Setup the target address
182
183         ldy     #EM_COPY::BUF
184         lda     (ptr1),y
185         sta     $d303
186         iny
187         lda     (ptr1),y
188         sta     $d304
189         lda     #$40            ; Always RAM, start at $00000
190         sta     $d305
191
192 ; Source and target steps
193
194         lda     #$01
195         ldy     #$00
196         sta     $d306
197         sty     $d307
198         sta     $d308
199         sty     $d309
200
201 ; Modulo disable
202
203         sty     $d31e
204
205 ; Length
206
207         ldy     #EM_COPY::COUNT
208         lda     (ptr1),y
209         sta     $d30a
210         iny
211         lda     (ptr1),y
212         sta     $d30b
213
214 ; Start DMA
215
216         stx     $d31f
217
218 ; Wait until DMA finished
219
220         jsr     WAIT
221
222 ; Disable access to the extended registers
223
224         lda     #$00
225         sta     $d03f
226
227         rts
228
229
230 ; ------------------------------------------------------------------------
231 ; Wait until DMA has finished
232
233 WAIT:   lda     $d31f
234         lsr     a
235         bcs     WAIT
236         rts