	TITLE	SW	SPACE WAR PROGRAM FOR STANFORD A.I. PROJECT
	SUBTTL	DEFINITIONS

	opdef	fix[247b8]

COMMENT/
	Revised September 5,1971 R.E. GORIN
		FEB 1972	R TAYLOR 
		AUG 1977	D WOODS
		jul 1978	M LeBrun & Tovar

	This program is based upon a traditional program written for
the PDP-1. Any resemblence to other programs, living or dead, is
purely coincidental.

/

IFDEF FOR,<MACRO__0;>MACRO==1		;SELECT ASSEMBLER

IFE MACRO,<
	DEFINE DEF(A,B)<
	A_B>
	DEFINE SDEF(A,B)<
	A__B>
>
IFG MACRO,<
	DEFINE DEF(A,B)<
	A=B>
	DEFINE SDEF(A,B)<
	A==B>
>
	DEF(F,0)
	DEF(A,1)
	DEF(B,2)
	DEF(C,3)
	DEF(D,4)
	DEF(W,5)
	DEF(X,6)
	DEF(Y,7)
	DEF(SHIP,10)
	DEF(R11,11)
	DEF(R12,12)
	DEF(BFP,13)
	DEF(R14,14)
	DEF(R15,15)
	DEF(R16,16)
	DEF(P,17)

	SDEF(VBRT,4000)			;LVW BRIGHTNESS FIELD
	SDEF(VSIZ,1000)			;LVW SIZE FIELD
	SDEF(VABS,100)			;LVW ABSOLUTE FIELD
	SDEF(VENDP,20)			;LVW ENDPOINT FIELD
	SDEF(VINVIS,40)			;LVW INVISIBLE FIELD

;	SWITCHES
	SDEF(FAST,1)			;SET FOR FAST ACTION
	SDEF(NMINE,4)			;SET TO THE MAXIMUM NUMBER OF MINES
	SDEF(NSHIP,5)			;SET FOR NUMBER OF SHIPS
	SDEF(PARM,1)			;FOR RUN TIME PARAMETER MODIFICATION
	SDEF(TEAMS,1)			;ON FOR TEAM SCORING
	IFL NSHIP-4,<	SDEF(TEAMS,0)	> ;TEAM SCORE ONLY FOR 4 SHIPS
	SDEF(GALAX,1)			;SET TO SHOW GALAXY'S SCORE

;	FORMULA OPTION BITS
	SDEF(FIROPT,1)			;FIRE=FIREPOWER
	SDEF(THROPT,2)			;THRUST=MANEUVERABILITY
	SDEF(SUNOPT,4)			;FIRE+THRUST=HEAT SHIELD
	SDEF(FINOPT,210)		;EITHER FIN=INVULNERABLE FINS
	SDEF(XXXOPT,3560)		;UNUSED
	SDEF(HYPOPT,4000)		;BOTH TURNS=HYPERSPACE
	SDEF(LOBOPT,10000)		;TURNS+FIRE=MOTIONLESS TORPS
	SDEF(GRVOPT,20000)		;TURNS+THRUST=NULL GRAVITY
	SDEF(ZOWOPT,40000)		;ALL FOUR=SELF-DESTRUCT
	SDEF(TURNOP,LOBOPT+GRVOPT+ZOWOPT) ;USE DUAL TURN BUT WORK EVEN WHEN DAMAGED

;	PARAMETERS
	SDEF(PDLEN,10)			;PUSHDOWN LENGTH
	SDEF(NTORPM,40)			;MAXIMUM NUMBER OF TORPEDOES/PLAYER
	SDEF(LTBL,NSHIP*22)		;TORPEDO TABLE LENGTH (SEE COMMENT BELOW)
	SDEF(NSTAR,144)			;NUMBER OF STARS TO PUT OUT


	DEFINE	LVW(X,Y,TYPE,MODE,BRT,SIZ)<
	IFIDN <MODE><a>,<SDEF(MD,1);>SDEF(MD,0)
	IFIDN <TYPE><i>,<SDEF(TT,2);>SDEF(TT,0)
	IFIDN <BRT><>,<SDEF(BQ,0);>SDEF(BQ,BRT)
	IFIDN <SIZ><>,<SDEF(SQ,0);>SDEF(SQ,SIZ)
	BYTE(11)<X>,<Y>(3)BQ,SQ(2)MD,TT(4)6
>

COMMENT/
A long vector word (LVW) for the III display has the following format

bits  0-10	X	Coordinate
bits 11-21	Y	Coordinate
bits 22-24	BRT	Brightness. 0=No change, 1-7 increasing brightness
bits 25-27	SIZ	Size. 0=No change, 1-7 increasing size
bit     29	M	Mode. 0=Relative to last, 1=Absolute from center
bits 30-31	T	Type. 0=Visible, 1=Endpoint, 2=Invisible
bits 32-35	6	Denotes LVW in the III display processor

Text is displayed on the III by means of PDP-10 words with left-justified
7-bit ASCII text with bit 35 set to 1.  This explains, e.g., ASCII/FOO/+1
that appears in various places.  (The III "opcode" is variable width at the
right end of the PDP-10 word.  Any odd opcode is for ASCII display.
All other opcodes are even.)

/

;	OPDEFS

;these are tame ones:
OPDEF	RESET	[CALLI	0]		;IO AND SW RESET
OPDEF	SLEEP	[CALLI	31]		;SLEEP UUO
OPDEF	CORE	[CALLI	11]		;CORE UUO
OPDEF	EXIT	[CALLI	12]		;STOP MY JOB
OPDEF	TTCALL	[51B8]			;TELETYPE IO

;These are the untamed AI lab specials:
OPDEF	UPGIOT	[703B8]			;DISPLAY A PIECE OF GLASS
OPDEF	SPCWAR	[CALLI	400000]		;READ SW BUTTONS
OPDEF	SPCWGO	[CALLI	400003]		;INITIATE A SPACE WAR MODULE
OPDEF	EIOTM	[CALLI	400005]		;ENTER IOT USER MODE
OPDEF	LIOTM	[CALLI	400006]		;LEAVE IOT USER MODE
OPDEF	DISMIS	[CALLI	400024]		;DISMISS SW MODULE
OPDEF	ACCTIM	[CALLI	400101]		;GET DATE AND TIME
OPDEF	SETPR2	[CALLI	400052]		;set simulated upper segment
OPDEF	TTREAD	[CALLI  477777]		;who knows?

COMMENT/
SPCWGO:
Set AC = Bits,,Adr
	Adr is the address of the "Spacewar" module
	Bits are
	Bit 0 = Run this on the PDP-10
	Bit 1 = Run this on the PDP-6
	Bits 14-17 = Number of ticks between startups

UPGIOT:
AC = Piece of glass number.
Address is for a two word block:
	Word0:	Address of display program
	Word1:	Length of Display program
	Program is run on the piece of glass named by AC (an immediate)
/

COMMENT $	Regarding the space allowed for certain things:

1.	The number of torpedoes that a ship can have active
	is bounded by 2+2*[TLIFE/TRELOD].

2.	Assuming that TLIFE <= 200 and TRELOD >= 20 then
	each ship can have < 18. torpedoes active.

3.	Therefore, LTBL = 18 * NSHIP.   Each torpedo is one display word.

4.	Each ship must be <= 150 (octal) points, including the flame

5.	Mines are usually 2 Display words.  In case of explosion,
	they are 10. words.

6.	The main buffer length, therefore is given by the expression:
		1+12*NMINE+150*NSHIP+LTBL
$

	DEF(BUFLEN,1+12*NMINE+150*NSHIP+LTBL)

	EXTERN	.JBDDT


	SUBTTL	ONCE-ONLY INITIALIZATION
STRT:	RESET				;RESET SPACEWAR
	MOVEI	1,DISTAB
	MOVEM	1,137			;SAVE POINTER TO DATA
	MOVE	P,PDP			;GET A PDL
	PUSHJ	P,SETP			;SET ALL THE PARAMETERS
	TTCALL	3,[BYTE(7)15,14,14,14]	;CLEAR SCREEN
	ACCTIM	A,			;USE DATE AND TIME
	IORI	A,1			;TO INITIALISE VARIOUS
	HRRZM	A,RAND2			;FLAVORS OF RANDOM
	ADDM	A,RANDX			;NUMBER GENERATORS
	MOVEI	B,221			;GET NUMBER OF LINES OF EACH TYPE
	PEEK	B,
	HLRZ	B,B			;MOVE QUARTER-WORDS INTO RH
	LSHC	B,-11			;MIN III # IN B, NUMBER OF III'S IN C-TOP
	LSH	C,-33			;SHIFT NUMBER DOWN TO RIGHT
	ADDI	C,(B)			;MAX III NUMBER
	SETO	A,			;SET FOR THIS JOB'S LINE
	TTCALL	6,A			;GET OUR LINE NUMBER
	HRRZ	A,A			;WIPE OUT ALL BUT THE NUMBER
	CAIG	A,(C)			;SKIP IF NOT A III
	CAIGE	A,(B)			;SKIP IF A DPY
	JRST	NOTIII			;THIS FOOL'S NOT AT A III
;;	SUBI	A,-100(B)		;NORMALIZE AND TURN ON 100 BIT FOR SCANNER
	HRRZM	A,LINE			;SAVE AS OUR LINE NUMBER
	MOVE	A,TRELOD		;GET THE RELOAD TIME
	LSH	A,-1			;HALVE IT
	SKIPN	TUBES			;SKIP IF WE HAVE TWO TUBES
	MOVEM	A,LATNCY		;SAVE AS LATENCY TIME
	MOVEI	BFP,CNTTBL		;ADDRESS OF COUNT TABLE
	MOVE	SHIP,NSHIPX		;FOR ALL SHIPS
	AOJA	SHIP,.+3		;PLUS ONE FOR GALAXY SCORE
STRT0:	SETZM	ZOWSW(SHIP)		;NOBODY LOST "PREVIOUS" ROUND
	SETZM	NUMWN(SHIP)		;NO WINS YET
	ADDI	BFP,1			;SKIP OVER COUNT LOCATOR WORD
	PUSH	BFP,[<ASCII/ />+1]	;NO TEXT YET
	SOJGE	SHIP,STRT0		;REPEAT FOR ALL SCORES
	SETZM	MAXSCR			;MAXIMUM SCORE ATTAINED SO FAR
	MOVSI	R11,-200		;CREATE -COS,,SIN TABLE
	SETZB	SHIP,GALAXY		;SIN/COS FOR 0 TO 2, 200(OCTAL) STEPS
STRT1:	MOVE	A,SHIP			;GET THE ARGUMENT
	PUSHJ	P,COS			;GET THE COSINE
	FIX	A,200000		;CONVERT TO INTEGER
	MOVNM	A,TAB(R11)		;SAVE IN THE TABLE
	MOVE	A,SHIP			;GET THE SAME ARGUMENT
	PUSHJ	P,SIN			;GET THE SINE
	FIX	A,200000		;FIX IT
	HLRM	A,TAB(R11)		;SAVE IT
	FAD	SHIP,[0.049087385]	;2/128
	AOBJN	R11,STRT1		;LOOP FOR MORE
	MOVSI	A,1000			;THIS HACK FIXES THE ONE ENTRY
	MOVEM	A,TAB+100		;IN THE TABLE THAT LOSES OTHERWISE
	SETOM	QRSTRT			;SET TO INITIALIZE A GAME
	SKIPE	TENSW			;DO WE USE THE 10 ONLY?
	JRST	PDP10G			;YES. INITIATE SW MODULE
	SKIPE	DEBUG			;ARE WE DEBUGGING
	JRST	SW6GO			;YES: DON'T START SPACE WAR MODULE
	SETOM	SIXSW			;CORE CELL FOR PDP6 STATUS
	MOVE	A,[XWD 400000,ONETIK]	;ONE TICK TO DISCOVER PDP6 STATE
	SPCWGO	A,			;RUN IN PDP-10 SW MODE FOR ONE TICK.
	SKIPGE	SIXSW			;WAIT FOR SW TICK TO HAPPEN
	JRST	.-1			;KEEP WAITING
	SKIPE	SIXSW			;OK.  IS PDP-6 ALIVE?
	JRST	PDP10G			;NO: RUN EVERYTHING ON THE PDP-10
	MOVE	A,[XWD	200003,SW6GO]	;THREE TICK SERVICE ON THE PDP-6
	SPCWGO	A,			;REQUEST SERVICE
	MOVE	A,[XWD	400002,SW10GO]	;TWO TICK SERVICE ON THE PDP-10
	JRST	PDP10H			;REQUEST USUAL SERVICE ON PDP-10

PDP10G:	SETOM	TENSW			;FLAG TO SAY USE THE 10 ONLY
	MOVE	A,[XWD	400003,SW6GO]	;RUN EVERYTHING FROM PDP10
PDP10H:	SPCWGO	A,			;SET UP MODULE
IFE PARM,<
	MOVEI	A,2			;GO INTO A SLEEP LOOP
	SLEEP	A,			;SNOOZE
	JRST	.-2			;AND SNOOZE MORE
>
IFG PARM,<
	SETZM	LPARM			;ZERO LAST PARM CELL
PARMS:	MOVE	P,UPDL			;LOAD USER MODE PDL
	PUSHJ	P,RPARM			;READ PARAMETERS
	JRST	PARMS			;LOOP
>
ONETIK:	MOVMM	5,SIXSW			;0 } OK, 1 } PDP6 SICK
	DISMIS				;DISMIS THE SW JOB.
SETP:	SKIPE	CLOBR			;HAS HI CORE BEEN CLOBBERED?
	POPJ	P,			;YES. CAN'T CHANGE ANYTHING
	JRST	SETALL			;NO. WE CAN SET ALL THE STUFF

;;RHT THIS CODE WAS SITTING ABOVE SETALL.  THUS THE CORE UUO
;; WAS KILLING IT OFF

%XIT:	SKIPE	.JBDDT
	POPJ	P,
	MOVEI	A,SETALL-1
	CORE	A,			;CUT BACK THE CORE
	JFCL
	SETOM	CLOBR
	POPJ	P,			;RETURN

NOTIII:	TTCALL	3,[ASCIZ/
Spacewar requires a III display!!
/]
	EXIT


	SUBTTL	THE PDP-10 SPACE WAR MODULE
SW10GO:	SKIPN DEBUG		;Skip if not at spacewar level
	JUMPGE 6,DIE		;Go away if CALL typed.
	SKIPN	SIXDON			;SKIP IF PDP-6 IS READY
	JRST	NORUN1			;NOT READY. DON'T RUN THIS MODULE.
	SETZM	SIXDON			;ZERO PDP-6 FLAG
	MOVEM	A,SWBUT2		;SAVE BUTTONS FOR FORMULA STUFF
	SKIPN	DDSW			;USING KEYBOARD BUTTONS?
	JRST	SW10G1			;DON'T READ KEYBOARD
;	SKIPE	DEBUG			;ARE WE AT USER MODE
;	EIOTM				;YES, ENTER IOT USER MODE
;	DATAO	310,LINE		;SELECT KEYBOARD NUMBER
;	DATAI	310,A			;READ THE BITS FROM HIS LINE
	MOVE A,LINE		;get our line number
	TTREAD A		;get latest version of kbd state
FOOGLY:	TRC	A,1700		;make on mean key down for shift,top,ctrl,meta
	MOVEM	A,BITS		;save for use later
;	SKIPE	DEBUG			;IF DEBUGGING THEN LEAVE IOT MODE
;	LIOTM				;LEAVE IOT MODE
SW10G1:	JRST	2,@[10000,,.+1]		;JUMP AND SET USER
	SKIPN	STARFG			;ARE THE STARS OUT YET?
	JRST	SW10ST			;STARS DONE ALREADY
	SOSGE	A,CDOWN			;ARE WE DONE WITH COUNTDOWN?
	JRST	ST.NOW			;YES. TIME TO SHOW THE STARS
	LSH	A,-2			;DIVIDE BY 8 (16 TICKS PER COUNT)
	IORI	A,141			;MAKE INTO A DIGIT WITH LSB
	CAIGE	A,155			;DOING FORMULA SELECT?
	JRST	SW10G3			;NO, CONTINUE COUNTDOWN
	MOVE	W,SWBUT2		;YES, FETCH BUTTONS
	SKIPN	DDSW			;USING KEYBOARD BUTTONS?
	JRST	SW10G2			;NO, IGNORE LINE BITS
	LSH	W,14			;SHIFT SW BITS 8 PLACES
	HRRZ	B,BITS			;GET LINE BITS
	TRZ	B,770000		;SHUT OFF SPURIOUS BITS
	IOR	W,B			;OR THE BUTTON BITS WITH SW BITS
SW10G2:	MOVEI	D,1			;STARFG<>0, SO REGS ARE EXPENDABLE
	MOVE	B,ALLTPS		;BUTTON COMBINATION 1 FOR ALL SHIPS
FMLOOP:	TRNE	D,XXXOPT		;IS THIS OPTION UNUSED?
	JRST	FMLOP2			;YES, DON'T ALLOW ITS SELECTION
	MOVE	C,B			;XOR THIS BUTTON COMBINATION
	XOR	C,W			;WITH ACTUAL BUTTONS
	MOVE	SHIP,NSHIPX		;FOR EACH SHIP
	TDNN	C,ALLBIT(SHIP)		;DOES THIS SHIP WANT THIS OPTION?
	MOVEM	D,FORMOP(SHIP)		;YES, LET HIM HAVE IT
	SOJGE	SHIP,.-2		;LOOP ON SHIPS
FMLOP2:	LSH	D,1			;SHIFT TO NEXT OPTION
	ADD	B,ALLTPS		;FORM NEXT BUTTON CONBINATION
	TRNE	B,17			;DONE ALL OF THEM?
	JRST	FMLOOP			;NO, DO NEXT COMBO
	MOVE	A,[<ASCIZ/OPT!/>+1]	;DISPLAY PRE-COUNTDOWN MESSAGE
SW10G3:	MOVEM	A,CTIM			;SAVE IT
	MOVE	A,SELWRD
	MOVEM	A,CTIM1
	UPGIOT	10,CTIME		;DISPLAY
	UPGIOT	11,CTIME
	JRST	SW10ST			;SKIP DISPLAY OF STARS
ST.NOW:	UPGIOT	10,STADR		;TIME TO DRAW THEM.
	SETZM	STARFG			;TELL PDP-6 THAT STARS ARE OUT
SW10ST:	AOSN	SHIPFG			;MUST WE DRAW THE SHIPS?
	UPGIOT	11,BPTRX		;YUP
	AOSN	CNTFG			;TIME TO SHOW NEW COUNTS?
	UPGIOT	12,CNTPNT		;DISPLAY THEM
SW10DN:	SETOM	TENDON			;SET TO INDICATE THE TEN HAS FINISHED.
NORUN1:	SKIPN	TENSW
	SKIPE	DEBUG			;ARE WE DEBUGGING?
CPOPJ:	POPJ	P,			;YES RETURN.
	DISMIS				;NO DEBUGGING: DISMISS SW



	SUBTTL	CREATE STARS AND WON COUNTS
STARS:	MOVE	A,RCONST		;INITIALIZE RANDOM NUMBERS
	MOVE	D,RANDX			;LOAD OLD RANDOM THING
	MOVEI	W,NSTAR-1		;NUMBER OF STARS TO MAKE
SL1:	ADD	D,A			;MAKE A RANDOM NUMBER
	MOVE	C,A			;SAVE IT IN C
	ADD	A,D			;MAKE ANOTHER RANDOM NUMBER
	PUSHJ	P,PLT1			;CONVERT C TO LVW COORDINATES
	IORI	C,526			;TURN ON END POINT AND LVW BITS SIZ=1
	DPB	A,[POINT 3,C,24]	;DEPOSIT A RANDOM BRIGHTNESS
	MOVEM 	C,STARBF+2(W)		;STUFF THIS IN THE STAR TABLE
	SOJGE	W,SL1			;BACK UNTIL THE TABLE IS FULL
	MOVEM	A,RANDX			;SAVE UPDATED NUMBER FOR NEXT TIME
	MOVE	A,CONS2			;GET NUMBER OF SECOND CONSOLE
	SUBI	A,24			;RESET TO REASONABLENESS
	JUMPL	A,NOTHR			;NO OTHER
	CAILE	A,5
	JRST	NOTHR
	MOVN	B,A			;CALCULATE SELECT BIT FOR DPYOUT
	MOVSI	A,400000
	LSH	A,(B)
	TROA	A,10			;MAKE IT A SELECT
NOTHR:	MOVEI	A,1
	MOVEM	A,SELWRD		;SAVE SELECTOR WORD
	MOVEM	A,STARBF+1		;STICK IT AT FRONT OF BUFFER
	SETOM	STARFG			;SEND OUT STARS
	MOVEI	W,BORROW-SUNVEC-1	;CREATE THE SUN
	PUSHJ	P,TWINKL		;ONE RAY AT A TIME
	SOJGE	W,.-1
	MOVEI	A,60			;START COUNTDOWN
	SKIPE	FORMUL			;IF PLAYING FORMULA
	ADDI	A,50			;PRECEDE WITH SELECTION PERIOD
	MOVEM	A,CDOWN			;SAVE TIMER
	MOVE	A,NSHIPX		;FOR ALL SHIPS,
	SKIPN	ZOWSW(A)		;DID HE LOSE?
	SOJGE	A,.-1			;LOOK FOR ONE LOSER
	JUMPL	A,CNT4			;NO LOSERS
	MOVE	A,NSHIPX		;COMPUTE SCORES AT RESTART
	MOVE	B,SURBEN		;SURVIVORS BENEFIT
CNT3:	SKIPN	ZOWSW(A)		;SKIP IF THIS GUY LOST
	ADDM	B,NUMWN(A)		;WINNER, INCREASE HIS SCORE.
	SOJGE	A,CNT3			;LOOP
CNT4:	MOVE	B,NSHIPX		;UPDATE ALL SCORES
CNT5:	MOVE	C,NUMWN(B)		;LOAD A SCORE
	CAMLE	C,MAXSCR		;BEST YET?
	MOVEM	C,MAXSCR		;YES, REMEMBER IT
	MOVE	W,B			;COPY SHIP NUMBER
	LSH	W,1			;AND DOUBLE FOR INDEXING
	ADD	W,[POINT 7,CNTTBL+4]	;ADD IN THE BYTE POINTER
	MOVEI	D,1
	MOVEM	D,(W)			;CLEAR TEXT FOR STARTERS
	SKIPN	DOTEAM			;REALLY DOING TEAMS?
	JRST	CNT5A			;NOPE
	MOVEM	D,-2(W)			;CLEAR OTHER TEAM MEMBER'S TEXT
	MOVE	D,NUMWN-1(B)		;GET THE OTHER GUY'S SCORE
	CAMLE	D,MAXSCR		;BEST YET?
	MOVEM	D,MAXSCR		;REMEMBER IT
	ADD	C,D			;ADD TO FIRST SCORE
	SUBI	B,1			;DECREMENT B AN EXTRA TIME
	SUBI	W,2			;POINT TO OTHER TEAM MEMBER'S DPY WORD
CNT5A:	MOVE	D,ABSENT		;IS THIS GUY BEING SUPPRESSED?
	TDNN	D,HANDBT(B)
	PUSHJ	P,DECDPX		;NO, WRITE SCORES
	SOJGE	B,CNT5			;LOOP
CNT6:	MOVE	C,GALAXY		;GET OVERHEAD COUNT
	MOVE	W,[POINT 7,CNTTBL+2]	;TEXT POINTER
	PUSHJ	P,DECDPX		;COUNT GALACTIC OVERHEAD
	MOVE	B,NSHIPX		;COMPUTE LENGTH OF COUNT TABLE
	ADDI	B,5(B)			;B_2B+5
	SKIPN	GSCORE
	SUBI	B,2			;NO GALACTIC SCORE
	MOVEM	B,CNTPNT+1		;SAVE AS LENGTH TO DISPLAY
	MOVEI	B,CNTTBL		;GET TABLE ADDRESS
	SKIPN	GSCORE
	ADDI	B,2			;POINT PAST GALAXY SCORE
	MOVEM	B,CNTPNT		;SET POINTER
	SKIPE	CNTR			;SKIP IF NO COUNTS
	SETOM	CNTFG			;ANNOUNCE THAT COUNTS ARE THERE
	MOVE	B,NSHIPX		;SEE WHO THE AMATEURS ARE
	MOVE	W,MAXSCR		;GET BEST SCORE SO FAR
	ASH	W,-3			;DIVIDE BY 8
CNT7:	SKIPN	BEGINR			;DO WE CARE ABOUT AMATEURS AT ALL
	JRST	CNT7A			;NO, PRETEND EVERYONE'S AN EXPERT
	SETOM	BGINR(B)		;ASSUME BEGINNER UNLESS PROVED OTHERWISE
	SKIPE	C,DRONES		;ACTIVE DRONES?
	MOVE	C,DRBUTS		;DRONES ARE NEVER AMATEURS
	TDNN	C,ALLBIT(B)		;TEST IF DRONE BITS ON FOR THIS SHIP
	CAMG	W,NUMWN(B)		;CHECK HIS SCORE AGAINST MAX/8
CNT7A:	SETZM	BGINR(B)		;HE'S NO AMATEUR
	SOJGE	B,CNT7			;CHECK OTHER SHIPS
	POPJ	P,			;RETURN TO GAME

DECDPX:	JUMPGE	C,DECDPB		;POSITIVE, GO PUT INTO DISPLAY
	MOVEI	D,"-"			;OOPS, LOSER NEEDS MINUS SIGN
	IDPB	D,W
	MOVM	C,C			;GET ABS C
DECDPB:	IDIVI	C,12			;ROUTINE USED TO DISPLAY THE
	HRLM	D,(P)			;WIN COUNTS
	JUMPE	C,.+2			;THIS SAVES DIGITS ON THE STACK
	PUSHJ	P,DECDPB		;BY WIPING THE FLAGS
	HLRZ	D,(P)			;WHICH IS FASTER THAN PUSHING
	ADDI	D,"0"			;THIS DEPOSITS TEXT USING
	IDPB	D,W			;W. ASSUMES LESS THAN 5 CHARACTERS
	POPJ	P,			;IN DECIMAL EXPANSION

TWINKL:	AOS	A,SUNRAY		;ADVANCE TO NEXT RAY (SCATTERED ORDER)
	ANDI	A,BORROW-SUNVEC-1	;ROTATE THROUGH LIST
	MOVEI	B,2003			;GET RANDOM NUMBER BY MULTIPLYING
	IMULB	B,RAND2			;PREVIOUS ONE BY (DEC) 1027
	TSC	B,B			;XOR RIGHT WITH LEFT
	ANDI	B,3			;GRAB A COUPLE OF RANDOM BITS
	SKIPN	B			;BIAS TOWARD MEDIUM LENGTH RAYS
	MOVEI	B,2			;BY REPLACING SHORTEST WITH MEDIUM
	MOVE	C,SUNVEC(A)		;GET FUNNY VECTOR WORD
	IMULI	C,1(B)			;MULTIPLY BY NUM FROM 2 TO 4
	MOVE	D,SUNVEC-1		;GET CORRECTION VALUE
	IMULI	D,1(B)			;MULT BY SAME LENGTH
	SUB	C,D			;NOW NEED TO CORRECT FOR BORROWS
	MOVE	D,SUNVEC(A)		;SO GET VECTOR AGAIN
	ANDCA	D,BORROW		;SEE WHICH CLOWNS ARE NEGATIVE
	LSH	D,4			;SHIFT BITS TO TOP OF BYTES
	ADD	C,D			;ADD BORROWS BACK IN
	ADDI	C,2			;CREATE SHORT-VECTOR III INST
	MOVEM	C,SUNBUF(A)		;STASH IT
	POPJ	P,			;AND THAT'S IT


	SUBTTL	INITIALIZE THE NEXT MATCH
	
GAME:	PUSHJ	P,STARS			;MAKE THE STARS COME OUT
	MOVE	W,CHANGD		;REMEMBER BUTTON CHANGES FROM LAST MATCH
	SETZB	A,GOBEG			;ZERO STUFF FOR NEW PLAY
	MOVE	B,[XWD GOBEG,GOBEG+1]	;LOAD A BLT POINTER
	BLT	B,GOEND			;ZERO THROUGH HERE
	SETOM	MINSTR			;MAKE THE MINES GET MADE
	SETOM	OLDBUT			;FORGET WHAT BUTTONS USED TO BE
	MOVE	SHIP,NSHIPX		;FOR EVERY SHIP,...
	PUSHJ	P,GAME2			;INITIALIZE A SHIP
	SOJGE	SHIP,.-1		;LOOP
	POPJ	P,			;RETURN

GAME2:	MOVE	B,NTORPS		;GET TORPEDO COUNT
	MOVEM	B,TPCN(SHIP)		;RESET TORPEDO COUNT
	SKIPE	DRONES			;PLAYING WITH ACTIVE DRONES?
	TDNE	W,ALLBIT(SHIP)		;YES, DID THIS SHIP DO ANYTHING?
	JRST	GAME2A			;DON'T ASSUME CONTROL
	SKIPE	FORMOP(SHIP)		;DECIDE WHICH BITS TO FORCE ON
	SKIPE	FORMUL			;FORMOP<>0=FORMUL IMPLIES HYPERSPACE
	TDZA	B,B			;NO HYPERSPACE OR FULL-FORMULA
	MOVE	B,HYPRBT(SHIP)		;HYPERSPACE, TURN OFF TURN BITS
	ANDCA	B,ALLBIT(SHIP)		;TOSS IN OTHER BITS
	IORM	B,DRBUTS		;TURN THESE DRONE BITS ON
	MOVEI	B,FIROPT		;GET FIREPOWER OPTION
	SKIPE	FORMUL			;FORMULA?
	MOVEM	B,FORMOP(SHIP)		;YES, SELECT FIREPOWER
GAME2A:	MOVE	D,IROT(SHIP)		;GET STANDARD INITIAL ROTATION
	MOVE	C,IPOS(SHIP)		;AND POSITION
	SKIPN	RSPSWT			;DO WE WANT RANDOM START?
	JRST	STDPSS			;NO USE STANDARD
	MOVEI	C,2003			;GET MULTIPLIER FOR RAND2
	IMULB	C,RAND2			;CREATE NEW RANDOM NUMBER
	TSC	C,C			;XOR RIGHT WITH LEFT
	MOVE	D,C			;GET A COPY OF IT
	ANDI	D,177			;USE 7 BITS FOR A DIRECTION
	LSH	C,-7			;GET A DIFFERENT 7 BITS
	ANDI	C,177			;GET A DIRECTION
	MOVE	C,TAB(C)		;GET UNIT VECTOR
	IMULI	C,240			;MULTIPLY BY FIXED RADIUS
STDPSS:	MOVSM	D,SRA(SHIP)		;SAVE ROTATION
	MOVEM	C,SP(SHIP)		;SAVE SHIP POSITION
	HLRE	D,C			;GET -2Y INTO D
	HRRE	C,C			;2X IN C
	FSC	C,223			;FLOAT POSITIONS
	FSC	D,223			;FLOAT POSITIONS
	MOVEM	C,SX(SHIP)		;SAVE X POSITION
	MOVNM	D,SY(SHIP)		;SAVE --Y POSITION
	MOVE	C,ALLBIT(SHIP)		;REINITIALISE STUFF IN CASE REINCARNATING
	ANDCAM	C,DMASK			;INITIALIZE DAMAGE MASK
	MOVEI	C,GO2SIZ(SHIP)		;CLEAR BUNCHES OF THINGS
	SETZM	GOBEG2(C)		;BETWEEN GOBEG2 AND GOBEG2+GO2SIZ
	SUBI	C,NSHIP			;ONLY FOR THIS SHIP
	JUMPGE	C,.-2
	SETZM	SV(SHIP)		;VELOCITY CAN'T BE IN GOBEG2
	SETZM	SVX(SHIP)		;BECAUSE MINE STUFF IS INTERLEAVED
	SETZM	SVY(SHIP)		;WITH SHIP STUFF
	POPJ	P,			;RETURN

;WIPE SUPPRESSES SHIP IF ABSENT (IN REG C) SAYS TO, ELSE RESURRECTS IT
WIPE:	SETOM	RESTAR(SHIP)		;START BY ASSUMING INSTANT RESURRECTION
	TDNN	C,HANDBT(SHIP)		;NOW SEE IF THIS SHIP IS BEING SUPPRESSED
	POPJ	P,			;NOPE, LET IT GO
	MOVEI	D,777			;YES, WIPE IT OUT NEVER TO RESURRECT
	MOVEM	D,ZOWSW(SHIP)		;WE PRETEND SHIP HAS EXPLODED
	MOVEM	D,ZORCHP(SHIP)		;AND EXPLOSION HAS FINISHED
	MOVEM	D,RESTAR(SHIP)		;AND IT'LL BE A WHILE AOSING TO ZERO
	SETZM	TPCN(SHIP)		;NO MORE TORPS (ELSE CTORP MIGHT
					;KEEP GAME GOING MISTAKENLY)
	POPJ	P,


	SUBTTL	THE PDP-6 SPACE WAR MODULE
SW6GO:	SKIPN DEBUG		;Skip if not at spacewar level
	JUMPGE 6,DIE		;Go away if CALL typed.
	MOVE	P,PDP			;GET A PDL
	SKIPE	DEBUG
	SPCWAR	A,			;READ BUTTONS IF NOT SPACEWAR
	MOVEM	A,SWBUT			;SAVE SW BUTTON
	SKIPN	TENSW
	SKIPE	DEBUG			;ARE WE ON THE PDP-10
	PUSHJ	P,SW10GO		;YES: FAKE THE 10 SW MODULE
	MOVE	B,TENDON		;IS PDP-10 READY?
	JUMPE	B,NORUN2		;NOT YET. HOLD THIS UP
	SETZM	TENDON			;CLEAR PDP-10 FLAG
	MOVE	A,SWBUT			;GET BUTTONS INTO A
	SKIPN	DDSW			;USING KEYBOARD BUTTONS?
	JRST	SW6GO1			;NO, IGNORE THEM
	LSH	A,14			;YES, SHIFT SW BITS 12 PLACES
	HRRZ	B,BITS			;GET LINE BITS
	TRZ	B,770000		;SHUT OFF SPURIOUS BITS
	IOR	A,B			;OR THE BUTTON BITS WITH SW BITS
SW6GO1:	AOSN	QRSTRT			;TEST THE RESTART FLAG
	PUSHJ	P,GAME			;TIME FOR A NEW GAME
	SKIPN	STARFG			;ARE THE STARS OUT YET
	JRST	SWG0			;YES, ALL OK

NORUN2:	SETOM	SIXDON			;TELL PDP-10 WE ARE READY
	SKIPE	DEBUG			;ARE WE DEBUGGING?
	JRST	SW6GO			;YES: WE'LL SOON FORCE THE STARS
	DISMIS				;NO. INTERLOCK WITH PDP-10
					;UNTIL HE FINISHES WITH STABLE
SWG0:	MOVE	SHIP,NSHIPX		;PREPARE TO LOOP ON SHIPS
	SKIPN	DRONES			;ACTIVE DRONES?
	JRST	SWG1			;NO, SKIP TO NEXT LOOP INSTEAD
	EXCH	A,OLDBUT		;COMPARE BUTTONS WITH PREV STATE
	SKIPGE	A			;IS PREV STATE NEGATIVE?
	MOVE	A,OLDBUT		;YES, PRETEND NO CHANGE
	XOR	A,OLDBUT		;XOR PREV STATE WITH CURRENT
	IORM	A,CHANGD		;ACCUMULATE CHANGES THIS ROUND
	MOVE	B,DRBUTS		;FETCH DRONE BITS FOR MUNGING
SWG0.0:	TDNE	A,ALLBIT(SHIP)		;IF ANY BUTTON CHANGED
	TDZ	B,ALLBIT(SHIP)		;THEN ZERO THAT SHIP'S DRONE BITS
	SOJGE	SHIP,SWG0.0		;LOOP
	MOVEM	B,DRBUTS		;SAVE NEW DRONE BITS
	MOVE	A,OLDBUT		;FETCH BUTTONS AGAIN
	IOR	A,DRBUTS		;FORCE DRONE BITS ON
	MOVE	SHIP,NSHIPX		;SHUT OFF BITS FROM ANYONE ZAPPED
SWG1:	MOVE	B,ABSENT		;WHO IS ABSENT
	XOR	B,ABSEN0		;WHO WASN'T A MOMENT AGO, AND VICE VERSA?
	JUMPE	B,SWG1.1		;IF NO CHANGE, SAVE TIME BY SKIPPING LOOP
	MOVE	C,ABSENT		;GET CURRENT ABSENTEE WORD
	MOVEM	C,ABSEN0		;SAVE IT FOR NEXT TIME
SWG1.0:	TDNE	B,HANDBT(SHIP)		;HAS THIS SHIP CHANGED ABSENTEE STATUS?
	PUSHJ	P,WIPE			;YES, WIPE IT OUT OR RESURRECT IT
	SOJGE	SHIP,SWG1.0		;LOOP
	PUSHJ	P,CNT4			;REDISPLAY SCORES
	MOVE	SHIP,NSHIPX
SWG1.1:	SETOM	STEMP(SHIP)		;FOR LATER USE BY SELF-DESTRUCT TEST
	SKIPN	ZOWSW(SHIP)		;IF EXPLODED
	SKIPLE	HYPER(SHIP)		;OR IN HYPERSPACE
	TDZ	A,ALLBIT(SHIP)		;ZERO ALL HIS BITS
	SKIPE	ZOWSW(SHIP)		;EXPLODED?
	AOSE	RESTAR(SHIP)		;YES, INCREMENT HIS RESTART DELAY
	JRST	SWG1.2			;NOT TIME TO RESTART
	MOVE	W,CHANGD		;GET BITS CHANGED SO FAR DURING MATCH
	SKIPL	QRSTRT			;SET TO RESTART GAME?
	PUSHJ	P,GAME2			;NO: RESTART THIS PLAYER
SWG1.2:	SOJGE	SHIP,SWG1.1		;LOOP
	PUSHJ	P,JS			;GO DOWN AND INTERPRET THE BUTTONS
	MOVSI	BFP,BUF-SUN		;THIS MANY WORDS PRECEDE BUFFER
	ADDI	BFP,BUF-1		;INITIALIZE BUFFER DEPOSIT POINTER
	SKIPE	FORMUL			;IF PLAYING "FORMULA"
	PUSHJ	P,SLFDST		;CHECK FOR SELF-DESTRUCTS
	MOVE	SHIP,NSHIPX		;FOR ALL SHIPS DO:
SWG2:	SOSLE	HYPER(SHIP)		;DECREMENT HYPERTIME
	JRST	SWG2.2			;STILL IN HYPERSPACE
	MOVEI	B,5			;GET DESTRUCT CODE
	SKIPL	R14,STEMP(SHIP)		;DEAD BY SELF-DESTRUCT?
	PUSHJ	P,QRST			;YES, SET UP RESTART (R14 HAS KILLER)
	SKIPE	ZOWSW(SHIP)		;IS THIS SHIP DEAD?
	JRST	SWG2.1			;NOTHING AFFECTS HIM BUT GRAVITY
	MOVEI	B,4			;EXPLOSION CODE
	SKIPGE	HYPCNT(SHIP)		;DID HE EXPLODE IN HYPERSPACE?
	PUSHJ	P,QRST0			;YEP, SET UP A RESTART
	SOS	TCNT0(SHIP)		;DEC SHIP n TUBE 0 DELAY
	SOS	TCNT1(SHIP)		;DEC SHIP n TUBE 1 DELAY
	SKIPN	SRX(SHIP)		;TURNING?
	SKIPE	B,STX(SHIP)		;THRUSTING?
	JRST	SWG2.0			;YES, DON'T FIX PARTIAL DAMAGE
	SOSN	LDAM(SHIP)		;TIME LEFT ON RIGHT FIN
	IOR	B,ROTLBT(SHIP)		;TIME TO FIX IT
	SOSN	RDAM(SHIP)		;TIME LEFT ON LEFT FIN
	IOR	B,ROTRBT(SHIP)		;FIX IT
	ANDCAM	B,DMASK			;UPDATE DAMAGE MASK
SWG2.0:	TDC	A,HYPRBT(SHIP)		;PREPARE FOR TESTING FOR DUAL TURN
	MOVE	B,FORMOP(SHIP)		;GET FORMULA OPTION BITS
	MOVE	F,[1.0]			;GET DEFAULT MANEUVERABILITY
	TRNE	B,THROPT		;EXTRA MANEUVERABILITY?
	MOVE	F,MNEUVR		;YES, GET EXTRA FACTOR
	FMPM	F,STX(SHIP)		;MULTIPLY INTO THRUST
	FMPB	F,SRX(SHIP)		;AND ROTATION AND GET LATTER IN F
	SKIPN	ANGMOM			;DOES THE UNIVERSE HAVE ANGULAR MOMENTUM?
	JRST	.+3			;NO
	FMP	F,[0.08]		;YES, CHANGE VELOCITY TO ACCELERATION
	FADB	F,SANGMM(SHIP)		;ADD TO OLD RATE
	FIX	F,211000		;FIX IN LEFT HALF
	ADDB	F,SRA(SHIP)		;UPDATE SHIP ORIENTATION
	TLZ	F,777600		;ZERO ALL BUT INDEX BITS
	HLRZM	F,SR(SHIP)		;SAVE ORIENTATION INDEX
	PUSHJ	P,STCOL			;COMPUTE POSSIBLE COLLISIONS
SWG2.1:	PUSHJ	P,GRAV			;COMPUTE GRAVITATIONAL INFLUENCE
SWG2.2:	SOJGE	SHIP,SWG2		;REPEAT ABOVE FOR EACH SHIP
	PUSHJ	P,MINE			;DO ALL MINE CALCULATIONS
	MOVE	SHIP,NSHIPX		;THE NEXT SECTION FOR EACH SHIP
SWG3:	MOVE	R16,SP(SHIP)		;GET THE SHIP POSITION
	MOVE	R15,SR(SHIP)		;GET THE SHIP ORIENTATION INDEX
	MOVEI	W,14			;ALL NOSES ARE 12. FROM CENTER
	SKIPE	BGINR(SHIP)		;EXCEPT FOR AMATEURS
	ASH	W,-1			;WHICH ARE HALF SIZE
	IMUL	W,TAB(R15)		;MULTIPLY BY APPROPRIATE COS-SIN
	MOVEM	W,STEMP(SHIP)		;SAVE OFFSET OF NOSE FROM CENTER
	ADD	R16,W			;ADD IT IN
	MOVE	R14,SPICT(SHIP)		;GET ADDRESS OF PICTURE
	PUSHJ	P,XDRAW			;DRAW THE SHIP
	TDNE	A,TPBIT(SHIP)		;IS HE FIRING TORPEDOES?
	PUSHJ	P,CTORP			;TRY TO LAUNCH A TORPEDO
	SKIPN	STX(SHIP)		;ANY THRUST
	JRST	SWG4			;NO FLAME
	MOVE	R15,SR(SHIP)		;GET THE SHIP ORIENTATION
	MOVN	R16,TAB(R15)		;GET THE COS-SIN TABLE ENTRY
	IMUL	R16,TFTAB(SHIP)		;MULTIPLY BY MAGIC NUMBER
	SKIPE	BGINR(SHIP)		;IS THIS AN AMATEUR?
	PUSHJ	P,HALFSZ		;YES, HALVE THE OFFSET
	ADD	R16,SP(SHIP)		;SUBTRACT FROM BASIC POSITION
	MOVE	W,RAND			;GET RANDOM NUMBER
	ROT	W,1			;ROTATE IT
	MOVEM	W,RAND			;REPLACE THIS IN CORE
	TLO	W,777760		;TURN ON BITS: MAKE A RANDOM LENGTH
	HRRI	W,100			;SET ORIENTATION=100, DOWN
	MOVEI	R14,W			;R14 POINTS TO W
	MOVEI	X,0			;W+1 IS ZERO TERMINATES LIST
	PUSHJ	P,DRAW			;DRAW THE FLAME
SWG4:	SKIPN	SRX(SHIP)		;TURNING?
	JRST	SWG4A			;NO SIDE FLAME
	MOVE	R15,SR(SHIP)		;GET BASIC ORIENTATION
	MOVEI	W,72(R15)		;MAGIC ANGLE
	SKIPL	SRX(SHIP)		;TURNING CLOCKWISE?
	MOVEI	W,-72(R15)		;YES, NEGATE ANGLE
	ANDI	W,177			;MAKE INTO AN INDEX
	MOVE	R16,TAB(W)		;GET COS-SIN TABLE ENTRY
	IMUL	R16,TSFTAB(SHIP)	;MULTIPLY BY MAGIC NUMBER
	SKIPE	BGINR(SHIP)		;AMATEUR?
	PUSHJ	P,HALFSZ		;HALF SIZE
	ADD	R16,SP(SHIP)		;ADD TO BASIC POSITION
	SUBI	W,2(R15)		;REMOVE ORIENTATION FROM ANGLE AND
	TRO	W,4			;SHARPEN ANGLE SLIGHTLY
	HRLI	W,-4			;FLAME LENGTH = 4
	MOVEI	R14,W			;R14 POINTS TO W
	MOVEI	X,0			;W+1 IS ZERO TERMINATES LIST
	PUSHJ	P,DRAW			;DRAW SIDE FLAME
SWG4A:	SOJGE	SHIP,SWG3		;DO ALL THAT FOR EACH SHIP
	SETZ	W,			;UPDATE TORPEDOES.
SWG5:	CAML	W,TPNT			;ARE WE STILL IN TABLE?
	JRST	SWG6			;NOPE: ALL DONE
	SKIPG	TL(W)
	JRST	Z6			;TORP EXPIRED
	SOS	Y,TL(W)			;DECREMENT TORP LIFE
	TRNN	Y,-1			;SKIP IF TIME >0
	JRST	Z6			;THIS TORPEDO HAS EXPIRED
	MOVE	X,TP(W)			;GET THE POSITION
	ADD	X,TV(W)			;ADD THE VELOCITY
	MOVE	C,X			;SAVE NEW POSTION IN C
	PUSHJ	P,PLT1			;FOR CALL ON PLT1
	IORI	C,11126			;LVW WITH ENDPOINT,SIZ=BRT=2
	TRNN	Y,777770		;IS THIS ABOUT TO EXPIRE?
	IORI	C,37400			;YES: TURN ON BRIGHT AND BIG SIZE
	PUSH	BFP,C			;SAVE THIS IN THE DPY BUFFER
	EXCH	X,TP(W)			;SWAP NEW-OLD POSITION
	XOR	X,TP(W)			;XOR NEW AND OLD
	TDNN	X,[XWD	400000,400000]	;IF THESE BITS SET THEN SKIP
	AOJA	W,SWG5			;LOOK AT NEXT TORP
	MOVE	F,TV(W)			;POSSIBLE WRAP OVER. GET VELOCITY
	XOR	F,TP(W)			;XOR WITH NEW POSITION
	AND	X,F			;AND WITH THE XOR OF OLD-NEW
	TDNE	X,[XWD	400000,400000]	;IF THESE ARE STILL SET
	PUSHJ	P,TCOL			;THEN WE HAVE WRAPPED. CHECK TCOL
	AOJA	W,SWG5			;LOOK FOR MORE
Z6:	SOS	X,TPNT			;TORP HAS EXPIRED
	CAML	W,X			;THIS THE LAST IN TABLE?
	JRST	SWG6			;YES: OUT OF THE LOOP
	MOVE	Y,TP(X)			;GET LAST FROM TABLE
	MOVEM	Y,TP(W)			;USE IT TO WIPE THIS ONE
	MOVE	Y,TV(X)			;...
	MOVEM	Y,TV(W)			;...
	MOVE	Y,TL(X)			;...
	MOVEM	Y,TL(W)			;...
	MOVE	Y,TVX(X)		;...
	MOVEM	Y,TVX(W)		;...
	MOVE	Y,TVY(X)		;...
	MOVEM	Y,TVY(W)		;...
	JRST	SWG5			;LOOK FOR MORE. DONT CHANGE W.
SWG6:	PUSHJ	P,TWINKL		;TWINKLE ONE RAY OF THE SUN
	HLRZM	BFP,BPTRX+1		;STORE NUMBER OF WORDS TO DISPLAY
	SETOM	SHIPFG			;TELL PDP-10 WE HAVE A DISPLAY READY
	SETOM	SIXDON
	SKIPN	DEBUG			;ARE WE USING DDT?
	DISMIS				;NOPE: DISMISS THIS SW MODULE
	SETZ	B,			;GO TO SLEEP FOR A WHILE
	SLEEP	B,			;SLEEP 1 TICK
	JRST	SW6GO			;A GO TO WORK AGAIN

DIE:	MOVEI A,'SSW'		;Stop spacewar processes
	SPCWGO A,
	DISMIS			;Stop this spacewar run


	SUBTTL	THE MINE CALCULATIONS
IFE NMINE,<
MINE:	POPJ	P,			;NO MINES
>
IFG NMINE,<
MINE:	MOVE	SHIP,NMINEX		;ALL THE CALCULATIONS FOR THE MINES
	ADDI	SHIP,NSHIP-1		;ADD TO INDEX THE MINE TABLES
	MOVE	R15,BFP			;SAVE BFP TO LEARN IF ANY ARE ALIVE
MINE1:	CAIG	SHIP,NSHIP-1		;ARE WE DONE YET?
	JRST	MINE6			;YES. TO EXIT STUFF
	SKIPN	C,SP(SHIP)		;GET MINE POSITION
	SOJA	SHIP,MINE1		;MINE IS DEAD
	HLRE	B,C			;GET MINE -2Y
	HRRE	C,C			;GET MINE  2X
	MOVEI	R12,1			;1 = TORPS, 0 = MINES
	MOVE	R11,TPNT		;GET TORPEDO COUNT
	JRST	MINE3			;CHECK MINE-TORPEDO COLLISION
MINE2:	MOVEI	R11,-1(SHIP)		;GET INDEX OF THIS MINE
	SUBI	R11,NSHIP-1		;LOOK AT MINE- LOWER MINES
MINE3:	SOJL	R11,MINE4		;ALL DONE WITH THESE OBJECTS
	HLRE	W,@STTB2(R12)		;GET OBJECT POSITION -2Y
	HRRE	X,@STTB2(R12)		;GET OBJECT POSITION +2X
	SUB	W,B			;GET DY
	SUB	X,C			;GET DX
	FSC	W,223			;FLOAT DIFFERENCE
	FSC	X,223			;FLOAT
	FMP	W,W			;SQUARE
	FMP	X,X			;SQUARE
	FAD	W,X			;GET R^2
	CAMLE	W,MTCOLR		;COMPARE TO COLLISION RADIUS
	JRST	MINE3			;OK. LOOK FOR MORE
	SETZM	@STTB3(R12)		;ZERO A MINE OR TORP LIFE
MINEFL:	PUSHJ	P,FLASH			;MAKE MINE FLASH
	SETZM	SP(SHIP)		;MINE IS NOW GONE AWAY
	SOJA	SHIP,MINE1		;LOOK AT OTHER MINES
MINE4:	SOJE	R12,MINE2		;LOOK FOR MINE-MINE COLLISIONS
	PUSHJ	P,GRAV			;COMPUTE GRAVITY FOR MINE
	SKIPN	C,SP(SHIP)		;GET POSITION
	JRST	MINEFL			;THIS IS A LOSER
	PUSHJ	P,PLT1			;MAKE IT A VECTOR
	IORI	C,6+VINVIS+VABS+5*VBRT	;INVIS, ABS, BRT 5
	PUSH	BFP,C			;SEND OUT VECTOR
	PUSH	BFP,[BYTE(7)0,3(2)1(7)<-1>,-2(2)1(4)2]	;DRAW MINE
	PUSH	BFP,[BYTE(7)<-2>,-1(2)1(7)2,-1(2)1(4)2]
	PUSH	BFP,[BYTE(7)1,-2(2)1(7)1,2(2)1(4)2]
	PUSH	BFP,[BYTE(7)2,1(2)1(7)<-2>,1(2)1(4)2]
	SOJA	SHIP,MINE1		;NEXT MINE
MINE6:	CAME	R15,BFP			;ANY TEXT DONE THIS TIME?
	TDZA	R11,R11			;YES, ZERO THE MINE RESTART TIMER
	MOVE	R11,RSTARD		;NO, GET RESTART DELAY
	SKIPL	MINSTR			;RESTART ALREADY BEGUN?
	MOVNM	R11,MINSTR		;NO, SET IT
	AOSE	MINSTR			;INCREMENT AND TEST IT
	POPJ	P,			;RETURN
					;FALL INTO MINE LAYING



LAYMIN:	MOVE	W,NMINEX		;LAY MINES: GET NUM OF MINES TO MAKE
LAY1:	SOJL	W,CPOPJ			;DECREMENT COUNT. RETURN WHEN DONE
	MOVE	R12,RCONST		;LOAD THE RANDOM BASE
	ADDB	R12,RANDX		;GET A RANDOM NUMBER
	MOVEM	R12,MINEP(W)		;SAVE AS THE MINE POSITION
	HRRE	X,R12			;GET 2X
	HLRE	Y,R12			;GET -2Y
	FSC	X,223			;FLOAT X
	FSC	Y,223			;FLOAT Y
	MOVEM	X,MINEX(W)		;SAVE X POSITION
	MOVNM	Y,MINEY(W)		;SAVE Y POSITION
	MOVN	Y,Y			;GET +Y POSITION
	MOVE	D,X			;GET X
	FMP	D,D			;X^2
	MOVE	B,Y			;GET Y
	FMP	B,B			;Y^2
	FADB	B,D			;R^2
	PUSHJ	P,SQRT			;GET R
	FMP	B,D			;B _ R^3
	MOVE	C,GG			;GRAV CONSTANT
	FDVM	C,B			;B _ GG/R^3
	PUSHJ	P,SQRT			;GET SQRT(GG/R^3)
	MOVE	C,B			;SQRT(GG/R) IN C AND B
	FMP	C,X			;Y VELOCITY
	FMP	B,Y			;X VELOCITY
	MOVNM	C,MINEVY(W)		;SAVE -Y VELOCITY
	MOVEM	B,MINEVX(W)		;SAVE +X VELOCITY
	FIX	B,223000
	FIX	C,223000
	HRL	B,C			;GET Y VELOCITY INTO B
	MOVEM	B,MINEV(W)		;SAVE THE MINE VELOCITY (FIXED POINT)
	TRNE	R12,1000		;TEST A RANDOM BIT
	JRST	LAY1			;KEEP THIS VELOCITY SENSE
	MOVNS	MINEV(W)		;NEGATE SENSE OF VELOCITIES
	MOVNS	MINEVX(W)		;NEGATE SENSE OF VELOCITIES
	MOVNS	MINEVY(W)		;NEGATE SENSE OF VELOCITIES
	JRST	LAY1			;LOOP
>


	SUBTTL	LAUNCH A TORPEDO
	
CTORP:	MOVE	W,TPNT			;GET COUNT OF ACTIVE TORPS
	MOVE	X,UTUBE(SHIP)		;GET THE TUBE NUMBER FOR THIS
	CAMGE	W,TTBMAX		;IS THERE ROOM IN THE TABLE?
	SKIPL	@RDELAY(X)		;YES: CHECK RELOAD DELAY
	POPJ	P,			;TABLE FULL OR NOT RELOADED
	SOSLE	W,TPCN(SHIP)		;DECREMENT TORPEDO COUNT
	JRST	TRLD			;LAUNCH IT
	MOVE	W,NSHIPX		;CHECK ALL OTHER SHIPS
	SKIPLE	TPCN(W)			;ANY TORPS LEFT FOR THIS?
	POPJ	P,			;SOMEBODY HAS TORPEDOES
	SOJGE	W,.-2			;LOOK FOR SOMEONE WITH TORPS
	MOVE	F,RSTARD		;USE RSTARD AS GAME RESET DELAY
	JRST	QRST4			;ALL EMPTY: GO SET RESTART
	
TRLD:	MOVE	R16,FORMOP(SHIP)	;GET OPTION BITS
	MOVN	B,TRELOD		;PREPARE TO SHAVE RELOAD TIME
	ASH	B,-3			;DECREMENT IS 1/8 OF TOTAL
	TRNN	R16,FIROPT		;DOES THIS SHIP HAVE THAT OPTION?
	MOVEI	B,0			;NO, GIVE HIM NORMAL TIME
	ADD	B,TRELOD		;COMPUTE RELOAD TIME
	MOVEM	B,@RDELAY(X)		;RESET DELAY ON THIS TUBE
	TRC	X,1			;SET UP THE OTHER TUBE NUMBER
	MOVEM	X,UTUBE(SHIP)		;USE OTHER TUBE NEXT TIME
	TRNE	R16,FIROPT		;FIREPOWER OPTION?
	ADDM	X,TPCN(SHIP)		;YES, COUNT ONLY EVERY OTHER SHOT
	MOVE	W,LATNCY		;LOAD THE LATENCY PERIOD
	CAML	W,@RDELAY(X)		;SKIP IF EXISTING DELAY > LATENCY
	MOVEM	W,@RDELAY(X)		;USE LATENCY AS MINIMUM
	MOVE	W,SR(SHIP)		;GET THE SHIP ORIENTATION
	HLRE	X,TAB(W)		;GET THE COSINE
	MUL	X,ITV			;MULTIPLY BY TORP VELOCITY
	HRRE	W,TAB(W)		;GET THE SINE
	MUL	W,ITV			;Y COMPONENT OF VELOCITY
	HLR	Y,X			;RELATIVE VELOCITY OF TORP
	ADD	Y,SV(SHIP)		;PLUS SHIP VELOCITY
	MOVE	W,TPNT			;GET NUMBER OF TORPS
	MOVEM	Y,TV(W)			;SAVE THE ABSOLUTE TORP VELOCITY
	MOVN	X,STEMP(SHIP)		;OFFSET FROM CENTER FOR LOB SHOT
	TRNE	R16,LOBOPT		;DOES HE HAVE THAT OPTION?
	TDNE	A,HYPRBT(SHIP)		;IS HE USING IT?
	SKIPA	X,STEMP(SHIP)		;NO, GET OFFSET FOR NOSE AND SKIP
	SETZM	TV(W)			;LOB SHOT, ZERO VELOCITY
	ADD	X,SP(SHIP)		;ADD SHIP POSITION TO OFFSET
	MOVEM	X,TP(W)			;SAVE AS THE INITIAL TORP POSIT.
	MOVE	X,TLIFE			;GET THE LIFE
	SKIPN	Y,HANDCP		;GET HANDICAP BITS
	JRST	TRLD.1			;NONE SET, SKIP THIS TO SAVE TIME
	AND	Y,HANDBT(SHIP)		;GET BITS FOR THIS SHIP
	LSH	X,3			;MULTIPLY TLIFE BY 8
	MOVEI	B,2			;DO THIS FOR EACH HANDICAP BIT:
TRLD.0:	TRNE	Y,111111		;IS THIS HANDICAP BIT SET?
	SUB	X,TLIFE			;YES, DECREASE LIFE OF TORP
	LSHC	X,-1			;HALVE LIFE AND GET NEXT H-BIT 
	SOJGE	B,TRLD.0		;LOOP, FINAL RANGE = 1/8 TO 1 * TLIFE
TRLD.1:	HRL	X,SHIP
	MOVEM	X,TL(W)			;SHIP NUMBER,,LIFE TIME
	AOS	TPNT			;COUNT A NEW TORPEDO
TCOL:	MOVE	X,TPNT			;DOES TORP EVER COLLIDE WITH ANOTHER?
	HRRE	B,TV(W)			;ACTIVE TORPS IN X. GET THIS VELOCITY
	FSC	B,223			;FLOAT THIS NUMBER
	MOVEM	B,TVX(W)		;SAVE X COMPONENT OF T. VELOCITY
	HLRE	C,TV(W)			;GET -2Y VELOCITY
	FSC	C,223			;MAKE IT FLOAT
	MOVEM	C,TVY(W)		;SAVE Y COMPONENT OF VELOCITY
	HRRE	R11,TP(W)		;GET 2X POSITION
	FSC	R11,223			;FLOAT IT 
	HLRE	R12,TP(W)		;GET -2Y POSITION
	FSC	R12,223			;FLOAT IT
	HRLO	R16,TL(W)		; TL,,-1 IN R16
TCL1:	SOJL	X,TCBASH		;LOOK AT NEXT TORPEDO IN TABLE
	CAMN	W,X			;IS THIS US?
	JRST	TCL1			;YES: SKIP THE CALCULATION
	HRRE	B,TP(X)			;GET THE 2X POSITION
	FSC	B,223			;FLOAT IT 
	FSBM	R11,B			;GET DELTA X IN B
	HLRE	C,TP(X)			;GET -2Y POSITION
	FSC	C,223			;FLOAT IT
	FSB	C,R12			;FORM DELTA Y IN C
	MOVE	Y,TVX(W)		;Y _ VX1-VX2
	FSB	Y,TVX(X)		;...
	MOVN	R15,TVY(W)		;R15  _ VY1-VY2
	FAD	R15,TVY(X)		;...
	MOVE	D,B		;D _"B" =2((X1-X2)(VX1-VX2)+(Y1-Y2)(VY1-VY2))
	FMP	D,Y
	MOVE	F,C
	FMP	F,R15
	FAD	D,F

	FMP	B,B		;B _ "C" = (X1-X2)^2 + (Y1-Y2)^2 - R^2
	FMP	C,C
	FAD	B,C
	FSB	B,TR2
	JUMPLE	B,TBAM			;IMMEDIATE DISINTEGRATION OF TORPS

	FMP	Y,Y		;Y _ "A" = (VX1-VX2)^2 + (VY1-VY2)^2
	FMP	R15,R15
	FAD	Y,R15
	JUMPE	Y,TCL1
	FMP	B,Y		;B = "B"^2 - 4*"A"*"C"
	MOVE	C,D
	FMP	C,C
	FSBM	C,B
	JUMPLE	B,TCL1		;DISCRIMINANANT IS < 0, SO NO COLLISION.

	PUSHJ	P,SQRT		;FINISH QUADRATIC FORMULA.
	MOVN	D,D		;B _ -"B"-SQRT(DISC.)
	FSBM	D,B
	FDV	B,Y
	FIX	B,233000	;FIX RELATIVE TIME OF COLLISION.
	JUMPL	B,TCL1		;IF NEG TIME
	JUMPE	B,TBAM		;INSTANT EXPLOSION
	HRRZ	C,TL(W)		;GET LIFTIME
	HRRZ	D,TL(X)		;GET LIFTIME
	CAMG	B,D		;WILL BOTH TORPS BE ALIVE THEN?
	CAMLE	B,C		;NOPE: FORGET IT
	JRST	TCL1		;NO COLLISION
	HRL	B,B
	HRR	B,X
	CAMG	B,R16		;IS THIS COLLISION SOONER THAN OUR SOONEST?
	MOVE	R16,B		;YES
	JRST	TCL1		;LOOP
TCBASH:	HLRM	R16,TL(W)	;SAVE THE EXPECTED LIFE
	TRNN	R16,700000	;R16 CONTAINS THE GUY WE COLIDE WITH
	HLRM	R16,TL(R16)	;SO SAVE THIS AS HIS TL
	POPJ	P,

TBAM:	SETZM	TL(W)		;MAKE BOTH TORPS. GO AWAY.
	SETZM	TL(X)
	POPJ	P,


	SUBTTL	XDRAW AND DRAW
	
XDRAW:	SKIPE	ZOWSW(SHIP)		;IS THIS GUY GONE?
	JRST	ZORCH			;YES.
	SKIPG	R12,HYPER(SHIP)		;IS THIS SHIP IN HYPERSPACE?
	JRST	XDRAW2			;NO. DRAW IT
	CAILE	R12,60			;TIME FOR THE STAR OF THE EAST?
	POPJ	P,			;NOPE
XDRAW1:	MOVE	C,SP(SHIP)		;GET CENTER OF SHIP
	PUSHJ	P,PLT1			;MAKE LVW
	IORI	C,6+7*VBRT+VENDP+VABS	;BRIGHT ENDPOINT ABSOLUTE
	PUSH	BFP,C			;STUFF IN BUFFER
	PUSH	BFP,C			;SECOND TIME FOR A VERY BRIGHT STAR
	POPJ	P,			;RETURN
XDRAW2:	MOVE	R12,UTUBE(SHIP)		;GET THE NEXT TUBE TO USE
	SKIPGE	@RDELAY(R12)		;SKIP IF TUBE IS UNREADY
	SKIPGE	TPCN(SHIP)		;TUBE READY. ANY TORPS LEFT?
	JRST	DRAW			;NOT READY OR EMPTY
	MOVE	R12,TPNT		;GET ACTIVE COUNT
	CAMGE	R12,TTBMAX		;LESS THAN MAX
	PUSHJ	P,XDRAW1		;YES, SHOW RELOAD LIGHT
DRAW:	MOVE	C,R16			;GET SHIP NOSE POSITION
	PUSHJ	P,PLT1			;MAKE LVW
	IORI	C,34146			;INVISIBLE, ABSOLUTE, BRITE
	PUSH	BFP,C			;STUFF THE LVW
L2:	SKIPN	R12,(R14)		;R14 POINTS TO SHIP TABLE
	POPJ	P,			;NO MORE SHIP TABLE
	HLRE	F,R12			;GET THE STEP COUNT
	ADD	R12,R15			;ADD THE ORIENTATION
	ANDI	R12,177			;MAKE IT AN INDEX
	MOVE	R12,TAB(R12)		;GET COS-SIN ENTRY
	SKIPN	BGINR(SHIP)		;IS THIS GUY AN AMATEUR?
	JRST	LLL			;NO, DRAW FULL SIZE
	ASH	R12,-1			;YES, HALVE THE STEP SIZE
	TRNE	R12,200000		;ACCOUNT FOR SIGN PROPOGATION
	TROA	R12,400000		;IN RIGHT HALFWORD
	TRZ	R12,400000
LLL:	ADD	R16,R12			;ADD ORIENTATION TO POSITION
	MOVE	C,R16			;LOAD NEW POINT
	PUSHJ	P,PLT1			;MAKE LVW
	IORI	C,14126			;TURN ON ENDPOINT, BRITE
	PUSH	BFP,C			;STUFF IT
	AOJL	F,LLL			;LOOP UNTIL NO MORE STEPS
	AOJA	R14,L2			;GET NEXT PART OF SHIP TABLE

PLT1:	LDB	B,[POINT 10,C,27]	;GET BITS 18-27: X POSITION
	ASH	C,-1			;SHIFT -2Y TO -Y
	SETCM	C,C			;ONES COMPLEMENT: MAKE +Y
	LSHC	B,-12			;SHIFT X INTO C
	ASH	C,-1			;ONE MORE PLACE FOR 11 BIT FIELD
	TRZ	C,37777			;SHUT OF ALL BUT X,Y BITS
	POPJ	P,			;AND RETURN
ZORCH:	SKIPLE	ZORCHP(SHIP)		;IS THIS FIRST TIME THRU?
	JRST	ZORCH1			;NOPE,
	PUSHJ	P,FLASH			;FIRST TIME: MAKE A FLASH
	MOVE	R14,RCONST
	ADDB	R14,RANDX		;MAKE A NEW RANDOM NUMBER
	MOVEM	R14,HYPCNT(SHIP)	;HYPCNT ISN'T NEEDED ANYMORE.
ZORCH1:	AOS	R14,ZORCHP(SHIP)	;COUNT TIMES THRU
	SKIPL	ZOWSW(SHIP)		;QUICK RETURN FOR FALL IN THE SUN
	CAIL	R14,60			;IS THIS ENOUGH?
	POPJ	P,			;RETURN
	LSH	R14,-3			;DIVIDE BY 32
	SUBI	R14,13			;14 IS MAX NUMBER OF FRAGS
	MOVE	R12,[POINT 3,HYPCNT(SHIP)]	;POINTER TO A DOZEN VELOCITIES
	MOVE	R11,[POINT 7,HYPCNT(SHIP),6]	;POINTER THAT SLIDES
ZORCH2:	ILDB	B,R12			;GET A VELOCITY
	IMUL	B,ZORCHP(SHIP)		;TIMES THE TIME
	ASH	B,-2			;SCALE IT DOWN
	LDB	C,R11			;GET A DIRECTION
	ADD	C,R15			;ADD IN BASE DIRECTION
	ANDI	C,177			;MAKE INDEX TO TAB
	MUL	B,TAB(C)		;MULTIPLY BY FRAGMENT DIRECTION
	SUB	R11,[XWD 20000,0]	;SLIDE THE DIRECTION OVER TWO BITS
	ADD	C,SP(SHIP)		;ADD IN THE BASIC POSITION
	PUSHJ	P,PLT1			;MAKE LVW
	MOVE	B,RCONST		;GET A RANDOM NUMBER
	ADDB	B,RANDX			;FOR THE BRIGHTNESS
	ANDI	B,7*VBRT		;AND OUT ALL BUT BRT
	IORI	C,6+VABS+VENDP(B)	;OR THE MAJIC BITS
	PUSH	BFP,C			;STUFF IT
	TRNE	B,VBRT
	PUSH	BFP,C
	AOJLE	R14,ZORCH2		;LOOP FOR EACH PARTICLE
	POPJ	P,			;RETURN

HALFSZ:	ASH	R16,-1			;HALVE AN X,,Y COORDINATE PAIR IN R16
	TRNE	R16,200000		;ACCOUNT FOR SIGN PROPOGATION
	TROA	R16,400000		;IN RIGHT HALFWORD
	TRZ	R16,400000
	POPJ	P,

FLASH:	MOVE	C,SP(SHIP)		;MAKE A FLASH. GET OBJECT POSITION
FLASH0:	PUSHJ	P,PLT1			;MAKE LVW
	IORI	C,6+7*VBRT+VABS+VINVIS+2*VSIZ	
FLASHX:	MOVEI	B,FLASHL-1		;GET TABLE SIZE
FLASH1:	PUSH	BFP,C			;STUFF VECTOR
	PUSH	BFP,FLASHT(B)		;STUFF CHARACTER
	POPJ	P,			;RETURN

FLASHT:	<ASCII	/*/>+1			;TABLE OF CHARACTERS

	<ASCII	/W/>+1

	<ASCII	/#/>+1

	<ASCII	/@/>+1

	<ASCII	/*/>+1
	SDEF(FLASHL,.-FLASHT)		;FLASH TABLE LENGTH


	SUBTTL	SIN, COS (and old SQRT)

COS:	FSB	A,[4.712389]
SIN:	MOVNI	F,10
	MOVE	Y,[1.0]
	MOVE	C,[1.0]
	JFCL	10,.+1
	MOVE	W,A
	MOVN	D,A
	FMP	D,A
L1:	FAD	Y,[1.0]
	FMP	C,Y
	FAD	Y,[1.0]
	FMP	C,Y
	FMP	W,D
	MOVE	X,W
	FDV	X,C
	JFCL	10,CPOPJ
	FAD	A,X
	AOJL	F,L1
	POPJ	P,


;Old SQRT routine, RIP.  Superceded by blasphemous code on next page.

;SQRT:	ASHC	B,-33
;	SUBI	B,201
;	ROT	B,-1
;	PUSH	P,B
;	LSH	B,-43
;	ASH	C,-10
;	FSC	C,177(B)
;	MOVEM	C,1(P)			;WATCH OUT FOR THE BUM WHO WROTE THIS
;	FMP	C,SQ1(B)
;	FAD	C,SQ2(B)
;	MOVE	B,1(P)
;	FDV	B,C
;	FAD	C,B
;	FSC	C,-1
;	MOVE	B,1(P)
;	FDV	B,C
;	FADR	B,C
;	POP	P,C
;	FSC	B,(C)
;	POPJ	P,
;SQ1:	0.8125				;CONSTANTS FOR SQRT ROUTINE
;	0.578125
;SQ2:	0.302734
;	0.421875


	SUBTTL	new kahan SQRT

;And you thought the old SQRT was bad ! This one is based on code due to Kahan and
;used on the Macsyma system.  Various accreted comments are preserved.  This routine
;is supposed to be accurate to about 1/2 an LSB and 20% faster than of yore.

SQRT:				;ARG IN B
	jumpe B,SQRT.0		;Exit on zero arg
	tlz B,400000		;Clear sign bit to force positive arg just in case
SQRT.1:
	MOVE C,B		;SAVE ARG FOR LATER
	ASH B,-1
	ADD B,[265116421]	;THAT'S 265116421 (KAHAN BLACK MAGIC)
	TLON B,400
	 JRST SQRT.2
	FMPRI B,301461		;(301461)=(FSC 1.19140625 100)
	JRST SQRT.3
SQRT.2:
	FMPRI B,300653		;(300653)=(FSC 0.833984375 100)

;NOW TWO NEWTON ITERATIONS, MODIFIED
SQRT.3:
	push P,D		;Save an AC for fun and profit
	MOVE D,C		;get saved copy
	FDV D,B			;UNROUNDED DIVIDE
	FAD B,D			;UNROUNDED ADD
	pop P,D			;restore D
				;In effect FSC B,-1 but Kahan sez:
	SUB B,[1000002645]	;INSTEAD OF DIVISION BY 2, SUBTRACT 1000002645
	FDV C,B			;UNROUNDED DIVIDE
	FADR B,C		;ROUNDED ADD!
	FSC B,-1

SQRT.0:
	POPJ P,			;bye bye

;;; A FEW HINTS, PAINFULLY WORKED OUT BY GLS AND RZ:
;;;	THE ASH BY -1 DIVIDES THE EXPONENT BY 2, AND MUNCHES
;;;	THE MANTISSA IN A BIZARRE WAY.
;;;	THE ADDITION OF 265116421 IS GUARANTEED TO CARRY
;;;	INTO THE 3.9 BIT, ASSUMING A NORMALIZED INPUT.  THIS
;;;	WILL COMPLEMENT THE ORIGINAL LOW EXPONENT BIT.
;;;	THIS IS THEN TESTED BY THE TLON, WHICH ALSO FORCES
;;;	THE 3.9 BIT ON, MAKING THE NEW NUMBER NORMALIZED.
;;;	THE SUBTRACTION OF 1000002645 INDEED DIVIDES BY 2,
;;;	BY SUBTRACTING 1 FROM THE EXPONENT; AND THE REST DOES
;;;	A WEIRD LITTLE PERTURBATION WHICH, HOWEVER, CANNOT
;;;	BORROW FROM THE EXPONENT.




	SUBTTL	GRAV:	CALCULATE SHIP POSITION
GRAV:	CAILE	SHIP,NSHIP-1		;SKIP IF A SHIP
	JRST	GRAV1			;IS A MINE
	SKIPGE	ZOWSW(SHIP)		;LOOK AT SHIP'S ZOWSW
	POPJ	P,			;DID COLLIDE WITH THE SUN
	SKIPA	R16,FORMOP(SHIP)	;GET OPTION BITS
GRAV1:	SETZ	R16,			;MINES HAVE NO OPTIONS!
	MOVE	B,SX(SHIP)		;GET X POSITION
	MOVE	C,SY(SHIP)		;GET Y POSITION
	FMP	B,B			;X^2
	FMP	C,C			;Y^2
	FAD	B,C			;R^2
	MOVN	X,B			;X _ -R^2
	PUSHJ	P,SQRT			;GET R
	CAMG	B,SCR			;ARE WE TOO CLOSE TO THE SUN?
	JRST	ZOWIE1			;YES: MAKE OBJECT DISAPPEAR
	FMP	B,X			;B _ -R^3
	SETZ	C,			;SET UP FOR NULL GRAVITY
	TRNE	R16,GRVOPT		;DOES HE HAVE THAT OPTION?
	TDNE	A,HYPRBT(SHIP)		;IS HE USING IT?
	MOVE	C,GG			;NO, GET GRAVITY CONSTANT IN C
	FDVB	C,B			;-GG/R^3 IN C AND B
	FMP	B,SX(SHIP)		;-GG*X/R^3 IN B = X ACCELERATION
	FMP	C,SY(SHIP)		;-GG*Y/R^3 IN C = Y ACCELERATION
GRAV2:	CAIG	SHIP,NSHIP-1		;IS THIS A MINE?
	SKIPN	STX(SHIP)		;IS HE THRUSTING?
	JRST	GINT			;NO THRUST FROM A SHIP, OR A MINE
	MOVE	W,MNEUVR		;GET MANEUVERABILITY FACTOR
	SKIPE	BGINR(SHIP)		;IS HE A BEGINNER?
	FMPM	W,STX(SHIP)		;YES, INCREASE THRUST
	MOVE	D,SR(SHIP)		;GET THE SHIP ORIENTATION
	HRRE	W,TAB(D)		;GET THE -COS
	FSC	W,206			;FLOAT IT
	FMP	W,STX(SHIP)		;MULTIPLY WITH THE THRUST
	FAD	B,W			;ADD THIS TO THE X ACCELERATION
	HLRE	W,TAB(D)		;GET THE SIN
	FSC	W,206			;FLOAT IT
	FMP	W,STX(SHIP)		;MULTIPLY BY THE THRUST
	FSB	C,W			;SUBTRACT FROM THE Y ACCELERATION
	
GINT:	FMP	B,GDT			;MULTIPLY ACCELERATION BY DELTA T
	FMP	C,GDT			;THE PRODUCT IS DELTA VELOCITY
	FADB	B,SVX(SHIP)		;ADD DELTA TO EXISTING VELOCITY
	FADB	C,SVY(SHIP)		;...
	FMP	B,GDT			;TAKE VELOCITY*DELTA T
	FMP	C,GDT			;FORMS A DELTA X AND Y
	MOVE	W,C			;DELTA Y IN W
	MULI	W,400			;FIX IT (CAN'T USE "FIX" OP BECAUSE
	TSC	W,W			;  ON KA-10 IT CAN'T YIELD >= 2^27)
	ASH	X,-211(W)		;SO USE HACK FROM HAKMEM
	MOVNM	X,SV(SHIP)		;SAVE -2Y IN SHIP VELOCITY
	MOVE	W,B			;GET DELTA X INTO W
	MULI	W,400			;FIX IT: SEPARATE EXP FROM FRACTION
	TSC	W,W			;TAKE ONE'S COMP ABS VALUE OF EXP
	ASH	X,-211(W)		;SCALE THE FRACTION
	HLRM	X,SV(SHIP)		;-2*DELTA Y,,2*DELTA X IN SV
	FAD	B,SX(SHIP)		;ADD THE POSITION
	FAD	C,SY(SHIP)		;...
	CAML	B,[511.0]		;CHECK THE POSITION ON THE SCREEN
	FSB	B,[1024.0]
	CAMG	B,[-512.0]
	FAD	B,[1024.0]
	CAML	C,[511.0]
	FSB	C,[1024.0]
	CAMG	C,[-512.0]
	FAD	C,[1024.0]
	MOVEM	B,SX(SHIP)
	MOVEM	C,SY(SHIP)		;SAVE (REVISED) POSITIONS
	MULI	C,400			;FIX THE POSITIONS
	TSC	C,C
	ASH	D,-211(C)
	MOVNM	D,SP(SHIP)
	MULI	B,400
	TSC	B,B
	ASH	C,-211(B)
	HLRM	C,SP(SHIP)		;SAVE FIXED POSITIONS IN SP
	POPJ	P,


	SUBTTL	SHIP - TORPEDO AND SHIP - MINE COLLISION

STCOL:	MOVE	W,SR(SHIP)		;GET SHIP ORIENTATION
	MOVN	X,TAB(W)		;GET --COS
	HRLZ	Y,TAB(W)		;AND +SIN
	MOVN	W,SP(SHIP)		;GET --Y POS.
	HRLZ	D,SP(SHIP)		;AND X POS.
	MOVEI	R12,1			;1 FOR TORPS, 0 FOR MINES
STL0:	MOVE	R11,@STTB1(R12)		;GET TPNT OR NMINEX
STL1:	SOJL	R11,STL2		;ALL DONE WITH TORPS-DO MINES
	MOVE	B,@STTB2(R12)		;GET POS. OF TORP (OR MINE)
	JUMPE	B,STL1			;EXPIRED MINE
	MOVE	F,R12			;WE MAY INTERPOLATE IF F > 0
STL1.1:	MOVN	C,B			;LOAD C WITH 2Y POSITION OF TORP
	MOVS	B,B			;SWAP B. X POSITION OF OBJECT
	SUB	B,D			;GET DELTA X FROM TORP TO SHIP
	CAMG	B,[25B9]		;IS IT EVEN CLOSE?
	CAMGE	B,[-25B9]		;....
	JRST	STL1			;NO
	SUB	C,W			;GET DELTA Y
	CAMG	C,[25B9]		;IS IT CLOSE?
	CAMGE	C,[-25B9]		;.....
	JRST	STL1			;NO
	MOVN	R14,BGINR(SHIP)		;SEE IF THIS GUY IS A BEGINNER
	ASH	B,(R14)			;IF SO, SHIP IS HALF SIZE
	ASH	C,(R14)			;IN BOTH DIMENSIONS
	MOVE	R14,B			;R14 _ DELTA X
	MUL	R14,X			;GET dx cos (phi)
	MOVE	R15,C			;R15 _ DELTA Y
	MUL	R15,Y			;GET dY sin(phi)
	SUB	R14,R15			;x' = dx cos(phi)-dy sin(phi)
	MOVEM	R14,SAVSID		;REMEMBER SIDE WERE ON
	MOVM	R14,R14			;GET ABS(X'). (SHIP IS SYMMETRIC)
	CAML	R14,[13B17]		;IN BOUNDS?
	JRST	STINTR			;NOPE: SEE ABOUT INTERPOLATING
	MOVE	R15,C			;NOW ROTATE DY INTO SHIP COORDINATES
	MUL	R15,X			;DY COS(PHI)
	MUL	B,Y			;DX SIN(PHI)
	ADD	R15,B			;Y' = DXSIN(PHI)+DY COS(PHI)
	CAMG	R15,[25B17]		;Y VALUE IN BOUNDS?
	CAMGE	R15,[-27B17]		;...
	JRST	STINTR			;NOPE: SEE ABOUT INTERPOLATION
	CAML	R15,[-12B17]		;SKIP IF TORP IN WIDE TAIL
	CAMG	R14,[4B17]		;SKIP UNLESS TORP IN NARROW BODY
	JRST	STX2			;WE HAVE A COLLISION
STINTR:	SOJL	F,STL1			;NO INTERPOLATION: SECOND TRY OR MINES
	MOVN	B,TV(R11)		;GET -(THE TORPEDO VELOCITY)
	HRRE	C,B			;GET RIGHT SIDE
	ASH	B,-1			;HALVE LEFT OF B
	ASH	C,-1			;HALVE RIGHT OF C
	HRR	B,C			;RELOAD B WITH HALF OF RIGHT SIDE
	ADD	B,TP(R11)		;ADD TO TORPEDO POSITION
	JRST	STL1.1			;B CONTAINS INTERPOLATED POSITION
STL2:	SOJGE	R12,STL0		;AFTER TORPS, DO MINES, THEN
	POPJ	P,			;RETURN
STX2:	MOVE	R16,FORMOP(SHIP)	;GET OPTION BITS
	TRNN	R16,FINOPT		;INVULNERABLE FINS?
	SKIPE	DAMHIT			;PARTIAL DAMAGE ALLOWED?
	CAMG	R14,[4B17]		;DIRECT HIT?
	JRST	STX3			;NO PARTIAL DAMAGE OR KILLED DEAD
	SETZM	@STTB3(R12)		;KILL OBJECT
	TRNE	R16,FINOPT		;INVULNERABLE? 
	POPJ	P,			;YES, NO DAMAGE TO SHIP
	MOVE	R14,FIXTIM		;TIME NEEDED TO FIX DAMAGE
	SKIPL	SAVSID			;CHECK WHICH SIDE
	JRST	STX2.1			;RIGHT FIN WAS HIT
	MOVEM	R14,RDAM(SHIP)		;LEFT FIN, CAN'T TURN RIGHT
	MOVE	R14,ROTRBT(SHIP)	;GET BIT FOR DAMAGE MASK
	JRST	STX2.2
STX2.1:	MOVEM	R14,LDAM(SHIP)		;RIGHT FIN, CAN'T TURN LEFT
	MOVE	R14,ROTLBT(SHIP)	;DAMAGE BIT
STX2.2:	TDOE	R14,DMASK		;SET BIT IN THE DAMAGE LIST
	JRST	STX3			;ALREADY HIT THERE, KILL HIM
	IORM	R14,DMASK		;SAVE NEW DAMAGE LIST
	MOVE	C,@STTB2(R12)		;GET WHERE
	PUSHJ	P,PLT1			;LVW
	IORI	C,7*VBRT+VSIZ+VINVIS+VABS+6;
	JRST	FLASHX			;FLASH & RETURN

STX3:	SETZ	R14,
	EXCH	R14,@STTB3(R12)		;ZERO OBJECT, REMEMBER FOR KILLBN
	MOVEI	B,2(R12)		;GET EXPLOSION TYPE
	JUMPE	R12,QRST0		;JUMP IF SHIP-MINE
	HLRZ	R14,R14			;GET THE NAME OF THE KILLER IN R14
QRST:	MOVE	R11,KILLBN		;KILLER'S REWARD
	ADDM	R11,NUMWN(R14)		;INCREASE HIS SCORE
	JRST	QRST1			;GO THINK ABOUT RESTARTING
;COME TO ZOWIE1 ONLY FROM GRAV IF TOO CLOSE TO SUN
ZOWIE1:	SETZB	B,C			;ZERO GRAVITATIONAL ACCELERATION
	TRNE	R16,SUNOPT		;HEAT SHIELD?
	JRST	GRAV2			;YES, LET HIM GO
	SETZM	SP(SHIP)		;ZERO POSITION MEANS DIED IN SUN
	CAIG	SHIP,NSHIP-1		;SKIP IF A MINE
	SKIPE	ZOWSW(SHIP)		;SKIP IF SHIP WAS ALIVE
	POPJ	P,			;MINE- SUN COLLISION
	SETO	B,			;SIGNIFIES DEATH BY THE SUN
QRST0:	AOS	GALAXY			;COUNT ONE FOR GALACTIC OVERHEAD
QRST1:	MOVEM	B,ZOWSW(SHIP)		;SAVE EXPLOSION TYPE
	MOVE	R14,RSTARD		;LOAD RESTART DELAY
	MOVNM	R14,RESTAR(SHIP)	;SAVE IT
	SETZM	TPCN(SHIP)		;NO MORE TORPS (ELSE CTORP MIGHT
					;KEEP GAME GOING MISTAKENLY)
	MOVN	R14,DIEPEN		;PENALTY FOR DYING
	ADDM	R14,NUMWN(SHIP)		;UPDATE SCORE
	PUSHJ	P,CNT4			;DISPLAY SCORE
	SKIPE	DOTEAM			;ARE WE DOING TEAM SCORES?
	JRST	QRST2			;YES COMPUTE IF ONE TEAM WIPED OUT
	MOVE	R14,NSHIPX		;ARE THERE ANY LEFT?
	SETO	F,			;COUNT NUMBER LEFT
	SKIPN	ZOWSW(R14)		;IS THIS STILL HERE
	ADDI	F,1			;YES: COUNT IT
	SOJGE	R14,.-2			;LOOP
	JUMPG	F,CPOPJ			;JUMP IF >1 LEFT
	JRST	QRST3			;OK. SET THE RESTART TIME
QRST2:	MOVE	R14,NSHIPX		;LOOK AT ALL SHIPS
QRST2A:	SUBI	R14,1			;DECREMENT
	SKIPE	ZOWSW(R14)		;SKIP IF STILL ALIVE
	SKIPN	ZOWSW+1(R14)		;DEAD. SKIP IF TEAMMATE LIVES
	SOJGE	R14,QRST2A		;ONE TEAM IS PARTIALLY LIVE
	JUMPL	R14,CPOPJ		;RETURN IF BOTH TEAMS THERE
QRST3:	MOVE	F,TLIFE			;TIME TO RESTART
QRST4:	SKIPL	QRSTRT			;DON'T RESTART IF ALREADY DOING SO
	MOVNM	F,QRSTRT		;SET RESTART TIME
	POPJ	P,			;RETURN


	SUBTTL	ANALYSE MANEUVERING BUTTONS

JS:	SETZM	JSTB				;ZERO TABLE BEGINNING
	MOVE	B,[XWD JSTB,JSTB+1]		;LOAD BLT POINTER
	BLT	B,JSTBX				;RUN THRU TABLE WITH ZEROES
	SETCM	X,A				;COPY BUTTONS (COMPLEMENTED)
	TDO	X,DMASK				;ASSESS DAMAGES
	MOVE	F,BTX				;GET STANDARD THRUST
	MOVE	B,BRX				;GET STANDARD ROTATION
	MOVE	SHIP,NSHIPX			;FOR THIS MANY SHIPS
BITLOP:	TDNN	X,THRUBT(SHIP)			;IS HE THRUSTING?
	MOVEM	F,STX(SHIP)			;YES. GIVE HIM SOME
	TDNN	X,ROTRBT(SHIP)			;ROTATING RIGHT?
	MOVEM	B,SRX(SHIP)			;YES
	TDNN	X,ROTLBT(SHIP)			;ROTATING LEFT?
	MOVNM	B,SRX(SHIP)			;YES GIVE HIM NEGATIVE
	MOVE	C,FORMOP(SHIP)			;GET OPTION BIT
	TRNE	C,TURNOP			;DOES THIS OP USE DUAL TURN?
	TDZ	X,HYPRBT(SHIP)			;YES, PRETEND NO DAMAGE
	TDC	A,HYPRBT(SHIP)			;SET-UP FOR HYPER TEST
	TDCN	A,HYPRBT(SHIP)			;IS HE HYPER SPACING?
	TDNE	X,HYPRBT(SHIP)			;YES, IS HE UNDAMAGED?
	JRST	JS1				;NO
	SETZM	SRX(SHIP)			;DON'T LET HIM ROTATE BOTH WAYS
	TRNE	C,HYPOPT			;DOES THIS SHIP HAVE HYPERSPACE?
	PUSHJ	P,SETHYP			;YES, SET UP FOR HYPERSPACE
JS1:	SOJGE	SHIP,BITLOP			;LOOP FOR EVERY SHIP
	POPJ	P,				;ALL DONE


	SUBTTL	COMPUTE RESULTS OF SELF-DESTRUCTION

SLFDST:	MOVE	SHIP,NSHIPX		;CHECK ALL SHIPS BEFORE DESTROYING ANYONE
SD1:	MOVE	B,FORMOP(SHIP)		;GET OPTION BITS
	TDC	A,ALLBIT(SHIP)		;PREPARE TO TEST BUTTONS
	TDCN	A,ALLBIT(SHIP)		;ALL BUTTONS PUSHED?
	TRNN	B,ZOWOPT		;YES, DOES HE HAVE ZOWIE OPTION?
	JRST	SD1.2			;NO, IGNORE THIS GUY
	MOVEI	B,2003			;CREATE RANDOM NUMBER
	IMULB	B,RAND2			;TO SEE IF HE REALLY EXPLODES
	MOVE	C,DMASK			;GET DAMAGED BITS
	TDNN	C,THRUBT(SHIP)		;IF THIS SHIP ALREADY MISFIRED
	TRNN	B,740000		;OR IF 1/16 CHANCE TURNS UP
	JRST	SD1.1			;THEN HE FAILS TO EXPLODE
	MOVE	B,NSHIPX		;LOOK FOR SHIPS WITHIN RANGE
SD2:	SKIPN	ZOWSW(B)		;HAS THIS SHIP EXPLODED ALREADY?
	SKIPLE	HYPER(B)		;OR IS IT IN HYPERSPACE?
	JRST	SD2.1			;YES, CAN'T BLOW HIM UP NOW
	PUSHJ	P,SDDIST		;IS HE WITHIN RANGE (SKIP RETURN IF SO)
	JRST	SD2.1			;NO, LET HIM GO
	FIX	X,230000		;GOT HIM!  FIX THE DISTANCE^2
	HRLZS	X			;PUT IN LEFT HALF
	ADD	X,SHIP			;PUT KILLER IN RIGHT HALF
	SKIPL	STEMP(B)		;ARE TWO KILLERS IN RANGE OF THIS GUY?
	CAMGE	X,STEMP(B)		;YES, REMEMBER CLOSER ONE
	MOVEM	X,STEMP(B)
SD2.1:	SOJGE	B,SD2			;LOOK FOR OTHER SHIPS IN RANGE
	MOVE	B,NMINEX		;LOOK FOR MINES WITHIN RANGE
	ADDI	B,NSHIP-1		;INCREMENT TO INDEX MINE INFO
SD3:	CAIGE	B,NSHIP			;OUT OF MINES?
	JRST	SD3.1			;YES, LEAVE LOOP
	SKIPE	C,SP(B)			;IS THIS MINE STILL AROUND?
	PUSHJ	P,SDDIST		;YES, IS IT CLOSE ENOUGH?
	SOJA	B,SD3			;NO, GO TO NEXT ONE
	SETZM	SP(B)			;KILL THE MINE
	PUSHJ	P,FLASH0		;MAKE A FLASH (POSITION IN C)
	SOJA	B,SD3			;LOOP ON MINES
SD3.1:	MOVE	B,TPNT			;AND FINALLY, TORPEDOES
SD4:	SOJL	B,SD1.2			;LEAVE IF DONE
	HRRE	X,TP(B)			;GET 2X OF TORP POSN
	FSC	X,223			;FLOAT IT
	HLRE	Y,TP(B)			;GET -2Y
	FSC	Y,223			;FLOAT
	MOVNS	Y			;NEGATE IT
	PUSHJ	P,SDDF0			;IS IT IN RANGE?
	JRST	SD4			;NO, IGNORE IT
	SETZM	TL(B)			;YES, ZAP IT
	JRST	SD4			;LOOP
SD1.1:	IOR	C,ALLBIT(SHIP)		;MISFIRE: SHIP IS NOW TOTALLY DAMAGED
	MOVEM	C,DMASK
	SETZM	TPCN(SHIP)		;CAN'T FIRE ANY MORE TORPS
	SETOM	LDAM(SHIP)		;THIS DAMAGE IS NEVER REPAIRED
	SETOM	RDAM(SHIP)
SD1.2:	SOJGE	SHIP,SD1		;CHECK FOR OTHER SELF-DESTRUCTING SHIPS
	POPJ	P,

SDDIST:	MOVE	X,SX(B)			;GET POSITION OF OBJECT
	MOVE	Y,SY(B)
SDDF0:	FSB	X,SX(SHIP)		;MAKE RELATIVE TO SHIP
	FSB	Y,SY(SHIP)
	FMP	X,X			;GET RADIUS-SQUARED IN X
	FMP	Y,Y
	FAD	X,Y
	CAMG	X,ZOWRAD		;COMPARE TO ZOWIE RADIUS
	AOS	(P)			;SKIP RETURN IF IN RANGE
	POPJ	P,


	SUBTTL	INSERT LOSER INTO HYPERSPACE

SETHYP:	MOVE	C,RCONST		;GET RANDOM BASE
	ADDB	C,RANDX			;MAKE NEW RANDOM NUMBER
	MOVS	D,C			;COPY IT (SORT OF)
	ANDI	C,177			;GET RANDOM ORIENTATION
	MOVEM	C,SR(SHIP)		;SAVE IT
	ANDI	D,177			;GET RANDOM LENGTH OF TIME
	ADDI	D,100			;MAKE SURE HE STAYS OUT A WHILE
	MOVEM	D,HYPER(SHIP)		;SAVE TIME TO SPEND THERE
	AOS	C,HYPCNT(SHIP)		;INCREMENT HIS TIMES IN H-SPACE
	ANDI	D,6			;GET RANDOM EVEN NUMBER FROM 0 TO 6
	CAMGE	D,C			;SKIP IF HE GETS TO SURVIVE
	SETOB	C,HYPER(SHIP)		;SORRY, ZAP TIME AND HYPCNT
	MOVEM	C,HYPCNT(SHIP)		;SAVE (POSSIBLY MODIFIED) HYPCNT
	JUMPL	C,CPOPJ			;HE'S GETTING ZAPPED, DON'T MOVE HIM
	MOVE	C,RCONST		;MAKE RANDOM NUMBER FOR POSITION
	ADDB	C,RANDX
	MOVEM	C,SP(SHIP)
	HLRE	D,C			;GET -2Y
	HRRE	C,C			;GET 2X
	FSC	D,223			;FLOAT IT
	FSC	C,223			;FLOAT Y
	MOVEM	C,SX(SHIP)		;SAVE X
	MOVNM	D,SY(SHIP)		;SAVE Y
	SETZM	SV(SHIP)		;NO VELOCITY FOR SHIP
	SETZM	SVX(SHIP)
	SETZM	SVY(SHIP)
	SETZM	SANGMM(SHIP)
	POPJ	P,


	SUBTTL	CODE FOR RUNTIME PARAMETER MODIFICATION

IFG PARM,<
	SDEF(DIGF,1)
	SDEF(LETF,2)
	SDEF(NEGF,4)
	SDEF(CNGF,10)
	SDEF(PNTF,20)
LPARM:	0				;CELL TO REMEMBER WHERE
RPARM:	SETO	A,			;GET OUR LINE CHARACTERISTICS
	TTCALL	6,A			;INTO A
	TLO	A,100			;SET SPECIAL ACTIVATION MODE
	TTCALL	7,A			;TTY WILL WAKE ON WORD BY WORD
	TTCALL	14,			;WAIT FOR A WORD TO COME IN
	SETO	A,			;FOR OUR LINE
	TTCALL	6,A			;GET LINE CHARACTERISTICS
	TLZ	A,100			;SHUT OFF SPECIAL BIT
	TTCALL	7,A			;RESET LINE MODE
	PUSHJ	P,GETNAM		;GET THE NAME OF A CELL
	CAIE	A,"/"			;/ IS THE ACTIVATOR
	JRST	QWERT			;LOSE
	CAIE	B,45			;CODE FOR .?
	JRST	RPARM0			;NOPE
	SKIPN	D,LPARM
	JRST	QWERT
	JRST	RPARM2			;WE HAVE IT

RPARM0:	CAMN	B,[RADIX50 0,LIST]	;COMMAND TO LIST?
	JRST	RPARML			;YES
	CAMN	B,[RADIX50 0,CLEAR]	;CLEAR SCREEN?
	JRST	RPMC			;YES
	MOVEI	D,PTAB			;GET ADDRESS OF TABLE
RPARM1:	MOVE	C,(D)			;GET SYMBOL CELL FROM TABLE
	TLZ	C,740000		;SHUT OFF CODE BITS
	CAMN	B,C			;MATCH?
	JRST	RPARM2			;YES!
	ADDI	D,2			;PRESS AHEAD
	CAIGE	D,PTABX			;END OF TABLE?
	JRST	RPARM1			;NO. LOOP.
QWERT:	TTCALL	11,0			;I DON'T UNDERSTAND
	TTCALL	3,[ASCIZ/?
/]
	POPJ	P,			;GIVE UP
RPARM2:	HRRZ	A,1(D)			;LOAD ADDRESS OF PARAMETER
	MOVEM	D,LPARM			;REMEMBER .
	MOVE	A,(A)			;GET WHOLE PARAMETER
	LDB	B,[POINT 3,0(D),3]	;GET CODE BITS
	TTCALL	3,[ASCIZ/	/]	;WRITE TAB
	HRRZ	C,IOTAB(B)
	PUSHJ	P,(C)
	TTCALL	3,[ASCIZ/	/]	;AND A TAB
	HLRZ	C,IOTAB(B)
	PUSHJ	P,(C)
	JRST	QWERT
	TRNN	F,CNGF
	POPJ	P,			;NO CHANGE
	HLRZ	B,1(D)
	JUMPE	B,RPARM4		;READY TO STUFF
	MOVE	C,(D)
	TLNE	C,400000
	JRST	RPARM3			;TEST FOR LOWER BOUND
	CAML	B,W
	JRST	RPARM4
RPARMX:	TTCALL	3,[ASCIZ/Out of bounds
/]
	POPJ	P,
RPARM3:	CAMLE	B,W
	JRST	RPARMX
RPARM4:	HRRZ	C,1(D)
	MOVEM	W,(C)
	POPJ	P,
RPARML:	MOVEI	D,PTAB
	TTCALL	3,[ASCIZ/
/]
RPML1:	MOVE	W,(D)			;GET RADIX 50
	TLZ	W,740000
	PUSHJ	P,R5OUT			;WRITE RADIX50
	LDB	B,[POINT 3,0(D),3]	;GET BITS
	TTCALL	3,[ASCIZ/	/]
	HRRZ	A,1(D)
	MOVE	A,(A)
	HRRZ	C,IOTAB(B)
	PUSHJ	P,(C)
	TTCALL	3,[ASCIZ/
/]
	ADDI	D,2
	CAIGE	D,PTABX
	JRST	RPML1
	POPJ	P,
R5OUT:	IDIVI	W,50
	HRLM	X,(P)
	JUMPE	W,.+2
	PUSHJ	P,R5OUT
	HLRZ	W,(P)
	JUMPG	W,R5OUT1
	TTCALL	3,[ASCIZ/ /]
	POPJ	P,
R5OUT1:	CAILE	W,12
	JRST	R5OUT2
	ADDI	W,"0"-1
	TTCALL	1,W
	POPJ	P,
R5OUT2:	CAILE	W,44
	JRST	R5OUT3
	ADDI	W,"A"-13
	TTCALL	1,W
	POPJ	P,
R5OUT3:	SUBI	W,2
	CAIN	A,43
	MOVEI	W,"."
	TTCALL	1,W
	POPJ	P,

RPMC:	TTCALL	3,[BYTE(7)15,14,14,14]
	POPJ	P,


	SUBTTL	MORE PARAMETER CODE

GETNAM:	SETZ	B,			;ZERO B. WE ACCUMULATE RADIX 50
GETNM1:	PUSHJ	P,GETLET		;GET A LETTER AND SKIP
	POPJ	P,			;B WILL CONTAIN THE NAME. A HAS BREAK
	PUSHJ	P,R50			;A IS CONVERTED TO RADIX 50
	IMULI	B,50			;MAKING RADIX 50
	ADD	B,A			;ADD IN CHARACTER
	JRST	GETNM1			;LOOP
GETCHR:	TTCALL	0,A			;GET A CHARACTER
	TRZ	F,LETF+DIGF		;ZERO FLAGS
	CAIL	A,"a"			;SKIP IF NOT LOWER CASE
	CAILE	A,"z"			;SKIP IF LOWER CASE
	JRST	GETCH1			;LOOK FOR MORE
	TRZ	A,40			;MAKE UPPER CASE
	JRST	GETCH2			;GO TURN ON LETF AND RETURN
GETCH1:	CAIL	A,"A"			;SKIP IF NOT LETTER
	CAILE	A,"Z"			;SKIP IF LETTER
	JRST	GETCH3			;TEST FOR DIGITS
GETCH2:	TRO	F,LETF			;TURN ON FLAG
	POPJ	P,			;RETURN
GETCH3:	CAIL	A,"0"			;SKIP IF NOT DIGIT
	CAILE	A,"9"			;SKIP IF DIGIT
	JRST	GETCH4			;NOT DIGIT
	TRO	F,DIGF			;SET FLAG
	POPJ	P,			;RETURN
GETCH4:	CAIN	A,15			;IS IT CR?
	JRST	GETCHR			;YES. GET NEXT
	CAIN	A,175			;TEST FOR ALTMODE
	TTCALL	3,[BYTE(7)15,14,14,14]	;YES, CLEAR SCREEN
	CAIN	A,175			;TEST AGAIN
	MOVEI	A,12			;CONVERT TO LF
	POPJ	P,			;RETURN
GETLET:	PUSHJ	P,GETCHR		;GET A LETTER. FIRST GET CHARACTER
	TRNE	F,LETF+DIGF		;ANY FLAGS SET?
	JRST	CPOPJ1			;YES: DO A SKIP RETURN
	CAIE	A,"$"
	CAIN	A,"%"
	JRST	CPOPJ1
	CAIN	A,"."
CPOPJ1:	AOS	(P)
	POPJ	P,
R50:	TRNE	F,LETF			;IS THIS A LETTER
	SUBI	A,"A"-13		;CONVERT TO R 50
	TRNE	F,DIGF			;IS IT A DIGIT
	SUBI	A,"0"-1
	TRNE	F,LETF+DIGF
	POPJ	P,
	ADDI	A,2
	CAIN	A,"."+2
	MOVEI	A,45
	POPJ	P,
DECOUT:	MOVEI	Y,12			;GET RADIX
	SKIPA
OCTOUT:	MOVEI	Y,10			;SET RADIX
	MOVM	W,A			;GET ARGUMENT
	JUMPGE	A,ARADIX
	TTCALL	3,[ASCIZ/-/]
ARADIX:	IDIV	W,Y
	HRLM	X,(P)
	JUMPE	W,.+2
	PUSHJ	P,ARADIX
	HLRZ	W,(P)
	ADDI	W,"0"
	TTCALL	1,W
	POPJ	P,
FLOUT:	JUMPN	A,FLOUT1		;JUMP UNLESS ARGUMENT IS 0
	TTCALL	3,[ASCIZ/0.0/]
	POPJ	P,
FLOUT1:	MOVM	W,A			;GET |ARG| INTO W
	JUMPG	A,FLOUT2		;JUMP PAST KLUGE IF ARG POSITIVE
	TTCALL	3,[ASCIZ/-/]
FLOUT2:	SETZ	Y,		;POSITION OF THE POINT
FLOUT3:	CAML	W,[1.0]		;LESS THAN 1.0
	JRST	FLOUT4		;NO
	FMPR	W,[10.0]	;MULTIPLY BY 10.0
	SOJA	Y,FLOUT3	;COUNT THE POINT SHIFT

FLOUT4:	CAMGE	W,[10.0]	;COMPARE TO 10.0
	JRST	FLOUT5		;WE ARE SCALED
	FDVR	W,[10.0]	;SCALE DOWN
	AOJA	Y,FLOUT3	;COUNT AND LOOP

FLOUT5:	CAML	Y,[-2]		;ARE WE IN BOUNDS?
	CAILE	Y,6		;IN BOUNDS?
	JRST	FLOUTE		;NO: WRITE IN EXPONENT FORM
	AOJG	Y,FLOUTX	;PREPARE FOR BIG NUMBER
	TTCALL	3,[ASCIZ/0./]	;WRITE BEGINNING OF NUMBER
	JUMPE	Y,FLOUTX	;JUMP IF NO MORE 0'S
	TTCALL	3,[ASCIZ/0/]	;WRITE PLACE HOLDER ZEROES
	AOJL	Y,.-1		;LOOP
FLOUTX:	FMPR	W,[1000000.0]	;MULTIPLY BY BIG NUMBER
	FIX	W,233000
FDOUT:	IDIVI	W,12
	HRLM	X,(P)
	JUMPE	W,.+2
	PUSHJ	P,FDOUT
	HLRZ	W,(P)
	ADDI	W,"0"
	TTCALL	1,W
	SOJN	Y,CPOPJ
	TTCALL	3,[ASCII/./]
	POPJ	P,
FLOUTE:	PUSH	P,Y		;SAVE FRACTION COUNT
	MOVEI	Y,1		;MAKE POINT COME AFTER 1 DIGIT
	PUSHJ	P,FLOUTX	;CALL OTHER STUFF
	TTCALL	3,[ASCII/'/]	;WRITE FOR EXPONENT
	POP	P,A		;RECOVER THE FRACTION COUNT
	JRST	DECOUT		;WRITE DECIMAL AND RETURN

RADIN:	SETZB	W,X			;NUMBER IN W. -POINT COUNT IN X
	TRZ	F,CNGF+NEGF+PNTF	;ZERO FLAGS
RADIN1:	PUSHJ	P,GETCHR
	TRNN	F,DIGF
	JRST	RADIN2			;NOT DIGIT
	CAIL	A,"0"(Y)		;IS LEGAL
	POPJ	P,			;ILLEGAL DIGIT
	IMUL	W,Y
	ADDI	W,-"0"(A)
	TRNE	F,PNTF			;POINT SEEN YET?
	SUBI	X,1			;YES: COUNT IN X
	TRO	F,CNGF			;MARK ATTEMPT TO CHANGE
	JRST	RADIN1			;LOOP
RADIN2:	CAIE	A,"."			;DECIMAL POINT
	JRST	RADIN3			;NOPE
	TROE	F,PNTF			;TURN ON POINT
	POPJ	P,			;IT WAS SET BEFORE
	JRST	RADIN1			;LOOP
RADIN3:	CAIE	A,"-"			;IS IT THE SIGN?
	JRST	RADIN4
	TRNN	F,CNGF+PNTF		;ANYTHING SEEN YET?
	TROE	F,NEGF			;TURN ON FLAG
	POPJ	P,			;LOSE
	JRST	RADIN1			;WIN
RADIN4:	TRZE	F,NEGF	
	MOVN	W,W			;NEGATE
	JRST	CPOPJ1			;SKIP RETURN TO WIN!

OCTIN:	MOVEI	Y,10
	SKIPA
DECIN:	MOVEI	Y,12
	PUSHJ	P,RADIN
	POPJ	P,			;LOSER
	CAIN	A,12			;MUST SEE LF
	JUMPE	X,CPOPJ1		;AND NO DIGITS PAST POINT
	POPJ	P,			;LOSE
FLIRT:	MOVEI	Y,12			;SET RADIX
	PUSHJ	P,RADIN	
	POPJ	P,
	CAIE	A,"'"
	JRST	FLIRT1			;NO EXPONENT
	PUSH	P,W			;SAVE STUFF
	PUSH	P,X
	PUSHJ	P,DECIN
	JRST	FLIRTL			;LOSSAGE FROM FLIRT
	POP	P,X			;GET OLD POINT COUNT
	ADD	X,W			;MAKE REAL EXPONENT
	POP	P,W			;GET DIGITS PART
FLIRT1:	CAIE	A,12			;END OF LINE?
	POPJ	P,			;NOPE. LOSE
	FSC	W,233
	JUMPE	X,CPOPJ1		;IF NO EXPONENT
	MOVE	Y,[10.0]
	JUMPG	X,FLIRT2
	MOVE	Y,[0.1]
	MOVM	X,X
FLIRT2:	FMPR	W,Y
	SOJG	X,.-1
	JRST	CPOPJ1
FLIRTL:	POP	P,(P)
	POP	P,(P)
	POPJ	P,


	SUBTTL	TABLES FOR THE PARAMETER MODIFICATION

COMMENT/
ENTRIES ARE:
	RADIX50 N,SYMBOL
	BOUND,,ADDRESS
WHERE N HAS THE FOLLOWING SIGNIFIGANCE
	IF N.GE.40 THEN THE BOUND IS A LOWER BOUND. TAKE N MOD 40 FOR
	N=0 	FLOATING POINT
	N=4	OCTAL
	N=10	DECIMAL
	N=14	UNUSED

	IF BOUND = 0 THEN THERE IS NO RESTRICTION
/

PTAB:	RADIX50	0,BTX
	XWD	0,BTX
	RADIX50	0,BRX
	XWD	0,BRX
	RADIX50	4,ANGMOM
	XWD	0,ANGMOM
	RADIX50	0,MNEUVR
	XWD	0,MNEUVR
	RADIX50	0,GG
	XWD	0,GG
	RADIX50	0,GDT
	XWD	0,GDT
	RADIX50	0,MTCOLR
	XWD	0,MTCOLR
	RADIX50	0,TR2
	XWD	0,TR2
	RADIX50	0,ZOWRAD
	XWD	0,ZOWRAD
	RADIX50	0,SCR
	XWD	0,SCR
	RADIX50	4,NTORPS
	XWD	NTORPM,NTORPS
	RADIX50	4,TTBMAX
	XWD	LTBL,TTBMAX
	RADIX50	44,TRELOD
	XWD	20,TRELOD
	RADIX50	4,LATNCY
	XWD	0,LATNCY
	RADIX50	4,TLIFE
	XWD	200,TLIFE
	RADIX50	4,ITV
	XWD	0,ITV
	RADIX50	4,BEGINR
	XWD	0,BEGINR
	RADIX50	4,HANDCP
	XWD	0,HANDCP
	RADIX50	4,ABSENT
	XWD	0,ABSENT
	RADIX50	4,DAMHIT
	XWD	0,DAMHIT
	RADIX50	10,SURBEN
	XWD	0,SURBEN
	RADIX50	10,KILLBN
	XWD	0,KILLBN
	RADIX50	10,DIEPEN
	XWD	0,DIEPEN
	RADIX50	4,DOTEAM
	XWD	0,DOTEAM
	RADIX50	10,GSCORE
	XWD	0,GSCORE
	RADIX50	10,CONS2
	XWD	0,CONS2
	RADIX50	4,RSTARD
	XWD	0,RSTARD
	RADIX50	4,FIXTIM
	XWD	0,FIXTIM
	RADIX50	4,DRONES
	XWD	0,DRONES
SDEF(PTABX,.-1)				;DEFINE END OF TABLE

IOTAB:	XWD	FLIRT,FLOUT
	XWD	OCTIN,OCTOUT
	XWD	DECIN,DECOUT
	XWD	CPOPJ,CPOPJ
	SDEF(UPDLEN,30)			;USER PUSHDOWN LENGTH
UPDL:	IOWD	UPDLEN,UPDLST
UPDLST:	BLOCK	UPDLEN
>;IFG PARM


	SUBTTL	DATA STORAGE FOR SPACEWAR

TENDON:	0			;SET -1 BY PDP-10 WHEN DONE.
				;TESTED BY PDP-6. ZEROED WHEN PDP-6 RUNS
SIXDON:	0			;SET -1 WHEN PDP-6 FINISHES. 
				;TESTED AND CLEARED BY PDP-10
CTIME:	.+2			;ADDRESS OF COUNTDOWN DPY BUFFER
	4			;LENGTH OF BUFFER
	0			;START OF BUFFER, CLOBBERED BY III
CTIM1:	0			;SAVE DPY SELECT WORD HERE
	LVW(0,0,i,a,7,7)	;SELECT CENTER, BIG BRIGHT
CTIM:	0			;ASCII DIGIT GOES HERE
CDOWN:	0
DMASK:	0				;DAMAGE MASK
SAVSID:	0				;USED BY DAMAGE ASSESSMENT
DEBUG:	0				;SET <>0 TO FAKE SPACEWAR
SWBUT:	0				;SAVE OLD SW BUTTONS HERE
SWBUT2:	0				;10 MODULE SAVES BUTTONS HERE
NSHIPX:	NSHIP-1				;NUMBER OF SHIPS-1 TO USE
DDSW:	0				;SET <> 0 FOR NEW BUTTONS
TUBES:	0				;SET <>0 FOR TWO TUBES
ANGMOM:	0				;SET <> 0 (AND AMFACT<>1) IF ANGULAR MOMENTUM
DAMHIT:	0				;SET <>0 FOR PARTIAL DAMAGE
RSPSWT:	0				;SET <>0 FOR RANDOM STARTS
CNTR:	0				;SET <> 0 FOR SCORES
FORMUL:	0				;SET <> 0 FOR FORMULA OPTION SELECT
TENSW:	0				;SET <>0 FOR SW ON THE 10
SIXSW:	0				;0 means PDP-6 is running.
OLDBUT:	-1				;OLD STATE OF BUTTONS
DRONES:	0				;SET <>0 TO ACTIVATE UNUSED SHIPS
DRBUTS:	0				;BUTTONS TO ASSUME ARE SET
RCONST:	532473734251			;A RANDOM CONSTANT
RANDX:	352716643514			;A RANDOM NUMBER (FOR SIMPLE STUFF)
RAND2:	0				;BETTER (BUT SLOWER) RANDOM NUMBER
RAND:	717271471534			;YET ANOTHER RANDOM NUMBER (FOR FLAME)
DISTAB:
STARFG:	0				;SET -1 TO DISPLAY STARS
SHIPFG:	0				;SET -1 TO DISPLAY SHIPS
CNTFG:	0				;SET -1 TO DISPLAY COUNTS
CONS2:	0				;NUMBER OF SECOND CONSOLE (IN DECIMAL)
SELWRD:	1				;III INST TO SELECT OTHER SCREEN (IF ANY)
STADR:	STARBF				;ADDRESS OF STAR TABLE
	NSTAR+2				;LENGTH OF STAR TABLE
BPTRX:	SUN				;ADDRESS OF DPY BUFFER
	0				;CLOBBER THIS TO BUFFER LENGTH
CNTPNT:	CNTTBL				;ADDRESS OF COUNT TABLE
	1+2*NSHIP			;SIZE OF COUNT TABLE
BITS:	0				;KBD BITS
LINE:	0				;KEYBOARD SCANNER LINE NUMBER
GSCORE:	0				;SET <> 0 FOR GALAXY SCORE
MINSTR:	0				;>0} TIME BEFORE RELAYING MINES
PDP:	IOWD	PDLEN,PDLIST		;THE PUSH DOWN POINTER
TAB:	BLOCK	200			;TABLE OF SINES AND COSINES
CLOBR:	0				;SET <> 0 AFTER HI CORE IS CLOBBERED
PDLIST:	BLOCK	PDLEN			;STORAGE FOR PUSH DOWN LIST
CNTTBL:	0				;DPY BUFFER FOR DISPLAYING SCORES
	LVW(10,10,i,a,5,5)		;POSITION FOR GALAXY SCORE
	BLOCK	1+2*NSHIP		;ROOM ENOUGH FOR THE REST
TV:	BLOCK	LTBL			;TORPEDO VELOCITY -2Y,,2X
TP:	BLOCK	LTBL			;TORPEDO POSITION -2Y,,2X
TL:	BLOCK	LTBL			;TORPEDO REMAINING LIFE
TVX:	BLOCK	LTBL			;TORPEDO X VELOCITY (FLOATING POINT)
TVY:	BLOCK	LTBL			;TORPEDO Y VELOCITY (FLOATING POINT)
NUMWN:	BLOCK	NSHIP			;WINS FOR EACH PLAYER
FORMOP:	BLOCK	NSHIP			;FORMULA-OPTIONS CURRENTLY SELECTED
STEMP:	BLOCK	NSHIP			;USED FOR SELF-DEST INFO AND NOSE POSN
SDEF(GOBEG,.)				;AREA TO ZERO AT GAME BEGINNING
TPNT:	0				;ACTIVE TORP COUNT
CHANGD:	0				;BUTTONS WHICH CHANGED STATE
QRSTRT:	0				;<0 } TIME BEFORE RESTART
ABSEN0:	0				;LAST KNOWN STATE OF ABSENTEE WORD
SDEF(GOBEG2,.)				;SUB-AREA OF NSHIP-SIZED BLOCKS
ZOWSW:	BLOCK	NSHIP			;NON ZERO DENOTING EXPLOSION
HYPER:	BLOCK	NSHIP			;POSITIVE } IN HYPERSPACE
TCNT0:	BLOCK	NSHIP			;RELOAD DELAY: SHIP n TUBE 0
TCNT1:	BLOCK	NSHIP			;RELOAD DELAY: SHIP n TUBE 1
LDAM:	BLOCK	NSHIP			;TIME BEFORE LEFT-TURNING FIXING
RDAM:	BLOCK	NSHIP			;RIGHT-TURNING
UTUBE:	BLOCK	NSHIP			;TUBE SELECT TOGGLE
ZORCHP:	BLOCK	NSHIP			;SHIP'S ZORCH PROGRESS
HYPCNT:	BLOCK	NSHIP			;# OF TIMES IN H-SPACE. &
					;RANDOM NUMBER DURING ZORCH
SANGMM:	BLOCK	NSHIP			;ACCUMULATED ANGULAR MOMENTUM (FLOATING)
SDEF(GO2SIZ,.-NSHIP-GOBEG2)		;SIZE OF GOBEG2 SECTION
SR:	BLOCK	NSHIP			;BASIC ORIENTATION (ROT) 0-177
SV:	BLOCK	NSHIP			;BASIC VELOCITY -2Y,,2X
MINEV:	BLOCK	NMINE
SVX:	BLOCK	NSHIP			;X VELOCITY (FLOATING)
MINEVX:	BLOCK	NMINE
SVY:	BLOCK	NSHIP			;Y VELOCITY (FLOATING)
MINEVY:	BLOCK	NMINE
SP:	BLOCK	NSHIP			;BASIC POSITION -2Y,,2X
MINEP:	BLOCK	NMINE
SX:	BLOCK	NSHIP			;X POSITION (FLOATING)
MINEX:	BLOCK	NMINE
SY:	BLOCK	NSHIP			;Y POSITION (FLOATING)
MINEY:	BLOCK	NMINE
TPCN:	BLOCK	NSHIP			;REMAINING TORPEDO COUNT
SRA:	BLOCK	NSHIP			;LEFTSIDE BITS=ORIENTATION
RESTAR:	BLOCK	NSHIP			;FOR AUTO RESTART COUNTS
SDEF(GOEND,.-1)				;END OF STUFF ZEROED BY GAME
SDEF(JSTB,.)				;ZERO BEFORE READING BUTTONS
STX:	BLOCK	NSHIP			;THRUST INCREMENT FOR SHIPS
SRX:	BLOCK	NSHIP			;DELTA OMEGA (ROTATION)
SDEF(JSTBX,.-1)				;END OF STUFF ZEROED BY JS
IFN FAST,<
BTX:	1.6				;THRUST
BRX:	2.0				;ANGULAR VELOCITY OF ROTATION
GG:	32.0				;GRAVITATIONAL CONSTANT
ITV:	3400000				;TORP VELOCITY
TRELOD: 60				;NORMAL RELOAD TIME
>
IFE FAST,<				;SLOW DEFAULTS
BTX:	0.8				;THRUST
BRX:	1.0				;ROTATIONAL D OMEGA/DT
GG:	16.0				;GRAV CONSTANT
ITV:	1600000				;INITIAL TORPEDO VELOCITY
TRELOD:	30				;TUBE RELOAD DELAY
>
MNEUVR:	1.4				;EXTRA SPEED FACTOR FOR THROPT
HANDCP:	0				;HANDICAPS FOR ALL SHIPS
ABSENT:	0				;SAYS WHICH SHIPS TO SUPPRESS
RSTARD:	400				;RESTART DELAY
FIXTIM:	400				;NON-MANEUVERING TIME TO FIX DAMAGE
MTCOLR:	100.0				;MINE-TORP COLLISION RADIUS ^ 2
TR2:	36.0				;TORPEDO RADIUS ^ 2
ZOWRAD:	2304.0				;SELF-DESTRUCT RADIUS ^ 2
DOTEAM:	0				;SET <> 0 IF USING TEAM SCORING
SURBEN:	1				;SURVIVAL BENEFIT
DIEPEN:	0				;PENALTY FOR DYING: DEATH PENALTY
KILLBN:	0				;REWARD FOR KILLING, WAGES OF SIN
GALAXY:	0				;SCORE FOR OVERHEAD
MAXSCR:	0				;MAX SCORE EVER
BEGINR:	0				;SET <> 0 TO CHECK FOR AMATEURS
BGINR:	BLOCK	NSHIP			;<> 0 FOR EACH SHIP IF AMATEUR
GDT:	6.0				;DELTA T FOR INTEGRATION
SCR:	10.0				;SUN COLLISION RADIUS
NTORPS:	NTORPM				;NUMBER OF TORPS/PLAYER
NMINEX:	NMINE				;MAXIMUM NUMBER OF MINES <= NMINE
TTBMAX:	LTBL				;MAXIMUM TORPS IN TABLE <= LTBL
LATNCY:	10				;MIN TIME BETWEEN SHOTS (TUBES)
TLIFE:	200				;TORPEDO LIFE
RDELAY:	XWD	SHIP,TCNT0		;@RDELAY(X) WILL GET/SET RELOAD
	XWD	SHIP,TCNT1		;DELAY FOR SHIP'S TUBE (X).
STTB1:	NMINEX				;NUMBER OF OBJECTS FOR STCOL (MINES)
	TPNT				;DITTO, TORPEDOES
STTB2:	XWD	R11,MINEP		;STCOL: OBJECT POSITION TABLE ADDRESS
	XWD	R11,TP			;TORPEDOES, (LAST LINE WAS MINES)
STTB3:	XWD	R11,MINEP		;ZERO THIS TO CANCEL OBJECT (MINE)
	XWD	R11,TL			;CANCEL TORPEDO
TPBIT:	1				;BIT SIGNIFYING TORP LAUNCH
	20
	400
	10000
	200000
ALLTPS:	210421				;TORP BUTTONS FOR ALL SHIPS
ALLBIT:	17				;BUTTON BITS FOR EACH SHIP
	360
	7400
	170000
	3600000
ALLALL:	3777777				;ALL USED BUTTONS
THRUBT:	2				;BIT FOR THRUST
	40
	1000
	20000
	400000
ROTRBT:	4				;BIT FOR LEFT FIN
	100
	2000
	40000
	1000000
ROTLBT:	10				;BIT FOR RIGHT FIN
	200
	4000
	100000
	2000000
HYPRBT:	14				;DOUBLE-TURN BITS (HYPERSPACE, ETC.)
	300
	6000
	140000
	3000000
ALLHYP:	3146314				;HYPRBT FOR ALL SHIPS AT ONCE
HANDBT:	7				;HANDICAP FIELD FOR EACH SHIP IN HANDCP
	70
	700
	7000
	70000
IPOS:	BLOCK	NSHIP			;INITIAL POSITIONS
IROT:	BLOCK	NSHIP
TFTAB:	10				;FLAME LOCATOR FOR SHIPS
	12				;FLAME POSITION = 
	12				;SP(SHIP)-TAB(SR(SHIP))*TFTAB(SHIP)
	12
	12
TSFTAB:	13				;SIDE FLAME LOCATOR
	12				;POSITION =
	13				;SP(SHIP)+TAB(SR(SHIP)+ANGLE)*TSFTAB(SHIP)
	13				;WHERE ANGLE = 72 OR -72
	14				;ANGLE OF FLAME ITSELF = 76 OR -76
SPICT:	S1TAB				;TABLE OF PICTURE ADDRESSES
	S2TAB
	S3TAB
	S4TAB
	S5TAB
S1TAB:	XWD	-4,70			;SHIP  1 PICTURE
	XWD	-21,100
	XWD	-4,60
	XWD	-6,0
	XWD	-4,160
	XWD	-3,140
	XWD	-4,120
	XWD	-6,100
	XWD	-4,20
	XWD	-3,40
	XWD	-3,140
	XWD	-20,0
	XWD	-4,10
	0
S2TAB:	XWD	-4,70
	XWD	-23,100
	XWD	-3,30
	XWD	-6,0
	XWD	-3,150
	XWD	-3,140
	XWD	-3,130
	XWD	-6,100
	XWD	-3,50
	XWD	-3,40
	XWD	-3,140
	XWD	-22,0
	XWD	-4,10
	0
S3TAB:	XWD	-4,70
	XWD	-23,100
	XWD	-3,40
	XWD	-7,0
	XWD	-4,120
	XWD	-3,140
	XWD	-4,160
	XWD	-7,100
	XWD	-6,40
	XWD	-3,140
	XWD	-23,0
	XWD	-4,10
	0
S4TAB:	XWD	-4,70
	XWD	-23,100
	XWD	-4,40
	XWD	-10,165
	XWD	-3,140
	XWD	-10,112
	XWD	-7,40
	XWD	-3,140
	XWD	-23,0
	XWD	-4,10
	0
S5TAB:	XWD	-4,70
	XWD	-23,100
	XWD	-2,60
	XWD	-4,20
	XWD	-6,160
	XWD	-3,140
	XWD	-6,120
	XWD	-4,60
	XWD	-2,20
	XWD	-3,40
	XWD	-3,140
	XWD	-22,0
	XWD	-4,10
	0

































































	LIT

COMMENT	/
THE FOLLOWING ODD STRUCTURE IS A III SHORT VECTOR, WITH THE COORDS IN
EXCESS 8 NOTATION.  THE IDEA WILL BE TO MULTIPLY THEM BY SMALL SCALARS,
THEN SUBTRACT OUT THE EXCESS (MULTIPLIED BY THE SCALARS), IN ORDER TO SCALE
THE WHOLE VECTOR AT ONCE.  WE'LL USE THE 8-BIT IN EACH BYTE TO DETERMINE
WHETHER THERE WILL BE A BORROW FROM THE ADJACENT BYTE.
/
	DEFINE	SUNVCT(X,Y)<BYTE(7)10+<X>,10+<Y>(2)0(7)10-<X>,10-<Y>(6)0>
	SUNVCT(0,0)			;CORRECTION FACTOR
SUNVEC:	SUNVCT(0,3)
	SUNVCT(2,-2)
	SUNVCT(-3,0)
	SUNVCT(2,2)
	SUNVCT(0,-3)
	SUNVCT(-2,2)
	SUNVCT(3,0)
	SUNVCT(-2,-2)
BORROW:	BYTE(7)10,10(2)0(7)10,10(6)0	;BITS TO CHECK TO SEE IF BORROW
SUNRAY:	0				;NEXT RAY TO BE TWEAKED
SUN:	0				;BEGINNING OF MAIN III BUFFER
SUNCTR:	LVW(0,0,i,a,7,2)		;CENTER FOR THE SUN
SUNBUF:	BLOCK	BORROW-SUNVEC		;ONE WORD PER RAY
STARBF:
BUF:	BLOCK	BUFLEN			;BUFFER FOR THE REST OF THE WORLD


	SUBTTL	ONCE ONLY SET PARAMETERS AT STARTUP

SETALL:	TTCALL	3,[ASCIZ/
			       Welcome to Spacewar!!

				 "Aspera ad astra"

		        Documentation is in SWR.REG[UP,DOC].


How many ships? Maximum is /]
	MOVEI	A,NSHIP
	PUSHJ	P,%DEC
	TTCALL	3,[ASCIZ/	/]
	PUSHJ	P,%DIGIN
	SUBI	A,1
	CAIL	A,NSHIP
	MOVEI	A,NSHIP-1
	MOVMM	A,NSHIPX		;TWO SHIPS IF CR
	CAILE	A,1
	 JRST	%SDD
	TTCALL	3,[ASCIZ/Keyboard buttons? (else regular). Type Y or N: /]
	PUSHJ	P,%YN
	TDZA	A,A
%SDD:	MOVEI	A,1
	MOVEM	A,DDSW			;SAVE DDSW
	TTCALL	3,[ASCIZ/The "Standard" game is:/]
	MOVE	A,NSHIPX
	MOVEI	B,1			;READY FOR >2-PERSON
	SOJG	A,%STG			;IS IT?
	TTCALL	3,[ASCIZ/

1 console, 2 torpedo tubes, (normal) scoring,
no beginners, no partial damage, no hyperspace,
no angular momentum, passive/]
	TDZA	B,B			;READY FOR 2-PERSON
%STG:	TTCALL	3,[ASCIZ/

1 console, 2 torpedo tubes, killer scoring,
no beginners, no partial damage, no hyperspace,
no angular momentum, active/]
	TTCALL	3,[ASCIZ/ drones,
ships start in random positions.

Type Y to get a standard game: /]
	PUSHJ	P,%YN
	JRST	%SELPM			;GO SELECT PARAMETERS
	MOVEM	B,KILLBN		;B=0 FOR <=2 PLAYERS, ELSE 1
	MOVEM	B,DIEPEN
	MOVEM	B,DRONES
	SETZM	BEGINR
	SETZM	DAMHIT
	SETZM	DOTEAM
	SETZM	FORMUL
	SETZM	ANGMOM
	SETZM	CONS2
	SETOB	A,RSPSWT
	MOVNM	A,TUBES
	MOVEI	A,NMINE
	MOVEM	A,NMINEX
	SETOM	CNTR
	JRST	%GO

%SELPM:	TTCALL	3,[ASCIZ/Second console? Number, else return: /]
	PUSHJ	P,%DIGIN
	MOVEM	A,CONS2
IFG NMINE,<
	MOVEI	A,NMINE
	TTCALL	3,[ASCIZ/How many space-mines (0 to /]
	PUSHJ	P,%DEC
	TTCALL	3,[ASCIZ/)? /]
	PUSHJ	P,%DIGIN
	CAILE	A,NMINE
	MOVEI	A,NMINE
	MOVEM	A,NMINEX
>;IFG NMINE
	TTCALL	3,[ASCIZ/Any beginners? /]
	PUSHJ	P,%YN
	TDZA	A,A
	MOVEI	A,1
	MOVEM	A,BEGINR
	TTCALL	3,[ASCIZ/Partial damage? /]
	PUSHJ	P,%YN
	TDZA	A,A
	MOVEI	A,1
	MOVEM	A,DAMHIT
	TTCALL	3,[ASCIZ/Display scores? /]
	PUSHJ	P,%YN
	TDZA	A,A
	MOVEI	A,1
	MOVEM	A,CNTR
	JUMPE	A,%NK
	MOVE	A,NSHIPX
	CAIE	A,3
	JRST	%NTS
	TTCALL	3,[ASCIZ/Team scores? /]
	PUSHJ	P,%YN
%NTS:	TDZA	A,A
	MOVEI	A,1
	MOVEM	A,DOTEAM
	TTCALL	3,[ASCIZ/Killer score? /]
	PUSHJ	P,%YN
	JRST	%NK
	MOVEI	A,1
	MOVEM	A,KILLBN
	MOVEM	A,DIEPEN
%NK:	TTCALL	3,[ASCIZ/Two torpedo tubes? /]
	PUSHJ	P,%YN
	TDZA	A,A
	MOVEI	A,1
	MOVEM	A,TUBES
	TTCALL	3,[ASCIZ/"Formula"? /]
	PUSHJ	P,%YN
	TDZA	A,A
	MOVEI	A,SUNOPT
	MOVEM	A,FORMUL
	JUMPN	A,%NOHYP	;IF NO, ASK ABOUT HYPERSPACE
	TTCALL	3,[ASCIZ/Hyperspace? /]
	PUSHJ	P,%YN
	TDZA	A,A
	MOVEI	A,HYPOPT
%NOHYP:	MOVE	SHIP,NSHIPX
	MOVEM	A,FORMOP(SHIP)
	SOJGE	SHIP,.-1
	TTCALL	3,[ASCIZ/Angular momentum? /]
	PUSHJ	P,%YN
	TDZA	A,A
	MOVEI	A,1
	MOVEM	A,ANGMOM
	TTCALL	3,[ASCIZ/Active drones? /]
	PUSHJ	P,%YN
	TDZA	A,A
	MOVEI	A,1
	MOVEM	A,DRONES
	TTCALL	3,[ASCIZ/Random starting positions? /]
	PUSHJ	P,%YN
	TDZA	A,A
	MOVEI	A,1
	MOVEM	A,RSPSWT
%GO:	MOVE	A,NSHIPX		;SET UP "STANDARD" STARTING POSNS
	MOVE	B,A
	MOVEI	BFP,CNTTBL+1		;AND SCORE LVW'S
%GLOOP:	ADDI	BFP,1
	PUSH	BFP,%CPOS(B)
	MOVE	X,%POS(B)
	MOVEM	X,IPOS(A)
	MOVE	X,%ROT(B)
	MOVEM	X,IROT(A)
	ADDI	B,NSHIP-1(A)
	SUB	B,NSHIPX
	SOJGE	A,%GLOOP
	JRST	%XIT


	SUBTTL	MORE ONCE ONLY

%YN:	TTCALL	4,A		;READ Y/N ANSWER, SKIP RETURN IF YES
	CAIE	A,"Y"
	CAIN	A,"y"
	AOS	(P)
%FLUSH:	TTCALL	11,		;FLUSH INPUT AND RETURN
	POPJ	P,

%DEC:	IDIVI	A,12		;PRINT REG A IN DECIMAL
	HRLM	B,(P)
	SKIPE	A
	PUSHJ	P,%DEC
	HLRZ	A,(P)
	ADDI	A,"0"
	TTCALL	1,A
	POPJ	P,

%DIGIN:	SETZ	A,		;INPUT A NUMBER
%DIG1:	TTCALL	4,B
	CAIL	B,"0"
	CAILE	B,"9"
	JRST	%FLUSH
	IMULI	A,12
	ADDI	A,-"0"(B)
	JRST	%DIG1


	SUBTTL	STANDARD POSITIONS, ETC.

;STANDARD STARTING POSITIONS, INTERLEAVED IN FUNNY FASHION

%POS:	XWD	-200000,200000	;1 OF 1
	XWD	200000,-200000	;2 OF 2
	XWD	 110000,-220000	;3 OF 3
	XWD	200000,200000	;4 OF 4
	XWD	-50000,-230000	;5 OF 5
	XWD	-200000,200000	;1 OF 2
	XWD	 110000,220000	;2 OF 3
	XWD	-200000,-200000	;3 OF 4
	XWD	200000,-140000	;4 OF 5
	XWD	-240000,0	;1 OF 3
	XWD	200000,-200000	;2 OF 4
	XWD	200000,140000	;3 OF 5
	XWD	-200000,200000	;1 OF 4
	XWD	-50000,230000	;2 OF 5
	XWD	-240000,0	;1 OF 5

;STANDARD STARTING ORIENTATIONS
%ROT:	100			;1 OF 1
	0			;2 OF 2
	25			;3 OF 3
	160			;4 OF 4
	46			;5 OF 5
	100			;1 OF 2
	153			;2 OF 3
	60			;3 OF 4
	14			;4 OF 5
	100			;1 OF 3
	20			;2 OF 4
	163			;3 OF 5
	120			;1 OF 4
	131			;2 OF 5
	100			;1 OF 5

;POSITIONS FOR SCORE COUNTS
%CPOS:	LVW(640,640,i,a,5,5)	;1 OF 1
	LVW(640,640,i,a,5,5)	;1 OF 2
	LVW(-40,640,i,a,5,5)	;1 OF 3
	LVW(640,640,i,a,5,5)	;1 OF 4
	LVW(-40,640,i,a,5,5)	;1 OF 5
	LVW(-700,-700,i,a,5,5)	;2 OF 2
	LVW(640,-700,i,a,5,5)	;2 OF 3
	LVW(-700,-700,i,a,5,5)	;2 OF 4
	LVW(640,300,i,a,5,5)	;2 OF 5
	LVW(-700,-700,i,a,5,5)	;3 OF 3
	LVW(-700,640,i,a,5,5)	;3 OF 4
	LVW(500,-700,i,a,5,5)	;3 OF 5
	LVW(640,-700,i,a,5,5)	;4 OF 4
	LVW(-540,-700,i,a,5,5)	;4 OF 5
	LVW(-700,300,i,a,5,5)	;5 OF 5


	END	STRT		;FINALLY, THE END
