]> git.sur5r.net Git - cc65/blobdiff - libsrc/atari/shadow_ram_prepare.s
Fixed _textcolor definition.
[cc65] / libsrc / atari / shadow_ram_prepare.s
index fe367dbdcdfd847b59ab252d5bb574ffbe7c8ea6..a1760bd72d303372250bf80d1966fcc31275709e 100644 (file)
 ; 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         __CHARGEN_START__, __CHARGEN_SIZE__
-       .import         __SAVEAREA_LOAD__
-       .import         zpsave
+        .export         sramprep
+
+        .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         __STARTADDRESS__       ; needed by xlmemchk.inc
 
         .include        "zeropage.inc"
         .include        "atari.inc"
-       .include        "save_area.inc"
+        .include        "save_area.inc"
 
 .macro print_string text
-       .local  start, cont
-       jmp     cont
-start: .byte   text, ATEOL
-cont:  ldx     #0              ; channel 0
-       lda     #<start
-       sta     ICBAL,x         ; address
-       lda     #>start
-       sta     ICBAH,x
-       lda     #<(cont - start)
-       sta     ICBLL,x         ; length
-       lda     #>(cont - start)
-       sta     ICBLH,x
-       lda     #PUTCHR
-       sta     ICCOM,x
-       jsr     CIOV_org
+        .local  start, cont
+        jmp     cont
+start:  .byte   text, ATEOL
+cont:   ldx     #0              ; channel 0
+        lda     #<start
+        sta     ICBAL,x         ; address
+        lda     #>start
+        sta     ICBAH,x
+        lda     #<(cont - start)
+        sta     ICBLL,x         ; length
+        lda     #>(cont - start)
+        sta     ICBLH,x
+        lda     #PUTCHR
+        sta     ICCOM,x
+        jsr     CIOV_org
 .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:
-       print_string "in sramprep"
+.ifdef DEBUG
+        print_string "entering stage #2"
+.endif
 
 ; save values of modified system variables and ports
 
-       lda     RAMTOP
-       sta     RAMTOP_save
-       lda     MEMTOP
-       sta     MEMTOP_save
-       lda     MEMTOP+1
-       sta     MEMTOP_save+1
-       lda     APPMHI
-       sta     APPMHI_save
-       lda     APPMHI+1
-       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
-
-       lda     $fffe
-       sta     IRQ_save
-       lda     $ffff
-       sta     IRQ_save+1
-       lda     $fffc
-       sta     RESET_save
-       lda     $fffd
-       sta     RESET_save+1
-       lda     $fffa
-       sta     NMI_save
-       lda     $fffb
-       sta     NMI_save+1
+        lda     RAMTOP
+        sta     RAMTOP_save
+        lda     MEMTOP
+        sta     MEMTOP_save
+        lda     MEMTOP+1
+        sta     MEMTOP_save+1
+        lda     APPMHI
+        sta     APPMHI_save
+        lda     APPMHI+1
+        sta     APPMHI_save+1
+        lda     PORTB
+        sta     PORTB_save
 
 ; disable BASIC
 
-       lda     PORTB
-       ora     #2
-       sta     PORTB
-
-
-; ... change system memory variables bla
-
-CMPVAL = 64+255+992            ; you may ask, why these values...   @@@ document
-
-sys_ok:        lda     #<__SAVEAREA_LOAD__
-       sec
-       sbc     #<CMPVAL
-       sta     MEMTOP
-       sta     APPMHI
-       lda     #>__SAVEAREA_LOAD__
-       sbc     #>CMPVAL
-       sta     MEMTOP+1
-       sta     APPMHI+1
-
-       lda     #>__SAVEAREA_LOAD__ - 1
-       sta     RAMTOP
-
-
-
-; ... issue a GRAPHICS 0 call (copied'n'pasted from TGI drivers)
-
-
-       ldx     #$50            ; take any IOCB, hopefully free (@@@ fixme)
+        lda     PORTB
+        ora     #2
+        sta     PORTB
+
+        .include "xlmemchk.inc" ; calculate lowest address used and new value for RAMTOP
+
+        ldx     lowadr
+        stx     MEMTOP
+        lda     lowadr+1
+        sta     MEMTOP+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) to move screen memory down
+
+
+        jsr     findfreeiocb
+.ifdef DEBUG            ; only check in debug version, this shouldn't really happen(tm)
+        beq     iocbok
+        print_string "Internal error, no free IOCB!"
+        jsr     delay
+        jsr     delay
+        jsr     delay
+        jsr     restore                 ; restore stuff we've changed
+        jmp     (DOSVEC)                ; abort loading
+iocbok:
+.endif
 
-        ; Reopen it in Graphics 0
+        ; reopen it in Graphics 0
         lda     #OPEN
         sta     ICCOM,x
         lda     #OPNIN | OPNOT
@@ -146,204 +134,275 @@ sys_ok: lda     #<__SAVEAREA_LOAD__
         lda     #>screen_device_length
         sta     ICBLH,x
         jsr     CIOV_org
-       bpl     okoko
-
-       print_string "Internal error, aborting..."
-       jsr     delay
-       jsr     delay
-       jsr     delay
-
-       jmp     (DOSVEC)                ; abort loading
+        bpl     scrok
 
+; shouldn't happen(tm)
+        print_string "Internal error, aborting..."
+        jsr     delay
+        jsr     delay
+        jsr     delay
+        jsr     restore                 ; restore stuff we've changed
+        jmp     (DOSVEC)                ; abort loading
 
-okoko:
 
-
-        ; Now close it again; we don't need it anymore :)
+scrok:  ; now close it again -- we don't need it anymore
         lda     #CLOSE
         sta     ICCOM,x
         jsr     CIOV_org
 
+
+; copy chargen to low memory, just after the next possible address beyond our loaded chunk data
+
 .ifdef DEBUG
-       print_string "Stage #2 OK"
-       jsr     delay
+        print_string "copy chargen to low memory"
 .endif
 
+        lda     #>__SRPREPCHNK_LAST__
+        sta     ptr3+1
+        lda     #<__SRPREPCHNK_LAST__
+        sta     ptr3
+        beq     cg_addr_ok
 
-; Save the zero page locations we need
-
-        ldx     #zpspace-1
-L1:     lda     sp,x
-        sta     zpsave,x
-        dex
-        bpl     L1
+        ; page align the new chargen address
+        inc     ptr3+1
+        lda     #0
+        sta     ptr3
 
-; copy chargen to low memory
+cg_addr_ok:
 
-       lda     #>(__SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__)
-       sta     ptr3+1
-       lda     #<(__SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__)
-       sta     ptr3
-       beq     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
 
-       ; page align the new chargen address
-       inc     ptr3+1
-       lda     #0
-       sta     ptr3
+.ifdef DEBUG
+        print_string "now setting up high memory"
+.endif
 
-cg_addr_ok:
-       lda     #<DCSORG
-       sta     ptr1
-       lda     #>DCSORG
-       sta     ptr1+1
-       lda     ptr3
-       sta     ptr2
-       lda     ptr3+1
-       sta     ptr2+1
-       lda     #>__CHARGEN_SIZE__
-       sta     tmp2
-       lda     #<__CHARGEN_SIZE__
-       sta     tmp2+1
-       jsr     memcopy
-
-; TODO: switch to this temp. chargen
-
-; disable ROMs
-       sei
-       ldx     #0
-       stx     NMIEN           ; disable NMI
-       lda     PORTB
-       and     #$fe
-       sta     PORTB           ; now ROM is mapped out
-
-; 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
+; 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 (segment SHADOW_RAM)
+
+        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 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
+; 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
+        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
-       sta     PORTB
-       lda     #$40
-       sta     NMIEN                   ; enable VB again
-       cli                             ; and enable IRQs
+        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
 ; tmp2:tmp1 - len
 
-.proc  memcopy
-
-       ldy     #0
-       ldx     tmp2
-       beq     last
-pagecp:        lda     (ptr1),y
-       sta     (ptr2),y
-       iny
-       bne     pagecp
-       inc     ptr1+1
-       inc     ptr2+1
-       dex
-       bne     pagecp
-last:  cpy     tmp1
-       beq     done
-       lda     (ptr1),y
-       sta     (ptr2),y
-       iny
-       bne     last
-done:  rts
+.proc   memcopy
+
+        ldy     #0
+        ldx     tmp2
+        beq     last
+pagecp: lda     (ptr1),y
+        sta     (ptr2),y
+        iny
+        bne     pagecp
+        inc     ptr1+1
+        inc     ptr2+1
+        dex
+        bne     pagecp
+last:   cpy     tmp1
+        beq     done
+        lda     (ptr1),y
+        sta     (ptr2),y
+        iny
+        bne     last
+done:   rts
 
 .endproc
 
 
-.byte "HERE ****************** HERE ***************>>>>>>"
+; clean up after a fatal error
 
-sramsize:
-       .word   __SHADOW_RAM_SIZE__
+restore:lda     RAMTOP_save
+        sta     RAMTOP
+        lda     MEMTOP_save
+        sta     MEMTOP
+        lda     MEMTOP_save+1
+        sta     MEMTOP+1
+        lda     APPMHI_save
+        sta     APPMHI
+        lda     APPMHI_save+1
+        sta     APPMHI+1
+        rts
 
 ; short delay
-.proc  delay
-
-       lda     #10
-l:     jsr     delay1
-       clc
-       sbc     #0
-       bne     l
-       rts
-
-delay1:        ldx     #0
-       ldy     #0
-loop:  dey
-       bne     loop
-       dex
-       bne     loop
-       rts
+.proc   delay
+
+        lda     #10
+@loop:  jsr     delay1
+        clc
+        sbc     #0
+        bne     @loop
+        rts
+
+delay1: ldx     #0
+        ldy     #0
+@loop:   dey
+        bne     @loop
+        dex
+        bne     @loop
+        rts
 
 .endproc
 
-screen_device: .byte "S:",0
+.ifdef DEBUG
+
+.byte "HERE ****************** HERE ***************>>>>>>"
+
+sramsize:
+        .word   __SHADOW_RAM_SIZE__
+
+.endif          ; .ifdef DEBUG
+
+screen_device:  .byte "S:",0
 screen_device_length = * - screen_device
 
-       .byte   " ** srprep ** end-->"
+.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__