mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2025-02-27 06:29:30 +00:00
Split up source code a bit more; work toward completing render pipeline
This commit is contained in:
parent
6b32d61fa9
commit
8ec31631eb
@ -30,6 +30,24 @@ _Div16 mac
|
|||||||
lsr
|
lsr
|
||||||
<<<
|
<<<
|
||||||
|
|
||||||
|
_R0W0 mac ; Read Bank 0 / Write Bank 0
|
||||||
|
ldal STATE_REG
|
||||||
|
and #$FFCF
|
||||||
|
stal STATE_REG
|
||||||
|
<<<
|
||||||
|
|
||||||
|
_R0W1 mac ; Read Bank 0 / Write Bank 1
|
||||||
|
ldal STATE_REG
|
||||||
|
ora #$0010
|
||||||
|
stal STATE_REG
|
||||||
|
<<<
|
||||||
|
|
||||||
|
_R1W1 mac ; Read Bank 0 / Write Bank 1
|
||||||
|
ldal STATE_REG
|
||||||
|
ora #$0030
|
||||||
|
stal STATE_REG
|
||||||
|
<<<
|
||||||
|
|
||||||
****************************************
|
****************************************
|
||||||
* Basic Error Macro *
|
* Basic Error Macro *
|
||||||
****************************************
|
****************************************
|
||||||
@ -46,3 +64,9 @@ NoErr eom
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,38 +16,38 @@
|
|||||||
|
|
||||||
mx %00
|
mx %00
|
||||||
|
|
||||||
MemInit PushLong #0 ; space for result
|
MemInit PushLong #0 ; space for result
|
||||||
PushLong #$008000 ; size (32k)
|
PushLong #$008000 ; size (32k)
|
||||||
PushWord UserId
|
PushWord UserId
|
||||||
PushWord #%11000000_00010111 ; Fixed location
|
PushWord #%11000000_00010111 ; Fixed location
|
||||||
PushLong #$002000
|
PushLong #$002000
|
||||||
_NewHandle ; returns LONG Handle on stack
|
_NewHandle ; returns LONG Handle on stack
|
||||||
plx ; base address of the new handle
|
plx ; base address of the new handle
|
||||||
pla ; high address 00XX of the new handle (bank)
|
pla ; high address 00XX of the new handle (bank)
|
||||||
_Deref
|
_Deref
|
||||||
stx Buff00
|
stx Buff00
|
||||||
sta Buff00+2
|
sta Buff00+2
|
||||||
|
|
||||||
PushLong #0 ; space for result
|
PushLong #0 ; space for result
|
||||||
PushLong #$008000 ; size (32k)
|
PushLong #$008000 ; size (32k)
|
||||||
PushWord UserId
|
PushWord UserId
|
||||||
PushWord #%11000000_00010111 ; Fixed location
|
PushWord #%11000000_00010111 ; Fixed location
|
||||||
PushLong #$012000
|
PushLong #$012000
|
||||||
_NewHandle ; returns LONG Handle on stack
|
_NewHandle ; returns LONG Handle on stack
|
||||||
plx ; base address of the new handle
|
plx ; base address of the new handle
|
||||||
pla ; high address 00XX of the new handle (bank)
|
pla ; high address 00XX of the new handle (bank)
|
||||||
_Deref
|
_Deref
|
||||||
stx Buff01
|
stx Buff01
|
||||||
sta Buff01+2
|
sta Buff01+2
|
||||||
|
|
||||||
PushLong #0 ; space for result
|
PushLong #0 ; space for result
|
||||||
PushLong #$000A00 ; size (10 pages)
|
PushLong #$000A00 ; size (10 pages)
|
||||||
PushWord UserId
|
PushWord UserId
|
||||||
PushWord #%11000000_00010101 ; Page-aligned, fixed bank
|
PushWord #%11000000_00010101 ; Page-aligned, fixed bank
|
||||||
PushLong #$000000
|
PushLong #$000000
|
||||||
_NewHandle ; returns LONG Handle on stack
|
_NewHandle ; returns LONG Handle on stack
|
||||||
plx ; base address of the new handle
|
plx ; base address of the new handle
|
||||||
pla ; high address 00XX of the new handle (bank)
|
pla ; high address 00XX of the new handle (bank)
|
||||||
_Deref
|
_Deref
|
||||||
stx ZeroPage
|
stx ZeroPage
|
||||||
sta ZeroPage+2
|
sta ZeroPage+2
|
||||||
@ -57,9 +57,28 @@ MemInit PushLong #0 ; space for result
|
|||||||
lup 13
|
lup 13
|
||||||
jsr AllocOneBank2
|
jsr AllocOneBank2
|
||||||
sta BlitBuff+]step+2
|
sta BlitBuff+]step+2
|
||||||
sta BlitBuffMid+]step+2
|
|
||||||
stz BlitBuff+]step
|
stz BlitBuff+]step
|
||||||
stz BlitBuffMid+]step
|
]step equ ]step+4
|
||||||
|
--^
|
||||||
|
|
||||||
|
ldx #0
|
||||||
|
ldy #0
|
||||||
|
lda BlitBuff+2,y ; Copy the high word first
|
||||||
|
]step equ 0
|
||||||
|
lup 16
|
||||||
|
sta BTableHigh+]step+2,x ; 16 lines per bank
|
||||||
|
sta BTableHigh+]step+2+{208*2},x ; 16 lines per bank
|
||||||
|
]step equ ]step+4
|
||||||
|
--^
|
||||||
|
lda BlitBuff,y
|
||||||
|
sta BTableLow,x
|
||||||
|
sta BTableLow+{208*2},x
|
||||||
|
clc
|
||||||
|
]step equ 0
|
||||||
|
lup 15
|
||||||
|
adc #$1000
|
||||||
|
sta BTableLow+]step,x
|
||||||
|
sta BTableLow+]step+{208*2},x
|
||||||
]step equ ]step+4
|
]step equ ]step+4
|
||||||
--^
|
--^
|
||||||
|
|
||||||
@ -69,14 +88,6 @@ Buff00 ds 4
|
|||||||
Buff01 ds 4
|
Buff01 ds 4
|
||||||
ZeroPage ds 4
|
ZeroPage ds 4
|
||||||
|
|
||||||
; Array of addressed for the banks that hold the blitter. This is actually a double-length
|
|
||||||
; array, which is a pattern that is used a lot in GTE. Whenever we have a situation where
|
|
||||||
; we need to wrap around an array, we can to this be doubling the array length and using an
|
|
||||||
; unrolled loop that starts in the middle instead of doing some kind of "mod N" or loop
|
|
||||||
; splitting.
|
|
||||||
BlitBuff ds 4*13
|
|
||||||
BlitBuffMid ds 4*13
|
|
||||||
|
|
||||||
; Bank allocator (for one full, fixed bank of memory. Can be immediately deferenced)
|
; Bank allocator (for one full, fixed bank of memory. Can be immediately deferenced)
|
||||||
|
|
||||||
AllocOneBank PushLong #0
|
AllocOneBank PushLong #0
|
||||||
@ -84,12 +95,12 @@ AllocOneBank PushLong #0
|
|||||||
PushWord UserId
|
PushWord UserId
|
||||||
PushWord #%11000000_00011100
|
PushWord #%11000000_00011100
|
||||||
PushLong #0
|
PushLong #0
|
||||||
_NewHandle ; returns LONG Handle on stack
|
_NewHandle ; returns LONG Handle on stack
|
||||||
plx ; base address of the new handle
|
plx ; base address of the new handle
|
||||||
pla ; high address 00XX of the new handle (bank)
|
pla ; high address 00XX of the new handle (bank)
|
||||||
xba ; swap accumulator bytes to XX00
|
xba ; swap accumulator bytes to XX00
|
||||||
sta :bank+2 ; store as bank for next op (overwrite $XX00)
|
sta :bank+2 ; store as bank for next op (overwrite $XX00)
|
||||||
:bank ldal $000001,X ; recover the bank address in A=XX/00
|
:bank ldal $000001,X ; recover the bank address in A=XX/00
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; Variation that return pointer in the X/A registers (X = low, A = high)
|
; Variation that return pointer in the X/A registers (X = low, A = high)
|
||||||
@ -99,8 +110,8 @@ AllocOneBank2 PushLong #0
|
|||||||
PushWord #%11000000_00011100
|
PushWord #%11000000_00011100
|
||||||
PushLong #0
|
PushLong #0
|
||||||
_NewHandle
|
_NewHandle
|
||||||
plx ; base address of the new handle
|
plx ; base address of the new handle
|
||||||
pla ; high address 00XX of the new handle (bank)
|
pla ; high address 00XX of the new handle (bank)
|
||||||
_Deref
|
_Deref
|
||||||
rts
|
rts
|
||||||
|
|
||||||
@ -136,6 +147,18 @@ ShutDown rts
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
173
src/App.Main.s
173
src/App.Main.s
@ -1,8 +1,16 @@
|
|||||||
; Test program for graphics stufff...
|
; Test driver to exercise graphics routines.
|
||||||
;
|
;
|
||||||
; Allow dynamic resizing to benchmark against different games
|
; The general organization of the code is
|
||||||
|
;
|
||||||
|
; 1. The blitter/ folder contains all of the low-level graphics primitives
|
||||||
|
; 2. The blitter/DirectPage.s file defines all of the DP locations
|
||||||
|
; 3. Subroutines are written to try and be stateless, but, if local
|
||||||
|
; storage is needed, it is takes from the stack and uses stack-relative
|
||||||
|
; addressing.
|
||||||
|
|
||||||
rel
|
; Allow dynamic resizing to benchmark against different games
|
||||||
|
REL
|
||||||
|
DSK MAINSEG
|
||||||
|
|
||||||
use Util.Macs.s
|
use Util.Macs.s
|
||||||
use Locator.Macs.s
|
use Locator.Macs.s
|
||||||
@ -17,7 +25,7 @@
|
|||||||
SHADOW_REG equ $E0C035
|
SHADOW_REG equ $E0C035
|
||||||
STATE_REG equ $E0C068
|
STATE_REG equ $E0C068
|
||||||
NEW_VIDEO_REG equ $E0C029
|
NEW_VIDEO_REG equ $E0C029
|
||||||
BORDER_REG equ $E0C034 ; 0-3 = border 4-7 Text color
|
BORDER_REG equ $E0C034 ; 0-3 = border, 4-7 Text color
|
||||||
VBL_VERT_REG equ $E0C02E
|
VBL_VERT_REG equ $E0C02E
|
||||||
VBL_HORZ_REG equ $E0C02F
|
VBL_HORZ_REG equ $E0C02F
|
||||||
|
|
||||||
@ -28,6 +36,9 @@ VBL_STATE_REG equ $E0C019
|
|||||||
SHR_SCREEN equ $E12000
|
SHR_SCREEN equ $E12000
|
||||||
SHR_SCB equ $E19D00
|
SHR_SCB equ $E19D00
|
||||||
|
|
||||||
|
; External references
|
||||||
|
tiledata ext
|
||||||
|
|
||||||
; Typical init
|
; Typical init
|
||||||
|
|
||||||
phk
|
phk
|
||||||
@ -46,7 +57,10 @@ SHR_SCB equ $E19D00
|
|||||||
|
|
||||||
_MTStartUp
|
_MTStartUp
|
||||||
|
|
||||||
; Install interrupt handlers
|
; Install interrupt handlers. We use the VBL interrupt to keep animations
|
||||||
|
; moving at a consistent rate, regarless of the rendered frame rate. The
|
||||||
|
; one-second timer is generally just used for counters and as a handy
|
||||||
|
; frames-per-second trigger.
|
||||||
|
|
||||||
PushLong #0
|
PushLong #0
|
||||||
pea $0015 ; Get the existing 1-second interrupt handler and save
|
pea $0015 ; Get the existing 1-second interrupt handler and save
|
||||||
@ -72,9 +86,6 @@ SHR_SCB equ $E19D00
|
|||||||
ldx #6 ; Gameboy Advance size
|
ldx #6 ; Gameboy Advance size
|
||||||
jsr SetScreenMode
|
jsr SetScreenMode
|
||||||
|
|
||||||
lda #0 ; Set the virtual Y-position
|
|
||||||
jsr SetYPos
|
|
||||||
|
|
||||||
; Load a picture and copy it into Bank $E1. Then turn on the screen.
|
; Load a picture and copy it into Bank $E1. Then turn on the screen.
|
||||||
|
|
||||||
jsr AllocOneBank ; Alloc 64KB for Load/Unpack
|
jsr AllocOneBank ; Alloc 64KB for Load/Unpack
|
||||||
@ -105,7 +116,7 @@ EvtLoop
|
|||||||
bne :5
|
bne :5
|
||||||
jsr DoHUP
|
jsr DoHUP
|
||||||
|
|
||||||
:5 cmp #'1'
|
:5 cmp #'1' ; User selects a new screen size
|
||||||
bcc :6
|
bcc :6
|
||||||
cmp #'9'+1
|
cmp #'9'+1
|
||||||
bcs :6
|
bcs :6
|
||||||
@ -116,6 +127,26 @@ EvtLoop
|
|||||||
|
|
||||||
:6 bra EvtLoop
|
:6 bra EvtLoop
|
||||||
|
|
||||||
|
; Exit code
|
||||||
|
Exit
|
||||||
|
pea $0007 ; disable 1-second interrupts
|
||||||
|
_IntSource
|
||||||
|
|
||||||
|
PushLong #VBLTASK ; Remove our heartbeat task
|
||||||
|
_DelHeartBeat
|
||||||
|
|
||||||
|
pea $0015
|
||||||
|
PushLong OldOneSecVec ; Reset the interrupt vector
|
||||||
|
_SetVector
|
||||||
|
|
||||||
|
PushWord UserId ; Deallocate all of our memory
|
||||||
|
_DisposeAll
|
||||||
|
|
||||||
|
_QuitGS qtRec
|
||||||
|
|
||||||
|
bcs Fatal
|
||||||
|
Fatal brk $00
|
||||||
|
|
||||||
; Allow the user to dynamically select one of the pre-configured screen sizes
|
; Allow the user to dynamically select one of the pre-configured screen sizes
|
||||||
;
|
;
|
||||||
; 1. Full Screen : 40 x 25 320 x 200 (32,000 bytes (100.0%))
|
; 1. Full Screen : 40 x 25 320 x 200 (32,000 bytes (100.0%))
|
||||||
@ -129,6 +160,7 @@ EvtLoop
|
|||||||
; 9. Game Boy Color : 20 x 18 160 x 144 (11,520 bytes ( 36.0%))
|
; 9. Game Boy Color : 20 x 18 160 x 144 (11,520 bytes ( 36.0%))
|
||||||
;
|
;
|
||||||
; X=mode number
|
; X=mode number
|
||||||
|
|
||||||
]ScreenModeWidth dw 320,272,256,256,280,256,240,288,160
|
]ScreenModeWidth dw 320,272,256,256,280,256,240,288,160
|
||||||
]ScreenModeHeight dw 200,192,200,176,160,160,160,128,144
|
]ScreenModeHeight dw 200,192,200,176,160,160,160,128,144
|
||||||
|
|
||||||
@ -194,45 +226,51 @@ DoHUP
|
|||||||
DoFrame
|
DoFrame
|
||||||
|
|
||||||
; Render some tiles
|
; Render some tiles
|
||||||
:bank equ 0
|
:bank equ 1
|
||||||
:column equ 2
|
:column equ 3
|
||||||
:tile equ 4
|
:tile equ 5
|
||||||
|
|
||||||
|
|
||||||
|
pea $0000 ; Allocate local variable space
|
||||||
|
pea $0000
|
||||||
|
pea $0000
|
||||||
|
|
||||||
stz :bank
|
|
||||||
stz :tile
|
|
||||||
:bankloop
|
:bankloop
|
||||||
ldx :bank
|
lda :bank,s
|
||||||
|
tax
|
||||||
ldal BlitBuff+1,x ; set the data bank to the code field
|
ldal BlitBuff+1,x ; set the data bank to the code field
|
||||||
pha
|
pha
|
||||||
plb
|
plb
|
||||||
plb
|
plb
|
||||||
|
|
||||||
stz :column
|
lda #0
|
||||||
|
sta :column,s
|
||||||
|
|
||||||
:tileloop
|
:tileloop
|
||||||
ldx :column
|
lda :column,s
|
||||||
|
tax
|
||||||
ldal Col2CodeOffset,x
|
ldal Col2CodeOffset,x
|
||||||
tay
|
tay
|
||||||
iny
|
iny
|
||||||
lda :tile
|
lda :tile,s
|
||||||
jsr CopyTile
|
jsr CopyTile
|
||||||
|
|
||||||
lda :tile
|
lda :tile,s
|
||||||
inc
|
inc
|
||||||
and #$000F
|
and #$000F
|
||||||
sta :tile
|
sta :tile,s
|
||||||
|
|
||||||
lda :column
|
lda :column,s
|
||||||
clc
|
clc
|
||||||
adc #4
|
adc #4
|
||||||
sta :column
|
sta :column,s
|
||||||
cmp #4*40
|
cmp #4*40
|
||||||
bcc :tileloop
|
bcc :tileloop
|
||||||
|
|
||||||
lda :bank
|
lda :bank,s
|
||||||
clc
|
clc
|
||||||
adc #4
|
adc #4
|
||||||
sta :bank
|
sta :bank,s
|
||||||
cmp #4*13
|
cmp #4*13
|
||||||
bcc :bankloop
|
bcc :bankloop
|
||||||
|
|
||||||
@ -251,7 +289,18 @@ DoFrame
|
|||||||
pha ; push twice because we will use it later
|
pha ; push twice because we will use it later
|
||||||
rep #$20
|
rep #$20
|
||||||
|
|
||||||
ldx #80*2 ; This is the word to exit from
|
; Set the Y-Position within the virtual buffer
|
||||||
|
|
||||||
|
lda #0 ; Set the virtual Y-position
|
||||||
|
jsr SetYPos
|
||||||
|
|
||||||
|
; Just load the screen width here. This is not semantically right; we actually are taking the nummber
|
||||||
|
; of tiles in the width of the playfield, multiplying by two to get the number of words and then
|
||||||
|
; multiplying by two again to get an index offset. It just happens that TILES * 4 = BYTES.
|
||||||
|
;
|
||||||
|
; TODO: Once we start scrolling, this will be ScreenWidth + BG0_X
|
||||||
|
|
||||||
|
ldx ScreenWidth ; This is the word to exit from
|
||||||
ldy Col2CodeOffset,x ; Get the offset
|
ldy Col2CodeOffset,x ; Get the offset
|
||||||
|
|
||||||
sep #$20 ; 8-bit acc
|
sep #$20 ; 8-bit acc
|
||||||
@ -265,15 +314,17 @@ DoFrame
|
|||||||
lda #OPCODE_SAVE
|
lda #OPCODE_SAVE
|
||||||
jsr SaveOpcode
|
jsr SaveOpcode
|
||||||
|
|
||||||
ldx #80*2 ; X-register is overwritten by SaveOpcode
|
ldx ScreenWidth ; X-register is overwritten by SaveOpcode
|
||||||
ldal CodeFieldEvenBRA,x ; Get the value to place there
|
ldal CodeFieldEvenBRA,x ; Get the value to place there
|
||||||
ldx #16*2
|
ldx #16*2
|
||||||
jsr SetConst
|
jsr SetConst
|
||||||
|
|
||||||
; lda #{$2000+159+15*160} ; Set the stack address to the right edge of the screen
|
|
||||||
; ldy #0
|
; Fill in the screen address of each line. This routine must be called whenever the
|
||||||
; ldx #16*2
|
; lda #{$2000+159+15*160} ; Set the stack address to the right edge of the screen
|
||||||
; jsr SetScreenAddrs
|
; ldy #0
|
||||||
|
; ldx #16*2
|
||||||
|
; jsr SetScreenAddrs
|
||||||
|
|
||||||
sep #$20 ; only need to do an 8-bit store
|
sep #$20 ; only need to do an 8-bit store
|
||||||
lda #$06 ; This is the entry address to start drawing
|
lda #$06 ; This is the entry address to start drawing
|
||||||
@ -285,26 +336,11 @@ DoFrame
|
|||||||
ldy #$7000 ; Set the return after line 200 (Bank 13, line 8)
|
ldy #$7000 ; Set the return after line 200 (Bank 13, line 8)
|
||||||
jsr SetReturn
|
jsr SetReturn
|
||||||
|
|
||||||
sei ; disable interrupts
|
jsr BltDispatch ; Execute the blit
|
||||||
|
|
||||||
ldal STATE_REG
|
|
||||||
ora #$0010 ; Read Bank 0 / Write Bank 1
|
|
||||||
stal STATE_REG
|
|
||||||
|
|
||||||
tsc ; save the stack pointer
|
|
||||||
stal stk_save+1
|
|
||||||
|
|
||||||
blt_entry jml $000006 ; Jump into the blitter code $XX/YY06
|
|
||||||
|
|
||||||
blt_return ldal STATE_REG ; Read Bank 0 / Write Bank 0
|
|
||||||
and #$FFCF
|
|
||||||
stal STATE_REG
|
|
||||||
stk_save lda #0000 ; load the stack
|
|
||||||
tcs
|
|
||||||
cli ; re-enable interrupts
|
|
||||||
|
|
||||||
plb ; set the bank back to the code field
|
plb ; set the bank back to the code field
|
||||||
ldx #80*2 ; This is the word to exit from
|
ldx ScreenWidth ; This is the word to exit from
|
||||||
ldal Col2CodeOffset,x ; Get the offset
|
ldal Col2CodeOffset,x ; Get the offset
|
||||||
tay
|
tay
|
||||||
ldx #16*2
|
ldx #16*2
|
||||||
@ -313,6 +349,10 @@ stk_save lda #0000 ; load the stack
|
|||||||
|
|
||||||
phk ; restore data bank
|
phk ; restore data bank
|
||||||
plb
|
plb
|
||||||
|
|
||||||
|
pla ; restore the stack
|
||||||
|
pla
|
||||||
|
pla
|
||||||
rts
|
rts
|
||||||
|
|
||||||
DoLoadPic
|
DoLoadPic
|
||||||
@ -332,27 +372,6 @@ DoLoadPic
|
|||||||
bpl :copySHR
|
bpl :copySHR
|
||||||
rts
|
rts
|
||||||
|
|
||||||
Exit
|
|
||||||
pea $0007 ; disable 1-second interrupts
|
|
||||||
_IntSource
|
|
||||||
|
|
||||||
PushLong #VBLTASK ; Remove our heartbeat task
|
|
||||||
_DelHeartBeat
|
|
||||||
|
|
||||||
pea $0015
|
|
||||||
PushLong OldOneSecVec ; Reset the interrupt vector
|
|
||||||
_SetVector
|
|
||||||
|
|
||||||
PushWord UserId ; Deallocate all of our memory
|
|
||||||
_DisposeAll
|
|
||||||
|
|
||||||
_QuitGS qtRec
|
|
||||||
|
|
||||||
bcs Fatal
|
|
||||||
Fatal brk $00
|
|
||||||
|
|
||||||
Hello str '000000' ; str adds leading length byte
|
|
||||||
|
|
||||||
****************************************
|
****************************************
|
||||||
* Fatal Error Handler *
|
* Fatal Error Handler *
|
||||||
****************************************
|
****************************************
|
||||||
@ -621,20 +640,12 @@ qtRec adrl $0000
|
|||||||
put App.Init.s
|
put App.Init.s
|
||||||
put App.Msg.s
|
put App.Msg.s
|
||||||
put font.s
|
put font.s
|
||||||
put blitter/Template.s
|
put blitter/Blitter.s
|
||||||
|
put blitter/PEISlammer.s
|
||||||
put blitter/Tables.s
|
put blitter/Tables.s
|
||||||
|
put blitter/Template.s
|
||||||
|
put blitter/Tiles.s
|
||||||
|
put blitter/Vert.s
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,8 +42,6 @@ Addr2ToString xba
|
|||||||
|
|
||||||
; A=Value
|
; A=Value
|
||||||
; X=Screen offset
|
; X=Screen offset
|
||||||
WordBuff dfb 4
|
|
||||||
ds 4
|
|
||||||
DrawWord phx ; Save register value
|
DrawWord phx ; Save register value
|
||||||
ldy #WordBuff+1
|
ldy #WordBuff+1
|
||||||
jsr WordToString
|
jsr WordToString
|
||||||
@ -53,27 +51,31 @@ DrawWord phx ; Save register value
|
|||||||
jsr DrawString
|
jsr DrawString
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; Rendout out the bank addresses of all the blitter fields
|
; Render out the bank addresses of all the blitter fields
|
||||||
:count = tmp0
|
DumpBanks
|
||||||
:ptr = tmp1
|
|
||||||
:addr = tmp3
|
:addr = 1
|
||||||
DumpBanks stz :addr
|
:count = 3
|
||||||
lda #13
|
:ptr = 5
|
||||||
sta :count
|
|
||||||
lda #BlitBuff
|
pea #^BlitBuff ; pointer to address table
|
||||||
sta :ptr
|
pea #BlitBuff
|
||||||
lda #^BlitBuff
|
pea #13 ; count = 13
|
||||||
sta :ptr+2
|
pea $0000 ; addr = 0
|
||||||
|
|
||||||
|
tsc
|
||||||
|
phd ; save the direct page
|
||||||
|
tcd ; set the direct page
|
||||||
|
|
||||||
:loop lda [:ptr]
|
:loop lda [:ptr]
|
||||||
tax
|
tax
|
||||||
ldy #2
|
ldy #2
|
||||||
lda [:ptr],y
|
lda [:ptr],y
|
||||||
|
|
||||||
ldy #Hello+1
|
ldy #Addr3Buff+1
|
||||||
jsr Addr3ToString
|
jsr Addr3ToString
|
||||||
|
|
||||||
lda #Hello
|
lda #Addr3Buff
|
||||||
ldx :addr
|
ldx :addr
|
||||||
ldy #$7777
|
ldy #$7777
|
||||||
jsr DrawString
|
jsr DrawString
|
||||||
@ -83,17 +85,36 @@ DumpBanks stz :addr
|
|||||||
adc #160*8
|
adc #160*8
|
||||||
sta :addr
|
sta :addr
|
||||||
|
|
||||||
inc :ptr
|
lda #4
|
||||||
inc :ptr
|
adc :ptr
|
||||||
inc :ptr
|
sta :ptr
|
||||||
inc :ptr
|
|
||||||
|
|
||||||
dec :count
|
dec :count
|
||||||
lda :count
|
|
||||||
bne :loop
|
bne :loop
|
||||||
|
|
||||||
|
pld ; restore the direct page
|
||||||
|
tcs ; restore the stack pointer
|
||||||
|
clc
|
||||||
|
adc #8
|
||||||
|
tsc
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
WordBuff str '0000'
|
||||||
|
Addr3Buff str '000000' ; str adds leading length byte
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
8
src/App.Tile.s
Normal file
8
src/App.Tile.s
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
REL
|
||||||
|
DSK TILESEG
|
||||||
|
tiledata ENT
|
||||||
|
ds 65536
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
31
src/App.s
31
src/App.s
@ -1,13 +1,38 @@
|
|||||||
; IIgs Game Engine
|
; IIgs Game Engine
|
||||||
;
|
|
||||||
DSK GTETestApp
|
|
||||||
TYP $B3 ; S16 file
|
TYP $B3 ; S16 file
|
||||||
|
DSK GTETestApp
|
||||||
XPL
|
XPL
|
||||||
|
|
||||||
; Segment #1 -- Main execution block
|
; Segment #1 -- Main execution block
|
||||||
|
|
||||||
ASM App.Main.s
|
ASM App.Main.s
|
||||||
SNA Main
|
; SNA Main
|
||||||
|
|
||||||
|
; Segment #2 -- 64KB Tile Memory
|
||||||
|
|
||||||
|
ASM App.Tile.s
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
57
src/Render.s
Normal file
57
src/Render.s
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
; Renders a frame of animation
|
||||||
|
;
|
||||||
|
; The rendering engine is built around the idea of compositing all of the moving components
|
||||||
|
; on to the Bank 01 graphics buffer and then revealing everything in a single, vertical pass.
|
||||||
|
;
|
||||||
|
; If there was just a scrolling screen with no sprites, the screen would just get rendered
|
||||||
|
; in a single pass, but it gets more complicated with sprites and various effects.
|
||||||
|
;
|
||||||
|
; Here is the high-level pipeline:
|
||||||
|
;
|
||||||
|
; 1. Identify row ranges with effects. These effects can be sprites or user-defined overlays
|
||||||
|
; 2. Turn shadowing off
|
||||||
|
; 3. Render the background for each effect row range (in any order)
|
||||||
|
; 4. Render the sprites (in any order)
|
||||||
|
; 5. Turn shadowing on
|
||||||
|
; 6. Render the background for each non-effect row, a pei slam for sprite rows, and
|
||||||
|
; the user-defined overlays (in sorted order)
|
||||||
|
;
|
||||||
|
; As a concrete example, consider:
|
||||||
|
;
|
||||||
|
; Rows 0 - 9 have a user-defined floating overlay for a score board
|
||||||
|
; Rows 10 - 100 are background only
|
||||||
|
; Rows 101 - 120 have one or more sprites
|
||||||
|
; Rows 121 - 140 are background only
|
||||||
|
; Rows 141 - 159 have a user-defined solid overlay for an animated platform
|
||||||
|
;
|
||||||
|
; A floating overlay means that some background data bay show through. A solid overlay means that
|
||||||
|
; the user-defined data covers the entire scan line.
|
||||||
|
;
|
||||||
|
; The renderer would proceed as:
|
||||||
|
;
|
||||||
|
; - shadow off
|
||||||
|
; - render_background(0, 10)
|
||||||
|
; - render_background(101, 121)
|
||||||
|
; - render_sprites()
|
||||||
|
; - shadow_on
|
||||||
|
; - render_user_overlay_1()
|
||||||
|
; - render_background(10, 101)
|
||||||
|
; - pei_slam(101, 121)
|
||||||
|
; - render_background(121, 141)
|
||||||
|
; - render_user_overlay_2()
|
||||||
|
;
|
||||||
|
; Generally speaking, a PEI Slam is faster that trying to do any sort of dirty-rectangle update by
|
||||||
|
; tracking sprinte bounding boxes. But, if an application would benefit from skipping some background
|
||||||
|
; drawing on sprite rows, that can be handled by using the low level routines to control the left/right
|
||||||
|
; edges of the rendered play field.
|
||||||
|
|
||||||
|
|
||||||
|
Render
|
||||||
|
|
||||||
|
jsr ShadowOff
|
||||||
|
|
||||||
|
jsr ShadowOn
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
|
122
src/blitter/Blitter.s
Normal file
122
src/blitter/Blitter.s
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
; This is the method that is most useful from the high-level code. We want the
|
||||||
|
; freedom to blit a range of lines. This subroutine can assume that all of the
|
||||||
|
; data in the code fields is set up properly.
|
||||||
|
;
|
||||||
|
; X = first line (inclusive), valid range of 0 to 199
|
||||||
|
; Y = last line (inclusive), valid range >X up to 199
|
||||||
|
;
|
||||||
|
; The lines are based on the appearance of lines in the play field, so blitting lines 0 through
|
||||||
|
; 19 will draw the first 20 lines on the play field, regardless of where the playfield is physically
|
||||||
|
; on the SHR screen or the current value of StartY
|
||||||
|
BltRange
|
||||||
|
clc`
|
||||||
|
|
||||||
|
tya ; Get the address of the line that we want to return from
|
||||||
|
adc StartY ; and create a pointer to it
|
||||||
|
asl
|
||||||
|
tay
|
||||||
|
lda BTableLow,y
|
||||||
|
sta exit_ptr
|
||||||
|
lda BTableHigh,y
|
||||||
|
sta exit_ptr+2
|
||||||
|
|
||||||
|
txa ; get the first line (0 - 199)
|
||||||
|
adc StartY ; add in the virtual offset (0, 207) -- max value of 406
|
||||||
|
asl
|
||||||
|
tax ; this is the offset into the blitter table
|
||||||
|
|
||||||
|
sep #$20 ; 8-bit Acc
|
||||||
|
lda BTableHigh,x ; patch in the bank
|
||||||
|
sta blt_entry+3
|
||||||
|
|
||||||
|
lda BTableLow+1,x ; patch in the page
|
||||||
|
sta blt_entry+2
|
||||||
|
|
||||||
|
; The way we patch the exit code is subtle, but very fast. The CODE_EXIT offset points to
|
||||||
|
; an JMP/JML instruction that transitions to the next line after all of the code has been
|
||||||
|
; executed. Since every code field line is bank-aligned, we know that the low-byte of the
|
||||||
|
; operand is always $00.
|
||||||
|
;
|
||||||
|
; The trick we use is to patch the low byte to force the code to jump to a special return
|
||||||
|
; function (jml blt_return) in the *next* code field line. When it's time to restore the
|
||||||
|
; code, we can unconditionally store a $00 value to set things back to normal.
|
||||||
|
;
|
||||||
|
; This is the ideal situation -- patch/restore in a single 8-bit lda #imm / sta instruction
|
||||||
|
; pair with no need to preserve the data
|
||||||
|
|
||||||
|
ldy #CODE_EXIT+1 ; this is a JMP or JML instruction that points to the next line.
|
||||||
|
lda #FULL_RETURN ; this is the offset of the return code
|
||||||
|
sta [exit_ptr],y ; patch out the low byte of the JMP/JML
|
||||||
|
rep #$20
|
||||||
|
|
||||||
|
; Now we need to set up the Bank, Stack Pointer and Direct Page registers for calling into
|
||||||
|
; the code field
|
||||||
|
|
||||||
|
pei BG1DataBank-1 ; Set the data bank for BG1 data
|
||||||
|
plb
|
||||||
|
plb
|
||||||
|
|
||||||
|
phd ; Save the application direct page
|
||||||
|
lda BlitterDP ; Set the direct page to the blitter data
|
||||||
|
tcd
|
||||||
|
|
||||||
|
sei ; disable interrupts
|
||||||
|
_R0W1
|
||||||
|
tsc ; save the stack pointer
|
||||||
|
stal stk_save+1
|
||||||
|
|
||||||
|
blt_entry jml $000000 ; Jump into the blitter code $XX/YYZZ
|
||||||
|
|
||||||
|
blt_return _R0W0
|
||||||
|
stk_save lda #0000 ; load the stack
|
||||||
|
tcs
|
||||||
|
cli ; re-enable interrupts
|
||||||
|
pld ; restore the direct page
|
||||||
|
|
||||||
|
sep #$20
|
||||||
|
ldy #CODE_EXIT+1
|
||||||
|
lda #00
|
||||||
|
sta [exit_ptr],y
|
||||||
|
rep #$20
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
; This subroutine is used to set up the BltDispatch code based on the current state of
|
||||||
|
; the machine and/or the state of the engine. The tasks it performs are
|
||||||
|
;
|
||||||
|
; 1. Set the blt_entry low byte based on the graphics engine configuration
|
||||||
|
BltSetup
|
||||||
|
sep #$20 ; Only need 8-bits for this
|
||||||
|
lda EngineMode
|
||||||
|
bit #$01 ; Are both background layers enabled?
|
||||||
|
beq :oneLyr
|
||||||
|
lda #entry_2-base
|
||||||
|
bra :twoLyr
|
||||||
|
:oneLyr lda #entry_3-base
|
||||||
|
:twoLyr sta blt_entry+1 ; set the low byte of the JML
|
||||||
|
rep #$20
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -9,6 +9,12 @@ ScreenTileHeight equ 12 ; Height of the playfield in 8x8 blocks
|
|||||||
ScreenTileWidth equ 14 ; Width of the playfield in 8x8 blocks
|
ScreenTileWidth equ 14 ; Width of the playfield in 8x8 blocks
|
||||||
|
|
||||||
StartY equ 16 ; Which code buffer line displays first on screen. Range = 0 to 207
|
StartY equ 16 ; Which code buffer line displays first on screen. Range = 0 to 207
|
||||||
|
EngineMode equ 18 ; Defined the mode/capabilities that are enabled
|
||||||
|
; bit 0: 0 = Single Background, 1 = Parallax
|
||||||
|
DirtyBits equ 20 ; Identify values that have changed between frames
|
||||||
|
|
||||||
|
BG1DataBank equ 22 ; Data bank that holds BG1 layer data
|
||||||
|
BlitterDP equ 23 ; Direct page address the holder blitter data
|
||||||
|
|
||||||
bstk equ 224 ; 16-byte stack to push bank addresses
|
bstk equ 224 ; 16-byte stack to push bank addresses
|
||||||
|
|
||||||
@ -21,6 +27,9 @@ tmp5 equ 250
|
|||||||
tmp6 equ 252
|
tmp6 equ 252
|
||||||
tmp7 equ 254
|
tmp7 equ 254
|
||||||
|
|
||||||
|
DIRTY_BIT_BG0_X equ $0001
|
||||||
|
DIRTY_BIT_BG0_Y equ $0002
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
; Collection of data tables
|
; Collection of data tables
|
||||||
;
|
;
|
||||||
|
|
||||||
; Tile2CodeOffset
|
; Col2CodeOffset
|
||||||
;
|
;
|
||||||
; Takes a tile number (0 - 40) and returns the offset into the blitter code
|
; Takes a column number (0 - 81) and returns the offset into the blitter code
|
||||||
; template.
|
; template.
|
||||||
;
|
;
|
||||||
; This is used for rendering tile data into the code field. For example, is we assume that
|
; This is used for rendering tile data into the code field. For example, is we assume that
|
||||||
; we are filling in the operans for a bunch of PEA values, we could do this
|
; we are filling in the operands for a bunch of PEA values, we could do this
|
||||||
;
|
;
|
||||||
; ldy tileNumber*2
|
; ldy tileColumn*2
|
||||||
; lda #DATA
|
; lda #DATA
|
||||||
; ldx Tile2CodeOffset,y
|
; ldx Col2CodeOffset,y
|
||||||
; sta $0001,x
|
; sta $0001,x
|
||||||
;
|
;
|
||||||
; This table is necessary, because due to the data being draw via stack instructions, the
|
; This table is necessary, because due to the data being draw via stack instructions, the
|
||||||
@ -207,3 +207,17 @@ ScreenAddr lup 200
|
|||||||
; playfield is less than 200 lines tall, then any values after 2 * PLAYFIELD_HEIGHT are undefine.
|
; playfield is less than 200 lines tall, then any values after 2 * PLAYFIELD_HEIGHT are undefine.
|
||||||
RTable ds 400
|
RTable ds 400
|
||||||
|
|
||||||
|
; Array of addresses for the banks that hold the blitter.
|
||||||
|
BlitBuff ds 4*13
|
||||||
|
|
||||||
|
; The blitter table (BTable) is a double-length table that holds the full 4-byte address of each
|
||||||
|
; line of the blit fields. We decompose arrays of pointers into separate high and low words so
|
||||||
|
; that everything can use the same indexing offsets
|
||||||
|
BTableHigh ds 208*2*2
|
||||||
|
BTableLow ds 208*2*2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
94
src/blitter/Tiles.s
Normal file
94
src/blitter/Tiles.s
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
; Collection of functions that deal with tiles. Primarily rendering tile data into
|
||||||
|
; the code fields.
|
||||||
|
;
|
||||||
|
; Tile data can be done faily often, so these routines are performance-sensitive.
|
||||||
|
;
|
||||||
|
; CopyTileConst -- the first 16 tile numbers are reserved and can be used
|
||||||
|
; to draw a solid tile block
|
||||||
|
; CopyTileLinear -- copies the tile data from the tile bank in linear order, e.g.
|
||||||
|
; 32 consecutive bytes are copied
|
||||||
|
|
||||||
|
|
||||||
|
; CopyTile
|
||||||
|
;
|
||||||
|
; Copy a solid tile into one of the code banks
|
||||||
|
;
|
||||||
|
; B = bank of the code field
|
||||||
|
; A = Tile ID (0 - 1023)
|
||||||
|
; Y = Base Adddress in the code field
|
||||||
|
|
||||||
|
CopyTile cmp #$0010
|
||||||
|
bcc :FillWord
|
||||||
|
cmp #$0400
|
||||||
|
bcc :CopyTileMem
|
||||||
|
rts ; Tile number is too large
|
||||||
|
|
||||||
|
:TilePatterns dw $0000,$1111,$2222,$3333
|
||||||
|
dw $4444,$5555,$6666,$7777
|
||||||
|
dw $8888,$9999,$AAAA,$BBBB
|
||||||
|
dw $CCCC,$DDDD,$EEEE,$FFFF
|
||||||
|
|
||||||
|
:FillWord asl
|
||||||
|
tax
|
||||||
|
ldal :TilePatterns,x
|
||||||
|
|
||||||
|
CopyTileConst sta: $0000,y
|
||||||
|
sta: $0003,y
|
||||||
|
sta $1000,y
|
||||||
|
sta $1003,y
|
||||||
|
sta $2000,y
|
||||||
|
sta $2003,y
|
||||||
|
sta $3000,y
|
||||||
|
sta $3003,y
|
||||||
|
sta $4000,y
|
||||||
|
sta $4003,y
|
||||||
|
sta $5000,y
|
||||||
|
sta $5003,y
|
||||||
|
sta $6000,y
|
||||||
|
sta $6003,y
|
||||||
|
sta $7000,y
|
||||||
|
sta $7003,y
|
||||||
|
rts
|
||||||
|
|
||||||
|
:CopyTileMem asl
|
||||||
|
asl
|
||||||
|
asl
|
||||||
|
asl
|
||||||
|
asl
|
||||||
|
tax
|
||||||
|
|
||||||
|
CopyTileLinear ldal tiledata+0,x
|
||||||
|
sta: $0000,y
|
||||||
|
ldal tiledata+2,x
|
||||||
|
sta: $0003,y
|
||||||
|
ldal tiledata+4,x
|
||||||
|
sta $1000,y
|
||||||
|
ldal tiledata+6,x
|
||||||
|
sta $1003,y
|
||||||
|
ldal tiledata+8,x
|
||||||
|
sta $2000,y
|
||||||
|
ldal tiledata+10,x
|
||||||
|
sta $2003,y
|
||||||
|
ldal tiledata+12,x
|
||||||
|
sta $3000,y
|
||||||
|
ldal tiledata+14,x
|
||||||
|
sta $3003,y
|
||||||
|
ldal tiledata+16,x
|
||||||
|
sta $4000,y
|
||||||
|
ldal tiledata+18,x
|
||||||
|
sta $4003,y
|
||||||
|
ldal tiledata+20,x
|
||||||
|
sta $5000,y
|
||||||
|
ldal tiledata+22,x
|
||||||
|
sta $5003,y
|
||||||
|
ldal tiledata+24,x
|
||||||
|
sta $6000,y
|
||||||
|
ldal tiledata+26,x
|
||||||
|
sta $6003,y
|
||||||
|
ldal tiledata+28,x
|
||||||
|
sta $7000,y
|
||||||
|
ldal tiledata+30,x
|
||||||
|
sta $7003,y
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
25
src/blitter/Vert.s
Normal file
25
src/blitter/Vert.s
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
; Subroutines that deal with the vertical scrolling and rendering. The primary function
|
||||||
|
; of these routines are to adjust tables and patch in new values into the code field
|
||||||
|
; when the virtual Y-position of the play field changes.
|
||||||
|
|
||||||
|
|
||||||
|
; SetBG0YPos
|
||||||
|
;
|
||||||
|
; Set the virtual position of the primary background layer. In addition to
|
||||||
|
; updating the direct page state locations, this routine needs to
|
||||||
|
SetBG0YPos
|
||||||
|
cmp StartY
|
||||||
|
beq :nochange
|
||||||
|
sta StartY ; Save the position
|
||||||
|
lda #DIRTY_BIT_BG0_Y ; Mark that it has changed
|
||||||
|
tsb DirtyBits
|
||||||
|
:nochange
|
||||||
|
rts
|
||||||
|
|
||||||
|
; Based on the current value of StartY in the direct page. Set up the dispatch
|
||||||
|
; information so that the BltDispatch driver will render the correct code field
|
||||||
|
; lines in the the correct order
|
||||||
|
_ApplyBG0YPos
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user