mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2024-11-26 22:50:22 +00:00
First implementation of BG0/BG1 mixed exception handling
This commit is contained in:
parent
6fc772ce78
commit
bdf885dafd
@ -16,8 +16,13 @@ MoveRight
|
||||
sec
|
||||
sbc 1,s
|
||||
bpl *+5
|
||||
lda #163
|
||||
lda #0
|
||||
jsr SetBG0XPos
|
||||
|
||||
lda StartX
|
||||
lsr
|
||||
jsr SetBG1XPos
|
||||
|
||||
jsr DoFrame
|
||||
pla
|
||||
rts
|
||||
@ -25,10 +30,12 @@ MoveRight
|
||||
MoveDown
|
||||
clc
|
||||
adc StartY ; Increment the virtual X-position
|
||||
cmp #207
|
||||
bcc *+5
|
||||
lda #0
|
||||
jsr SetBG0YPos
|
||||
|
||||
lda StartY
|
||||
lsr
|
||||
jsr SetBG1YPos
|
||||
|
||||
jsr DoFrame
|
||||
rts
|
||||
|
||||
@ -38,8 +45,13 @@ MoveUp
|
||||
sec
|
||||
sbc 1,s
|
||||
bpl *+5
|
||||
lda #207
|
||||
lda #0
|
||||
jsr SetBG0YPos
|
||||
|
||||
lda StartY
|
||||
lsr
|
||||
jsr SetBG1YPos
|
||||
|
||||
jsr DoFrame
|
||||
pla
|
||||
rts
|
||||
@ -87,3 +99,8 @@ FPSStr str 'FPS'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
107
src/App.Main.s
107
src/App.Main.s
@ -406,6 +406,8 @@ CopyPicToField
|
||||
:line_cnt equ tmp2
|
||||
:dstptr equ tmp3
|
||||
:col_cnt equ tmp5
|
||||
:mask equ tmp6
|
||||
:data equ tmp7
|
||||
|
||||
sta :srcptr
|
||||
stx :srcptr+2
|
||||
@ -429,26 +431,63 @@ CopyPicToField
|
||||
|
||||
:cloop
|
||||
phy
|
||||
lda [:srcptr],y ; load the picture data
|
||||
beq :transparent ; a value of $0000 is transparent
|
||||
|
||||
jsr :toMask ; Infer a mask value for this. If it's $0000, then
|
||||
bne :mixed ; the data is solid, otherwise mixed
|
||||
|
||||
; This is a solid word
|
||||
lda [:srcptr],y
|
||||
ldy Col2CodeOffset,x ; Get the offset to the code from the line start
|
||||
|
||||
cmp #0 ; Empty values are transparent
|
||||
beq :transparent
|
||||
|
||||
pha
|
||||
pha ; Save the data
|
||||
lda #$00F4 ; PEA instruction
|
||||
sta [:dstptr],y
|
||||
iny
|
||||
pla
|
||||
sta [:dstptr],y
|
||||
sta [:dstptr],y ; PEA operand
|
||||
bra :next
|
||||
:transparent
|
||||
ldy Col2CodeOffset,x ; Get the offset to the code from the line start
|
||||
lda #$B1 ; LDA (dp),y
|
||||
sta [:dstptr],y
|
||||
iny
|
||||
lda 1,s ; load the saved Y-index
|
||||
ora #$4800 ; put a PHA after the offset
|
||||
sta [:dstptr],y
|
||||
bra :next
|
||||
|
||||
:mixed
|
||||
sta :mask ; Save the mask
|
||||
lda [:srcptr],y ; Refetch the screen data
|
||||
sta :data
|
||||
|
||||
ldy Col2CodeOffset,x ; Get the offset into the code field
|
||||
lda #$4C ; JMP exception
|
||||
sta [:dstptr],y
|
||||
iny
|
||||
|
||||
lda JTableOffset,x ; Get the address offset and add to the base address
|
||||
clc
|
||||
adc :dstptr
|
||||
sta [:dstptr],y
|
||||
|
||||
ldy JTableOffset,x ; This points to the code fragment
|
||||
lda 1,s ; load the offset
|
||||
xba
|
||||
ora #$00B1
|
||||
sta [:dstptr],y ; write the LDA (--),y instruction
|
||||
iny
|
||||
iny
|
||||
iny ; advance to the AND #imm operand
|
||||
lda :mask
|
||||
sta [:dstptr],y
|
||||
iny
|
||||
iny
|
||||
iny ; advance to the ORA #imm operand
|
||||
lda :data
|
||||
sta [:dstptr],y
|
||||
|
||||
:next
|
||||
ply
|
||||
@ -469,8 +508,35 @@ CopyPicToField
|
||||
inc :line_cnt
|
||||
lda :line_cnt
|
||||
cmp #200
|
||||
bcc :rloop
|
||||
bcs :exit
|
||||
brl :rloop
|
||||
|
||||
:exit
|
||||
rts
|
||||
|
||||
:toMask bit #$F000
|
||||
beq *+7
|
||||
and #$0FFF
|
||||
bra *+5
|
||||
ora #$F000
|
||||
|
||||
bit #$0F00
|
||||
beq *+7
|
||||
and #$F0FF
|
||||
bra *+5
|
||||
ora #$0F00
|
||||
|
||||
bit #$00F0
|
||||
beq *+7
|
||||
and #$FF0F
|
||||
bra *+5
|
||||
ora #$00F0
|
||||
|
||||
bit #$000F
|
||||
beq *+7
|
||||
and #$FFF0
|
||||
bra *+5
|
||||
ora #$000F
|
||||
rts
|
||||
|
||||
; Copy a binary image data file into BG1. Assumes the file is the correct size.
|
||||
@ -872,6 +938,35 @@ qtRec adrl $0000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -8,6 +8,10 @@ SetBG1XPos
|
||||
sta BG1StartX
|
||||
rts
|
||||
|
||||
SetBG1YPos
|
||||
sta BG1StartY
|
||||
rts
|
||||
|
||||
; Everytime either BG1 or BG0 X-position changes, we have to update the direct page values. We
|
||||
; *could* do this by adjusting the since address offset, but we have to change up to 200 values
|
||||
; when the vertical position changes, and only 41 when the horizontal value changes. Plus
|
||||
@ -247,5 +251,6 @@ CopyBG1YTableToBG1Addr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -28,6 +28,9 @@ StartXMod164 equ 36
|
||||
BG1StartX equ 38 ; Logical offset of the second background
|
||||
BG1StartXMod164 equ 40
|
||||
|
||||
BG1StartY equ 42
|
||||
BG1StartYMod208 equ 44
|
||||
|
||||
bstk equ 208 ; 16-byte stack to push bank addresses
|
||||
|
||||
tmp8 equ 224
|
||||
@ -66,4 +69,5 @@ DIRTY_BIT_BG1_Y equ $0008
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -22,6 +22,15 @@ Col2CodeOffset lup 82
|
||||
--^
|
||||
dw CODE_TOP
|
||||
|
||||
; A parallel table to Col2CodeOffset that hold the offset to the exception handler address for each column
|
||||
SNIPPET_SIZE equ 32
|
||||
]step equ 0
|
||||
JTableOffset lup 82
|
||||
dw SNIPPET_BASE+{]step*SNIPPET_SIZE}
|
||||
]step equ ]step+1
|
||||
--^
|
||||
dw SNIPPET_BASE
|
||||
|
||||
; Table of BRA instructions that are used to exit the code field. Separate tables for
|
||||
; even and odd aligned cases.
|
||||
;
|
||||
|
@ -16,11 +16,12 @@ ODD_ENTRY equ odd_entry-base+1
|
||||
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
|
||||
OPCODE_SAVE equ odd_save-base ; spot to save the code field opcode when patching exit BRA
|
||||
OPCODE_HIGH_SAVE equ odd_save-base+2 ; 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
|
||||
SNIPPET_BASE equ snippets-base
|
||||
|
||||
; Locations that need the page offset added
|
||||
PagePatches da {long_0-base+2}
|
||||
@ -456,10 +457,10 @@ right_odd bit #$000B ; Check the bottom nibble
|
||||
|
||||
long_1 stal *+4-base ; Everything else is a two-byte LDA opcode + PHA
|
||||
dfb $00,$00
|
||||
bra r_is_pea+1
|
||||
bra r_jmp_rtn
|
||||
|
||||
r_is_pea xba ; fast code for PEA
|
||||
sep #$20
|
||||
r_jmp_rtn sep #$20 ; shared return code path by all methods
|
||||
pha
|
||||
rep #$20
|
||||
odd_entry jmp $0100 ; unconditionally jump into the "next" instruction in the
|
||||
@ -475,7 +476,7 @@ odd_entry jmp $0100 ; unconditionally jump in
|
||||
r_is_jmp sep #$41 ; Set the C and V flags which tells a snippet to push only the low byte
|
||||
long_2 ldal entry_jmp+1-base
|
||||
long_3 stal *+5-base
|
||||
dfb $4C,$00,$00 ; Jump back to address in entry_jmp (this takes 16 cycles, is there a better way?)
|
||||
jmp $0000 ; Jumps into the exception code, which return to r_jmp_rtn
|
||||
|
||||
; The next labels are special, in that they are entry points into special subroutines. They are special
|
||||
; because they are within the first 256 bytes of each code field, which allows them to be selectable
|
||||
@ -517,16 +518,13 @@ loop lup 82 ; +6 Set up 82 PEA inst
|
||||
loop_back jmp loop-base ; +252 Ensure execution continues to loop around
|
||||
loop_exit_3 jmp even_exit-base ; +255
|
||||
|
||||
odd_exit lda #0000 ; This operand field is *always* used to hold the original 2 bytes of the code field
|
||||
; that are replaced by the needed BRA instruction to exit the code field. When the
|
||||
; left edge is odd-aligned, we are able to immediately load the value and perform
|
||||
; similar logic to the right_odd code path above
|
||||
|
||||
long_5
|
||||
odd_exit ldal l_is_jmp+1-base
|
||||
bit #$000B
|
||||
bne :chk_jmp
|
||||
|
||||
sep #$20
|
||||
odd_high_byte lda #00 ; patch with high byte code operand
|
||||
long_6 ldal l_is_jmp+3-base ; get the high byte of the PEA operand
|
||||
|
||||
; 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
|
||||
@ -540,20 +538,18 @@ even_exit jmp $1000 ; Jump to the next line.
|
||||
|
||||
:chk_jmp
|
||||
bit #$0040
|
||||
bne :l_is_jmp
|
||||
bne l_is_jmp
|
||||
|
||||
long_4 stal *+4-base
|
||||
dfb $00,$00
|
||||
xba
|
||||
l_jmp_rtn xba
|
||||
sep #$20
|
||||
pha
|
||||
rep #$20
|
||||
bra even_exit
|
||||
|
||||
: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?)
|
||||
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
|
||||
odd_save dfb $00,$00,$00 ; The odd exit 3-byte sequence is always stashed here
|
||||
|
||||
; 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
|
||||
@ -604,18 +600,24 @@ epilogue_1 tsc
|
||||
; jmp exit_rtn ; 3
|
||||
; r_edge jmp entry_rtn ; 3
|
||||
|
||||
; snippets ds 32*82
|
||||
ds \,$00 ; pad to the next page boundary
|
||||
]index equ 0
|
||||
snippets lup 82
|
||||
ds 2 ; space for a 2-byte sequence; LDA (00),y LDA 00,x LDA 0,s
|
||||
and #$0000 ; the mask operand will be set when the tile is drawn
|
||||
ora #$0000 ; the data operand will be set when the tile is drawn
|
||||
pha
|
||||
bcs *+5
|
||||
brl loop+3+{3*]index} ; use relative branch for convenience
|
||||
bvs *+6 ; overflow set means this is the right edge (entry)
|
||||
clc ; carry is set only for edge operations; force clear
|
||||
brl l_jmp_rtn
|
||||
rep #$41 ; clear V and C
|
||||
brl r_jmp_rtn ; 25 bytes
|
||||
ds 7 ; padding
|
||||
]index equ ]index+1
|
||||
--^
|
||||
top
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user