mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2025-03-13 21:33:49 +00:00
Fully flesh out Script execution implementation
This commit is contained in:
parent
740a0f260d
commit
23f7e5b0fb
130
src/Script.s
130
src/Script.s
@ -29,57 +29,103 @@
|
||||
; A = low word of script command array
|
||||
; X = high word of script command array
|
||||
; Y = number of ticks between each command step
|
||||
;
|
||||
; A pointer to the current command instruction is stored in the first 4 bytes of the
|
||||
; timer's user data section.
|
||||
StartScript ENT
|
||||
phb
|
||||
phk
|
||||
plb
|
||||
|
||||
phx ; Save the script array address
|
||||
phx ; Save the script array address
|
||||
pha
|
||||
|
||||
lda #_DoScriptStep ; Try to create a timer for this script
|
||||
ldx #^_DoScriptStep
|
||||
lda #_DoScriptSeq ; Try to create a timer for this script
|
||||
ldx #^_DoScriptSeq
|
||||
clc
|
||||
jsl AddTimer
|
||||
bcs :err ; No timer slots available :(
|
||||
bcs :err ; No timer slots available :(
|
||||
|
||||
tax ; Initialize the UeerData with the command array and PC
|
||||
tax ; Initialize the UserData with the command pointer
|
||||
pla
|
||||
sta Timers+8,x
|
||||
pla
|
||||
sta Timers+10,x
|
||||
stz Timers+12,x ; Index of the commands
|
||||
|
||||
plb
|
||||
rtl
|
||||
|
||||
:err
|
||||
pla ; Pop the values and return with the carry flag set
|
||||
pla ; Pop the values and return with the carry flag set
|
||||
pla
|
||||
plb
|
||||
rtl
|
||||
|
||||
_DoScriptStep
|
||||
lda Timers+8,x
|
||||
lda Timers+10,x
|
||||
ldy Timers+12,y
|
||||
lda [CmdList],y
|
||||
pha ; save the full command word
|
||||
; This routine executes script command until it encounters one with the STOP bit set. In some
|
||||
; sense, the stop bit acts like a "yield" in high-levellanguages.
|
||||
_DoScriptSeq
|
||||
phx ; save the timer index; will need to update user data at the end
|
||||
phb ; save the current data bank
|
||||
|
||||
and #$001E
|
||||
sep #$20 ; push the bank byte of the command list pointer on the stack
|
||||
lda Timers+10,x
|
||||
pha
|
||||
rep #$20
|
||||
|
||||
lda Timers+8,x ; get the current address of the command sequence
|
||||
tax
|
||||
plb ; pop the bank
|
||||
|
||||
; Now we are ready to process commands until reaching one with the STOP bit set. Each command
|
||||
; is 8 bytes, so we just have to do a very simple fetch/execute/increment loop. The only
|
||||
; exception is handling the JUMP bit which requires moving the script pc stored in the
|
||||
; x-register.
|
||||
|
||||
:loop phx ; Save the command address
|
||||
|
||||
lda: 0,x ; Load the command word
|
||||
pha ; Stash it
|
||||
|
||||
and #$001E ; Only have 16 built-in command. Use the _UserCallback
|
||||
tax ; command for custom functionality
|
||||
jsr (:commands,x)
|
||||
|
||||
pla ; restore the command word
|
||||
bit #$4000 ; If the branch bit is set, change the command pointer
|
||||
beq :no_jump
|
||||
lda 1,s ; Reload the command word
|
||||
|
||||
; Move to the next instruction. If the JUMP bit is set, we move the address forward or
|
||||
; backward N commands (8 bytes at a time). If the JUMP bit is not set, then just move
|
||||
; to the next entry.
|
||||
bit #$4000 ; Just do a fall through and set the jump offset to
|
||||
bne :move_addr ; a hard-coded value of 1 if the jump bit is not set
|
||||
:retry lda #$0100
|
||||
:move_addr and #$0F00 ; mask out the number of commands to move
|
||||
beq :retry ; Don't allow zeros; will cause infinite loop. Just advance by one.
|
||||
|
||||
xba ; put it in the low byte
|
||||
cmp #$0008 ; Sign-extend the 4-bit value
|
||||
bcc *+5
|
||||
ora #$FFF0
|
||||
|
||||
asl ; multiply by 8
|
||||
asl
|
||||
asl
|
||||
clc
|
||||
adc 3,s ; add it to the saved command address
|
||||
sta 3,s
|
||||
|
||||
; Check to see if we stop on this instruction, or continue executing commands
|
||||
|
||||
pla ; Reload the command word
|
||||
plx ; Pop off the update command address
|
||||
|
||||
bit #$8000 ; If the stop bit is set, we're done with this sequence
|
||||
beq :continue ; Otherwise, keep going and fetch the next command word
|
||||
|
||||
txa ; save the current command address
|
||||
plb ; restore the data bank and the timer index
|
||||
plx
|
||||
sta Timers+8,x ; store the command address back into the timer user data space
|
||||
|
||||
:no_jump
|
||||
bit #$8000 ; If the terminate bit is set, remove this handler
|
||||
beq :no_term
|
||||
txa
|
||||
jsl RemoveTimer
|
||||
:no_term
|
||||
rtl
|
||||
|
||||
:commands dw _Null,_SetPalEntry,_SwapPalEntry,_Null,_Null,_Null,_Null,_Null
|
||||
@ -101,13 +147,13 @@ _SetPalEntry
|
||||
|
||||
_SwapPalEntry txy
|
||||
|
||||
ldx ARG1,y ; Load palette values
|
||||
ldx ARG1,y ; Load palette values
|
||||
ldal SHR_PALETTES,x
|
||||
pha
|
||||
ldx ARG2,y
|
||||
ldal SHR_PALETTES,x
|
||||
|
||||
ldx ARG1,y ; and swap
|
||||
ldx ARG1,y ; and swap
|
||||
stal SHR_PALETTES,x
|
||||
|
||||
ldx ARG2,y
|
||||
@ -142,6 +188,40 @@ _UserCallback lda ARG1,x
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user