
TITLE	MIT-AI PDP-6/10 Space-War

.MLLIT==1

IF2,{PRINTC "This is version " ? .TYO6 .FNAM2 ? PRINTC "
"}

	SUBTTL	Organization of Source File

;This file is organized roughly as follows:
;
;    1. Organization, History, and Record of Modifications
;    2. Macro Definitions
;    3. General Definitions (assembly parameters, general constants, bit names)
;    4. Low Core and I/O Routines (includes 340 definitions)
;    5. One-Time and Per-Game Initialization
;    6. Main Loop
;    7. End-Game Processing
;    8. The Vector of Mysteries
;    9. Type Definitions and Object Tables (includes type bit defintions)
;   10. Ship Code (includes initialization, update, collision handling, etc.)
;   11. Sun Code (includes gravity computation)
;   12. Other Types Code (Hyper-ships, Exploding Ships, Fragments, Torpedoes,
;	   Phasars, and Force-Fields)
;   13. Miscellaneous Routines (trigonometric, random number generators, etc.)
;   14. Display Lists (includes star field, fragments, etc.)
;----------------------------------------------------------------------------------------------


	SUBTTL	History of Space War

;WAR -> SWAR -> SUPER -> STAR -> SPACE -> SPACE4 -> NSPACE -> SPCWAR

;Present maintainers of Space-War are
;	KLH@MIT-AI, GMP@MIT-MC, and CBF@MIT-ML

; The history of the game will be added here as it is determined.

; On the ninth of April 1976, the new nine-bit Space-War consoles were completed.
;The consoles were designed and constructed by Kevin Hunter (KH).  Ken
;Harrenstein (KLH) and Lee Parks (LSP) spent ten hours wiring the new consoles
;into the PDP-6 alternate data switches bank.
;----------------------------------------------------------------------------------------------


	SUBTTL	Record of Modifications

;Modified:	04/10/76-	GMP
;		04/11/76:
;	Converted to seperate display lists for each ship.
;	Added capability to dynamically alter ship designs used during a game.

;Modified:	04/12/76:	GMP
;	Fixed the following bugs caused by previous modification:
;	1. Infinite loop on start-up: Caused by using a null display list.
;	2. Bug causing ships not in game to be displayed in score mode if
;	   they were in a previous game.
;	3. NXM when RANSUN was on: modifying "wired" register
;	4. Scores were displayed poorly.
;	5. Scores would never reset if game was last restarted at location
;	   101. (Old bug)
;	Removed SUNLCn from vector of mysteries as it is no longer used.

;Version 139:	04/13/76:	GMP
;	1. Finally fixed bug preventing start-up of prgoram.
;	2. Fixed bug causing shields to not be properly displayed.
;	3. Fixed SETF to recoginize upper and lower case responses due to
;	   recent changes in MIDAS.
;	4. Fixed to add FADR with 0.0 after all FSC's when running on PDP-6.

;Version 141:	04/16/76:	GMP
;	1. Fixed bug which caused the game not to end if a star-ship collided
;	   with a hyper-space star.

;Version 142:	04/17/76:	GMP
;	1. Converted to use mnemonic names for 340 display instructions.

;Version 148:	04/29/76:	GMP
;	1. Combined SPCWAR and ^COMBO into one assembly job.  Several .INSRT
;	   files were created (see following pages).
;	2. Converted STAR macro to use 340 command names.
;	3. Deleted non-AGB square root routine.
;	4. Change RELATV subroutine to a macro as it was called in only four places.

;Version 153:	10/18/76:	GMP
;	1. Fix bug where once a black-hole was used, there would always be a black-hole.
;	2. Add to the Vector of Mysteries:
;	   VERSION - the version of SPCWAR in SIXBIT, and
;	   OPTIONS - a bit string specifying the options with which SPCWAR was assembled.

;Version 154:	10/30/76:	GMP
;	1. Minor change to make correspondence of ships to control boxes more logical
;	   (see BUTTNS array).
;	2. Changed name of ships to more mnemonic values.
;	3. Added code to type version number of game on pass 2 of assembly.

;Version 155:	10/30/76:	GMP
;	1. Removed $FLARE, $TEXT, and $FBALL assembly parameters.
;	2. Made flares and fireballs the default situation.

;Version 161:	11/05/76:	GMP
;	1. Combined all files into a single source as it was already a single assembly.
;	2. Renamed a number of assembly parameters and tables.
;	3. Fixed a minor bug in the generion of flares that caused only half the number
;	   of vectors requested to appear.

;Version 163:	11/05/76:	GMP
;	1. Fixed the bug which caused display to flicker when a ship crossed an X
;	   boundary on the screen (X=0 or X=1024.).

	SUBTTL	Acumulator Defintions

; A wired accumulator may not have its value modified without extreme caution.

F=0

P=1					; PDL pointer (wired)

A=2					; Temporary registers
B=3
C=4
D=5
T=6
TT=7
MP1=10					; Index of object being processed
MP2=11

R=12
XFLAG=13

Q=14					; PDL pointer for current miscellaneous display
					;  buffer (wired)

S=15

DL=16					; Pointer to current display linked list (wired)
DP=17					; Pointer to display list being output (wired)

	SUBTTL	Assembly Parameter Defintions

; Macro to set a flag according to user's request

DEFINE SETFLG TEXT,FLAG
.TAG LOOP
%RETRY==0
	PRINTC "TEXT (" ? PRTVAL \FLAG ? PRINTC "): "
	.TTYMAC IFLAG
	IFSE [IFLAG][]		.STOP
	IFSE [IFLAG][YES]	FLAG==1 ? .STOP
	IFSE [IFLAG][yes]	FLAG==1 ? .STOP
	IFSE [IFLAG][Y]		FLAG==1 ? .STOP
	IFSE [IFLAG][y]		FLAG==1 ? .STOP
	IFSE [IFLAG][NO]	FLAG==0 ? .STOP
	IFSE [IFLAG][no]	FLAG==0 ? .STOP
	IFSE [IFLAG][N]		FLAG==0 ? .STOP
	IFSE [IFLAG][n]		FLAG==0 ? .STOP
	IFN IFLAG,		FLAG==IFLAG ? .STOP
	IFDEF IFLAG,		FLAG==IFLAG ? .STOP
	PRINTC "Undefined value; please retry.
"
	%RETRY==1
	TERMIN
	IFN %RETRY,		.GO LOOP
TERMIN


; Miscellaneous macros

DEFINE PRTVAL VALUE			; Macro to print a value
	IFE VALUE,	PRINTC "NO"
	IFE VALUE-1,	PRINTC "YES"
	IFG VALUE-1,	PRINTX /VALUE/
TERMIN

DEFINE NONITS TEXT,FLAG			; Similar to SETFLG below but only if not ITS
	IFN $ITS,	FLAG==0
	IFE $ITS,	SETFLG [TEXT] FLAG
TERMIN


; Define default values of conditionals

IF1,[
$ITS==  0				;Do not run under ITS
$10INT==1				;Enable interrupt to stop game
$MXSHP==4				;Maximum number of ships
$MXDSN==4				;Number of ship designs
$MXSUN==3				;Maximum number of suns
$MOVIE==0				;No movies


; Ask the user to change any options

PRINTC "Reply with <RETURN> to use default value.
"

	SETFLG	[ITS version] $ITS
	NONITS	[Inter-processor interrupt] $10INT
	SETFLG	[Maximun number of ships (1-4)] $MXSHP
	IFL $MXSHP-3,	$SSTYP==1	; Defaults to new ships
	IFL $MXSHP-3,	SETFLG [Enterprize and Klingon] $SSTYP
	SETFLG	[Number of ship designs] $MXDSN
	SETFLG	[Maximum number of suns (0-3)] $MXSUN
	NONITS	[Game recording] $MOVIE

PRINTC "
"
]

	SUBTTL	Miscellaneous Definitions

OBJCTS==50.				;NUMBER OF OBJECT IN GAME
					; TAKE CAUTION WHEN INCREASING THIS VALUE AS
					; THE GAME MAY SLOW DOWN


CPI==   3.1415926535897932384626433832	; Double precision value of PI
CPI.5== 1.5707963267948966192313216916


;---------- Lengths and Sizes

FFCPTS==30.				; Number of points in force field circle

LRANTB==200				; Length of random number table

MDBUFL==5000				; Length of miscellaneous display buffers

CORSIZ==40000				; Size of PDP-6 memory (16K)


;---------- Op-Codes and Instructions

PJRST==JRST				; PJRST X replaces PUSHJ P,X ? POPJ P,

JOV==<JFCL 10,>				; jump on overflow


;---------- Device Codes

WCNSLS=420				; Space-War consoles
..D420=WCNSLS

ITPDEV=20				; Inter-processor device
..D20=ITPDEV


;---------- Channel Assignments

APRCHN==1				; APR gets highest priority

FLGCHN==3				; Special Display Interrupts
DISCHN==4				; Normal Display

ITPCHN==7				; Inter-processor Device gets lowest priority


;---------- Initialize Symbols Used in Macros

%DSNNO==0				; Current ship design number

%MAXLN==0				; Maximum ship display list length

.X==    8192.				; Initial X coordinate for STAR macro

	SUBTTL	Miscellaneous Macros

DEFINE SSFIX A,B			;floating to fixed
	MULI A,400
	TSC A,A
	ASH A+1,-243+19.!B(A)
TERMIN

DEFINE SFIX A,B				;faster, but works only for + numbers
	MULI A,400
	ASH A+1,-243+19.!B(A)
TERMIN


DEFINE GETRAN AC			;get a random # at speed of light
	SOSGE AC,RINDEX
IFSE [AC][A]	PUSHJ P,RINSET		; if AC = A, needn't preserve.
.ELSE		PUSHJ P,RINSTX		; Else must.
	MOVE AC,RANTAB(AC)
TERMIN


DEFINE LIMIT XORY,AC			;X REPRESENTS EITHER "X" OR "Y"
	FADRB AC,OBJ!XORY(MP1)
	JUMPL AC,[SKIPN BOUNCE
		 JRST [	FADR AC,[1024.0] ;NORMAL +VE WRAP
			MOVEM AC,OBJ!XORY(MP1)
			JRST .+3]
		MOVM AC,AC
		MOVEM AC,OBJ!XORY(MP1)	; +VE BOUNCE
		MOVNS OBJ!XORY!VL(MP1)
		JRST .+3]
	CAML AC,[1024.0]
	 JRST [	SKIPN BOUNCE
		 JRST [	FSBR AC,[1024.0] ; -VE WRAPAROUND
			MOVEM AC,OBJ!XORY(MP1)
			JRST .+1]
		FSBR AC,[2048.0]	; -VE BOUNCE
		MOVM AC,AC
		MOVEM AC,OBJ!XORY(MP1)
		MOVNS OBJ!XORY!VL(MP1)
		JRST .+1]
TERMIN


DEFINE DISPT				;DISPLAY A POINT: PLACED IN CURRENT BUFFER
	MOVE MP2,D			;Y IN LH(D) -> LH(MP2)
	HLR MP2,C			;X IN LH(C) -> RH(MP2)
	AND MP2,[1777,,1777]		;COORDS MODULO 1024.
	IOR MP2,[PT%Y\NC%PNT,,PT%X\PT%DSP\NC%PNT]	;MAKE POINT MODE DISP COMMAND
	PUSH Q,MP2			;PUT IN LIST
TERMIN


DEFINE PFDVR AC,LOC			;DIVIDE WITH CHECK FOR OVERFLOW
	JOV .+1
	SKIPN LOC
	 JRST [	CAIL AC,0
		SKIPA AC,MAXFLO
		 MOVN AC,MAXFLO
		JRST .+3]
	FDVR AC,LOC
	JOV [	CAIGE AC,0
		 TROA F,OV%NEG
		  TRZ F,OV%NEG
		MOVM AC,AC
		CAML AC,[201400,,0]
		 JRST [	SETZ AC,
			JRST .+1]
		MOVE AC,MAXFLO
		TRZE F,OV%NEG
		 MOVN AC,AC
		JRST .+1]
TERMIN


DEFINE RELATV AC1,AC2			;COMPUTE RELATIVE DISTANCE WITH WRAPAROUND
	FSBR AC2,AC1
	MOVM AC1,AC2
	CAML AC1,[512.0]
	 JRST [	SKIPL AC2
		 JRST [	FADR AC2,[-1024.0]
			JRST .+1]
		 FADR AC2,[1024.0]
		JRST .+1]
TERMIN


DEFINE SLISTS				;generates display list section for ships
REPEAT $MXSHP,[	SDPTRS+.RPCNT,,.+1
]
TERMIN


DEFINE BITDEF A,B,C			;produces definition BITA.B and BITC
BIT!A!.!B==1_<<A-1>*9.+<B-1>>
BIT!C==1_<35.-C>
TERMIN


; Start 340 display

IFE $ITS,[
DEFINE DSTART AC			;PDP-6 version
	MOVE DL,DISLST
	MOVE DP,[-1,,[0]-1]		;causes immediate interrupt
	CONO DIS,D%INIT+<FLGCHN_3>+DISCHN
TERMIN
]

IFN $ITS,[
DEFINE DSTART				;ITS version
	.DSTART DISLST
	 .VALUE [ASCIZ /: 340 DISPLAY IS NOT AVAILABLE 
/]
TERMIN
]

	SUBTTL	Define Bit Names

RADIX 10.

%%3==-1
REPEAT 4,[%%1==.RPCNT+1 ? REPEAT 9.,[%%2==.RPCNT+1 ? %%3==%%3+1
BITDEF \%%1,\%%2,\%%3
]]

RADIX 8.


;---------- Miscellaneous Bit Definitions

OV%NEG==BIT35				; On if floating overflow was negative


APRBIT==1_<7-APRCHN>			; Bit to enable corrsponding channel

FLGBIT==1_<7-FLGCHN>
DISBIT==1_<7-DISCHN>

IFN $10INT,	ITPBIT==1_<7-ITPCHN>
IFE $10INT,	ITPBIT==0

	SUBTTL	Bit Definitions - PDP-6 Interrupt System

; ------ PDP-6 APR condition flags
;CONO
	A%RPOV==bit18			;reset the PDL OV flag
	A%RIO== BIT19			;I/O reset
	A%RMP== BIT22			;reset the Memory Protection flag
	A%RNXM==BIT23			;reset the nonexistent Memory flag
	A%CCEZ==BIT24			;turn the Clock Count Enable flag off
	A%CCEO==BIT25			;turn the Clock Count Enable flag on
	A%CLKZ==BIT26			;turn the Clock flag off
	A%PCEZ==BIT27			;turn the PC Change Enable flag off
	A%PCEO==BIT28			;turn the PC Change Enable flag on
	A%PCFZ==BIT29			;turn the PC Change flag off
	A%OVEZ==BIT30			;turn the OV flag enable off
	A%OVEO==BIT31			;turn the OV flag enable on
	A%OVFZ==BIT32			;turn the OV flag off
	;33-35 = assign PI channel to APR flags (listed above)

	;Reset and clear all flags and I/O
	A%STRT==A%RPOV+A%RIO+A%RMP+A%RNXM+A%CCEZ+A%CLKZ+A%PCEZ+A%PCFZ+A%OVEZ+A%OVFZ

;CONI
	A%POV== BIT18			;PDL OV flag set
	A%ILOP==BIT22			;Illegal Instruction flag set
	A%NXM== BIT23			;non-existent Memory flag set
	A%CCE== BIT25			;Clock Count enable on
	A%CLK== BIT26			;Clock Count flag set
	A%PCE== BIT28			;PC Change enable on
	A%PCF== BIT29			;PC Change flag set
	A%OVE== BIT31			;OV enable on
	A%OVF== BIT32			;OV flag set
	;33-35 = set to the current PI channel assignment


;-------- PDP-6 Priority Interrupt system flags
;CONO
	P%CLR== BIT23			;clear the PI system
	P%ACT== BIT24			;activate interrupt on channels selected (29-35)
	P%CENB==BIT25			;enable channels selected (")
	P%CDSB==BIT26			;disable channels selected (")
	P%OFF== BIT27			;turn off the PI system
	P%ON==  BIT28			;turn on the PI system
	;29-35 = channel select: bit 29 selects channel 1,
	;	 bit 35 selects channel 7, etc.

;CONI
	P%PIUP==BIT28			;PI system is on
	;29-35 = if a bit is 1, corresponding channel is on.


;---------- 340 display flags
;CONO
	D%INIT==BIT1.7			;initialize display
	D%CONT==BIT1.8			;resume display after special interrupt


;---------- Interprocessor interupt flags
;CONO
	I%CENB==BIT1.4			;reset and enable interrupts

	SUBTTL	Bit Definitions - 340 Display Commands

; The flags below are for a display command in the right half of a word.
;In this way, they can be used to generate instructions for either half of a word.
;NOTE:  These bit definitions will be replaced for the most part by macros.

;---------- Set mode of next command
	NC%PMR==0			;parameter
	NC%PNT==BIT22			;point
	NC%VCT==BIT20			;vector
	NC%VCC==BIT20\BIT22		;vector continue
	NC%CHR==BIT21\BIT22		;character
	NC%INC==BIT20\BIT21		;increment


;---------- Parameter mode command
	PM%ELP==BIT23			;enable lisght pen status change
	PM%LPS==12.			;with _ operator to place constant pen status
	PM%LPM==004000			;mask to get light pen status (1 bit)
	PM%STP==BIT25			;stop display
	PM%STI==BIT26			; ... generate interrupt
	PM%ESC==BIT29			;enable scale change
	PM%SCS==4.			;shift for scale
	PM%SCM==000060			;mask for scale (2 bits)
	PM%EBR==BIT32			;enable brightness change
	PM%BRM==000007			;mask for brightness (3 bits)

	PM%HLT==PM%STP\PM%STI		;parameter mode command to halt display


;---------- Point mode command
	PT%X==  0			;specify X ordinate
	PT%Y==  BIT19			;specify Y ordinate
	PT%DSP==BIT25			;display the current point
	PT%MSK==001777			;mask for value of coordinate

	PT%NOP==NC%PNT			;no-op command to point mode


;---------- Vector and vector continue command
	VC%ESC==BIT18			;return to parameter mode after this command
	VC%DSP==BIT19			;display this vector
	VC%YSN==BIT20			;sign bit for Y ordinate
	VC%YMS==8.			;shift for Y magnitude
	VC%YMM==077400			;mask to get Y magnitude (8 bits)
	VC%XSN==BIT28			;sign for X ordinate
	VC%XMM==000177			;mask for X magnitude (8 bits)


;---------- Special character for 340 character generator
	CH%ESC==37			;return to parameter mode
	CH%UC== 35			;upper case shift
	CH%LC== 36			;lower case shift
	CH%LF== 33			;line feed (any case)
	CH%CR== 34			;carriage-return (any case)
	CH%SP== 40			;space (any case)

	SUBTTL	APR Interrupt Processing

IFE $ITS,[
IFN $10INT,[
LOC ITPCHN*2+40
	JSR ITPBRK
]
LOC APRCHN*2+40
	JSR APRBRK			;jump to process clock interrupt (usually)
LOC FLGCHN*2+40
	JSR DSPBRK
LOC DISCHN*2+40
	BLKO DIS,DP			;put out next command word
	JSR DISBRK			;if done
LOC 41
	0				;should not JRST GO since
					;  may not be completely loaded.
LOC 61
	JSR FATAL
]
IFN $ITS,[
LOC 42
	JSR TSINT
]

LOC 100
	TDCA A,A			;100 is standard starting address.
	 SETO A,			;101 also starts but preserves scores.
	MOVEM A,SAVSCR'
	JRST GO

IFE $ITS,[
;interrupt handler for the clock (actually, APR in general)
APRBRK:	0
	CONSO APR,A%CLK			;is it 1/60 sec clock interrupt?
	 JRST APRBR3			; no - go handle exception
	SOSLE CLKCNT			;yes, decrement clock count... time up?
	 JRST APRB2			; nope, return.
	SETOM CLKSNK			; time's up! clear synch lock
	EXCH A,STEPTM			;get step time
	MOVEM A,CLKCNT			;store as new clock count
	EXCH A,STEPTM			;and restore acc A.
	CAMN DP,DISPNS'			;is current dis BLKO same as last tick?
	 CONO PI,P%act\FLGBIT		; yes - interrupt on FLGCHN to change list
					; (DISCHN handler doesn't CONO DIS, to restart!)
	MOVEM DP,DISPNS			;and remember current ptr for next tick.
APRB2:	CONO A%clkz\A%cceo\APRCHN	;restart clock,
	JRST 12,@APRBRK			;and dismiss.
]
CLKSNK:	0				; Clock synch lock, -1'd every STEPTM 60th's.
CLKCNT:	0				; current countdown of 1/60th sec ticks before
					;  -1'ing CLKSNK.  (see STEPTM in Vec of Myst.)
IFE $ITS,[

APRBR3:	CONSO APR,A%nxm			;skip if non-ex mem
	 JSR APRBAD			;foo! something we can't handle.
IFE $MOVIE,[
	AOS NXMCNT'			;increment cnt
	SKIPN NXMSW'			;switch says do anything special?
	 JSR APRBAD			;no, die
	SKIPL NXMSW			; if -1, ignore; if 1, stop but allow proceeding
	 JRST 4,.+1			;stop.  pushing CONTINUE will ignore the NXM.
	CONO APR,A%RNXM+A%RMP
	JRST APRB2
]
IFN $MOVIE,[
	PUSH P,A			;yes, NXM. something hit end of core. wrap back.
	PUSH P,B
	SETZM TWICE'			;set flag to do it twice
	SOS APRBRK			;point to bad or previous instr.
APRNX1:	MOVE B,@APRBRK			;get instr
	SETCM A,B			;compl for opcode test
	TLNN A,134000			;skip if ones incorrect for byte instr
	 TLNE B,640000			;don't skip if zeros incorrect
	  JRST APRNX2			;not a byte instr.
	HRRZ A,@B			;byte instr. get rh of pointer
	CAIGE A,40000			;skip if cause has been found
	 JRST APRNX2			;jump away if not
	HLLZ A,@B			;get lh of ptr
	TLZ A,770077			;mask off
	TLO A,440000			;set up new ptr
	HRRI A,PRGEND			;with new addr
	MOVEM A,@B			;and insert back
	CONO A%rnxm			;reset nxm flag
	POP P,B
	POP P,A
	JRST APRB2			;return
APRNX2:	SKIPE TWICE
	 JSR FATAL			;not a byte instr at all
	SETOM TWICE
	AOS APRBRK
	JRST APRNX1			;try next instr
]

APRBAD:	0				;come here when APR int. handler lost.
	CONI APR,APRCSV
	JSR FATAL
APRCSV:	0				;SAVE APR CONDITIONS
] ;END OF IFE $ITS

IFN $ITS,[
TSINT:	0
	0
	SKIPGE DL,TSINT
	 .DISMIS TSINT+1		;IGNORE 2ND WD INTS
	TLNN DL,(%PIRLT)		;REALT INT?
	 .DISMIS TSINT+1
	 SETOM CLKSNK
	.SUSET [.SAMASK,,[%PIRLT]]	;TURN OFF FUTURE INTS
	.DISMIS TSINT+1
]

	SUBTTL	Display Interrupt Processing

IFE $ITS,[
DISBRK:	0
DISBR0:	TRNN DL,-1			;ADDR OF NEXT ITEM IN RH?
	 MOVE DL,DISLST			;NO, GET PTR TO BEG OF CURRENT DISLIST
	MOVE DL,(DL)			;GET ITEM
	HLRZ DP,DL			;GET ADDR OF BLKO PTR FOR ITEM
	JUMPE DP,DISBR0			;NOTHING THERE, GET NEXT ITEM
	SKIPL DP,(DP)			;GET BLKO PTR
	 JRST DISBR0			;AGAIN NOTHING THERE, GET NEXT.
	JRST 12,@DISBRK			;RETURN


DSPBRK:	0				;SPECIAL DISPLAY INTERRUPT
	HLRZ DP,DL			;GET ADDR OF BLKO THAT INTERRUPTED
	CAIN DP,BKPT1			;IF WAS DOING FIRST BACKGROUND,
	 MOVE DL,(DL)			;SKIP NEXT (2ND BACKGND) ITEM.
DSPBR1:	TRNN DL,-1
	 MOVE DL,DISLST
	MOVE DL,(DL)
	HLRZ DP,DL
	JUMPE DP,DSPBR1
	SKIPL DP,(DP)
	 JRST DSPBR1
	CONO DIS,D%INIT+<FLGCHN_3>+DISCHN
	JRST 12,@DSPBRK			;RETURN
]

DISLST:	0				;PTR TO CURRENT DISLIST, SET BY DSTART.

DSLST1:	MDBPTR,,DSLSTC			;DISPLAY LIST USING FIRST BUFFER
DSLST2:	MDBPTR+1,,DSLSTC			; USING SECOND BUFFER

DSLST3:	SLISTS				;USED TO DISPLAY SCORES
	TDPTR,,0

DSLSTC:	SLISTS				;REMAINDER OF DSLST1 AND DSLST2
	TDPTR,,[BKPT0,,[BKPT1,,[BKPTR,,0]]]

SDPTRS:	BLOCK $MXSHP			;BLKO POINTERS FOR EACH SHIP DISPLAY LIST

TDPTR:	0				;BLKO POINTER FOR TORPEDOS

MDBPTR:	0				;HOLDS BLKO FOR MDBUF1
	0				;FOR MDBUF2

BKPT0:	-1,,BKVEC'-1			;HOLDS INITIALIZER FOR STARS
BKPT1:	0				;HOLDS PTR AT STARS
BKPTR:	0
BKPTRA:	-<BKEND-BKBEG>,,<BKBEG-1>	;HOLDS PTR TO ALL STARS

	SUBTTL  Interprocessor Interrupt handling

	; Hack to process interrupts from 10 and do stuff
	; like blow up ships, display messages, etc.
	; No-op for now until coded to work with new display scheme.

IFE $ITS,[IFN $10INT,[
ITPBRK:	0
	CONO ITPDEV,10+ITPCHN	; Reset interprocessor device
	JRST 12,@ITPBRK		; and reset channel
]]

	SUBTTL	Move Backround Star Field

BKINIT:	PUSH P,A
	SETZM BKTMF'			;zero backround time (star date?)
	SETZM BKTIME'
	SETZM BKTS'
	SETZM BKX'			;zero current start of backround list
	MOVE A,BKSTP			;set up star field pointer
	MOVEM A,BKSTRT'
	MOVE A,[PM%ESC\<0_PM%SCS>\NC%PNT,,PT%X\NC%VCT+0]
					;<scale zero, enter point>,,<x = 0, enter vector>
	MOVEM A,BKVEC
	SETZM BKPT1
IFN $ITS,	SETZM BKPTR
IFE $ITS,[
	MOVE A,BKPTRA
	MOVEM A,BKPTR
]
	POP P,A
	POPJ P,

;routine to shift the star field and display it
BKMOVE:	MOVE A,BKTIME			;get new star time and save it
	EXCH A,BKTS
	SUB A,BKTS			;compute -delta time

BK0:	ADDB A,BKX			;compute current x - delta time
	JUMPGE A,BK1			;if positive do not shift field

	;shift the star field
	IBP BKSTRT			;look at next halfword
	AOS A,BKSTRT			;get address of next word in list
	HRRZS A
	CAIGE A,BKEND			;skip if past end of field
	 JRST BK2
	MOVE A,BKSTP			;start over at beginning of field
	MOVEM A,BKSTRT

BK2:	LDB A,BKSTRT			;get next x value
	ANDI A,177
	JRST BK0			;and use it as delta time

BK1:	HRLI A,PM%ESC\<0_PM%SCS>\NC%PNT
	MOVEM A,BKVEC			;go to point mode, scale is 0
	MOVE A,BKSTRT			;get pointer to first star to display
	SKIPL @BKSTRT			;skip if a vector command
	 ADDI A,1			;will output another word
	MOVEI A,(A)
	SUBI A,BKEND			;compute length to end of list
IFN $ITS,[
	CAML A,[-100]
	 PJRST BKINIT
]
	MOVSS A
	HRR A,BKSTRT			;get starting address
	SKIPGE @BKSTRT			;if a vector command, use previous word instead
	 SUBI A,1
	MOVEM A,BKPT1
	POPJ P,

BKSTP:	.BP (777777),BKBEG		;byte ptr to beginning of star field.

	SUBTTL	The VECTOR Of MYSTERIES

VERSIO:	.FNAM2	;the version of Space-War

OPTION:	$MXSHP+$MXSUN_3+$ITS_6+$10INT_7+$MOVIE_12
;	    Specifies options used to assemble SPCWAR:
;		2.2: on if movies enabled
;		2.1: on if flares used in explosions
;		1.9: on if fireballs (ala PDP-9 war in use)
;		1.8: on if 10-6 interrupts enabled
;		1.7: on if ITS version of the game
;		1.6 - 1.4: maximum nummber of suns
;		1.3 - 1.1: maximum number of ships

ZAPPER:	0	;0=torp game,1=beam game

TNO:	30.	;# of torps
TVL:	12.0	;torp vel
RLT:	14.	;torp reload time in 30ths (0=one torp per push)
TLF:	110.	;torp life in 30ths
TXTM:	15.	;torp explode time in 30ths
TORBRI:	7	;torp brightness (0-7)

NSHIPS:	$MXSHP	;number of ships (initially max # assembled for)
NFU:	40.0	;fuel supply
SAC:	0.025	;spaceship accel
MAA:	.08	;angular accel (radians per 1/30 sec)
SPIN:	0	;0=normal turn+stop, 1=true space spin
MAALIM:	CPI.5	; when SPIN=1, exceeding this ang. vel. is fatal.
HYPT1:	120.	;time invisible in hyperspace (30ths)
HYPT2:	110.	;time as hyperspace star (30ths)
HYPT3:	120.	;hyperspace reload time (30ths)
HYPBO:	10	;hyperspace lose rate (fraction of 100 octal)
SSEXTM:	90.	;ss explode time (30ths)
SSBRI:	4	;ss brightness (0-7)
SHPSIZ:	1.0	;SS size (ratio - 1.0 normal, 2.0 twice size, etc)

STR:	12.5	;star capture radius
GRV:	600.0	;grav constant (gravity strength)
KILLER:	1	;0=warper sun, 1=killer sun
NSUNS:	$MXSUN	; yes!
RANSUN:	0	;0=specified sun locs, 1=random sun locs each game
BHOLE:	0	;1=make one sun invisible (black hole)
SUNBRI:	4	;sun brightness (0-7)

RANST:	0	;0=fixed start pos., 1=random start pos. (of ships)
EGT:	15.	;delay at end of game (30ths)
SCRTIM:	3*30.	;length of time to display scores (30ths)
ME1:	12.5	;max collision radius
BOUNCE:	0	;if non-zero, bounce off edges
FIRBAL:	1	;if non-zero, fireballs are deadly
SHPMAS:		1.0			;MASS OF A SHIP
TRPMAS:		0.5			;MASS OF A TORPEDO
EXSCL:	0	;explosion scale
FLRSCL:	3	;FLARE SCALE
BKGTSP:	0.05	;rate of star flow
GSSBX:	0	;control selection: 0=consoles, 1=data sws
		;(restart if you change gssbx)
SERL:	1	;scorekeeper series length (0=no scoring)
MSCBRI:	5	;miscellaneous (flames,expl,etc.) bri. (0-7)
STEPTM: 2	;clock rate in 1/60th's. 2 means each step = 1/30 sec
FATAL:	0
	JRST 4,34000   ;to ddt (tenlod) jsr'ed here when lose
HYPLOS:	BLOCK $MXSHP	;REQUIRES BOTH FIRE&HYPER BUTTONS TO HYPER
			;(this is a lossage due to use of weird consoles)

;********* Phaser (beam) component **********
RAYLEN:	400.	;length of beam (never over 512.!)
BRATE:	0.005	;beam power rate
FFRATE:	0.01	;rate of power loss for f.f.
FHITRT:	0.15	;power loss rate, attacked f.f..
TDSABL:	5.	;disable time(30ths)
DESTR1:	20.	;destruct time, consecutive hits
DESTR2:	100.	;destruct time, total hits
DISTIM:	450.	;time he is disabled
BMPLN:	90.	;time he can fire beam
BMRLD:	90.	;beam reload time
NOHYPR:	1	;0 = allow hyperspace, 1 = do not
;********************************

	SUBTTL	One Time Initialization and Patch Area

PAT:
PATCH:	BLOCK 50
PDL:	-40,,.
	BLOCK 40
MAXFLO:	377777,,777777			;MAX POSITIVE # (INT. OR FLOAT)
PIE:	CPI
PI2:	.OP FMPR CPI 2.0
PI1.5:	.OP FMPR CPI 1.5
PI.5:	.OP FMPR CPI 0.5
PI.25:	.OP FMPR CPI 0.25


	;one time initialization of the game

GO:	MOVE P,PDL
IFE $ITS,[
	MOVEI A,400000
	SOJGE A,.			;delay to ensure everything loaded
	CONO APR,A%STRT+APRCHN		;clear all APR flags and I/O
	CONO APR,A%CCEO+APRCHN		;enable clock
IFN $10INT, CONO ITPDEV,10+ITPCHN		;enable interrupts from pdp10
]

	PUSHJ P,BKINIT			; Initialize background starfield.
	CONO WCNSLS,40			;enable spacewar consoles
	PUSHJ P,CMPASS			;set up shield points for faster display
	MOVE A,[DATAI WCNSLS,T]		;for input selection. get datai for consoles
	SKIPE GSSBX			;and plug in if gssbx agrees.
	 MOVE A,[DATAI T]		;else get datai for data switches
IFE $MOVIE [
	MOVEM A,GSS			;and put in routine.
]
IFN $MOVIE [
	MOVEM A,GSS11			;and put in routine.
	MOVEM A,GSS21			;(2 ships, 2 input routines)
]

IFN $ITS,[
	MOVE A,[600000,,STEPTM]		;interrupt every steptm/60 sec
	.REALT A,
	 JFCL
	.SUSET [.SMASK,,[%PIRLT]]	;ENABLE RLT
	.SUSET [.SPICLR,,[-1]]		;ENABLE INTS
]

	MOVE T,TDISPT			;set up torpedo BLKO pointer
	MOVEM T,TDPTR
	PUSHJ P,SETSHP			;set ship BLKO pointers
	MOVEI A,DSLST3
	MOVEM A,DISLST
	DSTART 				;START 340 NOW WITHOUT SHIP AND TORP AREAS

IFE $ITS,[	CONO PI,P%CLR\P%CENB\P%ON\APRBIT\FLGBIT\DISBIT\ITPBIT
					;clear PI system and enable ints for channels
]

	SUBTTL	Per-Game Initialization

	;come here to clear scores before beginning series of games
SERIES:	MOVE A,SERL			;reset series length
	MOVEM A,SERCNT'
	SKIPE SAVSCR			;and clear scores unless requesting save.
	 JRST GAME
	MOVSI A,-$MXSHP			;get number of ships
	SETZM SCORE(A)			;zero scores for new series
	AOBJN A,.-1

	;initialization performed on a once per game basis
GAME:	PUSHJ P,RANSET			;set up random # table

	MOVSI A,-OBJCTS
	 SETZM OBJFLG(A)			;clear update address of each object
	 AOBJN A,.-1

	MOVE A,NSHIPS
	CAILE A,$MXSHP
	 MOVEI A,$MXSHP			;NSHIPS may not exceed $MXSHP
	MOVEM A,NSHIPS
	IMUL A,[-1,,0]			;create AOBJN pointer
	MOVEM A,NEGSHP'

	MOVE A,NSUNS			;same for NSUNS
	CAILE A,$MXSUN
	 MOVEI A,$MXSUN
	MOVEM A,NSUNS
	IMUL A,[-1,,0]
	MOVEM A,NEGSUN'

IFN $MOVIE,[	PUSHJ P,TAPRT		;do necessary stuff for taping setup
]


	;Perform set-up code for objects of those types for which
	;set-up is required.

	MOVEI R,0

	SKIPN SETTBL(R)			;done when zero address
	 JRST GAME2
	PUSHJ P,@SETTBL(R)		;set up this object class
	AOJA R,.-3


GAME2:	SETZM GEFLG'			;game is in progress

	MOVE A,NSHIPS
	SUBI A,1			;set counter that will hit zero when only
	MOVEM A,SSING'			; one ship left
	MOVE A,EGT			;save end of game delay
	MOVEM A,GECNT'

	MOVE A,ME1			;compute collision radius squared
	FMPR A,A
	MOVEM A,ME12'

	SETOB A,MDBFSW			;select an initial display list
	MOVE Q,MDBTAB+1(A)		;get BLKO  pointer for it
	MOVEM Q,MDBCUR

	LDB A,[.BP 7,MSCBRI]		;setup command for miscellaneous brightness
	IORI A,PM%EBR\NC%PNT
	MOVEM A,MDBFBR

	JRST ML0B			;and start the game


; Table specifying routines to set up each type of object in the game which
;requires set-up for any reason.  Currently, only suns, ships, and torpedos 
;require this processing

SETTBL:	SETSHP				;STAR-SHIPS
	SUNSET				;SUNS (I kept the name for KLH)
	SETTRP				;TORPEODS
	0				;end of list

	SUBTTL	Per-Game Star-Ship Initialization

SETSHP:	MOVE B,NEGSHP			;loop control

	MOVE C,SSEXTM			;values from vector of mystries for each ship
	MOVE T,TNO
	MOVN TT,NFU
	MOVE D,[%TSS,,SSS]		;initial update routine and type
	MOVEI XFLAG,100			;for computing hyperspace loss rate
	MOVE A,SHPMAS			;ship mass


	;Set all ships' vlaues except for starting location (see below).

STSHP1:	MOVEM T,MTR(B)
	MOVEM TT,MFU(B)
	MOVEM A,OBJMAS(B)
	MOVEM C,MB1(B)
	MOVEM D,OBJFLG(B)
	MOVEM XFLAG,MHYPP(B)

	SETZM OBJXVL(B)			;remaining variables are zeroed
	SETZM OBJYVL(B)
	SETZM OBJAVL(B)
	SETZM MNOGRV(B)			;affected by gravity
	SETZM MA1(B)
	SETZM MHYP(B)
	SETZM BMPOW(B)			;and phasar variables
	SETZM BMRLSF(B)
	SETZM BMENB(B)
	SETZM THENB(B)
	SETZM CWENB(B)
	SETZM CCWENB(B)
	SETZM DISTM(B)
	SETZM THITS(B)
	SETZM CHITS(B)
	SETZM HIT(B)
	SETZM DHITS(B)

	AOBJN B,STSHP1

	SKIPN RANST
	 JRST STSHP3			;set fixed locations


	;Give each ship a random starting position

	MOVE B,NEGSHP

STSHP2:	PUSHJ P,RANONE
	FMPR A,[1024.0]			;insure in proper range
	MOVEM A,OBJX(B)
	PUSHJ P,RANONE
	FMPR A,[1024.0]
	MOVEM A,OBJY(B)

	PUSHJ P,RANONE			;and random angle
	FMPR A,PI2
	MOVEM A,MTH(B)
	AOBJN B,STSHP2

	JRST STSHP5			;set up display information


	; Give each ship a fixed starting position and angle

STSHP3:	MOVE A,NSHIPS
	FSC A,233			;float number of ships
IFE $ITS,[	FADR A,[0.0]
]
	MOVE B,PI2
	FDVR B,A			;increment to equally place ships on circle

	MOVE D,NEGSHP
	TLNN D,1
	 JRST [MOVE C,PI.25		;even number of ships: first in upper right
	       JRST .+2]		; and skip next instruction
	 MOVE C,PI.5			;odd number of ships: first above center

STSHP4:	MOVE A,PIE
	FADR A,C			;make ship point to center
	MOVEM A,MTH(D)

	MOVE A,C
	PUSHJ P,SIN
	FMPR A,SHPIRD			;distance from center
	FADR A,[512.0]
	MOVEM A,OBJY(D)
	MOVE A,C
	PUSHJ P,COS
	FMPR A,SHPIRD
	FADR A,[512.0]
	MOVEM A,OBJX(D)

	FSBR C,B			;move around the circle clockwise
	AOBJN D,STSHP4


	; Set up information relating to generating the ship's display list.

STSHP5:	MOVE A,NEGSHP
	LDB B,[.BP 7,SSBRI]		;set up brighness instruction for dislay
	IORI B,PM%EBR\NC%PNT
	MOVEI C,PM%HLT			;stop command for last word of list

STSHP6:	MOVE MP2,SHPDSN(A)		;get design index to obtain information
	MOVE T,DSNADR(MP2)		;address of generation routine
	MOVEM T,SHPADR(A)

	MOVN TT,DSNLN(MP2)		;create a BLKO pointer for the list
	MOVE T,SDADRS(A)
	SUBI T,1
	HRL T,TT			;form <-length,,addr-1>
	MOVEM T,SHPDPT(A)

	MOVE T,DSNSL(MP2)		;ship-lengths
	MOVEM T,SHPSL(A)
	MOVE T,DSNSL1(MP2)
	MOVEM T,SHPSL1(A)
	MOVE T,DSNLN2(MP2)		;used to update list address
	MOVEM T,SHPLN2(A)

	MOVE T,SDADRS(A)		;place display instruction at list start
	MOVEM B,0(T)
	MOVEM C,1(T)			;make sure nothing happens until update

	MOVE T,SHPDPT(A)		;put BLKO pointer where display list expects it
	MOVEM T,SDPTRS(A)
	AOBJN A,STSHP6


	;Insure that all ships not in game have no display lists

	MOVE A,NSHIPS
	CAIL A,$MXSHP
	 POPJ P,			;no unused ships

	MOVEI A,$MXSHP
	SUB A,NSHIPS
	IMUL A,[-1,,0]			;make <nships-maxss,,0>
	HRR A,NSHIPS			;AOBJN pointer for ships not in game

	HLLZM SDPTRS(A)			;makes unused ship have no display list
	AOBJN A,.-1

	POPJ P,				;that's all

SHPIRD:	350.0				;initial ship radius from center

	SUBTTL	Sun and Torpedo Per-Game Initialization

	;Procedure to initialize suns for a game

SUNSET:	SKIPN S,NEGSUN
	 POPJ P,			;there are no suns

	LDB A,[.BP 7,SUNBRI]		;create command to set sun brightness
	IORI A,PM%EBR\NC%PNT
	MOVEM A,SUNBR'

	MOVE A,[%TSUN,,TWINKL]		;sun type plus name

	 MOVEM A,OBJFLG+$MXSHP(S)
	 SETZM SUNINV(S)		;clear black-hole flag
	AOBJN S,.-2

	SKIPE BHOLE
	 SETOM SUNINV 			;if this switch on, make sun #1 invisible

	SKIPN RANSUN
	 JRST SUNST2			;suns will be fixed

	;Place suns in random locations

	MOVE S,NEGSUN
SUNST1:	PUSHJ P,RANDOM			;get random position
	PUSHJ P,SUNDWN			;put it in
	AOBJN S,SUNST1
	POPJ P,				;that's all

	;Place sun sin fixed positions

SUNST2:	MOVE A,NSUNS
	FSC A,233			;float number of suns
IFE $ITS,[	FADR A,[0.0]
]
	MOVE B,PI2
	FDVR B,A			;put increment to equally space suns 

	MOVE S,NEGSUN
	CAME S,[-1,,0]
	 JRST SUNST3			;more than one sun

	MOVE A,[512.,,512.]		;one sun, place in center
	PUSHJ P,SUNDWN
	POPJ P,

SUNST3:	TLNN S,1
	 JRST [MOVE C,[0.0]		;even suns - start at right side
	       JRST .+2]
	 MOVE C,PI.5			;odd - start above center

SUNST4:	MOVE A,C
	PUSHJ P,SIN
	FMPR A,SUNIRD
	FADR A,[512.0]			;get Y coordinate (around center)
	MOVE T,A
	MOVE A,C
	PUSHJ P,COS
	FMPR A,SUNIRD
	FADR A,[512.0]			;and get X coordinate
	MOVE TT,A

	SSFIX TT,-1.			;fix X into left half on MP1
	SSFIX T,-19.			;fix Y into right half of TT
	HLL A,MP1			;put <x,,y> into A
	HRR A,TT
	PUSHJ P,SUNDWN			;set it

	FADR C,B			;get angle of next sun
	AOBJN S,SUNST4
	POPJ P,				;that's all

SUNIRD:	100.0				;distance of suns from center


	;Procedure to set sun location given [x,,y] in A

SUNDWN:	HLRZ MP1,A			;get X into MP1
	IDIV MP1,[1024.]		;get remainder in screen limits into MP2
	MOVEM MP2,ISUNLX(S)
	FSC MP2,233			;float it
IFE $ITS,[	FADR MP2,[0.0]
]
	MOVEM MP2,FSUNLX(S)
	MOVEM MP2,OBJX+$MXSHP(S)

	HRRZ MP1,A			;now fix Y coordinate
	IDIV MP1,[1024.]
	MOVEM MP2,ISUNLY(S)
	FSC MP2,233
IFE $ITS,[	FADR MP2,[0.0]
]
	MOVEM MP2,FSUNLY(S)
	MOVEM MP2,OBJY+$MXSHP(S)
	POPJ P,


	;Procedure to initialize torpedos for a game

SETTRP:	LDB A,[.BP 7,TORBRI]		;create command to set brightness of torps
	IORI A,PM%EBR\NC%PNT
	MOVEM A,TORDIS			;and put at start of list

	MOVE T,[PT%NOP,,PT%NOP]		;point no ops
	MOVSI A,TORDSB-TORDSE		;set list to noops
	MOVEM T,TORDSB(A)
	AOBJN A,.-1

	MOVE A,TDISPT			;fetch BLKO pointer
	MOVEM A,TDPTR			;place into DISLST: torps now displayed
	POPJ P,

	SUBTTL	Main Processing Loop of Space-War

ML0:	PUSH Q,[0]			;ENSURE IN PARAM MODE AT END
	HLRZ A,Q			;GET LH (USING THAT HELPS CHECK CONSISTENCY)
	ADDI A,MDBUFL			;GET CNT OF WDS PUSHED ONTO MDBUF LIST
	MOVN A,A
	HRLZ A,A
	HRR A,MDBCUR			;NOW HAVE BLKO PTR, -<CNT>,,<ADDR-1>
	MOVE B,MDBFSW			;GET CURRENT MDBUF SWITCH
	MOVEM A,MDBPTR+1(B)		;STORE BLKO PTR IN RIGHT PLACE
	MOVEI A,DSLST1+1(B)		;START 340 HACKING LIST JUST FINISHED
	MOVEM A,DISLST			;change list
	SETCAB B,MDBFSW			;SWITCH TO OTHER MDBUF BUFFER
	MOVE Q,MDBTAB+1(B)		;GET PDL PTR FOR IT
	MOVEM Q,MDBCUR			;SAVE AS CURRENT

ML0B:	PUSH Q,MDBFBR			;put brightness command into list
IFN $MOVIE [
	DATAI A				;read the switches
	TRNN A,1			;skip if stopping action
	 JRST NOSTOP
STOP1:	DATAI A
	TRNE A,2
	 JRST [	SKIPE STOPSW'
		 JRST STOP1
		SETOM STOPSW
		JRST NOSTOP]
	SETZM STOPSW
	JRST STOP1
NOSTOP:]

	;now before entering synch wait, check to see if game-end
	;flag should be set.  conditions are: 
	;1) all ships gone,
	;2) all torps gone (in torp game) and all torps/expls done
	;3) all fuel gone (in phaser game)
	;  -- algorithm waits for sole survivor (if any) to come out of
	;hyper or finish exploding before setting flag.
	SKIPE GEFLG			;if already set flag,
	 JRST MLSYNC			;obviously don't need to set again!
	MOVE D,NEGSHP
	SETZ B,
	MOVEI C,SSS
ML0E:	SKIPN A,OBJFLG(D)
	 JRST ML0F
	CAIE C,(A)			;SHIP IN SSS ROUTINE?
	 JRST MLSYNC			;NO, NEVER END UNLESS SO.
	SKIPE ZAPPER			;PHASER GAME?
	 JRST [	SKIPG MFU(D)		;SHIP HAS FUEL?
		 SETO B,		;YES, PROVISIONALLY CLEAR
		JRST ML0F]		;NO, CONTINUE SEARCH
	SKIPLE MTR(D)			;TORP GAME. SHIP HAS TORPS?
	 SETO B,			;YEP, PROVISIONALLY CLEAR
ML0F:	AOBJN D,ML0E
	JUMPE B,[ SETOM GEFLG		;IF SEARCH FAILED, END GAME.
		SKIPE ZAPPER
		 JRST .+1
		MOVE A,TLF		;if torp game, extend GECNT so that
		CAILE A,30.*10.		;remaining torps have chance to clobber ships.
		 MOVEI A,30.*10. 	;but only for 10 seconds or so.
		ADDM A,GECNT
		JRST MLSYNC]
	SKIPG SSING			;OR IF 1 (SSING=0) SHIP LEFT.
	 JRST [	MOVEI A,1		;IF ONLY ONE
		CAME A,NSHIPS		;STARTED GAME, THEN OK.
		 SETOM GEFLG		;ELSE END GAME.
		JRST .+1]

MLSYNC:	AOSE CLKSNK			;wait for clock sync (STEPTM/60 sec)
IFE $ITS, JRST .-1
IFN $ITS,[
	.HANG
	MOVE A,[-2,,[.SPIRQC,,[0] ? .SIMASK,,[%PIRLT]]]
	.SUSET A
]


	SKIPE GEFLG			;GAME-END FLAG SET?
	 JRST [	SOSG GECNT		;AND EGT COUNTED OUT?
		 JRST GAMEND		;YES, END OF THIS GAME.
		JRST .+1]		;NOT YET, CONTINUE UPDATING STUFF.
	PUSHJ P,RANDOM
	ANDI A,7
	MOVN A,A
	ADDM A,RINDEX			;change RINDEX randomly to avoid stepping
					;thru table the same # of times every pass.

;update each object in game (look for collisions first)
	SETZ MP1,
ML1:	SKIPN OBJFLG(MP1)
	 JRST MQ1			;object is not active
	SKIPG C,OBJFLG(MP1)
	 JRST MQ4			;object is not collideable
	MOVEI MP2,1(MP1)		;start with objects after this one
ML2:	SKIPG D,OBJFLG(MP2)
	 JRST MQ2B			;obj cannot collide
	MOVE A,OBJX(MP1)			;compute distance between them
	FSBR A,OBJX(MP2)
	MOVM A,A
	CAMLE A,ME1
	 JRST MQ2B
	MOVE B,OBJY(MP1)
	FSBR B,OBJY(MP2)
	MOVM B,B
	CAMLE B,ME1
	 JRST MQ2B
	FMPR A,A			;x difference**2
	FMPR B,B			;y difference**2
	FADR A,B			;difference**2
	CAMLE A,ME12			;are they close enough
	 JRST MQ2B			; no -continue looking

	; Collision! - find types

	PUSH P,C
	PUSH P,MP1
	PUSH P,MP2
	HLRZS C
	ANDI C,17
	HLRZS D
	ANDI D,17
	CAILE C,(D)
	 JRST [	EXCH MP1,MP2
		EXCH C,D
		JRST .+1]
	PUSHJ P,@COLTBL(C)		;VECTOR TO APPROPRIATE RTN
	POP P,MP2
	POP P,MP1
	POP P,C

MQ2B:	CAIGE MP2,OBJCTS-1			;check for more collisions here
	 AOJA MP2,ML2			;go do more collisions for this object

	;now create display list for object
MQ4:	SKIPE A,OBJFLG(MP1)		;in case object was removed in coll.
	 PUSHJ P,(A)			;make the list and other random functions
MQ1:	CAIGE MP1,OBJCTS-2			;next to last object
	 AOJA MP1,ML1			; no - continue
	AOS MP1				;yes - make mp1 point to last object
	SKIPE A,OBJFLG+OBJCTS-1		;is it active (do not look for collisions)
	 PUSHJ P,(A)			; yes - make its display list

	SKIPE ZAPPER
	 PUSHJ P,RAYGUN			;perform phaser manipulations here

	;move backround star field
	MOVE T,BKGTSP
	FADRB T,BKTMF			;increment position of background
	SFIX T,-19.
	MOVEM TT,BKTIME
	PUSHJ P,BKMOVE			;UPDATE DISPLAY COMMANDS
	JRST ML0			;start main loop again

	SUBTTL	Collision Processing

	;collision routine table, indexed by smaller of 2 types involved.
	;OBJFLG indices must be in MP1 (smaller) and MP2,
	; with object types in C and D respectively.
COLTBL:	COLSUN				; 0 - SUN
	COLSS				; 1 - SS
	COLSS				; 2 - HYPERSPACE SS
	COLT				; 3 - TORP
	COLFB				; 4 - FIREBALL

	;explosion routine table, to explode given object.
	;routines assume OBJFLG index in MP1!!
EXPTBL:	APOPJ				; 0 - SUN
	SEXP				; 1 - SS
	SEXP				; 2 - SS
	TEXP				; 3 - TORP
	APOPJ				; 4 - FIREBALL

	;clearing table, to simply flush object from game.
	;routines assume OBJFLG index in MP2!!
CLRTBL:	APOPJ				; SUN
	SCLR				; SS
	SCLR				; SS
	TCLR				; TORP
	APOPJ
	APOPJ
	APOPJ

TCLR:	MOVE T,[PT%NOP,,PT%NOP]		;clear torp's display slot
	MOVEM T,TORDSB-TORIDX(MP2)
RANCLR:	SETZM OBJFLG(MP2)			;clear random obj's routine slot.
APOPJ:	POPJ P,

SCLR:	; Clear a star ship
	HLLZM SDPTRS(MP2)		; zero list length: do not display
	SETZM OBJFLG(MP2)			; clear routine slot
	SOS SSING			; remove 1 more SS from game.
	POPJ P,


	;random object hit sun.
COLSUN:	SETZM OBJXVL(MP2)			;zero velocities so result stays put
	SETZM OBJYVL(MP2)
	SETOM MNOGRV(MP2)		;indicate gravity doesn't affect it any more.
	MOVSI A,(SETZ)
	IORM A,OBJFLG(MP2)			;make it non-collidable in future
	MOVE MP1,MP2			;special case: want to explode obj in MP2.
	SKIPE KILLER			;are suns deadly? (ha ha)
	 PJRST @EXPTBL(D)		;go blow him up
	CAIE D,%TSS			;hyper sun, but only warps if obj is SS.
	 PJRST @EXPTBL(D)
	SETZM OBJX(MP2)			;sigh, suspend belief and put him in corners.
	SETZM OBJY(MP2)
	ANDCAM A,OBJFLG(MP2)		;restore collidability
	SETZM MNOGRV(MP2)		;gravity affects.
	POPJ P,

	; SS vs. something (not sun)
COLSS:
	CAIN D,%TFB			; vs. fireball?
	 JRST [	SKIPN FIRBAL		; if so,
		 JRST APOPJ		;ignore unless FIRBAL says they're dangerous
		JRST .+1]		;in which case die!
	CAIE D,%TTORP
	 JRST COLSS2
	LDB A,[260500,,OBJFLG(MP2)]	;get creator of torp
	JUMPE A,COLSS2			;skip if no originator, OBJCTSody gets credit.
	CAIN A,1(MP1)			;originator index same as victim
	 SOSA SCORE(MP1)		;yes, take one off score of this clod!
	AOS SCORE-1(A)			;no, increment score of creator.
COLSS2:	PUSHJ P,MMNTUM			;calc new vel of expl,
	PUSHJ P,SEXP			;and explode SS, while
	PJRST @CLRTBL(D)		;clearing slot of other object.

	; Torp vs. torp or lesser entity
COLT:	CAIN D,%TFB			;if vs. fireball,
	 PJRST TEXP			;blow up regardless of FIRBAL setting.
	PUSHJ P,MMNTUM			;calc vel of expl
	PUSHJ P,TEXP			;blow up torp,
	PJRST @CLRTBL(D)		;and clear other object.

	; Fireball vs. fireball or lesser (if anything).
COLFB:	POPJ P,				;do nothing.


	;fireballs, worry about conservation of momentum
MMNTUM:	MOVE C,OBJMAS(MP1)			;compute combined mass
	FADR C,OBJMAS(MP2)
	;formula is vx=(m1*vx1+m2*vx2)/(m1+m2)
	IRP XORY,,[X,Y]
	MOVE A,OBJ!XORY!VL(MP1)
	FMPR A,OBJMAS(MP1)
	MOVE B,OBJ!XORY!VL(MP2)
	FMPR B,OBJMAS(MP2)
	FADR A,B
	FDVR A,C
	MOVEM A,OBJ!XORY!VL(MP1)
	TERMIN
	MOVEM C,OBJMAS(MP1)		;update the mass
	POPJ P,

	SUBTTL	End Of Game Processing

GAMEND:	SKIPN SERCNT			;keeping score?
	 JRST SERIES			; no - start over now
IFN $MOVIE [
	SKIPGE MOVIE
	 JRST GAME			;no score update or display if playbacking
]
	MOVE A,NEGSHP
	SETOM B

	;compute the current scores
MDN11:	HRRZ C,OBJFLG(A)
	CAIN C,SSS
	 HRRZ B,A
	AOBJN A,MDN11			;FIND SINGLE LIVE SHIP IF ANY
	SKIPL B
	 AOS SCORE(B)			;ONE POINT FOR BEING SOLE SURVIVOR.

	SOSLE SERCNT			;should score be displayed yet?
	 JRST GAME			; no - just start new game

	SETZM MDN3X'
	MOVE MP1,NEGSHP

	;create the display list of the ships
	MOVE A,PI.5
	PUSHJ P,TRIGVS			;set up trig. values for angle pi/2 (vertical)
	MOVEI A,4			; and make them four times normal size
	IRP V,,[XSIN,SXSIN,XCOS,SXCOS,XSIN45,SXSIN45,XCOS45,SXCOS45]
	IMULM A,V
	TERMIN

MDN4:	MOVE C,[<1024./<$MXSHP+1>>]
	FSC C,233			;FLOAT IT (caution- 6 doesn't normalize!)
	FADRB C,MDN3X			;position to  display next ship - x
	MOVE B,[600.0]			; y coordinate
	PUSHJ P,SSDIS			;make the display list
	AOBJN MP1,MDN4
	SKIPE NOSCR'
	 JRST [	MOVEI A,PM%HLT
		MOVEM A,TORDIS
		JRST MDN8]		;skip score

	;create the display list of the scores
	MOVEI B,0			;x for score of first ship
	MOVE MP1,NEGSHP
	MOVEI D,TORDIS			;area where numbers are put
	LDB C,[.BP 7,SSBRI]		;make scores as bright as ships
	IORI C,PM%ESC\<2_PM%SCS>\PM%EBR\NC%PNT	; ... with a scale of two
	MOVEM C,TORDIS			;put into display area
MDN5:	MOVE C,[PT%Y\<350.>\NC%PNT,,NC%CHR]	;point mode to charac, y=350.
	ADD B,[<1024./<$MXSHP+1>>]
	DPB B,[(001200)C]		;set x position
	PUSH D,C			;put into list
	HRLI D,600			;make d a byte pointer
	MOVE T,SCORE(MP1)		;GET SCORE TO DISPLAY
	PUSHJ P,MDNN			;put the number into the list
	MOVEI TT,37
	IDPB TT,D			;character to stop character mode
	SETZB TT,1(D)     		;make 1(d) zero, get zero byte
	MOVSI T,-4
	IDPB TT,D			;four zero bytes insure that
	AOBJN T,.-1			; next command starts in a new word
	AOBJP MP1,MDN6
	MOVEI TT,NC%PNT			;switch to point mode
	MOVEM TT,1(D)
	AOJA D,MDN5
MDN6:	MOVSI TT,PM%HLT			;put done command into list
	MOVEM TT,1(D)

	;wait for a signal to continue
	MOVE D,SCRTIM			;amount of time score displayed
MDN8:	MOVEI A,DSLST3
	MOVEM A,DISLST
	DSTART
MDN81:	SETOB MP2,Q
	MOVE MP1,NEGSHP
MDN7:
IFE $MOVIE,	PUSHJ P,GSS		;get input value for this ship
IFN $MOVIE [
	PUSH P,MOVIE'			;save in case recording
	SETZM MOVIE			;zero so nothing happens
	PUSHJ P,GSS			;GET INPUT VALUE FOR THIS SHIP
	POP P,MOVIE
]
	SKIPN B				;skip if thrust on
	 MOVEI MP2,0			;do not reset score
	TLNN C,200000			;skip if hyper on
	 MOVEI Q,0			;do not retain score
	AOBJN MP1,MDN7
	JUMPN Q,MDN12			;if q non-zero, agreed to retain
	JUMPN MP2,MDN12			;if mp2 zero, agree to reset
	AOSE CLKSNK			;has a 3oth of a second past?
IFE $ITS,  JRST MDN81			;no, continue polling buttons
IFN $ITS, .HANG
IFN $ITS,[
	MOVE A,[-2,,[.SPIRQC,,[0] ? .SIMASK,,[%PIRLT]]]
	.SUSET A
]
	SOJG D,MDN81			;yes, have we counted down score display
MDN12:	MOVEI B,30.			;fadeout delay in 30ths

	;wait and then restart
MDN9:	AOSE CLKSNK			;wait for clock sync
IFE $ITS,  JRST .-1
IFN $ITS, .HANG
IFN $ITS,[
	MOVE A,[-2,,[.SPIRQC,,[0] ? .SIMASK,,[%PIRLT]]]
	.SUSET A
]
	SOJG B,MDN9			;and wait for specified delay
	JUMPN MP2,[SETZM SAVSCR		;MP2 non-zero means all thrusted
		   JRST SERIES]		;which means reset scores

	MOVE A,SERL			;otherwise, start new series and retain scores.
	MOVEM A,SERCNT
	JRST GAME			;go start first game of another series

	;create a number to display
MDNN:	JUMPL T,[MOVEI TT,55		;IF NEG, ADD - IN FRONT OF ABS VAL.
		IDPB TT,D
		MOVM T,T
		JRST .+1]
MDNN1:	IDIVI T,10.
	PUSH P,TT			;save last digit
	SKIPE T				;if zero quotient, done
	 PUSHJ P,MDNN1			; else get next digits...
	POP P,TT
	ADDI TT,60			;convert digit to sixbit
	IDPB TT,D			;and into buffer
	POPJ P,



	SUBTTL	Star-Ship Update Routine

	;Update position, create new display, perform other functions

SSS:	PUSHJ P,GSS			;get function indicators
	SOS MHYP(MP1)			;decrement time till next hyperspace
	SKIPE ZAPPER
	 JRST LTEST			;different tests for phasers
	TLNE C,200000			;not phaser game - hyper on
	 JRST HYPGO			; yes - enter hyperspace if ok

	;processing if not going into hyperspace
SSNHYP:	MOVEM B,SACL'			;save acceleration
	MOVEM C,SFLGS'			;save fire, hyper flags
	SKIPE SPIN			;conservation of angular momentum on?
	 JRST [	FDVR A,[10.0]		;yes - first scale MAA down
		FADRB A,OBJAVL(MP1)	;then add to rotational speed
		CAML A,MAALIM		;if speed too high,
		 JRST SEXP		;ship flies apart.
		JRST .+1]
	FADR A,MTH(MP1)			;compute new angle
	CAML A,PI2			;normalize to some extent
	 FSBR A,PI2
	CAIGE A,0
	 FADR A,PI2
	MOVEM A,MTH(MP1)		;store new angle
	PUSHJ P,TRIGVS			;set trigonometric values for it (sin, cos, etc)
	PUSHJ P,SUNGRV			;get effects of gravity
	SKIPE T,SACL			;want to thrust
	 SKIPLE MFU(MP1)		; yes - fuel left
	  JRST SSNACL			; no - do not thrust

	;compute x and y components of thrust vector
	FADRM T,MFU(MP1)		;update fuel left
	MOVE T,SACL			;get total acceleartion
	FMPR T,FSIN
	FADR B,T			;y increment (thrust and gravity)
	MOVE T,SACL
	FMPR T,FCOS
	FADR C,T			;x component

	;remainder of processing for new postion
SSNACL:	FADRB C,OBJXVL(MP1)		;update velocities from gravity and thrust
	FADRB B,OBJYVL(MP1)
	LIMIT Y,B			;compute new y and x position
	LIMIT X,C
	SKIPE T,SACL			;thrusting
	 SKIPLE MFU(MP1)		; yes - fuel left
	  JRST FELL			;  no - can't thrust

	;create the thrust vector (rocket exhaust)
	PUSH P,C
	PUSH P,B
;	PUSHJ P,RANDOM
	GETRAN A
	SSFIX T,-17.
	ANDI A,17
	ADD A,TT			;compute a random length
	MOVN B,SHPSL(MP1)		;compute x and y coordinates
	MOVE C,B			; of center of tail
	FMPR B,FCOS
	FMPR C,FSIN
	FADR B,OBJX(MP1)
	FADR C,OBJY(MP1)
	SSFIX C,-1			;convert to fixed values
	SSFIX B,-1			; y in d, x in c
DRWEXH:	DISPT				;display a point
	SUB D,XSIN			;get address of next point in vector
	SUB C,XCOS
	SOJG A,DRWEXH			;continue
	POP P,B
	POP P,C
FELL:	PUSHJ P,SSDIS			;make the display list
	SKIPE ZAPPER
	 JRST FFIELD			;for phasers, display force field if any
	SOSG MA1(MP1)			;can ss fire yet
	 SKIPL SFLGS			; and should it fire
	  JRST SNOTRP			; no to either of above - return
	SOSGE MTR(MP1)			;any torps left
	 JRST SNOTRP			; no - ignore request

	;fire a torpedo
	MOVE C,TVL
	MOVE B,C
	FMPR C,FCOS			;c = x component of initial velocity
	FADR C,OBJXVL(MP1)
	FMPR B,FSIN
	FADR B,OBJYVL(MP1)			;b = y component
	MOVE D,[-<OBJCTS-TORIDX>,,TORIDX]
	SKIPE OBJFLG(D)			;skip if this slot available
	 AOBJN D,.-1
	CAIL D,0			;if d >= 0 then too many objects
	 JSR FATAL
	MOVEI T,TORPCL			;torp calc routine
	MOVEI A,1(MP1)			;get index+1 of ss
	DPB A,[260500,,T]		;deposit in creator-field
	TLO T,%TTORP			;set type = torp
	MOVEM T,OBJFLG(D)			;set to torpedo calculation routine
	SETZM MNOGRV(D)			;gravity affects
	MOVE T,SHPSL1(MP1)		;compute initial x position
	FMPR T,FCOS
	FADR T,OBJX(MP1)
	MOVEM T,OBJX(D)			;and save it
	MOVE T,SHPSL1(MP1)		;compute initial y
	FMPR T,FSIN
	FADR T,OBJY(MP1)
	MOVEM T,OBJY(D)			;and save it
	MOVEM B,OBJYVL(D)			;set x, y components of velocity
	MOVEM C,OBJXVL(D)
	MOVE T,TLF			;set life of torpedo
	MOVEM T,MA1(D)
	MOVE T,TRPMAS			;set mass of torpedo
	MOVEM T,OBJMAS(D)
	MOVE T,RLT
	MOVEM T,MA1(MP1)		;set reload time till next fire
	MOVE T,TXTM
	MOVEM T,MB1(D)			;set length of explosion for torpedo
SNOTRP:	POPJ P,				;return

	SUBTTL	Beam Location and Star-Ship Explode

	;compute starting position for phaser beam
BEAM:	SKIPN RAY(MP1)
	 POPJ P,			;return if not firing phaser
	MOVE B,XSIN			;beam is drawn every 3rd point
	IMULI B,3
	MOVEM B,BXSIN(MP1)		;adjust y increment
	MOVE B,XCOS
	IMULI B,3
	MOVEM B,BXCOS(MP1)		;adjust x increment
	MOVE B,SHPSL1(MP1)		;compute x and y coordinates
	MOVE C,B			; of start of phaser
	FMPR B,FCOS
	FADR B,OBJX(MP1)			;put x in b
	FMPR C,FSIN
	FADR C,OBJY(MP1)			;put y in c
	SSFIX C,-1			;convert to fixed values
	SSFIX B,-1
	MOVEM D,DSAVE(MP1)		;y coord of start of beam
	MOVEM C,CSAVE(MP1)		;x coordinate of start of beam
	POPJ P,0			;return from sss


	;blow up a star ship
SEXP:	MOVE T,[SETZ FLARE]
	SKIPE FIRBAL
	 TLZ T,400000			;can't collide - not fireballs
	TLO T,%TFB
	MOVEM T,OBJFLG(MP1)		;save address of computation routine
	MOVE A,FLRSCL			;get length of flare from exscl
	ANDI A,3
	MOVE A,FLAREL(A)
	MOVEM A,FLARET(MP1)
	SETZM FLAREC(MP1)		;no flare yet
	MOVE T,MB1(MP1)
	MOVEM T,MA1(MP1)		;set length of explosion
	HLLZM SDPTRS(MP1)		;zero list - remove from display
	SOS SSING			;decrement # ships in game.
	POPJ P,0			;return from sss or caller

	SUBTTL	Gravity Computation Procedure

SUNGRV:	SETZB XFLAG,R			;one stores X vel, other Y.
	SETZB B,C
	SKIPN MNOGRV(MP1)
	 SKIPN S,NEGSUN
	  POPJ P,			;if no sun or no gravity, returns zero accel
SUNGR1:	PUSHJ P,CGRAV
	FADRB C,XFLAG			;cumulative X
	FADRB B,R			;cumulative Y
	AOBJN S,SUNGR1
	POPJ P,

CGRAV:	MOVE T,OBJX(MP1)			;compute distance to sun
	FSBR T,FSUNLX(S)
	MOVEM T,T1'
	FMPR T,T			;delta x**2
	MOVE TT,OBJY(MP1)
	FSBR TT,FSUNLY(S)
	MOVEM TT,T2'
	FMPR TT,TT			;delta y**2
	FADR T,TT			;et delta r**2
	MOVE A,T
	PUSHJ P,SQRT			;get r to sun into a
	FMPR T,A			;compute r**3
	FDVR T,GRV			;divide by gravitational constant
	MOVN B,T2
	FDVR B,T			;put y component of accel. into b
	MOVN C,T1
	FDVR C,T			;put x component into c
	POPJ P,

	SUBTTL	Display a Ship

;PUSHJ P,SSDIS
;   Function:
;	Generates the display list for a ship.
;   Inputs:
;	MP1:	The index of the ship whose display list is created.
;   Registers Used:
;	B, C, D, T, TT

SSDIS:	MOVE T,SHPSL(MP1)		;compute x, y of front of ship
	FMPR T,FCOS
	FADR C,T
	MOVE T,SHPSL(MP1)
	FMPR T,FSIN
	FADR B,T
	SSFIX C,-1			;put fixed x into d
	SSFIX B,-1			;put fixed y into c
	MOVE A,[PT%Y\NC%PNT,,PT%X\PT%DSP\NC%PNT]
	TLZ C,776000			;remove high order bits from data
	TLZ D,776000
	MOVEM C,SYCOR			;save coordinates of center
	MOVEM D,SXCOR
	MOVE T,SHPLN2(MP1)		;save for use by generating routine
	MOVEM T,CSPLN2
	SETZM RLHSW			;start on right half
	MOVE T,SDADRS(MP1)		;get address of first word
	MOVEI T,1(T)			; by bypassing parameter command
	PUSHJ P,@SHPADR(MP1)		;create list
	MOVE T,SHPDPT(MP1)		;make ship visible again
	MOVEM T,SDPTRS(MP1)
	POPJ P,


;PUSHJ P,TRIGVS
;   Function:
;	Given an angle, computes various trigonometric values which are used to
;	generate the display list of a ship oriented at that angle.
;   Inputs:
;	A:	Angle in radians for which the trig values are computed.
;   Uses Registers:
;	A, B

TRIGVS:	MOVEM A,ORNTSV'
	PUSHJ P,SIN
	FMPR A,SHPSIZ
	MOVEM A,FSIN'
	MOVEM A,MPFSIN(MP1)		;save sine of angle of orientation (a)
	SSFIX A,-1			;convert to fixed
	MOVEM B,XSIN			; for display routine
	MOVEM B,SXSIN
	MOVE A,ORNTSV
	PUSHJ P,COS
	FMPR A,SHPSIZ
	MOVEM A,FCOS'
	MOVEM A,MPFCOS(MP1)		;save cos(a)
	SSFIX A,-1			;save fixed value for
	MOVEM B,XCOS			; display routine
	MOVEM B,SXCOS
	MOVE A,FSIN
	FADR A,FCOS
	FMPR A,[.7071068]		;sin (ang+45)= (1/(sqrt 2)) (sin+cos)
	MOVEM A,FSIN45'
	SSFIX A,-1			;save fixed(sin(a+pie/4))
	MOVEM B,XSIN45
	MOVEM B,SXSIN45
	MOVE A,FCOS
	FSBR A,FSIN
	FMPR A,[.7071068]		;cos (ang+45) = (1/(sqrt 2))(cos-sin)
	MOVEM A,FCOS45'
	SSFIX A,-1
	MOVEM B,XCOS45			;save fixed(cos(a+pie/4))
	MOVEM B,SXCOS45
	POPJ P,

RLHSW:		0			;specifies which half being generated
CSPLN2:		0			;length of first half current ship list
SXCOR:		0			;starting X coordinate of ship
SYCOR:		0
XCOS:		0			;used to rotate display list
XSIN:		0
SXCOS:		0
SXSIN:		0
XCOS45:		0
XSIN45:		0
SXCOS45:	0
SXSIN45:	0

	SUBTTL	Enter Hyper-Space and Update Routines for Hyper-Space

	;routine to enter hyperspace
HYPGO:	SKIPLE MHYP(MP1)		;ok to enter now
	 JRST SSNHYP			; no - continue as usual
	HLLZM SDPTRS(MP1)		;make list zero length: stop display
	MOVE A,[SETZ HYPI]		;initially invisible in hyperspace
	MOVEM A,OBJFLG(MP1)		; and not collidable
	MOVE A,HYPT1
	MOVEM A,MHYP(MP1)		;time invisible in hyperspace
	POPJ P,0			;return from sss

	;display routine for a ship invisible in hyperspace
HYPI:	SOSLE MHYP(MP1)			;time to become visible?
	POPJ P,				; no - that's all

	;time to reappear. compute a random x, y for object
	IRP XORY,,[X,Y]
;	PUSHJ P,RANDOM
	GETRAN A
	ANDI A,1777
	TLC A,232000
	FAD A,A
	MOVEM A,OBJ!XORY(MP1)
	TERMIN
	MOVEI A,HYPO			;use visible-in-hyperspace routine
	TLO A,%THSS			;indicate is HSS.
	MOVEM A,OBJFLG(MP1)
	MOVE A,HYPT2
	MOVEM A,MHYP(MP1)		;set time as hyperspace star
	POPJ P,

	;display routine for a ship visible as a hyperspace star
HYPO:	SOSG MHYP(MP1)			;still a star?
	 JRST HYPO1			; no - break out
	MOVE C,OBJY(MP1)			;make a star and display it at
	SFIX C,-1.			;fix y
	MOVE B,OBJX(MP1)
	SFIX B,-1.			;fix x
	ADD C,[(1)]
	DISPT				;make point at x,y+1
	SUB D,[(2)]
	SUB C,[(1)]
	DISPT				;make point at x-1,y-1
	ADD C,[(2)]
	DISPT				;make point at x+1,y-1
	POPJ P,

	;break out of hyperspace
HYPO1:	MOVN B,HYPBO			;decrement chance of coming out
	ADDB B,MHYPP(MP1)
;	PUSHJ P,RANDOM
	GETRAN A
	ANDI A,77
	CAMG B,A			;random chance, p=7/8, 6/8, 5/8, ...
	 JRST SEXP			;lose - explode
	MOVE A,[%TSS,,SSS]		;restore to usual starship update routine
	MOVEM A,OBJFLG(MP1)
	MOVE A,HYPT3			;set time till hyper legal again
	MOVEM A,MHYP(MP1)
	PUSHJ P,RANONE			;compute random orientation
	FMPR A,PI2
	MOVEM A,MTH(MP1)

	;compute random velocity
	IRP XORY,,[X,Y]
	PUSHJ P,RANONE
	FMPR A,SAC
	FMPR A,[90.0]			;exit at speed up to 3 sec's acceleration
	MOVEM A,OBJ!XORY!VL(MP1)
	TERMIN
	SETZM OBJAVL(MP1)			;stop any spinning
	JRST SSS


	SUBTTL	Torpedo Update Routines

;initial torp routine. this no-op is necessary because torps
;are created by ship update routines before any torps have been
;updated, so when the computer gets farther down the
;OBJFLG list to the torps, any created torps are 'updated' again!
;this leads to strange things like blowing yourself up if you
;fire backwards while moving faster than tvl. 

TORPCL:	MOVEI B,TRPCAL			;actual torp update routine
	HRRM B,OBJFLG(MP1)			;put in OBJFLG slot
	POPJ P,				;'no-op' done!

	;display routine for a torpedo
TRPCAL:	SOSGE MA1(MP1)			;torp life over
	 JRST TEXP			; yes - blow it up
	PUSHJ P,SUNGRV			;compute effects of gravity
	FADRB B,OBJYVL(MP1)		;update velocity components
	FADRB C,OBJXVL(MP1)
	SKIPE GMSLSW			;if torp is homer
	 JRST [	PUSHJ P,GMSTRN		;go adjust xy vels.
		MOVE B,OBJYVL(MP1)
		MOVE C,OBJXVL(MP1)
		JRST .+1]
	LIMIT Y,B			;update coordinates
	LIMIT X,C
	SFIX C,-1			;fix coordinates
	SFIX B,-1
	TLO C,PT%Y\NC%PNT		;y coord
	TLO D,PT%X\PT%DSP\NC%PNT	;x coord
	HLR C,D
	MOVEM C,TORDSB-TORIDX(MP1)	;put coordinates of point into disp list
	POPJ P,

	;blow up a torpedo
TEXP:
	MOVE T,[SETZ MEX]
	SKIPE FIRBAL
	 TLZ T,400000			;fireballs, CAN collide!
	TLO T,%TFB			;say are expl. now
	MOVEM T,OBJFLG(MP1)		;save address of explode routine
	MOVE T,[PT%NOP,,PT%NOP]		;clear out display of the torp
	MOVEM T,TORDSB-TORIDX(MP1)
	MOVE T,TXTM
	MOVEM T,MA1(MP1)		;save length of explosion
CPOPJ:	POPJ P,

	SUBTTL	Homeing Torpedo Guidance Control

GMSLSW:	0				;-1 -> XY guidance; 1 -> trigonemetric guidance
GMTINC:	.5				;amount XY coords can be adjusted each step
GMTAA:	0.05				;angular turn a step for trigonemetric guidance
GMSRNG:	40000.0				;range**2 within which torp locks on target.

GMSTRN:	LDB MP2,[330300,,OBJFLG(MP1)]	;get index of target if any
	JUMPG MP2,GMSTR3		;jump if one exists
	LDB C,[260500,,OBJFLG(MP1)]	;no, must look. get creator index
	SUBI C,1
	MOVE MP2,NEGSHP
GMSTR1:	CAIN C,(MP2)			;DON'T HOME ON CREATOR!
	 JRST GMSTR2
	SKIPG A,OBJFLG(MP2)		;find live (collidable) SS
	 JRST GMSTR2
	HRRZ A,A
	CAIE A,SSS
	 CAIN A,HYPO
	  CAIA
	   JRST GMSTR2
	MOVE A,OBJX(MP1)			;COMPUTE DISTANCE TO IT
	FSBR A,OBJX(MP2)
	FMPR A,A
	MOVE B,OBJY(MP1)
	FSBR B,OBJY(MP2)
	FMPR B,B
	FADR A,B
	CAMG A,GMSRNG			;WITHIN RANGE RADIUS?
	 JRST GMSTR4			;YES, LOCK ON TARGET!
GMSTR2:	AOBJN MP2,GMSTR1
	POPJ P,				;no target found, don't alter velocities.
GMSTR4:	MOVEI A,1(MP2)
	DPB A,[330300,,OBJFLG(MP1)]	;SET TARGET.
	JRST GMSTR5

GMSTR7:	SETZ A,
	DPB A,[330300,,OBJFLG(MP1)]
	POPJ P,
GMSTR3:	MOVEI MP2,-1(MP2)		;adjust index (since is stored as 1 greater)
	SKIPG R,OBJFLG(MP2)		;target now collidable?
	 JRST GMSTR7			;no, on next pass will hunt for another.
	HRRZ R,R
	CAIE R,SSS
	 CAIN R,HYPO
	  CAIA
	   JRST GMSTR7
GMSTR5:	MOVE A,OBJX(MP1)
	MOVE B,OBJX(MP2)
	RELATV A,B
	MOVE T,B
	MOVE A,OBJY(MP1)
	MOVE B,OBJY(MP2)
	RELATV A,B
	MOVE TT,B
	MOVE C,OBJXVL(MP1)
	MOVE D,OBJYVL(MP1)
	CAIN R,HYPO			;is SS a hyperspace star?
	 JRST GMSTR6			;yes, ignore SS 'vel'
	FSBR C,OBJXVL(MP2)
	FSBR D,OBJYVL(MP2)
GMSTR6:	PFDVR D,C			;get slope of TV vec (Torp Vel)
	PFDVR TT,T			;of TS vec (Torp-to-SS)
	SETZ B,				;clear flags
	CAML D,TT
	 TRO B,1			;set flag if TV slope > TS slope
	XOR T,C				;XOR X COORDS
	CAIGE T,0
	 TRO B,2			;SET FLAG IF SIGNS DIFFERENT
	JRST @(B)[
		GMSCCW			;IF SAME X SIGN AND VSL<SSL
		GMSCW			;IF SAME X SIGN AND VSL>SSL
		GMSCW			;IF DIFF X SIGN AND VSL<SSL
		GMSCCW]			;IF DIFF X SIGN AND VSL>SSL

	;TURN TV VECTOR CLOCKWISE 
GMSCW:	TDCA B,B			;HACKY WAY TO CLEAR AND SKIP
	;TURN COUNTER-CLOCKWISE
GMSCCW:	MOVEI B,1
	SKIPL GMSLSW			;if -1 turn cheaply
	 JRST GMSC50			;else if 1 go use trig to turn.
	MOVE T,OBJXVL(MP1)
	MOVE TT,OBJYVL(MP1)
	CAIGE D,0			;SKIP IF VSL POS
	 TRO B,2			;SET FLAG IF NEG
	CAILE B,0
	 CAIL B,3
	  TRO B,20			;SET IF +VSL/CW OR -VSL/CCW (MEANS SWAP X,Y)
	TRNE B,20
	 EXCH T,TT

	CAIGE T,0
	 TRO B,10
	CAIGE TT,0
	 TRO B,4			;SET FLAGS TO SIGNS
	MOVM T,T
	MOVM TT,TT
	MOVE C,T
	FSBR C,GMTINC
	JUMPL C,GMSC30			;IF |A|-e < 0 THEN HANDLE DIFFERENTLY
	MOVE T,C
	FADR TT,GMTINC
GMSC20:	TRNE B,10			;WAS ORIGINAL SIGN NEG?
	 MOVN T,T			;MAKE NEG IF SO
	TRNE B,4
	 MOVN TT,TT			;DITTO
	TRNE B,20
	 EXCH T,TT
	MOVEM T,OBJXVL(MP1)
	MOVEM TT,OBJYVL(MP1)
	POPJ P,

GMSC30:	MOVE A,GMTINC
	FADR C,TT
	JUMPL C,[MOVE A,T
		FADR A,TT
		JRST .+1]
	FADR TT,T
	FSBR TT,A
	FSBR T,A
	MOVM T,T
	MOVM TT,TT
	TRC B,10
	JRST GMSC20

GMSC50:	MOVE A,OBJYVL(MP1)
	PFDVR A,OBJXVL(MP1) 		;get slope of current torp velocity vector
	PUSHJ P,ATAN			;FIND ANGLE OF SLOPE RELATIVE TO 0
	SKIPGE OBJXVL(MP1)
	 FADR A,PIE			;ADD PI IF POINT ON OTHER SIDE OF X AXIS
	MOVE C,GMTAA			;get turn speed
	TRNN B,1
	 MOVN C,C			;NEGATE CORRECTION IF TURNING CLOCKWISE
	FADRB A,C
	PUSHJ P,SIN
	EXCH A,C			;PUT SIN IN C, SAME ANGLE AS ARG TO COS.
	PUSHJ P,COS
	MOVE D,A			;COS IN D
	MOVE A,OBJXVL(MP1)			;FIND MAGNITUDE OF VELOCITY.
	FMPR A,A
	MOVE B,OBJYVL(MP1)
	FMPR B,B
	FADR A,B
	PUSH P,C
	PUSHJ P,SQRT			;GET VELOCITY IN A
	POP P,C
	FMPR C,A			;GET Y COMPONENT
	FMPR D,A			;GET X COMPONENT
	MOVEM C,OBJYVL(MP1)
	MOVEM D,OBJXVL(MP1)
	POPJ P,

	SUBTTL	Flare Creation Routines

;routine to create a flare after a star ship blows up and before 
; the fireball is displayed.

FLARE:	AOS FLAREC(MP1)			;see if flare is complete
	AOS A,FLAREC(MP1)
	CAMLE A,FLARET(MP1)
	 JRST FLARE2			; flare is finished
	MOVEM A,MSKIND'			; no - save index into flare mask array
FLAREA:	PUSHJ P,SUNGRV			;compute effects of gravity
	FADRB B,OBJYVL(MP1)
	FADRB C,OBJXVL(MP1)		;compute velocity 
	LIMIT Y,B			;fix and update coordinates of expl
	LIMIT X,C
	SFIX C,-1			;convert to fixed
	SFIX B,-1
	MOVE A,MSKIND
	MOVE A,FLSMSK(A)		;get correct mask for time
	MOVEM A,SUNSIZ			;for use by twink2
	HLR C,D
	ANDCM C,[776000,,776000]	;set up to vector
	IOR C,[PT%Y\NC%PNT,,PT%X\PT%DSP\NC%VCT]
	MOVE A,C			;put into proper acc
	MOVSI T,-10.			;20 vectors sufficient
	PUSHJ P,TWINK2+2		;create explosion
	POPJ P,				;that's all

	;now make the flare get smaller
FLARE2:	MOVEI A,FLARE3
	SKIPN FIRBAL
	 TLO A,400000
	TLO A,%TFB
	MOVEM A,OBJFLG(MP1)
	JRST FLARE3			;start the flare getting smaller

	;make the flare decrease in size
FLARE3:	SOSGE A,FLAREC(MP1)		;check if flare done
	 JRST FLARE4			;done, make fireball
	MOVEM A,MSKIND			;save index of flare
	JRST FLAREA			;rest of code same as above

	;restore to a fireball
FLARE4:	MOVEI A,MEX
	SKIPN FIRBAL
	 TLO A,400000
	TLO A,%TFB			;SET TYPE= %TFB
	MOVEM A,OBJFLG(MP1)		;set addr of normal explosion
	MOVE A,MA1(MP1)			;decrease time left for explosion
	SUB A,FLARET(MP1)
	MOVEM A,MA1(MP1)
	POPJ P,				; that's all

	SUBTTL	Explosion Update Routine

MEX:	SOSGE MA1(MP1)			;is explosion over yet?
	 JRST MEXNO			; yes - remove object
	MOVEI T,200			;no - compute size of explosion now
	SKIPE FIRBAL
	 JRST MEX1			;fireballs can never get larger
	IMUL T,MA1(MP1)
	IDIV T,MB1(MP1)			;will increase with time
	MOVEI B,1400
	IDIV B,MB1(MP1)			;compute max size
	CAMG T,B			;and limit explosion to it
	 MOVE T,B

MEX1:	MOVEM T,EXSIZE'
	MOVE T,MA1(MP1)			;use time to go as point count
	ASH T,@EXSCL			;for big explosions
	SKIPE FIRBAL
	 MOVEI T,44			;with fireball always set number of points
	PUSH P,T			;save t which is used by cgrav
	PUSHJ P,SUNGRV			;compute effects of gravity
	POP P,T				;restore saved regs
MEX1A:	FADRB B,OBJYVL(MP1)		;update y, x velocities
	FADRB C,OBJXVL(MP1)
	LIMIT Y,B			;fix them
	LIMIT X,C
	SFIX C,-1
	SFIX B,-1
	MOVEM C,EXY'			;and save them
	MOVEM D,EXX'

	;create random points
	EXCH C,D			;put x into c and y into d

MEX2:	IRPS CORD,,D C
;	PUSHJ P,RANDOM
	GETRAN A
	TLZ A,776000
	IDIV A,EXSIZE
	TRNN B,2
	 LSH A,1
	TRNN B,1
	 MOVNS A
	ADD CORD,A
	TERMIN
	DISPT				;put POINT into list
	HRLS MP2
	MOVE D,EXY			;restore center coordinates
	MOVE C,EXX
	SOJGE T,MEX2			;continue making fireball
	POPJ P,

	;object has stopped exploding
MEXNO:	SETZM OBJFLG(MP1)			;flush object
	POPJ P,


	SUBTTL	Input Routines And Movie Code

;input routines for each star ship
;	OUTPUTS ARE:
;		a = ang. velocity increment (+ = ccw)
;		b = acceleration (if any)
;		c bits are:
;			0 - on for fire button
;			1 - on for hyper button

IFN $MOVIE [
MRECPT:	440500,,PRGEND			;initial recording head position
MPLYPT:	440500,,PRGEND			;initial playback head position

TAPRT:	DATAI A				;read data sws
	TRNN A,10			;tape hacking enabled?
	 JRST TRETZ			;no. movie=0
	TRNE A,20			;yes. filming or viewing?
	 JRST TAPRT1			;viewing playback.
	HRRZ A,MRECPT			;get current addr
	AOJ A,				;increment to get next(free) wd
	CAILE A,CORSIZ-3		;see if too high
	 MOVEI A,PRGEND			;correct if so
	SETZM (A)			;zero word as sign of game beginning
	SKIPN B,RAN			;make sure ran is non-zero
	 MOVE B,[123456,,654321]
	MOVEM B,1(A)			;store value of ran
	MOVEI A,2(A)			;finally done, point to start of record
	HRLI A,440500			;form byte pointer
	MOVEM A,MRECPT			;put back, all done
	MOVEI A,1			;return, setting movie to 1
	MOVEM A, MOVIE
	POPJ P,

TRETZ:	SETZM MOVIE
	POPJ P,

TAPRT1:	HRRZ B,MRECPT			;get current recording addr.
	SKIPGE MOVIE			;skip if mrecpt ok
	 HRRZ B,MPLYPT			;no,we were playing...reverse from mplypt.
	TRNE A,100			;play last thing?
	 JRST TAPRT4			;yes, go get it
	TRNE A,40			;playing forward?
	 JRST TAPRT3			;no, reverse.
	PUSHJ P,TAPFWD			;get next game--playing forward
	JRST TAPRT5

TAPRT3:	PUSHJ P,TAPREV			;takes arg in b, returns addr of prev. game in b
	SKIPL MOVIE
	 JRST TAPRT5			;once enuf if this first time
	SOJ B,				;set up for next pass
	CAIGE B,PRGEND
	 MOVEI B,CORSIZ-3
TAPRT4:	PUSHJ P,TAPREV
TAPRT5:	MOVE A,1(B)			;get val. of ran
	MOVEM A,RAN			;set it
	MOVEI B,2(B)			;get addr of input string
	HRLI B,440500			;convert to byte ptr
	MOVEM B,MPLYPT			;store
	SETOM MOVIE			;return setting movie neg.
	POPJ P,

TAPREV:	SETZM TWIC'
TPRV1:	SUBI B,PRGEND			;get index (=0 when run off low end)
	SKIPN PRGEND(B)			;look for zero word
	 SKIPN PRGEND+1(B)		;found one! test next for non-z
	  SOJGE B,.-2			;loop
	JUMPGE B,TPRV2			;found start of a game!
	SKIPE TWIC
	 JSR FATAL			;found nothing anywhere!
	SETOM TWIC
	MOVEI B,CORSIZ-3		;ran off low end, wrap to high end
	JRST TPRV1			;try again
TPRV2:	MOVEI B,PRGEND(B)		;insert real addr
	POPJ P,

TAPFWD:	SETZM TWIC
TPFD1:	SUBI B,CORSIZ-3			;get -<# words to try>
	JUMPG B,TPFD2			;jump if too close to end
	SKIPN CORSIZ-3(B)		;zero wd?
	 SKIPN CORSIZ-2(B)		;if so, next non-z?
	  AOJLE B,.-2
	JUMPLE B,TPFD3			;found start!
TPFD2:	SKIPE TWIC
	 JSR FATAL			;found nothing
	SETOM TWIC
	MOVEI B,PRGEND			;reset
	JRST TPFD1
TPFD3:	MOVEI B,CORSIZ-3(B)		;insert real addr
	POPJ P,


	;input routines when taping.
GSS1:	SKIPL MOVIE			;skip if playbacking!!!!
	 JRST GSS11
	ILDB T,MPLYPT			;load 5 bits from ptr
	ROT T,-5			;get bits into upper part
	JRST GSSGOT

GSS11:	DATAI 0				;get input for ship 1
	MOVSS T,T			;from right half of word
	JRST GSSGOT

GSS2:	SKIPL MOVIE			;skip if playbacking!!!
	 JRST GSS21
	ILDB T,MPLYPT
	ROT T,-5
	JRST GSSGOT

GSS21:	DATAI 0				;get input for ship 2

GSSGOT:	SKIPG MOVIE
	 JRST .+4
	ROT T,5				;get into low bits
	IDPB T,MRECPT
	ROT T,-5			;restore
] ;end of IFN $MOVIE !!!


;BYTE POINTERS TO SWITCHES FOR EACH SHIP

BUTTNS:	.BP 000777,T			;UPPER-RIGHT CORNER: TOP PLUG ON SWITCHES BANK
	.BP 777000,T			;LOWER-RIGHT CORNER: SECOND PLUG
	.BP (000777),T			;LOWER-LEFT  CORNER: THIRD PLUG
	.BP (777000),T			;UPPER-LEFT  CORNER: BOTTOM PLUG


	;except it wont work with movie mode yet anyway..
GSS:	DATAI 0
					;pick up inputs for the current ship
	LDB T,BUTTNS(MP1) 		;can be from any place this way
	SETZB A,B			;clear output values
	MOVEI C,0
	TRNN T,400			;turn clockwise?
	 MOVN A,MAA			; yes - put -maa into a
	TRNN T,200			;turn counter-clockwise?
	 MOVE A,MAA			; yes - put maa into a
	TRNN T,100			;thrust on
	 MOVE B,SAC			; yes - get acceleration
	TRNE T,40			;hyperspace on?
	 JRST NOTON			;no
	SKIPE HYPLOS(MP1) 		;IS IT A LOSSAGE WARCONSOLE?
	 TRNN T,20			; YES - DO IT ONLY IF FIRE ALSO ON
	  TLO C,200000			;turn on bit 1
NOTON:	TRNN T,20			;fire on?
	 TLO C,400000			; yes - turn on bit 0
	SKIPN ZAPPER			;all done with phaser input
	 SKIPE RLT			;is sniping on?
	  POPJ P,0			; no - return

	;process sniping by checking that fire button was released
	JUMPL C,TRIGGR			;firing?
	SETZM CHAMBR(MP1)		; no - clear chamber and return
	POPJ P,0
TRIGGR:	SKIPE CHAMBR(MP1)		;is chamber clear?
	 JRST JAMMED			; no - can't fire
	SETOM CHAMBR(MP1)		;fire and jam
	POPJ P,0
JAMMED:	TLZ C,400000			;turn off fire bit
	POPJ P,0

	SUBTTL	Random Number Generators

	;Routine to set up random # table
RANSET:	PUSH P,A
	PUSH P,B
	MOVSI B,-LRANTB
RANST1:	PUSHJ P,RANDOM
	MOVEM A,RANTAB(B)
	AOBJN B,RANST1
	POP P,B
	POP P,A
	POPJ P,

	;routine to set up index into RANTAB
RINSET:	MOVEI A,LRANTB-1
	MOVEM A,RINDEX
	POPJ P,

	;routine for use when AC specified for random # isn't A.
RINSTX:	EXCH A,RINDEX
	MOVEI A,LRANTB
	EXCH A,RINDEX
	SOS (P)
	SOS (P)				;return to the SOSGE before the call to RINSET.
	POPJ P,				;this is necessary to get index in right ac.

RINDEX:	0
RANTAB:	BLOCK LRANTB

;routine to compute a random number
;later replace by something more demonstrably random.  Note that an indeterministic
;random # can be obtained by crunching the current display BLKO pointer!!

RANDOM:	MOVE A,RAN
	FMPB A,RAN
	TSC A,A
	MOVEM A,RANSAV'
	MOVE A,RAN
	FMPB A,RAN
	TSC A,A
	HRR A,RANSAV
	POPJ P,

RAN:	123456,,654321			;initial seed

;routine to generate random no. 0.0<#<1.0
RANONE:
;	PUSHJ P,RANDOM	;get random pattern
	GETRAN A
	ANDI A,-1
	TLC A,232000			;float it
	FADR A,A
	FSC A,-18.			;get 0.0< # <1.0 (pdp-6 doesn't normalize!)
IFE $ITS,[	FADR A,[0.0]
]
	POPJ P,

	SUBTTL	Sun Update

TWINKL:	MOVEI S,-$MXSHP(MP1)		;adjust to comfortable index.
	SKIPE SUNINV(S)
	 POPJ P,			;no-op if this sun is black hole.
	PUSH Q,SUNBR			;sun brightness
	MOVSI T,1
	HRLZ D,ISUNLY(S)		;get sun y coord
	HRR D,ISUNLX(S)			;get sun x coord
	IRP Z,,[AX,AY,SX,SY,[AX,AY],[AX,SY],[SX,AY],[I,SX,SY]]
;	PUSHJ P,RANDOM
	GETRAN A
	ANDI A,7
	LTWNK=.
	IRP W,,[Z]
	IFSE W,AX,ADDI D,1
	IFSE W,SX,SUBI D,1
	IFSE W,AY,ADD D,T
	IFSE W,SY,SUB D,T
	TERMIN
	MOVE C,D
	AND C,[1777,,1777]
	IOR C,[PT%Y\NC%PNT,,PT%X\PT%DSP\NC%PNT]
	PUSH Q,C
	SOJGE A,LTWNK
	IRPC W,,[Z]
	IFSE [W]I,.ISTOP
	IFSE [W]X,HRR D,ISUNLX(S)
	IFSE [W]Y,HRL D,ISUNLY(S)
	TERMIN
	TERMIN
	POPJ P,


;display a twinkling object in vector mode
TWINK2:	MOVE A,[PT%Y\<512.>\NC%PNT,,PT%X\PT%DSP\<512.>\NC%VCT]	;default is sun
	MOVSI T,-4			;8 lines
	PUSH Q,A			;STORE INITIALIZING WD IN MDBUF LIST
LTWK:
;	PUSHJ P,RANDOM
	GETRAN A
	AND A,SUNSIZ			;get x,y increments in each half
	MOVS C,A			;put ra,,la in c
	HRR C,A				;put ra,,ra into c
	HLR A,A				;make a = la,,la
	XORI A,VC%DSP\VC%YSN\VC%XSN	;right half restores to center
	PUSH Q,A			;put into list
	XORI C,VC%DSP\VC%YSN\VC%XSN	;same with c
	PUSH Q,C			;put into list
	AOBJN T,LTWK
	IORI C,VC%ESC			;change last command
	MOVEM C,(Q)			; to enter parameter mode
	PUSH Q,MDBFBR			;NOW CAN REENTER POINT MODE
	POPJ P,0


TWINC:	PUSH Q,[PT%Y\<512.>\NC%PNT,,PT%X\PT%DSP\<512.>\NC%INC]
					;SET LOC AT CENTER, GO INTO VECINCR MODE
	MOVSI C,-8.
TWINC3:
;	PUSHJ P,RANDOM
	GETRAN A
	SETCM B,A			;GET COMPLEMENT INTO B
	ANDCM A,[600000,,600000]	;FLUSH ESC AND INTENSIFY BITS
	IOR A,[325252,,325252]		;INTENSIFY ON WAY OUT, ALWAYS INCR
	ANDCM B,[600000,,600000]
	IOR A,[125252,,125252]		;ALWAYS INCR
	PUSH Q,A
	PUSH Q,B
	AOBJN C,TWINC3
	IORI A,400000			;SET LAST HWD TO ESC TO PARAMETER.
	MOVEM A,(Q)
	PUSH Q,MDBFBR			;REENTER PT MODE
	POPJ P,

	SUBTTL	Phasar Per Loop Processing

; routine to handle phaser beams, called once on each main loop pass
RAYGUN:	MOVEM P,RYSAVP'			;save P since may stack instrs on PDL
	MOVE MP1,NEGSHP			;counter
RLOOP:	SOSLE DISTM(MP1)		;is he still disabled
	 JRST RLOP1			;yes
	SETZM BMENB(MP1)		;no- give back his powers
	SETZM THENB(MP1)
	SETZM CWENB(MP1)
	SETZM CCWENB(MP1)
RLOP1:	SKIPL T,MFU(MP1)		;power? put in t.
	 JRST RYLOUT			;jump if no power left.
	HRRZ A,OBJFLG(MP1)
	CAIE A,SSS			;make sure this ship not in hyper or expl.
	 JRST RYLOUT
	MOVE A,BMPOW(MP1)
	SKIPE RAY(MP1)			;beam?
	 JRST BMCHK			;jump if firing beam.
	SETZM BMRLSF(MP1)		;clear release flag.
BMINCP:	CAMGE A,BMPLN
	 AOSN A
	  MOVE A,BMPLN
	MOVEM A,BMPOW(MP1)
	JRST RYLOUT
BMCHK:	JUMPLE A,BMINCP
	SKIPE BMENB(MP1)		;nose damaged?
	 JRST BMINCP			;yes, no firing but continue reload.
	SKIPE BMRLSF(MP1)		;check for release.
	 JRST BMINCP
	SOSE BMPOW(MP1)
	 JRST FIREBM
	MOVN A,BMRLD			;set up reload time.
	MOVEM A,BMPOW(MP1)
	SETOM BMRLSF(MP1)		;set release flag.

	;fire beam.

FIREBM:	FADR T,BRATE			;beam eats power.
	MOVEM T,MFU(MP1)


	;initialize for rmiss routine

	MOVE D,MPFSIN(MP1)
	MOVE B,MPFCOS(MP1)
	MOVM T,B			;protection against cos=0
	SETZM VERT'
	CAMG T,[0.000001]
	 SETOM VERT
	FDVRB D,B			;get slope asl=sin/cos in d.
	FMPR B,B			;asl**2
	MOVE C,[1.0]
	FADR B,C			;asl**2 + 1
	FDVR C,B			;1/asl**2 + 1  in c


	MOVE MP2,NEGSHP			;INNER LOOP
RLUIP:	CAMN MP1,MP2			;CHECKING SAME SHIP?
	 JRST RYLIN			;DON'T.
	HRRZ A,OBJFLG(MP2)			;MAKE SURE THAT POTENTIAL VICTIM
	CAIE A,SSS			;IS NOT HYPER OR EXPL
	 JRST RYLIN
	SETZM HIT(MP2)			;ASSUME NO HIT TIL PROOF.

	;adjust coords of other ship

	MOVE A,OBJX(MP1)
	MOVE B,OBJX(MP2)
	RELATV A,B
	MOVEM B,X'
	MOVE A,OBJY(MP1)
	MOVE B,OBJY(MP2)
	RELATV A,B
	MOVEM B,Y'

	;test direction.

	XOR B,MPFSIN(MP1)		;sign bit will be 0 if same,1 if diff.
	JUMPGE B,OKDIR			;right dir. if either x,y have same sign.
	MOVE B,X
	XOR B,MPFCOS(MP1)
	JUMPL B,RYLIN			;no hit if neither coord matches.

OKDIR:	SKIPN FIELD(MP2)		;don't test for ff hit
	 JRST FLDOFF			;if enemy doesn't have it on!

	;test for force field hit.

	MOVEI R,0
	PUSHJ P,RMISS
	CAMG A,RAD2(R)			;a=(dist to center of field)**2
	 JRST ZAP			;a hit if dist. is less than radius of field.
	JRST RYLIN

	;test for ship hit (ship has 3 hittable circles, like snowman)

FLDOFF:	MOVEI R,3
	PUSHJ P,RMISS
	CAMG A,RAD2(R)
	 JRST ZAP			;if rmiss says so.
	SOJG R,FLDOFF+1
	JRST RYLIN 			;here only if no hits at all.


RMISS:	MOVE A,COLLOC(R)		;get loc of circle on ship axis
	MOVE B,A			;(+:to nose,-:to tail).
	FMPR A,MPFSIN(MP2)		;get x,y coords of the loc.
	FMPR B,MPFCOS(MP2)
	FADR A,Y			;now have y-coord in a
	FADR B,X			;       x         b
	SKIPE VERT			;don't try to get dist. if cos=0
	 JRST REQX
	MOVE T,A			;save x,y =center of coll. radius.
	MOVE TT,B

	FMPR A,D			;a=asl,a*y
	FADRB A,B			;a*y+x
	FMPR B,C			;(ay+x)/(a**2+1) now have xi in b
	MOVE A,B
	FMPR A,D			;a*xi now have yi in a
	EXCH A,T			;save xi,yi (coords. of intersection of beam
	EXCH B,TT			;with perpendicular of x,y) for zap

	FSBR A,T			;get y-yi
	FSBR B,TT			;get x-xi
	FMPR A,A			;y**2
	FMPR B,B			;x**2
	FADR A,B			;r**2 is now in a;this is the desired result.
	POPJ P,0

REQX:	MOVEI TT,0			;put xi=0 in tt for zap
	MOVE T,A			;put yi=y in t for zap
	MOVE A,B			;if vertical, dist. is just the x diff.
	FMPR A,A
	POPJ P,



RYLIN:	SETZM HIT(MP2)			;NO HIT, BUT CAN COME HERE WITH HIT=-1
	AOBJN MP2,RLUIP			;NO HIT ON THIS ONE, CHECK OTHER SHIPS.
	MOVE A,RAYLEN			;if here, no hit AT ALL - use standard length.
	PUSHJ P,DORAY			;do the ray.
	JRST RYLOUT			;NOW BACK TO OUTER LOOP.


ZAP:	SETOM HIT(MP2)
	FMPR T,T			;yi**2 (from rmiss)
	FMPR TT,TT			;xi**2
	FADR T,TT			;get rs**2 =dist from inters. to ship
	PUSHJ P,SQRT			;ri**2 is still in a from rmiss--get ri.
	MOVE B,[.707]			;sin pi/4
	FMPR B,RADIUS(R)		;now have rp/(2)**1/2 in b
	MOVE C,A			;put ri in c.
	MOVE A,T			;arg for sqrt
	PUSH P,B
	PUSH P,C
	PUSHJ P,SQRT			;get rs in a.
	POP P,C
	POP P,B
	CAMG C,B			;skip if ri>rp/sqrt(2)
	 JRST INNER

	;rb=rs-[(ri-rp)/(1-sqrt(2))]

	FSBR C,RADIUS(R)		;ri-rp
	FDVR C,[-.4144]			;1/(1-sqrt(2))
	FSBR A,C			;rb=rs-above
	JRST RANGE

	;rb=rs-[(1-sqrt(2))*ri +rp]

INNER:	FMPR C,[-.4144]			;(1-sqrt(2))*ri
	FADR C,RADIUS(R)		;above+rp
	FSBR A,C			;rs-above

RANGE:	FSBR A,SHPSL1(MP1)		;allow for ship nose
	SFIX A,-19.			;fix dist. for comparing with raylen
	CAMLE B,RAYLEN			;skip if raylen long enough
	 JRST RYLIN			;nope

	;we have a solid hit--draw beam for this length

	MOVE A,B			;arg to doray
	PUSHJ P,DORAY			;do it at long last
	MOVEM R,HIT(MP2)		;let other know where it's been hit
	JUMPN R,[MOVSI T,-5		;just do sparkle if no f.f.
		MOVE A,SXPMSK
		JRST NOFLD]
	MOVEI A,PM%EBR\7\NC%PNT
	MOVEM A,@FFBRI(MP2)		;increase f.f. brightness (flare)
	SETOM HIT(MP2)			;-1=hit in f.f.
	MOVSI T,-2			;initialize for twink2
	MOVE A,FXPMSK
NOFLD:	MOVEM A,SUNSIZ			;set size of sparkle

	SUB D,BXSIN(MP1)
	SUB C,BXCOS(MP1)
	HLR D,C				;y and x from doray are now in left+rt half of d
	ANDCM D,[776000,,776000]	;isolate y,x
	IOR D,[PT%Y\NC%PNT,,PT%X\PT%DSP\NC%VCT]	;set to go into vector mode
	MOVE A,D			;put in right acc. for twink2
	PUSHJ P,TWINK2+2		;bypass twink2's sun-loc initialize

	;the beams are done--now handle the hits produced.

	MOVE R,HIT(MP2)			;restore R
	JUMPG R,SSHIT			;R:-1=f.f. hit, 0=no hit,1,2,3=nose,mid,tail.

	MOVE A,[FADRM A,MFU]
	ADDI A,(MP2)			;make instr mung right slot
	PUSH P,A
	PUSH P,[MOVE A,FHITRT]		;this is what the FADRM will FADR.
	SETZM DHITS(MP2)		;zero the consec. counters
	SETZM CHITS(MP2)
	JRST RYLOUT

SSHIT:	AOS THITS(MP2)			;total hits in game
	AOS CHITS(MP2)			;consecutive hits thus far
	AOS A,DHITS(MP2)		;consec. hits for disabler
	CAMGE A,TDSABL			;skip if enough hits to disable something
	 JRST RYLOUT			;ELSE ALL FOR NOW.

	MOVE A,DISTIM			;cripple! set up how long he will be disabled
	MOVEM A,DISTM(MP2)
	SETZM DHITS(MP2)		;reset dhits.
	CAIE R,2
	 JRST SSHIT1			;not middle, skip.
	SETZ B,
	MOVE A,MTH(MP2)			;hit middle. see which side to kill.
	FSBR A,MTH(MP1)			;ths-th
	CAIGE A,0
	 TRO B,2			;SET IF NEG
	MOVM A,A
	CAIGE A,PIE
	 TRO B,1			;SET IF ABS VAL<PI
	MOVEI A,@(B)[
		CWENB(MP2)		;IF POS AND >PI
		CCWENB(MP2)		;IF POS AND <PI
		CCWENB(MP2)		;IF NEG AND >PI
		CWENB(MP2)]		;IF NEG AND <PI
SSHIT1:	CAIN R,1
	 MOVEI A,BMENB(MP2)		;hit nose, disable beam
	CAIN R,3
	 MOVEI A,THENB(MP2)		;hit tail, disable thrust
	HRLI A,(SETOM)
	PUSH P,A			;PUSH INSTR TO XCT LATER

SSHIT2:	MOVE A,DESTR1			;reached limit,
	CAMLE A,THITS			;total hits?
	 JRST SSHIT4			;yes, die.
	MOVE A,DESTR2			;else reached limit,
	CAMG A,CHITS			;consecutive hits?
	 JRST RYLOUT			;nope, not yet

SSHIT4:	PUSH P,[PUSHJ P,SEXP]
	MOVE A,[MOVEI MP1,]
	ADDI A,(MP2)			;turn into MOVEI MP1,<IDX>
	PUSH P,A			;and xct it before the SEXP call
	AOS SCORE(MP1)			;increment score of killing ship

RYLOUT:	AOBJN MP1,RLOOP

	CAME P,RYSAVP
	 JRST [	POP P,B			;pop queued instrs off PDL and XCT them.
		XCT B
		JRST .-1]
	POPJ P,

	;DRAW THE BEAM (LENGTH IN A)
DORAY:	LSH A,-2			;get proper iterate (div by 4 to get increment)
	JUMPGE A,.+2			;blow up if firing too close
	JRST SEXP
	HRLZ A,A			;GET CNT
	ADD Q,A				;ADD INTO PDL PTR
	CAIL Q,
	 JSR FATAL			;OVERFLOW!
	MOVN A,A			;NOW MAKE AOBJN
	HRRI A,1(Q)			;GET ADDR (+1 SINCE Q PTS TO LAST PUSHED WD)
	MOVE D,DSAVE(MP1)
	MOVE C,CSAVE(MP1)		;restore c and d from prev. calc.
	HLL B,D				;form display instr.
	HLR B,C
	AND B,[1777,,1777]
	IOR B,[PT%Y\NC%PNT,,PT%X\PT%DSP\NC%PNT]
	MOVEM B,(A)			;put it in dis area
	ADD D,BXSIN(MP1)
	ADD C,BXCOS(MP1)
	AOBJN A,.-7			;loop to form another
	HRRI Q,-1(A)			;UPDATE PDL PTR
	POPJ P,

	SUBTTL	ForceField Generator and Test For HyperSpace

LTEST:	SETZM RAY(MP1)
	TLNN C,400000			;skip if fire on
	 JRST NOHYP			;else cannot be hyp
	TLNN C,200000			;skip and hyper if both f.f. and fire on.
	 JRST NOHYP
	SKIPN NOHYPR			;skip if hyperspace disabled
	 JRST HYPGO
	TLZ C,400000			;can't fire with shields up

NOHYP:	SKIPE BMENB(MP1)
	 TLZ C,400000			;wipe out fire bit if nose disabled
	SKIPE THENB(MP1)
	 SETZ B,			;wipe out sac if tail disabled

	JUMPE A,.+7			;no action if maa=0
	JUMPL A,.+4			;pos or neg(ccw or cw)
	SKIPE CCWENB(MP1)		;ccw ok?
	 SETZ A,			;erase if no
	JRST .+3
	SKIPE CWENB(MP1) 		;cw ok?
	 SETZ A,			;ditto if ditto

	TLNE C,400000			;check for fire here
	 SETOM RAY(MP1)			;set flag if fire
	SETZM FIELD(MP1)
	TLNE C,200000			;hyper lever? asking for f.f.
	 SETOM FIELD(MP1)		;set flag if f.f.
	JRST SSNHYP


;routine to form f.f. (force field, deflectors)
FFIELD:	SKIPN FIELD(MP1)
	 JRST BEAM			;go to beam if no field to form
	SKIPLE T,MFU(MP1)		;see if still have power
	 JRST FFDIE			;erase flag+return if not
	MOVE A,FFRATE			;field uses power 
	FADRB A,MFU(MP1)		;use it!

	MOVE D,OBJX(MP1)
	FSBR D,RADIUS			;adjust so will only have to add positive #'s
	JUMPGE D,.+2			;must allow for wraparound
	FADR D,[1024.0]
	MOVE C,OBJY(MP1)
	FSBR C,RADIUS
	JUMPGE C,.+2
	FADR C,[1024.0]
	SFIX D,-19.			;fix to get scope coords
	SFIX C,-1.
	HRR D,T				;y in left half, x in right

	MOVEI A,1(Q)			;get addr of open dis loc
	MOVEM A,FFBRI(MP1)		;store it
	PUSH Q,[PM%EBR\7\NC%PNT]	;and put low bri in for f.f.

	MOVSI T,-FFCPTS			;# pts per circle
CIRCLE:	MOVE MP2,D			;get adjusted origin
	ADD MP2,CIRTAB(T)		;add incr. to get circle
	AND MP2,[1777,,1777]
	IOR MP2,[PT%Y\NC%PNT,,PT%X\PT%DSP\NC%PNT]
	PUSH Q,MP2
	AOBJN T,CIRCLE
	PUSH Q,MDBFBR			;must restore normal brightness
	POPJ P,

FFDIE:	SETZM FIELD(MP1)		;wipe out ff
	POPJ P,



;routine called on pgm startup to initialize f.f. circle coord table
CMPASS:	MOVE XFLAG,PI2
	MOVEI C,FFCPTS			;GET # PTS TO USE IN CIRCLE
	FSC C,233			;FLOAT IT
IFE $ITS,[	FADR C,[0.0]
]
	FDVR XFLAG,C			;NOW HAVE ARC PER POINT
	MOVSI R,-FFCPTS
	SETZ C,				;zero arg to sin routine
CLOOP:	FADR C,XFLAG			;increment argument
	MOVE A,C			;put in proper acc
	PUSHJ P,SIN
	FMPR A,RADIUS			;mul to get right distance from center
	FADR A,RADIUS			;adjust to get positive displacement
	SSFIX A,-1			;fix returned value
	HLL T,B				;store y in left half
	MOVE A,C
	PUSHJ P,COS
	FMPR A,RADIUS
	FADR A,RADIUS			;again get positive displ.
	SSFIX A,-1
	HLR T,B				;store x in right half
	MOVEM T,CIRTAB(R)		;store in table
	AOBJN R,CLOOP
	POPJ P,

	SUBTTL	Phasar Tables and Flare Masks

SUNSIZ:	303607,,303607			;twink2 uses this to mask for vector
SXPMSK:	303607,,303607			;put in sunsiz for ss hit
FXPMSK:	307617,,307617			;put in sunsiz for f.f. hit
SUNMSK:	303607,,303607			;mask for use in making sun
FLSMSK:	300200,,300200			;mask for each time during a flare
	300601,,300601			; 1
	301603,,301603			; 2
	301603,,301603			; 3
	303607,,303607			; 4
	303607,,303607			; 5
	303607,,303607			; 6
	303607,,303607			; 7
	307617,,307617			; 10
	307617,,307617			; 11
	307617,,307617			; 12
	307617,,307617			; 13
	317637,,317637			; 14
	317637,,317637			; 15
	317637,,317637			; 16
	317637,,317637			; 17
	337677,,337677			; 20
FLAREL:	4				; length of flare for exscl = 0
	10				; exscl = 1
	14				; exscl = 2
	20				; exscl = 3

HIT:	BLOCK $MXSHP
RAY:	BLOCK $MXSHP
FIELD:	BLOCK $MXSHP			;0=no ff, -1=ff on
BXSIN:	BLOCK $MXSHP			;for doray
BXCOS:	BLOCK $MXSHP			;for doray
FFBRI:	BLOCK $MXSHP			;loc. of ff birghtness word in d-list
DSAVE:	BLOCK $MXSHP			;for doray
CSAVE:	BLOCK $MXSHP			;for doray
THITS:	BLOCK $MXSHP			;total hits in game
CHITS:	BLOCK $MXSHP			;consecutive hit counter
DHITS:	BLOCK $MXSHP			;disabling hits counter

COLLOC:	0.0				;loc. of f.f.center
	9.0				;loc of nose center
	-7.0				;loc of tail center
	3.0				;loc of middle center
RADIUS:	20.0				;radius of f.f. circle
	4.0				;rad. of nose circle
	7.0				;rad of tail circle
	4.0				;rad. of middle circle
RAD2:	400.0				;radius table squared.
	16.0
	49.0
	16.0

BMPOW:	BLOCK $MXSHP			;beam timeout counter (duration and reload)
BMRLSF:	BLOCK $MXSHP			;beam release flag(analogous to chambr:)
BMENB:	BLOCK $MXSHP			;beam enable/disable
THENB:	BLOCK $MXSHP			;thrust    
CWENB:	BLOCK $MXSHP			;cw turn    
CCWENB:	BLOCK $MXSHP			;ccw turn   
DISTM:	BLOCK $MXSHP			;time he is still disabled
CIRTAB:	BLOCK FFCPTS			;table for circle coords (used in ff)

	SUBTTL	Sqaure Root Procedure

	; This is AGB's super fast SQRT routine, probably impossible to
	;improve on... clobbers B,C.

SQRT:	SKIPG B,A
	 POPJ P,
	ASH A,-1
	ADD A,[262370613]		; 0.292893/0.840186 B8.
					; or 0.414214/0.594101 B9.
	TLON A,400
	 JRST SQRT2

IFN $ITS, FMPRI A,301460		; 0.594101^101
IFE $ITS, FMPR A,[301460,,0]		; PDP-6 doesn't have FMPRI !!
	JRST SQRT3

SQRT2:
IFN $ITS, FMPRI A,300656		; 0.840186^100
IFE $ITS, FMPR A,[300656,,0]

SQRT3:	MOVE C,B
	FDV  B,A
	FAD A,B ? FSC A,-1
	FDVR C,A
	FAD A,C ? FSC A,-1		; MORE EXACT THAN FADR
	POPJ P,

	SUBTTL	SIN and COS Procedures

;FLOATING POINT SINE AND COSINE.  REENTERABLE.

SIND:	FMPR A,[.01745329251994]	;PI/180 (ENTRY PT FOR DEGREES)
	JRST SIN

COSD:	FMPR A,[.01745329251994]
COS:	FADR A,SC1	;PI/2
SIN:	CAMG A,SC9	;.000211431983 IS SUFFICIENT FOR IDENTITY, 10**-15 IS NECESSARY NOT TO UNDERFLOW
	CAMGE A,[-.000211431983]	;ABS X MIGHT CAUSE POLYNOMIAL UNDERFLOW
	JRST .+2
	POPJ P,	;AND IS SMALL ENOUGH FOR SIN X _ X
	FDVR A,SC1	;PI/2
	PUSH P,A
	PUSH P,B
	MULI A,400
	TSC A,A		;CAML A,...SETZB B,-1(P)
	ASH B,-243(A)
	MOVNS A,B
	ANDCMI A,1
	TLC A,232000
	FAD A,A
	FADRB A,-1(P)
	TRNE B,2
	MOVNS A,-1(P)
	FMP A,A
	MOVE B,SC9
	FMP B,A
	FAD B,SC7
	FMP B,A
	FAD B,SC5
	FMP B,A
	FAD B,SC3
	FMP A,B
	FADR A,SC1
	FMPRM A,-1(P)
	POP P,B
	POP P,A
	POPJ P,

SC1:	1.5707963267
SC3:	-0.64596371106
SC5:	0.07968967928
SC7:	-0.00467376557
SC9:	0.00015148419

	SUBTTL ATAN Procedure

;FLOATING POINT SINGLE PRECISION ARCTANGENT FUNCTION
;ATAN(X) = X(B0+A1(Z+B1-A2(Z+B2-A3(Z+B3)**-1)**-1)**-1)
;WHERE Z=X^2, IF 0<X<=1

;IF X>1, THEN ATAN(X) = PI/2 - ATAN(1/X)
;IF X>1, THEN RH(D) =-1, AND LH(D) = -SGN(X)
;IF X<1, THEN RH(D) = 0, AND LH(D) =  SGN(X)

;THE ROUTINE IS CALLED IN THE FOLLOWING MANNER:
;	MOVE A,ARGUMENT
;	PUSHJ P,ATAN
;THE ANSWER IS RETURNED IN ACCUMULATOR A

ATAN:	MOVEM	B, ATANB	;SAVE AC B
ATAN1:	MOVM	B, A		;GET ABSF OF ARGUMENT
	CAMG	B, A1		;IF X<2^-33, THEN RETURN WITH...
	POPJ P,			;ATAN(X) = X
	MOVEM	D, D1		;SAVE ACCUMULATOR D
	HLLO	D, A		;SAVE SIGN, SET RH(D) = -1
	CAML	B, A2		;IF A>2^33, THEN RETURN WITH
	JRST	AT4		;ATAN(X) = PI/2
	MOVEM	C, C1		;SAVE ACCUMULATOR C
	MOVSI	C, 201400	;FORM 1.0 IN C
	CAMG	B, C		;IS ABSF(X)>1.0?
	TRZA	D, -1		;IF B .LE. 1.0, THEN RH(D) = 0
	FDVM	C, B		;B IS REPLACED BY 1.0/B
	TLC	D, (D)		;XOR SIGN WITH .G. 1.0 INDICATOR
	MOVEM	B, C3		;SAVE THE ARGUMENT
	FMP	B, B		;GET B^2
	MOVE	C, KB3		;PICK UP A CONSTANT
	FAD	C, B		;ADD B^2
	MOVE	A, KA3		;ADD IN NEXT CONSTANT
	FDVM	A, C		;FORM -A3/(B^2 + B3)
	FAD	C, B		;ADD B^2 TO PARTIAL SUM
	FAD	C, KB2		;ADD B2 TO PARTIAL SUM
	MOVE	A, KA2		;PICK UP -A2
	FDVM	A, C		;DIVIDE PARTIAL SUM BY -A2
	FAD	C, B		;ADD B^2 TO PARTIAL SUM
	FAD	C, KB1		;ADD  B1 TO PARTIAL SUM
	MOVE	A, KA1		;PICK UP A1
	FDV	A, C		;DIVIDE PARTIAL SUM BY A1
	FAD	A, KB0		;ADD B0
	FMP	A, C3		;MULTIPLY BY ORIGINAL ARGUMENT
	TRNE	D, -1		;CHECK .G. 1.0 INDICATOR
	FSB	A, PIOT		;ATAN(A) = -(ATAN(1/A)-PI/2)
	SKIPA	C, C1		;RESTORE ACCUMULATOR C AND SKIP
AT4:	MOVE	A, PIOT		;GET PI/2 AS ANSWER
	SKIPGE	D		;LH(D) = -SGN(B) IF B>1.0
	MOVNS	A		;NEGATE ANSWER
	MOVE	D, D1		;RESTORE ACCUMULATOR
	MOVE	B, ATANB	;RESTORE AC B
	POPJ P,

A1:	145000000000		;2**-33
A2:	233000000000		;2**33
KB0:	0.1746554388
KB1:	6.762139240
KB2:	3.316335425
KB3:	1.448631538
KA1:	3.709256262
KA2:	-7.106760045
KA3:	-0.2647686202
C1:	0
C3:	0
D1:	0
PIOT:	201622077325		;PI/2
ATANB:	0

	SUBTTL Ship Design Macro

DEFINE INST IN,CO,ADR			;generates display generating instruction
IFSE CO,X,[IN D,ADR
	   HLRZ B,D
	  ]
IFSE CO,Y,[IN C,ADR
	   HLL B,C
	   TDZ B,[776000,,776000]
	   IOR B,A
	   MOVEM B,%DPP(T)
%DPP==%DPP+1
	  ]
TERMIN


;DESIGN	NAME,LENGTH,FORM
;   Inputs:
;	NAME:   The name to be used for this ship design.  It is given a
;	        global value of the design index.
;	LENGTH: A real number specifying the length of the ship.
;	FORM:   A list of symbols which define the design of the ship.  The 
;		ship's form is defined by specifying the operations necessary to
;		create the right hand side of the ship when the ship is pointing
;		straight up.  The possible symbols are:
;			U - move up one unit,
;			D - move down one unit,
;			L - move left one unit,
;			R - move right one unit,
;			UL - move up and left one unit (total length),
;			UR - move up and right one unit,
;			DL - move down and left one unit,
;			DR - move down and right one unit,
;			PUSH - remember current location, and
;			POP - return to last location saved by PUSH.

DEFINE DESIGN NAME,LENGTH,FORM
%DSLOC==.
%DPP==0

	IRPS FELMT,,[FORM]
	IFSE [FELMT][D][
INST SUB,X,XCOS
INST SUB,Y,XSIN
]
	IFSE [FELMT][R][
INST ADD,X,SXSIN
INST SUB,Y,SXCOS
]
	IFSE [FELMT][DR][
INST SUB,X,XCOS45
INST SUB,Y,SXSIN45
]
	IFSE [FELMT][L][
INST SUB,X,SXSIN
INST ADD,Y,SXCOS
]
	IFSE [FELMT][DL][
INST SUB,X,XSIN45
INST ADD,Y,SXCOS45
]
	IFSE [FELMT][U][
INST ADD,X,XCOS
INST ADD,Y,XSIN
]
	IFSE [FELMT][UL][
INST ADD,X,XCOS45
INST ADD,Y,SXSIN45
]
	IFSE [FELMT][UR][
INST ADD,X,XSIN45
INST SUB,Y,SXCOS45
]
	IFSE [FELMT][PUSH][
PUSH P,D
PUSH P,C
]
	IFSE [FELMT][POP][
POP P,C
POP P,D
]
TERMIN

	SKIPE RLHSW			;check if finished
	 POPJ P,

	SETOM RLHSW			;force left half and completion
	MOVNS SXSIN			;else, reverse to do left side
	MOVNS SXCOS
	MOVE TT,XCOS45
	EXCH TT,XSIN45
	MOVEM TT,XCOS45
	MOVN TT,SXCOS45
	EXCH TT,SXSIN45
	MOVNM TT,SXCOS45
	MOVE C,SYCOR
	MOVE D,SXCOR

	ADD T,CSPLN2			;move address to second half
	JRST %DSLOC

%CRLOC==.

IFL %MAXLN-<2*%DPP+1>,[%MAXLN==2*%DPP+1]

NAME==%DSNNO

LOC DSNNMS+%DSNNO
	.NTHWD 1,SIXBIT /NAME/

LOC DSNADR+%DSNNO
	%DSLOC

LOC DSNSL+%DSNNO
	.OP FMPR LENGTH 0.5

LOC DSNSL1+%DSNNO
	.OP FMPR LENGTH 0.57075

LOC DSNLN+%DSNNO
	2*%DPP+1			;account for brightness command

LOC DSNLN2+%DSNNO
	%DPP

LOC %CRLOC

%DSNNO==%DSNNO+1
TERMIN

	SUBTTL	 Ship Designs and Design Tables

;These tables contain information on the above designs

DSNNMS:		BLOCK $MXDSN		;names of the designs
DSNADR:		BLOCK $MXDSN		;address of display list generator
DSNSL:		BLOCK $MXDSN		;half the length of the ship
DSNSL1:		BLOCK $MXDSN		;location of gun at front of ship
DSNLN:		BLOCK $MXDSN		;total length of display list
DSNLN2:		BLOCK $MXDSN		;length of right side display list 


; THE STAR-SHIP ENTERPRISE: CONSTELLATION CLASS
DESIGN ENTERPRIZE,24.0,[R,DR,R,DR,DR,D	DR,D,D,D,DL,D
		    DL,L,DL,PUSH,L,L	POP,D,D,D,D,R
		    R,U,U,UR,DR,D	D,D,D,D,D,D
		    D,D,D,D,D,UL	DL,U,U,U,U,U
		    U,U,U,UL,L		DL,D,D,DL]

; THE KLINGON WARSHIP
DESIGN KLINGON,24.0,[R,R,DR,D,DL,DL	DL,D,D,D,D,D
		    D,DL,D,D,R,R	DR,DR,DR,DR,PUSH,U
		    POP,D,D,D,PUSH,D	D,POP,L,UL,UL,L
		    L,D,L,L]

; LONG THIN SHIP
DESIGN THINSHIP,30.0,[D,D,D,D,DR,D	D,D,D,D,D,D
		    D,D,D,D,D,D		D,D,D,D,PUSH,DR
		    DR,D,D,D,D,D	D,L,POP,D,D,D
		    D,D,D,D,D,L]

; SHORT FAT SHIP
DESIGN FATSHIP,22.0,[D,D,DR,D,D,DR	D,D,DR,D,D,D
		    D,D,PUSH,DR,D,DR	D,DR,D,D,D,D
		    D,POP,D,D,DL,D	D,D,D,PUSH,DR,DR
		    DR,POP,DL,D,D,L]

SDISTB:		BLOCK %MAXLN*$MXSHP	;area for display lists
SDADRS:		REPEAT $MXSHP,[	SDISTB+%MAXLN*.RPCNT
]

	SUBTTL	Ship Tables

;Specify the designs for each ship

IFL $MXSHP-3,[
IFE $SSTYP,[
SHPDSN:		THINSHIP			;Old fashioned ships only
		FATSHIP
]
IFN $SSTYP,[
SHPDSN:		ENTERPRIZE		;New ships only
		KLINGON
]
]					;of IFL $MXSHP-3

IFGE $MXSHP-3,[
SHPDSN:		ENTERPRIZE		;Upper-right corner when fixed starting positions
		KLINGON			;Lower-right corner
		THINSHIP		;Lower-left corner
		FATSHIP			;Upper-left corner
]


SHPADR:		BLOCK $MXSHP		;address of each's ship display generator
SHPDPT:		BLOCK $MXSHP		;BLKO pointers for each ship's display list
SHPSL:		BLOCK $MXSHP		;half-length of each ship
SHPSL1:		BLOCK $MXSHP		;adjusted for the gun
SHPLN2:		BLOCK $MXSHP		;length of one side of display list; used to
					;increment list address

	SUBTTL	Object Definition And Property Tables

	;Definition of Object Types
%TSUN==0
%TSS==1
%THSS==2
%TTORP==3
%TFB==4

;	organization of OBJCTS tables has:
; 1] $MXSHP slots reserved for SS's (exploding, hyperspatial, or otherwise)
; 2] $MXSUN slots reserved for suns
; 3] all remaining slots available for torps or randomness

TORIDX==$MXSHP+$MXSUN			; idx of first torp loc within OBJCTS tables

OBJFLG:	BLOCK OBJCTS			;dispatch table for each object.
					;bit 4.9 means non-collidable
					;000017,,0 field = type bits
					;000760,,0 field = index+1 of originator

OBJX:	BLOCK OBJCTS			;x pos
OBJY:	BLOCK OBJCTS			;y pos
MA1:	BLOCK OBJCTS			;counter for length of explosion
MB1:	BLOCK OBJCTS			;length of explosion
OBJXVL:	BLOCK OBJCTS			;xvel
OBJYVL:	BLOCK OBJCTS			;yvel
MNOGRV:	BLOCK OBJCTS			;gravity switch: 0 affects, -1 cuts off
OBJMAS:	BLOCK OBJCTS			;mass of object with ss = 1.0
FLARET:	BLOCK OBJCTS			;length of time as flare
FLAREC:	BLOCK OBJCTS			;length of time flare displayed

	;Star-Ship tables
OBJAVL:	BLOCK $MXSHP			;angular vel
MFU:	BLOCK $MXSHP			;fuel
MTR:	BLOCK $MXSHP			;torps
MTH:	BLOCK $MXSHP			;angle
MPFCOS:	BLOCK $MXSHP			;cos mth
MPFSIN:	BLOCK $MXSHP			;sin mth
MHYP:	BLOCK $MXSHP			;hyperspace counter
MHYPP:	BLOCK $MXSHP			;hyperspace survival chances
SCORE:	BLOCK $MXSHP			;wins to credit
CHAMBR:	BLOCK $MXSHP			;sniping state

	;Sun Tables
ISUNLY:	BLOCK $MXSUN
ISUNLX:	BLOCK $MXSUN
FSUNLY:	BLOCK $MXSUN
FSUNLX:	BLOCK $MXSUN
SUNINV:	BLOCK $MXSUN			;if non-zero, sun is not displayed-- black hole

	SUBTTL	Display List Area

TORDIS:	0				;torpedo brightness
TORDSB:	REPEAT <OBJCTS-TORIDX>,[	PT%NOP,,PT%NOP
]
TORDSE:	PM%HLT
TDISPT:	-<TORDSE-TORDIS>,,TORDIS-1

MDBFBR:	0				;Parametor word to set brightness and point mode
MDBFSW:	0				;SWITCH INDICATING WHICH MDBUF AREA TO USE
MDBTAB:	-MDBUFL,,MDBUF1-1		;PDL PTRS FOR EACH MDBUF BUFF
	-MDBUFL,,MDBUF2-1
MDBCUR:	0				;Original PDL pointer for current buffer

MDBUF1:	BLOCK MDBUFL			; misc. display buffer 1
MDBUF2:	BLOCK MDBUFL


CONSTANTS
VARIABLES

	SUBTTL	Star Field Definition

;STAR RA,DEC,MAG
;     Inputs:
;	RA:	The right ascension of the star.  A value of +8191 represents a
;		right ascension of zero hours;  the value zero represents an RA
;		of 24 hours.
;	DEC:	The declanation of the star.  A value of zero corresponds to zero
;		declanation; +511 corresponds to +90 degrees; and -511 corresponds
;		to -90 degrees.
;	MAG:	The magnitude of the star as a value from 0 to 7.  Seven is the
;		brightess.

DEFINE STAR #RA,DEC,MAG
%%DX==%%X-RA
%%X==RA
IFGE %%DX-200',{PRINTC "Offset in vector greeater than maximum (127.) for R.A. = "
		PRTVAL RA ? PRINTC "
"}
	VC%ESC\<%%DX&VC%XMM>
	PM%ESC\<0_PM%SCS>\PM%EBR\<MAG&PM%BRM>\NC%PNT
	PT%Y\PT%DSP\<<DEC+777'>&PT%MSK>\NC%VCT
TERMIN


%%X==8192.				;initialize X counter for following field

; This is the backround star field for Space-War.  It was copied from the
;field defined in the PDP-1X space war.  The field was generated from an
;actual star map.   This field in all probability was copied for CIPG's
;PDP-9 space war.

;Note: The following description is only valid for the 340 version of Space-War.
; The actual format of the field after compilation by the macro is described 
;below.  Each star requires three display instructions (PDP-6 halfwords).
;
;1. The first half word:
;	400000 + <X - X'>
;   X' is the previous X coordinate.  This is a vector instruction to shift
;   to the proper X position.  The 400000 causes an escape to parameter mode.
;
;2. The second half word:
;	020110 + <B>
;   The scale is set to zero and the brightness to the specified magnitude.  The
;   next instruction will be in point mode.
;
;3. The third half word:
;	302777 + <Y>
;   The Y coordinate is set to the specified value plus 511 to account for the
;   coordinate system used by the display.  The point is displayed.  The next 
;   instruction will be in vector mode.

; The 340 display must be in vector mode before starting to display the field.  This
;restriction does not apply when the display is started at BKBEG0.  To select a given
;part of the list for displaying, output a command to the 340 to enter vector mode and
;set the X coordinate properly.  Then, do a BLKO (in interrupt vector) from the
;desired place in the list.  The 340 will stop the display when it goes of the
;edge of the screen and will raise the EDGE FLAG causing a special interrrupt. If
;however, the BLKO counts out, wraparound of the field may be accomplished by
;continuing the display with a new BLKO pointer starting at BKBEG.  Space-War chooses
;the X coordinates in an intelligent manner to cause the star field to shift at
;the specifed rate.


	RADIX 10.

BKBEG0:	PM%ESC\<0_PM%SCS>\NC%PNT,,PT%X\<0&PT%MSK>\NC%VCT
					;[go to point mode with scale zero]
					;[set X to zero, enter vector mode]

BKBEG:
.BYTE 18.
	STAR	8188,-407,2	; 2 CETI
	STAR	8174,-149,2	;30 PISC
	STAR	8159,144,2	;28 PISC
	STAR	8064,-344,2	;105 AQAR
	STAR	8061,28,2	;18 PISC
	STAR	8059,-418,2	;104 AQAR
	STAR	8049,116,2	;17 PISC
	STAR	8010,-489,2	;101 AQAR
	STAR	7988,278,2	;70 PEGS
	STAR	7981,133,2	;10 PISC
	STAR	7975,16,2	; 8 PISC
	STAR	7969,-482,2	;99 AQAR
	STAR	7952,-470,2	;98 AQAR
	STAR	7923,-222,2	;93 AQAR
	STAR	7919,62,2	; 6 PISC
	STAR	7911,-219,2	;91 AQAR
	STAR	7903,-150,2	;90 AQAR
	STAR	7874,-494,2	;88 AQAR
	STAR	7862,202,2	;55 PEGS
	STAR	7849,334,3	;54 PEGS,MARKAB
	STAR	7844,75,2	; 4 PISC
	STAR	7795,189,2	;50 PEGS
	STAR	7790,-372,3	;76 AQAR
	STAR	7779,-185,2	;73 AQAR
	STAR	7761,-321,2	;71 AQAR
	STAR	7747,266,2	;46 PEGS
	STAR	7727,-440,2	;66 AQAR
	STAR	7717,235,3	;42 PEGS
	STAR	7681,-14,2	;62 AQAR
	STAR	7654,-255,2	;57 AQAR
	STAR	7644,-12,3	;55 AQAR
	STAR	7639,96,2	;35 PEGS
	STAR	7624,20,2	;52 AQAR
	STAR	7604,266,2	;31 PEGS
	STAR	7603,-43,2	;48 AQAR
	STAR	7575,-189,2	;43 AQAR
	STAR	7539,130,3	;26 PEGS
	STAR	7515,-327,2	;33 AQAR
	STAR	7513,104,2	;22 PEGS
	STAR	7513,-18,3	;34 AQAR
	STAR	7499,-60,2	;31 AQAR
	STAR	7404,-377,3	;49 CAPR
	STAR	7394,384,2	; 9 PEGS
	STAR	7391,214,3	; 8 PEGS
	STAR	7379,-440,2	;43 CAPR
	STAR	7365,-390,2	;40 CAPR
	STAR	7353,-189,2	;23 AQAR
	STAR	7347,-453,2	;39 CAPR
	STAR	7318,-137,3	;22 AQAR
	STAR	7299,-506,2	;36 CAPR
	STAR	7267,441,2	; 1 PEGS
	STAR	7263,-393,2	;32 CAPR
	STAR	7230,110,2	; 8 EQUL
	STAR	7223,219,2	; 7 EQUL
	STAR	7199,222,2	; 5 EQUL
	STAR	7192,-268,2	;13 AQAR
	STAR	7170,-401,2	;23 CAPR
	STAR	7161,-461,2	;22 CAPR
	STAR	7096,-213,2	; 6 AQAR
	STAR	7068,-123,2	; 3 AQAR
	STAR	7067,-225,2	; 2 AQAR
	STAR	7066,359,2	;12 DLPH
	STAR	7047,335,2	;11 DLPH
	STAR	7026,354,2	; 9 DLPH
	STAR	7020,475,2	;29 VULP
	STAR	7015,-33,2	;71 AQIL
	STAR	7014,324,3	; 6 DLPH
	STAR	7001,326,2	; 4 DLPH
	STAR	6988,250,2	; 2 DLPH
	STAR	6958,-413,2	;11 CAPR
	STAR	6914,-344,3	; 9 CAPR
	STAR	6913,-297,2	; 8 CAPR
	STAR	6898,-292,2	; 6 CAPR
	STAR	6896,-292,2	; 5 CAPR
	STAR	6882,339,2	;67 AQIL
	STAR	6862,-25,3	;65 AQIL
	STAR	6794,437,3	;12 SGTE
	STAR	6772,140,2	;60 AQIL
	STAR	6766,187,2	;59 AQIL
	STAR	6755,17,2	;55 AQIL
	STAR	6747,196,6	;53 AQIL,ALTAIR
	STAR	6739,430,2	; 8 SGTE
	STAR	6730,416,2	; 7 SGTE
	STAR	6721,236,3	;50 AQIL
	STAR	6693,393,2	; 6 SGTE
	STAR	6688,405,2	; 5 SGTE
	STAR	6665,-35,2	;41 AQIL
	STAR	6657,445,2	; 9 VULP
	STAR	6651,163,2	;38 AQIL
	STAR	6607,3,2	;32 AQIL
	STAR	6602,66,3	;30 AQIL
	STAR	6576,-368,2	;46 SGTR
	STAR	6576,-410,2	;44 SGTR
	STAR	6553,483,2	; 1 VULP
	STAR	6507,-482,3	;41 SGTR
	STAR	6491,-115,3	;16 AQIL
	STAR	6490,312,3	;17 AQIL
	STAR	6478,-498,2	;39 SGTR
	STAR	6465,-134,2	;12 AQIL
	STAR	6457,340,2	;13 AQIL
	STAR	6439,-483,3	;37 SGTR
	STAR	6436,93,2	;63 SERP
	STAR	6386,411,2	;111 HERC
	STAR	6382,-110,2	;BE SCUT
	STAR	6379,465,2	;110 HERC
	STAR	6313,-189,2	;AL SCUT
	STAR	6278,-333,2	;GA SCUT
	STAR	6255,494,2	;109 HERC
	STAR	6254,-469,2	;21 SGTR
	STAR	6247,-204,2	;XI SCUT
	STAR	6236,-66,3	;58 SERP
	STAR	6235,499,2	;106 HERC
	STAR	6234,76,2	;74 OPHI
	STAR	6188,-480,2	;13 SGTR
	STAR	6170,473,2	;102 HERC
	STAR	6159,217,3	;72 OPHI
	STAR	6158,198,2	;71 OPHI
	STAR	6146,57,2	;70 OPHI
	STAR	6125,30,2	;68 OPHI
	STAR	6119,67,2	;67 OPHI
	STAR	6119,381,2	;93 HERC
	STAR	6117,99,2	;66 OPHI
	STAR	6117,-84,2	;57 SERP
	STAR	6107,-222,3	;64 OPHI
	STAR	6047,63,3	;62 OPHI
	STAR	6016,-492,2	;58 OPHI
	STAR	6006,-292,2	;56 SERP
	STAR	5987,-183,2	;57 OPHI
	STAR	5984,-349,3	;55 SERP
	STAR	5975,288,5	;55 OPHI
	STAR	5925,96,2	;49 OPHI
	STAR	5924,-114,2	;
	STAR	5889,-290,2	;53 SERP
	STAR	5888,-478,2	;40 OPHI
	STAR	5868,-8,2	;41 OPHI
	STAR	5860,330,3	;64 HERC
	STAR	5828,-355,3	;35 OPHI
	STAR	5807,293,2	;60 HERC
	STAR	5763,217,2	;27 OPHI
	STAR	5742,235,2	;25 OPHI
	STAR	5713,-241,2	;20 OPHI
	STAR	5641,-236,3	;13 OPHI
	STAR	5620,266,2	;29 HERC
	STAR	5610,-484,2	; 9 OPHI
	STAR	5609,50,2	;10 OPHI
	STAR	5609,494,3	;27 HERC
	STAR	5606,-373,2	; 8 OPHI
	STAR	5589,-186,2	; 3 OPHI
	STAR	5582,-415,2	; 7 OPHI
	STAR	5580,325,2	;24 HERC
	STAR	5565,-451,2	; 4 OPHI
	STAR	5561,441,2	;20 HERC
	STAR	5558,29,2	;50 SERP
	STAR	5536,-101,3	; 2 OPHI
	STAR	5513,-78,3	; 1 OPHI
	STAR	5499,-223,2	;15 SCOR
	STAR	5497,-437,2	;14 SCOR
	STAR	5470,-469,2	;10 SCOR
	STAR	5467,-464,2	; 9 SCOR
	STAR	5459,-445,3	; 8 SCOR
	STAR	5455,-253,2	;XI SCOR
	STAR	5430,-508,3	; 7 SCOR
	STAR	5419,-318,2	;48 LIBR
	STAR	5415,364,2	;41 SERP
	STAR	5394,-374,2	;46 LIBR
	STAR	5387,484,2	;38 SERP
	STAR	5381,109,2	;37 SERP
	STAR	5373,-71,3	;32 SERP
	STAR	5372,420,2	;35 SERP
	STAR	5357,175,2	;27 SERP
	STAR	5357,358,3	;28 SERP
	STAR	5344,153,3	;24 SERP
	STAR	5331,455,2	;21 SERP
	STAR	5326,-440,2	;43 LIBR
	STAR	5291,247,2	;13 SERP
	STAR	5290,-329,2	;38 LIBR
	STAR	5283,-221,2	;37 LIBR
	STAR	5186,-205,3	;27 LIBR
	STAR	5157,-442,2	;24 LIBR
	STAR	5108,57,2	;110 VIRG
	STAR	5074,-90,2	;16 LIBR
	STAR	5045,444,2	;37 BOOT
	STAR	5037,-356,3	; 9 LIBR
	STAR	5013,53,2	;109 VIRG
	STAR	5009,396,2	;35 BOOT
	STAR	4994,-119,2	;107 VIRG
	STAR	4986,322,2	;30 BOOT
	STAR	4984,383,2	;29 BOOT
	STAR	4910,-41,2	;105 VIRG
	STAR	4864,382,2	;20 BOOT
	STAR	4857,-294,2	;100 VIRG
	STAR	4842,448,6	;16 BOOT,ARCTURUS
	STAR	4840,-126,2	;99 VIRG
	STAR	4822,-223,2	;98 VIRG
	STAR	4820,66,2	;
	STAR	4759,46,2	;93 VIRG
	STAR	4721,430,3	; 8 BOOT
	STAR	4691,371,2	; 5 BOOT
	STAR	4679,409,2	; 4 BOOT
	STAR	4606,-2,3	;79 VIRG
	STAR	4603,95,2	;78 VIRG
	STAR	4590,-131,2	;74 VIRG
	STAR	4563,-352,2	;69 VIRG
	STAR	4551,-242,6	;67 VIRG,SPICA
	STAR	4512,-404,2	;61 VIRG
	STAR	4466,411,2	;42 COMA
	STAR	4465,-114,2	;51 VIRG
	STAR	4421,262,3	;47 VIRG
	STAR	4403,409,2	;36 COMA
	STAR	4384,90,3	;43 VIRG
	STAR	4376,-205,2	;40 VIRG
	STAR	4305,245,2	;30 VIRG
	STAR	4304,-21,3	;29 VIRG
	STAR	4290,-170,2	;26 VIRG
	STAR	4249,-356,2	; 8 CORV
	STAR	4236,-363,3	; 7 CORV
	STAR	4185,418,2	;11 COMA
	STAR	4180,-3,2	;15 VIRG
	STAR	4157,-387,3	; 4 CORV
	STAR	4124,-502,3	; 2 CORV
	STAR	4097,211,2	; 9 VIRG
	STAR	4072,163,2	; 8 VIRG
	STAR	4013,53,2	; 5 VIRG
	STAR	4005,344,5	;94 LEON,DENEBOLA
	STAR	3998,473,2	;93 LEON
	STAR	3986,161,2	; 3 VIRG
	STAR	3981,-405,2	;27 CRAT
	STAR	3936,-6,2	;91 LEON
	STAR	3935,-211,2	;21 CRAT
	STAR	3868,-390,2	;15 CRAT
	STAR	3861,252,2	;78 LEON
	STAR	3846,150,2	;77 LEON
	STAR	3836,-324,2	;12 CRAT
	STAR	3821,-71,2	;74 LEON
	STAR	3806,364,3	;10 LEON
	STAR	3805,479,3	;68 LEON
	STAR	3793,-507,2	;11 CRAT
	STAR	3754,179,2	;63 LEON
	STAR	3738,471,2	;60 LEON
	STAR	3736,-44,2	;61 LEON
	STAR	3726,-404,2	;AL CRAT
	STAR	3668,-357,3	;NU HYDA
	STAR	3570,223,2	;47 LEON
	STAR	3557,-3,2	;30 SEXT
	STAR	3534,-372,2	;42 HYDA
	STAR	3496,463,3	;41 LEON,ALGIEBA
	STAR	3495,455,2	;40 LEON
	STAR	3446,-270,2	;41 HYDA
	STAR	3431,283,6	;32 LEON,REGULUS
	STAR	3429,3,2	;15 SEXT
	STAR	3428,239,2	;31 LEON
	STAR	3424,393,3	;30 LEON
	STAR	3415,-286,2	;40 HYDA
	STAR	3385,194,2	;29 LEON
	STAR	3338,-327,2	;39 HYDA
	STAR	3276,236,2	;14 LEON
	STAR	3274,-316,2	;38 HYDA
	STAR	3270,-16,2	;35 HYDA
	STAR	3261,116,2	;
	STAR	3225,-17,2	;32 HYDA
	STAR	3209,-53,2	;31 HYDA
	STAR	3201,-187,5	;30 HYDA,ALPHARD
	STAR	3161,-208,2	;27 HYDA
	STAR	3157,-263,2	;26 HYDA
	STAR	3124,62,2	;22 HYDA
	STAR	3032,279,2	;65 CANC
	STAR	3016,144,3	;16 HYDA
	STAR	2976,141,2	;13 HYDA
	STAR	2968,-300,2	;12 HYDA
	STAR	2967,154,3	;11 HYDA
	STAR	2953,421,2	;47 CANC
	STAR	2951,-156,2	;
	STAR	2947,85,2	; 7 HYDA
	STAR	2944,497,2	;43 CANC
	STAR	2942,-355,2	; 9 HYDA
	STAR	2921,84,2	; 5 HYDA
	STAR	2915,138,2	; 4 HYDA
	STAR	2848,-82,2	;
	STAR	2794,216,2	;17 CANC
	STAR	2768,-288,2	;19 PUPP
	STAR	2757,-431,2	;16 PUPP
	STAR	2751,-61,2	;29 MONO
	STAR	2714,60,2	;
	STAR	2709,-25,2	;28 MONO
	STAR	2704,-412,2	;
	STAR	2597,-212,2	;26 MONO
	STAR	2583,125,6	;10 CMIN,PROCYON
	STAR	2559,-503,2	;
	STAR	2527,278,2	; 6 CMIN
	STAR	2519,208,2	; 4 CMIN
	STAR	2513,193,3	; 3 CMIN
	STAR	2491,-429,2	;
	STAR	2470,504,3	;55 GEMI
	STAR	2460,380,3	;54 GEMI
	STAR	2428,-8,2	;22 MONO
	STAR	2385,-352,2	;23 CMAJ
	STAR	2379,471,2	;43 GEMI
	STAR	2378,-93,2	;19 MONO
	STAR	2342,-385,2	;20 CMAJ
	STAR	2340,-456,2	;19 CMAJ
	STAR	2330,-271,2	;14 CMAJ
	STAR	2328,-457,2	;15 CMAJ
	STAR	2327,303,2	;38 GEMI
	STAR	2291,57,2	;18 MONO
	STAR	2280,-377,7	; 9 CMAJ,SIRIUS
	STAR	2274,296,3	;31 GEMI
	STAR	2266,303,2	;30 GEMI
	STAR	2250,227,2	;15 MONO
	STAR	2245,-320,2	;
	STAR	2239,-413,2	; 8 CMAJ
	STAR	2232,-436,2	; 7 CMAJ
	STAR	2230,375,5	;24 GEMI
	STAR	2204,168,2	;13 MONO
	STAR	2184,-159,2	;11 MONO
	STAR	2179,-107,2	;10 MONO
	STAR	2179,462,2	;18 GEMI
	STAR	2153,106,2	; 8 MONO
	STAR	2152,-407,5	; 2 CMAJ
	STAR	2112,-311,2	;
	STAR	2105,-142,2	; 5 MONO
	STAR	2084,324,2	;70 ORIO
	STAR	2084,368,2	;69 ORIO
	STAR	2059,336,2	;67 ORIO
	STAR	2057,-340,2	;18 LEPS
	STAR	2037,458,2	;62 ORIO
	STAR	2032,-241,2	; 3 MONO
	STAR	2030,220,2	;61 ORIO
	STAR	2020,-70,2	;
	STAR	2002,-323,2	;16 LEPS
	STAR	1990,168,6	;58 ORIO,BETELGEUZE
	STAR	1982,461,2	;54 ORIO
	STAR	1974,-475,2	;15 LEPS
	STAR	1957,287,2	;134 TAUR
	STAR	1951,-221,5	;53 ORIO
	STAR	1948,-338,3	;14 LEPS
	STAR	1936,-511,2	;13 LEPS
	STAR	1910,-46,5	;50 ORIO
	STAR	1909,375,2	;126 TAUR
	STAR	1900,-165,2	;49 ORIO
	STAR	1900,93,2	;47 ORIO
	STAR	1899,-60,2	;48 ORIO
	STAR	1887,480,3	;123 TAUR
	STAR	1885,210,2	;40 ORIO
	STAR	1884,-29,5	;46 ORIO
	STAR	1880,-112,2	;42 ORIO
	STAR	1880,-136,3	;44 ORIO
	STAR	1878,-138,2	;
	STAR	1875,225,3	;39 ORIO
	STAR	1874,214,2	;37 ORIO
	STAR	1868,-407,3	;11 LEPS
	STAR	1861,-168,2	;36 ORIO
	STAR	1860,-8,3	;34 ORIO
	STAR	1857,421,2	;119 TAUR
	STAR	1851,134,2	;32 ORIO
	STAR	1843,-474,3	; 9 LEPS
	STAR	1830,69,2	;30 ORIO
	STAR	1830,497,2	;114 TAUR
	STAR	1819,143,5	;24 ORIO,BELLATRIX
	STAR	1818,40,2	;25 ORIO
	STAR	1817,-57,3	;28 ORIO
	STAR	1816,-180,2	;29 ORIO
	STAR	1807,79,2	;23 ORIO
	STAR	1801,-11,2	;22 ORIO
	STAR	1799,-486,2	;
	STAR	1792,-302,2	; 6 LEPS
	STAR	1779,-158,3	;20 ORIO
	STAR	1762,-189,6	;19 ORIO,RIGEL
	STAR	1756,-297,2	; 4 LEPS
	STAR	1755,-371,3	; 5 LEPS
	STAR	1753,63,2	;17 ORIO
	STAR	1750,-273,2	; 3 LEPS
	STAR	1732,-202,2	;69 ERID
	STAR	1729,352,2	;15 ORIO
	STAR	1723,-119,3	;67 ERID
	STAR	1700,347,2	;11 ORIO
	STAR	1690,488,2	;102 TAUR
	STAR	1690,-460,2	;
	STAR	1687,-167,2	;65 ERID
	STAR	1680,-289,2	;64 ERID
	STAR	1669,36,2	;10 ORIO
	STAR	1654,304,2	; 9 ORIO
	STAR	1646,228,2	; 7 ORIO
	STAR	1644,52,3	; 8 ORIO
	STAR	1638,-128,2	;61 ERID
	STAR	1626,124,2	; 3 ORIO
	STAR	1622,199,2	; 2 ORIO
	STAR	1618,154,3	; 1 ORIO
	STAR	1596,-78,2	;57 ERID
	STAR	1571,-452,2	;54 ERID
	STAR	1557,-330,2	;53 ERID
	STAR	1556,358,2	;92 TAUR
	STAR	1551,280,2	;90 TAUR
	STAR	1544,-81,2	;48 ERID
	STAR	1537,226,2	;88 TAUR
	STAR	1537,371,6	;87 TAUR,ALDEBARAN
	STAR	1526,333,2	;86 TAUR
	STAR	1518,-6,2	;45 ERID
	STAR	1507,364,2	;
	STAR	1496,356,3	;78 TAUR
	STAR	1495,358,2	;77 TAUR
	STAR	1495,432,3	;74 TAUR
	STAR	1485,330,2	;73 TAUR
	STAR	1483,350,2	;71 TAUR
	STAR	1477,403,2	;68 TAUR
	STAR	1476,502,2	;65 TAUR
	STAR	1470,392,2	;64 TAUR
	STAR	1463,394,2	;61 TAUR
	STAR	1446,350,2	;54 TAUR
	STAR	1430,463,2	;50 TAUR
	STAR	1426,-178,2	;40 ERID
	STAR	1423,197,2	;49 TAUR
	STAR	1414,205,2	;47 TAUR
	STAR	1405,-162,2	;38 ERID
	STAR	1358,497,2	;37 TAUR
	STAR	1353,130,2	;38 TAUR
	STAR	1338,278,2	;35 TAUR
	STAR	1328,-314,3	;34 ERID
	STAR	1304,-74,2	;32 ERID
	STAR	1260,-283,2	;26 ERID
	STAR	1243,-230,3	;23 ERID
	STAR	1205,2,2	;10 TAUR
	STAR	1191,-500,2	;19 ERID
	STAR	1185,-223,2	;18 ERID
	STAR	1170,-123,2	;17 ERID
	STAR	1168,287,2	; 5 TAUR
	STAR	1148,214,2	; 2 TAUR
	STAR	1135,198,2	; 1 TAUR
	STAR	1110,-503,2	;16 ERID
	STAR	1104,68,2	;96 CETI
	STAR	1087,-209,2	;13 ERID
	STAR	1076,470,2	;58 ARIE
	STAR	1058,440,2	;57 ARIE
	STAR	1007,84,3	;92 CETI
	STAR	992,194,2	;91 CETI
	STAR	976,-212,2	; 3 ERID
	STAR	947,-487,2	; 2 ERID
	STAR	913,-432,2	; 1 ERID
	STAR	908,221,2	;87 CETI
	STAR	907,-340,2	;89 CETI
	STAR	900,64,3	;86 CETI
	STAR	878,-2,2	;82 CETI
	STAR	838,-357,2	;76 CETI
	STAR	813,182,2	;73 CETI
	STAR	803,-290,2	;72 CETI
	STAR	764,-78,3	;68 CETI,MIRA
	STAR	727,191,2	;65 CETI
	STAR	665,52,2	;113 PISC
	STAR	656,-491,2	;59 CETI
	STAR	621,462,3	; 6 ARIE
	STAR	617,61,2	;14 PISC
	STAR	615,428,2	; 5 ARIE
	STAR	606,-247,2	;55 CETI
	STAR	595,-255,2	;53 CETI
	STAR	570,197,2	;110 PISC
	STAR	566,-375,3	;52 CETI
	STAR	548,113,2	;106 PISC
	STAR	490,338,3	;99 PISC
	STAR	450,-198,2	;45 CETI
	STAR	376,467,2	;84 PISC
	STAR	362,-244,3	;31 CETI
	STAR	329,167,2	;71 PISC
	STAR	273,-38,2	;20 CETI
	STAR	248,160,2	;63 PISC
	STAR	223,-254,2	;17 CETI
	STAR	150,0,0		;
	STAR	82,-214,2	; 8 CETI
	STAR	54,-443,2	; 7 CETI
	STAR	54,447,2	;89 PEGS
	STAR	46,333,3	;88 PEGS,ALGENIB
	STAR	1,-143,2	;33 PISC

.WALGN					;force to a word boundary
.BYTE					;go back to assembling full-words

BKEND:

	RADIX 8.

	END GO
