0 Members and 6 Guests are viewing this topic.
Script system outline:Internal notes:Warning: Do not use the following for names of a script system command"db", "dw", "end", "org", "byte", "word", "fill", "block", "addinstr","echo", "error", "list", "nolist", "equ", "show", "option", "seek"These are reserved by SPASMNaming conventions: rx = virtual register 0-7 nn = 1 byte value ww = 2 byte value b = Some value between 0-7 s = Some value between 0-15 Some names will have a more descriptive label for its use. If one is used,read the description to determine the data's size. VERY IMPORTANT NOTE: ALL SCRIPT NAMES HAVE A PERIOD (.) PRECEDING THE NAMESEVEN THOUGH THEY DO NOT SHOW IN THIS LIST. ALWAYS REMEMBER.COMMANDSET AND NAME==============================================================================------------------------------------------------------------------------------- NORMAL EVERYDAY USE --------------------------------------------------------------------------------------------------------------------------------------000 | No operation. The script system halts on encountering this. NOP | Used for filler or something.------------------------------------------------------------------------------001-008 | LOAD(rx,nn) LOAD | Stores a constant (1 byte) into a register. 2 bytes | ------------------------------------------------------------------------------009-016 | ADD(rx,nn) ADD | Adds a constant (1 byte) with a register, then stores the 2 bytes | results back to the register. Affects zero and carry flags. | There's no subtract operand for this mode. Use a negative | constant for doing that. There is no add with carry.------------------------------------------------------------------------------017-024 | CLEAR(rx) CLEAR | Sets a register to zero. 1 byte | ------------------------------------------------------------------------------025-032 | AND(rx,nn) AND | Do a bitwise AND operation between a register and a constant 2 bytes | and store the result back into the register. | Affects the zero flag. Does not affect the carry flag.------------------------------------------------------------------------------033-040 | XOR(rx,nn) XOR | Do a bitwise XOR operation between a register and a constant 2 bytes | and store the result back into the register. | Affects the zero flag. Does not affect the carry flag.------------------------------------------------------------------------------041-048 | OR(rx,nn) OR | Do a bitwise OR operation between a register and a constant 2 bytes | and store the result back into the register. | Affects the zero flag. Does not affect the carry flag.------------------------------------------------------------------------------049-056 | CPL(rx) CPL | Inverts all bits in a register. 1 byte | Affects the zero flag. | If you want to do NEG instead, just CPL, then INC it.------------------------------------------------------------------------------057-064 | WAIT(rx) WAIT | Makes the script system wait for the number of game cycles 1 byte | that is stored in a register. Remember that 24 cycles is | about one second's worth of time in normal gameplay mode. | You should be setting that register to some known value | before using this instruction. Feeding in 0 is using 256.------------------------------------------------------------------------------065-072 | CMP(rx,nn) CMP | Performs subtraction between a register and a constant in 2 bytes | the form: register-constant. The result is NOT stored back, | but instead, used to affect the zero and carry flags. | Good for use with conditional jumps.------------------------------------------------------------------------------073-080 | TEST(rx,nn) TEST | Performs a bitwise AND operation between a register and a 2 bytes | constant, but does NOT store the results back to the | register. Instead, it's used to affect the zero flag. | Used when you need to figure out which bits are set in a | register, perhaps for conditional jumps?------------------------------------------------------------------------------081-088 | TRACK(rx) TRACK | Output-only. Sets the given register to an angle that would, 1 byte | when used with the SHOOT command, fire a bullet directly | toward the player.------------------------------------------------------------------------------089-096 | SHOOT(rx) SHOOT | Fires a shot at the angle given in a register. 'nuff said. 1 byte | ------------------------------------------------------------------------------097-104 | SETSTATS(rx,nn) SETSTATS | Stores rx to an external variable. If you need to define 2 bytes | your own variables, look in the code developer's guide for | more information.------------------------------------------------------------------------------105-112 | GETSTATS(rx,nn) GETSTATS | Retrieves rx from an external variable. Again, if you need 2 bytes | to define your own variables, look in the code developer's | guide for more information.------------------------------------------------------------------------------113-120 | MULT(rx,nn) MULT | Multiplies a register by a constant, then stores the least 2 bytes | significant byte (LSB) of the result back into the register. | NOTE: If it's possible, try to use the rotate/shift | commands if you're dividing or multiplying by | multiples of 2. It's much friendlier that way. | The most significant byte (MSB) is stored in "sta.overflow" | be accessed by the getstats command. Flags are affected as | follows: Carry is set if the MSB is not zero. Zero is set if | the result in the LSB was zero (even if the whole isn't)------------------------------------------------------------------------------121-128 | DIVIDE(rx,nn) DIVIDE | Dividend (rx) / Divisor (nn) -> Quotient to (rx) 2 bytes | This is a slow operation. See if you can't use right shifts | instead. | The remainder is stored in "sta.overflow", which is accessed | via getstats command. Flags are affected as follows: | Carry is set if there is a remainder. Zero is set if the | quotient is zero (does not check remainder). | ------------------------------------------------------------------------------129-136 | INC(rx) INC | Increments rx by one. Same as ADD(rx,1) but much faster and 1 byte | uses less memory. Affects only the zero flag, to remain | consistent with how the Z80 does things.------------------------------------------------------------------------------137-144 | DEC(rx) DEC | Decrements rx by one. Same as ADD(rx,-1) but much faster and 1 byte | uses less memory. Affects only the zero flag, to remain | consistent with how the Z80 does things.------------------------------------------------------------------------------145-152 | DJNZ(rx,label) DJNZ | Automatically decrements the given register and takes the 2 bytes | specified relative jump while the register does not become | zero that cycle. Just like Z80's djnz instruction, except | you can use any register.------------------------------------------------------------------------------------------------------------------------------------------------------------153 | MOVE(rxa,rxb) MOVE | Copies the contents of register B over to register A. 2 bytes | Register A is overwritten with B and B stays the same.------------------------------------------------------------------------------154 | SWAP(rxa,rxb) SWAP | The values in register A and register B are swapped. 2 bytes | Nothing is destroyed in this operation.------------------------------------------------------------------------------155 | ADDRX(rxa,rxb) ADDRX | Adds register A and register B, then stores the result 2 bytes | back into register A. Affects only the carry flag.------------------------------------------------------------------------------156 | SUBRX(rxa,rxb) SUBRX | Subtracts register B from register A in the form of 2 bytes | rxa-rxb, then stores the result back into register A. | Affects | | ------------------------------------------------------------------------------157 | ROTR(rx,b) / ROTL(rx,b) ROTR/ROTL | Rotates a given register a number of bits right or left 2 bytes | (respectively). All bits that leave one side of the register | Immediately appears on the other side of the register. | Flags are NOT affected. | INTERNAL NOTE: Distinguishing between ROTR and ROTL is done | with bit 7 of the data byte. (1=ROTL)------------------------------------------------------------------------------158 | SHIFTR(rx,b) / SHIFTL(rx,b) SHIFTR/SHIFTL | Shifts a given register a number of bits right or left 2 bytes | (respectively. All bits that leave are gone forever. Bits | shifted in will always be zero. | Flags are NOT affected. | INTERNAL NOTE: Distinguishing between ROTR and ROTL is done | with bit 7 of the data byte. (1=SHIFTL)------------------------------------------------------------------------------159 | MULTRX(rxa,rxb) MULTRX | Multiplies register A with register B, then stores the 2 bytes | LSB of the result back to register A.------------------------------------------------------------------------------160 | DIVIDERX(rxa,rxb) DIVIDERX | Divides register A with register B in the form of rxa/rxb, 2 bytes | then stores the quotient to register A.------------------------------------------------------------------------------161 | ANDRX(rxa,rxb) ANDRX | Performs the bitwise AND function between register A and 2 bytes | register B, then stores the result to register A. Affects | the zero flag.------------------------------------------------------------------------------162 | ORRX(rxa,rxb) ORRX | Performs the bitwise OR function between register A and 2 bytes | register B, then stores the result to register A. Affects | the zero flag.------------------------------------------------------------------------------163 | XORX(rxa,rxb) XORRX | Performs the bitwise XOR function between register A and 2 bytes | register B, then stores the result to register A. Affects | the zero flag.------------------------------------------------------------------------------164 | CMPRX(rxa,rxb) CMPRX | Performs virtual subtraction between register A and register 2 bytes | B. Does NOT store the result anywhere, but the carry and | zero flags are affected as though subtraction took place. | Useful for testing conditions.------------------------------------------------------------------------------165 | TEXTRX(rxa,rxb) TESTRX | Performs a virtual AND function between register A and 2 bytes | register B. Does NOT store the result anywhere, but the | zero flag is affected as though an AND function was done. | Useful for testing bits to see if they're set.------------------------------------------------------------------------------166 | JUMPNC(label) [+ or - 127 bytes in either direction] JUMPNC | Sets the script's execution pointer to wherever you defined 2 bytes | the label only if the result of flag altering command prior | to this instruction stayed between 0 and 255 (carry flag | reset)------------------------------------------------------------------------------167 | JUMPC(label) [+ or - 127 bytes in either direction] JUMPC | Sets the script's execution pointer to wherever you defined 2 bytes | the label only if the result of flag altering command prior | to this instruction crossed zero. (Carry flag set)------------------------------------------------------------------------------168 | JUMPNZ(label) [+ or - 127 bytes in either direction] JUMPNZ | Sets the script's execution pointer to wherever you defined 2 bytes | the label only if the result of flag altering command prior | to this instruction was NOT zero. (Zero flag reset)------------------------------------------------------------------------------169 | JUMPZ(label) [+ or - 127 bytes in either direction] JUMPZ | Sets the script's execution pointer to wherever you defined 2 bytes | the label only if the result of flag altering command prior | to this instruction was zero. (Zero flag set)------------------------------------------------------------------------------170 | JUMP(label) [+ or - 127 bytes in either direction] JUMP | Unconditionally sets the script's execution pointer to 2 bytes | wherever the label is defined. Just like Z80's JR.------------------------------------------------------------------------------171 | NEWPOSRT(rx_angle,rx_radius) NEWPOSRT | Changes the firing position from the center of the enemy to 3 bytes | radius away from that center at some angle, both of which | are stored in registers. ANGLE is between 0 and 255, and | RADIUS can be anything, just note that 90 is the length of | the longest possible line on the screen. Keep that in mind | so you don't clip. | NOTE: Position is reset to center after a pause, or another | use of the NEWPOSRT command.------------------------------------------------------------------------------172 | NEWPOSXY(rx_x,rx_y) NEWPOSXY | Changes the firing position from the center of the enemy to 3 bytes | some offset X,Y away from the enemy. You MUST understand | that Y is reversed (positive values move down, negative | moves upward). To obtain negative values of a certain number | you should CPL/INC it. Or store a negative number to the | register to begin with. The screen is 64 by 64 pixels. | NOTE: Position is reset to center after a pause, or another | use of the NEWPOSRT command.------------------------------------------------------------------------------173 | USESPRITE(rx_resourceID,rx_locationID) SETSPRITE | Sets a sprite found in resourceID to an active enemy sprite 3 bytes | found in locationID. resourceID refers to a place on the | current script's resource table, which should be set at | "codegen"-time. locationID refers to a number 0-3, which | refers to which sprite slot to use (there are four).------------------------------------------------------------------------------174 | JUMPTABLE(rx_offset,nn_table_length) \.db label1,label2,... JUMPTABLE | Allows you branch to different routines depending on what 3+n bytes | is in a register. You MUST put the table immediately after | this instruction. Example: | | LOAD(r1,0) ;sets r1 to zero | JUMPTABLE(r1,4) ;r1 is the offset, 4 is the number of labels | .db Label_0 ;<-- Will be chosen, since it's the 0th one. | .db Label_1 ;Next label. If r1=1, then this is taken. | .db Label_2 ;Same, except if r1=2... | .db Label_3 ;And again... If r1=3... | | Note: If r1 is a value outside the bounds, the table is | skipped over and code beneath is will run. | Note: The labels are relative addresses, + or - 127 bytes | in either direction. This makes it prohibitive to use | very large tables. If you need to make tables that | large, use jump nodes as intermediaries. | IMPORTANT NOTE: THE TABLE CANNOT BE LARGER THAN 16 LABELS! | If you try to make it larger anyway, garden | gnomes will (likely) invade your home. | A typical use for this routine is retrieving the built-in | difficulty level, and then branching to different attacks | based on the difficulty, so one script does many things. | See how *you* can abuse this sucker. I won't be stopping you------------------------------------------------------------------------------175 | CALL(ww_relativelabel) CALL | Lets you run a subroutine so you can save precious space by 3 bytes | not having to replicate redudnant code. The spacing for this | label is double-wide, so it can reach anywhere you need it | to. DO NOT TRY TO CALL ANYTHING WHILE IN A SUBROUTINE. | Endless loops and never getting back to the main code will | result. It's safe this time around to do a PAUSE or a WAIT | while you're in a subroutine, however. It's safe this time | around to do a PAUSE/WAIT combination while in a subroutine.------------------------------------------------------------------------------176 | RETURN RETURN | Exits a subroutine. Don't try to use this if you're not in 1 byte | a subroutine. Main script code all have exit points, and | using this command is NOT one of them. You might end up | crashing your calc or something.------------------------------------------------------------------------------177 | XYTORT(rxa_x,rxb_y,rxc_r,rxd_t) XYTORT | Takes of the x,y coordinates found in registers A and B 3 bytes | (respectively), then uses the position given by the center | of the enemy in use (or whereever newposxy/newposrt has | changed it to) to output a distance and an angle in | registers C and D, respectively.------------------------------------------------------------------------------178 | RTTOXY(rxa_r,rxb_t,rxc_x,rxd_y) RTTOXY | Similar to above, except it takes a distance and an angle, 3 bytes | then converts it to its corresponding x,y coordinates, | outputting to registers C and D, respectively. | The starting position is the center of the enemy in use or | wherever you changed it to via newposxy/newposrt. |------------------------------------------------------------------------------179 | GETPLAYERXY(rxa_x,rxb_y) GETPLAYERXY | Outputs the player's X,Y coordinates to registers A and B, 2 bytes | respectively. If you only need an angle, you should be using | the TRACK command instead. Much faster that way.
I wanted to make sure it looked nice, but really, I just wanted to make sure that I have no dead test code sitting around like I did with the old CaDan.
StageScript: .load(r1,128) ;starting angle .load(r2,6) ;starting variable radius .load(r4,5) ;counter for increment .load(r5,1) ;toggle .load(r6,10) ;delay between cycles. Also hardcoded in routineStageScriptCont: .load(r0,2) \ .wait(r0) .newposrt(r1,r2) ;angle,radius .add(r1,3) .call(CustomMakeBullet) .move(r3,r2) .add(r3,3) .newposrt(r1,r3) .call(CustomMakeBullet) .dec(r6) .jumpnz(_) ;cycle delay .load(r6,10) .addrx(r2,r5) ;changing radius .dec(r4) .jumpnz(_) .load(r4,5) .cpl(r5) .inc(r5)_: .setstats(r7,rs.debug1) .jump(StageScriptCont)CustomMakeBullet: .runasm(_) bit fbt1full,(iy+stateflags) jr nz,SSSKIP;Include and call ionRandom for varying bullet speeds when that test;is about to be performed ld c,$20 ld hl,freebullet1 ld e,(hl) ;1.READ inc (hl) ;2.INC ld d,$8C ld a,(de) ld (ix+7),a jp p,$+7 set fbt1full,(iy+stateflags) ld h,$88>>2 add a,a ld L,a add hl,hl add hl,hl xor a ld (hl),CLSB(TestEBTShot) inc L ld (hl),CMSB(TestEBTShot) inc L ld (hl),c ;acc/TTL inc L ld (hl),b ;angle (allow to be uninitialized for now) inc L ld bc,(curpos) ;C=Y,B=X ld (hl),a ;*.8 set to zero inc L ld (hl),c ;8.* X position inc L ld (hl),a ;*.8 also set to zero inc L ld (hl),b ;8.* Y position. Finished writingSSSKIP: jp r.runasm.ret_: .return