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
18 .import __SRPREP_LOAD__, __SRPREPCHNK_LAST__
19 .import __SHADOW_RAM_LOAD__, __SHADOW_RAM_SIZE__, __SHADOW_RAM_RUN__
20 .import __SHADOW_RAM2_LOAD__, __SHADOW_RAM2_SIZE__, __SHADOW_RAM2_RUN__
21 .import __CHARGEN_START__, __CHARGEN_SIZE__
22 .import __STARTADDRESS__ ; needed by xlmemchk.inc
24 .include "zeropage.inc"
26 .include "save_area.inc"
28 .macro print_string text
31 start: .byte text, ATEOL
32 cont: ldx #0 ; channel 0
46 ; ------------------------------------------------------------------------
47 ; EXE load chunk header
52 .word __SRPREPCHNK_LAST__ - 1
54 ; ------------------------------------------------------------------------
59 ; ***** entry point *****
63 print_string "entering stage #2"
66 ; save values of modified system variables and ports
87 .include "xlmemchk.inc" ; calculate lowest address used and new value for RAMTOP
96 ; set APPMHI to MEMLO (+ 1 for sanity)
106 ; issue a GRAPHICS 0 call (copied'n'pasted from TGI drivers) to move screen memory down
110 .ifdef DEBUG ; only check in debug version, this shouldn't really happen(tm)
112 print_string "Internal error, no free IOCB!"
116 jsr restore ; restore stuff we've changed
117 jmp (DOSVEC) ; abort loading
121 ; reopen it in Graphics 0
132 lda #<screen_device_length
134 lda #>screen_device_length
139 ; shouldn't happen(tm)
140 print_string "Internal error, aborting..."
144 jsr restore ; restore stuff we've changed
145 jmp (DOSVEC) ; abort loading
148 scrok: ; now close it again -- we don't need it anymore
154 ; copy chargen to low memory, just after the next possible address beyond our loaded chunk data
157 print_string "copy chargen to low memory"
160 lda #>__SRPREPCHNK_LAST__
162 lda #<__SRPREPCHNK_LAST__
166 ; page align the new chargen address
177 ; align to next 1K boundary
193 pha ; needed later to set CHBAS/CHBASE
195 lda #>__CHARGEN_SIZE__
197 lda #<__CHARGEN_SIZE__
202 print_string "now setting up high memory"
208 stx NMIEN ; disable NMI
212 pla ; get temp. chargen address
213 sta WSYNC ; wait for horiz. retrace
214 stx PORTB ; now ROM is mapped out
216 ; switch to temporary chargen
221 ; copy shadow RAM contents to their destination (segment SHADOW_RAM)
223 lda #<__SHADOW_RAM_SIZE__
225 lda #>__SHADOW_RAM_SIZE__
226 beq no_copy ; we have no shadow RAM contents
228 ; ptr1 - src; ptr2 - dest; tmp1, tmp2 - len
229 do_copy:lda #<__SHADOW_RAM_LOAD__
231 lda #>__SHADOW_RAM_LOAD__
233 lda #<__SHADOW_RAM_RUN__
235 lda #>__SHADOW_RAM_RUN__
237 lda #<__SHADOW_RAM_SIZE__
239 lda #>__SHADOW_RAM_SIZE__
246 ; copy shadow RAM #2 contents to their destination (segment SHADOW_RAM2)
248 lda #<__SHADOW_RAM2_SIZE__
250 lda #>__SHADOW_RAM2_SIZE__
251 beq no_copy2 ; we have no shadow RAM #2 contents
253 ; ptr1 - src; ptr2 - dest; tmp1, tmp2 - len
255 lda #<__SHADOW_RAM2_LOAD__
257 lda #>__SHADOW_RAM2_LOAD__
259 lda #<__SHADOW_RAM2_RUN__
261 lda #>__SHADOW_RAM2_RUN__
263 lda #<__SHADOW_RAM2_SIZE__
265 lda #>__SHADOW_RAM2_SIZE__
272 ; copy chargen to its new (final) location
278 lda #<__CHARGEN_START__
280 lda #>__CHARGEN_START__
282 lda #>__CHARGEN_SIZE__
284 lda #<__CHARGEN_SIZE__
293 sta WSYNC ; wait for horiz. retrace
298 sta NMIEN ; enable VB again
299 cli ; and enable IRQs
302 print_string "Stage #2 OK"
303 print_string "loading main chunk"
308 .include "findfreeiocb.inc"
310 ; routine taken from http://www.obelisk.demon.co.uk/6502/algorithms.html
341 ; clean up after a fatal error
343 restore:lda RAMTOP_save
377 .byte "HERE ****************** HERE ***************>>>>>>"
380 .word __SHADOW_RAM_SIZE__
382 .endif ; .ifdef DEBUG
384 screen_device: .byte "S:",0
385 screen_device_length = * - screen_device
388 .byte " ** srprep ** end-->"
391 ; ------------------------------------------------------------------------
392 ; Provide empty SHADOW_RAM and SHADOW_RAM2 segments in order that the
393 ; linker is happy if the user program doesn't have these segments.
395 .segment "SHADOW_RAM"
396 .segment "SHADOW_RAM2"
399 ; ------------------------------------------------------------------------
400 ; EXE load chunk "trailer" - sets INITAD
408 .endif ; .ifdef __ATARIXL__