diff --git a/src/Script.s b/src/Script.s index e54820d..ed830ad 100644 --- a/src/Script.s +++ b/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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +