2 ; Atari XL shadow RAM preparation routines
5 ; - move screen memory below load address
6 ; - copy ROM chargen to its new place
7 ; - copy shadow RAM contents to their destination
9 ; Christian Groessler, chris@groessler.org, 2013
14 .if .defined(__ATARIXL__)
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__
23 .include "zeropage.inc"
25 .include "save_area.inc"
27 .macro print_string text
30 start: .byte text, ATEOL
31 cont: ldx #0 ; channel 0
45 ; ------------------------------------------------------------------------
46 ; EXE load chunk header
51 .word __SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__ - 1
53 ; ------------------------------------------------------------------------
60 print_string "entering stage #2"
63 ; save values of modified system variables and ports
84 .include "xlmemchk.inc" ; calculate lowest address used and new value for RAMTOP
93 ; set APPMHI to MEMLO (+ 1 for sanity)
103 ; issue a GRAPHICS 0 call (copied'n'pasted from TGI drivers) to move screen memory down
107 .ifdef DEBUG ; only check in debug version, this shouldn't really happen(tm)
109 print_string "Internal error, no free IOCB!"
113 jsr restore ; restore stuff we've changed
114 jmp (DOSVEC) ; abort loading
118 ; Reopen it in Graphics 0
129 lda #<screen_device_length
131 lda #>screen_device_length
136 ; shouldn't happen(tm)
137 print_string "Internal error, aborting..."
141 jsr restore ; restore stuff we've changed
142 jmp (DOSVEC) ; abort loading
145 scrok: ; now close it again -- we don't need it anymore
151 ; copy chargen to low memory
154 print_string "copy chargen to low memory"
157 lda #>(__SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__)
159 lda #<(__SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__)
163 ; page align the new chargen address
174 ; align to next 1K boundary
190 pha ; needed later to set CHBAS/CHBASE
192 lda #>__CHARGEN_SIZE__
194 lda #<__CHARGEN_SIZE__
199 print_string "now setting up high memory"
205 stx NMIEN ; disable NMI
209 pla ; get temp. chargen address
210 sta WSYNC ; wait for horiz. retrace
211 stx PORTB ; now ROM is mapped out
213 ; switch to temporary chargen
218 ; copy shadow RAM contents to their destination
220 lda #<__SHADOW_RAM_SIZE__
222 lda #>__SHADOW_RAM_SIZE__
223 beq no_copy ; we have no shadow RAM contents
225 ; ptr1 - src; ptr2 - dest; tmp1, tmp2 - len
226 do_copy:lda #<__SHADOW_RAM_LOAD__
228 lda #>__SHADOW_RAM_LOAD__
230 lda #<__SHADOW_RAM_RUN__
232 lda #>__SHADOW_RAM_RUN__
234 lda #<__SHADOW_RAM_SIZE__
236 lda #>__SHADOW_RAM_SIZE__
243 ; copy chargen to its new (final) location
249 lda #<__CHARGEN_START__
251 lda #>__CHARGEN_START__
253 lda #>__CHARGEN_SIZE__
255 lda #<__CHARGEN_SIZE__
264 sta WSYNC ; wait for horiz. retrace
269 sta NMIEN ; enable VB again
270 cli ; and enable IRQs
273 print_string "Stage #2 OK"
274 print_string "loading main chunk"
279 .include "findfreeiocb.inc"
281 ; routine taken from http://www.obelisk.demon.co.uk/6502/algorithms.html
312 ; clean up after a fatal error
314 restore:lda RAMTOP_save
329 .byte "HERE ****************** HERE ***************>>>>>>"
332 .word __SHADOW_RAM_SIZE__
354 .endif ; .ifdef DEBUG
356 screen_device: .byte "S:",0
357 screen_device_length = * - screen_device
360 .byte " ** srprep ** end-->"
363 ; ------------------------------------------------------------------------
364 ; Provide an empty SHADOW_RAM segment in order that the linker is happy
365 ; if the user program doesn't have a SHADOW_RAM segment.
367 .segment "SHADOW_RAM"
370 ; ------------------------------------------------------------------------
371 ; EXE load chunk "trailer" - sets INITAD
379 .endif ; .if .defined(__ATARIXL__)