From 63bfe5e8e7c7b1d60fbf4f8a48e710fd417ff306 Mon Sep 17 00:00:00 2001 From: Lucas Scharenbroich Date: Thu, 15 Jul 2021 21:00:35 -0500 Subject: [PATCH] Resolve horizontal scrolling issue with PEA code --- src/Actions.s | 4 +- src/App.Main.s | 101 +------------------ src/App.Tile.s | 27 +++-- src/blitter/Blitter.s | 3 - src/blitter/DirectPage.s | 4 +- src/blitter/Horz.s | 209 +++++++++++++++++---------------------- src/blitter/Tables.s | 8 -- src/blitter/Template.s | 122 ++++++++--------------- 8 files changed, 155 insertions(+), 323 deletions(-) diff --git a/src/Actions.s b/src/Actions.s index 38d66c6..f27536a 100644 --- a/src/Actions.s +++ b/src/Actions.s @@ -51,7 +51,7 @@ Demo stz frameCount :loop lda #1 - jsr MoveDown + jsr MoveLeft inc frameCount ldal KBD_STROBE_REG @@ -82,3 +82,5 @@ Demo bra :loop FPSStr str 'FPS' + + diff --git a/src/App.Main.s b/src/App.Main.s index 2c05a03..4c03ae8 100644 --- a/src/App.Main.s +++ b/src/App.Main.s @@ -289,7 +289,7 @@ DoTiles :rowloop lda #0 sta :column,s - lda #$0010 + lda #$0015 sta :tile,s :colloop @@ -301,7 +301,7 @@ DoTiles jsr CopyTile lda :tile,s - inc + eor #$0003 sta :tile,s lda :column,s @@ -667,100 +667,3 @@ qtRec adrl $0000 put blitter/Template.s put blitter/Tiles.s put blitter/Vert.s - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/App.Tile.s b/src/App.Tile.s index 0141594..29e64d0 100644 --- a/src/App.Tile.s +++ b/src/App.Tile.s @@ -47,13 +47,22 @@ tiledata ENT hex 00FFF000 hex 00000000 + hex 01234567 + hex 01234567 + hex 01234567 + hex 01234567 + hex 01234567 + hex 01234567 + hex 01234567 + hex 01234567 + + hex 89ABCDEF + hex 89ABCDEF + hex 89ABCDEF + hex 89ABCDEF + hex 89ABCDEF + hex 89ABCDEF + hex 89ABCDEF + hex 89ABCDEF + tileend - - - - - - - - - diff --git a/src/blitter/Blitter.s b/src/blitter/Blitter.s index b22b1f5..30c83b2 100644 --- a/src/blitter/Blitter.s +++ b/src/blitter/Blitter.s @@ -84,6 +84,3 @@ stk_save lda #0000 ; load the stack plb ; restore the bank rts - - - diff --git a/src/blitter/DirectPage.s b/src/blitter/DirectPage.s index 22ef5c6..13e09b0 100644 --- a/src/blitter/DirectPage.s +++ b/src/blitter/DirectPage.s @@ -13,7 +13,6 @@ StartY equ 18 ; Which code buffer line is the top of the s EngineMode equ 20 ; Defined the mode/capabilities that are enabled ; bit 0: 0 = Single Background, 1 = Parallax DirtyBits equ 22 ; Identify values that have changed between frames -LastPatchOffset equ 24 ; Offset into code field that was patched with BRA instructions BG1DataBank equ 24 ; Data bank that holds BG1 layer data BlitterDP equ 25 ; Direct page address the holder blitter data @@ -21,6 +20,8 @@ BlitterDP equ 25 ; Direct page address the holder blitter dat OldStartX equ 26 OldStartY equ 28 +LastPatchOffset equ 30 ; Offset into code field that was patched with BRA instructions + bstk equ 208 ; 16-byte stack to push bank addresses tmp8 equ 224 @@ -54,3 +55,4 @@ DIRTY_BIT_BG1_Y equ $0008 + diff --git a/src/blitter/Horz.s b/src/blitter/Horz.s index a7a2e4e..11279af 100644 --- a/src/blitter/Horz.s +++ b/src/blitter/Horz.s @@ -352,6 +352,7 @@ _ApplyBG0XPos ; 8-bit operation and, since the PEA code is bank aligned, we use the entry_offset value directly sep #$20 + ldx :draw_count_x2 lda :entry_offset ldy :base_address @@ -364,7 +365,7 @@ _ApplyBG0XPos ldy :base_address jsr SetCodeEntryOpcode -; If this is an odd entry, also set the odd_entry low byte +; If this is an odd entry, also set the odd_entry low byte and save the operand high byte lda :odd_entry_offset beq :not_odd @@ -373,6 +374,12 @@ _ApplyBG0XPos ldy :base_address jsr SetOddCodeEntry + ldx :draw_count_x2 + ldy :base_address + pei :exit_address + jmp :SaveHighOperand ; Only used once, so "inline" it +:save_high_op_rtn + :not_odd rep #$20 @@ -395,6 +402,88 @@ _ApplyBG0XPos plb rts +; SaveHighOperand +; +; Save the high byte of the 3-byte code field instruction into the odd handler at the end +; of each line. This is only needed +; +; X = number of lines * 2, 0 to 32 +; Y = starting line * $1000 +; A = code field location * $1000 +:SaveHighOperand + jmp (:tbl,x) + +:tbl da :bottom + da :do01,:do02,:do03,:do04 + da :do05,:do06,:do07,:do08 + da :do09,:do10,:do11,:do12 + da :do13,:do14,:do15,:do16 + +:do15 plx + bra :x15 +:do14 plx + bra :x14 +:do13 plx + bra :x13 +:do12 plx + bra :x12 +:do11 plx + bra :x11 +:do10 plx + bra :x10 +:do09 plx + bra :x09 +:do08 plx + bra :x08 +:do07 plx + bra :x07 +:do06 plx + bra :x06 +:do05 plx + bra :x05 +:do04 plx + bra :x04 +:do03 plx + bra :x03 +:do02 plx + bra :x02 +:do01 plx + bra :x01 +:do16 plx +:x16 lda $F002,x + sta OPCODE_HIGH_SAVE+$F000,y +:x15 lda $E002,x + sta OPCODE_HIGH_SAVE+$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 jmp :save_high_op_rtn + ; SaveOpcode ; ; Save the values to the restore location. This should only be used to patch the @@ -477,7 +566,6 @@ SaveOpcode sta: OPCODE_SAVE+$0000,y :bottom rts - ; RestoreOpcode ; ; Restore the values back to the code field. @@ -654,120 +742,3 @@ SetCodeEntryOpcode sta CODE_ENTRY_OPCODE+$1000,y sta: CODE_ENTRY_OPCODE+$0000,y :bottom rts - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/blitter/Tables.s b/src/blitter/Tables.s index 1d9c4d2..4073880 100644 --- a/src/blitter/Tables.s +++ b/src/blitter/Tables.s @@ -215,11 +215,3 @@ BlitBuff ds 4*13 ; that everything can use the same indexing offsets BTableHigh ds 208*2*2 BTableLow ds 208*2*2 - - - - - - - - diff --git a/src/blitter/Template.s b/src/blitter/Template.s index f7f2ee1..e0c4049 100644 --- a/src/blitter/Template.s +++ b/src/blitter/Template.s @@ -17,6 +17,7 @@ CODE_TOP equ loop-base CODE_LEN equ top-base CODE_EXIT equ even_exit-base OPCODE_SAVE equ odd_exit-base+1 ; spot to save the code field opcode when patching exit BRA +OPCODE_HIGH_SAVE equ odd_high_byte-base+1 ; save the third byte FULL_RETURN equ full_return-base ; offset that returns from the blitter ENABLE_INT equ enable_int-base ; offset that re-enable interrupts and continues LINES_PER_BANK equ 16 @@ -856,28 +857,36 @@ odd_exit lda #0000 ; This operand field is ; left edge is odd-aligned, we are able to immediately load the value and perform ; similar logic to the right_odd code path above -left_odd bit #$000B - beq l_is_pea + bit #$000B + bne :chk_jmp - bit #$0040 - bne l_is_jmp + sep #$20 +odd_high_byte lda #00 ; patch with high byte code operand -long_4 stal *+4-base - dfb $00,$00 -l_is_pea xba - sep #$30 +; Fall-through when we have to push a byte on the left edge. Must be 8-bit on entry. Optimize +; for the PEA $0000 case -- only 19 cycles to handle the edge, so pretty good +:left_byte pha - rep #$30 - bra even_exit -l_is_jmp sep #$01 ; Set the C flag (V is always cleared at this point) which tells a snippet to push only the high byte -long_5 ldal entry_jmp+1-base -long_6 stal *+5-base - dfb $4C,$00,$00 ; Jump back to address in entry_jmp (this takes 13 cycles, is there a better way?) + rep #$20 ; JMP opcode = $4C, JML opcode = $5C even_exit jmp $1000 ; Jump to the next line. ds 1 ; space so that the last line in a bank can be patched into a JML +:chk_jmp + bit #$0040 + bne :l_is_jmp + +long_4 stal *+4-base + dfb $00,$00 + sep #$20 + bra :left_byte + +:l_is_jmp sec ; Set the C flag (V is always cleared at this point) which tells a snippet to push only the high byte +long_5 ldal entry_jmp+1-base +long_6 stal *+5-base + dfb $4C,$00,$00 ; Jump back to address in entry_jmp (this takes 13 cycles, is there a better way?) + ; Special epilogue: skip a number of bytes and jump back into the code field. This is useful for ; large, floating panels in the attract mode of a game, or to overlay solid ; dialog while still animating the play field @@ -899,7 +908,7 @@ epilogue_1 tsc ; are: ; ; 1. Carry Clear -> 16-bit write and return to the next code field operand -; 2. Carry Set +; 2. Carry Set ; a. Overflow set -> Low 8-bit write and return to the next code field operand ; b. Overflow clear -> High 8-bit write and exit the line ; c. Always clear the Carry flags. It's actually OK to leave the overflow bit in @@ -908,77 +917,24 @@ epilogue_1 tsc ; ; Snippet Samples: ; -; Standard Two-level Mix (27 bytes) +; Standard Two-level Mix (23 bytes) ; -; Optimal = 18 cycles (LDA/AND/ORA/PHA) -; 16-bit write = 23 cycles -; 8-bit low = 35 cycles -; 8-bit high = 36 cycles +; Optimal = 18 cycles (LDA/AND/ORA/PHA/JMP) +; 16-bit write = 21 cycles +; 8-bit low = 30 cycles +; 8-bit high = 29 cycles ; -; start lda (00),y -; and #MASK -; ora #DATA ; 14 cycles to load the data -; bcs 8_bit -; pha -; out jmp next ; Fast-path completes in 9 additional cycles +; start lda (00),y ; 6 +; and #MASK ; 3 +; ora #DATA ; 3 = 12 cycles to load the data +; pha ; 4 +; bcs alt_exit ; 2/3 +; out jmp next ; 3 Fast-path completes in 5 additional cycles -; 8_bit sep #$30 ; Switch to 8 bit mode -; bvs r_edge ; Need to switch if doing the left edge -; xba -; r_edge pha ; push the value -; rep #$31 ; put back into 16-bit mode and clear the carry bit, as required -; bvs out ; jmp out and continue if this is the right edge -; jmp even_exit ; exit the line otherwise -; ; -; ; The slow paths have 21 and 22 cycles for the right and left -; ; odd-aligned cases respectively. +; alt_exit clc ; 2 +; bvs r_edge ; 2/3 Need to switch if doing the left edge +; jmp exit_rtn ; 3 +; r_edge jmp entry_rtn ; 3 ; snippets ds 32*82 top - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -