From df1a141d8b41b0810225a34aafbc2c6995deba7c Mon Sep 17 00:00:00 2001 From: blondie7575 Date: Tue, 18 Jul 2023 20:15:53 -0700 Subject: [PATCH] Groundwork for graphical loading screen --- GSCats.xcodeproj/project.pbxproj | 8 +- Makefile | 21 +-- equates.s | 2 + gscats.s | 7 +- loader.s | 140 +++++++-------- loaderGraphics.s | 164 +++++++++++++++++ terrain_e1.s | 297 ------------------------------- 7 files changed, 238 insertions(+), 401 deletions(-) create mode 100644 loaderGraphics.s delete mode 100644 terrain_e1.s diff --git a/GSCats.xcodeproj/project.pbxproj b/GSCats.xcodeproj/project.pbxproj index a511a96..d26fc05 100644 --- a/GSCats.xcodeproj/project.pbxproj +++ b/GSCats.xcodeproj/project.pbxproj @@ -15,10 +15,10 @@ 700F72872112428D00225B17 /* RenumberSpriteFiles.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = RenumberSpriteFiles.sh; sourceTree = ""; }; 701E708A2A649A230030C35D /* tinyNumbers.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = tinyNumbers.s; sourceTree = ""; }; 701E708B2A660CEB0030C35D /* progressBar.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = progressBar.s; sourceTree = ""; }; + 701E708E2A67844B0030C35D /* loaderGraphics.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = loaderGraphics.s; sourceTree = ""; }; 705456862A43E03B00A2B866 /* GeneratePixelCircle.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = GeneratePixelCircle.py; sourceTree = ""; }; 705456882A4D336200A2B866 /* animation.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = animation.s; sourceTree = ""; }; 7059502B1F37A0BE00BBE90F /* GenerateVRAMTable.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = GenerateVRAMTable.py; sourceTree = ""; }; - 705AAFA920040B0D001BB0ED /* terrain_e1.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = terrain_e1.s; sourceTree = ""; }; 705C54E62124B7F300515A6B /* fan.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = fan.s; sourceTree = ""; }; 706DF1641F2D39F700AA6680 /* loader.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = loader.s; sourceTree = ""; }; 706DF1651F2D4A8100AA6680 /* terrain.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = terrain.s; sourceTree = ""; }; @@ -58,14 +58,15 @@ children = ( 70E9D85F1F2BD95400555C19 /* equates.s */, 700F21DE1F43E31300D7007D /* input.s */, + 706DF1641F2D39F700AA6680 /* loader.s */, + 701E708E2A67844B0030C35D /* loaderGraphics.s */, + 70E9D8611F2BD95400555C19 /* gscats.s */, 70E9D8601F2BD95400555C19 /* graphics.s */, 70E9D8621F2BD95400555C19 /* macros.s */, 7099E3841F41022100182A82 /* gameobject.s */, 70F011D123B989B800C8873F /* random.s */, - 706DF1641F2D39F700AA6680 /* loader.s */, 706DF1651F2D4A8100AA6680 /* terrain.s */, 701E708B2A660CEB0030C35D /* progressBar.s */, - 705AAFA920040B0D001BB0ED /* terrain_e1.s */, 70F011D023B91B2900C8873F /* dirt.s */, 70C073091F5BAA3E009844A9 /* collision.s */, 70F086A01F4230CB002446C3 /* utility.s */, @@ -81,7 +82,6 @@ 708D1B1E27B9A1A600909AFC /* crosshair.s */, 70A80FB01F43D7F200BD34C9 /* gamemanager.s */, 70E554C41F807ADB00F3C871 /* spritebank.s */, - 70E9D8611F2BD95400555C19 /* gscats.s */, 70E9D8631F2BD95400555C19 /* Makefile */, 70BDCBC92006AD5F00CB51F1 /* linkerConfig */, 701E708A2A649A230030C35D /* tinyNumbers.s */, diff --git a/Makefile b/Makefile index 291f831..0c9d905 100644 --- a/Makefile +++ b/Makefile @@ -14,13 +14,13 @@ VOLNAME=GSAPP IMG=DiskImageParts EMU=/Applications/GSplus.app/Contents/MacOS/gsplus ADDR=0800 + CODEBANK=CODEBANK\#060000 -CODEBANKE1=CODEBANKE1\#060800 EXEC=$(PGM)\#06$(ADDR) SOUNDBANK=SOUNDBANK\#060000 FONTBANK=FONTBANK\#060000 - PGM=gscats + MRSPRITE=../MrSprite/mrsprite GENART=Art/Generated GENSOUND=Sound/Generated @@ -29,9 +29,9 @@ PALETTE=a4dffb a4dffb 008800 886611 cc9933 eebb44 dd6666 ff99aa 777777 ff0000 b7 SPRITES=SpriteBank SPRITEBANK=$(SPRITES)\#060000 FLIPLIST=$(wildcard Art/*Fan.gif) $(wildcard Art/*Spit*.gif) -REMOTESYMBOLS=-Wl $(shell ./ParseMapFile.py *.map) +REMOTESYMBOLS= # -Wl $(shell ./ParseMapFile.py *.map) <- Use this to share symbols across code banks -all: clean diskimage terrain_e1 fonts $(PGM) loader emulate +all: clean diskimage fonts $(PGM) loader emulate emulate: # Leading hypen needed because GSPlus maddeningly returns code 1 (error) always and for no reason @@ -51,24 +51,16 @@ $(PGM): $(CAD) ADDFILE $(PGM).2mg /$(VOLNAME) $(SPRITEBANK) $(CAD) ADDFILE $(PGM).2mg /$(VOLNAME) $(SOUNDBANK) $(CAD) ADDFILE $(PGM).2mg /$(VOLNAME) $(FONTBANK) - rm -f $(CODEBANK) rm -f $(FONTBANK) rm -f $(PGM).o - rm -f terrain_e1.map - + loader: @PATH=$(PATH):/usr/local/bin; $(CL65) -t apple2enh --cpu 65816 --start-addr $(ADDR) -lloader.lst loader.s -o $(EXEC) $(CAD) ADDFILE $(PGM).2mg /$(VOLNAME) $(EXEC) rm -f $(EXEC) rm -f loader.o -terrain_e1: - @PATH=$(PATH):/usr/local/bin; $(CL65) -t apple2enh -C linkerConfig --cpu 65816 --start-addr $(ADDR) -l -vm -m terrain_e1.map terrain_e1.s -o $(CODEBANKE1) - $(CAD) ADDFILE $(PGM).2mg /$(VOLNAME) $(CODEBANKE1) - rm -f $(CODEBANKE1) - rm -f terrain_e1.o - fonts: rm -rf $(FONTBANK) ./CompileFont.py 4 5 48 0 "tinyNum" "Art/Assets/TinyNumbers.gif" > fonts.s @@ -82,9 +74,6 @@ clean: rm -f $(PGM).o rm -f loader rm -f loader.o - rm -f terrain_e1.o - rm -f terrain_e1.map - rm -f terrain_e1 rm -f Art/*m.gif rm -f $(GENART)/* rm -f $(PGM).2mg diff --git a/equates.s b/equates.s index 3b7319c..2c335dd 100644 --- a/equates.s +++ b/equates.s @@ -13,6 +13,8 @@ VRAMBANK = $e10000 SHADOWVRAMBANK = $010000 PRODOS = $bf00 ; MLI entry point PRODOSRETURN = $300 ; Indirect jump to get back to ProDOS from any bank +BORDERCOLORCACHE= $304 ; Save system border color so we can put it back +TEXTCOLORCACHE = $306 ; Save system text colors so we can put it back ENSONIQ_CONTROL = $e1c03c ; Ensoniq-related registers/locations ENSONIQ_DATA = $e1c03d diff --git a/gscats.s b/gscats.s index 6cb1bb0..402cc7f 100644 --- a/gscats.s +++ b/gscats.s @@ -20,12 +20,7 @@ mainBank2: BITS8 lda #$f0 sta TEXTCOLOR - BITS16 - - ; Set up video - jsr initSCBs - SHRVIDEO - SHADOWMEMORY + BITS16 jmp beginGameplay diff --git a/loader.s b/loader.s index 938b7f3..5458d8b 100644 --- a/loader.s +++ b/loader.s @@ -6,6 +6,9 @@ ; Created by Quinn Dunki on 7/29/17 ; +.a16 +.i16 + .include "equates.s" .include "macros.s" @@ -15,8 +18,48 @@ MAINENTRY = $020000 .org $800 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; BORDER_COLOR +; +; Trashes A +; +.macro BORDER_COLOR color + SAVE_AXY + BITS8 + lda BORDERCOLOR + and #$f0 + ora color + sta BORDERCOLOR + BITS16 + RESTORE_AXY +.endmacro + + main: - OP8 ; We launch in emulation. Stay there for now + BITS16 + NATIVE + SHRVIDEO + SHADOWMEMORY + + ; Cache system colors + BITS8 + lda BORDERCOLOR + sta BORDERCOLORCACHE + lda TEXTCOLOR + sta TEXTCOLORCACHE + BITS16 + + ; Throw up a loading screen + lda #loaderPalette + sta PARAML0 + lda #0 + jsr setPalette +; jsr initSCBs + BORDER_COLOR #$7 + lda #$1111 + jsr slowColorFill + + EMULATION ; Open the main code file jsr PRODOS @@ -50,6 +93,11 @@ main: .byte $cc .addr fileClose + bra mainContinue +ioError: + brk + +mainContinue: NATIVE ; Copy rest of code into bank 2 (needed if code size exceeds BUFFERSIZE) @@ -60,59 +108,6 @@ main: EMULATION -;;;;;;;;;;;;;;;;;;;;; - - ; Open the E1 code file - jsr PRODOS - .byte $c8 - .addr fileOpenCodeE1 - bne ioError - - ; Load the code into bank 0 - jsr PRODOS - .byte $ca - .addr fileRead - bne ioError - - ; Close the file - jsr PRODOS - .byte $cc - .addr fileClose - - jmp loadData - ; Note that we skip E1 code bank loading now. This was used for the - ; fill mode terrain renderer, which is disabled until further notice - ; There isn't enough safe room in E1 to do everything we wanted and the fill - ; mode rendering isn't useful enough to keep - - NATIVE - - ; Copy code into bank E1 - ldx fileReadLen - lda #$E1 - ldy #$800 ; Must match terrain_e1 .org - jsr copyBytes - - - ; Copy vram table into bank E1 - ; Note that there's a GS memory manager jump table at 1680 - 16BB - ; in E1 that we have to work around. If we step on it, warm reboots and other - ; critical things start to fail. - phb - lda #vramRowInvertedSpanLookupEnd-vramRowInvertedSpanLookup-1 - ldx #vramRowInvertedSpanLookupEnd-1 - ldy #$16C0 + vramRowInvertedSpanLookupEnd-vramRowInvertedSpanLookup-1 ; Must match terrain_e1 vramRowInvertedSpanLookup - mvp $e1,$00 ; Note that ca65 reverses src,dest. Grrr. - plb - - EMULATION - - -ioError: - brk - -;;;;;;;;;;;;;;;;;;;;; -loadData: ; Open the sprite bank file jsr PRODOS .byte $c8 @@ -238,30 +233,26 @@ loadData: sta PRODOSRETURN jml MAINENTRY - + returnToProDOS: SYNCDBR EMULATION + + ; Restore system colors + lda BORDERCOLOR + and #$f0 + ora BORDERCOLORCACHE + sta BORDERCOLOR + lda TEXTCOLORCACHE + sta TEXTCOLOR rts ioErrorJmp: jmp ioError -; This table lives here in the loader because we need to copy -; it to a specific free hole in bank E1 -vramRowInvertedSpanLookup: - .word $9d00,$9c60,$9bc0,$9b20,$9a80,$99e0,$9940,$98a0,$9800,$9760,$96c0,$9620,$9580,$94e0,$9440,$93a0,$9300,$9260,$91c0,$9120 - .word $9080,$8fe0,$8f40,$8ea0,$8e00,$8d60,$8cc0,$8c20,$8b80,$8ae0,$8a40,$89a0,$8900,$8860,$87c0,$8720,$8680,$85e0,$8540,$84a0 - .word $8400,$8360,$82c0,$8220,$8180,$80e0,$8040,$7fa0,$7f00,$7e60,$7dc0,$7d20,$7c80,$7be0,$7b40,$7aa0,$7a00,$7960,$78c0,$7820 - .word $7780,$76e0,$7640,$75a0,$7500,$7460,$73c0,$7320,$7280,$71e0,$7140,$70a0,$7000,$6f60,$6ec0,$6e20,$6d80,$6ce0,$6c40,$6ba0 - .word $6b00,$6a60,$69c0,$6920,$6880,$67e0,$6740,$66a0,$6600,$6560,$64c0,$6420,$6380,$62e0,$6240,$61a0,$6100,$6060,$5fc0,$5f20 - .word $5e80,$5de0,$5d40,$5ca0,$5c00,$5b60,$5ac0,$5a20,$5980,$58e0,$5840,$57a0,$5700,$5660,$55c0,$5520,$5480,$53e0,$5340,$52a0 - .word $5200,$5160,$50c0,$5020,$4f80,$4ee0,$4e40,$4da0,$4d00,$4c60,$4bc0,$4b20,$4a80,$49e0,$4940,$48a0,$4800,$4760,$46c0,$4620 - .word $4580,$44e0,$4440,$43a0,$4300,$4260,$41c0,$4120,$4080,$3fe0,$3f40,$3ea0,$3e00,$3d60,$3cc0,$3c20,$3b80,$3ae0,$3a40,$39a0 - .word $3900,$3860,$37c0,$3720,$3680,$35e0,$3540,$34a0,$3400,$3360,$32c0,$3220,$3180,$30e0,$3040,$2fa0,$2f00,$2e60,$2dc0,$2d20 - .word $2c80,$2be0,$2b40,$2aa0,$2a00,$2960,$28c0,$2820,$2780,$26e0,$2640,$25a0,$2500,$2460,$23c0,$2320,$2280,$21e0,$2140,$20a0 -vramRowInvertedSpanLookupEnd: +loaderPalette: + .word $0aef,$06af,$0080,$0861,$0c93,$0eb4,$0d66,$0f9a,$0777,$0f00,$0bbb,$ddd,$007b,$0a5b,$0000,$0fff ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -329,13 +320,6 @@ fileOpenCode: .byte 0 ; Result (file handle) .byte 0 ; Padding -fileOpenCodeE1: - .byte 3 - .addr codePathE1 - .addr $9200 ; 1k below BASIC.SYSTEM - .byte 0 ; Result (file handle) - .byte 0 ; Padding - fileRead: .byte 4 .byte 1 ; File handle (we know it's gonna be 1) @@ -371,11 +355,11 @@ fileOpenFonts: codePath: pstring "/GSAPP/CODEBANK" -codePathE1: - pstring "/GSAPP/CODEBANKE1" spritePath: pstring "/GSAPP/SPRITEBANK" soundPath: pstring "/GSAPP/SOUNDBANK" fontPath: pstring "/GSAPP/FONTBANK" + +.include "loaderGraphics.s" diff --git a/loaderGraphics.s b/loaderGraphics.s new file mode 100644 index 0000000..9fde7ab --- /dev/null +++ b/loaderGraphics.s @@ -0,0 +1,164 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; slowColorFill +; Fills the screen with a color (or two). Slow because it has to run from +; bank 0 on the slow graphics path +; +; A = 4:4:4:4 = Palette entries to fill +; +; Trashes X,Y + +slowColorFill: + ldy #200 + ldx #$2000 + +slowColorFillLoop: + ; 80 STAs, for 1 line + ; sta VRAMBANK,x inx inx + .byte $9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8 + .byte $9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8 + .byte $9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8 + .byte $9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8 + .byte $9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8 + .byte $9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8 + .byte $9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8 + .byte $9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8 + .byte $9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8 + .byte $9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8,$9F,$00,$00,$E1,$e8,$e8 + + dey + beq slowColorFillLoopDone + jmp slowColorFillLoop + +slowColorFillLoopDone: + rts + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; initSCBs +; Initialize all scanline control bytes +; +; Trashes A,X + +initSCBs: + lda #0 + ldx #$0100 ;set all $100 scbs to A + +initSCBsLoop: + dex + dex + sta $e19d00,x + bne initSCBsLoop + rts + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; setScanlinePalette +; Set the palette for a given scan line +; +; PARAML0 = Palette index +; X = Start scan line +; Y = Count + +setScanlinePalette: + pha + +setScanlinePaletteLoop: + lda $e19d00,x + ora PARAML0 + sta $e19d00,x + inx + dey + bne setScanlinePaletteLoop + + pla + rts + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; setPalette +; Set all colors in a palette from memory +; PARAML0 = Pointer to 32 color bytes +; A = Palette index +; +setPalette: + SAVE_XY + + asl + asl + asl + asl + asl + BITS8A + sta setPaletteLoop_SMC+1 + BITS16 + ldx #0 + ldy #0 + +setPaletteLoop: + lda (PARAML0),y +setPaletteLoop_SMC: + sta $e19e00,x ; Self-modifying code! + + iny + iny + inx + inx + cpx #32 + bne setPaletteLoop + + RESTORE_XY + rts + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Vertical blank checkers +; + +; The Brutal Deluxe version, taken from LemminGS +; +nextVBL: + lda #75 + pha +nextVBL0: + lda $e0c02e + and #$7f + cmp 1,s + blt nextVBL0 + cmp #100 + bge nextVBL0 + pla +waitVBL: + lda $e0c018 + bpl waitVBL + rts + + +; The Apple version, taken from GS Tech Note 039 +; +syncVBL: + ;sei + BITS8 +syncVBL0: + ldaA $C02f + asl ; VA is now in the Carry flag + ldaA $C02e + rol ; Roll Carry into bit 0 + cmp #200 ; A now contains line number + blt syncVBL0 + BITS16 + ;cli + rts + +; The old style //e version +; +vblSync: + BITS8 + +waitVBLToFinish: + lda $E0C019 + bmi waitVBLToFinish +waitVBLToStart: + lda $E0C019 + bpl waitVBLToStart + + BITS16 + rts diff --git a/terrain_e1.s b/terrain_e1.s deleted file mode 100644 index 180535b..0000000 --- a/terrain_e1.s +++ /dev/null @@ -1,297 +0,0 @@ -; -; terrain (in E1 bank) -; -; Fill-mode terrain rendering code snippets -; that live in bank E1 for maximum speed. -; -; Created by Quinn Dunki on 7/29/17 -; - -.include "equates.s" -.include "macros.s" - -UNRENDERCACHESTACK = $7ff ; Stack downwards from bottom of VRAM. Mirrored from $01 into $E1! - -OP16 - -.org $800 - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; renderTerrainSpans: -; -; -renderTerrainSpans: - SAVE_AXY - SAVE_DBR - FASTGRAPHICS - - lda #UNRENDERCACHESTACK ; Prepare unrender cache - tcs - - lda #MAXTERRAINHEIGHT-1 - sec - sbc lastCompiledTerrainY - beq renderTerrainRowSpansSkip ; All terrain needs compiled rendering - -renderTerrainSpansLoop: - sta PARAML1 - - ; Find row data - lda PARAML1 - asl ; Shifts must match SPANROWBYTES - asl - asl - asl - asl - tay - lda terrainSpanData,y - sta SCRATCHL ; Track span color - - ; Find VRAM row - lda PARAML1 - asl - tax - lda vramRowInvertedSpanLookup,x - tax - - adc #160 - sta PARAML0 ; Watch for end of VRAM row - - ; Find span that intersects left logical edge - lda #0 - clc - -renderTerrainRowSpansFindLeftLoop: - adc terrainSpanData+2,y - cmp leftScreenEdge - bpl renderTerrainRowSpansFoundLeft - iny - iny - sta CACHEDATA - lda SCRATCHL - eor #%110000 ; Toggle span color cache - sta SCRATCHL - lda CACHEDATA - bra renderTerrainRowSpansFindLeftLoop - -renderTerrainRowSpansFoundLeft: - sec - sbc leftScreenEdge ; A now holds remainder of leftmost span - ; and Y points to leftmost span - -renderTerrainRowSpansLoop: - sta SCRATCHL2 - - ; Set fill mode byte for this span - lda SCRATCHL - sta VRAMBANK,x - - ; Cache the index we wrote to so we can erase later - phx - - ; Advance to end of span - clc - txa - adc SCRATCHL2 - cmp PARAML0 - bpl renderTerrainRowSpansDone - tax - - ; Prepare for next span - iny - iny - lda SCRATCHL - eor #%110000 ; Toggle span color cache - sta SCRATCHL - - lda terrainSpanData+2,y - bra renderTerrainRowSpansLoop - -renderTerrainRowSpansDone: - lda PARAML1 - dec - bne renderTerrainSpansLoop - - pea 0 ; Null-terminate the unrender cache - -renderTerrainRowSpansSkip: - SLOWGRAPHICS - RESTORE_DBR - RESTORE_AXY - rtl - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; unrenderTerrainSpans: -; -; - -unrenderTerrainSpans: - SAVE_AXY - SAVE_DBR - phb - pea $e1e1 ; Work entirely in bank E1 for all local read/writes - plb - plb - - ldy #UNRENDERCACHESTACK-1 - -unrenderTerrainSpansLoop: - lda 0,y - beq unrenderTerrainSpansDone - tax - lda #0 - sta a:0,x - dey - dey - bra unrenderTerrainSpansLoop - -unrenderTerrainSpansDone: - plb - RESTORE_DBR - RESTORE_AXY - rtl - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; compileTerrainSpans: -; -; -compileTerrainSpans: - pha - SAVE_DBR - lda #0 - -compileTerrainSpansLoop: - sta PARAML1 - jsr compileTerrainSpansRow - lda PARAML1 - inc - cmp #MAXTERRAINHEIGHT - bne compileTerrainSpansLoop - - RESTORE_DBR - pla - rtl - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; compileTerrainSpansRow: -; -; PARAML1 = Row index (bottom relative) -; -; Trashes SCRATCHL -; -compileTerrainSpansRow: - SAVE_AXY - - lda PARAML1 - asl ; Shifts must match SPANROWBYTES - asl - asl - asl - asl - clc - adc #terrainSpanData - sta SCRATCHL - - ldy #0 - ldx #TERRAINWIDTH-2 - - lda terrainDataFar,x ; Figure out start value for row - cmp PARAML1 - bcs compileTerrainSpansRowInitGreen - -compileTerrainSpansRowInitBlack: - lda #$0010 ; First span is black - sta (SCRATCHL) ; Initialize the row - inc SCRATCHL - inc SCRATCHL - ldy #-1 - -compileTerrainSpansRowBlackStart: - iny - -compileTerrainSpansRowBlackLoop: - lda terrainDataFar,x - cmp PARAML1 - bcs compileTerrainSpansBlackEnd - dex - dex - iny - cpx #-2 - bne compileTerrainSpansRowBlackLoop - -compileTerrainSpansBlackEnd: - tya ; Store this span's length - sta (SCRATCHL) - inc SCRATCHL - inc SCRATCHL - - dex ; Begin searching for next span - dex - cpx #0 - bmi compileTerrainSpansRowDone - ldy #0 - bra compileTerrainSpansRowGreenStart - -compileTerrainSpansRowDone: - RESTORE_AXY - rts - -compileTerrainSpansRowInitGreen: - lda #$0020 ; First span is green - sta (SCRATCHL) ; Initialize the row - inc SCRATCHL - inc SCRATCHL - ldy #-1 - -compileTerrainSpansRowGreenStart: - iny - -compileTerrainSpansRowGreenLoop: - lda terrainDataFar,x - cmp PARAML1 - bcc compileTerrainSpansGreenEnd - dex - dex - iny - cpx #-2 - bne compileTerrainSpansRowGreenLoop - -compileTerrainSpansGreenEnd: - tya ; Store this span's length - sta (SCRATCHL) - inc SCRATCHL - inc SCRATCHL - - dex ; Begin searching for next span - dex - cpx #0 - bmi compileTerrainSpansRowDone - ldy #0 - bra compileTerrainSpansRowBlackStart - -terrainSpanData: - .repeat MAXTERRAINHEIGHT - .word 0 ; Start value (0=BG) - .repeat MAXSPANSPERROW - .word 0 ; Length (in bytes) - .endrepeat - .endrepeat - - -vramRowInvertedSpanLookup = $16C0 ; This table is copied to here by the loader - - -.export renderTerrainSpans -.export unrenderTerrainSpans -.export compileTerrainSpans - - -; Suppress some linker warnings - Must be the last thing in the file -.SEGMENT "ZPSAVE" -.SEGMENT "EXEHDR" -.SEGMENT "STARTUP" -.SEGMENT "INIT" -.SEGMENT "LOWCODE"