diff --git a/Makefile b/Makefile index ab73af3e..9d4c2661 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,8 @@ include conf/network SRC = system syseng sysen1 sysen2 sysen3 sysnet kshack dragon channa \ midas _teco_ emacs emacs1 rms klh syshst sra mrc ksc eak gren \ bawden _mail_ l lisp libdoc comlap lspsrc nilcom rwk chprog rg \ - inquir acount gz sys decsys ecc alan sail kcc kcc_sy c games archy dcp + inquir acount gz sys decsys ecc alan sail kcc kcc_sy c games archy dcp \ + spcwar DOC = info _info_ sysdoc sysnet syshst kshack _teco_ emacs emacs1 c kcc chprog BIN = sys2 device emacs _teco_ lisp liblsp alan inquir sail comlap c decsys \ moon diff --git a/README.md b/README.md index 70e81d8f..0cfe5420 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,7 @@ A list of [known ITS machines](doc/machines.md). - SENSOR, sends censor. - SENVER, Chaosnet SEND server. - SN, snoop terminal. + - SPCWAR, Spacewar game. - SPELL, ESPELL spell checker. - SRCCOM, Compares/merges source files, compares binary files. - STINK, linker. diff --git a/build/build.tcl b/build/build.tcl index a7c66391..cf0bb92e 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -1119,6 +1119,27 @@ respond "with ^C" "DSPLY==0\r" respond "\n" "CHEOPS==0\r\003" expect ":KILL" +# Spacewar, standalone +respond "*" ":midas /t .;@ spcwar_spcwar; newwar\r" +respond "with ^C" "APR==0\r" +respond "\n" "PI==4\r" +respond "\n" "DIS==130\r\003" +respond "ITS version" "NO\r" +respond "interrupt" "NO\r" +respond "ships" "\r" +respond "designs" "\r" +respond "suns" "\r" +respond "recording" "\r" +expect ":KILL" + +# Spacewar, timesharing +respond "*" ":midas games;ts spcwar_spcwar; newwar\r" +respond "ITS version" "YES\r" +respond "ships" "\r" +respond "designs" "\r" +respond "suns" "\r" +expect ":KILL" + # ten50 respond "*" ":midas sys3;ts ten50_mrc; ten50\r" expect ":KILL" diff --git a/src/spcwar/340def.4 b/src/spcwar/340def.4 new file mode 100644 index 00000000..bce06a00 --- /dev/null +++ b/src/spcwar/340def.4 @@ -0,0 +1,95 @@ + SUBTTL 340 Display Definitions + +;Command Operation Codes + +;----- Valid in Any Mode +GTOPRM==BIT2.9 ;this command is guarenteed to place the display + ;into parameter mode regardless of the current mode + +;----- Valid in Parameter and Point Commands +PARM== 0 ;next command is parameter mode +POINT== BIT2.5 ; " " " point " +VECT== BIT2.7 ; " " " vector " +VECTC== BIT2.7+BIT2.5 ; " " " vector-continue mode +CHAR== BIT2.6+BIT2.5 ; " " " character mode +INCR== BIT2.7+BIT2.6 ; " " " increment " + +;----- Valid in Vector, Vector-Continue, and Increment Modes +ESCAPE==BIT2.9 ;return display to parameter mode + + +;Specific Bits/Values for Different Command Types + +;----- Parameter Mode +DISHLT== ;stop this display list + +;----- Point Mode +DISPNT==BIT2.2 ;intensify the current point + +;----- Vector and Vector-Continue Modes +DISVCT==BIT2.8 ;make this vector visible +NEGX== BIT1.8 ;if on, X shift is negative +NEGY== BIT2.7 ;if on, Y shift is negative + +;----- Character Mode (Any Case) +CHRESC==37 ;escape from character mode +CHRUC== 35 ;shift to upper-case +CHRLC== 36 ; " " lower-case +CHRLF== 33 ;line-feed +CHRCR== 34 ;carriage-return +CHRSP== 40 ;space + +;Macros to Generate Display Commands + +;SCALE(VALUE) +; Function: +; Generates a parameter mode command to set the display scaling factor. +; Inputs: +; VALUE: The scaling factor as a value from 0 to 3. + +DEFINE SCALE (VALUE +_4>TERMIN + + +;INTSTY(VALUE) +; Function: +; Generates a parameter mode display command to set the display intesity. +; Inputs: +; VALUE: The intensity as a value from 0 through 7. + +DEFINE INTSTY (VALUE +>TERMIN + + +;SETY(VALUE) +; Function: +; Generates a point mode command to set the Y ordinate. +; Inputs: +; VALUE: The Y ordinate as a value from 0 through 1777(8). + +DEFINE SETY (VALUE +>TERMIN + + +;SETX(VALUE) +; Function: +; Generates a point mode command to set the X ordinate. +; Inputs: +; VALUE: The X ordinate as a value from 0 through 1777(8). + +DEFINE SETX (VALUE +TERMIN + + +;VECTOR(XVALUE,YVALUE) +; Function: +; Generates a vector or vector-continue command to create a vector. +; Inputs: +; XVALUE: The magnitude (positive) of the X shift. It is in the range 0 +; through 177(8). +; YVALUE: The magnitude of the Y shift. It is treated identically to XVALUE. + +DEFINE VECTOR (XVALUE,YVALUE +<+<_8.>>TERMIN + + \ No newline at end of file diff --git a/src/spcwar/acsdef.1 b/src/spcwar/acsdef.1 new file mode 100644 index 00000000..e95ec162 --- /dev/null +++ b/src/spcwar/acsdef.1 @@ -0,0 +1,50 @@ + + SUBTTL Accumuator Definitions + +FLGS=0 ;flag word for bit testing + +P=1 ;PDL pointer +MBP=2 ;PDL pointer for display buffer being filled + +IDX1=3 ;index of objects currently being processed +IDX2=4 + +A=5 ;temporaries -- other names defined below +B=6 +C=7 +D=10 +T1=11 +T2=12 +T3=13 +T4=14 +T5=15 + +DCP=16 ;display chain pointer (wired) +DLP=17 ;BLKO pointer of list being output (wired) + + +; Other names used for the AC's + +TYP1==C ;types of objects in IDX1 and IDX2 +TYP2==D + +X==T1 ;X/Y coordinates built by DISPNT macro +Y==T2 +PTCMND==T4 ;point command placed here by DISPNT + +SDLP==T3 ;PDL pointer for building sun display + +.XCREF FLGS,P,MBP,IDX1,IDX2,A,B,C,D,T1,T2,T3,T4,T5,DCP,DLP +.XREF X,Y,PTCMND,SDLP + + +; Accumulator names used in older code (CREF'ed to find and eliminate) + +F==FLGS +T==T1 +TT==T2 +MP1==IDX1 +MP2==IDX2 +R==T3 +XFLAG==T4 +S==T5 diff --git a/src/spcwar/arith.1 b/src/spcwar/arith.1 new file mode 100644 index 00000000..059d0245 --- /dev/null +++ b/src/spcwar/arith.1 @@ -0,0 +1,89 @@ + + SUBTTL Arithmentic Mode Conversion Macros + +;SPCWAR uses three modes of arithmetic - integers (fixed), floating-point, and +;fractionals. +; +;Integer and floating-point numbers are the standard hardware representations. +; +;A fractional number is represented as an integer with a conceptual binary +;point (ala FIXED BINARY in PL/1). The binary point is to the left of bit +;2.9 of the value. That is, the left half of the word is the integer part, +;and the right half is the fraction. + + +;FLOAT AC +; Function: +; Converts an integer to a floating point value. The integer must be less than +; 27. bits. +; Inputs: +; AC: The accumulator containing the number. The result will be in placed here. + +DEFINE FLOAT AC + FSC AC,233 +IFDEF $PDP6, FADR AC,[0.0] ;PDP-6 FSC does not normalize. +TERMIN + + +;FIX AC +; Function: +; Convert a floating point number (positive or negative) to an integer. +; Inputs: +; AC: The accumulator containing the floating value. +; Outputs: +; AC+1: The result is placed in this accumulator. The contents of AC are lost. + +DEFINE FIX AC + MULI AC,400 + TSC AC,AC + ASH AC+1,-200-35.(AC) +TERMIN + + +;FIXP AC +; Function: +; This macro is identical to FIX. The only difference is that the value too convert +; must be positive. + +DEFINE FIXP AC + MULI AC,400 + ASH AC+1,-200-35.(AC) +TERMIN + + +;FRACT AC +; Function: +; Convert a floating-point number to a fractional value. The input may have any sign. +; The calling sequence and results are identical to FIX above. + +DEFINE FRACT AC + MULI AC,400 + TSC AC,AC + ASH AC+1,-200-17.(AC) +TERMIN + + +;FRACTP AC +; Function: +; This macro is identical to FRACT above, but the input must be positive. + +DEFINE FRACTP AC + MULI AC,400 + ASH AC+1,-200,-17.(AC) +TERMIN + + +;FRCSCL AC,SCALE +; Function: +; Convert a floating-point number to a fractional value with an arbitrary binary point. +; Inputs: +; AC: See FIX above. +; SCALE: The result will have SCALE bits of fraction in its representation. +; Outputs: +; See FIX above. + +DEFINE FRCSCL AC,SCALE + MULI AC,400 + TSC AC,AC + ASH AC+1,-200-35.+SCALE(AC) +TERMIN diff --git a/src/spcwar/frgmts.10 b/src/spcwar/frgmts.10 new file mode 100644 index 00000000..737c4fbb --- /dev/null +++ b/src/spcwar/frgmts.10 @@ -0,0 +1,101 @@ + SUBTTL Ship Fragments Defintion + +;Macros + +;ICBYTE VALUE +; Function: +; Internal macro used to generate a fragment display list. + +DEFINE ICBYTE VALUE +%%BYTS==%%BYTS+1 +%%WORD==%%WORD+_<16.-4*%%BYTS> +IFE %%BYTS-4,{ + %%WORD+%%DISP +%%WORD==0 ? %%BYTS==0 +} +TERMIN + + +;FRAGMENT [MOVES] +; Function: +; Generate the display list for a fragment. The form of the frgament is determined +; by the list MOVES. A display-list pointer for the list is left in the FRGMTS +; array. The first worf of the list is a parameter mode command (RH) to set the +; intensity and scale; the second word is a command to set the location of the +; fragment (Y in LH, X in RH). +; Inputs: +; MOVES: Controls the appearence of this fragment. It is composed of a sequence +; of symbols which are interpreted as follows: +; ON: Make points visible +; OFF: Make points invisible +; U: Move up one point +; UR: Move up and to the right one point +; R: Move right one point +; DR: Move down and right one point +; D: Move down one point +; DL: Move down and left one point +; L: Move left one point +; UL: Move up and left one point + +DEFINE FRAGMENT MOVES +IF1, $FRGMTS==$FRGMTS+1 + +%FRLOC==. +%%DISP==0 +%%WORD==0 +%%BYTS==0 + +.BYTE 18. + GTOPRM + SCALE(0)+INTSTY(0)+POINT + SETY(0)+POINT + SETX(0)+INCR + +IRPS MOVE,,[MOVES] + IFSE [MOVE][ON] %%DISP==200000 + IFSE [MOVE][OFF] %%DISP==0 + IFSE [MOVE][U] ICBYTE 02' + IFSE [MOVE][UR] ICBYTE 12' + IFSE [MOVE][R] ICBYTE 10' + IFSE [MOVE][DR] ICBYTE 13' + IFSE [MOVE][D] ICBYTE 03' + IFSE [MOVE][DL] ICBYTE 17' + IFSE [MOVE][L] ICBYTE 14' + IFSE [MOVE][UL] ICBYTE 16' +TERMIN + +IFN %%BYTS, %%WORD + ESCAPE + +.WALGN +.BYTE + +%FRLTH==.-%FRLOC +%%.==. + +IF2,{ +LOC FRGMTS+%FRGMTS + -%FRLTH,,%FRLOC-1 + +LOC %%. +%FRGMTS==%FRGMTS+1 +} +TERMIN + + +IF1,{ + $FRGMTS==0 ;have yet to define any fragments + %FRGMTS==0 +} + +;Definition of The Fragments + +FRAGMENT [U,U,U,U,ON DR,DR,DR,DR + DL,DL,DL,DL UL,UL,UL,UL + UR,UR,UR,UR] + + +;Fragment Defintions Tables + +FRGMTS: BLOCK $FRGMTS ;contains display pointers for fragments + \ No newline at end of file diff --git a/src/spcwar/newwar.164 b/src/spcwar/newwar.164 new file mode 100644 index 00000000..67428c79 --- /dev/null +++ b/src/spcwar/newwar.164 @@ -0,0 +1,4013 @@ + +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 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== ; 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_<*9.+> +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++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++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: -,, ;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] + ;,, + 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 + 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 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, -,, + 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,[-,,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 VSLSSL + GMSCW ;IF DIFF X SIGN AND VSLSSL + + ;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 VALPI + CCWENB(MP2) ;IF POS AND PI + CWENB(MP2)] ;IF NEG AND + 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 01, 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 ,[ PT%NOP,,PT%NOP +] +TORDSE: PM%HLT +TDISPT: -,,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\\NC%PNT + PT%Y\PT%DSP\<&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' 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 + +; 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 + +; 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 + \ No newline at end of file diff --git a/src/spcwar/setmac.12 b/src/spcwar/setmac.12 new file mode 100644 index 00000000..fea4cdf5 Binary files /dev/null and b/src/spcwar/setmac.12 differ diff --git a/src/spcwar/spcwar.163 b/src/spcwar/spcwar.163 new file mode 100644 index 00000000..9315e731 --- /dev/null +++ b/src/spcwar/spcwar.163 @@ -0,0 +1,3991 @@ + +TITLE MIT-AI PDP-6/10 Space-War + +.MLLIT==1 + +IF2,{PRINTC "This is version " ? .TYO6 .FNAM2 ? PRINTC " +"} + + 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 deterined. + +; 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 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== ; 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_<*9.+> +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++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++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: -,, ;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] + ;,, + 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 + 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 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, -,, + 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,[-,,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 VSLSSL + GMSCW ;IF DIFF X SIGN AND VSLSSL + + ;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 VALPI + CCWENB(MP2) ;IF POS AND PI + CWENB(MP2)] ;IF NEG AND + 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 01, 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 ,[ PT%NOP,,PT%NOP +] +TORDSE: PM%HLT +TDISPT: -,,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\\NC%PNT + PT%Y\PT%DSP\<&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' 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 + +; 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 + +; 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 + \ No newline at end of file diff --git a/src/spcwar/spcwar.164 b/src/spcwar/spcwar.164 new file mode 100644 index 00000000..392d7048 --- /dev/null +++ b/src/spcwar/spcwar.164 @@ -0,0 +1,3996 @@ + +TITLE MIT-AI PDP-6/10 Space-War + +.MLLIT==1 + +IF2,{PRINTC "This is version " ? .TYO6 .FNAM2 ? PRINTC " +"} + + 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 deterined. + +; 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 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== ; 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_<*9.+> +BIT!C==1_<35.-C> +TERMIN + + +; Start 340 display + +IFE $ITS,[ +APR==0 +PI==4 +DIS==130 +NOSYMS +RIM10 +DEFINE DSTART AC ;PDP-6 version + MOVE DL,DISLST + MOVE DP,[-1,,[0]-1] ;causes immediate interrupt + CONO DIS,D%INIT++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++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: -,, ;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] + ;,, + 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 + 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 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, -,, + 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,[-,,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 VSLSSL + GMSCW ;IF DIFF X SIGN AND VSLSSL + + ;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 VALPI + CCWENB(MP2) ;IF POS AND PI + CWENB(MP2)] ;IF NEG AND + 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 01, 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 ,[ PT%NOP,,PT%NOP +] +TORDSE: PM%HLT +TDISPT: -,,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\\NC%PNT + PT%Y\PT%DSP\<&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' 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 + +; 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 + +; 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 + \ No newline at end of file diff --git a/src/spcwar/tvwar.20 b/src/spcwar/tvwar.20 new file mode 100644 index 00000000..a275fa9c --- /dev/null +++ b/src/spcwar/tvwar.20 @@ -0,0 +1,897 @@ + TITLE SWR--SPACE WAR FOR TVS + +A=1 ;SUN BEING CONSIDERED +N=2 ;SHIP BEING CONSIDERED +X=3 ;POSITION +XT=4 +Y=5 +YT=6 +T1=10 ;TEMPORARIES +T2=11 +TT=12 +T3=13 +T4=14 +T5=15 +D=16 +SP=17 ;STACK POINTER +IN=1 ;INPUT CHANNEL +TYO=3 ;OUTPUT CHANNEL +TVBFR=24000 ;TOP OF TV +NDIREC==100 +INCH==2 ;INPUT CHNL FOR DISK +MAXSHP==3 +MAXSUN==2 +TORP==1 +MAXOBJ==600 + +LOC 42 + JSR TSINT ;OLD-STYLE INTERRUPT HANDLER IN THIS LOCATION. + +LOC 100 +ST: .OPEN IN,OPNIN ;TTY INPUT, NO-WAIT MODE + .VALUE + .OPEN TYO,OPNOUT ;TTY OUTPUT, 3 LINE ECHO AREA + .VALUE + .CALL TVSCRN ;TV BUFFER MAP + .VALUE + .CALL INSHIP ;OPEN THE DISK AND READ IN THE SHIP PATTERNS + .VALUE [ASCIZ/:NO SHIP FILES/] + .IOT INCH,PNTR + .CLOSE INCH, + .CALL INSINE ;OPEN THE DISK AND READ IN THE SINE WAVE + .VALUE [ASCIZ/:NO SINE WAVE FILE/] + .IOT INCH,PNTR1 + .CLOSE INCH, + .RTIME TT, ;INITIALIZE THE RANDOM NUMBER + MOVEM TT,RANNUM + MOVE TT,TVBFR+20000 ;GET TV ALU + MOVEM TT,TVALU + +RESTRT: MOVE TT,TVALU + MOVEM TT,TVBFR+20000 ;RESTORE TV ALU TO ORIGINAL + HRRZI TT,442.*18.-1 ;CLEAR THE SCREEN + SETZM TVBFR(TT) + SOJG TT,.-1 + HRLZI TT,22000 ;TV SCREEN INTO XOR MODE + XORM TT,TVBFR+20000 +NEWGAM: MOVEI SP,STACK + SETZM OBJLEN + SKIPG N,NSHIP + JRST NOSHPS +RANL: SETZM SWITCH-1(N) + SKIPN RANPOS + JRST NORAN + PUSHJ SP,RAND + MOVE X,TT + PUSHJ SP,RAND + MOVE Y,TT + PUSHJ SP,RAND + MOVE XT,TT + PUSHJ SP,RAND + MOVE YT,TT + ANDI X,77777 + ANDI Y,77777 + ASH XT,-34 + ASH YT,-34 + PUSHJ SP,BORDER + PUSHJ SP,RAND + ANDI TT,777 + JRST RANSTR +NORAN: MOVE X,IPX-1(N) + MOVE Y,IPY-1(N) + MOVE XT,IVX-1(N) + MOVE YT,IVY-1(N) + SETZ TT, +RANSTR: MOVEM TT,DIRECT-1(N) + MOVEM X,PX-1(N) + MOVEM Y,PY-1(N) + MOVEM XT,VX-1(N) + MOVEM YT,VY-1(N) + SOJG N,RANL +NOSHPS: SKIPN A,NSUN ;PUT SUN(S) ON THE SCREEN + JRST PUTS +INITSN: SKIPN RANSUN + JRST NORANS + PUSHJ SP,RAND + MOVE X,TT + PUSHJ SP,RAND + MOVE Y,TT + ANDI X,77777 + ANDI Y,77777 + MOVEI XT,1000 + MOVEI YT,1000 + PUSHJ SP,BORDER + JRST RSNSTR +NORANS: MOVE X,IGRVX-1(A) + MOVE Y,IGRVY-1(A) +RSNSTR: MOVEM X,GRVX-1(A) + MOVEM Y,GRVY-1(A) + PUSHJ SP,PUTSUN + SOJG A,INITSN +PUTS: SKIPG N,NSHIP ;PUT SHIPS ON THE SCREEN + JRST SETINT +PUTLP: PUSHJ SP,PUTSHP + SETOM SHPSTS-1(N) + SOJG N,PUTLP + SKIPG N,NSHIP + JRST SETINT + SKIPE TALLY-1(N) + JRST REHANG + SOJG N,.-2 +SETINT: SKIPE TEST ;SHOULD REALTIME BE SET UP? + JRST TSINT+2 + HRLZI TT,710000 ;SET THE REALTIME INTERRUPT + HRRI TT,TIME + .SUSET [.SMASK,,INTMSK] ;INTERRUPT FOR REALTIME + .REALT TT, + .VALUE [ASCIZ/:.REALT FAILED TO SKIP.VP /] + JRST RHJFCL +REHANG: SKIPE TEST ;IN REALTIME MODE? + JRST TSTSLP + .DISMISS TSINT+1 + .VALUE [ASCIZ/:GACK! THESE OLD TIME INTERRUPTS ARE WIERD!/] +RHJFCL: JFCL + .HANG + +INTMSK: %PIRLT + +TSINT: 0 ;PC, ETC. GO HERE + 0 + PUSHJ SP,CRASH ;CHECK FOR COLLISIONS + PUSHJ SP,SMACK + PUSHJ SP,HIT + PUSHJ SP,DFND + SOS SHOTTM + SOS SHOTTM+1 + PUSHJ SP,SCORE + MOVE N,NSHIP +LOOP: SKIPGE SHPSTS-1(N) + JRST LOPOK + SKIPG SHPSTS-1(N) + JRST LOPEND + SOS SHPSTS-1(N) + JRST LOPDED +LOPOK: PUSHJ SP,REPOS ;DO ANOTHER TIME INCREMENT + PUSHJ SP,CLRSHP + PUSHJ SP,VELPOS + PUSHJ SP,PUTSHP +LOPEND: SOJG N,LOOP + PUSHJ SP,DISOBL + SKIPE TEST ;IN REALTIME MODE? + JRST TSTSLP + .DISMISS TSINT+1 + .VALUE [ASCIZ/:GACK! THESE OLD TIME INTERRUPTS ARE WIERD!/] +TSTSLP: MOVE TT,TIME ;NOT IN REALTIME, SO JUST SLEEP ON IT + .SLEEP TT, + JRST TSINT+2 + +LOPDED: PUSHJ SP,REPOS + PUSHJ SP,VELPOS + MOVE TT,SHPSTS-1(N) + TRNN TT,1 + JRST PUTDWN + JRST PUTUP +PUTDWN: PUSHJ SP,CLRSHP + JRST LOPEND +PUTUP: PUSHJ SP,PUTSHP + JRST LOPEND + +SCORE: SKIPG N,NSHIP + JRST SCRL +SCRLP: MOVE TT,SHPSTS-1(N) + CAIE TT,1 + JRST SCRNXT + SKIPG TT,NSHIP + JRST SCRNXT + SKIPGE SHPSTS-1(TT) + AOS TALLY-1(TT) + SOJG TT,.-2 +SCRNXT: SOJG N,SCRLP +SCRL: SKIPG N,NSHIP + JRST SCRXIT + SETO TT, +SCRXL: SKIPE SHPSTS-1(N) + AOJG TT,SCROK + SOJG N,SCRXL +SCRXIT: POP SP, + .IOT TYO,[15] + .IOT TYO,[12] + .IOT TYO,[12] + SKIPG N,NSHIP + JRST SCRXIT +SCRPL: .IOT TYO,[40] + .IOT TYO,[40] + MOVE T1,TALLY-1(N) + PUSHJ SP,PRNUM + SOJG N,SCRPL + MOVE TT,SCRTIM + .SLEEP TT, + MOVE TT,TVALU + MOVEM TT,TVBFR+20000 ;RESTORE TV ALU TO ORIGINAL + HRRZI TT,407.*18.-1 ;CLEAR THE SCREEN + SETZM TVBFR(TT) + SOJG TT,.-1 + HRLZI TT,22000 ;TV SCREEN INTO XOR MODE + XORM TT,TVBFR+20000 + JRST NEWGAM +SCROK: POPJ SP, + + +DISOBL: SETZ T2, ;DISPLAY THE TORPS + SKIPN OBJLEN + POPJ SP, + MOVE X,OBJCL(T2) + CAIE X,TORP + JRST NOTRP + SOSL X,OBJCL+5(T2) + JRST NOTRP + MOVE X,OBJCL+1(T2) + MOVE Y,OBJCL+2(T2) + PUSHJ SP,DISPLY + PUSHJ SP,DELTRP + JRST DISOLP +NOTRP: ADDI X,1 + CAML X,TRPLIF + JRST DIS1 + MOVE X,OBJCL+1(T2) + MOVE Y,OBJCL+2(T2) + PUSHJ SP,DISPLY +DIS1: MOVE X,OBJCL+1(T2) ;ADD TORP VELOCITY TO POSITION + MOVE Y,OBJCL+2(T2) + MOVE XT,OBJCL+3(T2) + MOVE YT,OBJCL+4(T2) + ADD X,XT + ADD Y,YT + PUSHJ SP,BORDER ;CHECK FOR WRAP OR BOUNCE + MOVEM X,OBJCL+1(T2) ;MAKE THE NEW POSITION AND VELOCITY PERMANENT + MOVEM Y,OBJCL+2(T2) + MOVEM XT,OBJCL+3(T2) + MOVEM YT,OBJCL+4(T2) + PUSHJ SP,DISPLY + ADDI T2,6 +DISOLP: CAMGE T2,OBJLEN ;FINISHED WITH THE TORPS YET? + JRST DISOBL+1 + POPJ SP, + +DELTRP: HRLI TT,OBJCL+6(T2) ;DELETE TORP(T2) FROM THE OBJCL LIST + HRRI TT,OBJCL(T2) + BLT TT,MAXOBJ+OBJCL-7 + MOVE TT,OBJLEN + SUBI TT,6 + MOVEM TT,OBJLEN + POPJ SP, + +DISPLY: LSH X,-6 ;PUT A 2X2 POINT AT X,Y (USUALLY A TORP) + LSH Y,-6 + IMULI Y,18. + IDIVI X,32. + ADD Y,X + MOVNS XT + HRLZI T4,600000 + LSH T4,(XT) + TRZN T4,17 + JRST .+4 + HRLZI T5,400000 + MOVEM T5,TVBFR+1(Y) + MOVEM T5,TVBFR+19.(Y) + MOVEM T4,TVBFR(Y) + MOVEM T4,TVBFR+18.(Y) + POPJ SP, + +MKTRP1: SETZ T1, ;GENERATE A TORPEDO AND ENTER IT ON THE OBJCL LIST + SKIPLE SHOTTM + POPJ SP, + MOVE TT,RLDTIM + MOVEM TT,SHOTTM + JRST MKALL +MKTRP2: HRRZI T1,1 + SKIPLE SHOTTM+1 + POPJ SP, + MOVE TT,RLDTIM + MOVEM TT,SHOTTM+1 +MKALL: SKIPL SHPSTS(T1) + POPJ SP, + MOVE TT,OBJLEN + CAIL TT,MAXOBJ + POPJ SP, + MOVE TT,DIRECT(T1) + PUSHJ SP,DXDY + MOVNS Y + MOVE XT,X + MOVE YT,Y + IMUL XT,TRPVEL + IMUL YT,TRPVEL + IMUL X,XPLODR + IMUL Y,XPLODR + ASH X,-7 + ASH Y,-7 + ASH XT,-3 + ASH YT,-3 + SUB X,XT + SUB Y,YT + ADD X,PX(T1) + ADD Y,PY(T1) + ADD XT,VX(T1) + ADD YT,VY(T1) + MOVEI T5,TORP + MOVE T2,OBJLEN + MOVEM T5,OBJCL(T2) + MOVEM X,OBJCL+1(T2) + MOVEM Y,OBJCL+2(T2) + MOVEM XT,OBJCL+3(T2) + MOVEM YT,OBJCL+4(T2) + MOVE YT,TRPLIF + MOVEM YT,OBJCL+5(T2) + ADDI T2,6 + MOVEM T2,OBJLEN + POPJ SP, + +CRASH: SKIPG N,NSHIP ;CRASH=SHIP-TO-SUN COLLISION + POPJ SP, +CRSHP: SKIPL SHPSTS-1(N) + JRST NOSUN + SKIPG A,NSUN + POPJ SP, +CRSHPL: MOVE X,PX-1(N) + SUB X,GRVX-1(A) + MOVMS X + CAML X,SUNRAD + JRST CRNXT + MOVE Y,PY-1(N) + SUB Y,GRVY-1(A) + MOVMS Y + CAML Y,SUNRAD + JRST CRNXT + MOVE XT,XPLDTM + ADDM XT,SHPSTS-1(N) + SKIPA +CRNXT: SOJG A,CRSHPL +NOSUN: SOJG N,CRSHP + POPJ SP, + +SMACK: SKIPG N,NSHIP ;SMACK=SHIP-TO-SHIP COLLISION + POPJ SP, +SMK: SKIPN SHPSTS-1(N) ;IF THE SHIP FLIES OR DIES, ITS VALID + JRST SMKNXT + MOVE A,N + SOJLE A,SMACK+1 ;IF THERE AREN'T TWO SHIPS, THEY CAN'T HIT +SMKRPT: SKIPN SHPSTS-1(A) + JRST SMKLP + MOVE XT,PX-1(N) ;SEE IF THEY REALLY HIT + SUB XT,PX-1(A) + MOVMS XT + CAML XT,XPLODR + JRST SMKLP + MOVE YT,PY-1(N) + SUB YT,PY-1(A) + MOVMS YT + CAML YT,XPLODR + JRST SMKLP + MOVE XT,VX-1(N) ;AVERAGE THE TWO VELOCITIES + MOVE X,VX-1(A) + ASH XT,-1 + ASH X,-1 + SKIPGE SHPSTS-1(A) + ADDM XT,VX-1(A) + SKIPGE SHPSTS-1(N) + ADDM X,VX-1(N) + MOVE YT,VY-1(N) + MOVE Y,VY-1(A) + ASH YT,-1 + ASH Y,-1 + SKIPGE SHPSTS-1(A) + ADDM YT,VY-1(A) + SKIPGE SHPSTS-1(N) + ADDM Y,VY-1(N) + SKIPGE SHPSTS-1(N) ;MAKE THEM DISAPPEAR + PUSHJ SP,CLRSHP + EXCH A,N + SKIPGE SHPSTS-1(N) + PUSHJ SP,CLRSHP + EXCH A,N + MOVE XT,XPLDTM ;THEY HIT, SO MAKE THEM EXPLODE + SKIPGE SHPSTS-1(N) ;BUT ONLY IF THEY AREN'T ALREADY + MOVEM XT,SHPSTS-1(N) + SKIPGE SHPSTS-1(A) + MOVEM XT,SHPSTS-1(A) +SMKLP: SOJG A,SMKRPT +SMKNXT: SOJG N,SMK + POPJ SP, + +HIT: SETZ T2, ;HIT=TORP-TO-SHIP COLLISION + CAML T2,OBJLEN + POPJ SP, + SKIPG N,NSHIP + POPJ SP, +HITSHL: SKIPN SHPSTS-1(N) + JRST HITNXT + MOVE X,PX-1(N) + SUB X,OBJCL+1(T2) + MOVMS X + CAML X,XPLODR + JRST HITNXT + MOVE Y,PY-1(N) + SUB Y,OBJCL+2(T2) + MOVMS Y + CAML Y,XPLODR + JRST HITNXT + MOVE XT,XPLDTM + ADDM XT,SHPSTS-1(N) + MOVE X,OBJCL+3(T2) + ASH X,-2 + ADD X,VX-1(N) + MOVE Y,OBJCL+4(T2) + ASH Y,-2 + ADD Y,VY-1(N) + MOVEM X,VX-1(N) + MOVEM Y,VY-1(N) + MOVE X,OBJCL+1(T2) + MOVE Y,OBJCL+2(T2) + PUSHJ SP,DISPLY + PUSHJ SP,DELTRP + SKIPA +HITNXT: SOJG N,HITSHL + ADDI T2,6 + JRST HIT+1 + +DFND: SETZ T1, ;DFND=TORP-TO-TORP COLLISION + MOVE T2,T1 +DFNDL: ADDI T2,6 + CAML T2,OBJLEN + JRST DFNDXT + MOVE X,OBJCL+1(T1) + SUB X,OBJCL+1(T2) + MOVMS X + CAML X,XPLODR + JRST DFNDL + MOVE Y,OBJCL+2(T1) + SUB Y,OBJCL+2(T2) + MOVMS Y + CAML Y,XPLODR + JRST DFNDL + MOVE X,OBJCL+3(T1) + ADD X,OBJCL+3(T2) + ASH X,-1 + MOVEM X,OBJCL+3(T1) + MOVE Y,OBJCL+4(T1) + ADD Y,OBJCL+4(T2) + ASH Y,-1 + MOVEM Y,OBJCL+4(T1) + SETZM OBJCL+5(T1) + MOVE X,OBJCL+1(T2) + MOVE Y,OBJCL+2(T2) + PUSHJ SP,DISPLY + PUSHJ SP,DELTRP + JRST DFNDL +DFNDXT: ADDI T1,6 + CAML T1,OBJLEN + POPJ SP, + JRST DFNDL-1 + +REPOS: SKIPN A,NSUN ;CALCULATE ACCELERATION ON SHIP#N + POPJ SP, ;NO SUNS TO CHANGE VELOCITY +RPSLP: MOVE X,PX-1(N) + MOVE Y,PY-1(N) + SUB X,GRVX-1(A) + SUB Y,GRVY-1(A) + MOVE XT,X + MOVE YT,Y + IMUL XT,XT + IMUL YT,YT + MOVE T1,XT + ADD T1,YT + MOVE D,T1 + PUSHJ SP,ISQRT + MOVE TT,GRAV + IMUL TT,GRVK-1(A) + IDIV T1,TT + HRLZ X,X + HRLZ Y,Y + IDIV X,T1 + IDIV Y,T1 + LSH D,-2 + IDIV X,D + IDIV Y,D + SUB X,VX-1(N) + SUB Y,VY-1(N) + MOVNM X,VX-1(N) + MOVNM Y,VY-1(N) + MOVMS X + MOVMS Y + CAML X,MAXVEL + SETZM VX-1(N) + CAML Y,MAXVEL + SETZM VY-1(N) + SOJG A,RPSLP + POPJ SP, + +VELPOS: .IOT IN,TT ;INPUT ANY COMMANDS + CAIN TT,": + PUSHJ SP,MKTRP1 + CAIN TT," + PUSHJ SP,MKTRP2 + CAIN TT,"[ + MOVEM TT,SWITCH + CAIN TT,"] + MOVEM TT,SWITCH + CAIN TT,"\ + MOVEM TT,SWITCH + CAIN TT,"/ + MOVEM TT,SWITCH + CAIN TT,"Z + MOVEM TT,SWITCH+1 + CAIN TT,"X + MOVEM TT,SWITCH+1 + CAIN TT,"C + MOVEM TT,SWITCH+1 + CAIN TT,"V + MOVEM TT,SWITCH+1 + MOVE TT,SWITCH-1(N) + MOVE T1,DIRECT-1(N) + CAIE N,1 ;PERFORM THE LAST COMMAND OF SHIP #N + JRST VLPS2 + CAIN TT,"[ + ADD T1,SHPSPN + CAIN TT,"] + SUB T1,SHPSPN + CAIN TT,"\ + PUSHJ SP,SPEED + JRST VLPALL +VLPS2: CAIN TT,"Z + ADD T1,SHPSPN + CAIN TT,"X + SUB T1,SHPSPN + CAIN TT,"C + PUSHJ SP,SPEED +VLPALL: ANDI T1,777 ;DIRECTION IS A 9 BIT NUMBER + MOVEM T1,DIRECT-1(N) + MOVE X,PX-1(N) ;REPOSITION AND CHECK FOR WRAP OR BOUNCE + MOVE Y,PY-1(N) + ADD X,VX-1(N) + ADD Y,VY-1(N) + MOVE XT,VX-1(N) + MOVE YT,VY-1(N) + PUSHJ SP,BORDER +STASH: MOVEM X,PX-1(N) ;MAKE IT PERMANENT + MOVEM Y,PY-1(N) + MOVEM XT,VX-1(N) + MOVEM YT,VY-1(N) + POPJ SP, + +BORDER: +CHKXL: CAML X,LEFTF ;CHECK FOR WRAP OR BOUNCE + JRST CHKXR + SKIPE BOUNCE + JRST .+3 + ADD X,WIDE + JRST CHKXL + MOVMS XT + JUMPG XT,.+2 + ADDI XT,1 + ADD X,XT +CHKXLP: ADD X,XT + CAMGE X,LEFTF + JRST CHKXLP +CHKXR: CAMG X,RITEF + JRST CHKYT + SKIPE BOUNCE + JRST .+3 + SUB X,WIDE + JRST CHKXR + MOVMS XT + JUMPG XT,.+2 + ADDI XT,1 + MOVNS XT + ADD X,XT +CHKXRP: ADD X,XT + CAMLE X,RITEF + JRST CHKXRP +CHKYT: CAML Y,TOPF + JRST CHKYB + SKIPE BOUNCE + JRST .+3 + ADD Y,HIGH + JRST CHKYT + MOVMS YT + JUMPG YT,.+2 + ADDI YT,1 + ADD Y,YT +CHKYTP: ADD Y,YT + CAMGE Y,TOPF + JRST CHKYTP +CHKYB: CAMG Y,BTMF + POPJ SP, + SKIPE BOUNCE + JRST .+3 + SUB Y,HIGH + JRST CHKYB + MOVMS YT + JUMPG YT,.+2 + ADDI YT,1 + MOVNS YT + ADD Y,YT +CHKYBP: ADD Y,YT + CAMLE Y,BTMF + JRST CHKYBP + POPJ SP, + +SPEED: MOVE TT,DIRECT-1(N) ;CALCULATE SHIP'S ACCELERATION DUE TO ENGINES + PUSHJ SP,DXDY + IMUL X,SHPACC + IMUL Y,SHPACC + LSH X,-12 + LSH Y,-12 + MOVNS Y + HRRES X + HRRES Y + ADDM X,VX-1(N) + ADDM Y,VY-1(N) + POPJ SP, + +ISQRT: HRRZI T4,30 ;INTEGER SQUARE-ROOT SUBR., T1 TO T1 + MOVE T2,T1 + MOVE T3,T1 + MOVE T1,10000 +ISQRTL: IDIV T2,T1 + ADD T1,T2 + LSH T1,-1 + MOVE T2,T3 + SOJG T4,ISQRTL + POPJ SP, + +DXDY: MOVE T5,TT ;SINE AND COSINE LOOKUP + ANDI T5,777 ;TT CONTAINS ANGLE, 9 BIT = FULL CIRCLE + MOVE Y,SIN(T5) + ADDI T5,200 + ANDI T5,777 + MOVE X,SIN(T5) + POPJ SP, + +RANMSK: 401020003045 +RANNUM: 0 +RAND: MOVE TT,RANNUM ;GENERATE RANDOM #,USING FEEDBACK S-R + AND TT,RANMSK + SETZ T1, + JUMPGE TT,.+2 + SETCA T1, + LSH TT,1 + JUMPN TT,.-3 + ANDI T1,1 + MOVE TT,RANNUM + LSH TT,1 + IOR TT,T1 + MOVEM TT,RANNUM + POPJ SP, + +PRNUM: MOVEI T3,4 +PRLP: IDIVI T1,10. + PUSH SP,T2 + SOJG T3,PRLP + MOVEI T3,4 +PRL: POP SP,T1 + .IOT TYO,[40] + JUMPN T1,PRN + SOJG T3,PRL +PRN: ADDI T1,60 + .IOT TYO,T1 + POP SP,T1 + SOJG T3,PRN + JRST (T1) + +PUTSUN: LSH X,-6 ;DISPLAY A SUN AT X,Y + LSH Y,-6 + IMULI Y,18. + ADDI X,16. + IDIVI X,32. + ADD Y,X + MOVNS XT + MOVEI T1,31. + ADDI Y,16.*18. +PUTLOP: MOVE T3,SUN(T1) + SETZ T4, + LSHC T3,(XT) + LSH T3,4 + MOVEM T3,TVBFR-1(Y) + MOVEM T4,TVBFR(Y) + SUBI Y,18. + SOJGE T1,PUTLOP + POPJ SP, + +CLRSHP: MOVE T3,N ;DISPLAY SHIP IN CLRS BUFFER (ERASES TOO) + SUBI T3,1 + IMULI T3,70. + MOVE T1,CLRS(T3) + SUBI T1,1 + MOVEI T4,32. +CLRLP: SKIPE T2,CLRS+1(T3) + MOVEM T2,TVBFR(T1) + SKIPE T2,CLRS+2(T3) + MOVEM T2,TVBFR+1(T1) + ADDI T3,2 + ADDI T1,18. + SOJG T4,CLRLP + POPJ SP, + +PUTSHP: MOVE T3,N ;REGENERATE A CLRS FIELD + SUBI T3,1 + MOVE T4,T3 + IMULI T3,70. + IMULI T4,NDIREC*10 + ADD T4,DIRECT-1(N) + LSH T4,-3 + IMULI T4,32. + SETZM CLRS+1(T3) + HRRZI TT,CLRS+2(T3) + HRLI TT,CLRS+1(T3) + BLT TT,CLRS+64.(T3) + MOVE T1,PX-1(N) + LSH T1,-6 + ADDI T1,16. + IDIVI T1,32. + MOVNS T2 + MOVE TT,PY-1(N) + LSH TT,-6 + SUBI TT,16. + IMULI TT,18. + ADD T1,TT + MOVEM T1,CLRS(T3) + MOVEI TT,32. +PUTSLP: SETZ XT, + MOVE X,SHPBFR(T4) + LSHC X,-4(T2) + LSH X,4 + MOVEM X,CLRS+1(T3) + MOVEM XT,CLRS+2(T3) + ADDI T3,2 + ADDI T4,1 + SOJG TT,PUTSLP + JRST CLRSHP + +TIME: 4 ;REPEAT FRAME TIME (60THS), OR DELAY TIME + 2 ;WHEN REALTIME IS SUPPRESSED + 0 + 0 + +TEST: -1 ;TEST-MODE SWITCH, SUPPRESSES REALTIME +OPNIN: 1044,,646471 ;TTY INPUT NO-WAIT ECHO AREA +OPNOUT: 15,,646471 ;TTY OUTPUT, 3 LINE ECHO AREA + +PNTR: -32.*MAXSHP*NDIREC,,SHPBFR ;DISK INPUT OF SHIPS POINTER + +INSHIP: SETZ ;DISK OPEN INFO FOR SHIPS PATERNS + SIXBIT /OPEN/ + [6,,INCH] + [SIXBIT /DSK/] + [SIXBIT /SWR/] + [SIXBIT /SHIPS/] + SETZ [SIXBIT /GJD/] + +PNTR1: -512.,,SIN + +INSINE: SETZ ;DISK OPEN INFO FOR SINE WAVE + SIXBIT /OPEN/ + [6,,INCH] + [SIXBIT /DSK/] + [SIXBIT /SINE/] + [SIXBIT /BINARY/] + SETZ [SIXBIT /GJD/] + +TVALU: 0 ;TV ALU BEFORE CHANGING IT + +TVSCRN: SETZ ;TV MAPPING INFO + SIXBIT /CORBLK/ + 1000,,600000 + 1000,,-1 + TMP + 1000,,-2 + SETZ TMP2 +TMP: -11,,TVBFR/2000 ;8.K TV MEM, START AT PAGE 12 IN PDP10 +TMP2: 0 + +IPX: 40000 ;SHIP STARTING POSITIONS + 50000 + 50000 +IPY: 30000 + 40000 + 30000 +IVX: 300 ;SHIP STARTING VELOCITIES + 0 + 200 +IVY: 0 + 250 + 100 +PX: BLOCK MAXSHP ;SHIP DATA DURING A GAME +PY: BLOCK MAXSHP +VX: BLOCK MAXSHP +VY: BLOCK MAXSHP +DIRECT: BLOCK MAXSHP +IGRVX: 40000 ;SUN STARTING LOCATIONS + 20000 +IGRVY: 40000 + 40000 +GRVX: BLOCK MAXSUN ;SUN GAME LOCATIONS +GRVY: BLOCK MAXSUN +GRVK: 2 ;SUN RELATIVE MASSES + 1 +GRAV: 100 ;GRAVITY CONSTANT +LEFTF: 4000 ;FRINGE POSITIONS, FOR WRAP & BOUNCE +RITEF: 72000 +TOPF: 4000 +BTMF: 60000 +WIDE: 66000 ;THE UNIVERSE'S DIMENSIONS +HIGH: 54000 +BOUNCE: 0 ;-1=BOUNCE, 0=WRAP +RANPOS: -1 ;RANDOM SHIP POSITIONING +RANSUN: -1 ;RANDOM SUN POSITIONING +NSUN: 1 ;NUMBER OF SUNS IN THIS GAME +NSHIP: 2 ;NUMBER OF SHIPS STARTING THIS GAME +SHPACC: 40 ;SHIP ACCELERATION WHEN ENGINES ARE ON +SHPSPN: 20 ;RATE OF SPIN WHEN TURNING +XPLODR: 1400 ;PROXIMITY FUSE FOR TORPS +XPLDTM: 30 ;EXPLOSION TIME +SUNRAD: 1400 ;PROXIMITY RADIUS FOR SUNS +TRPVEL: 20 ;TORPEDO VELOCITY +TRPLIF: 50 ;TORPEDO LIFETIME BEFORE AUTO-DETINATION +RLDTIM: 4 ;TORPEDO RELOAD TIME IN FRAMES +SCRTIM: 20 ;SCORE DISPLAY TIME AT END OF GAME IN 30ths +MAXVEL: 2000 ;MAXIMUM VELOCITY OF THE SHIPS + +SWITCH: BLOCK MAXSHP ;SHIP COMMAND STORAGE +SHPSTS: BLOCK MAXSHP ;0=SHIP NOT ACTIVE, >0=SHIP EXPLODING, -1=SHIP ALIVE +SHOTTM: BLOCK MAXSHP ;TORPEDO RELOAD TIME +TALLY: BLOCK MAXSHP + +CLRS: BLOCK MAXSHP*2*40. ;STORAGE BUFFER FOR EACH SHIP ON THE TV + + RADIX 2 +SUN: 000000000000000000000000000000000000 ;A TYPICAL SUN + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000001000010000000000000000 + 000000000000001000100000000000000000 + 000000000000100101000111000000000000 + 000000000000010110111000000000000000 + 000000000000001111000000000000000000 + 000000000000001110110000000000000000 + 000000000000111010001000000000000000 + 000000000011010001000000000000000000 + 000000000000100000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + 000000000000000000000000000000000000 + + + RADIX 1000 + +SIN: BLOCK 512. ;SINEWAVE TABLE, 512. ENTRIES, TO +/-255. + +STACK: BLOCK 20 ;STACK AREA, OBVIOUSLY + +OBJLEN: 0 ;OBJCL POINTER +OBJCL: BLOCK MAXOBJ ;STORAGE AREA FOR TORPEDOS + +SHPBFR: BLOCK 32.*MAXSHP*NDIREC + +EOM1: SIXBIT/EOM1/ ;A KLUDGE + +;THEN COMES THE TV AREA STARTING AT PAGE 12 + + END ST +       \ No newline at end of file