X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=libsrc%2Fatari%2Fshadow_ram_prepare.s;h=e0dc23f778346621da59008ae80e1696e875e253;hb=85170998ad45cadb2064fa68349bb3a8975efd89;hp=2fc8ffbc3aa45b82b0152f44b9d9784bad31713e;hpb=79d150b62671ae7eaa2b94350f08179582cc836c;p=cc65 diff --git a/libsrc/atari/shadow_ram_prepare.s b/libsrc/atari/shadow_ram_prepare.s index 2fc8ffbc3..e0dc23f77 100644 --- a/libsrc/atari/shadow_ram_prepare.s +++ b/libsrc/atari/shadow_ram_prepare.s @@ -3,48 +3,52 @@ ; ; Tasks: ; - move screen memory below load address +; - copy ROM chargen to its new place ; - copy shadow RAM contents to their destination ; ; Christian Groessler, chris@groessler.org, 2013 ; +DEBUG = 1 + .if .defined(__ATARIXL__) - .export sramprep + .export sramprep .import __SRPREP_LOAD__, __SRPREP_SIZE__ - .import __SHADOW_RAM_LOAD__, __SHADOW_RAM_SIZE__ - .import __CHARGEN_LOAD__, __CHARGEN_SIZE__ - .import __SAVEAREA_LOAD__ + .import __SHADOW_RAM_LOAD__, __SHADOW_RAM_SIZE__ + .import __SHADOW_RAM_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 ICBAH,x - lda #<(cont - start) - sta ICBLL,x ; length - lda #>(cont - start) - sta ICBLH,x - lda #PUTCHR - sta ICCOM,x - jsr CIOV + .local start, cont + jmp cont +start: .byte text, ATEOL +cont: ldx #0 ; channel 0 + 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__ - 1 + .word __SRPREP_LOAD__ + __SRPREP_SIZE__ + __SHADOW_RAM_SIZE__ - 1 ; ------------------------------------------------------------------------ ; Actual code @@ -52,52 +56,64 @@ cont: ldx #0 ; channel 0 .segment "SRPREP" 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 -; disable BASIC + 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 PORTB - ora #2 - sta PORTB +; disable BASIC + lda PORTB + ora #2 + sta PORTB -; ... change memory bla + .include "xlmemchk.inc" ; calculate lowest address used and new value for RAMTOP -CMPVAL = 64+255+992 ; you may ask, why these values... @@@ document + ldx lowadr + stx MEMTOP + lda lowadr+1 + sta MEMTOP+1 + lda lodadr+1 + sta RAMTOP -sys_ok: lda #<__SAVEAREA_LOAD__ - sec - sbc #__SAVEAREA_LOAD__ - sbc #>CMPVAL - sta MEMTOP+1 - sta APPMHI+1 + ; set APPMHI to MEMLO (+ 1 for sanity) + lda MEMLO + clc + adc #1 + sta APPMHI + lda MEMLO+1 + adc #0 + sta APPMHI+1 - lda #>__SAVEAREA_LOAD__ - 1 - sta RAMTOP - - -; ... issue ar 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 - ldx #$50 ; take any IOCB, hopefully free (@@@ fixme) + 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 lda #OPEN @@ -114,72 +130,250 @@ sys_ok: lda #<__SAVEAREA_LOAD__ sta ICBLL,x lda #>screen_device_length sta ICBLH,x - jsr CIOV - bpl okoko - - print_string "GR 0 FAILED" - jsr delay - jsr delay - jsr delay + jsr CIOV_org + bpl scrok - jmp xxx +; 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 - - print_string "GR 0 OKOKO" - jsr delay + jsr CIOV_org +; copy chargen to low memory +.ifdef DEBUG + print_string "copy chargen to low memory" +.endif + 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 + ; 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+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 -xxx: +.include "findfreeiocb.inc" +; 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 +.endproc +; clean up after a fatal error +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 + +.ifdef DEBUG + +.byte "HERE ****************** HERE ***************>>>>>>" + +sramsize: + .word __SHADOW_RAM_SIZE__ + ; 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 +l: jsr delay1 + clc + sbc #0 + bne l + rts + +delay1: ldx #0 + ldy #0 +loop: dey + bne loop + dex + bne loop + rts .endproc -screen_device: .byte "S:",0 +.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. + +.segment "SHADOW_RAM" + ; ------------------------------------------------------------------------ -; 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 ; .if .defined(__ATARIXL__)