]> git.sur5r.net Git - cc65/blob - libsrc/atari/shadow_ram_prepare.s
some debug messages ".ifdef DEBUG"
[cc65] / libsrc / atari / shadow_ram_prepare.s
1 ;
2 ; Atari XL shadow RAM preparation routines
3 ;
4 ; Tasks:
5 ; - move screen memory below load address
6 ; - copy ROM chargen to its new place
7 ; - copy shadow RAM contents to their destination
8 ;
9 ; Christian Groessler, chris@groessler.org, 2013
10 ;
11
12 DEBUG   =       1
13
14 .if .defined(__ATARIXL__)
15
16         .export         sramprep
17         .import         __SRPREP_LOAD__, __SRPREP_SIZE__
18         .import         __SHADOW_RAM_LOAD__, __SHADOW_RAM_SIZE__
19         .import         __SHADOW_RAM_RUN__
20         .import         __CHARGEN_START__, __CHARGEN_SIZE__
21         .import         __SAVEAREA_LOAD__
22         .import         zpsave
23
24         .include        "zeropage.inc"
25         .include        "atari.inc"
26         .include        "save_area.inc"
27
28 .macro print_string text
29         .local  start, cont
30         jmp     cont
31 start:  .byte   text, ATEOL
32 cont:   ldx     #0              ; channel 0
33         lda     #<start
34         sta     ICBAL,x         ; address
35         lda     #>start
36         sta     ICBAH,x
37         lda     #<(cont - start)
38         sta     ICBLL,x         ; length
39         lda     #>(cont - start)
40         sta     ICBLH,x
41         lda     #PUTCHR
42         sta     ICCOM,x
43         jsr     CIOV_org
44 .endmacro
45
46 ; ------------------------------------------------------------------------
47 ; Chunk header
48
49 .segment        "SRPREPHDR"
50
51         .word   __SRPREP_LOAD__
52         .word   __SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__ - 1
53
54 ; ------------------------------------------------------------------------
55 ; Actual code
56
57 .segment        "SRPREP"
58
59 sramprep:
60         print_string "in sramprep"
61
62 ; save values of modified system variables and ports
63
64         lda     RAMTOP
65         sta     RAMTOP_save
66         lda     MEMTOP
67         sta     MEMTOP_save
68         lda     MEMTOP+1
69         sta     MEMTOP_save+1
70         lda     APPMHI
71         sta     APPMHI_save
72         lda     APPMHI+1
73         sta     APPMHI_save+1
74         lda     PORTB
75         sta     PORTB_save
76         lda     CIOV            ; zero-page wrapper
77         sta     ZP_CIOV_save
78         lda     CIOV+1
79         sta     ZP_CIOV_save+1
80         lda     CIOV+2
81         sta     ZP_CIOV_save+2
82         lda     SIOV            ; zero-page wrapper
83         sta     ZP_SIOV_save
84         lda     SIOV+1
85         sta     ZP_SIOV_save+1
86         lda     SIOV+2
87         sta     ZP_SIOV_save+2
88
89         lda     $fffe
90         sta     IRQ_save
91         lda     $ffff
92         sta     IRQ_save+1
93         lda     $fffc
94         sta     RESET_save
95         lda     $fffd
96         sta     RESET_save+1
97         lda     $fffa
98         sta     NMI_save
99         lda     $fffb
100         sta     NMI_save+1
101
102 ; disable BASIC
103
104         lda     PORTB
105         ora     #2
106         sta     PORTB
107
108
109 ; ... change system memory variables bla
110
111 CMPVAL = 64+255+992             ; you may ask, why these values...   @@@ document
112
113 sys_ok: lda     #<__SAVEAREA_LOAD__
114         sec
115         sbc     #<CMPVAL
116         sta     MEMTOP
117         sta     APPMHI
118         lda     #>__SAVEAREA_LOAD__
119         sbc     #>CMPVAL
120         sta     MEMTOP+1
121         sta     APPMHI+1
122
123         lda     #>__SAVEAREA_LOAD__ - 1
124         sta     RAMTOP
125
126
127
128 ; ... issue a GRAPHICS 0 call (copied'n'pasted from TGI drivers)
129
130
131         ldx     #$50            ; take any IOCB, hopefully free (@@@ fixme)
132
133         ; Reopen it in Graphics 0
134         lda     #OPEN
135         sta     ICCOM,x
136         lda     #OPNIN | OPNOT
137         sta     ICAX1,x
138         lda     #0
139         sta     ICAX2,x
140         lda     #<screen_device
141         sta     ICBAL,x
142         lda     #>screen_device
143         sta     ICBAH,x
144         lda     #<screen_device_length
145         sta     ICBLL,x
146         lda     #>screen_device_length
147         sta     ICBLH,x
148         jsr     CIOV_org
149         bpl     okoko
150
151         print_string "GR 0 FAILED"
152         jsr     delay
153         jsr     delay
154         jsr     delay
155
156         jmp     (DOSVEC)                ; abort loading
157
158
159 okoko:
160
161
162         ; Now close it again; we don't need it anymore :)
163         lda     #CLOSE
164         sta     ICCOM,x
165         jsr     CIOV_org
166
167 .ifdef DEBUG
168         print_string "Stage #2 OK"
169         jsr     delay
170 .endif
171
172
173 ; Save the zero page locations we need
174
175         ldx     #zpspace-1
176 L1:     lda     sp,x
177         sta     zpsave,x
178         dex
179         bpl     L1
180
181 ; copy chargen to low memory
182
183         lda     #>(__SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__)
184         sta     ptr3+1
185         lda     #<(__SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__)
186         sta     ptr3
187         beq     cg_addr_ok
188
189         ; page align the new chargen address
190         inc     ptr3+1
191         lda     #0
192         sta     ptr3
193
194 cg_addr_ok:
195         lda     #<DCSORG
196         sta     ptr1
197         lda     #>DCSORG
198         sta     ptr1+1
199         lda     ptr3
200         sta     ptr2
201         lda     ptr3+1
202         sta     ptr2+1
203         lda     #>__CHARGEN_SIZE__
204         sta     tmp2
205         lda     #<__CHARGEN_SIZE__
206         sta     tmp2+1
207         jsr     memcopy
208
209 ; TODO: switch to this temp. chargen
210
211 ; disable ROMs
212         sei
213         ldx     #0
214         stx     NMIEN           ; disable NMI
215         lda     PORTB
216         and     #$fe
217         sta     PORTB           ; now ROM is mapped out
218
219 ; copy shadow RAM contents to their destination
220
221         lda     #<__SHADOW_RAM_SIZE__
222         bne     do_copy
223         lda     #>__SHADOW_RAM_SIZE__
224         beq     no_copy                         ; we have no shadow RAM contents
225
226         ; ptr1 - src; ptr2 - dest; tmp1, tmp2 - len
227 do_copy:lda     #<__SHADOW_RAM_LOAD__
228         sta     ptr1
229         lda     #>__SHADOW_RAM_LOAD__
230         sta     ptr1+1
231         lda     #<__SHADOW_RAM_RUN__
232         sta     ptr2
233         lda     #>__SHADOW_RAM_RUN__
234         sta     ptr2+1
235         lda     #<__SHADOW_RAM_SIZE__
236         sta     tmp1
237         lda     #>__SHADOW_RAM_SIZE__
238         sta     tmp2
239
240         jsr     memcopy
241
242 no_copy:
243
244 ; copy chargen to its new location
245
246         lda     ptr3
247         sta     ptr1
248         lda     ptr3+1
249         sta     ptr1+1
250         lda     #<__CHARGEN_START__
251         sta     ptr2
252         lda     #>__CHARGEN_START__
253         sta     ptr2+1
254         lda     #>__CHARGEN_SIZE__
255         sta     tmp2
256         lda     #<__CHARGEN_SIZE__
257         sta     tmp1
258         jsr     memcopy
259
260 ; re-enable ROM
261
262         lda     PORTB
263         ora     #1
264         sta     PORTB
265         lda     #$40
266         sta     NMIEN                   ; enable VB again
267         cli                             ; and enable IRQs
268
269         rts
270
271
272 ; my 6502 fu is rusty, so I took a routine from the internet (http://www.obelisk.demon.co.uk/6502/algorithms.html)
273
274 ; copy memory
275 ; ptr1      - source
276 ; ptr2      - destination
277 ; tmp2:tmp1 - len
278
279 .proc   memcopy
280
281         ldy     #0
282         ldx     tmp2
283         beq     last
284 pagecp: lda     (ptr1),y
285         sta     (ptr2),y
286         iny
287         bne     pagecp
288         inc     ptr1+1
289         inc     ptr2+1
290         dex
291         bne     pagecp
292 last:   cpy     tmp1
293         beq     done
294         lda     (ptr1),y
295         sta     (ptr2),y
296         iny
297         bne     last
298 done:   rts
299
300 .endproc
301
302
303 .byte "HERE ****************** HERE ***************>>>>>>"
304
305 sramsize:
306         .word   __SHADOW_RAM_SIZE__
307
308 ; short delay
309 .proc   delay
310
311         lda     #10
312 l:      jsr     delay1
313         clc
314         sbc     #0
315         bne     l
316         rts
317
318 delay1: ldx     #0
319         ldy     #0
320 loop:   dey
321         bne     loop
322         dex
323         bne     loop
324         rts
325
326 .endproc
327
328 screen_device:  .byte "S:",0
329 screen_device_length = * - screen_device
330
331         .byte   " ** srprep ** end-->"
332
333 ; ------------------------------------------------------------------------
334 ; Provide an empty SHADOW_RAM segment in order that the linker is happy
335 ; if the user program doesn't have a SHADOW_RAM segment.
336
337 .segment        "SHADOW_RAM"
338
339
340 ; ------------------------------------------------------------------------
341 ; Chunk "trailer" - sets INITAD
342
343 .segment        "SRPREPTRL"
344
345         .word   INITAD
346         .word   INITAD+1
347         .word   __SRPREP_LOAD__
348
349 .endif  ; .if .defined(__ATARIXL__)