Trailing-Edge
-
PDP-10 Archives
-
decuslib10-06
-
43,50363/pirets.mac
There are no other files named pirets.mac in the archive.
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)<<N1'.'N2>&<-1,,0>>
DEFINE FLOAT(N1<0>,N2<0>) ;CONVERTS INTEGER PARAMETERS INTO
<^D<FLOATI(\<N1>,\<N2>)>> ;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( <QADSIZ+1>/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==<STRTGY==6>;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: <SIXBIT/VER/>+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,<SIXBIT/NOTICE/>,<SIXBIT/TXT/>,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+<TRPLSZ-1>*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==<VR==A7>
VY==<R2==A10>
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