DEF TITREK REF GPLLNK,GPLWS,KSCAN,XMLLNK REF VSBR,VMBR,VSBW,VMBW,VWTR TITREK LWPI WS Load workspace registers at >20BE LI R15,STACK Load R15 with stack location MOV R11,*R15+ Move return address(R11) into Stack block and increment R15 LI R0,>1200 Load R0 with VDP address >1200 MOV R0,@VSTACK Copy R0 into Floating Point Stack location in VDP BL @INIT Branch and Link to Initialize subroutine MAIN BL @TITLE Branch and Link to Title subroutine BL @SETUP Branch and Link to Setup subroutine BL @DRAWSC Branch and Link to Draw Screen subroutine BL @GENQD Branch and Link to Generate Quadrant subroutine BL @CONTRL Branch and Link to Control Routine. This routine isn't * left until game has concluded. PLAYAG LI R0,738 Load and print "play again?" on screen LI R1,GO7 * LI R2,17 * BLWP @VMBW * LI R0,756 Load R0 with 736 MOV R0,@CURPOS Move 736 into CURPOS, the cursor position on screen MASCAN BL @SCAN Branch and Link to key scan subroutine. When a key is * pressed this routine is returned from. CB @KEYVAL,@KY Compare key value to Y JEQ MAIN If equal, jump back to Main label above CB @KEYVAL,@KN Compare key value to N JNE MASCAN If not equal, jump back to mascan label. LIMI 2 Open interrupts LWPI GPLWS Load GPL workspace registers BLWP @>0000 Branch and Link to >0000 (Quit to Master Title Screen) CURPOS BSS 2 Word variable, cursor position ENERGY BSS 2 Word variable, energy amount TIME BSS 2 Word variable, time remaining TORPS BSS 2 Word variable, torpedoes remaining ENEMY BSS 2 Word variable, enemy drones remaining QROW BSS 2 Word variable, Quadrant row QCOL BSS 2 Word variable, Quardrant column NUM BSS 2 Word variable, storage for number obtained from player DEG BSS 2 Word variable, degree angle INC BSS 2 Word variable, increment angle DIF BSS 2 Word variable, difficulty of game OLDPOS BSS 2 Word variable, old position in movement CHKPOS BSS 2 Word variable, checking variable for movement TPOS BSS >28 Word array, positions of all quadrant objects 1-20 TTYPE BSS >14 Byte array, quadrant object types 1-20 * (Position is always your ship. Ttype(0) is also used to * store whether shields are up or down.) GALAXY BSS >50 Word array. Data stored in 5 columns of 8 rows. first byte * weight >80 stores if the quadrant has been scanned or * visited, weight >08->01 stores the number of enemy ships. * Second byte weight >80 stores if there's a base ship present * or not. Weight >08->01 stores the number of mines. STRING BSS 4 8 byte array, stores strings of data inputed by player. ADJY BSS 8 FP number, adjustment Y value ADJX BSS 8 FP number, adjustment X value CURY BSS 8 FP number, current Y value CURX BSS 8 FP number, current X value RAD BSS 8 FP number, angle in radians INTY BSS 2 Word variable, integer Y position INTX BSS 2 Word variable, integer X position STACK BSS >20 Word array, return address stack. (16 levels possible). * In-game text below. Self-explanatory. START1 TEXT 'TI-TREK' EVEN START2 TEXT 'TEXAS INSTRUMENTS' EVEN START3 TEXT 'COPYRIGHT 1980' START4 TEXT 'TMS9900 ASSEMBLY VERSION' START5 TEXT 'COPYRIGHT 2003 - ADAM HAASE' EVEN START6 TEXT 'LEVEL OF DIFFICULTY:' START7 TEXT '1-EASY,5-HARD' EVEN CMD1 TEXT 'COMMAND?' CMD2 TEXT 'ANGLE IN DEGREES?' EVEN CMD3 TEXT 'DESTINATION ROW?' CMD4 TEXT 'DESTINATION COL?' CMD5 TEXT 'MOVE HOW FAR?' EVEN CMD6 TEXT 'EMERGENCY STOP!' EVEN CMD7 TEXT 'NO TORPEDOES LEFT' EVEN CMD8 TEXT 'OUTSIDE PATROL BOUNDARY' EVEN CMD9 TEXT 'ALREADY HERE' CMD10 DATA >9191,>9120,>5741,>5250 This is "XXX WARP XXX" with somes special * characters. DATA >2091,>9191 CMD11 TEXT 'MAGNETIC STORM' CMD12 TEXT 'BLOWN OFF COURSE' CMD13 TEXT 'NO BASE NEAR' CMD14 TEXT 'HOW MUCH POWER?' EVEN CMD15 TEXT 'WASTED' CMD16 TEXT 'INCREMENT ANGLE?' CMD17 TEXT 'ALERT! FOES FIRING!' EVEN CMD18 TEXT 'LONG RANGE SCAN' EVEN CMD19 TEXT 'PRESS ENTER' EVEN GO1 TEXT 'CONGRATULATIONS!' GO2 TEXT 'ALL ENEMY SHIPS DESTROYED!' GO3 TEXT 'YOU HAVE SAVED THE GALAXY!' GO4 TEXT 'TIME EXPIRED' GO5 TEXT 'ENERGY GONE' EVEN GO6 TEXT 'GAME OVER, YOU LOST' EVEN GO7 TEXT 'PLAY AGAIN? (Y/N)' EVEN DISP1 TEXT 'TORP' DISP2 TEXT 'PWR' EVEN DISP3 TEXT 'FOES' DISP4 TEXT 'TIME' DISP5 TEXT 'QUAD(' SHIP DATA >0040,>EF24,>3E00,>0000 Ship pattern SHLD DATA >5A81,>40EF,>243E,>815A Ship with shields up pattern DRONE DATA >0000,>037F,>3060,>F000 Drone pattern BASE DATA >0018,>99BD,>FF99,>18E7 Base ship pattern MINE DATA >0010,>5428,>D628,>5410 Mine pattern TORP DATA >0000,>0010,>3810,>0000 Torpedo pattern EXP1 DATA >815A,>3C66,>663C,>5A81 Explosion frame 1 pattern EXP2 DATA >0000,>3810,>3800,>0000 Explosion frame 2 pattern BLANK DATA >0000,>0000,>0000,>0000 Blank pattern BLOCK DATA >FFFF,>FFFF,>FFFF,>FFFF Block pattern CURSOR DATA >0000,>0000,>0000,>007C Cursor pattern COLDAT DATA >F1E1,>8151,>B100,>0000 Color set data BAR1 DATA >8181,>8181,>8181,>8181 20 byte data block of character >81. (black blank) DATA >8181,>8181,>8181,>8181 DATA >8181,>8181 BAR2 DATA >2D2D,>2D2D,>2D2D,>2D2D 20 byte data block of character >2d. (minus) DATA >2D2D,>2D2D,>2D2D,>2D2D DATA >2D2D,>2D2D BAR3 DATA >2020,>2020,>2020,>2021 20 byte data block. (minuses and spaces for LRS) DATA >2020,>2020,>2021,>2020 DATA >2020,>2020 BAR4 DATA >2020,>2021,>2020,>2021 20 byte data block (minuses and spaces for chart) DATA >2020,>2021,>2020,>2021 DATA >2020,>2021 BAR0 DATA >2020,>2020,>2020,>2020 32 byte data block (all spaces, used for clearing DATA >2020,>2020,>2020,>2020 screen and other purposes.) DATA >2020,>2020,>2020,>2020 DATA >2020,>2020,>2020,>2020 RADCNV DATA >4039,>1D39,>4F33,>1E52 FP constant, used to convert degrees to radians, * 57.29577951. (180/PI) FP05 DATA >3F32,>0000,>0000,>0000 FP constant, 0.5. Used to round up. NGONE DATA >BFFF,>0000,>0000,>0000 FP constant, -1. Used to flip cosine around. DIV1K DATA >03E8 Constant, 1,000 in hexidecimal. DIV1H DATA >0064 Constant, 100 in hexidecimal. DIV10 DATA >000A Constant, 10 in hexidecimal. M160 DATA >00A0 Constant, 160 in hexidecimal. M6 DATA >0006 Constant, 6 in hexidecimal. ROW DATA >0020 Constant, 32 in hexidecimal. NUMOFF BYTE >30 Constant, number offset. (48 decimal) ANYKEY BYTE >20 Constant. (32 decimal, or weight >20 for key scan) KL BYTE >4C Key constant, the letter 'L'. KS BYTE >53 Key constant, the letter 'S'. KW BYTE >57 Key constant, the letter 'W'. KM BYTE >4D Key constant, the letter 'M'. KD BYTE >44 Key constant, the letter 'D'. KC BYTE >43 Key constant, the letter 'C'. KT BYTE >54 Key constant, the letter 'T'. KF BYTE >46 Key constant, the letter 'F'. KQ BYTE >51 Key constant, the letter 'Q'. KV BYTE >56 Key constant, the letter 'V'. KN BYTE >4E Key constant, the letter 'N'. KY BYTE >59 Key constant, the letter 'Y'. KENTER BYTE >0D Key constant, the Enter key. KMINUS BYTE >2D Key constant, the symbol '-'. KBACK BYTE >0F Key constant, FNCT-9 HSHIP BYTE >80 Character constant, the ship. HMINE BYTE >A0 Character constant, a mine. HBASE BYTE >98 Character constant, a base. HDRONE BYTE >90 Character constant, a drone. HSPACE BYTE >81 Character constant, empty space. HEMPTY BYTE >82 Character constant, a recently emptied space. H01 BYTE >01 Constant, the number 1 in byte. * Sound data. The first 28 groups of 8 bytes is the torpedo incrementing sound. The second 20 groups of 8 bytes is the warp incrementing sound. Afterwards, the remaining 8 sounds are bracketed in 16 byte groups for easy access by the sound system. SNDDAT DATA >0380,>0A93,>0301,>9F00 Start of torpedo sounds. A maximum of 28 is DATA >038D,>0993,>0301,>9F00 possible to hear, if a torpedo is fired from a far DATA >038A,>0993,>0301,>9F00 corner at a perpendicular angle to the opposite DATA >0387,>0993,>0301,>9F00 corner. DATA >0384,>0993,>0301,>9F00 DATA >0381,>0993,>0301,>9F00 DATA >038E,>0893,>0301,>9F00 DATA >038B,>0893,>0301,>9F00 DATA >0388,>0893,>0301,>9F00 DATA >0385,>0893,>0301,>9F00 DATA >0382,>0893,>0301,>9F00 DATA >038F,>0793,>0301,>9F00 DATA >038C,>0793,>0301,>9F00 DATA >0389,>0793,>0301,>9F00 DATA >0386,>0793,>0301,>9F00 DATA >0383,>0793,>0301,>9F00 DATA >0380,>0793,>0301,>9F00 DATA >038D,>0693,>0301,>9F00 DATA >038A,>0693,>0301,>9F00 DATA >0387,>0693,>0301,>9F00 DATA >0384,>0693,>0301,>9F00 DATA >0381,>0693,>0301,>9F00 DATA >038E,>0593,>0301,>9F00 DATA >038B,>0593,>0301,>9F00 DATA >0388,>0593,>0301,>9F00 DATA >0385,>0593,>0301,>9F00 DATA >0382,>0593,>0301,>9F00 DATA >038F,>0483,>0301,>9F00 DATA >0383,>1592,>0A01,>9F00 Start of warp sounds. A maximum of 20 is possible. DATA >038C,>1492,>0A01,>9F00 DATA >0386,>1492,>0A01,>9F00 DATA >038F,>1392,>0A01,>9F00 DATA >0389,>1392,>0A01,>9F00 DATA >0383,>1392,>0A01,>9F00 DATA >038D,>1292,>0A01,>9F00 DATA >0387,>1292,>0A01,>9F00 DATA >0381,>1292,>0A01,>9F00 DATA >038C,>1192,>0A01,>9F00 DATA >0386,>1192,>0A01,>9F00 DATA >0381,>1192,>0A01,>9F00 DATA >038C,>1092,>0A01,>9F00 DATA >0386,>1092,>0A01,>9F00 DATA >0381,>1092,>0A01,>9F00 DATA >038C,>0F92,>0A01,>9F00 DATA >0387,>0F92,>0A01,>9F00 DATA >0382,>0F92,>0A01,>9F00 DATA >038D,>0E92,>0A01,>9F00 DATA >0389,>0E92,>3C01,>9F00 DATA >038D,>2692,>0201,>9F00 Movement sound DATA >0000,>0000,>0000,>0000 DATA >058C,>0192,>E2F2,>0F02 Emergency stop sound DATA >9FFF,>0000,>0000,>0000 DATA >02E6,>F00A,>01FF,>0000 Explosion 1 sound DATA >0000,>0000,>0000,>0000 DATA >02E7,>F003,>01FF,>0000 Explosion 2 sound DATA >0000,>0000,>0000,>0000 DATA >0584,>0E92,>E0F0,>0202 Warp entry #1 sound DATA >9FFF,>0000,>0000,>0000 DATA >058C,>0193,>E5F1,>0C02 Warp entry #2 sound DATA >9FFF,>0000,>0000,>0000 DATA >02E1,>F001,>01FF,>0000 Warp exit sound DATA >0000,>0000,>0000,>0000 DATA >02E5,>F00C,>01FF,>0000 Attack sound DATA >0000,>0000,>0000,>0000 WS EQU >20BE Location of workspace registers in low memory. STATUS EQU >837C Status byte location. KEYADR EQU >8374 Key address location. KEYVAL EQU >8375 Key value location. VSTACK EQU >836E VDP FP stack location pointer. FAC EQU >834A Floating Point Accumlulator location. ARG EQU >835C Argument for FAC location. CIF EQU >2300 Convert Integer to Floating Point XMLLNK command. CFI EQU >1200 Convert Floating Point to Integer XMLLNK command. FADD EQU >0600 FP adding routine, XMLLNK. FMUL EQU >0800 FP multiplying routine, XMLLNK. FDIV EQU >0900 FP division routine, XMLLNK. INT EQU >0022 Round FP off into Integer, GPLLNK routine. SIN EQU >002E Calculate sine, GPLLNK routine. COS EQU >002C Calculate cosine, GPLLNK routine. SQR EQU >0026 Calculate square root, GPLLNK routine. CONTRL MOV R11,*R15+ Move return address to stack, increment stack pointer. CNLOOP LI R0,683 Load R0 with 683, move into cursor position. MOV R0,@CURPOS * BL @WIPE Branch and link to Wipe subroutine. LI R0,674 Put "Command? " on screen. LI R1,CMD1 * LI R2,8 * BLWP @VMBW * BL @SCAN Scan for key press. MOV @CURPOS,R0 Store cursor position in R0 MOVB @KEYVAL,R1 Move key value to R1 BLWP @VSBW Print character pressed onto screen. CB @KEYVAL,@KS Was S pressed? JNE CON1 If no, jump to next key check. BL @SHLDS Branch and link to shields subroutine. B @CNLOOP Return to CNLOOP above. CON1 CB @KEYVAL,@KL Was L pressed? JNE CON2 If no, jump to next key check. BL @LRSCAN Branch and link to long-range scan subroutine. B @CNLOOP Return to CNLOOP above CON2 CB @KEYVAL,@KC Was C pressed? JNE CON3 If no, jump to next key check. BL @CHART Branch and link to galactic chart subroutine. B @CNLOOP Return to CNLOOP above CON3 CB @KEYVAL,@KT Was T pressed? JNE CON4 If no, jump to next key check. CLR @INC Clear INC to 0. (Only one torpedo.) BL @FTORP Branch and Link to Torpedo subroutine. BL @ENLOOP Branch and Link to Enemy Loop subroutine. B @CNLOOP Return to CNLOOP above. CON4 CB @KEYVAL,@KV Was V pressed? JNE CON5 If no, jump to next key check. LI R0,2 Load R0 with a value of 2. MOV R0,@INC Copy R0 into INC. (Three torpedos.) BL @FTORP Branch and Link to Torpedo subroutine. BL @ENLOOP Branch and Link to Enemy Loop subroutine. B @CNLOOP Return to CNLOOP above. CON5 CB @KEYVAL,@KM Was M pressed? JNE CON6 If no, jump to next key check. BL @MOVE Branch and Link to Movement subroutine. BL @ENLOOP Branch and Link to Enemy Loop subroutine. B @CNLOOP Return to CNLOOP above. CON6 CB @KEYVAL,@KW Was W pressed? JNE CON7 If no, jump to next key check. BL @WARP Branch and Link to Warp subroutine. BL @ENLOOP Branch and Link to Enemy Loop subroutine. B @CNLOOP Return to CNLOOP above. CON7 CB @KEYVAL,@KD Was D pressed? JNE CON8 If no, jump to next key check. BL @DOCK Branch and link to Dock subroutine. B @CNLOOP Return to CNLOOP above. CON8 CB @KEYVAL,@KF Was F pressed? JNE CON9 If no, jump to next key check. BL @FIRE Branch and link to Fire Lasers subroutine. BL @ENLOOP Branch and Link to Enemy Loop subroutine. B @CNLOOP Return to CNLOOP above. CON9 CB @KEYVAL,@KQ Was Q pressed? JEQ CONEND If yes, jump to CONEND B @CNLOOP Otherwise, jump back to CNLOOP to repeat key scan. CONEND B @SUBRET Return to calling routine. ENLOOP MOV R11,*R15+ Move return address to stack, increment stack pointer. MOV @QROW,R0 Move Quadrant row into R0. MOV @QCOL,R1 Move Quadrant column into R1. BL @GETQD Branch and Link to Get Quadrant. MOV R12,R12 Check to see if R12 (# of drones) is 0. JEQ CHKNUM If it is, jump to CHKNUM and skip attack phase. LI R4,45 Load R4 with 45. BL @DELAY Branch and Link to Delay subroutine. BL @WIPE Branch and LInk to Wipe subroutine. LI R0,674 Print "Alert! foes are firing!" on screen. LI R1,CMD17 * LI R2,19 * BLWP @VMBW * ATKLP LI R0,>0706 Load R0 with VDP register 7, color >06. BLWP @VWTR Write to VDP register. (Turn screen red). LI R0,>11F0 Load sound table location. (Attack sound) BL @SNDCON Branch and Link to Sound Control subroutine. LI R0,30 Load R0 with 30. MPY @DIF,R0 Multiply 30 by the difficulty, store in R0 and R1. AI R1,120 Add 120 to R1. MOV @DIF,R2 Move Difficulty value into R2. MPY @ROW,R2 Multiply Difficulty by 32. Stores in R3, which is used for * random number generation. BL @RANDNO Branch and link to random number subroutine. AI R5,R1 Add R5 (random number) to R1, total damage dealt. CB @TTYPE,@HSHIP Check to see if shields are up or down. JEQ LOSEN If equal, shields are down, go directly to energy loss. SRL R1,2 Otherwise, shift R1 to the right by 2. (Divide by 4). LOSEN S R1,@ENERGY Subtract R1 from Energy. C @ENERGY,@BLANK Check Energy against 0. JGT ATKDN If greater than 0, skip next instruction. MOV @BLANK,@ENERGY Set Energy to 0. (If equal or below 0) ATKDN LI R0,>0703 Load R0 with VDP register 7, color >03. BLWP @VWTR Write to VDP register. (Turn screen green.) LI R4,10 Load R4 with 10. BL @DELAY Branch and Link to Delay subroutine. DEC R12 Decrement R12. MOV R12,R12 Check to see if R12 is 0. JNE ATKLP If not, loop back to ATKLP CHKNUM BL @UPDNUM Update all numbers on screen. (energy, time.) C @TIME,@BLANK Check to see if time is 0. JLE LTIME If so, jump to LTIME. (Lost game due to time running out.) C @ENERGY,@BLANK Check to see if energy is 0. JLE LENG If so, jump to LENG. (Lost game due to energy running out.) C @ENEMY,@BLANK Check to see if # of enemies is 0. JEQ WINGME If so, jump to WINGME. (Won game!) B @SUBRET Return to calling routine. LTIME BL @WIPE Wipe bottom part of screen. LI R0,642 Write "Ran out of time" on screen LI R1,GO4 * LI R2,12 * BLWP @VMBW * JMP OVER Jump to "Over" in next part. LENG BL @WIPE Wipe bottom part of screen. LI R0,642 Write "ran out of energy" on screen. LI R1,GO5 * LI R2,11 * BLWP @VMBW * OVER AI R0,32 Write "You have lost the game." on screen. LI R1,GO6 * LI R2,19 * BLWP @VMBW * B @PLAYAG Branch to "play again?" label up in main loop. WINGME BL @WIPE Wipe bottom part of screen. LI R0,642 Write "You won!" and various bits on screen. LI R1,GO1 * LI R2,16 * BLWP @VMBW * AI R0,32 * LI R1,GO2 * LI R2,26 * BLWP @VMBW * AI R0,32 * LI R1,GO3 * BLWP @VMBW * B @PLAYAG Branch to "play again?" label up in main loop. SNDCON MOV R11,*R15+ Move return address to stack, increment stack pointer. MOV R0,@>83CC Move sound location into >83CC. MOVB @H01,@>83CE Set auto-sound counter. SOCB @H01,@>83FD set auto-sound to activate. SNDLP LIMI 2 Open and close interrupts. LIMI 0 * MOVB @>83CE,@>83CE Check to see if >83CE is 0 yet. JNE SNDLP If not, continue to loop. B @SUBRET Return to calling routine. GENQD MOV R11,*R15+ Move return address to stack, increment stack pointer. MOV @QROW,R0 Move quadrant row to R0. MOV @QCOL,R1 Move quadrant column to R1. BL @GETQD Branch and Link to get quadrant subroutine. MOV @GALAXY(R1),R7 Move Galaxy data at location GALAXY+R1 into R7. ANDI R7,>FF7F Reset bit >0080 in R7. (Quadrant visited.) MOV R7,@GALAXY(R1) Move R7 into GALAXY+R1. LI R8,1 Load R8 with value of 1. (Counter for objects.) LI R9,TTYPE+1 Load R9 with TTYPE address+1. MOV R7,R12 Move R7 into R12. ANDI R7,>8000 Reset all bits except >8000 in R7. (Base present.) CI R7,0 Is R7 0? JEQ PLTMNE If yes, jump to plot mines. LI R1,>9800 Otherwise, load R1 with Base graphic MOVB R1,*R9+ And copy R1's high-byte into R9 indirect and increment R9. INC R8 Increment R8. (Counter for objects.) PLTMNE MOV R12,R7 Copy R12 back into R7. ANDI R7,>7F00 Reset all bits but >7F00. (# of mines.) SRA R7,8 Shift R7 over 8 bits. (Make a word, not a byte.) CI R7,0 Check to see if R7 is 0. JEQ PLTENM If so, jump to plot enemy. LI R1,>A000 Otherwise load, R1 with Mine graphic. MINELP MOVB R1,*R9+ Copy R1's high byte into R9 indirect and increment R9. INC R8 Increment R8. (object counter) DEC R7 Decrement R7. (# of mines remaining) JNE MINELP Jump up to Mine loop unless R7=0. PLTENM MOV R12,R7 Copy R12 back into R7. ANDI R7,>007F Reset all bits but >007f. (# of drones.) CI R7,0 Check to see if R7 is 0. JEQ PLTEMP If so, jump to plot empty. LI R1,>9000 Otherwise, load Drone character into R1. ENEMLP MOVB R1,*R9+ Copy R1's high byte into R9 indirect and increment R9 INC R8 Increment r8. (Object counter) DEC R7 Decrement R7. (# of drones remaining.) JNE ENEMLP Jump up to Enemy loop unless R7=0. PLTEMP CI R8,20 Check to see if R8 is 20. JEQ PLTST If so, then everything is plotted, go to PLTST. LI R1,>8200 Otherwise, load R1 with "special" blank space. MOVB R1,*R9+ Copy R1's high byte into R9 indirect and increment R9. INC R8 Increment R8. JMP PLTEMP Jump up to Plot empty loop. PLTST CLR R8 Clear R8. (reset object counter to 0). LI R12,TPOS Load R12 with TPOS address. LI R13,TTYPE Load R13 with TTYPE address. PLOTRC LI R0,2 Load R0 with 2. (Column offset) LI R3,19 Load R3 with 19. BL @RANDNO Get random number, 0-19. (Row) MPY @ROW,R5 Multiply R5 (random number) by 32. A R6,R0 Add R6 (random number) to R0. LI R3,19 Load 0-19 into R3. BL @RANDNO Get random number, 0-19. (Column) A R5,R0 Add random number to R0. BLWP @VSBR Read in byte from position in R0 from screen. CI R1,>8100 Check R1 to see if it's empty space or not. JNE PLOTRC If it isn't, go back and get a new random coordinate. MOVB *R13+,R1 Otherwise, move the object character into R1, increment R13 BLWP @VSBW And write it to the screen. MOV R0,*R12+ Copy R0 (position coordinate) into TPOS and increment R12. INC R8 Increment R8 CI R8,20 If R8=20, all objects plotted, otherwise reloop until done. JLT PLOTRC * * This part removes >82 from the screen, which is a special "empty" space used solely * to make certain that none of the 20 objects overlap each other by accident. CLR R4 Clear R4 (New counter) LI R2,TPOS Load R2 with TPOS address. LI R3,TTYPE Load R3 with TTYPE address. BLKPLT MOV *R2+,R0 Copy Position into R0, increment R2. MOVB *R3+,R1 Copy Type into R1, increment R3. CI R1,>8200 Check if R1 is a "special" blank space. JNE BLKSKP If not, skip this part. LI R1,>8100 Load R1 with normal empty space BLWP @VSBW Write it to screen. BLKSKP INC R4 Increment counter CI R4,20 Check if R4 is 20. JLT BLKPLT If not, loop back and plot blanks until done. B @SUBRET Return to calling routine. REPLOT MOV R11,*R15+ Move return address to stack, increment stack pointer. BL @SRSCAN Clear the short-range scan window. CLR R7 Clear R7. LI R8,TPOS Load TPOS address into R8. LI R9,TTYPE Load TTYPE address into R9. PLOTLP MOV *R8+,R0 Copy position into R0. MOVB *R9+,R1 Copy type into R1. CB R1,@HEMPTY Check to see if R1 is >82 or not (special empty) JEQ PLTSKP If so, don't plot anything, skip this one. BLWP @VSBW Otherwise, plot object to screen. PLTSKP INC R7 Increment counter. CI R7,20 If 20, we're done, otherwise loop. JLT PLOTLP * B @SUBRET Return to calling routine. COURSE MOV R11,*R15+ Move return address to stack, increment stack pointer. LI R1,CURY Load R1 with CURY address. LI R2,FAC Load R2 with FAC address. BL @MOVFP Move FP number from R1 to R2. LI R1,ADJY Load R1 with ADJY address. LI R2,ARG Load R2 with ARG address. BL @MOVFP Move FP number from R1 to R2. BLWP @XMLLNK Add the FP numbers in FAC and ARG. DATA FADD * LI R1,FAC Load R1 with FAC address. LI R2,CURY Load R2 with CURY address. BL @MOVFP Move FP number from R1 to R2. LI R1,FP05 Load R1 with FP05 constant address. LI R2,ARG Load R2 with ARG address. BL @MOVFP Move FP number from R1 to R2. BLWP @XMLLNK Add the FP numbers in FAC and ARG. DATA FADD * CLR @STATUS Clear the status byte. BLWP @GPLLNK Convert FP number at FAC to whole integer FP number. DATA INT * BLWP @XMLLNK Convert FP number at FAC to real integer. DATA CFI * MOV @FAC,@INTY Move word at FAC into INTY. LI R1,CURX Load R1 with CURX address. LI R2,FAC Load R2 with FAC address. BL @MOVFP Move FP number from R1 to R2. LI R1,ADJX Load R1 with ADJX address. LI R2,ARG Load R2 with ARG address BL @MOVFP Move FP number from R1 to R2. BLWP @XMLLNK Add the FP numbers in FAC and ARG. DATA FADD * LI R1,FAC Load R1 with FAC address. LI R2,CURX Load R2 with CURX address. BL @MOVFP Move FP number from R1 to R2. LI R1,FP05 Load R1 with FP05 constant address. LI R2,ARG Load R2 with ARG address. BL @MOVFP Move FP number from R1 to R2. BLWP @XMLLNK Add the FP numbers in FAC and ARG. DATA FADD * CLR @STATUS Clear the status byte. BLWP @GPLLNK Convert FP number at FAC to whole integer FP number. DATA INT * BLWP @XMLLNK Convert FP number at FAC to real integer. DATA CFI * MOV @FAC,@INTX Move word at FAC into INTX B @SUBRET Return to calling routine. CREAXY MOV R11,*R15+ Move return address to stack, increment stack pointer. MOV @INTY,@FAC Move INTY value into FAC. BLWP @XMLLNK Convert word at FAC into FP number at FAC. DATA CIF * LI R1,FAC Load R1 with FAC address. LI R2,CURY Load R2 with CURY address. BL @MOVFP Move FP number from R1 to R2. MOV @INTX,@FAC Move INTX value into FAC BLWP @XMLLNK Convert word at FAC into FP number at FAC. DATA CIF * LI R1,FAC Load R1 with FAC address. LI R2,CURX Load R2 with CURX address. BL @MOVFP Move FP number from R1 to R2. MOV @DEG,@FAC Move DEG value into FAC. BLWP @XMLLNK Convert word at FAC into FAC number at FAC. DATA CIF * LI R1,FAC Load R1 with FAC address. LI R2,ARG Load R2 with ARG address. BL @MOVFP Move FP number from R1 to R2. LI R1,RADCNV Load R1 with constant RADCNV address. LI R2,FAC Load R2 with FAC address. BL @MOVFP Move FP number from R1 to R2. BLWP @XMLLNK Divide FP number at FAC by ARG. DATA FDIV * LI R1,FAC Load R1 with FAC address. LI R2,RAD Load R2 with RAD address. BL @MOVFP Move FP number from R1 to R2. CLR @STATUS Clear status byte. BLWP @GPLLNK Calculate cosine of number at FAC. DATA COS * LI R1,NGONE Load R1 with NGONE constant address. LI R2,ARG Load R2 with ARG address. BL @MOVFP Move FP number from R1 to R2. BLWP @XMLLNK Multiply FAC by ARG. DATA FMUL * LI R1,FAC Load R1 with FAC address. LI R2,ADJY Load R2 with ADJY address. BL @MOVFP Move FP number from R1 to R2. LI R1,RAD Load R1 with RAD address. LI R2,FAC Load R2 with FAC address. BL @MOVFP Move FP number from R1 to R2. CLR @STATUS Clear status byte. BLWP @GPLLNK Calculate sine of number at FAC. DATA SIN * LI R1,FAC Load R1 with FAC address. LI R2,ADJX Load R2 with ADJX address. BL @MOVFP Move FP number from R1 to R2. B @SUBRET Return to calling routine. TITLE MOV R11,*R15+ Move return address to stack, increment stack pointer. BL @CLRSCR Clear screen. LI R0,204 Write all the title text on screen. Fairly self-explanatory. LI R1,START1 * LI R2,7 * BLWP @VMBW * LI R0,264 * LI R1,START2 * LI R2,17 * BLWP @VMBW * LI R0,329 * LI R1,START3 * LI R2,14 * BLWP @VMBW * LI R0,452 * LI R1,START4 * LI R2,24 * BLWP @VMBW * LI R0,515 * LI R1,START5 * LI R2,27 * BLWP @VMBW * B @SUBRET Return to calling routine. SETUP MOV R11,*R15+ Move return address to stack, increment stack pointer. LI R0,704 Write "Level of difficulty?" and stuff on screen. LI R1,START6 * LI R2,20 * BLWP @VMBW * LI R0,736 * LI R1,START7 * LI R2,13 * BLWP @VMBW * LI R0,725 Load Cursor position with 725. MOV R0,@CURPOS * LOOP BL @SCAN Scan for keystroke LI R0,>3100 Load R0 with "1" character. CB @KEYVAL,R0 Check key value against R0. JLT LOOP If less, try scanning again. LI R0,>3500 Load R0 with "5" character. CB @KEYVAL,R0 Check key value against R0. JGT LOOP If greater, try scanning again. CLR R1 Clear R1. MOVB @KEYVAL,R1 Move key value into R1 MOV @CURPOS,R0 Move cursor position into R0. BLWP @VSBW Write number on screen in cursor position. SB @NUMOFF,@KEYVAL Subtract numeric offset from key value MOVB @KEYVAL,R9 Move key value into R9. SRL R9,8 Shift R9 8 bits to the right. (Make a full word.) MOV R9,@DIF Move R9 into DIF variable. BL @CLRSCR Clear the screen. LI R0,375 Draw the basic screen text and components. LI R1,DISP1 * LI R2,4 * BLWP @VMBW * AI R0,64 * LI R1,DISP2 * LI R2,3 * BLWP @VMBW * AI R0,64 * LI R1,DISP3 * LI R2,4 * BLWP @VMBW * AI R0,64 * LI R1,DISP4 * BLWP @VMBW * CLR R0 Clear R0 CLR @ENEMY Clear @ENEMY variable CLR @TIME Clear @TIME variable LI R1,GALAXY Load GALAXY address into R1 GLXLP CLR R2 Clear R2 LI R3,10 Load 10 into R3 BL @RANDNO Generate random number (0-10) AI R5,-6 Subtract 6 from random number. (-6 to 4 range) A R9,R5 Add difficulty to R5. CI R5,0 Check if R5 is greater than 0 JGT ENMPOP If so, jump to populate enemy drones CLR R5 Otherwise, clear R5 back to 0. ENMPOP MOV R5,R2 Move R5 into R2 A R5,@ENEMY Add R5 to @ENEMY ORI R2,>0080 Set the scanned/visited bit to 1. LI R3,8 Load 8 into R3. BL @RANDNO Generate random number (0-8) INC R5 Increment R5 by 1. (range of 1-9) SLA R5,8 Shift R5 to the left 8 bits. AB R5,R2 Add R5 to R2. LI R3,21 Load R3 with 21. BL @RANDNO Generate random number (0-21) CI R5,2 Check if R5 is greater than 2. JGT MKQUAD If so, skip base population phase ORI R2,>8000 Sent the base bit in R2. MKQUAD MOV R2,*R1+ Move R2, the quadrant data, into R1 indirect and increment R1. INC R0 Increment R0 CI R0,40 If R0 is equal to 40, Galaxy creation is done. Otherwise loop. JLT GLXLP * LI R0,11 Load 11 into R0 S R9,R0 Subtract R9 (Difficulty) from R0 MPY @ENEMY,R0 Multiply the number of enemies by R0. MOV R1,@TIME Move the result value into @TIME variable. LI R0,8000 Load 8000 into @ENERGY variable. MOV R0,@ENERGY * LI R0,20 Load 20 into @TORPS variable. MOV R0,@TORPS * LI R0,>8000 Move ship pattern (>80) into @TTYPE position 0. MOVB R0,@TTYPE * LI R3,7 Generate random quadrant row (1-8) BL @RANDNO * INC R5 * MOV R5,@QROW * LI R3,4 Generate random quadrant column (1-5) BL @RANDNO * INC R5 * MOV R5,@QCOL * B @SUBRET Return to calling routine. SCAN MOV R11,*R15+ Move return address to stack, increment stack pointer. CLR R4 Clear R4. (cursor blink rate) MOV @CURPOS,R0 Move cursor position into R0 LI R1,>1E00 Load cursor byte character into R1. MOV @>8378,R10 Move random number seed into R10 ANDI R10,>0001 Get an even or odd bit from R10. SEED MOV @>83D6,R5 Move screen timeout counter into R5. CI R4,60 Check if R4 has reached 60. JLT DOSCAN If not, jump to DOSCAN. CLR R4 Otherwise, clear R4 CB R1,@ANYKEY Is R1 a space character? JEQ CURVIS If so, jump to CURVIS LI R1,>2000 Otherwise, make R1 a space character instead. JMP DOSCAN And goto DOSCAN. CURVIS LI R1,>1E00 Load a cursor character into R1. DOSCAN CLR @STATUS Clear the status byte BLWP @KSCAN Scan the keyboard. BLWP @VSBW Print the cursor/space character. LIMI 2 Open and close interrupts. LIMI 0 * INC R4 Increment R4. CB @ANYKEY,@STATUS Has a key been pressed? JNE SEED If not, jump up to SEED. MOVB @KEYVAL,R1 Move the key value into R1 BLWP @VSBW Write the key value to the cursor position MOV R5,@>83C0 Move R5 (screen timeout value) into random number seed. MOVB @>8379,@>83C0 Move VDP interrupt timer value (high byte) into random number seed. XOR @>83C0,R10 Exclusive OR the random number seed with R10. (1 or 0) MOV R10,@>83C0 Move R10 into the random number seed. LI R4,10 Load R4 with a value of 10 BL @DELAY Branch and link to Delay subroutine. B @SUBRET Return to calling routine. GETNUM MOV R11,*R15+ Move return address to stack, increment stack pointer. CLR @NUM Clear the @NUM variable. MOV @CURPOS,R14 Copy the cursor position to R14 CLR R13 Clear R13 (string length counter) KNLOOP BL @SCAN Scan the keyboard. CB @KEYVAL,@KMINUS Check if the minus key was struck. JEQ NEGCHK If so, jump to NEGCHK. CB @KEYVAL,@KBACK Check if the BACK key was struck. JEQ REDO If so, jump to REDO. CB @KEYVAL,@KENTER Check if the Enter key was struck. JEQ DONE If so, jump to DONE. LI R1,>3000 Load R1 with "0" value. CB @KEYVAL,R1 Is the key value less than R1? JLT KNLOOP If so, loop back to rescan. LI R1,>3900 Load R1 with "9" value. CB @KEYVAL,R1 Is the key value greater than R1? JGT KNLOOP If so, loop back to rescan. JMP INPUT Jump to input. (valid number entered.) REDO MOV R14,@CURPOS Restore the cursor's original position. MOV R14,R0 Load 4 spaces and write them from cursor position onward LI R1,BAR0 * LI R2,4 * BLWP @VMBW * CLR R13 Clear R13 (string length counter) JMP KNLOOP Jump back to key scan. NEGCHK MOV R13,R13 Check if R13 is 0 (first position). JNE KNLOOP If not, can't have a minus here, go back to scan. INPUT CI R13,3 Check if R13 is greater than 3 (4 character max) JGT KNLOOP If it is, jump back to key scan. INC R13 Otherwise, increment R13. MOV @CURPOS,R0 Move cursor position into R0 MOVB @KEYVAL,R1 Move key value into R1 high-byte. BLWP @VSBW Write key value to screen. INC R0 Increment R0 MOV R0,@CURPOS Copy R0 into @CURPOS. JMP KNLOOP Jump back to key scan. DONE LI R1,>2000 Load R1 with space character, high-byte. BLWP @VSBW Write a space. (Keeps the cursor from getting in the * string.) MOV R14,R0 Move R14 into R0. (Starting position of string.) LI R1,STRING Read the 4 bytes from the screen into STRING. LI R2,4 * BLWP @VMBR * LI R14,STRING+3 Load R14 with STRING+3, the end of the string. CLR R13 Clear R13 (decimal place counter). RDSTRG MOVB *R14,R0 Move the byte at R14 into R0. CB R0,@ANYKEY Check if R0 is a space. JNE ADDNUM If not, go to addnum. RDMOVE DEC R14 Otherwise, decrement R14. CI R14,STRING If R14 is less than the STRING base address... JLT GNEND Jump to GNEND JMP RDSTRG Otherwise, jump back to RDSTRG. ADDNUM CI R13,0 Check if R13 is 0. JEQ MONE If so, it's the one position. Jump to MONE. CI R13,1 Check if R13 is 1. JEQ MTEN If so, it's the ten position. Jump to MTEN. CI R13,2 Check if R13 is 2. JEQ MHUND If so, it's the hundred position. Jump to MHUND. CI R13,3 Check if R13 is 3. JEQ M1K If so, it's the thousand position. Jump to M1K. B @GNEND Branch to GNEND. MONE SRL R0,8 Shift R0 8 bits to the right. AI R0,-48 Subtract 48 from R0. (Convert it to raw value.) A R0,@NUM Add R0 to @NUM. INC R13 Increment R13 B @RDMOVE Branch back to RDMOVE. MTEN CB R0,@KMINUS Check if R0 is the minus sign. JEQ NEGNUM If so, jump to NEGNUM. SRL R0,8 Shift R0 8 bits to the right. AI R0,-48 Subtract 48 from R0 (Convert it to raw value.) MPY @DIV10,R0 Multiply R0 by @DIV10. (Which is 10) A R1,@NUM Add R1 to @NUM. INC R13 Increment R13. B @RDMOVE Branch to RDMOVE. MHUND CB R0,@KMINUS Check if R0 is the minus sign. JEQ NEGNUM If so, jump to NEGNUM. SRL R0,8 Shift R0 8 bits to the right. AI R0,-48 Subtract 48 from R0 (Convert it to raw value.) MPY @DIV1H,R0 Multiply R0 by @DIV1H. (Which is 100) A R1,@NUM Add R1 to @NUM. INC R13 Increment R13. B @RDMOVE Branch to RDMOVE. NEGNUM NEG @NUM Negate @NUM. JMP GNEND Jump to GNEND. (The minus is always last.) M1K CB R0,@KMINUS Check if R0 is the minus sign. JEQ NEGNUM If so, jump to NEGNUM. SRL R0,8 Shift R0 8 bits to the right. AI R0,-48 Subtract 48 from R0 (Convert it to raw value.) MPY @DIV1K,R0 Multiply R0 by @DIV1K. (Which is 1000) A R1,@NUM Add R1 to @NUM. GNEND B @SUBRET Return to calling routine. WARP MOV R11,*R15+ Move return address to stack, increment stack pointer. WDLP BL @WIPE Clear text area below. LI R0,674 Print "quadrant row?" on screen. LI R1,CMD3 * LI R2,16 * BLWP @VMBW * LI R0,691 Load 691 into @CURPOS MOV R0,@CURPOS * BL @GETNUM Branch and link to Get Number subroutine. MOV @NUM,R7 Move @NUM into R7. CI R7,0 If R7 is less than/equal to 0, jump back to WDLP. JLE WDLP * CI R7,8 If R7 is greater than 8, jump back to WDLP. JGT WDLP * WDLP2 LI R0,706 Print "quadrant column?" on screen. LI R1,CMD4 * LI R2,16 * BLWP @VMBW * LI R0,723 Load 723 into @CURPOS MOV R0,@CURPOS * BL @GETNUM Branch and link to Get Number subroutine. MOV @NUM,R8 Move @NUM into R8 CI R8,0 If R8 is less than/equal to 0, jump back to WDLP2 JLE WDLP2 * CI R8,5 IF R8 is greater than 5, jump back to WDLP2 JGT WDLP2 * CKSAME C @QROW,R7 Compare @QROW to R7. JNE GOWARP If they're not equal, jump to GOWARP. C @QCOL,R8 Compare @QCOL to R8. JNE GOWARP If they're not equal, jump to GOWARP. BL @WIPE Otherwise, clear text area. LI R0,674 Print "You're already there" on screen. LI R1,CMD9 * LI R2,12 * BLWP @VMBW * LI R4,30 Delay for 30 units. BL @DELAY * B @SUBRET Return to calling routine. GOWARP BL @WIPE Clear text area. MOV @QROW,R9 Copy @QROW into R9. MOV @QCOL,R10 Copy @QCOL into R10. MOV R7,@QROW Move R7 into @QROW. MOV R8,@QCOL Move R8 into @QCOL. S R9,R7 Subtract R9 from R7 S R10,R8 Subtract R10 from R8. ABS R7 Make R7 an absolute value. ABS R8 Make R8 an absolute value. MOV R8,R9 Copy R8 into R9. MPY R7,R7 Multiply R7 by R7. (R7^2) MOV R8,R7 Copy R8 into R7. MPY R9,R9 Multiply R9 by R9. (R9^2) A R10,R7 Add R10 to R7. MOV R7,@FAC Move R7 to @FAC location. BLWP @XMLLNK Convert word at FAC into FP number. DATA CIF * CLR @STATUS Clear the status byte. BLWP @GPLLNK Calculate the square root of the number at FAC. DATA SQR * CLR @STATUS Clear the status byte. BLWP @GPLLNK Convert the FP number at FAC into a whole integer FP. DATA INT * BLWP @XMLLNK Convert the FP number at FAC into a real integer. DATA CFI * MOV @FAC,@NUM Move the integer at FAC into @NUM. LI R6,2 Load the value 2 into R6. (Starting column.) LI R4,>10E0 Load the value >10E0 into R4. (Starting sound location.) PLAID CLR R5 Clear R5. (vertical counter.) MOV R6,R0 Move R6 into R0. (screen position.) LI R1,>9200 Load R1 with orange block. PLDRAW BLWP @VSBW Write to screen. AI R0,32 Add 32 to position. (One whole row.) INC R5 Increment R5 CI R5,20 If R5 is less than 20, jump back and repeat. JLT PLDRAW * MOV R4,R0 Else, move R4 into R0. BL @SNDCON Branch and link to Sound Control. (warp sound) AI R4,8 Add 8 bytes to sound register. (up one sound) INC R6 Increment R6. (starting column at top.) CI R6,22 If column is less than 22, jump back to PLAID. JLT PLAID * LI R0,294 Print "XXX WARP XXX" on screen. LI R1,CMD10 * LI R2,12 * BLWP @VMBW * LI R0,>11C0 Load R0 with first warp entry sound. BL @SNDCON Play sound. LI R4,5 Delay 5 units. BL @DELAY * LI R0,>11D0 Load R0 with second warp entry sound. BL @SNDCON Play sound. LI R4,30 Delay 30 units. BL @DELAY * LI R3,10 Generate a random number from 0-10. BL @RANDNO * MOV R5,R5 Is the number 0? If not, jump to WPEND. JNE WPEND * LI R3,7 Otherwise, generate a random set of new BL @RANDNO coordinates and move these to @QROW and @QCOL. INC R5 * MOV R5,@QROW * LI R3,4 * BL @RANDNO * INC R5 * MOV R5,@QCOL * LI R0,357 Print on screen "Position shift, going off course." LI R1,CMD11 * LI R2,14 * BLWP @VMBW * LI R0,420 * LI R1,CMD12 * LI R2,16 * BLWP @VMBW * LI R4,30 Delay 30 units. BL @DELAY * WPEND LI R0,>11E0 Load warp exit sound and play it. BL @SNDCON * LI R4,50 Delay 50 units. BL @DELAY * MOV @NUM,R5 Move integer distance to R5. LI R4,5 Load R4 with the value 5. MPY R4,R5 Multiply distance by 5. S R6,@TIME Subtract result from @TIME variable. LI R3,200 Get a random number from 0-200. BL @RANDNO * MOV R5,R4 Move this value to R4, and add 200 to it. AI R4,200 * MOV @NUM,R5 Move integer distance to R5. MPY R4,R5 Multiply distance by random energy cost. S R6,@ENERGY Subtract this from @ENERGY. BL @DRAWSC Branch and link to Draw Screen subroutine. BL @GENQD Branch and link to Generate Quadrant subroutine. B @SUBRET Return to calling routine. DOCK MOV R11,*R15+ Move return address to stack, increment stack pointer. LI R2,-32 Load R2 with value -32. LI R3,-1 Load R3 with value -1. DKLOOP MOV @TPOS,R0 Move @TPOS (ship position) into R0. CLR R1 Clear R1. A R2,R0 Add R2 to R0. A R3,R0 Add R3 to R0. CI R0,0 Check if R0 is less than 0. (Off-screen) JLT DKADJ If so, jump to DKADJ. BLWP @VSBR Otherwise, read the value off screen at that position. CB R1,@HBASE Check if it's a base character JEQ DKYES IF so, jump to DKYES DKADJ INC R3 Increment R3 CI R3,2 If R3 is less than 2, jump to DKLOOP JLT DKLOOP * LI R3,-1 Otherwise, reset R3 back to -1. AI R2,32 Add 32 to R2 CI R2,32 Check if R2 is less than/equal to 32. JLE DKLOOP If so, jump to DKLOOP DKNO LI R0,706 Otherwise, write "No base nearby" on screen. LI R1,CMD13 * LI R2,12 * BLWP @VMBW * LI R4,30 Delay for 30 units. BL @DELAY * B @SUBRET Return to calling routine. DKYES LI R0,8000 Reset @ENERGY to 8000. MOV R0,@ENERGY * LI R0,20 Reset @TORPS to 20. MOV R0,@TORPS * BL @UPDNUM Branch and link to Update Numbers subroutine. B @SUBRET Return to calling routine. FIRE MOV R11,*R15+ Move return address to stack, increment stack pointer. LI R1,>8000 Load R1 with >8000. (Ship with shields down.) CB @TTYPE,R1 Check if @TTYPE (current status) is equal to R1. JEQ GETPOW If so, jump to GETPOW. MOVB R1,@TTYPE Otherwise, set @TTYPE to R1. (Shields down.) MOV @TPOS,R0 Move @TPOS to R0. BLWP @VSBW Write the adjusted ship to screen. GETPOW BL @WIPE Wipe text area. LI R0,674 Print "how much power?" on screen. LI R1,CMD14 * LI R2,15 * BLWP @VMBW * LI R0,690 Load @CURPOS with value 690. MOV R0,@CURPOS * BL @GETNUM Branch and link to Get Number subroutine. C @ENERGY,@NUM Compare @ENERGY value to result number in @NUM. JLE GETPOW If less than or equal to, loop back for a new entry at GETPOW. S @NUM,@ENERGY Otherwise, subtract @NUM from @ENERGY. LI R2,3 Subtract 3 units from @TIME. S R2,@TIME * FIRELP MOV @QROW,R0 Move @QROW to R0. MOV @QCOL,R1 Move @QCOL to R1. BL @GETQD Branch and link to Get Quadrant subroutine. CI R12,0 Check if R12 (# of drones) is 0. JEQ FRDONE If so, jump to FRDONE. LI R2,50 Otherwise, load R2 with value 50. MPY @DIF,R2 Multiply R2 by @DIF (difficulty). MOV R3,R1 Move the value in R3 (result) to R1. AI R1,50 Add 50 to R1. LI R2,20 Load a value of 20 into R2. MPY @DIF,R2 Multiply R2 by @DIF (difficulty). BL @RANDNO Get a random number from 0-20. A R5,R1 Add the random number to R1. C R1,@NUM Compare R1 (energy cost to destroy) to @NUM. JGT FRDONE If it's greater, jump to FRDONE. S R1,@NUM Otherwise, subtract R1 from @NUM. LI R0,>9000 Load R0 with >9000. (Drone character) BL @FDTYPE Branch and link to Find Type subroutine. MOVB @HEMPTY,@TTYPE(R4) Move @HEMPTY (>82) to @TTYPE(location of first drone) SLA R4,1 Shift R4 to the left by 1. (Multiply by 2) MOV @TPOS(R4),R0 Move @TPOS(location of first drone) to R0. BL @EXPLD Branch and link to Explosion subroutine. DEC R12 Decrement R12. (# of drones) MOV @QROW,R0 Move @QROW to R0. MOV @QCOL,R1 move @QCOL to R1. BL @UPDQD Branch and link to Update Quadrant subroutine. MOV @ENEMY,R2 Decrement @ENEMY by 1. DEC R2 * MOV R2,@ENEMY * B @FIRELP Branch back to FIRELP. FRDONE MOV @NUM,R3 Move @NUM to R3. BL @INTSTG Branch and link to Integer to String subroutine. (R3 contains * value, STRING holds resultant number.) LI R0,706 Print the remaining power wasted on screen. LI R1,STRING * LI R2,4 * BLWP @VMBW * LI R0,711 Print " wasted" on screen after number. LI R1,CMD15 * LI R2,6 * BLWP @VMBW * BL @UPDNUM Branch and link to Update Numbers routine. LI R4,60 Delay 60 units. BL @DELAY * B @SUBRET Return to calling routine. LRSCAN MOV R11,*R15+ Move return address to stack, increment stack pointer. LI R0,2 Draw vertical bars onto screen LRDRW LI R1,BAR3 * LI R2,20 * BLWP @VMBW * AI R0,32 Add 32 to drawing position CI R0,482 Compare R0 with 482 JLT LRDRW If less, jump back to LRDRW LI R0,130 Load position 130 LI R1,BAR2 Load horizontal bar BLWP @VMBW Write to screen. AI R0,160 Add 160 (5 rows) to R0. BLWP @VMBW Write to screen. AI R0,160 Add 160 (5 rows) to R0. BLWP @VMBW Write to screen. LI R0,482 Load 482 into R0. LI R1,BAR0 Load all spaces bar LI R2,20 * BLWP @VMBW *Write to screen and advance one row five times AI R0,32 * BLWP @VMBW * AI R0,32 * BLWP @VMBW * AI R0,32 * BLWP @VMBW * AI R0,32 * BLWP @VMBW * LI R0,485 Load "Long Range Scan" text and write to screen. LI R1,CMD18 * LI R2,15 * BLWP @VMBW * LI R3,-1 Load -1 into R3. (Vertical offset) LI R4,-1 Load _1 into R4. (Vertical offset) LRSLP CLR @STRING Clear STRING (two bytes) CLR @STRING+2 Clear STRING+2 (two bytes) MOV @QROW,R5 Copy @QROW into R5. MOV @QCOL,R6 Copy @QCOL into R6. A R3,R5 Add R3 to R5. A R4,R6 Add R4 to R6. CI R5,0 If R5 is 0, it's out of bounds, jump to LRK. JEQ LRK * CI R5,9 If R5 is 9, it's out of bounds, jump to LRK. JEQ LRK * CI R6,0 If R6 is 0, it's out of bounds, jump to LRK. JEQ LRK * CI R6,6 If R6 is 6, it's out of bounds, jump to LRK. JEQ LRK * JMP LRSST If all is in bounds, jump to LRSST LRK B @LRSSK Branch to LRSSK LRSST MOV R5,R0 Move R5 to R0. MOV R6,R1 Move R6 to R1. BL @GETQD Branch and link to Get Quadrant subroutine. MOV @GALAXY(R1),R7 Move GALAXY(quadrant position) to R7. ANDI R7,>FF7F Reset the scanned/visited bit. MOV R7,@GALAXY(R1) Copy R7 back to GALAXY(quadrant position). MOV R3,R0 Copy R3 (adjustment x) to R0. MPY @M160,R0 Multiply R0 by 160. (Five row adjustment) MOV R1,R0 Copy R1 to R0. MOV R4,R1 Move R4 (adjustment y) to R1. MPY @M6,R1 Multiply R1 by 6. (Six column adjustment) A R2,R0 Add R2 to R0. (This is the starting position of data string.) AI R0,171 Add 171 to R0. (Adjust for screen boundary offsets) LI R1,>9020 Load R1 with >9020. (Drone graphic followed by space.) MOV R1,@STRING Copy R1 into @STRING. AI R12,48 Add 48 to R12. (Number of drones) SLA R12,8 Shift R12 to the left 8 bits. (Put in high byte) MOVB R12,@STRING+2 Copy R12 high-byte into @STRING+2. (# of drones in ASCII) LI R1,STRING Load R1 with String address LI R2,3 Load R2 with length of string. (3 bytes) BLWP @VMBW Write to screen. AI R0,32 Add 32 to position. (One row down) LI R1,>9820 Load R1 with >9820. (Base graphic followed by space.) MOV R1,@STRING Copy R1 into @STRING. AI R13,48 Add 48 to R13. (Number of bases) SLA R13,8 Shift R13 to the left 8 bits. (Put in high byte) MOVB R13,@STRING+2 Copy R13 high-byte into @STRING+2. (# of bases in ASCII) LI R1,STRING Load R1 with String address BLWP @VMBW Write to screen. AI R0,32 Add 32 to position. (One row down) LI R1,>A020 Load R1 with >A020. (Mine graphic followed by space.) MOV R1,@STRING Copy R1 into @STRING. AI R14,48 Add 48 to R14. (Number of mines) SLA R14,8 Shift R14 to the left 8 bits. (Put in high byte) MOVB R14,@STRING+2 Copy R14 high-byte into @STRING+2. (# of mines in ASCII) LI R1,STRING Load R1 with String address BLWP @VMBW Write to screen. LRSSK INC R3 Increment R3. CI R3,2 Check if R3 is equal to 2. JEQ LRS1 If so, jump to LRS1. B @LRSLP Otherwise, branch back to LRSLP. LRS1 LI R3,-1 Load R3 with -1 again. INC R4 Increment R4. CI R4,2 Check if R4 is equal to 2. JEQ LRSEND If so, jump to LRSEND. B @LRSLP Otherwise, branch back to LRSLP. LRSEND LI R0,578 Write "press enter" on screen. LI R1,CMD19 * LI R2,11 * BLWP @VMBW * CLR @STATUS Clear GPL status byte LRKSCA BLWP @KSCAN Scan the keyboard. CB @ANYKEY,@STATUS Compare to see if any key has been pressed. JNE LRKSCA If not, jump back to LRKSCA BL @SRSCAN Branch and link to Short-Range Scan subroutine. BL @REPLOT Branch and link to Replot subroutine. B @SUBRET Return to calling routine. CHART MOV R11,*R15+ Move return address to stack, increment stack pointer. CLR R3 Clear R3. (counter) LI R0,2 Draw horizontal bar on screen at top and every other bar. CHDRAW LI R1,BAR2 * LI R2,20 * BLWP @VMBW * AI R0,32 Increase R0 by 32. LI R1,BAR4 Load R1 with BAR4 address. (spaced vertical bars.) BLWP @VMBW Write to screen. AI R0,32 Add 32 to position. INC R3 Increment R3 CI R3,8 Check if R3 is still less than 8 JLT CHDRAW If so, jump back and do another set of bars at CHDRAW. LI R1,BAR2 Load R1 with a horizontal bar BLWP @VMBW Write to screen at bottom of chart. AI R0,32 Write a space bar three times. LI R1,BAR0 * BLWP @VMBW * AI R0,32 * BLWP @VMBW * AI R0,32 * BLWP @VMBW * LI R3,1 Load R3 with 1. (Starting row) LI R4,1 Load R4 with 1. (Starting column) CHLOOP CLR @STRING Clear @STRING (two bytes) CLR @STRING+2 Clear @STRING+2 (two bytes) MOV R3,R0 Copy R3 into R0. MOV R4,R1 Copy R4 into R1. BL @GETQD Branch and link to Get Quadrant subroutine. CI R10,1 Check if R10 is 1. (Unvisited) JNE CHFULL If not, jump to CHFULL. CI R13,1 Check to see if R13 (Bases) is 1. JNE CHDONE If not, jump to CHDONE (totally empty) LI R0,>3F31 Otherwise, load R0 with >3f31 (?1) MOV R0,@STRING Copy R0 to @STRING. MOVB R0,@STRING+2 Copy R0 high-byte to @STRING+2. JMP CHPLOT Jump to CHPLOT. CHFULL AI R12,48 Add 48 to R12. (numeric offset) AI R13,48 Add 48 to R13. (numeric offset) AI R14,48 Add 48 to R14. (numeric offset) SLA R12,8 Shift R12 8 bits to the left. (put in high byte) SLA R13,8 Shift R13 8 bits to the left. (put in high byte) SLA R14,8 Shift R14 8 bits to the left. (put in high byte) MOVB R12,@STRING Copy R12 high-byte to @STRING. MOVB R13,@STRING+1 Copy R13 high-byte to @STRING+1. MOVB R14,@STRING+2 Copy R14 high-byte to @STRING+2. CHPLOT MOV R3,R0 Copy R3 to R0. DEC R0 Decrement R0 SLA R0,6 Shift R0 6 bits to the left. (Multiply by 64) MOV R4,R1 Move R4 into R1. DEC R1 Decrement R1. SLA R1,2 Shift R1 2 bits to the left. (Multiply by 4) AI R1,34 Add 34 to R1. A R1,R0 Add R1 to R0. (R0 is position on screen now.) LI R1,STRING Load R1 with STRING address. LI R2,3 Load length of string in R2. (3 bytes) BLWP @VMBW Write to screen. CHDONE INC R4 Increment R4. CI R4,5 Check if R4 is less than or equal to 5. JLE CHLOOP If so, jump back to CHLOOP. LI R4,1 Otherwise, set R4 back to 1. INC R3 Increment R3. CI R3,8 Check if R3 is less than or equal to 8. JLE CHLOOP IF so, jump back to CHLOOP LI R0,578 Otherwise, print "press enter" on screen. LI R1,CMD19 * LI R2,11 * BLWP @VMBW * CLR @STATUS Clear status byte. CHSCAN BLWP @KSCAN Scan keyboard. CB @ANYKEY,@STATUS Check if a key has been pressed. JNE CHSCAN If not, jump back to CHSCAN BL @SRSCAN Branch and link to Short-Range Scan subroutine. BL @REPLOT Branch and link to Replot subroutine. B @SUBRET Return to calling routine. DRAWSC MOV R11,*R15+ Move return address to stack, increment stack pointer. BL @SRSCAN Branch and link to Short-Range Scan subroutine. LI R0,87 Display "Quad(" on screen. LI R1,DISP5 * LI R2,5 * BLWP @VMBW * LI R0,92 Load following position. MOV @QROW,R1 Copy @QROW into R1. AI R1,48 Add numeric offset to R1. SLA R1,8 Shift R1 8 bits to the left. (high-byte) BLWP @VSBW Write to screen. INC R0 Increment R0. LI R1,>2C00 Load "," character into R1. BLWP @VSBW Write to screen. INC R0 Increment R0. MOV @QCOL,R1 Copy @QCOL into R1. AI R1,48 Add numeric offset to R1. SLA R1,8 Shift R1 8 bits to the left. (high-byte) BLWP @VSBW Write to screen. INC R0 Increment R0 LI R1,>2900 Load ")" into R1. BLWP @VSBW Write to screen. BL @UPDNUM Branch and link to Update Numbers subroutine. B @SUBRET Return to calling routine. UPDNUM MOV R11,*R15+ Move return address to stack, increment stack pointer. MOV @TORPS,R3 Copy @TORPS value into R3. BL @INTSTG Branch and link to Integer to String subroutine. LI R0,380 Write value to screen LI R1,STRING * LI R2,4 * BLWP @VMBW * MOV @ENERGY,R3 Copy @ENERGY value into R3. BL @INTSTG Branch and link to Integer to String subroutine. LI R0,444 Write value to screen LI R1,STRING * LI R2,4 * BLWP @VMBW * MOV @ENEMY,R3 Copy @ENEMY value into R3. BL @INTSTG Branch and link to Integer to String subroutine. LI R0,508 Write value to screen LI R1,STRING * LI R2,4 * BLWP @VMBW * MOV @TIME,R3 Copy @TIME value into R3. BL @INTSTG Branch and link to Integer to String subroutine. LI R0,572 Write value to screen LI R1,STRING * LI R2,4 * BLWP @VMBW * B @SUBRET Return to calling routine. GETANG MOV R11,*R15+ Move return address to stack, increment stack pointer. LI R0,706 Write "Angle in degrees?" on screen. LI R1,CMD2 * LI R2,17 * BLWP @VMBW * LI R0,724 Load 724 into cursor position. MOV R0,@CURPOS * BL @GETNUM Branch and link to Get Number subroutine. MOV @NUM,@DEG Copy @NUM into @DEG. B @SUBRET Return to calling routine. MOVE MOV R11,*R15+ Move return address to stack, increment stack pointer. MALOOP BL @WIPE Wipe text area BL @GETANG Branch and link to Get Angle subroutine. LI R0,738 Write "Move how far?" onto screen. LI R1,CMD5 * LI R2,13 * BLWP @VMBW * LI R0,752 Load value 752 into @CURPOS. MOV R0,@CURPOS * BL @GETNUM Branch and link to Get Number subroutine. MOV @NUM,R0 Copy @NUM into R0. CI R0,0 Check if R0 is less than 0. JLT MALOOP If so, jump back to MALOOP. BL @WIPE Wipe text area. MOV @NUM,R5 Copy @NUM to R5. (R5 is # of spaces to move) MOV @TPOS,@OLDPOS Copy @TPOS(ship position) to @OLDPOS. CLR R0 Clear R0. MOV @TPOS,R1 Copy @TPOS to R1. DIV @ROW,R0 Divide R1 by @ROW (32). MOV R0,@INTY Move R0 to @INTy (adjusted row position 0-23) MOV R1,@INTX Move R1 to @INTX (adjusted col position 0-31) BL @CREAXY Branch and link to Create X/Y subroutine. MVLOOP BL @COURSE Branch and link to Course subroutine. MOV @INTY,R0 Copy @INTY to R0. CI R0,0 Check if R0 is less than 0. JLT MVBND If so, jump to MVBND. MOV @INTX,R1 Copy @INTX to R1. SLA R0,5 Shift R1 5 bits to the left. (Multiply by 32) A R1,R0 Add R1 to R0. (R0 is now screen position) CLR R1 Clear R1. BLWP @VSBR Read value from screen position into R1. MOV R1,@CHKPOS Move R1 into @CHKPOS. CB @CHKPOS,@ANYKEY Compare @CHKPOS with @ANYKEY (space character) JEQ MVBND If equal, jump to MVBND. CB @CHKPOS,@TTYPE Compare @CHKPOS with @TTYPE (current ship graphic) JEQ NOMOVE If equal, jump to NOMOVE. CB @CHKPOS,@HSPACE Compare @CHKPOS with @HSPACE (empty space) JNE MVSTOP If not equal, jump to MVSTOP. MOV R0,R4 Copy R0 to R4. MOV @OLDPOS,R0 Copy @OLDPOS (old position) to R0. MOVB @HSPACE,R1 Copy @HSPACE (empty space) to R1 (high-byte). BLWP @VSBW Write to screen. MOV R4,R0 Copy R4 back to R0. MOV R4,@OLDPOS Copy R4 to @OLDPOS. MOVB @TTYPE,R1 Copy @TTYPE (ship graphic) to R1 (high-byte). BLWP @VSBW Write to screen. NOMOVE LI R0,>1180 Load and play movement sound BL @SNDCON * LI R4,10 Delay 10 units BL @DELAY * DEC R5 Decrement R5. (# of spaces to move) MOV R5,R5 Check if R5 is 0. JEQ MVEND If so, jump to MVEND. B @MVLOOP Branch to MVLOOP. MVSTOP LI R0,738 Print "Emergency stop!" on screen. LI R1,CMD6 * LI R2,15 * BLWP @VMBW * LI R0,>1190 Play emergency stop sound BL @SNDCON * LI R4,20 Delay 20 units. BL @DELAY * JMP MVEND Jump to MVEND MVBND LI R0,738 Print "Out of boundary" on screen. LI R1,CMD8 * LI R2,23 * BLWP @VMBW * LI R4,60 Delay 60 units BL @DELAY * MVEND MOV @OLDPOS,@TPOS Copy @OLDPOS to @TPOS. (New position) S R5,@NUM Subtract R5 from @NUM. (Adjusted movement amount) MOV @NUM,R5 Copy @NUM to R5. MPY @DIV10,R5 Multiply R5 by 10. S R6,@ENERGY Subtract R6 (result) from @ENERGY. MOV @NUM,R5 Copy @NUM to R5. SLA R5,1 Shift R5 to the left 1 bit. (Multiply by 2.) S R5,@TIME Subtract R5 from @TIME. BL @UPDNUM Branch and link to Update Numbers subroutine. B @SUBRET Return to calling routine. FTORP MOV R11,*R15+ Move return address to stack, increment stack pointer. MOV @TORPS,@TORPS Check if @TORPS is zero. JNE TOANG If not, jump to TOANG LI R0,706 Print "out of torpedoes" on screen. LI R1,CMD7 * LI R2,17 * BLWP @VMBW * LI R4,60 Delay 60 units. BL @DELAY * B @SUBRET Return to calling routine. TOANG BL @GETANG Branch and link to Get Angle subroutine. CLR R9 Clear R9. MOV @INC,@INC Check if @INC is 0. JNE VOLLEY if not zero, jump to VOLLEY. LI R9,1 Load R9 with a value of 1. (1 torpedo) JMP LAUNCH Jump to LAUNCH. VOLLEY LI R0,738 Write "Increment angle?" on screen. LI R1,CMD16 * LI R2,16 * BLWP @VMBW * LI R0,755 Load value 755 into @CURPOS. MOV R0,@CURPOS * BL @GETNUM Branch and link to Get number subroutine. MOV @NUM,@INC Copy @NUM into @INC LI R9,3 Load R9 with value of 3. (3 torpedoes) LAUNCH BL @WIPE Clear text area. LI R5,>1000 Load R5 with value of >1000. (Sound table start) CLR R0 Clear R0. (Position calculation) MOV @TPOS,R1 Copy @TPOS (ship location) into R1 DIV @ROW,R0 Divide R0 by @ROW (32). MOV R0,@INTY Copy R0 into @INTY (row 0-23) MOV R1,@INTX Copy R1 into @INTX (Column 0-31) BL @CREAXY Branch and link to Create X/Y subroutine. TOPLOT BL @COURSE Branch and link to Course subroutine. MOV @INTY,R0 Copy @INTY to R0. CI R0,0 Check if R0 is less than 0. (Off-screen) JLT TODONE If so, jump to TODONE. MOV @INTX,R1 Copy @INTX to R1. SLA R0,5 Shift R0 5 bits to the left. (Multiply by 32) A R1,R0 Add R1 to R0. CLR R1 Clear R1. BLWP @VSBR Read position from screen. CLR @CHKPOS Clear @CHKPOS. MOVB R1,@CHKPOS Move R1 (screen char) to @CHKPOS CB @CHKPOS,@HSPACE Check if @CHKPOS is empty space JNE HIT If not, you hit something. Jump to HIT. LI R1,>8900 Otherwise, load R1 with >8900. (Torpedo graphic) BLWP @VSBW Write to screen. MOV R0,R6 Copy R0 to R6. MOV R5,R0 Copy R5 (Sound table) to R0. BL @SNDCON Play torpedo sound. AI R5,8 Add 8 to R5. (Move up to higher tone sound) MOV R6,R0 Restore position to R0 from R6. MOVB @HSPACE,R1 Copy @HSPACE (empty space) to R1. (high-byte) BLWP @VSBW Write to screen. LI R4,20 Delay 20 units. BL @DELAY * JMP TOPLOT Jump back to TOPLOT HIT CB @CHKPOS,@ANYKEY Check if you hit a space (off screen) JEQ TODONE If so, jump to TODONE. BL @FDOBJ Otherwise, branch and link to Find Object subroutine. * (Given R0 as the location to seek) SRL R4,1 Shift R4 1 bit to the right. (divide by 2) MOVB @HEMPTY,@TTYPE(R4) Copy @HEMPTY (empty space) to @TTYPE(object position) BL @EXPLD Branch and link to Explosion routine. MOV @QROW,R0 Copy @QROW to R0. MOV @QCOL,R1 Copy @QCOL to R1. BL @GETQD Branch and link to Get Quadrant subroutine. CB @CHKPOS,@HDRONE Check if you hit a drone. JNE HITBSE If not, jump to HITBSE. DEC R12 Decrement R12. (# of drones) MOV @ENEMY,R2 Decrement @ENEMY by 1 using R2 as a switch register. DEC R2 * MOV R2,@ENEMY * JMP HITQD Jump to HITQD. HITBSE CB @CHKPOS,@HBASE Check if you hit a base. (Not good) JNE HITMNE If not, jump to HITMNE. DEC R13 Decrement R13 (# of bases) JMP RADIAT Jump to RADIAT HITMNE CB @CHKPOS,@HMINE Check if you hit a mine. (Not good) JNE HITQD If not, jump to HITQD. DEC R14 Decrement R14 (# of mines) RADIAT LI R3,3 Get a random number from 0-3 BL @RANDNO * INCT R5 Add two to the random number. (2-5) CLR R0 Clear R0. MOV @ENERGY,R1 Copy @ENERGY into R1. DIV R5,R0 Divide R1 by R5. (Get a ratio of 1/2-1/5 energy value) S R0,@ENERGY Subtract R0 from @ENERGy. HITQD MOV @QROW,R0 Copy @QROW into R0. MOV @QCOL,R1 Copy @QCOL into R1. BL @UPDQD Branch and link to Update Quadrant subroutine. TODONE DEC R9 Decrement R9. (# of torpedoes) MOV @TORPS,R2 Reduce @TORPS by 1 using R2 as a switch register. DEC R2 * MOV R2,@TORPS * CI R2,0 Check if you've run out of torpedoes. JEQ TEND If so, jump to TEND. MOV R9,R9 Otherwise, check if R9 is 0. JEQ TEND If so, jump to TEND. A @INC,@DEG Add @INC (angle increment) to @DEG (degree angle) B @LAUNCH Branch to LAUNCH to do it again. TEND BL @UPDNUM Branch and link to Update Numbers subroutine. B @SUBRET Return to calling routine. FDOBJ CLR R4 Clear R4. FDLOOP C @TPOS(R4),R0 Compare @TPOS(current position) to R0. (Search word.) JEQ FDDONE If equal, jump to FDDONE. INCT R4 Otherwise, increment R4 by two. JMP FDLOOP Jump to FDLOOP. FDDONE RT Branch to *R11. FDTYPE CLR R4 Clear R4. FD2LP CB @TTYPE(R4),R0 Compare @TTYPE(current position) to R0. (Search byte.) JEQ FD2DN If equal, jump to FD2DN. INC R4 Otherwise, increment R4. JMP FD2LP Jump to FD2LP. FD2DN RT Branch to *R11. EXPLD MOV R11,*R15+ Move return address to stack, increment stack pointer. MOV R0,R6 Move R0 (position of explosion) to R6. LI R0,>0706 Load R0 with >0706. (Register 7, color >06) BLWP @VWTR Write to VDP register. (Turns screen red) MOV R6,R0 Move R6 to R0. (Restore location) LI R1,>9100 Load R1 with >9100 (First explosion frame) BLWP @VSBW Write to screen. MOV R0,R6 Move R0 to R6. (Store location again) LI R0,>11A0 Load R0 with first explosion sound location. BL @SNDCON Play sound. LI R0,>0703 Load R0 with >0703. (Register 7, color >03) BLWP @VWTR Write to VDP register. (Turns screen green.) MOV R6,R0 Restore screen location to R0. LI R1,>A100 Load R1 with >A100. (Second explosion frame) BLWP @VSBW Write to screen. MOV R0,R6 Move R0 to R6. (Store location again) LI R0,>11B0 Load R0 with second explosion sound location. BL @SNDCON Play sound. MOV R6,R0 Restore screen location to R0. MOVB @HSPACE,R1 Move @HSPACE (>81) to R1. BLWP @VSBW Write to screen. B @SUBRET Return to calling routine. WIPE LI R0,672 Load 672 into R0. LI R1,>2000 Load space character into R1. WPLOOP BLWP @VSBW Write to screen. INC R0 Increment R0. CI R0,767 Check if R0 is greater than screen address max. JLE WPLOOP If not, jump back to WPLOOP. RT Branch to *R11. SHLDS MOV @TPOS,R0 Move @TPOS (ship position) to R0. LI R1,>8000 Load R1 with >8000. (Ship with shields down.) CB @TTYPE,R1 Compare @TTYPE (ship type) to R1. JEQ SHLDUP If equal, jump to SHLDUP. MOVB R1,@TTYPE Otherwise, copy R1 to @TTYPE. BLWP @VSBW Write to screen RT Branch to *R11. SHLDUP LI R1,>8800 Load R1 with >8800. (Ship with shields up.) MOVB R1,@TTYPE Move R1 high-byte to @TTYPE. BLWP @VSBW Write to screen. RT Branch to *R11. UPDQD DEC R1 Decrement R1. (Column position) SLA R1,4 Shift R1 to the left 4 bits. (Multiply by 16) DEC R0 Decrement R0. (Row position) SLA R0,1 Shift R0 to the left 1 bit. (Multiply by 2) A R0,R1 Add R0 to R1. SLA R13,15 Shift R13 to the left 15 bits. SLA R14,8 Shit R14 to the left 8 bits. A R13,R14 Add R13 to R14. A R14,R12 Add R14 to R12. MOV R12,@GALAXY(R1) Copy R12 to GALAXY(quadrant position). RT Branch to *R11. GETQD DEC R1 Decrement R1 (column position). SLA R1,4 Shift R1 to the left 4 bits. (Multiply by 16) DEC R0 Decrement R0 (row position). SLA R0,1 Shift R0 to the left 1 bit. (Multiply by 2) A R0,R1 Add R0 to R1. MOV @GALAXY(R1),R10 Move GALAXY(quadrant position) to R10. MOV @GALAXY(R1),R12 Move GALAXY(quadrant position) to R10. MOV @GALAXY(R1),R13 Move GALAXY(quadrant position) to R10. MOV @GALAXY(R1),R14 Move GALAXY(quadrant position) to R10. ANDI R10,>0080 Reset all bits but >0080 in R10. (scanned/visited bit) SRA R10,7 Shift R10 7 bits to the left. (Make 0-1) ANDI R12,>007F Reset all bits but >007f in R12. (Drone count) ANDI R13,>8000 Reset all bits but >8000 in R13 (Base count) SRL R13,15 Shift R13 to the right 15 bits. (Make 0-1) ANDI R14,>7F00 Reset all bits but >7f00 in R14. (Mine count) SRA R14,8 Shift R14 to the right 8 bits. (Make 1-9) RT Branch to *R11. SRSCAN CLR R2 Clear R2. (counter byte) LI R0,2 Load BAR1 for writing to screen. LI R1,BAR1 * LI R2,20 * DRAWLP BLWP @VMBW Write BAR1 (blank black line) to screen. AI R0,32 Add 32 to row position CI R0,642 Check if position is less than 642 JLT DRAWLP If so, jump back to DRAWLP. RT Branch to *R11 INTSTG CLR @STRING Clear @STRING. (two bytes) CLR @STRING+2 Clear @STRING+2. (two bytes) CI R3,0 Check if R3 (value submitted) is greater than zero. JGT INTST If so, jump to INTST. CLR R3 Otherwise, clear R3. (Values less than zero are made zero.) INTST CLR R2 Clear R2 (quotient) LI R1,STRING Load R1 with STRING address. DIV @DIV1K,R2 Divide R3 by 1000. AI R2,48 Add 48 to R2. (Numeric offset) SLA R2,8 Shift R2 to the left 8 bits. (put in high byte) MOVB R2,*R1+ Move the high-byte of R2 to STRING byte and increment R1 CLR R2 Clear R2 again. DIV @DIV1H,R2 Divide R3 by 100. AI R2,48 Add 48 to R2. (Numeric offset) SLA R2,8 Shift R2 to the left 8 bits. (put in high byte) MOVB R2,*R1+ Move the high-byte of R2 to STRING byte and increment R1 CLR R2 Clear R2 again. DIV @DIV10,R2 Divide R3 by 10. AI R2,48 Add 48 to R2. (Numeric offset) SLA R2,8 Shift R2 to the left 8 bits. (put in high byte) MOVB R2,*R1+ Move the high-byte of R2 to STRING byte and increment R1 AI R3,48 Add 48 to R2. (Numeric offset) SLA R3,8 Shift R2 to the left 8 bits. (put in high byte) MOVB R3,*R1 Move the high-byte of R2 to STRING byte and increment R1 RT Branch to *R11. MOVFP LI R0,4 Load R0 with value of 4. MOVLP MOV *R1+,*R2+ Move value at address in R1 to address in R2 and increment both. DEC R0 Decrement R0. JNE MOVLP If R0<>0, then jump back to MOVLP. RT Branch to *R11. INIT LI R0,>0703 Load R0 with value >0703. (Register 7, screen color >03) BLWP @VWTR Write to VDP register. (make screen green.) LI R0,>1000 Load R0 with value >1000. (Start of sound table in VDP.) LI R1,SNDDAT Load SNDDAT address into R1. LI R2,512 Load length of table. (512 bytes) BLWP @VMBW Write table to VDP. LI R0,>0380 Load value of color set table start. LI R1,>1000 Load R1 with >1000. (Black letters, transparent background.) COLLP1 BLWP @VSBW Write to color set table. INC R0 Increment R0 CI R0,>0390 Is R0 less than >0390? (Set 16) JLT COLLP1 If so, loop back to COLLP1. LI R0,>0390 Otherwise, load R0 with >0390. LI R1,COLDAT Load R1 with COLDAT address. (graphic colors) LI R2,8 Load length of table. (8 bytes.) BLWP @VMBW Write to VDP color table. LI R0,>08F0 Load address of pattern 30 into R0. LI R1,CURSOR Load CURSOR pattern address into R1. BLWP @VMBW Write to VDP pattern table. LI R0,>0C00 Load address of pattern 128 into R0. LI R1,SHIP Load SHIP pattern address into R1. BLWP @VMBW Write to VDP pattern table. AI R0,8 Add 8 to R0. LI R1,BLANK Load BLANK pattern address into R1. BLWP @VMBW Write to VDP pattern table. AI R0,8 Add 8 to R0. LI R1,BLANK Load BLANK pattern address into R1. BLWP @VMBW Write to VDP pattern table. AI R0,48 Add 48 to R0. LI R1,SHLD Load SHLD pattern address into R1. BLWP @VMBW Write to VDP pattern table. AI R0,8 Add 8 to R0. LI R1,TORP Load TORP pattern address into R1. BLWP @VMBW Write to VDP pattern table. AI R0,56 Add 56 to R0. LI R1,DRONE Load DRONE pattern address into R1. BLWP @VMBW Write to VDP pattern table. AI R0,8 Add 8 to R0. LI R1,EXP1 Load EXP1 pattern address into R1. BLWP @VMBW Write to VDP pattern table. AI R0,8 Add 8 to R0. LI R1,BLOCK Load BLOCK pattern address into R1. BLWP @VMBW Write to VDP pattern table. AI R0,48 Add 48 to R0. LI R1,BASE Load BASE pattern address into R1. BLWP @VMBW Write to VDP pattern table. AI R0,64 Add 64 to R0. LI R1,MINE Load MINE pattern address into R1. BLWP @VMBW Write to VDP pattern table. AI R0,8 Add 8 to R0. LI R1,EXP2 Load EXP2 pattern address into R1. BLWP @VMBW Write to VDP pattern table. RT Branch to *R11. SUBRET DECT R15 Decrement R15 by 2. MOV *R15,R11 Move the value at R15 back into R11. RT Branch to *R11. CLRSCR LI R0,0 Clear R0. LI R1,BAR0 Load BAR0 address into R1. (32 spaces) LI R2,32 Load length of R1 into R2. (32) CLRLP BLWP @VMBW Write to screen. AI R0,32 Add 32 to R0. CI R0,767 Check if R0 has exceeded 767. JLT CLRLP If not, jump back to CLRLP. RT Branch to *R11. DELAY CLR @>8378 Clear @>8378. (VDP interrupt timer) DLYLP LIMI 2 Open and close interrupts. LIMI 0 * C R4,@>8378 Check if @>8378 equals R4. (The counter value) JGT DLYLP If not, jump to DLYLP. RT Branch to *R11. RANDNO LI R4,28645 Load a large value (28,645) into R4. MPY @>83C0,R4 Multiply R4 by the random seed at @>83C0. AI R5,31417 Add large value (31,417) to R5. (low word result of * multiplication.) MOV R5,@>83C0 Copy R5 back @>83C0. CLR R4 Clear R4 INC R3 Increment R3 (random value max) DIV R3,R4 Divide R4 by R3. (Creates a 0-random value max in R5) RT Branch to *R11. END