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