+ ; page align the new chargen address
+ inc ptr3+1
+ lda #0
+ 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
+ sta ptr1+1
+ 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 tmp1
+ jsr memcopy
+
+.ifdef DEBUG
+ print_string "now setting up high memory"
+.endif
+
+; disable ROM
+ sei
+ ldx #0
+ stx NMIEN ; disable NMI
+ lda PORTB
+ and #$fe
+ 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
+
+ lda #<__SHADOW_RAM_SIZE__
+ bne do_copy
+ lda #>__SHADOW_RAM_SIZE__
+ beq no_copy ; we have no shadow RAM contents
+
+ ; ptr1 - src; ptr2 - dest; tmp1, tmp2 - len
+do_copy:lda #<__SHADOW_RAM_LOAD__
+ sta ptr1
+ lda #>__SHADOW_RAM_LOAD__
+ sta ptr1+1
+ lda #<__SHADOW_RAM_RUN__
+ sta ptr2
+ lda #>__SHADOW_RAM_RUN__
+ sta ptr2+1
+ lda #<__SHADOW_RAM_SIZE__
+ sta tmp1
+ lda #>__SHADOW_RAM_SIZE__
+ sta tmp2
+
+ jsr memcopy
+
+no_copy:
+
+; copy chargen to its new (final) location
+
+ lda ptr3
+ sta ptr1
+ lda ptr3+1
+ sta ptr1+1
+ lda #<__CHARGEN_START__
+ sta ptr2
+ lda #>__CHARGEN_START__
+ sta ptr2+1
+ lda #>__CHARGEN_SIZE__
+ sta tmp2
+ lda #<__CHARGEN_SIZE__
+ sta tmp1
+ jsr memcopy
+
+; re-enable ROM
+
+ 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