Google
 

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