; Christian Groessler, chris@groessler.org, 2013
;
-DEBUG = 1
+;DEBUG = 1
-.if .defined(__ATARIXL__)
+.ifdef __ATARIXL__
.export sramprep
- .import __SRPREP_LOAD__, __SRPREP_SIZE__
- .import __SHADOW_RAM_LOAD__, __SHADOW_RAM_SIZE__
- .import __SHADOW_RAM_RUN__
+
+ .import __SRPREP_LOAD__, __SRPREPCHNK_LAST__
+ .import __SHADOW_RAM_LOAD__, __SHADOW_RAM_SIZE__, __SHADOW_RAM_RUN__
+ .import __SHADOW_RAM2_LOAD__, __SHADOW_RAM2_SIZE__, __SHADOW_RAM2_RUN__
.import __CHARGEN_START__, __CHARGEN_SIZE__
- .import __SAVEAREA_LOAD__
+ .import __STARTADDRESS__ ; needed by xlmemchk.inc
.include "zeropage.inc"
.include "atari.inc"
.endmacro
; ------------------------------------------------------------------------
-; Chunk header
+; EXE load chunk header
.segment "SRPREPHDR"
.word __SRPREP_LOAD__
- .word __SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__ - 1
+ .word __SRPREPCHNK_LAST__ - 1
; ------------------------------------------------------------------------
; Actual code
.segment "SRPREP"
+; ***** entry point *****
+
sramprep:
.ifdef DEBUG
print_string "entering stage #2"
sta APPMHI_save+1
lda PORTB
sta PORTB_save
- lda CIOV ; zero-page wrapper
- sta ZP_CIOV_save
- lda CIOV+1
- sta ZP_CIOV_save+1
- lda CIOV+2
- sta ZP_CIOV_save+2
- lda SIOV ; zero-page wrapper
- sta ZP_SIOV_save
- lda SIOV+1
- sta ZP_SIOV_save+1
- lda SIOV+2
- sta ZP_SIOV_save+2
; disable BASIC
ldx lowadr
stx MEMTOP
- stx APPMHI
lda lowadr+1
sta MEMTOP+1
- sta APPMHI+1
lda lodadr+1
sta RAMTOP
+ ; set APPMHI to MEMLO (+ 1 for sanity)
+ lda MEMLO
+ clc
+ adc #1
+ sta APPMHI
+ lda MEMLO+1
+ adc #0
+ sta APPMHI+1
+
-; ... issue a GRAPHICS 0 call (copied'n'pasted from TGI drivers)
+; issue a GRAPHICS 0 call (copied'n'pasted from TGI drivers) to move screen memory down
jsr findfreeiocb
-.ifdef DEBUG ; only check in debug version, this shouldn't happen normally(tm)
+.ifdef DEBUG ; only check in debug version, this shouldn't really happen(tm)
beq iocbok
print_string "Internal error, no free IOCB!"
jsr delay
iocbok:
.endif
- ; Reopen it in Graphics 0
+ ; reopen it in Graphics 0
lda #OPEN
sta ICCOM,x
lda #OPNIN | OPNOT
jsr CIOV_org
-; copy chargen to low memory
+; copy chargen to low memory, just after the next possible address beyond our loaded chunk data
.ifdef DEBUG
print_string "copy chargen to low memory"
- print_string "set up high memory"
.endif
- lda #>(__SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__)
+ lda #>__SRPREPCHNK_LAST__
sta ptr3+1
- lda #<(__SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__)
+ lda #<__SRPREPCHNK_LAST__
sta ptr3
beq cg_addr_ok
sta ptr3
cg_addr_ok:
+
+ lda ptr3+1
+ and #3
+ beq cg_addr_ok2
+
+ ; align to next 1K boundary
+ lda ptr3+1
+ and #$fc
+ clc
+ adc #4
+ sta ptr3+1
+
+cg_addr_ok2:
+
lda #<DCSORG
sta ptr1
lda #>DCSORG
lda ptr3
sta ptr2
lda ptr3+1
+ pha ; needed later to set CHBAS/CHBASE
sta ptr2+1
lda #>__CHARGEN_SIZE__
sta tmp2
lda #<__CHARGEN_SIZE__
- sta tmp2+1
+ sta tmp1
jsr memcopy
-; TODO: switch to this temp. chargen
+.ifdef DEBUG
+ print_string "now setting up high memory"
+.endif
-; disable ROMs
+; disable ROM
sei
ldx #0
- stx NMIEN ; disable NMI
+ stx NMIEN ; disable NMI
lda PORTB
and #$fe
- sta PORTB ; now ROM is mapped out
+ tax
+ pla ; get temp. chargen address
+ sta WSYNC ; wait for horiz. retrace
+ stx PORTB ; now ROM is mapped out
+
+; switch to temporary chargen
+
+ sta CHBASE
+ sta CHBAS
-; copy shadow RAM contents to their destination
+; copy shadow RAM contents to their destination (segment SHADOW_RAM)
lda #<__SHADOW_RAM_SIZE__
bne do_copy
lda #>__SHADOW_RAM_SIZE__
- beq no_copy ; we have no shadow RAM contents
+ beq no_copy ; we have no shadow RAM contents
; ptr1 - src; ptr2 - dest; tmp1, tmp2 - len
do_copy:lda #<__SHADOW_RAM_LOAD__
no_copy:
+; copy shadow RAM #2 contents to their destination (segment SHADOW_RAM2)
+
+ lda #<__SHADOW_RAM2_SIZE__
+ bne do_copy2
+ lda #>__SHADOW_RAM2_SIZE__
+ beq no_copy2 ; we have no shadow RAM #2 contents
+
+ ; ptr1 - src; ptr2 - dest; tmp1, tmp2 - len
+do_copy2:
+ lda #<__SHADOW_RAM2_LOAD__
+ sta ptr1
+ lda #>__SHADOW_RAM2_LOAD__
+ sta ptr1+1
+ lda #<__SHADOW_RAM2_RUN__
+ sta ptr2
+ lda #>__SHADOW_RAM2_RUN__
+ sta ptr2+1
+ lda #<__SHADOW_RAM2_SIZE__
+ sta tmp1
+ lda #>__SHADOW_RAM2_SIZE__
+ sta tmp2
+
+ jsr memcopy
+
+no_copy2:
+
; copy chargen to its new (final) location
lda ptr3
lda PORTB
ora #1
+ ldx #>DCSORG
+ sta WSYNC ; wait for horiz. retrace
sta PORTB
+ stx CHBASE
+ stx CHBAS
lda #$40
sta NMIEN ; enable VB again
cli ; and enable IRQs
.ifdef DEBUG
print_string "Stage #2 OK"
+ print_string "loading main chunk"
jsr delay
.endif
rts
.include "findfreeiocb.inc"
-; my 6502 fu is rusty, so I took a routine from the internet (http://www.obelisk.demon.co.uk/6502/algorithms.html)
-
+; routine taken from http://www.obelisk.demon.co.uk/6502/algorithms.html
+;
; copy memory
; ptr1 - source
; ptr2 - destination
sta APPMHI+1
rts
-
-.byte "HERE ****************** HERE ***************>>>>>>"
-
-sramsize:
- .word __SHADOW_RAM_SIZE__
-
; short delay
.proc delay
lda #10
-l: jsr delay1
+@loop: jsr delay1
clc
sbc #0
- bne l
+ bne @loop
rts
delay1: ldx #0
ldy #0
-loop: dey
- bne loop
+@loop: dey
+ bne @loop
dex
- bne loop
+ bne @loop
rts
.endproc
+.ifdef DEBUG
+
+.byte "HERE ****************** HERE ***************>>>>>>"
+
+sramsize:
+ .word __SHADOW_RAM_SIZE__
+
+.endif ; .ifdef DEBUG
+
screen_device: .byte "S:",0
screen_device_length = * - screen_device
+.ifdef DEBUG
.byte " ** srprep ** end-->"
+.endif
; ------------------------------------------------------------------------
-; Provide an empty SHADOW_RAM segment in order that the linker is happy
-; if the user program doesn't have a SHADOW_RAM segment.
+; Provide empty SHADOW_RAM and SHADOW_RAM2 segments in order that the
+; linker is happy if the user program doesn't have these segments.
.segment "SHADOW_RAM"
+.segment "SHADOW_RAM2"
; ------------------------------------------------------------------------
-; Chunk "trailer" - sets INITAD
+; EXE load chunk "trailer" - sets INITAD
.segment "SRPREPTRL"
.word INITAD
.word INITAD+1
- .word __SRPREP_LOAD__
+ .word sramprep
-.endif ; .if .defined(__ATARIXL__)
+.endif ; .ifdef __ATARIXL__