diff --git a/ORCACDefs/gte.h b/ORCACDefs/gte.h index 3af4406..e0103d2 100644 --- a/ORCACDefs/gte.h +++ b/ORCACDefs/gte.h @@ -104,6 +104,8 @@ extern pascal void GTEClearBG1Buffer(Word value) inline(0x29A0, tool_dispatcher) /* GTE Misc. Functions */ extern pascal Word GTEReadControl(void) inline(0x09A0, tool_dispatcher); extern pascal Word GTEGetSeconds(void) inline(0x14A0, tool_dispatcher); +extern pascal Pointer GTEGetAddress(Word tableId) inline(0x2CA0, tool_dispatcher); +extern pascal void GTESetAddress(Word tableId, Pointer pointer) inline(0x2EA0, tool_dispatcher); /* GTE Timer Functions */ diff --git a/demos/kfest-2022/demo-1/App.Main.s b/demos/kfest-2022/demo-1/App.Main.s index 6ad1f60..44d6d02 100644 --- a/demos/kfest-2022/demo-1/App.Main.s +++ b/demos/kfest-2022/demo-1/App.Main.s @@ -35,6 +35,7 @@ MaxGlobalX equ 16 MaxGlobalY equ 18 MaxBG0X equ 20 MaxBG0Y equ 22 +frameCount equ 24 OldOneSecondCounter equ 26 appTmp0 equ 28 @@ -74,6 +75,10 @@ appTmp0 equ 28 jsr BG0SetUp jsr SetLimits + pea #80 + pei MaxBG0Y + _GTESetBG0Origin + lda #193 ; Tile ID of '0' jsr InitOverlay ; Initialize the status bar pha @@ -82,6 +87,18 @@ appTmp0 equ 28 sta OldOneSecondCounter jsr UdtOverlay +; Set up the per-scanline rendering + + lda #0 + jsr InitOffsets + pea #scanlineHorzOffset + pea #^BG0Offsets + pea #BG0Offsets + _GTESetAddress + + pea $0000 ; one regular render to fill the screen with the tilemap + _GTERender + ; Set up a very specific test. First, we draw a sprite into the sprite plane, and then ; leave it alone. We are just testing the ability to merge sprite plane data into ; the play field tiles. @@ -102,9 +119,11 @@ EvtLoop bcc *+5 brl :do_render inc StartX - pei StartX - pei StartY - _GTESetBG0Origin + lda StartX + jsr SetOffsets +; pei StartX +; pei StartY +; _GTESetBG0Origin brl :do_render :not_d @@ -114,9 +133,11 @@ EvtLoop bne *+5 brl :do_render dec StartX - pei StartX - pei StartY - _GTESetBG0Origin + lda StartX + jsr SetOffsets +; pei StartX +; pei StartY +; _GTESetBG0Origin brl :do_render :not_a @@ -144,7 +165,7 @@ EvtLoop :not_w :do_render - pea $0000 + pea #RENDER_PER_SCANLINE _GTERender ; Update the performance counters @@ -234,7 +255,85 @@ SetLimits rts -frameCount equ 24 +SetOffsets + and #$00FF + brl _SetOffsets + +InitOffsets + and #$00FF + sta appTmp0 + + ldx #0 + ldy #80 + jsr _InitRange + ldx #80 + ldy #80 + jsr _InitRange + ldx #160 + ldy #48 + jsr _InitRange + + lda appTmp0 +_SetOffsets + ldx #160 + ldy #48 + jsr _SetRange + lsr + ldx #80 + ldy #80 + jsr _SetRange + lsr + ldx #0 + ldy #80 + jsr _SetRange + rts + +_SetRange + pha + + txa + asl + tax + +:loop2 lda BG0Offsets,x + and #$FF00 + ora 1,s + sta BG0Offsets,x + + dey + beq :done + + inx + inx + cpx #416 + bcc :loop2 +:done + pla + rts + +_InitRange + txa + asl + tax + + tya + dec + and #$00FF + xba + +:loop1 sta BG0Offsets,x + sec + sbc #$0100 + dey + beq :done + inx + inx + cpx #416 + bcc :loop1 +:done + rts + +BG0Offsets ds 416 PUT ../StartUp.s PUT ../../shell/Overlay.s diff --git a/macros/GTE.Macs.s b/macros/GTE.Macs.s index 46ca6b1..0e9e976 100644 --- a/macros/GTE.Macs.s +++ b/macros/GTE.Macs.s @@ -132,6 +132,9 @@ _GTEGetAddress MAC _GTECompileSpriteStamp MAC UserTool $2D00+GTEToolNum <<< +_GTESetAddress MAC + UserTool $2E00+GTEToolNum + <<< ; EngineMode definitions ; Script definition diff --git a/src/CoreImpl.s b/src/CoreImpl.s index 7041f82..18a2ac9 100644 --- a/src/CoreImpl.s +++ b/src/CoreImpl.s @@ -251,13 +251,13 @@ EngineReset bne :loop ; Set the scanline tables to reasonable default values - ldx #{416*2}-2 - lda #0 -:sxm_loop - sta StartXMod164Arr,x - dex - dex - bpl :sxm_loop +; ldx #{416*2}-2 +; lda #0 +;:sxm_loop +; sta StartXMod164Arr,x +; dex +; dex +; bpl :sxm_loop rts diff --git a/src/Defs.s b/src/Defs.s index 7134be2..c642db1 100644 --- a/src/Defs.s +++ b/src/Defs.s @@ -102,7 +102,9 @@ RenderFlags equ 124 ; Flags passed to the Render() function BG1Scaling equ 126 activeSpriteList equ 128 ; 32 bytes for the active sprite list (can persist across frames) -; tiletmp equ 178 ; 16 bytes of temp storage for the tile renderers + +; Free space from 160 to 192 + blttmp equ 192 ; 32 bytes of local cache/scratch space for blitter tmp8 equ 224 ; another 16 bytes of temporary space to be used as scratch @@ -282,8 +284,8 @@ VBuffHorzTableSelect EXT BG1YCache EXT ScalingTables EXT -StartXMod164Arr EXT -LastPatchOffsetArr EXT +;StartXMod164Arr EXT +;LastPatchOffsetArr EXT _SortedHead EXT _ShadowListCount EXT @@ -294,6 +296,7 @@ _DirectListTop EXT _DirectListBottom EXT StartXMod164Tbl EXT +LastOffsetTbl EXT ; Tool error codes NO_TIMERS_AVAILABLE equ 10 diff --git a/src/Render.s b/src/Render.s index ab2d3ef..73959e6 100644 --- a/src/Render.s +++ b/src/Render.s @@ -169,7 +169,17 @@ _RenderScanlines ; jsr _ApplyTiles ; This function actually draws the new tiles into the code field - jsr _ScanlineBG0XPos ; Patch the code field instructions with exit BRA opcode + jsr _ApplyScanlineBG0XPos ; Patch the code field instructions with exit BRA opcode + + jsr _BuildShadowList ; Create the rages based on the sorted sprite y-values + + jsr _ShadowOff ; Turn off shadowing and draw all the scanlines with sprites on them + jsr _DrawShadowList + jsr _DrawDirectSprites ; Draw the sprites directly to the Bank $01 graphics buffer (skipping the render-to-tile step) + + jsr _ShadowOn ; Turn shadowing back on +; jsr _DrawComplementList ; Alternate drawing scanlines and PEI slam to expose the full fram + jsr _DrawFinalPass ; jsr _ApplyBG1XPos ; Update the direct page value based on the horizontal position @@ -209,11 +219,11 @@ _RenderScanlines ; jsr _BltRange ; bra :done -:no_ovrly - ldx #0 ; Blit the full virtual buffer to the screen - ldy ScreenHeight - jsr _BltRange -:done +;:no_ovrly +; ldx #0 ; Blit the full virtual buffer to the screen +; ldy ScreenHeight +; jsr _BltRange +;:done ; ldx #0 ; ldy ScreenHeight diff --git a/src/Tool.s b/src/Tool.s index d442127..814b09c 100644 --- a/src/Tool.s +++ b/src/Tool.s @@ -99,6 +99,7 @@ _CallTable adrl _TSGetAddress-1 adrl _TSCompileSpriteStamp-1 + adrl _TSSetAddress-1 _CTEnd _GTEAddSprite MAC @@ -302,6 +303,12 @@ _TSRender bra :done :no_shadowing + bit #RENDER_PER_SCANLINE + beq :no_scanline + jsr _RenderScanlines + bra :done + +:no_scanline jsr _Render :done @@ -865,27 +872,45 @@ _TSSetBG1Scale sta BG1Scaling _TSExit #0;#2 +; Pointer GetAddress(tblId) _TSGetAddress -:output equ FirstParam+0 -:tblId equ FirstParam+4 +:tblId equ FirstParam+0 +:output equ FirstParam+2 _TSEntry lda #0 sta :output,s sta :output+2,s - lda :value,s + lda :tblId,s cmp #scanlineHorzOffset bne :out - lda #StartXMod164Arr + lda StartXMod164Tbl sta :output,s - lda #^StartXMod164Arr + lda StartXMod164Tbl+2 sta :output+2,s :out _TSExit #0;#2 +; SetAddress(tblId, Pointer) +_TSSetAddress +:ptr equ FirstParam+0 +:tblId equ FirstParam+4 + + _TSEntry + lda :tblId,s + cmp #scanlineHorzOffset + bne :out + + lda :ptr,s + sta StartXMod164Tbl + lda :ptr+2,s + sta StartXMod164Tbl+2 +:out + _TSExit #0;#6 + ; CompileSpriteStamp(spriteId, vbuffAddr) _TSCompileSpriteStamp :vbuff equ FirstParam @@ -916,7 +941,7 @@ _TSCompileSpriteStamp put Sprite2.s put SpriteRender.s put Render.s - put blitter/Scanline.s +; put blitter/Scanline.s put render/Render.s put render/Fast.s put render/Slow.s diff --git a/src/blitter/Horz.s b/src/blitter/Horz.s index 3655e53..5e3f4aa 100644 --- a/src/blitter/Horz.s +++ b/src/blitter/Horz.s @@ -50,11 +50,7 @@ _RestoreBG0Opcodes :virt_line_x2 equ tmp1 :lines_left_x2 equ tmp2 -:draw_count_x2 equ tmp3 :exit_offset equ tmp4 -:stk_save equ tmp5 - - phb ; Save data bank asl sta :virt_line_x2 ; Keep track of it @@ -66,6 +62,14 @@ _RestoreBG0Opcodes lda LastPatchOffset ; If zero, there are no saved opcodes sta :exit_offset +_RestoreBG0OpcodesAlt +:virt_line_x2 equ tmp1 +:lines_left_x2 equ tmp2 +:draw_count_x2 equ tmp3 +:exit_offset equ tmp4 +:stk_save equ tmp5 + + phb ; Save data bank tsc sta :stk_save @@ -144,18 +148,8 @@ _ApplyBG0XPosPre rts _ApplyBG0XPos - -:stk_save equ tmp0 :virt_line_x2 equ tmp1 :lines_left_x2 equ tmp2 -:draw_count_x2 equ tmp3 -:exit_offset equ tmp4 -:entry_offset equ tmp5 -:exit_bra equ tmp6 -:exit_address equ tmp7 -:base_address equ tmp8 -:opcode equ tmp9 -:odd_entry_offset equ tmp10 ; If there are saved opcodes that have not been restored, do not run this routine lda LastPatchOffset @@ -232,6 +226,21 @@ _ApplyBG0XPos ; +-----------+ lda StartXMod164 + +; Alternate entry point if the virt_line_x2 and lines_left_x2 and XMod164 values are passed in externally +_ApplyBG0XPosAlt +:stk_save equ tmp0 +:virt_line_x2 equ tmp1 +:lines_left_x2 equ tmp2 +:draw_count_x2 equ tmp3 +:exit_offset equ tmp4 +:entry_offset equ tmp5 +:exit_bra equ tmp6 +:exit_address equ tmp7 +:base_address equ tmp8 +:opcode equ tmp9 +:odd_entry_offset equ tmp10 + bit #$0001 jne :odd_case ; Specialized routines for even/odd cases @@ -368,7 +377,7 @@ _ApplyBG0XPos sbc #164 tax - lda Col2CodeOffset-1,x + lda Col2CodeOffset-1,x ; Odd offset to get the value in the high byte and #$FF00 ora #$00AF sta :opcode @@ -445,361 +454,148 @@ _ApplyBG0XPos plb rts +_RestoreScanlineBG0Opcodes +:virt_line_x2 equ tmp1 +:lines_left_x2 equ tmp2 +:exit_offset equ tmp4 + +; Avoid local var collisions +:virt_line_pos_x2 equ tmp11 +:total_left_x2 equ tmp12 +:current_count_x2 equ tmp13 +:ptr equ tmp14 + + asl + sta :virt_line_pos_x2 + tay + + txa + asl + sta :total_left_x2 + + lda StartXMod164Tbl + sta :ptr + lda StartXMod164Tbl+2 + sta :ptr+2 + +; Patch our the ranges from the StartXMod164Tbl array starting at the first virtual line +:loop + lda [:ptr],y + and #$FF00 ; Determine how many sequential lines to restore + xba + inc + asl + min :total_left_x2 ; Don't draw more than the number of lines that are left to process + sta :current_count_x2 ; Save a copy for later + + sta :lines_left_x2 ; Set the parameter + sty :virt_line_x2 ; Set the parameter + lda LastOffsetTbl,y + sta :exit_offset + jsr _RestoreBG0OpcodesAlt + + clc + lda :virt_line_pos_x2 + adc :current_count_x2 + cmp #208*2 ; Do the modulo check in this loop + bcc *+5 + sbc #208*2 + sta :virt_line_pos_x2 + tay + + lda :total_left_x2 + sec + sbc :current_count_x2 + sta :total_left_x2 + bne :loop + + rts + ; This is a variant of the above routine that allows each x-position to be set independently from a table of value. This is ; quite a bit slower than the other routine since we cannot store constant values for each line. ; -; We still want to perform operation in blocks of 16 to avoid repeatedly setting the data bank register for each line. In -; order to accomplish this, the even/odd cases are split into separate code blocks and the unrolled loop will patch up -; all of the memory locations on each line, rather than doing each patch one at a time. This may actually be more efficient -; since it eliminates several jmp (abs,x) / tax instructions and removed some register reloading. +; This routine operates at a higher level and does not try to be super optimized for the case where every line has a different +; set of parameters. Instead, we optimize for the case where there are a few large ranges of the screen moving at different +; rates, e.g. a fixed status bar area on top, a slow-scrolling area in the middle and a fast are in the foreground. ; -; The two unrolled loop elements are: +; The table that drives this is dense and has the following format for each word ; -; Even: -; lda: $0000,x ; Load from X = BTableLow + exit_offset -; sta: OPCODE_SAVE,y ; Save the two byte in another area of the line code -; lda :exit_bra[n] -; sta $0000,x ; Replace the two bytes with a BRA instruction to exit the blitter -; lda :opcode[n] -; sta: CODE_ENTRY_OPCODE,y ; CODE_ENTRY_OPCODE and CODE_ENTRY are adjacent -- could make this a single 16-bit store +; Bits 0 - 7: X mod 164 value +; Bits 8 - 15: Number of scanline to persist this mod value ; -; Odd: -; Same as above, plus... -; lda :odd_entry_offset[n] ; [8-bit] Get back into the code after fixing up the odd edge -; sta: ODD_ENTRY,y -; lda: $0001,x ; Save the high word in case the last instruction is PEA and we need to load the top byte -; sta: OPCODE_HIGH_SAVE,y -; -_ApplyBG0XPosPerScanline -:stk_save equ tmp0 +; So, if the first 10 entries has a mod value of 5, they would look like: $0905, $0805, $0705, ... $0105, $0005 +; +; This allows the code to start an an arbitrary location and immeditely sync up with the modulo list. It also allows +; the code to easily skip ranges of constant values using the existing _ApplyBG0XPos function as a subroutine. +_ApplyScanlineBG0XPos + +; Copies of the local variables in _ApplyBG0XPos :virt_line_x2 equ tmp1 :lines_left_x2 equ tmp2 -:draw_count_x2 equ tmp3 :exit_offset equ tmp4 -:entry_offset equ tmp5 -:exit_bra equ tmp6 -:exit_address equ tmp7 -:base_address equ tmp8 -:opcode equ tmp9 -:odd_entry_offset equ tmp10 -; If there are saved opcodes that have not been restored, do not run this routine - lda LastPatchOffset - beq :ok +; Avoid local var collision with _ApplyBG0XPos +:virt_line_pos_x2 equ tmp11 +:total_left_x2 equ tmp12 +:current_count_x2 equ tmp13 +:ptr equ tmp14 + + lda StartXMod164Tbl + sta :ptr + lda StartXMod164Tbl+2 + sta :ptr+2 + ora :ptr + bne *+3 ; null pointer check rts -; In this routine, basically every horizontal parameter is based off of the :virt_line_x2 index -:ok lda StartYMod208 ; This is the base line of the virtual screen asl - sta :virt_line_x2 ; Keep track of it + sta :virt_line_pos_x2 + tay lda ScreenHeight asl - sta :lines_left_x2 - -; Sketch out the core structural elements of the loop + bank management - - phb ; Save the existing bank - tsc - sta :stk_save + sta :total_left_x2 +; Patch our the ranges from the StartXMod164Tbl array starting at the first virtual line :loop - ldx :virt_line_x2 - - txa - and #$001E - eor #$FFFF - sec - adc #2*16 ; 2 * (16 - virt_line % 16). This get us aligned to 16-line boundaries - min :lines_left_x2 ; Make sure we handle cases where lines_left < aligned remainder - sta :draw_count_x2 ; We are drawing this many lines on this iteration starting at _virt_line_x2 - - ldal BTableHigh,x ; Set the bank - pha - plb - - jsr :DoScanlineRange ; Patch in the code field for this range (Bank is set) - - lda :draw_count_x2 - clc ; advance to the virtual line after the segment we just - adc :virt_line_x2 ; filled in - sta :virt_line_x2 - - lda :lines_left_x2 ; subtract the number of lines we just completed - sec - sbc :draw_count_x2 - sta :lines_left_x2 - jne :loop - - lda :stk_save - tcs - plb - rts - -; Run through and build an array of scanline data and place it in temporary zero page space. Need a total of 48 bytes. -:BuildScanlineData - -; First step, run though and create the tables for the copy routine - lda StartXMod164Tbl,x - bit #$0001 -; bne :bsd_odd - - tay - lda CodeFieldEvenBRA-2,y ; The exit point comes after the left edge (reverse order due to stack) - sta :exit_bra,x - lda Col2CodeOffset-2,y - sta :exit_offset,x - - -:DoScanlineRange - ldx :virt_line_x2 - -; First, calculate the exit point - - ldal StartXMod164Tbl,x ; Get the origin for this line - bit #$0001 - bne :is_odd ; Quickly switch to specialized even/odd routines - -; For even offsets, the index is x - 2 -; For odd offsets, the index is x - 1 -; -; So, for both we can do (x - 1) & $FFFE = dec / and #$FFFE = lsr / asl + clears the carry - -; This is an even-aligned line - -; dec ; Move to the previous address for entry (a - 1) % 164 -; dec ; Optimization: Coule eliminate this with a double-width tbale for CodeFieldEvenBRA -; bpl *+5 -; lda #162 - - tay - lda CodeFieldEvenBRA-2,y - sta :exit_bra ; Store are exit_offset + - lda Col2CodeOffset-2,y - sta :exit_offset - -; tya -; adc ScreenWidth -; cmp #164 ; Keep the value in range -; bcc *+5 -; sbc #164 -; tay - - lda Col2CodeOffset-2-1,y ; -2 for even case , -1 to load value into high byte - and #$FF00 -; sta :entry_offset - ora #$004C ; set the entry_jmp opcode to JMP - sta :opcode -; stz :odd_entry_offset ; mark as an even case - - ldal BTableLow,x ; Get the address of the code field line - tay ; Save it to use as the base address - clc - adc :exit_offset ; Add some offsets to get the base address in the code field line + lda [:ptr],y tax - clc -; This is the core even patch loop. The y-register tracks the base address of the starting line. Set the x-register -; based on the per-line exit_offset and eveything else references other data + and #$FF00 ; Determine how many sequential lines have this mod value + xba + inc + asl + min :total_left_x2 ; Don't draw more than the number of lines that are left to process + sta :current_count_x2 ; Save a copy for later -; tya -; adc :exit_offset+{]line*2} -; tax -; lda: {]line*$1000},x -; sta: OPCODE_SAVE+{]line*$1000},y -; lda :exit_bra+{]line*2} ; Copy this value into all of the lines -; sta: {]line*$1000},x -; lda :entry_offset+{]line*2} ; Pre-merged with the appropriate opcode + offset -; sta: CODE_ENTRY_OPCODE+{]line*$1000},y + sta :lines_left_x2 ; Set the parameter + sty :virt_line_x2 ; Set the parameter + txa ; Put the X mod 164 value in the accumulator + and #$00FF + jsr _ApplyBG0XPosAlt - bra :prep_complete - -; This is an odd-aligned line -:is_odd - dec ; Remove the least-significant byte (must stay positive) - tay - lda CodeFieldOddBRA,y - sta :exit_bra - lda Col2CodeOffset,y - sta :exit_offset + lda :exit_offset ; Get the direct address in the code field that was overwritten + ldy :virt_line_pos_x2 + sta LastOffsetTbl,y ; Stash it for use by the per-scanline resotre function tya - adc ScreenWidth - cmp #164 ; Keep the value in range - bcc *+5 - sbc #164 - tay - lda Col2CodeOffset,y - sta :entry_offset ; Will be used to load the data - lda Col2CodeOffset-2,y - sta :odd_entry_offset ; will be the actual location to jump to - lda #$00AF ; set the entry_jmp opcode to LDAL - sta :opcode - -:prep_complete - ldal BTableLow,x ; Get the address of the code field line - tay ; Save it to use as the base address clc - adc :exit_offset ; Add some offsets to get the base address in the code field line + adc :current_count_x2 + cmp #208*2 ; Do the modulo check in this loop + bcc *+5 + sbc #208*2 + sta :virt_line_pos_x2 + tay -; sta :exit_address -; sty :base_address - - -; ldy :base_address -; ldx :exit_address ; Save from this location (not needed in fast mode) -; SaveOpcode ; X = :exit_address on return - tax - lda: $0000,x - sta: OPCODE_SAVE+$0000,y - - -; txy ; ldy :exit_address -- starting at this address -; ldx :draw_count_x2 ; Do this many lines - lda :exit_bra ; Copy this value into all of the lines -; SetConst ; All registers are preserved - sta: $0000,x - -; Next, patch in the CODE_ENTRY value, which is the low byte of a JMP instruction. This is an -; 8-bit operation and, since the PEA code is bank aligned, we use the entry_offset value directly - - sep #$20 - - lda :entry_offset -; ldy :base_address -; SetCodeEntry ; All registers are preserved - sta: CODE_ENTRY+$0000,y - -; Now, patch in the opcode - - lda :opcode -; SetCodeEntryOpcode ; All registers are preserved - sta: CODE_ENTRY_OPCODE+$0000,y - -; If this is an odd entry, also set the odd_entry low byte and save the operand high byte - - lda :odd_entry_offset - jeq :not_odd - -; SetOddCodeEntry ; All registers are preserved - sta: ODD_ENTRY+$0000,y -; SaveHighOperand :exit_address ; Only used once, so "inline" it - ldx :exit_address - lda: $0002,x - sta: OPCODE_HIGH_SAVE+$0000,y - -:not_odd - rep #$21 ; clear the carry - - lda :virt_line_x2 ; advance to the virtual line after - adc :draw_count_x2 ; filled in - sta :virt_line_x2 - - lda :lines_left_x2 ; subtract the number of lines we just completed + lda :total_left_x2 sec - sbc :draw_count_x2 - sta :lines_left_x2 - - jne :loop + sbc :current_count_x2 + sta :total_left_x2 + bne :loop rts - -; DoEvenRange -; -; Does all the core operations for an even range (16-bit accumulator and registers) -; -; X = number of lines * 2, 0 to 32 -; Y = starting line * $1000 -; A = code field location * $1000 -DoEvenRange mac - asl ; mult the offset by 2 and clear the carry at the same time - adc #dispTbl - stal patch+1 -patch jmp $0000 -dispTbl jmp bottom - db 1 - jmp x01 - db 1 - jmp x02 - db 1 - jmp x03 - db 1 - jmp x04 - db 1 - jmp x05 - db 1 - jmp x06 - db 1 - jmp x07 - db 1 - jmp x08 - db 1 - jmp x09 - db 1 - jmp x10 - db 1 - jmp x11 - db 1 - jmp x12 - db 1 - jmp x13 - db 1 - jmp x14 - db 1 - jmp x15 - db 1 -x16 tya - adc :exit_offset+$1E - tax - lda: $F000,x - sta: OPCODE_SAVE+$F000,y - lda :exit_bra+$1E - sta: $F000,x - lda :entry_offset+$1E ; Pre-merged with the appropriate opcode + offset - sta: CODE_ENTRY_OPCODE+$F000,y - -x15 tya - adc :exit_offset+$1E - tax - lda: $E000,x - sta: OPCODE_SAVE+$E000,y - lda :exit_bra+$1C - sta: $E000,x - lda :entry_offset+$1C - sta: CODE_ENTRY_OPCODE+$E000,y - -x14 lda $D002,x - sta OPCODE_HIGH_SAVE+$D000,y -x13 lda $C002,x - sta OPCODE_HIGH_SAVE+$C000,y -x12 lda $B002,x - sta OPCODE_HIGH_SAVE+$B000,y -x11 lda $A002,x - sta OPCODE_HIGH_SAVE+$A000,y -x10 lda $9002,x - sta OPCODE_HIGH_SAVE+$9000,y -x09 lda $8002,x - sta OPCODE_HIGH_SAVE+$8000,y -x08 lda $7002,x - sta OPCODE_HIGH_SAVE+$7000,y -x07 lda $6002,x - sta OPCODE_HIGH_SAVE+$6000,y -x06 lda $5002,x - sta OPCODE_HIGH_SAVE+$5000,y -x05 lda $4002,x - sta OPCODE_HIGH_SAVE+$4000,y -x04 lda $3002,x - sta OPCODE_HIGH_SAVE+$3000,y -x03 lda $2002,x - sta OPCODE_HIGH_SAVE+$2000,y -x02 lda $1002,x - sta OPCODE_HIGH_SAVE+$1000,y -x01 lda: $0002,x - sta: OPCODE_HIGH_SAVE+$0000,y -bottom <<< - ; SaveHighOperand ; ; Save the high byte of the 3-byte code field instruction into the odd handler at the end diff --git a/src/static/TileStore.s b/src/static/TileStore.s index 6bc53cf..b5767af 100644 --- a/src/static/TileStore.s +++ b/src/static/TileStore.s @@ -108,6 +108,10 @@ TileStoreLookup ENT Col2CodeOffset ENT lup 82 dw CODE_TOP+{{81-]step}*PER_TILE_SIZE} +]step equ ]step+1 + --^ + lup 82 ; Make is a double-length table so we can add the ScreenWidth without testing for wrap-around + dw CODE_TOP+{{81-]step}*PER_TILE_SIZE} ]step equ ]step+1 --^ dw CODE_TOP+{81*PER_TILE_SIZE} @@ -386,6 +390,10 @@ BG1YOffsetTable ENT ; Per-scanline offsets for BG0 StartXMod164Tbl ENT + dw 0,0 + +LastOffsetTbl ENT + ds 416 ; Other Toolset variables OneSecondCounter ENT @@ -566,7 +574,7 @@ Scale15 dw $003C,$003C,$003C,$003E,$003E,$003E,$003E,$0040,$0040,$0040,$0040,$ blt_return stk_save -StartXMod164Arr ENT - ds 416*2 -LastPatchOffsetArr ENT - ds 416*2 +;StartXMod164Arr ENT +; ds 416*2 +;LastPatchOffsetArr ENT +; ds 416*2