TITLE STRTRK ; GALACTIC INFORMATION SURVEY DATA GENERATOR ; D. STRICK ; JANUARY, 1975 TWOSEG LOC <.JBVER=137> 300,,36 ;VERSION=3,,ABC=36 (OCTOBER 1975) VERCOM==4 ;VERSION/SAVED GAME COMPATIBILITY CODE SUBTTL **** SYMBOLS AND WORK AREAS **** EXTERN TTYINT,OUTCHR,READ,OUTSTR,ENDMSG,OUTINT,OUTF.3,FILINF EXTERN OUTF.2,OUTF.1,OUTF.0,READPR,NEWLIN,BRKOUT,WAITTY,PAGE EXTERN SQRT,RANDOM,RANDIT,RANFLO,DSIN,DCOS,ARCTAN,FLOFDG EXTERN .JBREN,.JBINT,.JBSA,ACCESS ;ACCUMULATOR ASSIGNMENTS: F==0 ;FLAGS LFQFLG==1B1 ;TIMING CHARACTER HAS BEEN OUTPUT. DSHFLG==1B18 ;DESIRED SPEED IF HYPER. HYPFLG==1B19 ;CURRENTLY IN HYPERSPACE. QSUFLG==1B20 ;QUADRANT IS SET UP. XCLDST==1B21 ;EXCALIBUR HAS BEEN DESTROYED. XCLDBE==1B22 ;EXCALIBUR DESTROYED BY ENTERPRISE PHASERS. XCEFLG==1B23 ;EXCALIBUR COLLIDED WITH ENTERPRISE. SPCFLG==1B24 ;A SPEED CHANGE HAS BEEN REQUESTED. BRCFLG==1B25 ;A BEARING CHANGE HAS BEEN REQUESTED. DOCFLG==1B26 ;ENTERPRISE HAS DOCKED SINCE LAST QUAD SETUP. LHPFLG==1B27 ;ENTERPRISE JUST LEFT HYPERSPACE. HASFLG==1B28 ;HYPERSPACE ATTACK TACTIC ATTEMPTED. T==1 ;TEMPORARY ACCUMULATORS: T2==2 T3==3 T4==4 A5==5 ;GENERAL PURPOSE ACCUMULATORS: A6==6 A7==7 A10==10 A11==11 A12==12 A13==13 A14==14 R==15 ;PARAMETERS AND RETURN ADDRESSES A==16 ;PARAMETERS AND POINTERS TO PARAMETERS P==17 ;STACK CONTROL OPDEF GOTO[JRST] OPDEF NOOP[JFCL] OPDEF INVOKE[PUSHJ P,] OPDEF RETURN[POPJ P,] OPDEF SAVE[PUSH P,] OPDEF RESTORE[POP P,] OPDEF PORTAL[JRST 1,] ;PARAMETERS: ;NOTE: THESE SYMBOLS AND SOME OF THE CONSTANTS AT THE START OF THE HIGH ;SEGMENT CAN BE MODIFIED WITH OUT CAUSING BUGS. THESE ARE THE ONLY SYMBOLS ;THAT ARE INTENDED TO BE SO MODIFIED. STKLEN==^D200 ;STACK SIZE. GALSIZ==^D10 ;GALAXY SIZE. (MAXIMUM) QADSIZ==^D10 ;QUADRANT SIZE. TRPMAX==^D30 ;MAXIMUM NUMBER OF ENTERPRISE TORPEDOES. MAXEGY==^D10000 ;MAXIMUM ENTERPRISE ENERGY. TOTMEN==^D500 ;MAXIMUM ENTERPRISE CREW. TRPEGY==^D600 ;TORP ENERGY AS FIRED BY ENTERPRISE. NMENRG==^D500 ;AVERAGE ENEMY ENERGY XCLEGY==^D800 ;MAXIMUM EXCALIBUR ENERGY TRPLSZ==^D14 ;MAXIMUM NUMBER OF FIRED TORPS CAPVAL==-^D10 ;VALUE OF A CAPTAIN (DAMAGE ROUTINE) DEVVAL==^D100 ;VALUE OF A DEVICE (DAMAGE ROUTINE) CAPPRT==^D20 ;DIVIDES DEATH TIME (DAMAGE ROUTINE) DEVPRT==^D10 ;DIVIDES DAMAGE TIME (DAMAGE ROUTINE) NMETIM==2 ;NUMBER STAR MINUTES ALLOCATED PER ENEMY. QADTIM==^D11 ;NUMBER STAR MINUTES ALLOCATED PER QUADRANT. STRMAX==7 ;MAXIMUM NUMBER OF STARS PER QUADRANT. NMEMAX==4 ;MAXIMUM NUMBER OF KLINGONS(ROMULANS) PER QUADRANT. ;STRMAX AND NMEMAX CANNOT EXCEED 7. NMEMIN==^D30 ;MINIMUM NUMBER OF AN ENEMY IN A 10 BY 10 GALAXY. MSWAIT==^D1500 ;MILLISECONDS WAIT FOR A COMMAND ACCOST==40.0 ;ACCELERATION COST PER 1.0 SPEED CHANGE AT NORMAL ACCELERATION. GHOLIM==^D10 ;AVERAGE NUMBER OF QUADS SET UP PER GHOST CREATION. SHLDLK==^D35 ;TWICE THE AVERAGE NUMBER OF HITS PER SHIELD LEAK. NOCLIM==^D50 ;MAX NUMBER STARMINUTES WITHOUT COMMAND INPUT. ETRPS2==0.25 ;SQUARE OF ENTERPRISE TORP SPEED RTRPS2==0.4225&<-1,,0> ;SQUARE OF ROMULAN TORP SPEED ETRPSP==0.5 ;ENTERPRISE TORP SPEED SCRPPN==000,,000 ;PPN OF SCORE RECORDER. SCRDEV==SIXBIT/NUL/ ;NAME OF SCORE DEVICE. SCRFIL==SIXBIT/PIRETS/ ;NAME OF SCORE FILE. SCREXT==SIXBIT/DAT/ ;EXTENSION OF SCORE FILE. DEFINE FLOATI(N1,N2)<&<-1,,0>> DEFINE FLOAT(N1<0>,N2<0>) ;CONVERTS INTEGER PARAMETERS INTO <^D,\)>> ;FLOATING POINT NUMBERS. ;DERIVED PARAMETERS: GALSZ2==GALSIZ*GALSIZ QADSZ2==QADSIZ*QADSIZ FQADSZ==FLOAT(QADSIZ) ;FLOATING POINT QUADRANT SIZE. FQADSL==FLOAT(QADSIZ-1,5) ;QUADRANT SIZE FOR ENEMY MOVE. MIDPOS==FLOAT( /2,5*<1+QADSIZ-QADSIZ/2*2>) ;QUAD HALF SIZE. ;OBJECT TYPE CODES: FDGCOD==0,,-1 ;FAKE OBJECT STRCOD==0 ;STAR BASCOD==1 ;BASE KLGCOD==2 ;KLINGON ROMCOD==3 ;ROMULAN ENTCOD==4 ;ENTERPRISE GHOCOD==5 ;GHOST XCLCOD==6 ;EXCALIBUR TRPCOD==7 ;ENTERPRISE TORPEDO RTPCOD==10 ;ROMULAN TORPEDO ;DEVICE TYPE CODES: WRPCOD==0 ;WARP DRIVES SSCCOD==1 ;SHORT SCAN LSCCOD==2 ;LONG SCAN PHACOD==3 ;PHASERS PHTCOD==4 ;PHOTON TORPEDOES ;OBJECT FORMAT: (DISPLACEMENT FROM OBJECT BASE ADDRESS) TYPE==0 ;OBJECT TYPE CODE--LEFT HALF WORD LINK==0 ;OBJECT LIST LINK--RIGHT HALF WORD XPOS==1 ;POSITION IN QUADRANT--FLOATING POINT YPOS==2 ENERGY==3 ;REMAINING ENERGY XVEL==4 ;VELOCITY--FLOATING POINT YVEL==5 XACC==;ACCELERATION--FLOATING POINT. YACC==7 ;OR ENEMY STRATEGY--BITS. ;NOT ALL OBJECTS HAVE ALL OF ABOVE PROPERTIES, HENCE OBJECT LENGTHS: STRLEN==3 BASLEN==3 KLGLEN==7 ROMLEN==7 ENTLEN==10 GHOLEN==6 XCLLEN==6 TRPLEN==6 ;ENEMY STRATEGY BITS: FIXSTT==1B0 ;ENEMY IS ATTACKING OR ESCAPING. ATTSTT==1B1 ;ENEMY IS ATTACKING. CLKSTT==1B2 ;ENEMY IS CLOCKWISE. IOCHAN==2 ;THE SAVE GAME AND NOTICE READ I/O CHANNEL. IOCHSC==3 ;THE SCORE RECORDING I/O CHANNEL. .IODPR==16 ;DUMP AS RECORDS I/O MODE. DV.DIR==1B15 ;DEVCHR UUO DIRECTORY FLAG. DV.M16==1B21 ;DEVCHR UUO MODE 16 FLAG. BLKSIZ==200 ;DISK BLOCK SIZE. RELOC 0 CCTRPB: BLOCK 4 ;.JBINT TRAP CONTROL BLOCK. .SGDEV: BLOCK 1 ;STRTRK RUN FILE DEVICE. .SGPPN: BLOCK 1 ;STRTRK RUN FILE PPN. PERIOD: BLOCK 1 ;CONTAINS THE TIMING CHARACTER. NOCCNT: BLOCK 1 ;CONTAINS THE NO-COMMAND COUNT. STACK: BLOCK STKLEN ;PUSH DOWN STORAGE. DISMAT: BLOCK QADSZ2 ;TEMP STORE FOR QUAD DISPLAY AND OTHERS. GAMDAT==. ;SAVABLE GAME DATA BEGINS HERE. IMGCOM: BLOCK 1 ;GAME/VERSION COMPATIBILITY CODE. CRETIM: BLOCK 1 ;DATE/TIME OF GALAXY CREATION. RESCNT: BLOCK 1 ;GAME RESTORE COUNT. GHOCNT: BLOCK 1 ;COUNT USED TO DERANDOMIZE GHOST CREATIONS. IDTCNT: BLOCK 1 ;COUNT OF SHIELD HITS TILL NEXT LEAK. GALASZ: BLOCK 1 ;ACTUAL GALAXY SIZE. GALAS2: BLOCK 1 ;SQUARE OF ACTUAL GALAXY SIZE. XQUAD: BLOCK 1 ;COORDINATES (1-10) OF CURRENT QUADRANT. YQUAD: BLOCK 1 NUMKLG: BLOCK 1 ;NUMBER OF KLINGONS LEFT NUMKL2: BLOCK 1 ;#KLINGONS,,ROMULANS AT LAST CREATION/RESTORE. NUMROM: BLOCK 1 ;NUMBER OF ROMULANS LEFT MEN: BLOCK 1 ;NUMBER OF MEN LEFT SHIELD: BLOCK 4 ;DEFLECTOR LEVELS TRVLTM: BLOCK 1 ;REMAINING TRAVEL TIME TOTEMY: BLOCK 1 ;NUMBER OF INITIAL KLINGONS,,ROMULANS. INIDAT: BLOCK 1 ;INITIAL TIME LIMIT. (IN STARMINUTES) INIDA2: BLOCK 1 ;SAME AT LAST CREATION/RESTORE. TIMLIM: BLOCK 1 ;SAME AT CURRENT TIME. STRDAT: BLOCK 1 ;CURRENT STARDATE XCLF3: BLOCK 1 ;#TIMES EXCALIBUR HIT BY ENTERPRISE PHASERS ENTVEC: BLOCK ENTLEN ;ENTERPRISE OBJECT VECTOR BASE: BLOCK BASLEN ;BASE VECTOR GHOST: BLOCK GHOLEN ;GHOST VECTOR XCALBR: BLOCK XCLLEN ;EXCALIBUR VECTOR STARS: BLOCK STRMAX*STRLEN ;STAR VECTORS ROMLNS: BLOCK NMEMAX*ROMLEN ;ROMULAN VECTORS KLNGNS: BLOCK NMEMAX*KLGLEN ;KLINGON VECTORS STARP: BLOCK 1 ;TOP OF STAR LIST ROMLNP: BLOCK 1 ;TOP OF ROMULAN AND KLINGON LIST DEATHS: BLOCK 5*3 ;LIST OF DEAD CAPTAINS DAMAGE: BLOCK 5*3 ;LIST OF DAMAGED DEVICES PRBLMS: BLOCK 1 ;POINTS TO PROBLEM LIST ACCTIM: BLOCK 1 ;TIME LEFT TO ACCELERATE DSPEED: BLOCK 1 ;DESIRED SPEED DBERNG: BLOCK 1 ;DESIRED BEARING EPACST: BLOCK 1 ;ENERGY COST PER STARMINUTE OF ACCELERATION TRPREQ: BLOCK TRPMAX ;LIST OF ENTERPRISE TORP FIRE REQUESTS TRPNUM: BLOCK 1 ;NEXT ENTERPRISE TORP TO FIRE TRPRNM: BLOCK 1 ;NUMBER OF ENT TORP REQUESTS PENDING TRPLST: BLOCK TRPLSZ*TRPLEN ;FIRED TORP VECTORS TRPFRE: BLOCK 1 ;POINTS TO LIST OF FREE TORPS TRPTOP: BLOCK 1 ;POINTS TO LIST OF FIRED TORPS FLGSAV: BLOCK 1 ;FLAGS STORED HERE DURING GAME SAVE/RESTORE. GALAXY: BLOCK GALSZ2 ;LIST OF QUADRANT CONTENTS ;IS ALWAYS LAST ITEM IN SAVABLE GAME DATA. DATLEN==.-GAMDAT ;SAVABLE GAME DATA ENDS HERE. DSKBLK: BLOCK BLKSIZ ;ONE STANDARD LENGTH DISK BLOCK. ;MUST FOLLOW GAME DATA. SUBTTL **** FLOATING POINT CONSTANTS AND PARAMETERS **** RELOC 400000 ONE: 1.0 NFQADL: EXP 0.5 ;QADRANT LOWER BOUND NFQADH: EXP FLOAT(QADSIZ,5) ;QUADRANT UPPER BOUND ZERO: 1.0E-4 ;A USEFUL APPROXIMATION OF ZERO ;PARAMETERS: COLMAX: 2.0 ;SQUARE OF ENEMY-ENTERPRISE TORP COLLISION RADIUS. COLLIM: 0.95 ;SQUARE OF NORMAL COLLISION RADIUS COLTEL: 0.5 ;SQUARE OF ENTERPRISE-TORP COLLISION RADIUS. COLTIM: 0.05 ;SQUARE OF TORP-TORP COLLISION RADIUS BADMAX: 0.305 ;MAX BASE DOCKING SPEED GODMAX: 0.505 ;MAX GHOST DOCKING SPEED ACCMAG: 0.5 ;ACCELERATION MAGNITUDE IN P/SM**2 AT NORM ACCEL VISOBS: 0.30 ;SQUARE OF RADIUS OF VISION OBSTRUCTION BY A STAR. STRLIM: 4.0 ;STRATEGY SETTING RADIUS. SUBTTL **** INITIALIZATION **** BEGIN: PORTAL .+1 ;START COMMAND CAUSES PUBLIC MODE. MOVEM A11,.SGDEV ;SAVE THIS CORE IMAGE'S SOURCE DEVICE MOVEM A7,.SGPPN ;AND PPN. MOVEI T,BEGIN2 ;PROTECT THEM AGAINST START COMMAND. HRRM T,.JBSA BEGIN2: PORTAL .+1 ;START COMMAND CAUSES PUBLIC MODE. JSP R,INITSB ;PERFORM GENERAL INITIALIZATION. INVOKE PAGE ;TYPE A FORM FEED AND MOVEI A,STMSG1 ;THE INITIAL MESSAGE. INVOKE ENDMSG ;TYPE THE VARIABLE STARTUP MESSAGE: INVOKE NOSUPP ;MAKE SURE THIS MESSAGE GETS THROUGH. MOVE T,.SGDEV ;SEE IF GAME SOURCE DEVICE HAS DEVCHR T, ;A DIRECTORY AND TAKES THE DUMP TRNE T,DV.M16 ;AS RECORDS I/O MODE. IF SO, WE TLNN T,(DV.DIR) ;CAN TRY TO GET THE NOTICE.TXT GOTO NOTYP1 ;MESSAGE FILE FROM IT: MOVE T,NOTICB ;GET THE NOTICE.TXT OPEN AND LOOKUP BLT T,DISMAT+5 ;ARG BLOCKS AND PUT THE SOURCE DEVICE MOVE T,.SGDEV ;AND PPN INTO THEM. MOVEM T,DISMAT+1 MOVE T,.SGPPN MOVEM T,DISMAT+6 OPEN IOCHAN,DISMAT ;TRY TO OPEN AND LOOKUP THE RESULTING GOTO NOTYP1 ;FILE. IF UNABLE TO ACCESS IT, TRY THE LOOKUP IOCHAN,DISMAT+3 ;SAME FILE ON THE SCORE DEVICE. GOTO NOTYP1 GOTO NOTYP3 NOTYP1: RELEASE IOCHAN, ;CLEAN UP THE OPENED SOURCE DEVICE. MOVE T,NOTICB ;GET THE NOTICE.TXT OPEN AND LOOKUP ARG BLT T,DISMAT+6 ;BLOCKS FOR THE SCORE DEVICE AND PPN. OPEN IOCHAN,DISMAT ;IF WE CAN'T ACCESS THIS FILE, GOTO NOTYP4 ;WE CAN'T TYPE THE STARTUP NOTICE. LOOKUP IOCHAN,DISMAT+3 GOTO NOTYP4 NOTYP3: CLEARM GAMDAT MOVE T,[GAMDAT,,GAMDAT+1] ;CLEAR THE GAME DATA AND BLT T,DSKBLK ;THE FIRST WORD OF DSKBLK. INVOKE SAVWRC ;MAKE A DUMP COMMAND LIST. INPUT IOCHAN,DISMAT ;READ THE FIRST COUPLE OF NOTICE BLOCKS. MOVEI A,GAMDAT ;TYPE THE NOTICE MESSAGE AS AN INVOKE OUTSTR ;ASCIZ STRING. (MAX LENGTH IS 5*DATLEN) INVOKE NEWLIN NOTYP4: RELEASE IOCHAN, ;CLEAN UP AFTER TYPING THE NOTICE. ;GET THE GALAXY SIZE: NEWGAM: CLEARM GALASZ ;SET GALAXY NOT CREATED CONDITION. MOVEI A,COMS93 ;ASK FOR THE GALAXY SIZE. INVOKE ASKFOR INVOKE READ GOTO NEWGAM ;IGNORE END-OF-FILES AT THIS POINT. FIXR A,A ;CONVERT SIZE TO INTEGER. CAIN A,^D19 ;IF RESPONSE IS THE RESTORE COMMAND, GOTO RESRTY ;GO TO RESTORE ROUTINE. JUMPLE A,NEWGAH ;IF SIZE IS NOT LEGAL CAIG A,GALSIZ ;(LESS OR EQUAL TO ZERO OR MORE THAN GOTO GALSET ;THAN THE MAXIMUM GALSIZ), TYPE NEWGAH: MOVEI A,COMS94 ;A "HELP" MESSAGE AND ASK AGAIN. INVOKE ENDMSG ;IF THE GALAXY SIZE IS OK, GOTO NEWGAM ;PROCEED WITH GALAXY CREATION. ;GENERATE RANDOM GALAXY CREATION PARAMETERS: GALSET: MOVEM A,GALASZ ;SET UP THE REQUESTED IMUL A,A ;GALAXY SIZE PARAMETERS. MOVEM A,GALAS2 CLEARM RESCNT ;SET THE INITIAL GAME RESTORE COUNT. INVOKE DAYTIM ;SET GALAXY CREATION DATE/TIME. MOVEM A,CRETIM REGEN: MOVEI A14,KLGCOD MOVEI A,NMEMIN ;GENERATE NUMBER OF KLINGONS. INVOKE ITMGEN MOVE A5,R MOVEM A5,NUMKLG ;NEED THIS FOR KEEPING SCORE. HRLZM A5,NUMKL2 HRLZM A5,TOTEMY MOVEI A14,ROMCOD MOVEI A,NMEMIN ;GENERATE NUMBER OF ROMULANS. INVOKE ITMGEN MOVE A6,R MOVEM A6,NUMROM ;NEED THIS FOR KEEPING SCORE. HRRM A6,NUMKL2 HRRM A6,TOTEMY ADD R,A5 ;COMPUTE THE TOTAL NUMBER OF ENEMIES. JUMPE R,REGEN ;MAKE SURE THERE ARE SOME ENEMIES. MOVE A7,R MOVEI A14,STRCOD MOVEI A,^D199 ;GENERATE THE NUMBER OF STARS. INVOKE ITMGEN MOVE A10,R JSP R,RANDOM ;GENERATE THE INITIAL STARDATE. MULI R,^D100K MOVEI A,^D70K(R) MOVEM A,STRDAT MOVE R,A7 ;GENERATE THE TIME LIMIT. IMULI R,NMETIM ;GIVE SO MUCH TIME PER ENEMY MOVE A,GALAS2 ;AND SO MUCH TIME PER QUADRANT. IMULI A,QADTIM ADD R,A MOVEM R,TIMLIM MOVEM R,INIDAT MOVEM R,INIDA2 ;TYPE THE ORDERS: INVOKE PAGE MOVEI A,STMSG2 ;TYPE "ATTENTION CAPTAIN". INVOKE OUTSTR HRROI A12,<.GTNM1==31> ;GET THE USER'S NAME. GETTAB A12, HALT HRROI A13,<.GTNM2==32> GETTAB A13, HALT MOVEI A11,^D12 MOVE A14,[POINT 6,A12] USENAM: ILDB A,A14 ;TYPE IT. ADDI A," " ;CONVERT TO 7 BIT. CAIE A,"*" ;DELETE ASTERISKS. INVOKE OUTCHR SOJG A11,USENAM MOVEI A,STMSG3 ;TYPE "ORDERS: STARDATE ". INVOKE OUTSTR MOVE A,STRDAT ;TYPE THE INITIAL STARDATE. INVOKE OUTDAT MOVEI A,STMSG4 INVOKE OUTSTR MOVE A,A5 ;TYPE THE NUMBER OF KLINGONS. INVOKE OUTINT MOVEI A,STMSG5 INVOKE OUTSTR MOVE A,A6 ;TYPE THE NUMBER OF ROMULANS. INVOKE OUTINT MOVEI A,STMSG6 INVOKE OUTSTR MOVE A,A7 ;TYPE THE TOTAL NUMBER OF ENEMIES. INVOKE OUTINT MOVEI A,STMSG7 INVOKE OUTSTR MOVE A,TIMLIM ;TYPE THE TIME LIMIT. INVOKE OUTDAT MOVEI A,STMSG8 INVOKE OUTSTR MOVE A,STRDAT ;TYPE THE FINAL STARDATE. ADD A,TIMLIM INVOKE OUTDAT INVOKE ENDLIN INVOKE BRKOUT ;CREATE THE GALAXY: CLEARM GALAXY ;CLEAR THE GALAXY. MOVE T,GALCLR BLT T,GALAXY+GALSZ2-1 MOVE A13,GALAS2 ;THE FOLLOWING CODE KEEPS THE IDIVI A13,4 ;ENEMY OUT OF 1/4TH OF THE QUADRANTS JUMPE A13,NOGIX ;BY FILLING THEM UP. HRREI A14,777700 GIX1: JSP R,RANDOM ;THIS TENDS TO LOCALIZE THEM. MUL R,GALAS2 SKIPE GALAXY(R) GOTO GIX1 MOVEM A14,GALAXY(R) SOJG A13,GIX1 NOGIX: MOVEI A14,STRCOD ;DISTRIBUTE THE STARS. MOVE A13,A10 INVOKE GALDIS MOVEI A14,KLGCOD ;DISTRIBUTE THE KLINGONS. MOVE A13,A5 INVOKE GALDIS MOVEI A14,ROMCOD ;DISTRIBUTE THE ROMULANS. MOVE A13,A6 INVOKE GALDIS JSP R,RANDOM ;THIS PIECE OF CODE PUTS MULI R,5 ;A BASE IN EVERY CHUNK OF ABOUT MOVEI A11,^D22(R) ;25 QUADRANTS, DEPENDING ON FATE MOVE A12,GALAS2 ;AND THE RANDOM (HA!) NUMBER GENERATOR. IDIV A12,A11 CLEAR A13, MOVEI A14,BASCOD BASDIS: JUMPG A12,BASDIX MOVE A11,GALAS2 SUB A11,A13 BASDIX: JSP R,RANDOM MUL R,A11 ADD R,A13 INVOKE ADDQAX HALT .+1 ADD A13,A11 SOJGE A12,BASDIS MOVEI A14,77 ;THIS CODE UNFILLS THE EXCLUDED QUADRANTS. MOVEI R,GALSZ2-1 GIX2: SKIPGE GALAXY(R) ANDM A14,GALAXY(R) SOJGE R,GIX2 INVOKE WAITTY MOVEI T,^D2000 HIBER T, HALT .+1 INVOKE PAGE ;INITIALIZE THE ENTERPRISE: MOVEI T,TOTMEN ;SET INITIAL ENTERPRISE CREW. MOVEM T,MEN INVOKE DAMSET ;CLEAR THE DAMAGE LIST. CLEARM TRPRNM ;CLEAR TORPEDO FIRE REQUESTS. TRZ F,-1 ;INITIALIZE ALL FLAGS. INVOKE DOCSUB ;INIT SHIELDS,ENERGY,VELOCITY,TORPEDOES,... HLRZ T,TOTEMY HRRZ T3,TOTEMY ;COMPUTE TOTAL INITIAL ENEMIES. ADDB T,T3 ;GIVE THE ENTERPRISE 1000 UNITS OF IMULI T,^D500 ;ENERGY AND AN ADDITIONAL 500 UNITS ADDI T,^D1000 ;FOR EACH ENEMY CREATED BUT NOT MORE CAMGE T,ENERGY+ENTVEC ;THAN A BASE WILL GIVE. MOVEM T,ENERGY+ENTVEC MOVN T,T3 ;GIVE THE ENTERPRISE 4 TORPEDOES AND IMULI T,2 ;2 ADDITIONAL TORPEDOES FOR EACH ENEMY HRREI T,TRPMAX-3(T) ;CREATED BUT NOT MORE THAN A BASE CAMLE T,TRPNUM ;WOULD GIVE. MOVEM T,TRPNUM ;SETUP THE CURRENT SITUATION: RESTRT: INVOKE CCTRPI ;PERFORM BASIC RESTART INITIALIZATION. JSP R,RANDOM ;PICK A QUADRANT AT RANDOM. MUL R,GALAS2 IDIV R,GALASZ AOJ R, AOJ A, MOVEM R,XQUAD MOVEM A,YQUAD JSP R,RANDOM ;GENERATE A RANDOM POSITION. MULI R,QADSZ2 ;(FOR THE ENTERPRISE) IDIVI R,QADSIZ AOJ R, AOJ A, FSC R,233 ;FLOAT THE COORDINATES. FSC A,233 MOVEM R,ENTVEC+XPOS ;REMEMBER THIS POSITION MOVEM A,ENTVEC+YPOS INVOKE CANTRP ;CANCEL TORPEDO LAUNCHES. INVOKE CANWRP ;CANCEL WARP CHANGES. TRZ F,QSUFLG+DSHFLG+HYPFLG+LHPFLG CLEARM TRVLTM ;SET THE INITIAL TRAVEL TIME. CLEARM ENTVEC+XVEL CLEARM ENTVEC+YVEL ;STOP ENTERPRISE MOTION. MOVEI A,GHOLIM ;SET THE GHOST CREATION COUNT. INVOKE RNDVAR MOVEM A,GHOCNT MOVEI A,SHLDLK ;SET SHIELD LEAK COUNT. INVOKE RNDVAR MOVEM A,IDTCNT MOVEI A,REMSG1 ;TYPE NEW LOCATION MESSAGE. INVOKE OUTSTR INVOKE OUTQAD INVOKE NEWLIN ;SET UP THE QUADRANT: ;NOTE: AN OBJECT IS PUT INTO THE CURRENT QUADRANT BY ENTERING IT INTO A ;LINKED LIST OF ALL OBJECTS IN THE QUADRANT. WHEN SEARCHING THE LIST, OBJECT ;TYPES ARE DETERMINED FROM TYPE CODES STORED IN EACH OBJECT. THE OBJECTS ARE ;ENTERED IN A SPECIAL ORDER TO SIMPLIFY PARTS OF THIS PROGRAM. THE ORDER IS ; SP,S,B,RP,R,K,X,G,TP,T,E (WHERE THE SINGLE LETTERS INDICATE OBJECT TYPES ;AND THE P'S INDICATE FAKE OBJECTS PUT INTO THE LIST TO PERMIT EASY LOOKUP ;OF INDIVIDUAL TYPES). QADSET: INVOKE TRPCLR ;FREE ALL FIRED TORPEDOES. SETOM DISMAT ;CLEAR THE COORDINATE EXCLUSION MATRIX. MOVE T,DISCLR BLT T,DISMAT+QADSZ2-1 FIXR R,ENTVEC+YPOS ;PREVENT OBJECT PLACEMENT FIXR A,ENTVEC+XPOS ;AROUND THE ENTERPRISE'S CURRENT LOCATION. INVOKE SETBAR MOVEI A,ENTVEC ;FIGURE OUT WHERE THE ENTERPRISE INVOKE SPEED ;WILL BE A LITTLE WHILE FROM NOW. JUMPE A,QADSH1 MOVE T,A FSC T,-1 MOVE R,ENTVEC+YVEL MOVE A,ENTVEC+XVEL FDVR R,T FDVR A,T FADR R,ENTVEC+YPOS FADR A,ENTVEC+XPOS FIXR R,R FIXR A,A ;PREVENT OBJECT PLACEMENT AROUND INVOKE SETBAR ;THIS FUTURE LOCATION. QADSH1: MOVSI T,FDGCOD ;BEGIN CONSTRUCTION OF THE OBJECT LIST. MOVEM T,STARP ;SET THE TOP OF THE LIST. MOVEI A5,STARP ;SET THE BOTTOM OF THE PARTIAL LIST. MOVEI A14,STRCOD ;GET THE NUMBER OF STARS IN THE QUADRANT. INVOKE GETCQD JUMPE A,NOSTAR MOVE A6,A ;ADD THEM TO THE OBJECT LIST: MOVEI A7,STARS ;LOCATE THE FIRST STAR. NEXTAR: INVOKE RANCRD ;PUT IT IN THE OBJECT LIST. ADDI A7,STRLEN ;LOCATE THE NEXT STAR. SOJG A6,NEXTAR NOSTAR: MOVEI A14,BASCOD ;GET THE NUMBER OF BASES IN THE QUADRANT. INVOKE GETCQD ;(THERE SHOULD BE AT MOST 1) JUMPE A,NOBASE MOVEI A7,BASE ;IF THERE IS ONE, ADD IT TO THE OBJECT LIST. INVOKE RANCRD TRZ F,DOCFLG ;INDICATE NOT DOCKED SINCE LAST QUAD SETUP. NOBASE: MOVEI A14,FDGCOD ;PUT THE ROMULAN POINTER INTO THE LIST. MOVEI A7,ROMLNP INVOKE ADQLST MOVEI A14,ROMCOD ;GET THE NUMBER OF ROMULANS IN THE QUADRANT. INVOKE GETCQD JUMPE A,NOROMS MOVE A6,A ;ADD THEM TO THE OBJECT LIST: MOVEI A7,ROMLNS ;LOCATE THE FIRST ROMULAN. NEXROM: INVOKE RANCRD ;PUT IT INTO THE OBJECT LIST. INVOKE NMESET ;SET UP ITS PARAMETERS. ADDI A7,ROMLEN ;LOCATE THE NEXT ROMULAN. SOJG A6,NEXROM NOROMS: MOVEI A14,KLGCOD ;GET THE NUMBER OF KLINGONS IN THE QUADRANT. INVOKE GETCQD JUMPE A,NOKLGS MOVE A6,A ;PUT THEM INTO THE QUADRANT: MOVEI A7,KLNGNS ;LOCATE THE FIRST KLINGON. NEXKLG: INVOKE RANCRD ;GIVE IT A POSITION AND ENTER INTO LIST. INVOKE NMESET ;FIX UP ITS PARAMETERS. ADDI A7,KLGLEN ;LOCATE THE NEXT KLINGON. SOJG A6,NEXKLG NOKLGS: CLEARM XCALBR ;SET DEFAULT: EXCALIBUR NOT IN QUADRANT. TRNE F,XCLDST ;TEST FOR EXCALIBUR DESTROYED. GOTO NOXLBR JSP R,RANDOM ;CONSIDER PUTTING EXCALIBUR INTO QUAD. MULI R,^D20 ;(PROBABILITY OF EXCALIBUR=0.05) JUMPN R,NOXLBR MOVEI A14,XCLCOD ;THIS PUTS THE EXCALIBUR INTO THE QUADRANT. MOVEI A7,XCALBR INVOKE RANCRD MOVE A10,[0.3] ;SET THE EXCALIBUR'S SPEED TO 0.3 P/SM. INVOKE MIDVEC MOVEI T,3 ;SET THE EXCALIBUR'S FIRED ON COUNT. MOVEM T,XCLF3 ;(FIRED ON BY THE ENTERPRISE) MOVEI A,XCLEGY ;SET THE EXCALIBUR'S ENERGY. INVOKE RNDVAR MOVEM A,ENERGY+XCALBR NOXLBR: SOSLE GHOCNT ;CONSIDER PUTTING A GHOST IN THE QUADRANT. GOTO NOGOST MOVEI A,GHOLIM ;COMPUTE NEXT GHOST WAIT. INVOKE RNDVAR MOVEM A,GHOCNT MOVEI A14,GHOCOD ;THIS ADDS A GHOST TO THE QUADRANT. MOVEI A7,GHOST INVOKE RANCRD MOVE A10,[0.1] ;SET THE GHOST'S VELOCITY. INVOKE MIDVEC JSP R,RANDOM ;SET THE GHOST'S ENERGY. (THIS IS WHAT MULI R,MAXEGY/5 ;THE ENTERPRISE GETS WHEN IT DOCKS) ADDI R,MAXEGY/5 MOVEM R,ENERGY(A7) ;AMOUNT=MAXEGY*(1+RANDOM)/5 NOGOST: MOVEI A14,FDGCOD ;PUT TORP POINTER INTO OBJECT LIST. MOVEI A7,TRPTOP INVOKE ADQLST MOVEI A14,ENTCOD ;PUT THE ENTERPRISE INTO THE LIST. MOVEI A7,ENTVEC INVOKE ADQLST TRO F,QSUFLG ;INDICATE QUADRANT SET UP. ;QUADRANT DISPLAY: QADISP: INVOKE NEWLIN MOVEI A,SSCCOD ;MAKE SURE THE SHORT SCAN IS NOT DAMAGED. MOVEI R,0 ;SUPPRESS ERROR MESSAGES. INVOKE DAMCHK GOTO COMMND ;(NON-SKIP RETURN IF DAMAGED) INVOKE SDBCQD ;INDICATE QUADRANT CONTENTS ARE KNOWN. MOVEI A,QDMS01 ;TYPE QUADRANT IDENTIFICATION: INVOKE OUTSTR INVOKE OUTQAD ;TYPE QUADRANT COORDINATES. INVOKE NEWLIN INVOKE UNDLIN ;(TYPES A LINE OF MINUS SIGNS) MOVEI T,"." ;SET QUADRANT DISPLAY FILL CHARACTER. MOVEM T,DISMAT ;FILL THE DISPLAY MATRIX WITH IT. MOVE T,DISCLR BLT T,DISMAT+QADSZ2-1 HRRZ A7,STARP ;LOCATE TOP OF THE OBJECT LIST. DISCON: HLRZ A5,TYPE(A7) ;GET THE OBJECT TYPE. CAIN A5,FDGCOD GOTO DISNOB ;IGNORE FUDGE ENTRIES. CAIE A5,STRCOD CAIN A5,ENTCOD ;ALWAYS DISPLAY THE ENTERPRISE GOTO DISOBJ ;AND ALL STARS. MOVE A,A7 INVOKE VISION ;DISPLAY ALL OTHER OBJECTS GOTO DISNOB ;ONLY WHEN VISIBLE. DISOBJ: FIXR R,YPOS(A7) ;COMPUTE THE OBJECTS POSITION FIXR A,XPOS(A7) ;IN THE DISPLAY MATRIX: JUMPLE R,DISNOB ;DON'T DISPLAY OBJECTS OUTSIDE OF QUAD. JUMPLE A,DISNOB CAIG R,QADSIZ CAILE A,QADSIZ GOTO DISNOB IMULI R,QADSIZ ADDI R,-QADSIZ-1(A) MOVE T,LETTER(A5) ;GET THE OBJECT'S IDENTIFYING CHARACTER. MOVEM T,DISMAT(R) ;PUT IT INTO THE DISPLAY MATRIX. DISNOB: HRRZ A7,LINK(A7) ;GET THE NEXT OBJECT IN THE LIST. JUMPN A7,DISCON ;CONSIDER ITS DISPLAY (IF IT EXISTS). MOVEI A5,QADSIZ ;SET OUTER OUTPUT LOOP COUNT. MOVEI A6,0 ;SET OUTER LOOP INDEX. DISOTL: MOVSI A7,-QADSIZ ;SET LINE DISPLAY CONTROL. HRR A7,A6 DISOL2: MOVE A,DISMAT(A7) ;DISPLAY A QUADRANT POSITION. INVOKE OUTCHR INVOKE OUTSPC ;THROW OUT A BLANK. AOBJN A7,DISOL2 ;LOOP THROUGH ONE LINE OF THE QUADRANT. MOVEI A,QDMS02 ;SKIP 4 SPACES. INVOKE OUTSTR CAILE A5,QADSIZ-^D10 ;CONSIDER TYPING SUPPLEMENTARY INFO. INVOKE @DISINF-^D11+QADSIZ(A5) INVOKE NEWLIN ADDI A6,QADSIZ SOJG A5,DISOTL INVOKE UNDLIN INVOKE NEWLIN TRNN F,HASFLG ;IF CHEATING FLAG SET, GOTO COMMND ;GIVE BAD GUYS FIRST SHOT. MOVEI A,COMS47 ;TELL THE CAPTAIN THAT WE INVOKE ENDMSG ;CAUGHT HIM CHEATING. GOTO NMEMOV SUBTTL **** READ AND OBEY THE COMMANDS **** COMMND: SOSLE TRVLTM ;CHECK FOR REMAINING TRAVEL TIME. GOTO TRVLBT TLNE F,(LFQFLG) GOTO TIMING ;CHECK FOR NO OUTPUT SINCE LAST ASTERISK. COMREQ: INVOKE NOSUPP ;MAKE SURE THE PROMPTING CHAR IS TYPED. MOVEI A,COMS00 ;IF TIMING CHARACTER NO LAST OUTPUT, INVOKE OUTSTR ;FLUSH THE OUTPUT BUFFER INVOKE WAITTY ;BEFORE PROCEEDING. TIMING: MOVE T,[1B13+MSWAIT] ;WAIT A MAXIMUM OF ONE SECOND HIBER T, ;FOR A COMMAND. HALT SKPINL ;IF NO COMMAND IS YET AVAILABLE, GOTO ACTION ;PROCEED WITH EXISTENCE MODIFICATION. ;COMMAND INTERPRETATION: MOVEI T,NOCLIM ;RESET NO-COMMAND TIME COUNT. MOVEM T,NOCCNT INVOKE READ ;GET COMMAND NUMBER. GOTO COMREQ ;IGNORE END-OF-FILES. FIXR A,A JUMPL A,COMHLP ;NEGATIVE COMMANDS ASK FOR HELP. CAIN A,^D44 GOTO ALTPHA ;44=ALTERNATE PHASERS. CAIN A,^D55 ;55=ALTERNATE TORPEDOES. GOTO ALTORP CAILE A,^D20 GOTO COMWHT ;THE MAXIMUM LOW COMMAND NUMBER IS 19. JUMPE A,COMREQ ;"COMMAND" 0 DOES NOTHING. GOTO @.(A) EXP SETWRP,SSCAN,LSCAN,FIRPHA,FIRTRP,PULSIV,TRAVEL,STATUS EXP REPDAM,HGHWRP,EMGWRP,RASDEF,DRPDEF,REQTRC,SHRTRK,GALMAP EXP SETPRD,SAVGAM,RESGAM,CCTORP TRVLBT: TLNN F,(LFQFLG) ;WHEN TRAVELLING, WE MUST BREAK INVOKE BRKOUT ;PENDING OUTPUT BETWEEN STARMINUTES. GOTO ACTION ;WARP CHANGE COMMANDS: SETWRP: MOVSI A5,(1.0) ;SET ACCELERATION FACTOR TO NORMAL. WRPMRG: MOVEI A,WRPCOD MOVEI R,1 INVOKE DAMCHK ;MAKE SURE THE WARP DRIVES ARE NOT DAMAGED. GOTO COMREQ MOVEI A,COMS01 INVOKE ASKFOR ;ASK FOR THE NEW BEARING. INVOKE READ ;GET THE NEW BEARING. GOTO COMCAN MOVE A7,A ;SAVE THE BEARING. SETSPD: MOVEI A,COMS02 INVOKE ASKFOR ;ASK FOR THE NEW SPEED. INVOKE READ ;GET THE NEW SPEED. GOTO COMCAN MOVE A6,A ;SAVE THE SPEED. MOVM A,A ;MAKE SURE IT DOES NOT EXCEED 1000 P/SM. CAML A,WRPMAX GOTO WRPRID TRZ F,DSHFLG ;SET THE HYPERSPACE DESIRED FLAG: CAML A,ONE TRO F,DSHFLG CAME A6,DSPEED ;CHECK FOR A SPEED CHANGE REQUEST. TRO F,SPCFLG MOVEM A6,DSPEED CAME A7,DBERNG ;CHECK FOR A BEARING CHANGE REQUEST. TRO F,BRCFLG MOVEM A7,DBERNG MOVE A10,A6 ;COMPUTE DESIRED X VELOCITY. MOVE A,A7 JSP R,DCOS FMPR A10,A MOVN A11,A6 ;COMPUTE DESIRED Y,VELOCITY. MOVE A,A7 JSP R,DSIN FMPR A11,A FSBR A10,ENTVEC+XVEL ;COMPUTE REQUIRED VELOCITY CHANGE. FSBR A11,ENTVEC+YVEL MOVE R,A10 ;COMPUTE CHANGE MAGNITUDE. MOVE A,A11 INVOKE SQUMS MOVE R,A FMPRI R,(ACCOST) ;COMPUTE TOTAL COST IN ENERGY. FMPR R,A5 ;COST IS PROPORTIONAL TO CHANGE AND FIXR R,R ;ACCELERATION. FDVR A,ACCMAG ;COMPUTE THE TIME REQUIRED. FDVR A,A5 ;NORMAL ACCELERATION IS 0.5P/SM**2. FIXR A,A ;THE MINIMUM TIME IS 1 SM. CAIG A,0 MOVEI A,1 MOVEM A,ACCTIM ;SET THE ACCELERATION TIME. MOVE T,R IDIV T,A ;COMPUTE ENERGY LOSS PER STARMINUTE. MOVEM T,EPACST FSC A,233 ;FLOAT THE TIME. FDVR A10,A ;COMPUTE AND SET X ACCELERATION. MOVEM A10,ENTVEC+XACC FDVR A11,A ;COMPUTE AND SET Y ACCELERATION. MOVEM A11,ENTVEC+YACC GOTO COMREQ HGHWRP: MOVEI A,COMS03 ;TYPE HIGH WARP IDENTIFICATION. INVOKE ENDMSG MOVSI A5,(2.0) ;SET HIGH ACCELERATION FACTOR. GOTO WRPMRG EMGWRP: MOVEI A,COMS04 ;TYPE EMERGENCY WARP IDENTIFICATION. INVOKE ENDMSG MOVSI A5,(4.0) ;SET EMERGENCY ACCELERATION FACTOR. GOTO WRPMRG WRPRID: MOVEI A,COMS05 INVOKE ENDMSG GOTO SETSPD WRPMAX: 100.0 ;MAXIMUM SPEED PERMITTED. ;SHORT RANGE SCAN: SSCAN: TRNE F,HYPFLG ;REJECT COMMAND WHEN IN HYPERSPACE. GOTO SSCREJ MOVEI A,SSCCOD ;CHECK FOR DAMAGE. MOVEI R,1 ;PERMIT AUTOMATIC ERROR MESSAGE. INVOKE DAMCHK GOTO COMREQ GOTO QADISP ;(ALL IS OK; DO A SHORT SCAN) SSCREJ: MOVEI A,COMS06 ;JUMP HERE TO REJECT COMMAND BECAUSE GOTO COMHLX ;THE ENTERPRISE IS IN HYPERSPACE. ;LONG RANGE SCAN: LSCAN: MOVEI A,LSCCOD ;CHECK FOR DAMAGE. MOVEI R,1 ;PERMIT AUTOMATIC ERROR MESSAGES. INVOKE DAMCHK GOTO COMREQ MOVEI A,COMS07 ;IDENTIFY THE CENTER QUADRANT. INVOKE OUTSTR INVOKE OUTQAD INVOKE NEWLIN MOVSI A13,(1B0) MOVE A5,YQUAD ;SET Y INDEX CONTROL. HRLI A5,-3 LSCALO: INVOKE LSCUND ;TYPE A LINE OF MINUS SIGNS. MOVE A6,XQUAD ;SET X INDEX CONTROL. HRLI A6,-3 INVOKE LSCSPA LSCALI: MOVEI A,COMS08 ;SOME FORMATTING INVOKE OUTSTR MOVEI R,-1(A5) ;GET Y AND X COORDINATES. MOVEI A,-1(A6) JUMPLE R,LSCALX ;MAKE SURE THEY ARE LEGAL. JUMPLE A,LSCALX CAMG R,GALASZ CAMLE A,GALASZ GOTO LSCALX SOJ R, IMUL R,GALASZ ;CONVERT TO A GALAXY INDEX. ADDI R,-1(A) ORM A13,GALAXY(R) ;SET QUADRANT DISPLAY FLAG. INVOKE LSCDSP ;TYPE QUADRANT CONTENTS. LSCALY: AOBJN A6,LSCALI MOVEI A,COMS09 ;SPURIOUS FORMATTING INVOKE ENDMSG AOBJN A5,LSCALO INVOKE LSCUND GOTO COMREQ LSCALX: MOVEI A,COMS10 ;SPECIAL CONTENTS FOR NON-EXISTANT QUADS. INVOKE OUTSTR GOTO LSCALY LSCUND: INVOKE LSCSPA ;TYPE 10 SPACES. INVOKE OUTSPC MOVEI A14,^D22 ;TYPE 22 MINUS SIGNS. MOVEI A,"-" INVOKE OUTCHR SOJG A14,.-2 GOTO NEWLIN LSCSPA: MOVEI A14,^D9 ;TYPE 9 SPACES. INVOKE OUTSPC SOJG A14,.-1 RETURN ;GALAXY MAP: GALMAP: MOVEI A,COMS11 ;TYPE DISPLAY TITLE. INVOKE ENDMSG INVOKE OUTSPC ;TYPE THE XCOORD IDENT LINE: MOVN A6,GALASZ MOVSI A6,(A6) GALLP1: MOVEI A,COMS10 INVOKE OUTSTR INVOKE GALINT AOBJN A6,GALLP1 INVOKE NEWLIN MOVE A5,YQUAD ;COMPUTE INDEX TO CURRENT QUADRANT. SOJ A5, IMUL A5,GALASZ ADD A5,XQUAD SOJ A5, MOVN A6,GALASZ ;SETUP OUTER LOOP CONTROL. HRLZ A6,A6 GALLP2: INVOKE GALINT INVOKE OUTSPC MOVEI A7,(A6) ;SETUP INNER LOOP CONTROL. IMUL A7,GALASZ MOVN T,GALASZ HRL A7,T GALLP3: INVOKE OUTSPC ;INNER MAP LOOP: MOVEI R,(A7) ;TYPE A SPACE. MOVEI A,GALUKN SKIPGE GALAXY(R) ;(FUDGE UNKNOWN QUADRANTS) MOVEI A,LSCDSP INVOKE (A) ;TYPE QUADRANT CONTENTS. MOVEI A," " ;TYPE EITHER " " OR "E" DEPENDING CAIN A5,(A7) ;ON THE LOCATION OF THE ENTERPRISE. MOVEI A,"E" INVOKE OUTCHR AOBJN A7,GALLP3 INVOKE NEWLIN AOBJN A6,GALLP2 GOTO COMREQ GALUKN: MOVEI A,COMS12 ;TYPE CONTENTS OF AN UNKNOWN QUADRANT. GOTO OUTSTR GALINT: MOVEI R,1(A6) ;TYPE A TWO DIGIT INTEGER. CAIGE R,^D10 INVOKE OUTSPC MOVEI A,1(A6) GOTO OUTINT ;PHASER FIRE: FIRPHA: TRNE F,HYPFLG ;MAKE SURE NOT IN HYPERSPACE. GOTO SSCREJ MOVEI A,PHACOD ;CHECK FOR DAMAGE. MOVEI R,1 INVOKE DAMCHK GOTO COMREQ MOVEI A,COMS13 ;TYPE COMMAND IDENTIFICATION. INVOKE ENDMSG MOVEI A,COMS14 ;GET BEARING TO FIRE. INVOKE ASKFOR INVOKE READ GOTO COMCAN MOVN A5,A ;CONVERT TO A UNIT VECTOR. JSP R,DCOS EXCH A5,A JSP R,DSIN MOVE A6,A PHAENG: MOVEI A,COMS15 ;GET THE ENERGY TO FIRE. INVOKE OUTSTR MOVE A,ENTVEC+ENERGY INVOKE OUTINT MOVEI A,COMS16 INVOKE ASKFOR INVOKE READ GOTO COMCAN JUMPL A,PHARID ;MAKE SURE ENERGY NOT NEGATIVE. FIXR R,A CAMLE R,ENTVEC+ENERGY GOTO PHALOW ;MAKE SURE ENT HAS SUFFICIENT ENERGY. MOVN R,R ADDM R,ENTVEC+ENERGY ;APPLY PHASER COST. MOVE A7,A MOVEI A11,ROMLNP ;INIT PHASER FIRE LOOP. GOTO PHASKP ;ENTER FIRING LOOP. PHALUP: MOVE A,A11 ;HIT ONLY VISIBLE OBJECTS. INVOKE VISION GOTO PHASKP MOVE T,XPOS(A11) ;COMPUTE VECTOR FROM ENT TO OBJ. MOVE T2,YPOS(A11) FSBR T,XPOS+ENTVEC FSBR T2,YPOS+ENTVEC MOVE T3,T ;COMPUTE THE 4TH POWER OF THE DISTANCE. MOVE T4,T2 FMPR T3,T3 FMPR T4,T4 FADR T3,T4 FMPR T3,T3 FMPR T,A5 ;COMPUTE PROJECTION OF DISPLACEMENT FMPR T2,A6 ;ON PHASER FIRE DIRECTION. FADR T,T2 FMPRI T,(25.0) FMPR T,A7 ;ENERGY HIT=(INNER PRODUCT OF BEARING AND FDVR T,T3 ;DISPLACEMENT)*25*ENERGY/DISTANCE**4. FIXR T,T JUMPLE T,PHASKP ;NO HIT IF IN WRONG DIRECTION. MOVE A,T MOVN A13,T ADDB A13,ENERGY(A11) ;COMPUTE NEW OBJECT ENERGY. INVOKE OUTINT ;TYPE HIT MESSAGE. MOVEI A,COMS17 INVOKE OUTSTR MOVE A,A11 INVOKE IDENT INVOKE NEWLIN CAIE A12,XCLCOD GOTO PHAKLL ;SPECIAL JUNK FOR EXCALIBUR HIT: JUMPLE A13,PHAXKL ;SPECIAL JUNK IF EXCALIBUR DESTROYED. SOSGE A14,XCLF3 ;SEND MESSAGE IF HIT # 1,2,3. GOTO PHASKP MOVEI A,COMS18 ;SEND FIRST PART OF MESSAGE. INVOKE OUTSTR MOVE A,XCLMSG(A14) ;GET APPROPRIATE SECOND PART. INVOKE ENDMSG ;SEND IT. GOTO PHASKP PHAXKL: MOVEI A,COMS18 ;SEND SPECIAL EXCALIBUR-DESTRUCTION MESSAGE. INVOKE OUTSTR MOVEI A,COMS22 INVOKE ENDMSG TRO F,XCLDST+XCLDBE ;TELL AUTHORITIES WHO DID IT. PHAKLL: JUMPG A13,PHASKP ;SKIP FOLLOWING IF OBJ NOT DESTROYED. MOVE T,LINK(A11) ;REMOVE OBJECT FROM THE OBJECT LIST. HRRM T,LINK(A10) MOVE A,A11 ;REPORT OBJECT DESTROYED. INVOKE REPORT MOVE A11,A10 ;FUDGE ADDRESS CURRENT OBJ FOR LOOP CONTROL. PHASKP: MOVE A10,A11 ;CONSIDER HITTING NEXT OBJECT: HRRZ A11,LINK(A10) ;LOCATE NEXT OBJECT. HLRZ A12,TYPE(A11) ;FIND OUT WHAT IT IS. CAIN A12,FDGCOD ;IGNORE FUDGE ITEMS. GOTO PHASKP CAIE A12,ROMCOD ;KEEP FIRING AS LONG AS CAIN A12,KLGCOD ;THE OBJECT IS A ROMULAN, GOTO PHALUP ;KLINGON, OR THE EXCALIBUR. CAIN A12,XCLCOD GOTO PHALUP GOTO COMREQ PHARID: MOVEI A,COMS05 ;ENERGY TO FIRE IS NEGATIVE. PHARDX: INVOKE ENDMSG GOTO PHAENG PHALOW: MOVEI A,COMS23 ;TOO MUCH ENERGY REQUESTED. GOTO PHARDX ;ALTERNATE PHASER FIRE: ALTPHA: TRNE F,HYPFLG ;MAKE SURE NOT IN HYPERSPACE. GOTO SSCREJ MOVEI A,PHACOD ;CHECK FOR DAMAGE. MOVEI R,1 INVOKE DAMCHK GOTO COMREQ MOVEI A,COMS13 ;TYPE COMMAND IDENTIFICATION. INVOKE ENDMSG ALPTGT: MOVEI A,COMS24 ;GET LOCATION TO HIT. INVOKE ASKFOR INVOKE READPR GOTO COMCAN INVOKE COMCRD ;MAKE SURE COORDINATES ARE IN QUADRANT. GOTO ALPOTQ MOVE A5,XPOS+ENTVEC ;COMPUTE THE VECTOR FROM THE MOVE A6,YPOS+ENTVEC ;ENTERPRISE TO THE TARGET. FSBRB A,A5 FSBRB R,A6 INVOKE SQUMS CAMG A,ALPTCL ;IF ITS MAGNITUDE IS TOO SMALL, GOTO ALPABS ;ASSUME ATTEMPT TO HIT THE ENTERPRISE. FDVR A5,A ;CONVERT TO UNIT VECTOR. FDVR A6,A GOTO PHAENG ALPOTQ: MOVEI A,COMS25 ALPOTX: INVOKE ENDMSG GOTO ALPTGT ALPABS: MOVEI A,COMS05 GOTO ALPOTX COMCRD: FIXR T,R ;SEE IF COORDINATES NOT IN QUADRANT. FIXR T2,A JUMPLE T,COMCRT JUMPLE T2,COMCRT CAIG T,QADSIZ CAILE T2,QADSIZ COMCRT: RETURN AOS (P) RETURN ALPTCL: 0.2 ;MINIMUM DISTANCE FROM ENTERPRISE TO TARGET. ;PHOTON TORPEDO FIRE: ;NORMAL FIRE (AT A GIVEN ANGLE) FIRTRP: INVOKE FRTINT ;GET ALL INFO REQUIRED BUT THE BEARINGS. FIRTL1: MOVEI A,COMS34 ;ASK FOR A BEARING. INVOKE OUTSTR MOVEI A,(A5) ;GIVE TORPEDO NUMBER. INVOKE OUTINT MOVEI A,COMS35 INVOKE ASKFOR INVOKE READ ;GET THE BEARING. GOTO COMCAN INVOKE ANGROP ;REDUCE IT TO A SMALL ANGLE. INVOKE FLOPAK ;PACK IT INTO A HALF WORD. HRRZM A,TRPREQ-1(A5) ;SAVE WITH BEARING FLAG IN REQUEST LIST. AOBJN A5,FIRTL1 ;REPEAT FOR REST OF SPREAD. TRPMRG: ADDM A6,TRPRNM ;RESET FIRE COUNT. GOTO COMREQ ;REQUEST NEXT COMMAND. ;ALTERNATE TORPEDO FIRE (ON A GIVEN POSITION) ALTORP: INVOKE FRTINT ;GET ALL INFO REQUIRED BUT TARGETS. FIRTL2: MOVEI A,COMS36 ;ASK FOR TARGET LOCATION. INVOKE OUTSTR MOVEI A,(A5) ;GIVE A TORPEDO NUMBER. INVOKE OUTINT MOVEI A,COMS35 INVOKE ASKFOR INVOKE READPR ;GET THE TARGET LOCATION. GOTO COMCAN INVOKE COMCRD ;MAKE SURE TARGET IS IN THIS QUADRANT. GOTO FRTAB2 MOVE A7,R ;PACK THE X AND Y COORDINATES INTO INVOKE FLOPAK ;ONE WORD. SINCE THE LEFT HALF WORD EXCH A7,A ;(THE X COORDINATE) CAN'T BE ZERO, INVOKE FLOPAK ;IT CAN'T BE MISTAKEN FOR A BEARING HRL A,A7 ;TORP FIRE REQUEST. MOVEM A,TRPREQ-1(A5) ;SAVE IN TORP REQUEST LIST. AOBJN A5,FIRTL2 ;REPEAT FOR REST OF SPREAD. GOTO TRPMRG FRTAB2: MOVEI A,COMS05 ;REJECT POSITIONS NOT IN QUADRANT. INVOKE ENDMSG GOTO FIRTL2 CCTORP: INVOKE CANTRP ;THE TORP CANCEL COMMAND WAS IMPLEMENTED GOTO COMREQ ;FOR RICH LOETHER, WINNER OF THE 1975 "WHAT ;I'D LIKE YOUR PROGRAM TO DO" AWARD. ;TORPEDO COMMAND INITIALIZATION SUBROUTINE. ;A5=-#TO FIRE,,#OF FIRST TO FIRE; A6=#TO FIRE. FRTINT: RESTORE DISMAT ;POP STACK UP ONE LEVEL IN CASE NO RETURN. TRNE F,HYPFLG ;MAKE SURE NOT IN HYPERSPACE. GOTO SSCREJ MOVE A5,TRPNUM ;MAKE SURE THERE ARE TORPS LEFT. ADD A5,TRPRNM ;CONSIDER PENDING REQUESTS. CAILE A5,TRPMAX GOTO FRTREJ MOVEI A,PHTCOD ;CHECK FOR DAMAGE. MOVEI R,1 INVOKE DAMCHK GOTO COMREQ MOVEI A,COMS30 ;TYPE COMMAND IDENTIFICARION. INVOKE ENDMSG FRTAR1: MOVEI A,COMS31 ;ASK FOR NUMBER OF TORPS TO FIRE. INVOKE OUTSTR MOVEI A,TRPMAX+1 SUB A,A5 MOVE A6,A ;(HERE WE TYPE THE NUMBER AVAILABLE) INVOKE OUTINT MOVEI A,COMS32 INVOKE ASKFOR INVOKE READ ;GET THE NUMBER TO FIRE. GOTO COMCAN FIXR A,A JUMPE A,COMREQ JUMPL A,FRTAB1 ;THE NUMBER TO FIRE MUST NOT BE NEGATIVE. CAMLE A,A6 ;IT MUST NOT EXCEED THE NUMBER AVAILABLE. GOTO FRTAB1 MOVE A6,A MOVN A,A HRL A5,A GOTO @DISMAT ;RETURN TO CALLER. FRTAB1: MOVEI A,COMS05 INVOKE ENDMSG ;TYPE THE ABSURD MESSAGE. GOTO FRTAR1 FRTREJ: MOVEI A,COMS33 GOTO COMHLX ;TYPE THE EXPENDED MESSAGE. ;PULSIVE BEAM ACTIVATION: PULSIV: MOVEI A,COMS40 ;CURRENTLY NOT IMPLEMENTED. GOTO COMHLX ;TRAVEL FOR SOME STARMINUTES WITHOUT A COMMAND REQUEST. TRAVEL: MOVEI A,COMS45 INVOKE ASKFOR ;ASK FOR TRAVEL TIME (IN STARMINUTES). INVOKE READ GOTO COMCAN FIXR A,A JUMPLE A,COMREQ ;IF TIME<0, DON'T TRAVEL. MOVEM A,TRVLTM ;ELSE SET COMMAND REQUEST SUPPRESSION GOTO ACTION ;COUNT AND BEGIN THE JOURNEY. ;STATUS REPORT: STATUS: MOVEI A,COMS50 ;TYPE NUMBER OF DAYS LEFT. INVOKE OUTSTR MOVE A,TIMLIM INVOKE OUTDAT MOVEI A,COMS51 ;TYPE ENERGY LEFT. INVOKE OUTSTR MOVE A,ENTVEC+ENERGY INVOKE OUTINT INVOKE NEWLIN INVOKE OUTQAD ;TYPE THE CURRENT QUADRANT. MOVEI A,COMS55 INVOKE OUTSTR ;TYPE POSITION IN QUADRANT. MOVE A,YPOS+ENTVEC INVOKE OUTF.1 INVOKE OUTCOM MOVE A,XPOS+ENTVEC INVOKE OUTF.1 INVOKE NEWLIN MOVEI A,ENTVEC INVOKE SPEED ;IF THE ENTERPRISE'S SPEED IS NOT CAMG A,ZERO GOTO STASK1 ;ZERO, TYPE THE SPEED AND BEARING. MOVE A14,A MOVEI A,COMS52 INVOKE OUTSTR MOVE A,A14 INVOKE OUTF.2 MOVEI A,COMS53 INVOKE OUTSTR MOVEI A,ENTVEC INVOKE BERING INVOKE OUTINT INVOKE NEWLIN STASK1: SKIPN NUMKLG ;TYPE THE NUMBER OF KLINGONS LEFT. GOTO STASK2 MOVEI A,COMS54 INVOKE OUTSTR MOVE A,NUMKLG INVOKE OUTINT SKIPN NUMROM GOTO STASK3 MOVEI A,11 ;TYPE # OF ROMULANS (IF ANY). INVOKE OUTCHR STASK2: MOVEI A,COMS56 INVOKE OUTSTR MOVE A,NUMROM INVOKE OUTINT STASK3: INVOKE NEWLIN GOTO COMREQ ;DAMAGE REPORT: REPDAM: INVOKE DAMLST GOTO COMREQ ;RAISE DEFLECTORS: RASDEF: MOVEI A,COMS60 ;TYPE COMMAND IDENTIFICATION. INVOKE OUTSTR MOVE A,ENERGY+ENTVEC INVOKE OUTINT MOVEI A,")" INVOKE OUTCHR INVOKE NEWLIN MOVE A11,ENERGY+ENTVEC MOVSI A12,-4 RASLP1: MOVEI A,COMS61 ;TYPE "ENERGY FOR DEFLECTOR X = XXX ADD?" INVOKE OUTSTR MOVEI A,1(12) ADDI A,"0" INVOKE OUTCHR MOVEI A,COMS62 INVOKE OUTSTR MOVE A,SHIELD(A12) INVOKE OUTINT MOVEI A,COMS63 INVOKE ASKFOR INVOKE READ ;GET THE ENERGY. GOTO COMCAN FIXR A,A JUMPL A,RASER1 ;MAKE SURE IT IS NOT NEGATIVE AND CAMLE A,A11 ;DOES NOT EXCEED AVAILABLE ENERGY. GOTO RASER2 MOVEM A,A5(A12) ;SAVE THE ADDITION TO THE SHIELD. SUB A11,A ;UPDATE THE AVAILABLE ENERGY. AOBJN A12,RASLP1 ;REPEAT FOR ALL SHIELDS. MOVEI A12,3 RASLP2: MOVE T,A5(A12) ;PUT THE REQUESTED ENERGY INTO THE SHIELDS. ASH T,1 ;DOUBLE IT BEFORE ADDITION. ADDM T,SHIELD(A12) SOJGE A12,RASLP2 MOVEM A11,ENERGY+ENTVEC ;CHARGE FOR THIS. GOTO COMREQ RASER1: MOVEI A,COMS64 ;NEGATIVE ENERGY. RESERX: INVOKE ENDMSG GOTO RASLP1 RASER2: MOVEI A,COMS65 ;TO MUCH ENERGY REQUESTED. GOTO RESERX ;DROP DEFLECTORS: DRPDEF: MOVEI A,COMS69 ;CONFIRM THE ACTION. INVOKE ENDMSG INVOKE DFDOWN GOTO COMREQ DFDOWN: CLEAR T, ;SUBROUTINE TO DROP SHIELDS WITHOUT PENALTY. MOVEI T2,3 DRPLUP: ADD T,SHIELD(T2) ;ADD UP THE SHIELD ENERGIES. CLEARM SHIELD(T2) SOJGE T2,DRPLUP ASH T,-1 ;ADD HALF TO THE ENTERPRISE ENERGY. ADDM T,ENTVEC+ENERGY RETURN ;SET TIMING CHARACTER SETPRD: MOVEI A,COMS80 ;REQUEST THE NEW VALUE. INVOKE ASKFOR INVOKE READ GOTO COMCAN FIXR A,A MOVEM A,PERIOD ;SET IT. GOTO COMREQ ;NO-COMMAND LIMITATION. NOCCOM: INVOKE NOSUPP ;MAKE SURE NEXT MESSAGE GETS THROUGH. MOVEI A,COMS82 ;WHEN TOO MANY STARMINUTES PASS INVOKE ENDMSG ;WITHOUT COMMAND INPUT, WE STOP THE GAME INVOKE BRKOUT ;AND REQUEST A MONITOR CONTINUE COMMAND. EXIT 1, MOVEI T,NOCLIM ;RESET THE NO-COMMAND LIMIT COUNT. MOVEM T,NOCCNT GOTO COMREQ ;RESUME THE GAME COMHLP: MOVEI A,COMS98 ;TYPE THE HELP MESSAGE. COMHLX: INVOKE ENDMSG ;(LOTS OF PEOPLE JUMP HERE) GOTO COMREQ COMCAN: MOVEI A,COMS99 ;TYPE THE CANCELLATION MESSAGE. GOTO COMHLX COMWHT: MOVEI A,COMS97 ;TYPE CONFUSION MESSAGE. GOTO COMHLX ;REQUEST TRUCE: REQTRC: MOVEI A,COMS70 ;NOT YET IMPLEMENTED. GOTO COMHLX ;SHORT RANGE TRACK: SHRTRK: TRNE F,HYPFLG ;MAKE SURE NOT IN HYPERSPACE. GOTO SSCREJ MOVEI A,SSCCOD ;CHECK FOR DAMAGE. MOVEI R,1 INVOKE DAMCHK GOTO COMREQ MOVEI A,COMS75 ;TYPE COMMAND IDENTIFICATION. INVOKE ENDMSG HRRZ A5,LINK+ROMLNP SHRLUP: HLRZ A7,TYPE(A5) ;IGNORE FUDGES. CAIN A7,FDGCOD GOTO SHRLND MOVE A,A5 ;CHECK FOR OBJECT VISIBILITY. INVOKE VISION ;(LIST VISIBLE OBJECTS ONLY) GOTO SHRLND MOVE A,A5 ;TYPE OBJECT NAME AND LOCATION. INVOKE IDENT MOVEI A,COMS76 ;TYPE THE OBJECTS SPEED. INVOKE OUTSTR MOVE A,A5 INVOKE SPEED MOVE A6,A INVOKE OUTF.2 CAMG A6,ZERO ;IF THE OBJECT'S SPEED IS ZERO, GOTO SHRENG ;IT HAS NO BEARING. MOVEI A,COMS77 ;ELSE TYPE ITS BEARING. INVOKE OUTSTR MOVE A,A5 INVOKE BERING INVOKE OUTINT SHRENG: MOVEI A,COMS78 ;TYPE THE OBJECTS ENERGY. INVOKE OUTSTR MOVE A,ENERGY(A5) INVOKE OUTINT INVOKE NEWLIN SHRLND: HRRZ A5,LINK(A5) JUMPN A5,SHRLUP GOTO COMREQ ;SAVE THE CURRENT GAME. SAVGAM: MOVEM F,FLGSAV ;PUT THE FLAGS WHERE THEY CAN BE SAVED. MOVE T,VERPAT ;PUT THE VERSION WHERE IT CAN BE SAVED. MOVEM T,IMGCOM MOVEI A,COMS85 ;CONFIRM COMMAND IDENTITY. INVOKE ENDMSG SAVRTY: MOVEI A,DISMAT ;LOCATE OPEN AND ENTER ARG BLOCKS. MOVEI R,SAVDSK ;LOCATE DEFAULT ARG BLOCK CONTENTS. INVOKE FILINF ;GET FILE SPEC. GOTO COMCAN ;TTY EOF RETURNS HERE. OPEN IOCHAN,DISMAT ;OPEN THE OUTPUT DEVICE. GOTO SAVOPE ;OPEN ERROR RETURNS HERE. ENTER IOCHAN,DISMAT+3 ;ENTER THE OUTPUT FILE. GOTO SAVENE ;ENTER ERROR RETURNS HERE. MOVEI T,GAMDAT-GALAXY ;PUT DUMP COMMAND LIST INTO LOW SEG. SUB T,GALAS2 ;USE ACTUAL GALAXY SIZE WHEN FIGURING MOVS T,T ;OUT THE FILE LENGTH. HRRI T,GAMDAT-1 MOVEM T,DISMAT CLEARM DISMAT+1 OUT IOCHAN,DISMAT ;DUMP THE GAME DATA. GOTO SAVEND ;HERE IF NO OUTPUT ERROR. MOVEI A,COMS86 ;HERE IF OUTPUT ERROR OCCURED. SKIPA SAVENE: MOVEI A,COMS88 ;LOCATE ERROR MESSAGE. INVOKE ENDMSG ;TYPE IT. RESDV. IOCHAN, ;CLEAR THE I/O CHANNEL. NOOP ;MAY GIVE AN ERROR RETURN. GOTO SAVRTY ;TRY AGAIN. SAVEND: RELEASE IOCHAN, ;CLOSE THE FILE. MOVEI A,SAV%TC ;RECORD THE CURRENT SCORE. INVOKE SCORE INVOKE RATCMP ;TYPE THE RATINGS. INVOKE RATYPE GOTO NEWGAM ;CONSIDER A NEW GAME.. SAVOPE: MOVEI A,COMS87 ;TYPE OPEN ERROR MESSAGE. INVOKE ENDMSG GOTO SAVRTY ;RETRY THE GAME SAVE. SAVDSK: .IODPR ;I/O MODE = DUMP AS RECORDS. SIXBIT /DSK/ ;DEFAULT DEVICE = DISK. 0 ;THERE ARE NO BUFFER HEADERS. EXP 0,0,0 ;THE LOOKUP BLOCK DEFAULT ARE ZILCH. VERPAT: +VERCOM ;THE GAME IMAGE VERSION. SAVWRD: IOWD DATLEN,GAMDAT ;SAVE/RESTORE DUMP COMMAND. SAVWRC: MOVE T,SAVWRD ;CALL HERE TO CREATE A DUMP MOVEM T,DISMAT ;COMMAND LIST TO COPY THE CLEARM DISMAT+1 ;GAME DATA AREA. RETURN ;RESTORE THE CURRENT GAME: RESGAM: MOVEI A,COMS89 ;CONFIRM COMMAND IDENTITY. INVOKE ENDMSG RESRTY: MOVEI A,DISMAT ;LOCATE OPEN AND LOOKUP ARG BLOCKS. MOVEI R,SAVDSK ;LOCATE DEFAULT ARG BLOCK CONTENTS. INVOKE FILINF ;GET THE FILE SPEC. GOTO RESCAN ;CANCEL ON TTY EOF. OPEN IOCHAN,DISMAT ;OPEN THE INPUT DEVICE. GOTO RESOPE ;OPEN ERROR RETURNS HERE. LOOKUP IOCHAN,DISMAT+3 ;LOOKUP THE INPUT FILE. GOTO RESLKE ;LOOKUP ERROR RETURNS HERE. MOVE T,INIDA2 ;IF THE GAME WAS CREATED JUST SUB T,TIMLIM ;TO ISSUE A RESTORE COMMAND, CAIG T,^D10 ;DON'T BOTHER TO SCORE IT. GOTO RESNSC MOVEI A,RES%TC ;SET THE RESTORE TERMINATION CODE. INVOKE SCORE ;RECORD THE CURRENT SCORE. RESNSC: CLEARM GALASZ ;DISABLE THIS GALAXY. CLEARM .JBINT ;PERMIT ^C'S. INVOKE SAVWRC ;CREATE THE RESTORE DUMP COMMAND LIST. INPUT IOCHAN,DISMAT ;RESTORE THE OLD GAME. MOVE T2,IMGCOM ;GET THE SAVE FILE VERSION. CAME T2,VERPAT ;IF THE VERSION CODE IS WRONG, GOTO RESERR ;REJECT THE GAME SAVE FILE. STATO IOCHAN,74B23 GOTO RESEND ;HERE IF READ OK. SKIPA A,[COMS86] ;HERE IF INPUT ERROR. RESLKE: MOVEI A,COMS88 ;LOCATE LOOKUP ERROR MESSAGE. RESLKX: INVOKE ENDMSG ;TYPE IT. RESDV. IOCHAN, ;CLEAR THE I/O CHANNEL. NOOP ;MAY GIVE AN ERROR RETURN. GOTO RESRTY ;RETRY THE GAME RESTORE. RESEND: RELEASE IOCHAN, HRR F,FLGSAV ;RESTORE THE GAME FLAGS. HRLZ T,NUMKLG ;SAVE SOME VALUES NEEDED HRR T,NUMROM ;WHEN THE SCORE IS REPORTED. MOVEM T,NUMKL2 MOVE T,TIMLIM MOVEM T,INIDA2 INVOKE CCTRPI ;RESET THE ^C TRAP. AOS RESCNT ;KEEP TRACK OF GALAXY RESTORATIONS. GOTO COMREQ ;RESUME THE GAME. RESERR: CLEARM GALASZ ;IF BAD VERSION, ZAPP THE GALAXY. MOVEI A,COMS90 ;TELL THE CAPTAIN. GOTO RESLKX RESOPE: MOVEI A,COMS87 ;TYPE OPEN ERROR MESSAGE. GOTO RESLKX ;AND RETRY THE RESTORE. RESCAN: SKIPE GALASZ ;WE CANNOT CANCEL UNTIL GALASZ GOTO COMCAN ;SHOWS A CREATED GALAXY. MOVEI A,COMS91 ;TELL THE CAPTAIN. INVOKE ENDMSG GOTO NEWGAM COMS00: ASCIZ /* / COMS01: ASCIZ /NEW BEARING? / COMS02: ASCIZ /WARP FACTOR? / COMS03: ASCIZ /** HIGH WARP CHANGE **/ COMS04: ASCIZ /** EMERGENCY WARP CHANGE **/ COMS05: ASCIZ /DON'T BE ABSURD./ COMS06: ASCIZ /IMPOSSIBLE - HYPERSPACE!/ COMS07: ASCIZ /LONG RANGE SENSOR SCAN AROUND / COMS08: ASCIZ / : / COMS09: ASCIZ / :/ COMS10: ASCIZ / / COMS11: ASCIZ /GALACTIC UPDATE:/ COMS12: ASCIZ / ?? / COMS13: ASCIZ /** ENERGIZE PHASERS **/ COMS14: ASCIZ /BEARING? / COMS15: ASCIZ /ENERGY? (AVAILABLE=/ COMS16: ASCIZ /) / COMS17: ASCIZ / UNIT HIT ON / COMS18: ASCIZ /*--- INTRAQUADRANT MESSAGE FROM THE EXCALIBUR ---* / COMS19: ASCIZ /YOU HOMICIDAL MANIAC! I'M GONNA GIVE YOU YOURS!/ COMS20: ASCIZ /OUCH! WATCH IT, YOU INCOMPETANT BOOB./ COMS21: ASCIZ /BE MORE CAREFUL NEXT TIME./ COMS22: ASCIZ /EEEEEEYYYYAAAAAAAAAAAGGGHH!/ XCLMSG: EXP COMS19,COMS20,COMS21 COMS23: ASCIZ /THAT IS TOO MUCH ENERGY./ COMS24: ASCIZ /TARGET COORDINATES? / COMS25: ASCIZ /TARGET NOT IN QUADRANT./ COMS30: ASCIZ /** TORPEDO ROOM READY **/ COMS31: ASCIZ /NUMBER TO FIRE? (/ COMS32: ASCIZ / AVAILABLE) / COMS33: ASCIZ /**CANCELLED** PHOTON TORPEDOES EXPENDED/ COMS34: ASCIZ /BEARING FOR TORPEDO / COMS35: ASCIZ /? / COMS36: ASCIZ /TARGET FOR TORPEDO / COMS40: ASCIZ "**CANCELLED** THE PULSIVE BEAMS ARE DAMAGED. THE REPLACEMENT PART (NUMBER A786274915B3R-X -- 6-32*1/4 MACHINE SCREW) WILL NOT BE AVAILABLE UNTIL THE NEXT FISCAL YEAR." COMS45: ASCIZ /TRAVEL TIME IN STARMINUTES? / COMS47: ASCIZ /*--- INTRAQUADRANT MESSAGE FROM THE GLORIOUS ENEMY ---* ** SURPRISE ** YOU CAN'T SNEAK UP ON ME./ COMS50: ASCIZ /STATUS REPORT: DAYS LEFT: / COMS51: ASCIZ / ENERGY: / COMS52: ASCIZ /SPEED: / COMS53: ASCIZ / BEARING: / COMS54: ASCIZ /KLINGONS LEFT: / COMS55: ASCIZ / POSITION: / COMS56: ASCIZ /ROMULANS LEFT: / COMS60: ASCIZ /RAISE DEFLECTORS: (ENERGY=/ COMS61: ASCIZ /ENERGY FOR DEFLECTOR / COMS62: ASCIZ / = / COMS63: ASCIZ / ADD?? / COMS64: ASCIZ /NEGATIVE ENERGY ADDITIONS ARE NOT PERMITTED./ COMS65: ASCIZ /YOU DON'T HAVE THAT MUCH ENERGY./ COMS69: ASCIZ /DEFLECTORS DROPPED/ COMS70: ASCIZ /COMMUNICATIONS DECLINED./ COMS75: ASCIZ /SHORT RANGE TRACK:/ COMS76: ASCIZ / SPEED: / COMS77: ASCIZ / BEARING: / COMS78: ASCIZ / ENERGY: / COMS80: ASCIZ /ENTER NEW TIMING CHARACTER ASCII CODE IN DECIMAL: / COMS82: ASCIZ /I SUSPECT YOU OF DERELICTION OF DUTY! TYPE "CONTINUE" TO RESUME GAME./ COMS85: ASCIZ /** ENERGIZE GAME SAVERS **/ COMS86: ASCIZ "?I/O ERROR" COMS87: ASCIZ /?UNABLE TO OPEN REQUESTED DEVICE/ COMS88: ASCIZ /?UNABLE TO ACCESS REQUESTED FILE/ COMS89: ASCIZ /** ENERGIZE GAME RESTORERS **/ COMS90: ASCIZ /RESTORED GAME IS NOT COMPATIBLE WITH THIS VERSION!/ COMS91: ASCIZ /%GAME NOT RESTORED/ COMS93: ASCIZ / GALAXY SIZE? / COMS94: ASCIZ / ?ENTER GALAXY SIZE (1 TO 10) TO CREATE THE GALAXY OR THE RESTORE COMMAND (19) TO RESTORE AN OLD GAME./ COMS97: ASCIZ /WHAT??/ COMS99: ASCIZ /**** CANCELLED ****/ COMS98: ASCIZ / COMMANDS: 1 - WARP CHANGE 2 - SHORT RANGE SCAN 3 - LONG RANGE SCAN 4 - FIRE PHASERS 5 - FIRE PHOTON TORPEDOES 6 - ENERGIZE PULSIVE BEAMS 7 - TRAVEL 8 - STATUS REPORT 9 - DAMAGE REPORT 10 - HIGH WARP CHANGE 11 - EMERGENCY WARP CHANGE 12 - RAISE DEFLECTORS 13 - DROP DEFLECTORS 14 - ATTEMPT COMMUNICATIONS 15 - SHORT RANGE TRACK 16 - GALACTIC MAP 17 - SET TIMING CHARACTER 18 - SAVE GAME 19 - RESTORE GAME 20 - CANCEL PENDING TORPEDO LAUNCHES 44 - FIRE PHASERS AT TARGET 55 - FIRE TORPEDOES AT TARGET ^Z - CANCEL COMMAND ^C - SURRENDER/ SUBTTL **** THE FAST AND FURIOUS ACTION **** ACTION: TTCALL 1,PERIOD ;OUTPUT A TIMING CHARACTER. TLO F,(LFQFLG) ;INDICATE TIMING CHARACTER OUTPUT. SOSGE NOCCNT ;LIMIT THE NUMBER OF STARMINUTES GOTO NOCCOM ;WITHOUT COMMAND INPUT. SOSGE A14,ACCTIM ;TEST FOR ACCELERATION REQUEST. GOTO HYPCHK ;(THIS SKIPS ACCELERATION) MOVN T2,EPACST ;GET THE ACCELERATION COST. ADDM T2,ENTVEC+ENERGY;DEDUCT IT FROM THE ENTERPRISE ENERGY. MOVE T3,ENTVEC+XACC ;INCREMENT THE ENTERPRISE VELOCITY. MOVE T4,ENTVEC+YACC FADRM T3,ENTVEC+XVEL FADRM T4,ENTVEC+YVEL TRC F,DSHFLG+HYPFLG ;CONSIDER A HYPERSPACE CHANGE. TRCE F,DSHFLG+HYPFLG TRNN F,DSHFLG+HYPFLG GOTO DESEND MOVE A,ENTVEC+XVEL ;COMPUTE THE SQUARE OF THE ENTERPRISES SPEED. MOVE R,ENTVEC+YVEL FMPR A,A FMPR R,R FADR A,R TRNN F,DSHFLG ;TEST FOR LEAVING HYPERSPACE. CAML A,ONE GOTO H204 TRZ F,HYPFLG ;INDICATE NOT IN HYPERSPACE. MOVEI A,ACCMS3 INVOKE ENDMSG TRO F,LHPFLG ;SET LEAVING HYPERSPACE FLAG. H204: TRNE F,DSHFLG ;TEST FOR ENTERING HYPERSPACE. CAMG A,HYPLIM GOTO DESEND TRO F,HYPFLG ;INDICATE NOW IN HYPERSPACE. MOVEI A,ACCMS4 INVOKE ENDMSG INVOKE CANTRP DESEND: JUMPG A14,HYPCHK ;SKIP FOLLOWING IF MORE ACCELERATION NEEDED. TRZN F,SPCFLG ;TEST FOR SPEED CHANGE REQUEST. GOTO H201 ;(SKIP FOLLOWING IF NO REQUEST) MOVEI A,ACCMS1 INVOKE OUTSTR MOVE A,DSPEED INVOKE OUTF.3 MOVEI A,HABEOB INVOKE ENDMSG H201: TRZN F,BRCFLG ;TEST FOR BEARING CHANGE REQUEST. GOTO HYPCHK ;(SKIP FOLLOWING IF NO REQUEST) MOVEI A,ACCMS2 INVOKE OUTSTR MOVE A,DBERNG INVOKE OUTF.0 MOVEI A,HABEOB INVOKE ENDMSG HYPCHK: TRNN F,HYPFLG GOTO LHPCHK MOVEI A,ENTVEC ;IF IN HYPERSPACE, MOVE THE INVOKE NUDGE ;ENTERPRISE. IF STILL IN OLD QUADRANT, GOTO TIMECK ;SKIP THE REMAINING ACTION. GALCHK: JUMPN T3,NEWQAD ;MAKE SURE THE NEW QUADRANT EXISTS. MOVEI A,POSMS5 ;THE ENTERPRISE LEAVES THE GALAXY! INVOKE ENDMSG MOVEI A,ENTVEC ;GET THE ENTERPRISE'S SPEED. INVOKE SPEED FMPRI A,(100.0) ;UNITS DAMAGE= SPEED*100. FIXR A,A INVOKE OUCH GOTO RESTRT NEWQAD: SAVE T3 ;SAVE THE NEW QUADRANT COORDINATES. SAVE T4 MOVEI A,POSMS1 INVOKE OUTSTR ;TYPE THE QUADRANT CHANGE MESSAGE. INVOKE OUTQAD INVOKE ENDLIN INVOKE CANTRP RESTORE YQUAD RESTORE XQUAD MOVEI A,POSMS2 INVOKE OUTSTR INVOKE OUTQAD INVOKE ENDLIN TRZ F,QSUFLG ;INDICATE QUADRANT NOT SET UP. MOVE A,ENTVEC+XPOS ;FIXUP OLD EP COORDINATES. INVOKE POSFIX MOVEM A,ENTVEC+XPOS MOVE A,ENTVEC+YPOS INVOKE POSFIX MOVEM A,ENTVEC+YPOS TRNE F,HYPFLG ;IF IN HYPERSPACE, GOTO TIMECK ;THEN SKIP REST OF ACTION, GOTO QADSET ;ELSE GOTO QUADRANT SETUP. POSFIX: CAMGE A,NFQADL ;FUDGE NUMBER INTO RANGE 0.5-10.5. FADRI A,(FQADSZ) CAMLE A,NFQADH FSBRI A,(FQADSZ) RETURN LHPCHK: TRZN F,LHPFLG ;CHECK IF AUTO SETUP-DISPLAY REQUIRED. GOTO POSCHK ;IF NOT, GOTO STANDARD ACTION. TRNN F,QSUFLG ;ELSE SETUP OR DISPLAY QUAD AS REQUIRED. GOTO QADSET TRO F,HASFLG ;IF QUAD ALREADY SET UP, THE USER GOTO QADISP ;MAY BE TRYING A HYPERSPACE ATTACK. ACCMS1: ASCIZ /A DESIRED SPEED OF / ACCMS2: ASCIZ /A DESIRED BEARING OF / HABEOB: ASCIZ / HAS BEEN OBTAINED./ ACCMS3: ASCIZ /LEAVING HYPERSPACE!/ ACCMS4: ASCIZ /ENTERING HYPERSPACE!/ HYPLIM: 0.9992 ;MINIMUM SPEED TO GET INTO HYPERSPACE. POSMS1: ASCIZ /LEAVING / POSMS2: ASCIZ /ENTERING / POSMS3: ASCIZ / EXCEEDS GALACTIC BOUNDRIES!/ POSMS4: ASCIZ / ESCAPED!/ POSMS5: ASCIZ /GALACTIC LIMITS EXCEEDED! SPACE-TIME WRINKLE!/ POSMS6: ASCIZ / TRAPPED IN INTERQUADRANT VORTEX!/ ;THE GRACEFUL MOTION: POSCHK: MOVEI A5,ROMLNP ;GET TOP OF MOVING OBJECT LIST. HRRZ A6,LINK(A5) POSLUP: HLRZ A7,TYPE(A6) ;FIND OUT WHAT KIND OF OBJECT WE HAVE. CAIN A7,FDGCOD ;IGNORE FAKE OBJECTS. GOTO POSLND MOVE A,A6 ;ELSE MOVE THE OBJECT. INVOKE NUDGE GOTO POSLND ;ALL DONE WITH OBJ IF STILL IN QUAD. CAIN A7,ENTCOD ;IF THE OBJECT IS THE ENTERPRISE, GOTO GALCHK ;FORGET ABOUT THIS QUADRANT. MOVE T,LINK(A6) ;ELSE REMOVE THE OBJECT FROM THE LIST. HRRM T,LINK(A5) EXCH A5,A6 CAIN A7,GHOCOD ;GHOSTS REQUIRE NO FURTHER ACTION. GOTO POSLND CAIE A7,ROMCOD CAIN A7,KLGCOD ;EVERYTHING ELSE REQUIRES GOTO KLGNUD ;OBJECT DEPENDENT ACTION. CAIN A7,XCLCOD GOTO XCLNUD ;TORPEDOES: MOVE T,TRPFRE ;PUT THE TORPEDO INTO THE FREE TORP LIST. HRRM T,LINK(A5) MOVEM A5,TRPFRE GOTO POSLND ;EXCALIBUR: XCLNUD: CLEARM XCALBR ;INDICATE EXCALIBUR NOT IN QUADRANT. GOTO POSLND ;KLINGONS AND ROMULANS: KLGNUD: MOVE A10,T3 ;SAVE NEW QUADRANT COORDINATES. MOVE A11,T4 MOVE A,A5 ;TYPE THE ENEMY IDENTITY. INVOKE IDENT JUMPN A10,POSESC ;TEST FOR OUT OF GALAXY. MOVEI A,POSMS3 ;ENEMY LEAVES THE GALAXY. GOTO POSKKK POSESC: MOVE R,A11 MOVE A,A10 MOVE A14,A7 INVOKE ADDQAD ;TRY TO ADD ENEMY TO NEW QUADRANT. GOTO POSKIV ;IF REJECTED, DESTROY IT. MOVEI A,POSMS4 ;ENEMY ESCAPED. INVOKE ENDMSG INVOKE REMCQD ;DEDUCT HIM FROM THE CURRENT QUADRANT. GOTO POSLND POSKIV: MOVEI A,POSMS6 ;ENEMY STUCK BETWEEN QUADRANTS. POSKKK: INVOKE ENDMSG MOVE A,A5 ;REPORT THE DESTRUCTION OF THE ENEMY. INVOKE REPORT POSLND: MOVE A5,A6 ;MOVE TO THE NEXT OBJECT IN THE LIST. HRRZ A6,LINK(A5) ;(IF IT EXISTS) JUMPN A6,POSLUP ;COLLISION CHECKS: ;(IN A NUTSHELL, TWO NESTED LOOPS ARE USED TO CHECK THE DISTANCES BETWEEN ;ALL PAIRS OF OBJECTS IN WHICH AT LEAST ONE IS MOVING. IT IS ASSUMED ;THAT THE ROMULAN POINTER BEGINS THE LIST OF MOVING OBJECTS.) MOVEI A5,ROMLNP ;GET TOP OF MOVING OBJECT LIST. HRRZ A6,LINK(A5) COLOLP: HLRZ A11,TYPE(A6) ;GET THE MOVING OBJECTS TYPE CODE. CAIN A11,FDGCOD ;IGNORE FAKE OBJECTS. GOTO COLOND MOVEI A7,STARP ;SET THE INNER LOOP CONTROL. HRRZ A10,LINK(A7) ;(GET TOP OF OBJECT LIST) COLILP: HLRZ A12,TYPE(A10) ;GET THE OTHER OBJECT TYPE CODE. CAIN A12,FDGCOD ;IGNORE FAKE OBJECTS. GOTO COLIND MOVE T,XPOS(A6) ;COMPUTE THE SQUARE OF THE FSBR T,XPOS(A10) ;DISTANCE BETWEEN THE OBJECTS: FMPR T,T MOVE T2,YPOS(A6) FSBR T2,YPOS(A10) FMPR T2,T2 FADR T,T2 CAML T,COLMAX ;IF THIS IS NOT LESS THAN THE MAXIMUM GOTO COLIND ;COLLISION RADIUS, TRY THE NEXT OBJECT PAIR. CAIL A11,TRPCOD ;CHECK FOR A TORP-TORP COLLISION: CAIGE A12,TRPCOD ;(THE RADIUS IS SMALLER) GOTO COLLID ;TRAP HERE IF NOT TORP-TORP CAML T,COLTIM ;MAKE SURE THE TORPS ARE WITHIN GOTO COLIND ;THE REQUIRED COLLISION RADIUS. MOVEI A,COLM01 ;TYPE THE TORP-TORP COLLISION MESSAGE. INVOKE ENDMSG INVOKE COLBTC ;REMOVE BOTH OBJECTS FROM THE OBJECT LIST. HRRM A10,LINK(A5) MOVE T,TRPFRE ;PUT BOTH OBJECTS INTO THE FREE TORP LIST. HRRM T,LINK(A10) MOVEM A5,TRPFRE GOTO COLOND ;CHECK OUT THE NEXT OBJECT PAIR. COLLID: CAMG T,COLLIM ;IF NOT WITHIN NORMAL COLLISION RADIUS, GOTO COLLD2 ;THIS MUST BE AN ENEMY/ENTERPRISE TORP CAIN A11,TRPCOD ;COLLISION (I SHOW FAVORITISM). CAIGE A12,ROMCOD GOTO COLIND COLLD2: CAIN A11,ENTCOD ;CHECK FOR ENTERPRISE COLLISIONS. GOTO @COLVEC(A12) ;THEY ARE SPECIAL. INVOKE COLBTC ;OTHERWISE, BOTH OBJECTS ARE DESTROYED. CAIGE A11,TRPCOD ;IF THE MOVING OBJECT IS NOT A TORPEDO, GOTO COLNOT ;(OTHER CAN'T BE ONE) GO TO DOUBLE COLLISION. MOVE T,TRPFRE ;FOR A TORP HIT, FIRST PUT THE TORP HRRM T,LINK(A5) ;INTO THE FREE TORP LIST. MOVEM A5,TRPFRE MOVEI A,COLM02 ;TYPE THE HIT MESSAGE. INVOKE OUTSTR INVOKE COLNAM GOTO COLDIN ;MERGE WITH DOUBLE COLLISION. COLNOT: MOVE A,NAMES(A11) ;TYPE THE COLLISION MESSAGE. INVOKE OUTSTR MOVEI A,COLM03 INVOKE OUTSTR INVOKE COLNAM MOVE A,A5 ;REPORT DESTRUCTION OF THE MOVING OBJECT. INVOKE REPORT COLDIN: MOVE A,A10 ;REPORT DESTRUCTION OF THE OTHER OBJECT. INVOKE REPORT GOTO COLOND ;CONSIDER NEXT COLLISION PAIR. COLNAM: MOVE A,NAMES(A12) ;MINOR SUBROUTINE TO FINISH INVOKE OUTSTR ;THE COLLISION MESSAGE. MOVEI A,"!" INVOKE OUTCHR GOTO NEWLIN COLBTC: MOVE T,LINK(A6) ;MINOR SUBROUTINE TO REMOVE HRRM T,LINK(A5) ;BOTH OBJECTS FROM THE OBJECT LIST. MOVE T,LINK(A10) HRRM T,LINK(A7) EXCH A5,A6 ;A FUDGE FOR THE OUTER LOOP CONTROL. CAMN A6,A10 ;WATCH OUT FOR OVERLAP! MOVE A6,A7 ;IN THIS CASE, A7 POINTS TO NEXT MOVING OBJ. RETURN COLVEC: EXP COLSTR,COLBAS,COLMOV,COLMOV ;ENTERPRISE COLLISION VECTOR. EXP COLMOV,COLGHO,COLXCL,COLTRP,COLTRP;(INDEX BY TYPE CODE) COLSTR: MOVEI A,CWS%TC ;COLLISION WITH STAR. GOTO ENDGAM ;(YOU LOSE) ;ENTERPRISE/TORPEDO COLLISION: COLTRP: CAML T,COLTEL ;REQUIRE A BETTER SHOT TO GOTO COLIND ;HIT THE BIG "E". MOVE A,ENERGY(A10) ;TYPE THE TORP HIT MESSAGE. INVOKE OUTINT MOVEI A,COLM07 INVOKE ENDMSG MOVE T,LINK(A10) ;REMOVE THE TORP FROM THE OBJECT LIST. HRRM T,LINK(A7) MOVE T,TRPFRE ;PUT THE TORP INTO THE FREE LIST. HRRM T,LINK(A10) MOVEM A10,TRPFRE MOVN A13,XVEL(A10) ;SHOOT UP THE ENTERPRISE. MOVN A14,YVEL(A10) MOVE A,ENERGY(A10) INVOKE SHLDHT GOTO COLNIX ;DOCKING WITH BASE: COLBAS: MOVEI A,ENTVEC ;POSSIBLE COLLISION WITH BASE. INVOKE SPEED ;GET THE ENTERPRISE SPEED. CAML A,BADMAX ;IF THIS EXCEEDS MAX BASE DOCKING SPEED, GOTO COLFIX ;WE HAVE COLLIDED WITH THE BASE. MOVEI A,COLM08 ;OTHERWISE WE HAVE DOCKED. INVOKE OUTSTR TRNE F,XCLDBE+XCEFLG GOTO COLBE1 ;TEST FOR ENTERPRISE DESTRUCTION OF EXCALIBUR MOVE T,XPOS+ENTVEC ;FIND A POSITION FOR THE ENTERPRISE FSBR T,XVEL+ENTVEC ;THAT IS OUTSIDE OF DOCKING RADIUS: FIXR T,T FLTR T,T MOVEM T,XPOS+ENTVEC MOVE T,YPOS+ENTVEC FSBR T,YVEL+ENTVEC FIXR T,T FLTR T,T MOVEM T,YPOS+ENTVEC INVOKE DOCSUB ;PERFORM STANDARD REFURBISHMENT. TROE F,DOCFLG ;IF WE HAVE ALREADY BEEN DOCKED GOTO QADISP ;SINCE LAST QUAD SETUP, THAT IS ALL. SKIPN PRBLMS ;ELSE WE WILL REPAIR SOME DAMAGE AND DEATHS. GOTO COLFAT ;DON'T REPAIR DAMAGE IF THERE IS NONE. MOVEI A,COLM09 INVOKE ENDMSG JSP R,RANDOM ;THE FIXUP TIME IS 20 STARMINUTES + MULI R,^D30 ;A RANDOM PART OF 30 STARMINUTES. MOVEI A14,^D20(R) INVOKE DAMFIX SOJG A14,.-1 COLFAT: MOVEI A14,TOTMEN ;COMPUTE NUMBER OF FATALITIES. SUB A14,MEN JUMPLE A14,QADISP ;IF THIS IS NOT POSITIVE, THERE ARE NO DEAD. JSP R,RANDOM ASH A14,-2 MUL R,A14 ADD R,A14 ;LET THE NUMBER OF REINFORCEMENTS BE MOVEI A,1(R) ; 1+FATALITIES*RANDOM/4+FATALITIES/4. ADDM A,MEN INVOKE OUTINT ;TYPE THE REINFORCEMENT MESSAGE: MOVEI A,COLM10 ;"XX REINFORCEMENTS -- CREW = XXX" INVOKE OUTSTR MOVE A,MEN INVOKE OUTINT INVOKE NEWLIN GOTO QADISP COLBE1: MOVEI A,XCP%TC ;PENALIZE FOR DESTRUCTION OF EXCALIBUR. TRNN F,XCLDBE MOVEI A,XCC%TC GOTO ENDGAM ;DOCKING WITH GHOST: COLGHO: MOVE A,XVEL+GHOST ;COMPUTE SPEED OF ENT RELATIVE TO GHOST. FSBR A,XVEL+ENTVEC MOVE R,YVEL+GHOST FSBR R,YVEL+ENTVEC INVOKE SQUMS CAML A,GODMAX ;IF THIS EXCEEDS THE MAX GHOST DOCKING GOTO COLMOV ;SPEED, WE HAVE COLLIDED WITH THE GHOST. MOVEI A,COLM13 ;ELSE WE HAVE DOCKED WITH IT. INVOKE ENDMSG MOVE T,LINK(A10) ;REMOVE THE GHOST FROM THE QUADRANT. HRRM T,LINK(A7) ;(I.E. THE OBJECT LIST) INVOKE CANTRP ;CANCEL TORPEDO LAUNCHES. INVOKE DFDOWN ;DROP SHIELDS. MOVE A,ENERGY(A10) ;GET THE GHOST'S ENERGY TO ADD A,ENTVEC+ENERGY ;GIVE TO THE ENTERPRISE. CAILE A,MAXEGY MOVEI A,MAXEGY ;THE TOTAL ENERGY IS LIMITED TO MAXEGY. MOVEM A,ENTVEC+ENERGY INVOKE OUTINT MOVEI A,COLM14 INVOKE OUTSTR JSP R,RANDOM ;GENERATE A NICE NUMBER OF TORPEDOES TO MULI R,TRPMAX/4 ;GIVE TO THE ENTERPRISE. THE FORMULA IS: MOVNI A,TRPMAX/4+1(R) ;TRPMAX/4+RANDOM*TRPMAX/4 ADD A,TRPNUM CAIG A,0 ;THE TOTAL NUMBER OF TORPEDOES IS MOVEI A,1 ;LIMITED TO TRPMAX. MOVEM A,TRPNUM MOVEI A,TRPMAX+1 SUB A,TRPNUM INVOKE OUTINT INVOKE NEWLIN MOVE A13,XVEL+GHOST ;MERGE WITH COLLISION SEQUENCE. MOVE A14,YVEL+GHOST GOTO COLVEL ;COLLISION MESSAGES: COLM01: ASCIZ /TORPEDO COLLISION WITH TORPEDO!/ COLM02: ASCIZ /TORPEDO HIT ON / COLM03: ASCIZ / COLLISION WITH / COLM04: ASCIZ /COLLISION WITH STAR!/ COLM05: ASCIZ /ENTERPRISE COLLISION WITH / COLM06: ASCIZ /SHIELDS DESTROYED!/ COLM07: ASCIZ / UNIT TORPEDO HIT ON ENTERPRISE!/ COLM08: ASCIZ /DOCKED!!/ COLM09: ASCIZ /TEMPORARY MAINTENANCE CREW BOARDED!/ COLM10: ASCIZ / REINFORCEMENTS -- CREW = / COLM11: ASCIZ /YOU HAVE BEEN ARRESTED FOR THE DESTRUCTION OF GOVERNMENT PROPERTY (THE EXCALIBUR)!/ COLM12: ASCIZ /YOU HAVE BEEN RELIEVED OF YOUR COMMAND FOR DERELICTION OF DUTY (THE "EXCALIBUR INCIDENT")!/ COLM13: ASCIZ /DOCKED WITH GHOSTSHIP!/ COLM14: ASCIZ / UNITS OF ENERGY AVAILABLE PHOTON TORPEDOES NOW NUMBER / COLFIX: CLEAR A13, ;COLLISION WITH FIXED OBJECT: CLEAR A14, ;GET THE OBJECTS VELOCITY. GOTO COLCOL COLXCL: TRO F,XCEFLG ;SET EXCALIBUR-ENTERPRISE COLLISION FLAG. COLMOV: MOVE A13,XVEL(A10) ;COLLISION WITH MOVING OBJECT: MOVE A14,YVEL(A10) ;GET THE OBJECT'S VELOCITY. COLCOL: MOVEI A,COLM05 ;TYPE THE COLLISION MESSAGE. INVOKE OUTSTR INVOKE COLNAM MOVE T,LINK(A10) ;REMOVE THE OTHER OBJECT HRRM T,LINK(A7) ;FROM THE OBJECT LIST. MOVE A,A10 ;REPORT DESTRUCTION OF INVOKE REPORT ;THE OTHER OBJECT. MOVEI T,3 ;DESTROY THE ENTERPRISES SHIELDS. CLEARM SHIELD(T) SOJGE T,.-1 MOVEI A,COLM06 ;SEND SHIELD DESTRUCTION MESSAGE. INVOKE ENDMSG MOVE R,A13 ;COMPUTE THE MAGNITUDE OF THE VELOCITY MOVE A,A14 ;OF THE ENTERPRISE RELATIVE FSBR R,XVEL+ENTVEC ;TO THE OTHER OBJECT. FSBR A,YVEL+ENTVEC INVOKE SQUMS FMPRI A,(500.0) ;THE NUMBER OF UNITS DAMAGE APPLIED FIXR A,A ;IS THIS TIMES 500. INVOKE OUCH COLVEL: INVOKE CANWRP ;CANCEL ENTERPRISE ACCELERATION. FADR A13,XVEL+ENTVEC ;THE ENTERPRISE VELOCITY BECOMES FADR A14,YVEL+ENTVEC ;THE AVERAGE OF ITS OLD VELOCITY FSC A13,-1 ;WITH THAT OF THE OTHER OBJECT. FSC A14,-1 MOVEM A13,XVEL+ENTVEC MOVEM A14,YVEL+ENTVEC COLNIX: MOVE A10,A7 ;FUDGE THE LINKS FOR THE INNER LOOP. COLIND: MOVE A7,A10 ;SAVE THE LOCATION OF THE OTHER OBJECT HRRZ A10,LINK(A7) ;AND GET ITS CHILD WHICH BECOMES CAME A10,A6 ;THE NEW OTHER OBJECT UNLESS IT GOTO COLILP ;IS THE SAME AS THE MOVING OBJECT COLOND: MOVE A5,A6 ;IN WHICH CASE WE GO TO THE HRRZ A6,LINK(A5) ;NEXT MOVING OBJECT. JUMPN A6,COLOLP ;(IF IT EXISTS) ;ENTERPRISE TORPEDO FIRE: SKIPN TRPRNM ;TEST FOR LAUNCH REQUESTED. GOTO XCLFIR INVOKE LAUNCH ;TRY TO GET A PHOTON TORPEDO. GOTO XCLFIR ;TRAPS HERE IF NONE AVAILABLE. MOVEI T,TRPCOD ;SET TORPEDO'S SOURCE. HRLM T,TYPE(A) MOVE A14,A ;SAVE THE TORPEDO ADDRESS. SOS TRPRNM ;DECREMENT TORP FIRE REQUESTS. MOVEI A,TRPMS1 ;TYPE TORPEDO LAUNCH MESSAGE: INVOKE OUTSTR MOVE A,TRPNUM INVOKE OUTINT MOVEI A,TRPMS2 INVOKE ENDMSG AOS A13,TRPNUM ;SET POINTER FOR NEXT LAUNCH. HLRZ A,TRPREQ-2(A13) ;GET THE 2 FLOATING POINT NUMBERS INVOKE FLONPK ;STORED IN THIS TORP REQUEST ENTRY. MOVE A5,A HRRZ A,TRPREQ-2(A13) INVOKE FLONPK MOVE A6,A ;IF THE FIRST NUMBER IS NOT ZERO, JUMPN A5,CRDLCH ;THE LAUNCH IS AT A TARGET. JSP R,DCOS ;COMPUTE TORP VELOCITY: FMPRI A,(ETRPSP) FADR A,XVEL+ENTVEC ;ADD IN THE ENTERPRISES VELOCITY. MOVE A5,A MOVN A,A6 JSP R,DSIN FMPRI A,(ETRPSP) FADR A,YVEL+ENTVEC MOVE A6,A GOTO EFTMRG ;MERGE WITH TARGET METHOD. CRDLCH: FSBR A5,XPOS+ENTVEC ;TARGET METHOD: FSBR A6,YPOS+ENTVEC ;SETUP FOR A CALL ON A VERY FANCY SUBROUTINE MOVE A7,XVEL+ENTVEC ;THAT MAGICALLY DISGORGES THE REQUIRED MOVE A10,YVEL+ENTVEC ;TORPEDO VELOCITY. MOVSI A11,(ETRPS2) INVOKE DIRECT GOTO EFTERR ;ERROR RETURN--CANNOT HIT TARGET WITH EFTMRG: MOVEM A5,XVEL(A14) ;CURRENT ENTERPRISE VELOCITY. MOVEM A6,YVEL(A14) ;FILL IN TORP POSITION AND VELOCITY. EFTREP: MOVE R,A5 MOVE A,A6 ;LAUNCH THE TORP 1 PARSEC AWAY FROM THE INVOKE SQUMS ;ENTERPRISE TO AVOID COSTLY MISFIRES. CAMG A,ZERO ;IF TORP VELOCITY IS ZERO, GOTO EFTFUD ;WE MUST FUDGE THE LAUNCH DIRECTION. FDVR A5,A FDVR A6,A FADR A5,XPOS+ENTVEC FADR A6,YPOS+ENTVEC MOVEM A5,XPOS(A14) MOVEM A6,YPOS(A14) MOVEI T,TRPEGY ;SET THE TORPEDO'S ENERGY. MOVEM T,ENERGY(A14) GOTO XCLFIR TRPMS1: ASCIZ /TORPEDO / TRPMS2: ASCIZ / LAUNCHED!/ TRPMS3: ASCIZ /TORPEDO UNABLE TO OBTAIN DESIRED BEARING! TORPEDO MOTORS BURNED OUT!! PREPARE FOR PHOTON TORPEDO EXPLOSION!!!/ EFTFUD: MOVN A5,XVEL+ENTVEC ;HERE WE SET THE TORP VELOCITY TO MOVN A6,YVEL+ENTVEC ;THE NEGATIVE OF THE ENTERPRISE'S GOTO EFTREP ;FOR LAUNCH COMPUTATION. EFTERR: MOVSI T,XPOS+ENTVEC ;JUST COPY THE ENTERPRISE POSITION HRRI T,XPOS(A14) ;AND VELOCITY INTO THE TORPEDO VECTOR. BLT T,YVEL(A14) MOVEI T,TRPEGY ;SET THE TORPEDO'S ENERGY. MOVEM T,ENERGY(A14) MOVEI A,TRPMS3 ;SEND WARNING MESSAGE INVOKE ENDMSG ;EXCALIBUR FIRE: XCLFIR: SKIPN XCALBR ;THE EXCALIBUR CAN FIRE ONLY IF GOTO NMEMOV ;IT IS IN THE QUADRANT. JSP R,RANDOM ;MAKE THE PROBABILITY OF EXCALIBUR MULI R,2 ;FIRE ABOUT 1/3. JUMPN R,NMEMOV ;IF THE ENTERPRISE HAS NOT HIT THE EXCALIBUR SKIPLE XCLF3 ;WITH PHASERS MORE THAN TWICE, IT WILL FIRE GOTO XCLNME ;ON THE ENEMY. OTHERWISE IT WILL FIRE ON MOVEI A,XCALBR ;YOU KNOW WHO: (GUESS?) INVOKE VISION ;(BUT ONLY IF VISIBLE) GOTO NMEMOV MOVE A13,XPOS+XCALBR ;COMPUTE THE VECTOR FROM THE FSBR A13,XPOS+ENTVEC ;EXCALIBUR TO THE ENTERPRISE. MOVE A14,YPOS+XCALBR FSBR A14,YPOS+ENTVEC MOVE A,A13 ;COMPUTE THE DISTANCE BETWEEN THEM. MOVE R,A14 INVOKE SQUMS FLTR R,ENERGY+XCALBR ;THE ENERGY HIT IS TWICE THE FSC R,1 ;EXCALIBUR'S ENERGY DIVIDED FDVR R,A ;BY THE DISTANCE. FIXR A,R MOVEI R,XCALBR INVOKE KLGHIT ;THIS SUBROUTINE DOES THE REST. GOTO NMEMOV XCLFM1: ASCIZ / UNIT HIT ON / XCLFM2: ASCIZ / FROM / XCLNME: MOVEI A6,ROMLNP ;INITIALIZE AND ENTER THE EXCALIBUR GOTO XCLNLC ;ENEMY HITTING LOOP: XCLNLP: MOVE R,XPOS(A6) ;COMPUTE THE DISTANCE TO THE ENEMY. FSBR R,XPOS+XCALBR MOVE A,YPOS(A6) FSBR A,YPOS+XCALBR INVOKE SQUMS FLTR R,ENERGY+XCALBR ;THE HIT FORMULA IS THE SAME AS ABOVE. FSC R,1 FDVR R,A FIXR A,R MOVN A7,A INVOKE OUTINT ;SEND THE HIT MESSAGE. MOVEI A,XCLFM1 INVOKE OUTSTR MOVE A,A6 INVOKE IDENT MOVEI A,XCLFM2 INVOKE OUTSTR MOVEI A,XCALBR INVOKE IDENT MOVEI A,"!" INVOKE OUTCHR INVOKE NEWLIN ADDB A7,ENERGY(A6) ;RECOMPUTE THE ENEMY'S ENERGY. JUMPG A7,XCLNLC ;IF NOT POSITIVE, THE ENEMY IS DESTROYED! MOVE T,LINK(A6) ;REMOVE IT FROM THE OBJECT LIST. HRRM T,LINK(A5) MOVE A,A6 ;REPORT DESTRUCTION. INVOKE REPORT MOVE A6,A5 ;FIX LIST ADDRESS FOR LOOP CONTROL. XCLNLC: MOVE A5,A6 HRRZ A6,LINK(A5) ;GET THE NEXT OBJECT IN THE LIST. HLRZ A7,TYPE(A6) CAIN A7,FDGCOD ;IGNORE FAKE OBJECTS. GOTO XCLNLC CAIE A7,ROMCOD ;HIT ENEMY SHIPS ONLY. CAIN A7,KLGCOD GOTO XCLNLP ;ENEMY VELOCITY SET AND WEAPONS FIRE: NMEMOV: HRRZ A5,LINK+ROMLNP ;GET ADDRESS OF FIRST ENEMY. GOTO KMOVNY ;ENTER ENEMY FIRE LOOP. KMOVLP: HRRZ A6,LINK+STARP ;LOCATE TOP OF STAR LIST. CLEAR A13, ;CLEAR NEW VELOCITY SUMS. CLEAR A14, GOTO KMOVAS ;ENTER REPULSION LOOP. REPEL: MOVE T,XPOS(A5) ;COMPUTE THE VECTOR FROM THE FSBR T,XPOS(A6) ;OBJECT TO THE ENEMY. MOVE T2,YPOS(A5) FSBR T2,YPOS(A6) MOVE T3,T ;COMPUTE THE FOURTH POWER OF THE DISTANCE. FMPR T3,T ;BETWEEN THEM. MOVE T4,T2 FMPR T4,T2 FADR T3,T4 FMPR T3,T3 FSC T3,1 ;DOUBLE IT. FDVR T,T3 ;DIVIDE THE VECTOR BY THIS VALUE. FDVR T2,T3 ;THE RESULT IS THE VELOCITY REPULSION FADR A13,T ;FROM THIS OBJECT. FADR A14,T2 KMOVLD: HRRZ A6,LINK(A6) KMOVAS: JUMPE A6,STRMOV ;REPEL THE ENEMY FROM ALL OBJECTS CAMN A6,A5 ;OTHER THAN ITSELF (EXCEPT TORPEDOS). GOTO KMOVLD HLRZ T,TYPE(A6) CAIGE T,TRPCOD CAIN T,FDGCOD GOTO KMOVLD GOTO REPEL STRMOV: FADR A13,T ;DOUBLE THE REPULSION FROM THE ENTERPRISE. FADR A14,T2 MOVE A7,XPOS+ENTVEC ;FINALLY, FIGURE OUT THE STRATEGY MOVE: FSBR A7,XPOS(A5) ;COMPUTE VECTOR FROM THIS ENEMY MOVE A10,YPOS+ENTVEC ;TO THE ENTERPRISE. FSBR A10,YPOS(A5) MOVE R,A7 ;MAKE THIS COMPONENT OF ENEMY VELOCITY MOVE A,A10 ;POINT TO THE ENTERPRISE FROM THE ENEMY INVOKE SQUMS ;AND HAVE A MAGNITUDE EQUAL TO MOVE A12,A ; ENEMY ENERGY/1000. FLTR R,ENERGY(A5) FDVRI R,(1000.0) FDVR R,A FMPR A7,R FMPR A10,R TRNN F,HASFLG ;IF THE USER IS CHEATING OR SKIPE PRBLMS ;THE ENTERPRISE IS DAMAGED, GOTO SETKIL ;PUT ON THE PRESSURE. SKIPGE T,STRTGY(A5) ;GET THE ENEMY'S STRATEGY BITS. GOTO SPCMOV ;IF SPECIAL STRATEGY, GO DO IT. CAMGE A12,STRLIM ;ELSE IF WITHIN STRATEGY LIMIT, GOTO SPCDEC ;CHOOSE SPECIAL STRATEGY. EXCH A7,A10 ;ELSE MARK TIME WITH CLOCKWISE OR TLNE T,(CLKSTT) ;COUNTERCLOCKWISE VELOCITY. MOVN A7,A7 TLNN T,(CLKSTT) ;TO DO THIS, SWAP VELOCITY COMPONENTS AND MOVN A10,A10 ;NEGATE ONE OF THEM. MOVSI T2,(1.5) CAMLE T2,XPOS(A5) MOVSI A7,(0.25) ;ALSO CHECK FOR NEARING QUADRANT CAMLE T2,YPOS(A5) ;BOUNDRIES. FIX STRATEGY VELOCITY MOVSI A10,(0.25) ;TO KEEP US IN THE QUADRANT MOVSI T2,(FQADSL) ;(MOST OF THE TIME). CAMGE T2,XPOS(A5) MOVSI A7,(-0.25) CAMGE 72,YPOS(A5) MOVSI A10,(-0.25) GOTO VELSET SPCDEC: JSP R,RANDOM ;MAKE RANDOM DECISION BETWEEN MULI R,2 ;ATTACKING AND ESCAPING STRATEGIES MOVSI T,(FIXSTT) SKIPN R SETKIL: MOVSI T,(FIXSTT+ATTSTT) MOVEM T,STRTGY(A5) ;MAKE THE STRATEGY PERMANENT. SPCMOV: TLNE T,(ATTSTT) ;IF ATTACKING, STRATEGY VELOCITY GOTO VELSET ;IS OK AS IT IS. IF ESCAPING, MOVN A7,A7 ;IT MUST BE NEGATED. MOVN A10,A10 VELSET: FADR A13,A7 ;ADD STRATEGY COMPONENT TO THE PREVIOUSLY FADR A14,A10 ;COMPUTED REPULSIVE VELOCITY. MOVEM A13,XVEL(A5) ;SET THE ENEMYS VELOCITY EQUAL MOVEM A14,YVEL(A5) ;TO THIS FINAL RESULT. TLNE T,(ATTSTT) ;IF ATTACKING, ALWAYS GOTO MURDER ;FIRE WHEN POSSIBLE. OTHERWISE JSP R,RANDOM ;CONSIDER FIRING ON THE ENTERPRISE. MULI R,3 ;(PROBABILITY=1/3) JUMPN R,KMOVNX MURDER: MOVE A,A5 ;ONLY VISIBLE ENEMYS MAY FIRE. INVOKE VISION GOTO KMOVNX HLRZ T,TYPE(A5) ;MUST KNOW TYPE SO WE CAN KNOW TRNN F,HASFLG ;(PHASERS IF THE USER IS CHEATING) CAIE T,ROMCOD ;WHAT TO FIRE. GOTO KLGFIR ;ROMULAN TORPEDO FIRE: SKIPN TRPFRE ;ARE ANY TORPS FREE? GOTO KMOVNX ;NO - CAN'T FIRE ANY. MOVE A12,A5 ;SAVE ENEMY LOOP CONTROL. MOVE A13,XPOS+ENTVEC ;COMPUTE PARAMETERS FOR DIRECT: MOVE A14,YPOS+ENTVEC ;VECTOR TO TARGET (THE ENTERPRISE). FSBR A13,XPOS(A12) FSBR A14,YPOS(A12) MOVE A5,A13 MOVE A6,A14 MOVE A7,XVEL(A12) ;VELOCITY RELATIVE TO TARGET. MOVE A10,YVEL(A12) FSBR A7,XVEL+ENTVEC FSBR A10,YVEL+ENTVEC MOVSI A11,(RTRPS2) ;SQUARE OF TORP SPEED. INVOKE DIRECT ;CAN WE HIT THE ENTERPRISE? GOTO ROMNOF ;NO, SHE IS MOVING TO FAST. FADR A5,XVEL+ENTVEC ;COMPUTE TORP VELOCITY. FADR A6,YVEL+ENTVEC MOVE R,A13 ;COMPUTE TORP LAUNCH POSITION. MOVE A,A14 ;(ROMULAN POS + 1 PARSEC TOWARD THE ENT) INVOKE SQUMS FDVR A13,A FDVR A14,A FADR A13,XPOS(A12) FADR A14,YPOS(A12) INVOKE LAUNCH ;GET THE TORP. HALT . ;IMPOSSIBLE-ALREADY CHECKED. MOVEI T,RTPCOD ;IDENTIFY AUTHOR AS ROMULAN. HRLM T,TYPE(A) MOVEM A13,XPOS(A) ;SET THE TORP PARAMETERS. MOVEM A14,YPOS(A) ;POSITION MOVEM A5,XVEL(A) ;VELOCITY MOVEM A6,YVEL(A) MOVE T,ENERGY(A12) ;ENERGY MOVEM T,ENERGY(A) ROMNOF: MOVE A5,A12 ;RESTORE ENEMY LOOP CONTROL. GOTO KMOVNX ;KLINGON PHASER FIRE: KLGFIR: FLTR R,ENERGY(A5) ;THE ENERGY HIT ON THE ENTERPRISE FSC R,2 ;IS TO BE FOUR TIMES THE KLINGON'S FDVR R,A12 ;ENERGY DIVIDED BY THE SQUARE OF FDVR R,A12 ;THE DISTANCE FIXR A,R ;FROM THE ENTERPRISE. TRNE F,HASFLG ;MAKE SURE THAT CHEATING ADD A,ENERGY+ENTVEC ;DOES NOT PAY. MOVE R,A5 MOVE A13,XPOS(A5) FSBR A13,XPOS+ENTVEC MOVE A14,YPOS(A5) FSBR A14,YPOS+ENTVEC INVOKE KLGHIT ;USE A SUBROUTINE FOR THE OTHER MESSY DETAIL KMOVNX: HRRZ A5,LINK(A5) KMOVNY: HLRZ T,LINK(A5) ;LET EACH KLINGON CAIE T,ROMCOD ;AND ROMULAN CAIN T,KLGCOD ;DO ITS THING. GOTO KMOVLP TRZ F,HASFLG ;PUNISH CHEATERS ONLY ONCE. ;TIME, ENERGY CHECKS; DAMAGE FIXUP; MISCELLANEOUS JUNK: TIMECK: AOS STRDAT ;UPDATE CURRENT STARDATE. MOVEI A,TLE%TC ;SET TIME LIMIT TERMINATION CODE. SOSG TIMLIM ;CHECK THE TIME LIMIT. GOTO ENDGAM ;STOP GAME IF EXCEEDED. INVOKE DAMFIX ;REPAIR DAMAGE (IF ANY). SOSLE ENERGY+ENTVEC ;CHECK THE ENTERPRISES ENERGY. ;ALSO SUBTRACT OVERHEAD=1 UNIT/SM. GOTO COMMND ;IF POSITIVE, REQUEST NEXT COMMAND. INVOKE DFDOWN ;ELSE DROP DEFLECTORS AND SKIPG ENERGY+ENTVEC ;IF THE ENERGY IS STILL NOT POSITIVE, GOTO OUTENG ;THE ENTERPRISE IS DEAD. MOVEI A,ENGMS2 ;ELSE TYPE THE SHIELD COLLAPSE MESSAGE. INVOKE ENDMSG GOTO COMMND OUTENG: MOVEI A,OOE%TC ;TERMINATE THE GAME. GOTO ENDGAM ;(OUT OF ENERGY) TIMNDM: ASCIZ /TIME UP!!/ ENGMSG: ASCIZ /OUT OF ENERGY! SHIP DESTROYED./ ENGMS2: ASCIZ /ENERGY TOO LOW TO MAINTAIN SHIELDS, SHIELDS COLLAPSED!/ ;ENDGAM--TYPE TERMINATING MESSAGE, RATING, AND QUIT. ;CALL: MOVEI A,GAME TERMINATION REASON NUMBER ; GOTO ENDGAM ; (DOES NOT RETURN) CWS%TC==0 ;COLLISION WITH STAR TLE%TC==1 ;TIME LIMIT EXCEEDED OOE%TC==2 ;OUT OF ENERGY CWO%TC==3 ;CREW WIPED OUT VIC%TC==4 ;VICTORY XCP%TC==5 ;DESTROYED EXCALIBUR WITH PHASERS XCC%TC==6 ;COLLIDED WITH EXCALIBUR SUR%TC==7 ;SURRENDER(^C) SAV%TC==16 ;SAVE GAME RES%TC==17 ;RESTORED GAME ENDGAM: MOVE A5,A ;SAVE REASON FOR TERMINATION. CLEARM .JBREN ;PROHIBIT REENTERS. INVOKE SCORE ;RECORD THE SCORE. INVOKE PAGE ;TYPE A FORM FEED. MOVE A,REASON(A5) INVOKE ENDMSG ;TYPE THE REASON FOR TERMINATION. INVOKE RATCMP ;GET THE RATINGS. MOVE A5,A ;SAVE THEM. MOVEI T,(A) IDIVI T,^D250 ;PICK A EULOGY. MOVE A,FINMSG(T) ;TYPE IT. INVOKE ENDMSG MOVE A,A5 ;RECALL THE RATINGS. INVOKE RATYPE ;TYPE THEM. INVOKE BRKOUT EXIT FINMSG: EXP FINMS1,FINMS2,FINMS3,FINMS4,FINMS5 FINMS1: ASCIZ / DEFEAT! THE ENEMY WILL CONQUER THE FEDERATION. YOUR DEMISE SIGNALS THE END OF THE FEDERATION AND THE CIVILIZED FREE WORLD. POSTERITY WILL CURSE YOUR NAME AS THEY SLAVE UNDER THE WHIP OF THE ROMULAN SLIME DEMONS!/ FINMS2: ASCIZ / YOU DESTROYED A SEGMENT OF THE INVADING FORCE BUT FAILED TO DAMAGE THE HEART OF THE ENEMY FLEET. YOUR VALIANT COMRADES WILL BE OVERCOME; THE DARK YEARS ARE NOW INEVITABLE. IN RECOGNITION OF YOUR SUPREME INCOMPETANCE, YOUR COMMANDING OFFICER HAS BUSTED YOU (POSTHUMOUSLY) TO THE RANK OF SPACEMAN (BASIC)./ FINMS3: ASCIZ / IT'S BEEN A HARD BATTLE WITH INCONCLUSIVE RESULTS. YOUR SACRIFICE HAS BEEN WORTHY BUT BY NO MEANS DEFINITIVE./ FINMS4: ASCIZ / THE ENEMY RANKS HAVE BEEN DECIMATED, LESS THAN A FOURTH REMAIN. YOU WILL BE GIVEN A HERO'S BURIAL./ FINMS5: ASCIZ / THE ENEMY IS TOTALLY DESTROYED. THE FEDERATION IS SAVED. CONGRATULATIONS, YOU HAVE BEEN ELECTED FEDERATION PRESIDENT!/ REASON: EXP COLM04,TIMNDM,ENGMSG,DAMSG6,WINMSG,COLM11,COLM12,SURMSG SURMSG: ASCIZ /SURRENDER!/ ;RATCMP COMPUTES TWO RATINGS AND RETURNS THEM IN AC A. ;THE RIGHT HALF OF A IS FOR THE WHOLE GAME (% ENEMY KILLED). ;THE LEFT HALF IS FOR THE PERIOD FROM RESTORE TO SAVE. RATCMP: HLRZ T,TOTEMY ;COMPUTE NUMBER OF INITIAL ENEMY. HRRZ T3,TOTEMY ADDB T,T3 ;COMPUTE FOR TOTAL EFFORT: SUB T,NUMKLG ;THIS IS JUST THE PERCENTAGE SUB T,NUMROM ;OF ENEMIES KILLED. IMULI T,^D1000 IDIV T,T3 MOVE A,T MOVE T4,INIDA2 ;COMPUTE FOR CURRENT EFFORT: SUB T4,TIMLIM ;THIS ONE IS TIME NORMALIZED SKIPG T4 ;WHERE NORMAL = 1000. MOVEI T4,1 HLRZ T,NUMKL2 HRRZ T2,NUMKL2 ADD T,T2 SUB T,NUMKLG SUB T,NUMROM IMULI T,^D1000 IMUL T,INIDAT IDIV T,T4 IDIV T,T3 HRL A,T RETURN ;RATYPE TYPES THE RATINGS IN AC A. RATYPE: SAVE A MOVEI A,RATYP1 INVOKE OUTSTR HRRZ A,(P) INVOKE OUTINT MOVEI A,RATYP2 INVOKE OUTSTR RESTORE A HLRZ A,A INVOKE OUTINT INVOKE NEWLIN RETURN RATYP1: ASCIZ / RATINGS: TOTAL EFFORT = / RATYP2: ASCIZ / PROFICIENCY = / ;SUBROUTINE SCORE RECORDS THE PROGRESS OF THE USER SINCE GAME CREATION OR ;RESTORATION ON DISK SO ANOTHER NOSEY USER CAN KEEP TRACK OF WHO DID WHAT. ;IT APPENDS AN 8 WORD RECORD TO THE BINARY SCORE FILE. ;TO CALL, SET THE TERMINATION REASON CODE IN AC A. ;^C TRAPS WILL BE DISABLED AFTER SCORING. SCORE: RESDV. IOCHSC, ;JUST IN CASE CHANNEL IN USE. JFCL ;CAN GIVE AN ERROR RETURN. SKIPN GALASZ ;DON'T SCORE IF GALAXY NOT CREATED. RETURN OPEN IOCHSC,SCOREO ;THIS JUNK IS SUPPOSED TO APPEND GOTO SCORET ;SOME NIFTY INFORMATION TO A MOVE T2,[SCORED,,DISMAT] ;LIKELY FILE: BLT T2,DISMAT+3 ;(I HOPE IT WORKS) LOOKUP IOCHSC,DISMAT ;THE NIFTY INFORMATION IS: GOTO NOSCOR HLRE T3,DISMAT+3 MOVN T3,T3 ;DATE/TIME OF GALAXY CREATION -- WORD 0 CAIL T3,^D100*BLKSIZ ;DATE/TIME OF GAME TERMINATION -- WORD 1 GOTO NOSCOR ;PPN--WORD 2 MOVE T2,SCORED+3 MOVEM T2,DISMAT+3 ENTER IOCHSC,DISMAT ;NAME(SIXBIT)--WORDS 3 & 4 GOTO NOSCOR ;REASON FOR TERMINATION--BITS 32-35 WORD 5 IDIVI T3,BLKSIZ ;RESTORE # KLINGONS -- BITS 0-6 WORD 5 JUMPE T4,NXTBLK ;RESTORE # ROMULANS -- BITS 7-13 WORD 5 USETI IOCHSC,1(T3) ;CURRENT # KLINGONS -- BITS 14-20 WORD 5 MOVE T2,SCOREC ;CURRENT # ROMULANS -- BITS 21-27 WORD 5 MOVEM T2,DISMAT ;GALAXY SIZE -- BITS 28-31 WORD 5 CLEARM DISMAT+1 ;STARTUP TIME LEFT -- BITS 0-11 WORD 6 IN IOCHSC,DISMAT ;RESTORE TIME LEFT -- BITS 12-23 WORD 6 SKIPA ;CURRENT TIME LEFT -- BITS 24-35 WORD 6 GOTO NOSCOR ;INITIAL # KLINGONS -- BITS 0-6 WORD 7 NXTBLK: SAVE A ;INITIAL # ROMULANS -- BITS 7-13 WORD 7 MOVE T2,CRETIM ;RESTORE COUNT -- BITS 14-20 WORD 7 MOVEM T2,DSKBLK(T4) ;GAME VERSION -- BITS 21-25 WORD 7 INVOKE DAYTIM ;GAME EDIT NUMBER -- BITS 26-35 WORD 7 MOVEM A,DSKBLK+1(T4) GETPPN T2, JFCL MOVEM T2,DSKBLK+2(T4) HRROI T2,.GTNM1 GETTAB T2, HALT .+1 MOVEM T2,DSKBLK+3(T4) HRROI T2,.GTNM2 GETTAB T2, HALT .+1 MOVEM T2,DSKBLK+4(T4) RESTORE A MOVE T2,[POINT 7,A] HLRZ T,NUMKL2 IDPB T,T2 HRRZ T,NUMKL2 IDPB T,T2 MOVE T,NUMKLG IDPB T,T2 MOVE T,NUMROM IDPB T,T2 MOVE T,GALASZ DPB T,[POINT 4,A,31] MOVEM A,DSKBLK+5(T4) MOVE T2,[POINT 12,A] MOVE A,TIMLIM MOVE T,INIDAT IDPB T,T2 MOVE T,INIDA2 IDPB T,T2 MOVEM A,DSKBLK+6(T4) MOVE T2,[POINT 7,A] HRRZ A,.JBVER HLRZ T,TOTEMY IDPB T,T2 HRRZ T,TOTEMY IDPB T,T2 MOVE T,RESCNT IDPB T,T2 LDB T,[POINT 5,.JBVER,11] DPB T,[POINT 5,A,25] MOVEM A,DSKBLK+7(T4) USETO IOCHSC,1(T3) MOVNI T4,10(T4) MOVS T4,T4 HRRI T4,DSKBLK-1 MOVEM T4,DISMAT CLEARM DISMAT+1 OUTPUT IOCHSC,DISMAT NOSCOR: RELEASE IOCHSC, CLEARM GALASZ ;DISABLE THIS GAME. CLEARM .JBINT ;REENABLE ^C'S. SCORET: RETURN SCOREO: 16 SCRDEV ;SCORE FILE DEVICE. 0 SCORED: SCRFIL ;SCORE FILE NAME SCREXT ;SCORE FILE EXTENSION Z SCRPPN ;SCORE FILE PPN. SCOREC: IOWD BLKSIZ,DSKBLK ;DAYTIM PROVIDES THE DATE/TIME IN AC A. DAYTIM: MSTIME T, ;THE DATE IS THE DEC-10 15 BIT IDIVI T,^D100 ;STANDARD AND IS FOUND IN THE DATE A, ;LEFTMOST 16 BITS OF AC A. LSH A,^D20 ;THE TIME OF DAY IS GIVEN IN IOR A,T ;TENTHS OF SECONDS AND IS FOUND RETURN ;IN THE RIGHTMOST 20 BITS. SUBTTL **** DAMAGE PACKAGE **** ;EACH PROBLEM IS RECORDED IN A 3 WORD VECTOR WITH A FIXED LOCATION. THE FIRST ;WORD IN A RECORD IS A LINK TO THE NEXT VECTOR IN THE PROBLEM LIST (SEE BELOW). ;THE SECOND WORD IS A CODE THAT IDENTIFIES THE PROBLEM -- CAPTAIN CODES ARE THE ;DEVICE NUMBERS (SEE DEVICE NAME LIST) AND DEVICE CODES ARE THE DEVICE NUMBERS ;PLUS THE NUMBER OF CAPTAINS. THE THIRD WORD IS THE NUMBER OF STARMINUTES THAT ;THE PROBLEM IS TO EXIST. ; THE PROBLEM RECORDS ARE STORED IN THE ORDER OF THEIR PROBLEM CODES (SEE ;ARRAYS "DEATHS" AND "DAMAGE"). WHEN A PROBLEM EXISTS, IT APPEARS ON A LINKED ;LIST. THE LOCATION "PRBLMS" POINTS TO THE TOP OF THE LIST. IF A PROBLEM DOES ;NOT EXIST, IT WILL NOT BE ON THE LIST AND ITS DAMAGE TIME WILL BE ZERO. ;OUCH--GENERATE A BIT OF HOLOCAUST ;CALL: MOVE A,#UNITSDAMAGE ; INVOKE OUCH ; (RETURN IF ENTERPRISE NOT DESTROYED) OUCH: JUMPLE A,OUCHRT ;IGNORE NON-POSITVE DAMAGE SAVE A5 SAVE A6 SAVE A7 MOVE A5,A ;MEN KILLED=#UNITS DAMAGE*(1+RANDOM)/8 JSP R,RANDOM ;ENERGY LOSS = #UNITSDAMAGE-MENKILLED MUL R,A5 ADD R,A5 ASH R,-3 SUB A5,R MOVN T,A5 ADDM T,ENTVEC+ENERGY JUMPLE R,OUCHDV ;IF MEN KILLED, TYPE CASUALTY MESSAGE. MOVN T,R ADDB T,MEN JUMPGE T,.+3 ;A FUDGE TO ELIMINATE OVERKILL: ADD R,MEN CLEARM MEN HRREI A6,-CAPVAL(R) ;SAVE THE CAPTAIN DEATH TIME. MOVE A,R ;TYPE THE NUMBER OF MEN KILLED. INVOKE OUTINT MOVEI A,DAMSG4 INVOKE OUTSTR MOVE A,MEN INVOKE OUTINT MOVEI A,DAMSG5 INVOKE ENDMSG SKIPG MEN ;CHECK FOR CREW WIPE OUT. GOTO MENDED IDIVI A6,CAPPRT MOVEI T4,0 ;SET CAPTAIN KILL FLAG. INVOKE ZAPPIT ;CONSIDER KILLING A CAPTAIN. OUCHDV: HRREI A6,-DEVVAL(A5) ;COMPUTE DEVICE DAMAGE. IDIVI A6,DEVPRT MOVEI T4,1 ;SET DEVICE DAMAGE FLAG. INVOKE ZAPPIT ;CONSIDER DAMAGING A DEVICE. RESTORE A7 RESTORE A6 RESTORE A5 OUCHRT: RETURN MENDED: MOVEI A,CWO%TC GOTO ENDGAM ;DAMCHK--CHECK FOR A DEVICE DAMAGED OR A CAPTAIN KILLED. ;CALL: MOVE A,DEVICE# ;SEE DEVICE NAME LIST. ; MOVEI R,0 ;ZERO AC15 IFF NO ERROR MESSAGE. ; INVOKE DAMCHK ; (RETURN--DEVICE NOT OPERABLE) ; (RETURN--DEVICE OK) DAMCHK: MOVE T,A IMULI T,3 ;COMPUTE INDEX TO DAMAGE LISTS. SKIPLE DEATHS+2(T) ;CHECK FOR CAPTAIN KILLED. GOTO DAMDED SKIPLE DAMAGE+2(T) ;CHECK FOR DEVICE DAMAGED. GOTO DAMDAM AOS (P) ;GIVE DEVICE OK RETURN. DAMRET: RETURN DAMDED: JUMPE R,DAMRET ;IF R NOT ZERO, GIVE AN ERROR MESSAGE. SAVE A MOVEI A,DAMSG1 INVOKE OUTSTR RESTORE A GOTO DAMLSC DAMDAM: JUMPE R,DAMRET ;IF R NOT ZERO, GIVE AN ERROR MESSAGE. SAVE A MOVEI A,DAMSG1 INVOKE OUTSTR RESTORE A GOTO DAMLSD DAMSG1: ASCIZ /**** CANCELLED **** / DAMSG2: ASCIZ / CAPTAIN IS DEAD./ DAMSG3: ASCIZ /DAMAGE REPORT:/ DAMSG4: ASCIZ / MEN KILLED - / DAMSG5: ASCIZ / LEFT!/ DAMSG6: ASCIZ /CREW WIPED OUT!/ DAMSG7: ASCIZ / CAPTAIN KILLED!/ DAMSG8: ASCIZ / DAMAGED FOR / DAMSG9: ASCIZ / STARDAYS./ DAMSG0: ASCIZ /NO DAMAGE/ ;ZAPPIT--DISABLE A DEVICE OR KILL A CAPTAIN. ;CALL: MOVE A6,#STARMINUTESDAMAGED ; MOVEI T4,X ;WHERE X=0 FOR CAPTAIN AND X=1 FOR DEVICE. ; INVOKE ZAPPIT ; (RETURN) ZAPPIT: JUMPLE A6,ZAPPNO ;NO PROBLEM IF DAMAGE NOT POSITIVE. CAIGE A6,2 ;MAKE SURE DAMAGE NOT FIXED IMMEDIATELY. MOVEI A6,2 JSP R,RANDOM ;PICK A CAPTAIN OR A DEVICE. MULI R,PRBNUM MOVE T,R IMULI T,3 ADD T,ZAPTYP(T4) ;LOCATE CORRESPONDING PROBLEM VECTOR. MOVE T2,2(T) ADDM A6,2(T) ;INCREASE DEVICE DAMAGE TIME. SKIPLE T2 ;IF DEVICE ALREADY DAMAGED, NO ZAPPNO: RETURN ;FURTHER ACTION IS REQUIRED. MOVE T2,PRBLMS ;ELSE THE PROBLEM MUST BE MOVEM T2,(T) ;ENTERED INTO THE LIST OF PROBLEMS. HRRZM T,PRBLMS SAVE R ADD R,ZAPNAM(T4) MOVE A,(R) SAVE T4 INVOKE OUTSTR RESTORE T JUMPN T,ZAPDEV ;FINISH PROBLEM MESSAGE. MOVEI A,DAMSG7 INVOKE ENDMSG ZAPCAN: RESTORE T ;IF WARP PROBLEM, CAIN T,WRPCOD ;CANCEL WARP CHANGES, GOTO CANWRP CAIN T,PHTCOD ;IF TORP PROBLEM, GOTO CANTRP ;CANCEL TORPEDO LAUNCHES. RETURN ZAPDEV: MOVEI A,DAMSG8 INVOKE OUTSTR HRREI A,-1(A6) INVOKE OUTDAT MOVEI A,DAMSG9 INVOKE ENDMSG GOTO ZAPCAN ZAPTYP: Z DEATHS ;ADDRESS OF PROBLEM RECORDS. Z DAMAGE ZAPNAM: Z CAPTAN ;ADDRESS OF PROBLEM NAMES LIST. Z DEVICE CAPTAN: [ASCIZ /WARP/] [ASCIZ /SHORT SONAR/] [ASCIZ /LONG SONAR/] [ASCIZ /PHASER/] [ASCIZ /TORPEDO/] DEVICE: [ASCIZ /WARP DRIVE/] [ASCIZ /SHORT SCAN/] [ASCIZ /LONG SCAN/] [ASCIZ /PHASERS/] [ASCIZ /PHOTON TORPEDOES/] PRBNUM==DEVICE-CAPTAN ;DAMFIX--REPAIR DAMAGED DEVICES AND DEAD CAPTAINS ;CALL: INVOKE DAMFIX ; (RETURN) DAMFIX: MOVEI A,PRBLMS ;LOCATE TOP OF DAMAGE LIST. DAMFLP: MOVE R,A ;SAVE PREVIOUS PROBLEM LOCATION. SKIPN A,(A) ;LOCATE NEXT PROBLEM IN LIST. RETURN ;QUIT IF END OF LIST. SOSLE 2(A) ;REPAIR BY ONE STARMINUTE. GOTO DAMFLP ;IF THIS FIXES THE PROBLEM, DO: MOVE T,(A) ;REMOVE THE PROBLEM FROM MOVEM T,(R) ;THE PROBLEM LIST. CLEARM (A) SAVE R ;SAVE PREVIOUS PROBLEM LOCATION. MOVE A,1(A) ;GET THE PROBLEM ID. CAIL A,DEVICE-CAPTAN GOTO DAMFDV ;SEND DIFFERENT MESSAGE FOR DEVICE. SAVE CAPTAN(A) ;SEND REPLACEMENT FOUND MESSAGE: MOVEI A,DAMFM1 INVOKE OUTSTR RESTORE A INVOKE OUTSTR MOVEI A,DAMFM2 DAMFBK: INVOKE ENDMSG RESTORE A GOTO DAMFLP DAMFDV: MOVE A,CAPTAN(A) ;SEND DEVICE REPAIRED MESSAGE: INVOKE OUTSTR MOVEI A,DAMFM3 GOTO DAMFBK DAMFM1: ASCIZ /REPLACEMENT FOUND FOR / DAMFM2: ASCIZ / CAPTAIN!/ DAMFM3: ASCIZ / REPAIRED!/ ;DAMLSD--LIST DAMAGED DEVICE ;CALL: MOVE A,DEVICENUMBER ; INVOKE DAMLSD ; (RETURN) DAMLSD: SAVE A MOVE A,DEVICE(A) INVOKE OUTSTR MOVEI A,DAMSG8 INVOKE OUTSTR RESTORE A IMULI A,3 MOVE A,DAMAGE+2(A) INVOKE OUTDAT MOVEI A,DAMSG9 GOTO ENDMSG ;DAMLSC--LIST CAPTAIN KILLED ;CALL: MOVE A,CAPTAINNUMBER ; INVOKE DAMLSC ; (RETURN) DAMLSC: MOVE A,CAPTAN(A) INVOKE OUTSTR MOVEI A,DAMSG2 GOTO ENDMSG ;DAMSET--INITIALIZE DAMAGE LIST ;CALL: INVOKE DAMSET ; (RETURN) DAMSET: CLEARM PRBLMS ;CLEAR PROBLEM LIST. MOVEI T,2*PRBNUM-1 DAMSLP: MOVE T2,T ;CLEAR PROBLEM RECORDS: IMULI T2,3 ;COMPUTE INDEX TO RECORD. CLEARM DEATHS(T2) ;CLEAR RECORD LIST LINK. MOVEM T,DEATHS+1(T2) ;SET RECORD IDENT CODE. CLEARM DEATHS+2(T2) ;CLEAR DAMAGE TIME. SOJGE T,DAMSLP RETURN ;DAMLST--TYPE A DAMAGE REPORT ;CALL: INVOKE DAMLST ; (RETURN) DAMLST: SAVE A5 SAVE A6 MOVEI A,DAMSG3 INVOKE ENDMSG MOVEI A5,PRBNUM-1 ;LIST DEVICES DAMAGED: CLEAR A6, DAMLP1: MOVE T,A5 IMULI T,3 SKIPG DAMAGE+2(T) GOTO DAMLX1 SETO A6, MOVE A,A5 INVOKE DAMLSD DAMLX1: SOJGE A5,DAMLP1 JUMPN A6,.+3 ;(MESSAGE IF NO DEVICES DAMAGED:) MOVEI A,DAMSG0 INVOKE ENDMSG MOVEI A5,PRBNUM-1 ;LIST CAPTAINS KILLED: DAMLP2: MOVE T,A5 IMULI T,3 MOVE A,A5 SKIPLE DEATHS+2(T) INVOKE DAMLSC SOJGE A5,DAMLP2 MOVEI A,TOTMEN ;TYPE # OF FATALITIES: SUB A,MEN JUMPLE A,DAMLRT INVOKE OUTINT MOVEI A,DAMLM1 INVOKE OUTSTR MOVE A,MEN INVOKE OUTINT MOVEI A,DAMLM2 INVOKE ENDMSG DAMLRT: RESTORE A6 RESTORE A5 RETURN DAMLM1: ASCIZ / FATALITIES / DAMLM2: ASCIZ / MEN LEFT/ SUBTTL **** SETUP AND DISPLAY ROUTINES AND CONSTANTS **** ;SHORT SCAN AUXILLIARY ROUTINES: DISINF: EXP DISL10,DISL9,DISL8,DISL7,DISL6,DISL5,DISL4,DISL3,DISL2,DISL1 DISL1: MOVEI A,QDMS03 ;STARDATE LINE: INVOKE OUTSTR MOVE A,STRDAT INVOKE OUTDAT ;TYPE CURRENT STARDATE. MOVEI A,QDMS04 INVOKE OUTSTR MOVE A,TIMLIM ;TYPE NUMBER OF DAYS LEFT. GOTO OUTDAT DISL2: MOVEI A,QDMS06 ;TYPE THE CONDITION. INVOKE OUTSTR MOVEI A,QDMS07 ;CONDITION GREEN--ALL IS NIFTY. MOVE T,ENTVEC+ENERGY CAIGE T,^D500 MOVEI A,QDMS08 ;CONDITION YELLOW--ENERGY LOW. HRRZ T,LINK+ROMLNP HLRZ T,TYPE(T) CAIE T,KLGCOD ;CONDITION ORANGE--KLINGON IN QUADRANT. CAIN T,ROMCOD MOVEI A,QDMS09 ;CONDITION ORANGE--ROMULAN IN QUADRANT HRRZ T,LINK+TRPTOP HLRZ T,TYPE(T) CAIL T,TRPCOD MOVEI A,QDMS10 ;CONDITION RED--TORPEDO IN QUADRANT GOTO OUTSTR DISL3: MOVEI A,QDMS05 ;SHIP POSITION LINE: INVOKE OUTSTR MOVE A,YPOS+ENTVEC ;TYPE IT: INVOKE OUTF.1 INVOKE OUTCOM MOVE A,XPOS+ENTVEC GOTO OUTF.1 DISL4: MOVEI A,QDMS11 ;ENERGY LINE: INVOKE OUTSTR MOVE A,ENERGY+ENTVEC ;TYPE CURRENT ENERGY. GOTO OUTINT DISL5: MOVEI A,QDMS12 ;TORPEDO LINE: INVOKE OUTSTR MOVEI A,TRPMAX+1 ;COMPUTE THE NUMBER OF UNFIRED TORPEDOES. SUB A,TRPNUM GOTO OUTINT DISL6: MOVEI A,QDMS13 INVOKE OUTSTR MOVE A,NUMKLG ;TYPE THE NUMBER OF KLINGONS LEFT. GOTO OUTINT DISL7: MOVEI A,QDMS14 INVOKE OUTSTR MOVE A,NUMROM ;TYPE THE NUMBER OF ROMULANS LEFT. GOTO OUTINT DISL8: MOVEI A,QDMS15 ;DEFLECTOR LINE: INVOKE OUTSTR MOVSI A14,-4 DISL8X: MOVE A,SHIELDS(A14) ;TYPE THE DEFLECTOR LEVELS. INVOKE OUTINT ;BEGINNING WITH DEFLECTOR 1. INVOKE OUTSPC AOBJN A14,DISL8X RETURN DISL9: MOVEI A,QDMS16 ;SPEED LINE: INVOKE OUTSTR MOVEI A,ENTVEC INVOKE SPEED ;GET THE ENTERPRISE SPEED. MOVE A14,A ;SAVE IT FOR THE NEXT LINE. GOTO OUTF.2 ;TYPE IT. DISL10: CAMG A14,ZERO ;IF SPEED IS NON-ZERO, RETURN MOVEI A,QDMS17 ;TYPE THE BEARING. INVOKE OUTSTR MOVEI A,ENTVEC INVOKE BERING GOTO OUTINT QDMS01: ASCIZ /SHORT RANGE SENSOR SCAN FOR / QDMS02: ASCIZ / / QDMS03: ASCIZ /STARDATE: / QDMS04: ASCIZ / LEFT: / QDMS05: ASCIZ /SHIP POSITION: / QDMS06: ASCIZ /CONDITION: / QDMS07: ASCIZ /GREEN/ QDMS08: ASCIZ /YELLOW/ QDMS09: ASCIZ /ORANGE/ QDMS10: ASCIZ /RED/ QDMS11: ASCIZ /ENERGY: / QDMS12: ASCIZ /PHOTON TORPEDOES: / QDMS13: ASCIZ /KLINGONS LEFT: / QDMS14: ASCIZ /ROMULANS LEFT: / QDMS15: ASCIZ /DEFLECTOR POWER: / QDMS16: ASCIZ /SPEED: / QDMS17: ASCIZ /BEARING: / DISCLR: XWD DISMAT,DISMAT+1 ;BLT XWD FOR CLEARING THE DISPLAY MATRIX. GALCLR: XWD GALAXY,GALAXY+1 ;BLT XWD FOR CLEARING THE GALAXY. LETTER: EXP "*","B","K","R","E","G","X","T","P" ;SETBAR--SET POSITION FLAGS (IN DISMAT) AROUND COORDINATES IN R AND A. ;(E.G. FOR Y=R-1,R,R+1 AND X=A-1,A,A+1) SETBAR: MOVEI T3,2 ;SET THE LOOP COUNTS. SETBAK: MOVEI T4,2 SETBAL: MOVEI T,-1(R) ;GENERATE A COORDINATE PAIR. MOVEI T2,-1(A) ADD T,T3 ADD T2,T4 JUMPLE T,SETBAX JUMPLE T2,SETBAX CAIG T,QADSIZ CAILE T2,QADSIZ GOTO SETBAX IMULI T,QADSIZ ;CONVERT COORDINATES TO INDEX. ADDI T,-QADSIZ-1(T2) AOS DISMAT(T) ;FLAG THE POSITION AS OCCUPIED. SETBAX: SOJGE T4,SETBAL ;LOOP FOR ALL POSITIONS AROUND R,A. SOJGE T3,SETBAK RETURN ;ADQLST--ADD AN OBJECT TO THE QUADRANT LIST ;CALL: MOVE A7,OBJECTLOCATION ; MOVE A14,OBJECTTYPECODE ; INVOKE ADQLST ; (RETURN) ADQLST: HRRM A7,LINK(A5) HRLZM A14,TYPE(A7) MOVE A5,A7 RETURN ;RANCRD--PLACE AN OBJECT AT A RANDOM POSITION AND ENTER IT INTO THE OBJECT LIST ;CALL: MOVE A7,OBJECTLOCATION ; MOVE A14,OBJECTTYPECODE ; INVOKE RANCRD ; (RETURN) RANCRD: JSP R,RANDOM ;GENERATE A RANDOM INDEX MULI R,QADSZ2 ;TO THE QUADRANT. AOSE DISMAT(R) ;TEST FOR INDEX ALREADY USED. GOTO RANCRD IDIVI R,QADSIZ ;CONVERT IT TO X-Y COORDINATES. AOJ R, AOJ A, FSC R,233 ;FLOAT THEM. FSC A,233 MOVEM R,YPOS(A7) ;SET THE OBJECTS LOCATION. MOVEM A,XPOS(A7) GOTO ADQLST ;PUT THE OBJECT INTO THE QUADRANT LIST. ;MIDVEC--SETS VELOCITIES TOWARD THE CENTER OF THE QUADRANT. ;CALL: MOVE A10,MAGNITUDEOFVELOCITY ; MOVEI A7,OBJECT ; INVOKE MIDVEC ; (RETURN) MIDVEC: CLEARM XVEL(A7) ;INITIALIZE THE VELOCITY TO ZERO. CLEARM YVEL(A7) JSP R,RANFLO ;RANDOMIZE THE SPEED SOMEWHAT. FADRI A,(0.5) FMPR A10,A MOVSI A12,(MIDPOS) ;COMPUTE DISPLACEMENT OF QUADRANT FSBR A12,XPOS(A7) ;CENTER FROM OBJECT. MOVSI A13,(MIDPOS) FSBR A13,YPOS(A7) MOVE R,A12 ;COMPUTE MAGNITUDE OF DISPLACEMENT. MOVE A,A13 INVOKE SQUMS CAMG A,ZERO ;(IF ZERO, LET OBJECT BE MOTIONLESS) RETURN FDVR A,A10 FDVR A12,A ;DIVIDE DISPLACEMENT BY MAGNITUDE FDVR A13,A ;AND MULTIPLY BY DESIRED SPEED. MOVEM A12,XVEL(A7) MOVEM A13,YVEL(A7) GALDIR: RETURN ;GALDIS--PUT OBJECTS INTO RANDOM QUADRANTS GALDIS: SOJL A13,GALDIR GALDIX: JSP R,RANDOM MUL R,GALAS2 INVOKE ADDQAX GOTO GALDIX GOTO GALDIS ;TYPE A LINE OF MINUS SIGNS. UNDLIN: SAVE A11 MOVEI A11,^D30 UNDLIL: MOVEI A,"-" INVOKE OUTCHR SOJG A11,UNDLIL RESTORE A11 GOTO NEWLIN ;INITIALIZES ENEMY PARAMETERS: NMESET: MOVEI A,NMENRG ;SET THE OBJECT'S ENERGY. INVOKE RNDVAR MOVEM A,ENERGY(A7) CLEARM XVEL(A7) ;SET ITS VELOCITY. CLEARM YVEL(A7) MOVEI A10,0 ;SET ITS STRATEGY. JSP R,RANDOM MULI R,2 SKIPN R ;DECIDE ORIENTATION AT RANDOM. TLO A10,(CLKSTT) MOVEM A10,STRTGY(A7) RETURN ;THE ^C TRAP ROUTINE TURNS A ^C INTO A SURRENDER COMMAND. CCTRPI: MOVE T,[CCTRPD,,CCTRPB] ;CALL HERE TO ENABLE THE TRAP. BLT T,CCTRPB+2 MOVEI T,CCTRPB ;HERE WE SET THE CONTENTS OF THE MOVEM T,.JBINT ;^C (.JBINT) INTERRUPT CONTROL BLOCK. MOVEI T,REENTR ;HERE WE SET THE REENTRY POINT. HRRM T,.JBREN RETURN CCTRPL: PORTAL .+1 ;WE TRAP IN PUBLIC MODE. CLEARM CCTRPB+2 ;WHEN A ^C IS TYPED, MOVEI A,SUR%TC ;JUST REENABLE THE TRAP AND CALL GOTO ENDGAM ;THE ENDGAME ROUTINE. CCTRPD: XWD R,CCTRPL ;THESE ARE THE INITIAL CONTENTS XWD 0,2 ;OF THE .JBINT INTERRUPT CONTROL BLOCK. Z ;SEE DEC-10-OMCMA-A-D FOR ENLIGHTENMENT. ;ITMGEN GENERATES A SOMEWHAT RANDOM NUMBER (OF ITEMS) FOR GALAXY SETUP. ;TO CALL, PUT THE MINIMUM NUMBER OF THE OBJECT FOR A 10 BY 10 ;GALAXY INTO AC A. THE RANDOM NUMBER IS RETURNED IN AC A. ITMGEN: SAVE A JSP R,RANDOM ;GENERATE THE RANDOM COMPONENT. MOVE T,GALASZ ;THIS WORKS OUT TO BE FROM 0 TO ADDI T,3 ;ITEMAX FOR 1 BY 1 GALAXIES AND MOVE A,ITEMAX(A14) IMULI T,1(A) ;3*ITEMAX FOR 10 BY TEN GALAXIES. MUL R,T ;IN BETWEEN VALUES ARE IN BETWEEN. IDIVI R,4 RESTORE T ;MAKE THE NON-RANDOM COMPONENT MOVE A,GALAS2 IMULI T,-1(A) ;PROPORTIONAL TO THE NUMBER OF QUADS. IDIVI T,^D99 ADD R,T MOVE A,ITEMAX(A14) ;MAKE SURE THE FINAL RESULT DOES NOT IMUL A,GALAS2 ;EXCEED THE NUMBER THAT WE CAN FIT MOVE T,A ;INTO THE AVAILABLE QUADRANTS. IDIVI T,4 SUB A,T CAMLE R,A MOVE R,A RETURN ;VISION--DETERMINES IF AN OBJECT IS VISIBLE FROM THE ENTERPRISE. ;CALL: MOVEI A,OBJECT ;VISION IS BLOCKED ONLY IF THERE IS A STAR ; INVOKE VISION ;WITHIN "OBSTRUCTION" RADIUS OF THE LINE ; (RETURN--OBJECT NOT VISIBLE) ;SEGMENT FROM ENTERPRISE TO THE OBJECT. ; (RETURN--OBJECT IS VISIBLE) VISION: SAVE A5 ;SAVE SOME USEFUL ACCUMULATORS. SAVE A6 SAVE A7 MOVE A5,XPOS+ENTVEC ;COMPUTE VECTOR FROM OBJECT TO ENTERPRISE. MOVE A6,YPOS+ENTVEC FSBR A5,XPOS(A) FSBR A6,YPOS(A) MOVE A7,A5 ;COMPUTE THE SQUARE OF ITS MAGNITUDE. MOVE T,A6 FMPR A7,A7 FMPR T,T FADR A7,T HRRZ R,LINK+STARP ;LOCATE THE TOP OF THE STAR LIST. GOTO VISLNX ;ENTER THE VISION CHECK LOOP. VISLUP: MOVE T,XPOS(R) ;CHECK IF THE STAR IS BETWEEN MOVE T2,YPOS(R) ;THE OBJECT AND THE ENTERPRISE FSBR T,XPOS(A) ;IN THE SENSE THAT THE PROJECTION FSBR T2,YPOS(A) ;OF THE STAR ON THE LINE THROUGH MOVE T3,T ;THE OBJECT AND THE ENTERPRISE MOVE T4,T2 ;LIES BETWEEN THEM. FMPR T3,A5 FMPR T4,A6 FADR T3,T4 JUMPLE T3,VISLND FMPR T3,T3 FDVR T3,A7 CAML T3,A7 GOTO VISLND ;IF THIS IS TRUE, COMPUTE THE FMPR T,T ;DISTANCE OF THE STAR TO THIS LINE. FMPR T2,T2 FADR T,T2 FSBR T,T3 ;IF THIS DISTANCE IS LESS THAN THE CAMGE T,VISOBS ;VISION-OBSTRUCTION RADIUS, THEN GOTO VISRET ;THE STAR OBSTRUCTS VISION. VISLND: HRRZ R,LINK(R) ;ELSE GET THE NEXT OBJECT IN THE VISLNX: HLRZ T,TYPE(R) ;LIST. IF IT IS A STAR, CHECK CAIN T,STRCOD ;FOR VISION OBSTRUCTION. GOTO VISLUP AOS -3(P) ;GIVE SKIP RETURN IF VISIBLE. VISRET: RESTORE A7 RESTORE A6 RESTORE A5 RETURN STMSG1: ASCIZ /SPACE, THE FINAL FRONTIER: THIS IS A VOYAGE OF THE STARSHIP "ENTERPRISE". ITS FIVE YEAR MISSION: TO EXPLORE STRANGE NEW WORLDS, TO SEEK OUT NEW LIFE AND NEW CIVILIZATIONS, TO BOLDLY GO WHERE NO MAN HAS GONE BEFORE. PITT REAL TIME S T A R T R E K VERSION 3 ---------- / STMSG2: ASCIZ /ATTENTION CAPTAIN / STMSG3: ASCIZ / ORDERS: STARDATE / STMSG4: ASCIZ / AS COMMANDER OF THE FEDERATION STARSHIP ENTERPRISE, YOUR MISSION SHOULD YOU DECIDE TO ACCEPT IT, IS TO DESTROY THE UNHOLY KLINGON-ROMULAN ALLIANCE. A FLEET OF / STMSG5: ASCIZ / KLINGONS AND / STMSG6: ASCIZ / ROMULANS (/ STMSG7:ASCIZ/ ALL TOGETHER) HAS INVADED THIS PORTION OF THE GALAXY. YOU HAVE / STMSG8: ASCIZ / STARDATES TO COMPLETE YOUR MISSION, UNTIL STARDATE / REMSG1: ASCIZ /NOW IN / NOTICE: EXP .IODPR,SCRDEV,0,,,0,SCRPPN NOTICB: XWD NOTICE,DISMAT ;NOTICE.TXT I/O ARG BLOCKS AND BLT WORD. SUBTTL **** MISCELLANEOUS SUBROUTINES **** ;NUDGE A MOVING OBJECT: ;CALL: MOVE A,OBJECTADDRESS ; INVOKE NUDGE ; (RETURN--OBJECT REMAINS IN CURRENT QUADRANT) ; (RETURN--NEW QUADRANT IN T3 & T4) NUDGE: MOVE T,XVEL(A) ;COMPUTE NEW POSITION. MOVE T2,YVEL(A) FADRB T,XPOS(A) FADRB T2,YPOS(A) SETZ T3, SETZ T4, CAMGE T,NFQADL SOJ T3, CAMLE T,NFQADH AOJ T3, CAMGE T2,NFQADL SOJ T4, CAMLE T2,NFQADH AOJ T4, JUMPN T3,NUDLEV ;TEST FOR QUADRANT CHANGE. JUMPN T4,NUDLEV RETURN NUDLEV: AOS (P) ;CAUSE SKIP RETURN. ADD T3,XQUAD ;COMPUTE NEW QUADRANT. ADD T4,YQUAD CAIL T3,1 ;TEST FOR GALAXY LIMITS. CAMLE T3,GALASZ SETZ T3, CAIL T4,1 CAMLE T4,GALASZ SETZ T3, RETURN ;IDENT--IDENTIFIES AN OBJECT ;CALL: MOVE A,OBJECTADDRESS ; INVOKE IDENT ; (RETURN) IDENT: SAVE A HLRZ A,TYPE(A) ;TYPE OBJECT NAME. MOVE A,NAMES(A) INVOKE OUTSTR MOVEI A,IDENMS INVOKE OUTSTR MOVE A,(P) ;TYPE ITS VERTICAL POSITION. MOVE A,YPOS(A) INVOKE OUTF.1 INVOKE OUTCOM RESTORE A ;TYPE ITS HORIZONTAL POSITION. MOVE A,XPOS(A) INVOKE OUTF.1 RETURN NAMES: [ASCIZ/STAR/] ;INDEX BY TYPE CODE. [ASCIZ/STARBASE/] [ASCIZ/KLINGON/] [ASCIZ/ROMULAN/] [ASCIZ/ENTERPRISE/] [ASCIZ/GHOST/] [ASCIZ/EXCALIBUR/] [ASCIZ/TORPEDO/] [ASCIZ/ENEMY TORP/] IDENMS: ASCIZ / AT / ;REPORT--DESTRUCTION OF AN OBJECT AND PERFORM OBJECT DEPENDENT ACTION. ;CALL: MOVEI A,OBJECT ; INVOKE REPORT ; (RETURN) REPORT: SAVE A SAVE A14 HLRZ A14,TYPE(A) ;UPDATE THE GALAXY MAP IF THE OBJECT IS CAIG A14,3 ;A RECORDABLE OBJECT -(TYPE CODES 0,1,2,3) INVOKE REMCQD RESTORE A14 MOVE A,(P) INVOKE IDENT MOVEI A,RPTMSG INVOKE ENDMSG RESTORE A HLRZ R,TYPE(A) CAIE R,XCLCOD GOTO RPTNXL CLEARM XCALBR ;INDICATE EXCALIBUR NOT IN QUADRANT. TRO F,XCLDST ;INDICATE EXCALIBUR DESTROYED. RETURN RPTNXL: CAIN R,KLGCOD SOS NUMKLG CAIN R,ROMCOD SOS NUMROM SKIPN NUMKLG SKIPE NUMROM RETURN MOVEI A,VIC%TC GOTO ENDGAM RPTMSG: ASCIZ / DESTROYED!/ WINMSG: ASCIZ /VICTORY!!/ ;OUTQAD--IDENTIFIES A QUADRANT ;CALL: INVOKE OUTQAD ; (RETURN) OUTQAD: MOVEI A,OUTQMG INVOKE OUTSTR MOVE A,YQUAD INVOKE OUTINT INVOKE OUTCOM MOVE A,XQUAD INVOKE OUTINT RETURN OUTQMG: ASCIZ /QUADRANT / ;SQUMS--COMPUTES SQUARE ROOT OF SUM OF SQUARES OF A AND R. ;CALL: INVOKE SQUMS ; (RETURN) SQUMS: FMPR A,A FMPR R,R FADR A,R JSP R,SQRT RETURN ;ENDLIN--OUTPUTS A PERIOD AND A NEWLINE. ;CALL: INVOKE ENDLIN ; (RETURN) ENDLIN: MOVEI A,"." INVOKE OUTCHR GOTO NEWLIN ;SPEED--COMPUTE THE SPEED OF AN OBJECT. ;CALL: MOVEI A,OBJECT ; INVOKE SPEED ; (RETURN--SPEED IN A) SPEED: MOVE R,XVEL(A) MOVE A,YVEL(A) FMPR R,R FMPR A,A FADR A,R JSP R,SQRT RETURN ;BERING--COMPUTE THE BEARING OF AN OBJECT. ;CALL: MOVEI A,OBJECT ; INVOKE BERING ; (RETURN--INTEGRAL DEGREES IN A) BERING: MOVE R,XVEL(A) MOVN A,YVEL(A) GOTO IATAN2 ;ASKFOR--PUTS A STRING INTO THE OUTPUT BUFFER AN GIVES IT TO THE MONITOR. ;CALL: MOVEI A,MESSAGE ; INVOKE ASKFOR ; (RETURN) ASKFOR: INVOKE OUTSTR GOTO BRKOUT ;OUTSPC--TYPES A SPACE OUTSPC: MOVEI A," " GOTO OUTCHR ;OUTCOM--TYPES A COMMA OUTCOM: MOVEI A,"," GOTO OUTCHR ;CANWRP--CANCELS ENTERPRISE WARP CHANGES ;CALL: INVOKE CANWRP ; (RETURN) CANWRP: MOVEI A,CANWRM SKIPLE ACCTIM INVOKE ENDMSG CLEARM ACCTIM TRO F,SPCFLG+BRCFLG ;FORCE OBTAINED MESSAGES NEXT TIME. RETURN CANWRM: ASCIZ /** WARP CHANGES CANCELLED **/ ;OUTDAT--OUTPUTS STARMINUTES IN DATE FORMAT ;CALL: MOVE A,#STARMINUTES ; INVOKE OUTDAT ; (RETURN) OUTDAT: FSC A,233 ;CONVERT TO FLOATING POINT. FDVRI A,(100.0) ;FORMAT=#DAYS.#MINUTES GOTO OUTF.2 ;CALL HERE TO STOP TTY OUTPUT SUPPRESSION. NOSUPP: INVOKE BRKOUT SKPINC RETURN RETURN ;DOCSUB--INITIALIZES ENTERPRISE SHIELDS,ENERGY,VELOCITY,TORPEDOES. DOCSUB: INVOKE DFDOWN MOVEI T,MAXEGY MOVEM T,ENTVEC+ENERGY INVOKE CANTRP CLEARM ACCTIM CLEARM ENTVEC+YVEL CLEARM ENTVEC+XVEL SETOM DBERNG CLEARM DSPEED TRZ F,BRCFLG+SPCFLG MOVEI T,1 MOVEM T,TRPNUM RETURN ;LAUNCH--PUTS A PHOTON TORPEDO INTO THE QUADRANT. ;CALL: INVOKE LAUNCH ; (RETURN--TORPEDO NOT AVAILABLE) ; (RETURN--TORPEDO ADDRESS IN A) LAUNCH: SKIPN A,TRPFRE RETURN MOVE T,LINK(A) HRRZM T,TRPFRE ;MAKE SURE THE LEFT HALF OF TRPFRE IS ZERO. MOVE T,TRPTOP+LINK HRRM T,LINK(A) HRRM A,TRPTOP+LINK AOS (P) RETURN ;CANTRP--CANCELS ENTERPRISE TORP LAUNCHES. ;CALL: INVOKE CANTRP ; (RETURN) CANTRP: MOVEI A,CANTRM SKIPLE TRPRNM ;SEND MESSAGE ONLY IF LAUNCHES ARE PENDING. INVOKE ENDMSG CLEARM TRPRNM RETURN CANTRM: ASCIZ /** ALL TORPEDO LAUNCHES CANCELLED **/ ;TRPCLR--PUTS ALL FIRED TORP VECTORS ON THE FREE LIST. ;CALL: INVOKE TRPCLR ; (RETURN) TRPCLR: MOVEI A,TRPLST ;SET TOP OF FREE LIST. MOVEM A,TRPFRE MOVSI A,TRPCOD ;SET BOTTOM OF LIST. MOVEM A,TRPLST+*TRPLEN HRRI A,TRPLST+TRPLEN ;FILL IN THE MIDDLE. MOVEI R,TRPLSZ-1 TRPCLL: MOVEM A,-TRPLEN(A) ADDI A,TRPLEN SOJG R,TRPCLL RETURN ;INITSB--PERFORM BASIC INITIALSIZATION. ;CALL: JSP R,INITSB ; (RETURN) INITSB: RESET SKPINC ;SUPPRESS OUTPUT SUPPRESSION. NOOP MOVE P,[IOWD STKLEN,STACK] ;SET STACK CONTROL. SAVE R ;SAVE RETURN ADDRESS IN STACK. JSP R,RANDIT ;INITIALIZE THE RANDOM NUMBER GENERATOR. JSP R,FLOFDG ;INITIALIZE THE FLOATING OVERFLOW FUDGER. MOVEI T,"." ;SET THE INITIAL TIMING CHARACTER. MOVEM T,PERIOD MOVEI T,NOCLIM ;SET INITIAL NOCOMMAND COUNT. MOVEM T,NOCCNT INVOKE TTYINT GOTO ACCESS ;VERIFY ACCESS PRIVS. ;REENTR--RESTART PROCEDURE REENTR: PORTAL .+1 ;WE REENTER IN PUBLIC MODE. JSP R,INITSB ;CALL GENERAL INITIALIZATION. TRZ F,-1 ;RESET THE FLAGS. GOTO RESTRT ;RANDOMIZE AN INTEGER SLIGHTLY: RNDVAR: SAVE A ;THIS CODE REPLACES THE INTEGER IN A JSP R,RANDOM ;WITH A*(1+-RANDOM/8). MUL R,(P) ASH R,1 SUB R,(P) ASH R,-3 RESTORE A ADD A,R RETURN ;KLGHIT--GENERATE A UNIT HIT ON THE ENTERPRISE FROM A KLINGON LIKE OBJECT. ;CALL: MOVE A13,OBJECT X POSITION - ENTERPRISE X POSITION ; MOVE A14,OBJECT Y POSITION - ENTERPRISE Y POSITION ; MOVE A,ENERGY HIT ; MOVEI R,OBJECT ; INVOKE KLGHIT ; (RETURN) KLGHIT: JUMPLE A,KLGHRT SAVE A SAVE R INVOKE OUTINT ;TYPE "XX UNIT HIT ON ENTERPRISE FROM MOVEI A,KLGHM1 ;XXX AT X,X". INVOKE OUTSTR MOVE A,(P) INVOKE IDENT MOVEI A,KLGHM2 INVOKE ENDMSG RESTORE R RESTORE A GOTO SHLDHT KLGHM1: ASCIZ / UNIT HIT ON ENTERPRISE FROM / KLGHM2: ASCIZ /!/ ;SHLDHT--APPLY ENERGY HIT ON ENTERPRISE AGAINST SHIELDS. ;CALL: MOVE A13,SAME AS FOR KLGHIT ; MOVE A14,SAME AS FOR KLGHIT ; MOVE A,ENERGY ; INVOKE SHLDHT ; (RETURN) SHLDHT: MOVE T,A ;BREAK UP THE ENERGY INTO 2 PIECES. IDIVI T,3 ;DISTRIBUTE 1/3 AT RANDOM. ADD T2,T JSP R,RANDOM MUL R,T2 SUB T2,R ADD R,T ADD T,T2 MOVEI A,2 ;DECIDE BETWEEN SHIELDS 2 AND 4. SKIPLE A13 MOVEI A,4 MOVE A13,A MOVEI A,1 ;DECIDE BETWEEN SHIELDS 1 AND 3. SKIPLE A14 MOVEI A,3 MOVE A14,T INVOKE SHLDH2 ;HIT THE FIRST SHIELD. EXCH R,A14 ;SAVE ENERGY LEFT OVER. MOVE A,A13 INVOKE SHLDH2 ;HIT THE SECOND SHIELD. ADD R,A14 ;COMPUTE TOTAL ENERGY NOT DISIPATED MOVE A,R ;IN SHIELDS AND PASS IT TO OUCH. GOTO OUCH SHLDH2: SKIPG T,SHIELD-1(A) RETURN SAVE A13 SAVE A14 MOVE A13,R ;SAVE SHIELD # AND ENERGY HIT. MOVE A14,A SOSG IDTCNT ;CONSIDER A SHIELD LEAK. GOTO SHLDNO MOVEI A,SHLDM1 ;TYPE "SHIELD X KNOCKED DOWN BY XXX UNITS". INVOKE OUTSTR MOVEI A,"0"(A14) INVOKE OUTCHR MOVEI A,SHLDM2 INVOKE OUTSTR MOVE A,A13 CAMLE A,SHIELD-1(A14) ;THE MAXIMUM UNITS KNOCKED DOWN MOVE A,SHIELD-1(A14) ;IS THE SHIELD ENERGY. INVOKE OUTINT MOVEI A,SHLDM3 INVOKE ENDMSG MOVN A13,A13 ;COMPUTE NEW SHIELD ENERGY. ADDB A13,SHIELD-1(A14) CLEAR R, ;IF POSITIVE, ALL IS HUNKY DORY: JUMPG A13,SHLDRT ;THE HIT WAS ENTIRELY DISSIPATED IN THE SHIEL CLEARM SHIELD-1(A14) ;ELSE THE SHIELD IS DESTROYED. MOVEI A,SHLDM1 ;SEND THE DESTRUCTION MESSAGE. INVOKE OUTSTR MOVEI A,"0"(A14) INVOKE OUTCHR MOVEI A,SHLDM4 INVOKE ENDMSG MOVN R,A13 ;RETURN UNDISSIPATED PART OF HIT. SHLDRT: RESTORE A14 RESTORE A13 KLGHRT: RETURN SHLDNO: MOVEI A,SHLDLK ;COMPUTE NEW LEAK COUNT. INVOKE RNDVAR MOVEM A,IDTCNT MOVE A,A13 ;SEND SHIELD LEAK MESSAGE. INVOKE OUTINT MOVEI A,SHLDM5 INVOKE OUTSTR MOVEI A,"0"(A14) INVOKE OUTCHR MOVEI A,"!" INVOKE OUTCHR INVOKE NEWLIN MOVE R,A13 GOTO SHLDRT ;RETURN ENTIRE HIT. SHLDM1: ASCIZ /SHIELD / SHLDM2: ASCIZ / KNOCKED DOWN BY / SHLDM3: ASCIZ / UNITS/ SHLDM4: ASCIZ / DESTROYED!/ SHLDM5: ASCIZ / UNIT INTERDIMENSIONAL ENERGY LEAK THROUGH SHIELD / ;THE GALAXY MANIPULATION ROUTINES: ;THE GALAXY IS A SQUARE MATRIX OF SIZE GALASZ. EACH ENTRY IN THIS MATRIX IS A ;WORD LISTING THE CONTENTS OF THAT QUADRANT. ITS BITS ARE AS FOLLOWS: ; 0-INITIALIZED TO ZERO, SET TO 1 WHEN QUADRANT CONTENTS BECOME KNOWN. ; 24-26 - THE NUMBER OF ROMULANS IN THIS QUADRANT, ; 27-29 - THE NUMBER OF KLINGONS, ; 30-32 - THE NUMBER OF STARBASES, ; 33-35 - THE NUMBER OF STARS. ;THE RELATIONSHIP BETWEEN X,Y COORDINATES AND GALAXY INDICES IS AS FOLLOWS: ; QUADRANT(Y,X)=GALAXY+GALASZ*(Y-1) +(X-1) ;ADDQAD--ADD OBJECT TO QUADRANT R,A. ;ADDQAX--ADD OBJECT TO QUADRANT "GALAXY(R)". ;THE OBJECT NUMBER (TYPE CODE) IS TO BE PROVIDED IN A14. ;THE NORMAL RETURN IS A SKIP RETURN. A NON-SKIP RETURN IS GIVEN IF THE NUMBER ;OF THESE OBJECTS IN THE QUADRANT WOULD EXCEED THE MAXIMUM. ADDQAD: IMUL R,GALASZ ;COMPUTE GALAXY INDEX FROM QUAD COORDS. SUB R,GALASZ ADDI R,-1(A) ADDQAX: LDB A,QADPNT(A14) ;GET THE NUMBER OF EXISTING OBJECTS. CAML A,ITEMAX(A14) RETURN ;TEST FOR OVERFLOW. AOJ A, DPB A,QADPNT(A14) ;SET THE INCREASED NUMBER OF OBJECTS. AOS (P) RETURN QADPNT: POINT 3,GALAXY(R),35 POINT 3,GALAXY(R),32 POINT 3,GALAXY(R),29 POINT 3,GALAXY(R),26 ITEMAX: EXP STRMAX,1,NMEMAX,NMEMAX ;MAX NUMBER OF ITEMS PER QUADRANT. ;INDEX BY TYPE CODE. ;SIMILAR TO ADDCQD BUT REMOVES AN OBJECT AND GIVES ONLY ONE RETURN. REMCQD: MOVE R,YQUAD MOVE A,XQUAD REMQAD: IMUL R,GALASZ SUB R,GALASZ ADDI R,-1(A) REMQAX: LDB A,QADPNT(A14) SOJ A, DPB A,QADPNT(A14) RETURN ;GETS THE NUMBER OF AN OBJECT IN A QUADRANT. GETCQD: MOVE R,YQUAD MOVE A,XQUAD GETQAD: IMUL R,GALASZ SUB R,GALASZ ADDI R,-1(A) GETQAX: LDB A,QADPNT(A14) RETURN ;SDBCQD--SETS CURRENT QUADRANT DISPLAY BIT. SDBCQD: MOVE R,YQUAD MOVE A,XQUAD SDBQAD: IMUL R,GALASZ SUB R,GALASZ ADDI R,-1(A) MOVSI A,(1B0) ORM A,GALAXY(R) RETURN ;TYPE THE CONTENTS OF THE QUADRANT INDEXED BY AC R. LSCDSP: SAVE A13 SAVE A14 MOVE A13,R MOVEI A14,3 LSCDSL: MOVE R,A13 LDB A,QADPNT(A14) ADDI A,"0" CAIN A,"0" MOVEI A,"." INVOKE OUTCHR SOJGE A14,LSCDSL RESTORE A14 RESTORE A13 RETURN ;IATAN2--ROUTINE TO COMPUTE THE DIRECTION OF A POINT FROM THE ORIGIN ;CALL: MOVE R,XCOORDINATE(IN FLOATING POINT) ; MOVE A,YCOORDINATE ; INVOKE IATAN2 ; (RETURN WITH INTEGRAL ANGLE IN DEGREES IN A) IATAN2: MOVE T,R ;SAVE X & Y COORDINATES. MOVE T2,A ;(THE ARCTAN ROUTINE SAVES ALL ACCUMULATORS) FDVR A,R ;COMPUTE SLOPE OF LINE TO POINT. JSP R,ARCTAN FMPR A,DPERAD ;CONVERT RADIANS INTO DGREES. FIXR A,A CAIN A,^D180 ;HANDLE HORIZONTAL DIRECTIONS CLEAR A, ;DIFFERENTLY FROM OTHERS. JUMPE A,IATANZ SKIPGE T2 ;IF SOMEWHAT VERTICAL, CHOOSE ADDI A,^D180 ;FROM ALTERNATIVES WITH Y COORDINATE. RETURN IATANZ: SKIPGE T ;IF HORIZONTAL, CHOOSE FROM ADDI A,^D180 ;ALTERNATIVES WITH X COORDINATE. RETURN DPERAD: 57.2957795 ;THE FOLLOWING TWO SUBROUTINES ARE USED TO PACK FULL WORD FLOATING POINT ;NUMBERS INTO HALF WORDS TO SAVE SPACE IN THE GAME SAVE FILES. THE NUMBERS ;ARE PACKED BY GIVING UP 2 EXPONENT BITS AND 16 FRACTION BITS. THUS ;THE PACKED MAGNITUDES RANGE FROM ABOUT 2**-32 TO 2**32. PACKED PRECISION ;IS 11 BITS. ;FLOPAK PACKS THE NUMBER IN AC A INTO THE RIGHT HALF OF AC A. ;FLONPK UNPACKS THE NUMBER IN THE RIGHT HALF OF AC A INTO AC A. FLOPAK: CLEAR R, ;SET SIGN FLAG TO POSITIVE. JUMPGE A,FLOPA1 ;IF THE NUMBER IS NOT POSITIVE, MOVEI R,1B18 ;SET THE SIGN FLAG TO NEGATIVE AND MOVM A,A ;USE THE NUMBER'S MAGNITUDE. FLOPA1: ADDI A,1B20 ;ROUND OFF AFTER 11 FRACTION BITS. LSH A,-^D16 ;POSITION FRACTION IN RIGHT HALF WORD. CAIGE A,140B24 ;IF THE MAGNITUDE IS TOO SMALL, CLEAR A, ;USE THE SMALLEST POSSIBLE MAGNITUDE. JUMPE A,FLOPA2 ;CONVERSION IS COMPLETE IF NUMBER IS 0. TRNN A,3777 ;IF ROUNDING CLEARED THE FRACTION, TRO A,2000 ;SET IT BACK TO 1/2. SUBI A,140B24 ;CONVERT FROM EXCESS 128 TO EXCESS 32. CAILE A,377777 ;IF THE MAGNITUDE IS TOO LARGE, MOVEI A,377777 ;USE THE LARGEST POSSIBLE MAGNITUDE. OR A,R ;SET THE SIGN FLAG IN THE RESULT. FLOPA2: RETURN FLONPK: TLZ A,-1 ;LEFT HALF SHOULD BE ZERO. JUMPE A,FLONP1 ;CONVERSION COMPLETE IF NUMBER IS ZERO. MOVE R,A ;SAVE PACKED SIGN FLAG. TRZ A,1B18 ;CLEAR PACKED SIGN FLAG. ADDI A,140B24 ;CONVERT BACK TO EXCESS 128. LSH A,^D16 ;NEW FRACTION BITS ARE ZERO. TRNE R,1B18 ;SET SIGN OF UNGARBAGED NUMBER. MOVN A,A FLONP1: RETURN ;ANGROP REDUCES A FLOATING POINT ANGLE TO ONE BETWEEN -360 AND +360. ANGROP: MOVE R,A ;FIND THE NUMBER OF 360'S IN THE FDVRI R,(360.0) ;UNKNOWN ANGLE AND SUBTRACT FIX R,R ;THAT MANY 360'S FROM IT. FLTR R,R FMPRI R,(360.0) FSBR A,R RETURN ;SUBROUTINE TO COMPUTE XD*G AND YD*G WHERE G=(VR+SQRT((VR)**2-R2(V2-S2))/R2 ;WHERE VR=XD*VX + YD*VY ; V2=VX*VX + VY*VY ; R2=XD*XD + YD*YD ;IN WHICH THE PARAMETERS ARE (XD,YD,VX,VY,S2). THEY ARE EXPECTED IN ;ACCUMULATORS A5-A11 AND THE RESULTS ARE RETURNED IN ACCUMULATORS A5(XD*G) ;AND A6. THE NORMAL RETURN IS A SKIP RETURN. IF THE ANSWER IS COMPLEX OR ;G IS NEGATIVE, THE ERROR (NON-SKIP) RETURN WILL BE USED. ;IN CASE THE USEFULNESS OF THIS SUBROUTINE IS NOT SELF EVIDENT (DUMMY!), ;I NOW INFORM YOU THAT IT DOES THE "FIRE TORPEDO AT MOVING TARGET" COMPUTATION. XD==A5 YD==A6 VX== VY== S2==A11 DIRECT: MOVE R,VX ;COMPUTE R=V2-S2. FMPR R,VX MOVE A,VY FMPR A,VY FADR R,A FSBR R,S2 FMPR VX,XD ;COMPUTE VX=VR: FMPR VY,YD FADR VX,VY MOVE VY,XD ;COMPUTE VY=R2: FMPR VY,XD MOVE S2,YD FMPR S2,YD FADR VY,S2 FMPR R,R2 ;COMPUTE R2*(V2-S2). MOVE A,VR ;COMPUTE VR**2 FMPR A,VR FSBR A,R ;COMPUTE VR**2-R2*(V2-S2). JUMPL A,CNTCMP ;IF THIS IS NEGATIVE, JSP R,SQRT ;WE CAN'T COMPUTE THE SQUARE ROOT. FADR A,VR ;ALSO, IF G IS NEGATIVE, JUMPLE A,CNTCMP ;WE WON'T GET NIFTY RESULTS. FDVR A,R2 ;FINISH COMPUTING G. FMPR XD,A FMPR YD,A AOS (P) ;GIVE A SKIP-RETURN. CNTCMP: RETURN LIT END BEGIN