X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libsrc%2Fatari%2Fshadow_ram_prepare.s;h=a08aa8cfeb8c33ff7550fac100020c94db367ef1;hb=b727c075e9935078cf8f34baeacb8a32439794e1;hp=60de9dbf16c45c7398c4f6648869b454a232f122;hpb=8e632b2847e6a6321023e41d67baf23e4faf8d9e;p=cc65 diff --git a/libsrc/atari/shadow_ram_prepare.s b/libsrc/atari/shadow_ram_prepare.s index 60de9dbf1..a08aa8cfe 100644 --- a/libsrc/atari/shadow_ram_prepare.s +++ b/libsrc/atari/shadow_ram_prepare.s @@ -9,45 +9,46 @@ ; Christian Groessler, chris@groessler.org, 2013 ; -.if .defined(__ATARIXL__) +;DEBUG = 1 - .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 +.ifdef __ATARIXL__ + + .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 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 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 __SRPREPCHNK_LAST__ - 1 ; ------------------------------------------------------------------------ ; Actual code @@ -55,78 +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 - 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 + lda PORTB + ora #2 + sta PORTB + .include "xlmemchk.inc" ; calculate lowest address used and new value for RAMTOP -; ... change system memory variables bla + ldx lowadr + stx MEMTOP + lda lowadr+1 + sta MEMTOP+1 + lda lodadr+1 + sta RAMTOP -CMPVAL = 64+255+992 ; you may ask, why these values... @@@ document + ; set APPMHI to MEMLO (+ 1 for sanity) + lda MEMLO + clc + adc #1 + sta APPMHI + lda MEMLO+1 + adc #0 + sta APPMHI+1 -sys_ok: lda #<__SAVEAREA_LOAD__ - sec - sbc #__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) to move screen memory down - -; ... issue a GRAPHICS 0 call (copied'n'pasted from TGI drivers) - - - 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 @@ -144,202 +131,275 @@ sys_ok: lda #<__SAVEAREA_LOAD__ lda #>screen_device_length sta ICBLH,x jsr CIOV_org - bpl okoko - - print_string "GR 0 FAILED" - jsr delay - jsr delay - jsr delay + bpl scrok - jmp (DOSVEC) ; abort loading +; 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 - print_string "GR 0 OKOKO" - jsr delay - -; Save the zero page locations we need - - ldx #zpspace-1 -L1: lda sp,x - sta zpsave,x - dex - bpl L1 +; copy chargen to low memory, just after the next possible address beyond our loaded chunk data -; copy chargen to low memory +.ifdef DEBUG + print_string "copy chargen to low memory" +.endif - lda #>(__SRPREP_LOAD__ + __SRPREP_SIZE__) - sta ptr3+1 - lda #<(__SRPREP_LOAD__ + __SRPREP_SIZE__) - sta ptr3 - beq cg_addr_ok + lda #>__SRPREPCHNK_LAST__ + sta ptr3+1 + lda #<__SRPREPCHNK_LAST__ + sta ptr3 + beq cg_addr_ok - ; page align the new chargen address - inc ptr3+1 - lda #0 - sta ptr3 + ; page align the new chargen address + inc ptr3+1 + lda #0 + sta ptr3 cg_addr_ok: - 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 + + 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 (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 tmp2+1 - 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 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__