;WORK:<RASPUZZI.VTTREK>VTTREK.MAC.172, 14-Jul-88 11:45:24, Edit by RASPUZZI
; Cleanup beginning comments.
;WORK:<RASPUZZI.VTTREK>VTTREK.MAC.171, 14-Jul-88 11:39:41, Edit by RASPUZZI
; Phaser shots should always be yellow. Make sure. (edit 204)
;WORK:<RASPUZZI.VTTREK>VTTREK.MAC.168, 28-Jun-88 15:07:36, Edit by RASPUZZI
; Make sure LAT terminals can't supress stars. (edit 203)
;WORK:<RASPUZZI.VTTREK>VTTREK.MAC.165, 24-Jun-88 09:58:29, Edit by RASPUZZI
; Fix a bug when redisplaying the console. (edit 202)
;WORK:<RASPUZZI.VTTREK>VTTREK.MAC.163, 22-Jun-88 10:42:08, Edit by RASPUZZI
; Make sure screen stays Magenta for Klingon torpedoes (edit 201).
;WORK:<RASPUZZI.VTTREK>VTTREK.MAC.158, 9-Jun-88 14:47:29, Edit by RASPUZZI
; Finish code cleanup. Neatness counts!
;WORK:<RASPUZZI.VTTREK>VTTREK.MAC.133, 9-Jun-88 12:30:31, Edit by RASPUZZI
; Remove TOPS-10 stuff so this is now TOPS-20 only.
;WORK:<RASPUZZI.VTTREK>VTTREK.MAC.12, 7-Jun-88 14:50:36, Edit by RASPUZZI
; Add VT241 support and begin cleanup of messy code.
;<HESS>VTTREK.MAC.41 15-Jan-81 09:42:56, Edit by HESS
; VT100 TREK Version 4.0
;
; TREK is a VT100 game for up to eight players. It's written in
; MACRO-20 for VT100s that are equipped with the Advanced Video
; Option, VT125s, VT241s or GIGIs
;
; Each player runs the game from a separate TTY and job. The
; jobs communicate via a shareable high segment.
;
; VTTREK.DOC contains a complete game description. The program
; uses a file of help texts named VTTREK.HLP. This file should be
; on the same device and in the same directory as the VTTREK.EXE.
; The file isn't required in order to run the game.
;
; Version 2.0 contains all of the modifications since the release
; of Version 1.0 plus many new routines. VTTREK.DOC describes
; Version 4.0 and the differences between the old and new versions.
;
; Version 4.0 has GIGI, VT125 and VT241 support. VT241s must be in
; VT125 mode for the ReGIS graphics. Color is also a feature in
; this version.
;
; VTTREK timing is based on 1200 baud lines. Lower baud rates give a
; slow-motion effect and an advantage to interceptors and bases. Higher
; baud rates seem to make it easy to defeat computer ships.
;
; Questions, comments, suggestions, etc, are welcome.
;
; For further information, contact:
;
; Michael Raspuzzi
; TOPS-20 Monitor Engineering
; MRO1-2/L14 Pole P14
; (617) 467-2346 DTN 297-2346
;
; Revisions since release of version 1.0:
;
; 7-Jun-88 Add VT241 support and start general cleanup and
; start edit history.
;
; 7-Jan-81 Conversion to TOPS20
;
; 16-Sep-80 added optional ADJBP macro for KL to KI conversion.
;
; 16-Sep-80 added ROTRAN routine to randomize starting orientation.
;
; 05-Oct-80 move one-line messages to the bottom of the display.
;
; 12-Oct-80 modify RF command to allow setting energy/torpedoes.
;
; 28-Oct-80 photon fire visually detectable up to 2048 distance.
;
; 28-Oct-80 'harden' starbases by allowing them to refuel.
;
; 04-Nov-80 ship-to-ship messages displayed at bottom of screen.
;
; 04-Nov-80 'more' message shifted to keypad.
;
; 04-Nov-80 added planet rebellions.
TITLE TREK
.REQUEST SYS:FORLIB
.REQUIRE SYS:MACREL
SEARCH MONSYM,MACSYM
SALL
.JBUUO==40
;Version definitions
TK.VER=4 ;Version number
TK.MIN=0 ;Minor version
TK.WHO=0 ;Who last edited
TK.EDT=^D204 ;Edit #
UOT==5 ;Accumulator for universal table index
ROW==6 ;Accumulator for row values
COL==7 ;Accumulator for col values
LST==10 ;Accumulator for target list routines
P1==11 ;Registers used by the queue routines.
P2==12 ;Must be considered permanent by any routine
P3==13 ;That isn't a queue routine.
P4==14
SUOT==15 ;UOT of this ship - set at startup, never changed
AP==16 ;General purpose register
C==16 ; (AP is sometimes called C)
P==17 ;Stack pointer
SP==17 ; (P is sometimes called SP)
PDLSZ==300 ;Stack size
SH.CT=10 ;Number of ships
SB.CT=10 ;Number of starbases
PL.CT=100 ;Number of planets and interceptors
ST.CT=100 ;Number of stars
SH.MN=0 ;Low index of ships in universal table
SB.MN=10 ;Low index of starbases
PL.MN=20 ;Low index of planets and interceptors
ST.MN=120 ;Low index of stars
SH.MX=7 ;High index of ships in universal table
SB.MX=17 ;High index of starbases
PL.MX=117 ;High index of planets
ST.MX=217 ;High index of stars
Q.SIZE=600*6 ;Size of the event queue
HQ.MIN=0
HQ.MAX=77*6
LQ.MIN=100*6
LQ.MAX=577*6
SUBTTL Data Storage -- General Usage
PDL: BLOCK PDLSZ ;Stack
TTTYP: 0 ;Terminal type flag (-1 = GIGI)
GRTYP: 0 ;Graphics type (-1 = ReGIS)
VT241F: 0 ;VT241 flag (-1 = VT241)
VKFLAG: 0 ;VK flag (-1 = GIGI) Used for FONTs
.DIRECTIVE FLBLST ;Really don't need a big listing.
VTFLAG: 1
V52FLG: 0 ;-1 if VT100 in VT52 mode
DBUGF: 0 ;Debug flag
BOOTF: BLOCK 1 ;Once only flag for BOOTS
HLPJFN: BLOCK 1 ;Help file JFN
SAVMOD: BLOCK 1 ;TTY JFN mode saved here
D.TCNT: BLOCK 1 ;Counter to prevent time from being displayed too often
GJBLK: GJ%OLD ;File must exist
.NULIO,,.NULIO ;No primary input/output
-1,,TK.DEV ;Device is here
-1,,TK.DIR ;Directory goes here
-1,,TK.NAM ;File name goes here
0 ;File extension - to be supplied
0 ;Protection
0 ;Account
0 ;JFN (not used)
TK.NAM: BLOCK 10 ;Name of program
TK.DIR: BLOCK 10 ;Directory of program
TK.DEV: BLOCK 10 ;Device of program
D.LINE: BLOCK 1
D.LAST: BLOCK 1
F.DATA: BLOCK 1 ;Data for FORTRAN calls
F.LOC: 200,,F.DATA ;Location of FORTRAN data
R.FIRE: BLOCK 1 ;= 0 rapid fire off
;< 0 rapid fire on
RF.PHA: ^D200 ;Rapid fire phaser energy (default 200)
RF.PHO: ^D1 ;Rapid fire photon count (default 1)
A.FIRE: BLOCK 1 ;Phaser/photon work area for bases,
;interceptors, and unmanned ships:
;
;LH - weapons code, bit 9: 0 = pha, 1 = pho.
;RH - energy to be applied.
SUBTTL Data Storage -- Ship Masks
;Ship masks
;
; Ship masks are used in the event queue to indicate which ship an
; event applies to, and in the universal table to indicate which
; libraries an object is in. The mask is always the leftmost 8 bits
; in a halfword. The bits are in reverse order. Bit 18 pertains to
; ship 8, bit 25 to ship 1.
MASK.F: 252000 ;All Federation ships
MASK.K: 524000 ;All Klingon ships
MASK.A: 776000 ;All ships, Federation and Klingon
MASK.C: 0 ;This ship only (set during setup)
MASK.O: 776000 ;Any ship but this one (set during setup)
MASK.U: 524000 ;'US' - friendly ships (set during setup)
MASK.T: 524000 ;'THEM' - enemy ships (set during setup)
MSKA.U: BLOCK 1 ;'US' for unmanned ships.
MSKA.T: BLOCK 1 ;'THEM' for unmanned ships.
SUBTTL Data Storage -- Ally Ship Masks
;Ally masks
;
; Used to determine which side an object is on. Masks bits
; 29 thru 31 in the U.TAB word.
ALLY.F: 1B31 ;Federation mask.
ALLY.K: 1B30 ;Klingon mask.
ALLY.N: 1B29 ;Neutral mask.
ALLY.A: 7B31 ;Neutral, Federation, or Klingon.
ALLY.U: 1B30 ;'US' - our side (set by setup routine).
ALLY.T: 1B30 ;'THEM' - their side (set by setup routines).
ALYA.U: BLOCK 1 ;'US' for unmanned ships.
ALYA.T: BLOCK 1 ;'THEM' for unmanned ships.
LOCSHR:: PHASE 400K
SHRBEG::
SEGVER: BYTE (3)TK.WHO (9)TK.VER (6)TK.MIN (18)TK.EDT ;Matched against EV+2 at startup
INITF: BLOCK 1 ;Interlock for boot init
;High-segment information shared by all ships
GAM.NR: BLOCK 1 ;Tournament game number or 0 if random
GAM.TM: ^D20 ;Minutes remaining in the game
GAM.HR: BLOCK 1 ;Current hour
GAM.MN: BLOCK 1 ;Current minute
I.LOCK: BLOCK 1 ;Initial (startup) lock. Keeps 2 or more
;players from starting up simultaneously.
I.TIME: BLOCK 1 ;Time I.LOCK was set. Allows I.LOCK to be reset
;if system crash occurred while a player was
;starting up.
Q.TIME:: 1 ;= 0, no non-ship (base, planet, interceptor)
; is waiting to be activated.
;> 0, lowest time that a non-ship is due to
; be activated.
A.SHIPS:: 10 ; number of ships under automatic control
MASK.Q::BLOCK 1 ;8-bit mask (0-7) indicating active ships.
TIME.Q:: BLOCK 120 ;Time that an unmanned ship or a non-ship is to
;be activated. Zero means the entry is empty.
REBEL: BLOCK 120 ;Time after which a planet may consider rebellion.
;Event queue
q:: BLOCK Q.SIZE
EVNT.T==Q ;Time after which event is to occur.
;= 0, entry is empty.
;< 0, entry is being temporarily held by a ship.
EVNT.A==Q+1 ;Event code word:
;0-7 ships to whom event applies (8-bit mask, ships
; 7 to 0). when a ship processes the event,
; it sets its bit to 0. when the mask is all 0,
; all ships have processed the event and the
; entry is returned to the available pool.
;8-9 weapons code:
; 0 = phasers
; 1 = photon torpedo
; message code:
; 0 = ship detected
; 1 = ship attacked
;10-17 uot of ship that sourced the event. this is
; the 'secondary' uot.
;18 message bit indicating an 'under attack' msg
; should be displayed.
;19-29 not used.
;30-35 event code.
EVNT.B==Q+2 ;UOT word:
;0-17 energy (for weapons and energy transfer).
;18-27 not used.
;28-35 uot of ship to whom the event is to occur.
; (may also be the sourcing uot, depending on
; the event.) this is the 'primary' uot.
EVNT.X==Q+3 ;absolute coordinates of object to whom event is to
EVNT.Y==Q+4 ;occur. used to test whether object has moved since
EVNT.Z==Q+5 ;event was initiated (mainly for weapons).
BLOCK 1
SUBTTL Data Storage -- Universal Object Table
;Universal Object Tables
;
; Data describing all of the objects in the galaxy. U.TAB is a
; general information word filled in when the galaxy is loaded.
; Initially, U.TAB contains only uid's (ID identifying what the
; object is). The term 'UOT' usually means the index into these
; tables.
U.ENER: BLOCK 220 ;Ship and shield energy. All objects have an
U.SHLD: BLOCK 220 ;energy allocation. (binary milliunits)
U.MSG: BLOCK 130 ;message area, one line per ship
U.ALRT: BLOCK 10 ;Alert status (ships only).
U.JOB: BLOCK 10 ;Job number of player
U.NAMX: BLOCK 10 ;User number of player
U.TIME: BLOCK 10 ;Time (ms) player was last active. when game
;is run, any player with no activity for
;past 5 minutes is reset. This is intended
;as a means to reset the game after a system
;crash. The time is updated every second
;or so whether the player enters a command
;or not, so it's not a time limit within
;which a player has to make a move.
U.BEGX: BLOCK 10 ;Ship positions assigned at startup. Players
U.BEGY: BLOCK 10 ;coming back into the game begin at their
U.BEGZ: BLOCK 10 ;original starting position.
U.LSTX: BLOCK 10 ;Last known position of a ship.
U.LSTY: BLOCK 10
U.LSTZ: BLOCK 10
U.TTY: BLOCK 10 ;TTY of player. TTY number determines
;whether a player was previously in the
;game, hence is in the shared section.
U.WAIT: BLOCK 10 ;Time (ms) at which a player may reenter the
;game. Player must wait 2 minutes before
;reentry is allowed.
U.TORP: BLOCK 10 ;Number of torpedoes a ship has.
N.MUOT: BLOCK 10 ;Object toward which an unmanned ship is
;moving.
N.MSSN: BLOCK 10 ;Unmanned ship's current mission.
SUBTTL Warp Distances
;WF.DIS and WF.ENE - distances and energy used when moving at
;standard warp factors.
WF.DIS: DEC 1 ;Warp 0
DEC 2 ;Warp 1
DEC 4 ;Warp 2
DEC 8 ;Warp 3
DEC 16 ;Warp 4
DEC 32 ;Warp 5
DEC 64 ;Warp 6
DEC 128 ;Warp 7
DEC 256 ;Warp 8
DEC 512 ;Warp 9
WF.ENE: DEC 1 ;Warp 0
DEC 4 ;Warp 1
DEC 16 ;Warp 2
DEC 64 ;Warp 3
DEC 256 ;Warp 4
DEC 1024 ;Warp 5
DEC 4096 ;Warp 6
DEC 16384 ;Warp 7
DEC 65536 ;Warp 8
DEC 262144 ;Warp 9
SUBTTL Universal Table Initial Values
;Universal table initial values, loaded at startup
;
; U.TAB bit assignments and values:
;18 0 0 (positive), object is active.
; 1 (negative), object is inactive or destroyed.
;19 1 0 - ship is not occupied (not under human control).
; 1 - ship is under human control.
; 2-7 not used.
;26 8 enemy detected.
; 0 - notify others.
; 1 - others have been notified.
;27 9 enemy under attack.
; 0 - notify others.
; 1 - others have been notified.
; 10-17 planets:
; 10 not used.
;29 11 defenses up (1) or down (0).
;30-32 12-14 launched interceptor bits.
;33-35 15-17 interceptor in base bits.
; interceptors:
;28-31 10-13 count-down field, fire if zero.
;32-35 14-17 index to a.fact and b.fact, offset values for motion.
; 18-25 library mask, 1 bit per ship. if mask bit is set, object
; is in that ships library.
; 26-28 not used.
; 29-31 alliance:
; 29 neutral.
; 30 klingon.
; 31 federation.
; 32-35 object id (uid).
; 0 - not used.
; 1 - star.
; 2 - planet.
; 3 - federation base.
; 4 - klingon base.
; 5 - federation ship.
; 6 - klingon ship.
; 7 - interceptor.
UI.E0: DEC 3000000 ;Ship energy starting values
UI.E1: DEC 200000000
UI.E2: DEC 20000000
UI.E3: DEC 5000000
UI.E4: DEC 5000000
UI.E5: DEC 3000000
UI.E6: DEC 3000000
UI.E7: DEC 0
UI.S0: DEC 2000000 ;Shield energy starting values
UI.S1: DEC 200000000 ;Starbase
UI.S2: DEC 20000000
UI.S3: DEC 5000000 ;Ship
UI.S4: DEC 5000000
UI.S5: DEC 2000000
UI.S6: DEC 2000000
UI.S7: DEC 499000 ;Interceptor
SHREND::DEPHASE ;End of shareable data base
SUBTTL Ship Object Tables
;Ship object tables
;
; object information from the perspective of the ship
O.ELEV: BLOCK 220 ;Object elevation, bearing, and range
O.BEAR: BLOCK 220 ;(B,E are tangents; R is floating point)
O.RANG: BLOCK 220
S.UOT: BLOCK 1 ;UOT of the ship (same as SUOT accumulator)
S.MASK: BLOCK 1 ;A work mask
S.MUID: BLOCK 1 ;A work universal ID
S.WARP: DEC 7 ;Current warp factor
N.ENER: BLOCK 1 ;Total shield plus ship energy of unmanned ship
N.PCNT: BLOCK 1 ;Count of captured planets, used by unmanned ships.
N.SCNT: BLOCK 1 ;Count of near enemy ships, used by unmanned ships.
SUBTTL Quadrant Table
; Quadrant table used at startup. XYZ.I is the index. XYZ.T entries
; have a bit for X,Y,Z. If set, bit means coordinate is to be
; negated. Determines where objects will go at startup, ensures that
; objects will be evenly distributed in 8 quadrants of galaxy.
T.ROW: ^D7 ;Target ROW and COL, not necessarily within
T.COL: ^D41 ;range of the viewer or the screen.
T.VIEW: 1
T.ELEM: BLOCK 1
T.UOT: -1 ;If not < 0, indicates target is locked on
;object T.UOT
T.BEAR: BLOCK 1 ;To confuse things, target B,E is kept in
T.ELEV: BLOCK 1 ;degrees, not as tangents (floating point)
T.RMAX: BLOCK 1 ;Some MIN and MAX values used when determining
T.RMIN: BLOCK 1 ;whether an object is pointed to by the target.
T.CMAX: BLOCK 1
T.CMIN: BLOCK 1
A.FACT: 128.0 ;Each of a planet's 3 interceptors rotates
118.2565802 ;around the planet at a fixed distance of
90.50966802 ;128 units. Rotation is in one of the planet's
48.98347936 ;3 primary planes. A.FACT and B.FACT are
0.0 ;used to compute the interceptor's next
-48.98347936 ;position, in absolute coordinates, relative
-90.50966802 ;to the absolute coordinates of the planet.
-118.2565802
-128.0 ;It keeps the program from having to do a lot
-118.2565802 ;of accumulator-destroying trig.
-90.50966802
-48.98347936 ;A.FACT = 128 * COS ang
0.0 ;B.FACT = 128 * SIN ang
48.98347936
90.50966802 ;Where ang varies from 0 to 360 in
118.2565802 ;22.5 degree increments
SUBTTL Command Storage
C.INTE: BLOCK 1 ;Integer returned by VTGET
C.CHAR: BLOCK 1 ;Character returned by VTGET
C.CMD: BLOCK 1 ;Command number returned by VTCMD
C.DIR: BLOCK 1 ;Direction returned by VTCMD
C.NBR1: BLOCK 1 ;1st number returned by VTCMD
C.NBR2: BLOCK 1 ;2nd number returned by VTCMD
C.CNT: BLOCK 1 ;Count of numbers entered
C.IMM: BLOCK 1 ;Immediate execute flag
C.TAB: XWD 0," " ;Command abbreviations
XWD 0,"SP" ;1 special
XWD 0,"LO" ;2 lock target
XWD 0,"RE" ;3 refuel and reload
XWD 0,"SH" ;4 shields
XWD 0,"TA" ;5 target
XWD 0,"PH" ;6 phaser
XWD 0,"TO" ;7 photon torpedo
XWD 8,"MO" ;8 move
XWD 0,"RO" ;9 rotate
XWD 0,"WR" ;10 warp
XWD 0,"LI" ;11 display target list
XWD 0,"CA" ;12 capture planet
XWD 0,"TR" ;13 transfer energy
XWD 0,"BA" ;14 display all bases
XWD 0,"BN" ;15 display nearest base
XWD 0,"AL" ;16 list all objects
XWD 0,"FE" ;17 list federation objects
XWD 0,"KL" ;18 list klingon objects
XWD 0,"PL" ;19 list planetary objects
XWD 0,"SE" ;20 send a message
XWD 0,"NE" ;21 get the news (a HELP feature)
XWD 0,"US" ;22 list users
XWD 0,"HE" ;23 help
XWD 0,"H " ;24 help synonym
XWD 0,"X " ;25 exit program
XWD 0,"Q " ;26 quit (exit synonym)
XWD 0,"R " ;27 refresh screen
XWD 0,"RT" ;28 refresh with VT100 self-test
XWD 0,"RF" ;29 rapid fire mode on/off
XWD 0,"ST" ;30 display active status
XWD 0,"AS" ;31 request assistance
XWD 0,"RA" ;32 red alert
XWD 0,"YA" ;33 yellow alert
XWD 0,"SA" ;34 secure from alert
XWD 0,"FB" ;35 list fed bases
XWD 0,"FP" ;36 list fed planets
XWD 0,"FS" ;37 list fed ships
XWD 0,"KB" ;38 list kli bases
XWD 0,"KP" ;39 list kli planets
XWD 0,"KS" ;40 list kli ships
XWD 0,"NP" ;41 list neutral planets
XWD 0,"PN" ;42 list neutral planets (synonym)
XWD 0,"S " ;43 display/suppress stars
C.SIZE=.-C.TAB ;Size of command abbr table
SUBTTL Scanner Tables
;Scanner tables
;
; SCAN.1 and SCAN.2 contain data on objects that are visible in the
; viewer.
;
; SCAN.1:
; bit 0-8 object nbr (index to universal tables)
; bit 9-17 object id (1 thru 7)
; bit 18-26 viewer column
; bit 27-35 viewer row
; SCAN.2:
; range (converted to integer)
;
; the scan tables are in ascending sequence by row, descending
; sequence by range within row.
V.MOD: BLOCK 1
V.GRA: ASCIZ "
(0" ;Escape sequence to enter graphics mode
V.ASC: ASCIZ "
(B" ;Escape sequence to get back to ASCII mode
SUBTTL Viewer Tables
;Viewer tables
;
; viewer area 'bit maps'.
;
; V.WRK: work area for one viewer row
; V.TAB: complete viewer area (all rows)
;
; Viewer tables are in '6-bit'; the low 5 bits correspond to an
; entry in the viewer element table; the high bit indicates the
; location is the target if 1, not the target if 0
V.WRK: BLOCK ^D14
V.TAB: BLOCK ^D173
V.WRKP: POINT 6,v.wrk
V.TABP: POINT 6,v.tab
V.WPTR: POINT 6,v.wrk
V.TPTR: POINT 6,v.tab
;viewer object table
;
; list of displayable objects at 8 ranges
;
; 1st 6 bytes are element nrs (from v.elem); 00 implies end of elements.
; 7th byte is offset from center of object; 7 implies no display.
V.OBJ: BYTE (5)17,22,12,22,17,00(6)2 ;Range 0 - rom ship
BYTE (5)34,00,00,00,00,00(6)0 ; star
BYTE (5)13,15,14,00,00,00(6)1 ; planet
BYTE (5)20,12,20,12,20,00(6)2 ; fed base
BYTE (5)11,12,11,12,11,00(6)2 ; kli base
BYTE (5)16,21,27,21,16,00(6)2 ; fed ship
BYTE (5)36,30,10,30,36,00(6)2 ; kli ship
BYTE (5)24,17,25,00,00,00(6)1 ; interceptor
BYTE (5)23,12,23,00,00,00(6)1 ;Range 1 - rom ship
BYTE (5)34,00,00,00,00,00(6)0 ; star
BYTE (5)13,15,14,00,00,00(6)1 ; planet
BYTE (5)20,12,20,12,20,00(6)2 ; fed base
BYTE (5)11,12,11,12,11,00(6)2 ; kli base
BYTE (5)22,26,22,00,00,00(6)1 ; fed ship
BYTE (5)23,36,23,00,00,00(6)1 ; kli ship
BYTE (5)32,00,00,00,00,00(6)0 ; interceptor
BYTE (5)04,00,00,00,00,00(6)0 ;Range 2 - rom ship
BYTE (5)05,00,00,00,00,00(6)0 ; star
BYTE (5)33,00,00,00,00,00(6)0 ; planet
BYTE (5)17,17,17,00,00,00(6)1 ; fed base
BYTE (5)12,12,12,00,00,00(6)1 ; kli base
BYTE (5)04,00,00,00,00,00(6)0 ; fed ship
BYTE (5)37,00,00,00,00,00(6)0 ; kli ship
BYTE (5)31,00,00,00,00,00(6)0 ; interceptor
BYTE (5)01,00,00,00,00,00(6)0 ;Range 3 - rom ship
BYTE (5)06,00,00,00,00,00(6)0 ; star
BYTE (5)36,00,00,00,00,00(6)0 ; planet
BYTE (5)07,00,00,00,00,00(6)0 ; fed base
BYTE (5)07,00,00,00,00,00(6)0 ; kli base
BYTE (5)01,00,00,00,00,00(6)0 ; fed ship
BYTE (5)01,00,00,00,00,00(6)0 ; kli ship
BYTE (5)02,00,00,00,00,00(6)0 ; interceptor
BYTE (5)02,00,00,00,00,00(6)0 ;Range 4 - rom ship
BYTE (5)35,00,00,00,00,00(6)0 ; star
BYTE (5)03,00,00,00,00,00(6)0 ; planet
BYTE (5)01,00,00,00,00,00(6)0 ; fed base
BYTE (5)01,00,00,00,00,00(6)0 ; kli base
BYTE (5)02,00,00,00,00,00(6)0 ; fed ship
BYTE (5)02,00,00,00,00,00(6)0 ; kli ship
BYTE (5)00,00,00,00,00,00(6)7 ; interceptor
BYTE (5)00,00,00,00,00,00(6)7 ;Range 5 - rom ship
BYTE (5)03,00,00,00,00,00(6)0 ; star
BYTE (5)01,00,00,00,00,00(6)0 ; planet
BYTE (5)02,00,00,00,00,00(6)0 ; fed base
BYTE (5)02,00,00,00,00,00(6)0 ; kli base
BYTE (5)00,00,00,00,00,00(6)7 ; fed ship
BYTE (5)00,00,00,00,00,00(6)7 ; kli ship
BYTE (5)00,00,00,00,00,00(6)7 ; interceptor
BYTE (5)00,00,00,00,00,00(6)7 ;Range 6 - rom ship
BYTE (5)01,00,00,00,00,00(6)0 ; star
BYTE (5)02,00,00,00,00,00(6)0 ; planet
BYTE (5)00,00,00,00,00,00(6)7 ; fed base
BYTE (5)00,00,00,00,00,00(6)7 ; kli base
BYTE (5)00,00,00,00,00,00(6)7 ; fed ship
BYTE (5)00,00,00,00,00,00(6)7 ; kli ship
BYTE (5)00,00,00,00,00,00(6)7 ; interceptor
BYTE (5)00,00,00,00,00,00(6)7 ;Range 7 - rom ship
BYTE (5)02,00,00,00,00,00(6)0 ; star
BYTE (5)00,00,00,00,00,00(6)7 ; planet
BYTE (5)00,00,00,00,00,00(6)7 ; fed base
BYTE (5)00,00,00,00,00,00(6)7 ; kli base
BYTE (5)00,00,00,00,00,00(6)7 ; fed ship
BYTE (5)00,00,00,00,00,00(6)7 ; kli ship
BYTE (5)00,00,00,00,00,00(6)7 ; interceptor
V.ELEM: XWD 0,"0 " ;Viewer element table
XWD 1,"1~" ;
XWD 1,"0~" ;a list of all characters that can be displayed
XWD 1,"0." ;in the viewer area
XWD 22,"0-" ;
XWD 1,"1*" ;left half: 1st digit is color, 2nd is mode
XWD 1,"0*" ; 0 - can be displayed in any mode
XWD 52,"0-" ; 1 - requires graphics mode
XWD 60,"00" ; 2 - requires ASCII mode
XWD 51,"08" ;
XWD 51,"0=" ;right half - 1st character:
XWD 41,"0(" ; 0 - normal intensity
XWD 41,"0)" ; 1 - bold (increased) intensity
XWD 41,"0@" ;
XWD 21,"0f" ;right half - 2nd character:
XWD 52,"0o" ; character to be displayed
XWD 52,"0O"
XWD 21,"0p"
XWD 21,"0q"
XWD 61,"0r"
XWD 51,"0t"
XWD 51,"0u"
XWD 22,"0v"
XWD 20,"0V"
XWD 61,"0q"
XWD 51,"0-"
XWD 51,"0H"
XWD 41,"0O"
XWD 31,"1*"
XWD 1,"0+"
XWD 62,"0o"
XWD 62,"0-"
;For VT241s
SETPHA: ;Phaser setup is the same as...
SET241: [ASCIZ /
PpS(M0(AD)1(AC)2(AW)3(AY))
\/] ;...initial setup
SETTOR: [ASCIZ /
PpS(M0(AD)1(AC)2(AW)3(AR))
\/] ;When torps are fired
HIT241: [ASCIZ /
PpS(M0(AW)1(AR)2(AD)3(AM))
\/] ;Reverse when we are hit
SBAUDR==^D1200 ;Baud rate below which we allow
; the "S " command to work.
TOTSP: BLOCK 1
MPPTR: BLOCK 1
MWPTR: BLOCK 1
MPTRA: BLOCK 1
MPTRB: BLOCK 1
MCOL: BLOCK 1
MTXT.A: BLOCK 13
MTXT.B: BLOCK 13
SUBTTL Macro Definitions
; TYPE types an ASCII string without a CRLF.
; TYPEC types an ASCII string followed by a CRLF.
; CRLF types a CRLF.
; .TTSTR builds an ASCII string without a CRLF.
; .TTSTC builds an ASCII string followed by a CRLF.
SUBTTL UUO Definitions
; Displays in the 4-line display area and on the message line are
; performed using local UUOs. The DSP UUOs display in the display
; area. The MSP UUOs display on the message line.
LOC 41 ;Must be at this location
CALL UUOSER ;UUO service routine
RELOC
SUBTTL Macro & UUO Handling Routines
;MORFLS - Cause MOR key to flash
MORFLS: OUTSTR [ASCIZ /
[m/]
SKIPE .TTTYP ;Skip if VT100
OUTSTR @V.YEL ;Yellow
OUTSTR [ASCIZ /
[5;7m
[22;72HMOR
8/] ;Show the key
OUTSTR [ASCIZ /
[m/] ;Normal cursor again
RET
;MORSTP - Undoes the flashing MOR key
MORSTP: OUTSTR [ASCIZ /
[m/]
SKIPE .TTTYP ;If GIGI
OUTSTR @V.GRN ;Then make it normal color (green)
OUTSTR [ASCIZ /
[22;72HMOR
8/] ;Show the key
OUTSTR [ASCIZ /
[m/] ;Cursor not graphics no more
RET
;UUO service
UUOSER: SAVE AP ;Save stack pointer
LDB AP,[POINT 9,.JBUUO,8] ;Get us an op code
JUMPE AP,UUOERR ;If 0, then we have a problem
CALL @UUOTAB-1(AP) ;Dispatch to correct UUO
REST AP ;Restore stack
RET ;And done
TREK:: RESET% ;Like a good program should
MOVE SP,[IOWD PDLSZ,PDL] ;Set up the stack
MOVE T1,SEGVER ;Get .SHARE version
CAME T1,EV+2 ;Same version as us?
JRST VERERR ;Nope - sorry can't play
CALL INIPSI ;Init the PSI system
CALL VTINI ;Init the terminal
SKIPE DBUGF ;If debugging
JRST TREK2 ;Then skip these tests
CALL VTEST ;Test terminal
CALL FINTTY
TREK2: CALL SETUP ;Init the galaxy
MOVEI C,CCTRAP ;Setup ^C handling
HRRM C,CHNTAB+1 ;Put this in channel table
CALL VTEST
JRST TREK1
TYPE <
[H
[J> ;Blank the screen
CALL GILOAD ;Load GIGI macrographs
CALL DSPCON ;Display the trek console
CALL ENEDSP ;Setup energy display
CALL SHLDSP ;And shield
TREK1: CALL WRPDSP ;Now for current warp factor
CALL ROTRAN
CALL OBLOAD ;Load objects in viewer
DSPCLR ;Clear viewer
MSPCLR
SETZM T.TIME
SETZM T.MORE
;..
SUBTTL Main Program Loop
;..
TRMAIN::CALL VTCMD ;See if command there
SKIPGE T1,C.IMM ;Immediate?
IFNSK. ;If so,
SKIPE T.MORE ;See if more
CALL @T.MORE ;If so, do the more command
JRST TRMAIN ;And loop back
ENDIF.
SKIPN T.MORE ;Still more?
IFSKP. ;If not,
SETZM T.MORE ;Flag no more
MORCLR ;And stop flashing
ENDIF.
MOVE AP,C.DIR ;Get command
CAIE AP,5 ;Some type of help?
IFSKP. ;If so,
CALL HELP ;Be as helpful as we can
JRST TRMAIN ;And see if anything else typed
ENDIF.
JUMPE T1,TR.CMD
TR.IMM: SKIPN T.MORE ;See if we must clear "MOR" key
IFSKP. ;If so,
SETZM T.MORE ;Unflag
MORCLR ;And do it
ENDIF.
CALL @[SRSCAN
SRSCAN
SRSCAN
SRSCAN
LRSCAN
RFPHAS
RFPHOT]-1(T1) ;Dispatch to immediate command
JRST TRMAIN ;And loop back
TR.CMD: SKIPN T.MORE ;More been flashing?
IFSKP.
SETZM T.MORE ;If so, that's enough
MORCLR ;Reset display
ENDIF.
MOVE T1,C.CMD ;Get command
JUMPE T1,TRMAIN ;If none, then go back
CALL @CMDDSP-1(T1) ;Dispatch to command
JRST TRMAIN ;Done, now loop back
SUBTTL Short Range Sensor Scan
;SRSCAN
;
; Short range sensor scan. Search depends on the value of the
; immediate flag:
;
; 1 = Federation, 2 = Klingon, 3 = Planet, 4 = anything
LRSCAN::CALL TARSCN ;Scan the target
IFNSK. ;If no target
MSPINI
MSPTYP <nothing detected by long-range sensors>
MSPOUT
RET
ENDIF.
CALL LSTCLR
AOJ LST,
MOVEM UOT,LUOT.B(LST)
CALL CATALG
MOVE AP,[XWD LUOT.B,LUOT.A]
BLT AP,LUOT.A+4
DSPINI
CALL LSTDSP
CALL LRSHLD
DSPOUT
RET
SUBTTL Long Range Sensor Scan -- Display Target Information
LRSHLD::MOVE AP,U.TAB(UOT)
ANDI AP,17
CAIE AP,7
CAIG UOT,17
SKIPA
RET
DSPINI 2
DSPTYP < shields > ;Prefix shields
SKIPG T3,U.SHLD(UOT) ;Are they up or down?
IFSKP. ;I guess they are up
DSPTYP <UP > ;Say so
IDIVI T3,^D1000 ;Scale down for display
CALL NBROUT ;Show us shield value
RET ;And done
ENDIF.
MOVM T3,T3
DSPTYP <DN > ;Say shields are down
IDIVI T3,^D1000 ;Get a printable value
CALL NBROUT ;Show shield value
DSPTYP <, energy > ;Also display energy remaining
MOVE T3,U.ENER(UOT) ;First we get the energy
IDIVI T3,^D1000 ;Adjust it by scale
CALL NBROUT ;Now display it
RET ;And done
RAPFIR::MSPINI
SKIPN C.NBR1
SKIPE C.NBR2
SKIPA
IFNSK.
SETZM R.FIRE
MSPTYP <weapons in normal mode>
MSPOUT
SKIPE .TTTYP ;Skip if VT100
OUTSTR @V.GRN ;Green for GIGI
TYPE <
[18;68HPHA
[CTOR
8> ;Display in normal mode
TYPE <
[m> ;Restore cursor attributes
RET
ENDIF.
SKIPN T1,C.NBR1 ;Get RF phaser energy
MOVEI T1,^D200 ;If 0, then make it 200 by default
CAILE T1,0 ;If not between 0
CAILE T1,^D1000 ;and 1000, then
JRST RF.ERR ;say this is a problem
SKIPN T2,C.NBR2 ;Get photon count
MOVEI T2,1 ;If 0, then burst default to 1
CAILE T2,0 ;If not between 1 and 3,
CAILE T2,3
JRST RF.ERR ;Then say we have a problem
MOVEM T1,RF.PHA
MOVEM T2,RF.PHO
SETOM R.FIRE
MSPTYP <weapons in rapid fire mode>
MSPOUT
SKIPE .TTTYP ;Skip if VT100
TYPE @V.RED ;Red for GIGIs
TYPE <
[18;68H
[7mPHA
[CTOR
8>
TYPE <
[m> ;Restore cursor attributes
RET
RF.ERR: TYPE <>
RET
SUBTTL Command Support -- Rapid Fire (Shoot Phasers)
RFPHAS::PUSH P,C.CNT
PUSH P,C.NBR1
MOVE C,RF.PHA
MOVEM C,C.NBR1
MOVEI C,1
MOVEM C,C.CNT
CALL PHASER
POP P,C.NBR1
POP P,C.CNT
RET
MOVMSG::PUSH SP,T1
PUSH SP,T2
MOVE T1,SUOT
IMULI T1,^D11
ADDI T1,U.MSG
MOVE T2,T1
HRLI T1,M.MSG
BLT T1,^D10(T2)
POP SP,T2
POP SP,T1
RET
SUBTTL Help File -- Open Help File
OPENIN::SAVE T1,T2 ;Save these for now
HRROI T1,[ASCIZ /HLP/] ;This is the file extension
MOVEM T1,GJBLK+.GJEXT ;Put it in GTJFN argument block
SETZ T2, ;No default strings for anything
MOVEI T1,GJBLK ;GTJFN argument block is here
GTJFN% ;Get a JFN for the help file
ERJMP OPENIX ;Must not be here
MOVEM T1,HLPJFN ;Save help file JFN here
MOVX T2,<FLD(7,OF%BSZ)+OF%RD> ;Open file for read
OPENF%
IFJER. ;If we can't open it
MOVE T1,HLPJFN ;Get the JFN back
RLJFN% ;And release it
JFCL
JRST OPENIX ;Now report error
ENDIF.
OPENIX: REST T1,T2 ;Restore the used ACs
RETSKP ;And return success
SUBTTL Help File -- Read Information in From Help File
READIN::SETZM IO.BLK ;Clear object list display
MOVE AP,[XWD IO.BLK,IO.BLK+1]
BLT AP,IO.BLK+12
MOVE AP,[POINT 7,IO.BLK]
MOVEM AP,IO.PTR
SETZM IO.CNT
RD.1: MOVE T1,HLPJFN ;Get help file JFN
BIN% ;Read a byte
ERJMP CLOSIN ;Probably EOF
CAIN T2,.CHCRT ;Carriage return?
JRST RD.1 ;Yes, now eat LF
CAIN T2,.CHLFD ;End of line?
RETSKP ;Yes, we have read in something
IDPB T2,IO.PTR ;Stick character in this area
AOS IO.CNT ;And keep track of the number of characters
JRST RD.1 ;Get next character from file
SUBTTL Help File -- Close Help File
CLOSIN::SAVE T1 ;Save this AC
MOVE T1,HLPJFN ;Get JFN for help file
CLOSF% ;Get rid of it
JFCL ;Don't care about errors
SETZM HLPJFN ;Say we have no help file for now
REST T1 ;And restore this AC
RET
SUBTTL Standard Scan
;STDSCN
;
; Scans for active objects, skips stars and our ship. Returns
; UOT in UOT and UID in T1. UOT must be initialized to 1 less
; than the 1st U.TAB entry to be scanned. In most cases, this
; value is -1. If object is found, skip return is taken.
LXYZ.1: PUSH P,U.ABSX(UOT)
PUSH P,U.ABSY(UOT)
PUSH P,U.ABSZ(UOT)
LXYZ.2: POP P,Z1
POP P,Y1
POP P,X1
RET
SUBTTL Display Warp Factor on Console
WRPDSP::SKIPE .TTTYP ;Skip if VT100
OUTSTR @V.GRN ;Green
TYPE <
[16;39H> ;Position cursor
MOVE T1,S.WARP ;Get current warp setting
TRO T1,"0" ;ASCIIfy it
OUTCHR T1 ;Show it to the user
TYPE <
[m> ;Reset cursor attributes
RET
ENE.ER: SUB T1,U.ENER(SUOT)
MSPINI
MSPTYP <insufficient energy, >
CALL FLTDSP
MSPTYP < units required>
MSPOUT
RET
SUBTTL Energy Display on Console
ENEDSP::SKIPE .TTTYP ;Skip if VT100
OUTSTR @V.GRN ;Green
MOVE SUOT,S.UOT
TYPE <
[16;13H> ;Position cursor
MOVE T1,U.ENER(SUOT) ;Get energy
IDIVI T1,^D1000 ;Scale it down
CALL NBRDSP ;Display it
TYPE <
8>
TYPE <
[m> ;Reset cursor attributes
RET
SUBTTL Shield Display on Console
SHLDSP::SKIPE .TTTYP ;Skip if VT100
OUTSTR @V.GRN ;Green
MOVE SUOT,S.UOT
TYPE <
[16;24H> ;Position cursor
SKIPLE U.SHLD(SUOT) ;Shields up?
IFSKP. ;No
TYPE <DN > ;Say they are down
SKIPA ;And go on
ENDIF.
TYPE <UP > ;Shields are up
SHLD.1: MOVM T1,U.SHLD(SUOT) ;Get shield power
IDIVI T1,^D1000 ;Scale it down
CALL NBRDSP ;Now display it
TYPE <
8>
TYPE <
[m> ;Reset cursor
RET
SUBTTL Planet Defense
;PLANET
;
; Planet routine. Responsible for launching and retrieving interceptors.
;
; Planet UOT's are a multiple of 4, ie the last 3 bits are 0. The
; planet's three interceptors immediately follow the planet and have
; UOT's equal to the planet uot plus 1, 2, or 3.
;
; If a planet UOT is known, the interceptor UOT's are also known.
; If an interceptor UOT is known, the planet's UOT can be found by
; changing the last 3 bits of the interceptor uot to 0. A number
; of routines depend on this relationship.
SUBTTL Test For Ship in Range
;SHPTST
;
; Test for nearest ship within a given range of an object. T1 = test
; range. UOT = object UOT. Non-skip return and T1 < 0 if no ship
; is in range. Skip return and T1 = ship UOT if a ship is in range.
; Range is in T2. If object is neutral all ships are tested,
; otherwise only enemy ships are tested.
SHPTST::IMUL T1,T1 ;Square the distance
FLTR T4,T1 ;T4 is the distance to beat
HRRZ C,U.TAB(UOT) ;Get the UOT's U.TAB word
ANDI C,3B31 ;Mask everything but the alliance field
SKIPE C ;Zero means neutral
TRC C,3B31 ;The complement is the enemy
MOVEM C,S.MASK ;Save either neutral (0) or enemy mask
MOVEI T1,117 ;Test ships and interceptors
SETOM F.UOT ;Temp storage if any ship passes the tests
SPT.LP: CAME T1,UOT
SKIPGE T2,U.TAB(T1) ;Active ship?
JRST SPT.NX ;No - skip it
TRNN T2,3B31 ;Neutral?
JRST SPT.NX ;Yes - skip it
MOVE C,T2 ;Going to look for a ship or an interceptor
ANDI C,17
CAIL C,3 ;Ship UIDs are 5 and 6
CAILE C,7 ;Interceptor UID is 7
JRST SPT.NX ;Neither a ship nor an interceptor
SKIPE S.MASK ;If the mask isn't zero,
IFNSK.
XOR T2,S.MASK ;Xor it with U.TAB word;
TRNE T2,3B31 ;If zero, the ship is an enemy,
JRST SPT.NX ;If not zero, it's a friend
ENDIF. ;It's an enemy
SPT.RN: MOVE T3,U.ABSX(UOT) ;Compute range ** 2 = (X1 - X2) ** 2
FSBR T3,U.ABSX(T1)
FMPR T3,T3 ;If any intermediate square is greater than
CAMLE T3,T4 ;the squared least distance
JRST SPT.NX ;the ship is not nearest or is out of range.
MOVE C,U.ABSY(UOT)
FSBR C,U.ABSY(T1)
FMPR C,C
CAMLE C,T4 ;Test the y distance
JRST SPT.NX
FADR T3,C
MOVE C,U.ABSZ(UOT)
FSBR C,U.ABSZ(T1)
FMPR C,C
CAMLE C,T4 ;Test the Z distance
JRST SPT.NX
FADR T3,C
CAMLE T3,T4 ;Test the total distance
JRST SPT.NX ;Ship is not closest or is out of range
MOVEM T3,T4 ;Store the new least distance
MOVEM T1,F.UOT ;Save the ship's uot
SPT.NX: SOJGE T1,SPT.LP
SKIPGE T1,F.UOT ;F.UOT < 0 means no target found.
RET
MOVEM T4,F.DATA
MOVEI C,F.LOC
SAVE T1
CALL SQRT.##
FIXR T2,RS
REST T1
RETSKP
TRWAIT::MOVE T2,TOTSP ;Get termnal speed
CAIG T2,^D300
RET
TYPE <
[0;2q>
GETIME AP
ADD AP,T1
MOVEM AP,T.TIME
TR.WT: MOVEI T1,^D250
DISMS%
CALL QTEST
GETIME AP
CAMGE AP,T.TIME
JRST TR.WT
TYPE <
[q>
RET
SUBTTL Phaser Hit
PHAHIT::SKIPG O.RELX(UOT)
RET
FIX T1,O.RANG(UOT)
CAILE T1,^D1028
RET
SAVE T1
CALL CONUOT
CALL CONURC
REST T1
HLRZ T3,EVNT.B(P1) ;Get energy
MOVEI C,^D3 ;Standard size flash05
CAILE t3,^D500 ;Stronger than 500 units
MOVEI C,^D4 ;Yes, make flash bigger
CAILE T1,^D512 ;Is it farther than 512
SUBI C,^D1 ;Yes, make flash smaller
MOVEM C,FLSH.C
CALL FLASCI
RET
FLASCI: CALL FLSHLD
OUTSTR V.ASC
TYPE <
[1;7m>
CALL FLSHBR
TYPE <
[m>
CALL FLSHCH
TYPE <
8>
OUTSTR V.ASC
MOVEI T1,7
MOVEM T1,V.COLR
RET
SUBTTL Photon Hit
PHOHIT::SKIPG O.RELX(UOT)
RET
FIX T1,O.RANG(UOT)
CAILE T1,^D1792
RET
SAVE T1
CALL CONUOT
CALL CONURC
REST T1
MOVEI C,^D5 ;Largest flash size,flsh16
CAILE T1,^D128 ;Is it farther than 128?
MOVEI C,^D4 ;Yes, flsh11
CAILE T1,^D512 ;Is it farther than 512?
MOVEI C,^D3
CAILE T1,^D768 ;Is it farther than 768?
MOVEI C,^D2 ;Yes,flsh03
CAILE T1,^D1028 ;Is it farther than 1028?
MOVEI C,^D1 ;Yes,flsh01
MOVEM C,FLSH.C
CALL FLASCI
RET
SUBTTL Display Explosion
EXPLOD::SKIPG O.RELX(UOT)
RET
FIXR T1,O.RANG(UOT)
CAILE T1,^D3072
RET
SAVE T1,UOT
CALL SCNDEL
SKIPN ROW,ROW.1
IFSKP.
CAMN ROW,T.ROW
CALL TARUPD
MOVE ROW,ROW.1
SETOM V.FLAG
CALL VWRCHG
ENDIF.
REST UOT
CALL CONUOT
CALL CONURC
REST T1
IDIVI T1,^D512
HRRZ C,U.TAB(UOT)
ANDI C,17
CAIN C,7 ;Is it an interceptor?
ADDI T1,4 ;Yes, smaller explosion
CAIN C,3 ;Is it a Federation base?
SUBI T1,2 ;Yes, make it a bigger explosion
CAIN C,4 ;Is it a Klingon base?
SUBI T1,2 ;Yes, make it a bigger explosion
CAIL T1,7
RET
MOVEI C,^D7
SUB C,T1
MOVEM C,FLSH.C
CALL FLALT
RET
SUBTTL Ship Destoryed!
ZAPPED::MOVSI C,1B18
IORM C,U.TAB(SUOT)
MOVE UOT,SUOT
ANDI UOT,1
SETZ C,
ZAP.1: SKIPL U.TAB(UOT)
AOJ C,
ADDI UOT,2
CAIG UOT,SH.MX
JRST ZAP.1
SKIPN .GRTYP
IFSKP.
SKIPN VT241F
TYPE <
Ppp[767,23]@z@z@z@z
\>
ENDIF.
TYPE <
[12;41H
[2K
[B
[2K>
TYPE <
[2A
[2K
[3B
[2K>
TYPE <
[4A
[2K
[5B
[2K>
TYPE <
[6A
[2K
[7B
[2K>
TYPE <
[8A
[2K
[9B
[2K>
TYPE <
[10A
[2K
[11B
[2K>
TYPE <
[12A
[2K
[13B
[2K>
TYPE <
[14A
[2K
[15B
[2K>
TYPE <
[16A
[2K
[17B
[2K>
TYPE <
[18A
[2K
[19B
[2K>
TYPE <
[20A
[2K
[21B
[2K>
TYPE <
[22A
[2K
[23B
[2K>
TYPE <
[;5m>
OUTSTR V.ASC
MOVEI T1,[ASCIZ /
[12;9H
#3/]
SKIPN C
MOVEI T1,[ASCIZ /
[8;9H
#3/]
OUTSTR (T1)
OUTSTR @O.NAME(SUOT)
TYPE < Destroyed!>
MOVEI T2,[ASCIZ /
[13;9H
#4/]
SKIPN C
MOVEI T2,[ASCIZ /
[9;9H
#4/]
OUTSTR (T2)
OUTSTR @O.NAME(SUOT)
TYPE < Destroyed!>
SKIPE C
IFSKP.
MOVEI T1,[ASCIZ /FEDERATION/]
MOVEI T2,[ASCIZ /KLINGON EMPIRE/]
TRNE UOT,1
EXCH T1,T2
TYPE <
[12;9H
#3>
OUTSTR (T1)
TYPE < Defeated!>
TYPE <
[13;9H
#4>
OUTSTR (T1)
TYPE < Defeated!>
TYPE <
[16;9H
#3>
OUTSTR (T2)
TYPE < Victorious!>
TYPE <
[17;9H
#4>
OUTSTR (T2)
TYPE < Victorious!>
ENDIF.
TYPE <
[3B
[m>
MOVEI T1,.CTTRM ;This terminal
DOBE% ;Wait till all characters displayed
CALL STWAIT
AOS A.SHIPS ;Add 1 to auto ship count
CALL WRAPUP
MOVSI C,2000
LSH C,@SUOT
ANDCAM C,MASK.Q
JRST FINI
SUBTTL Energy Transfer Notification
ENETRN::CALL ENEDSP
CALL SHLDSP
MSPINI
MSPTYP <transfer complete>
MSPOUT
RET
SUBTTL Display Sent Message
DSPMSG::IMULI UOT,^D11
TYPE <>
MSPINI
MSPSTR U.MSG(UOT)
MSPOUT
RET
MNM.BS: MSPTYP <Starbase >
MNM.RS: MSPSTR @O.NAME(UOT)
RET
SUBTTL Unmanned Ship Phaser/Photon Control
;AUTPHA, AUTPHO
;
; Weapons fire from a base, interceptor, or unmanned ship. UOT is
; uot of firing entity. T1 is uot of receiving entity. uses A.FIRE
; work area. AUTPHA fires 200 units phaser, AUTPHO fires 1 torpedo.
ENEADD::IMULI T1,^D1000
SKIPG C,U.SHLD(UOT)
JRST EDA.2
SUB C,T1
IFGE. C
CAIG C,^D100000
MOVN C,C ;Shields down
MOVEM C,U.SHLD(UOT)
RET
ENDIF.
EDA.1: MOVN T1,C
SETZB C,U.SHLD(UOT)
EDA.2: ADD T1,U.ENER(UOT)
SUB T1,C ;C is < 0 - this is an add
CAMLE T1,MAX.EN
MOVE T1,MAX.EN
ADD T1,C ;C is < 0 - this is a subtract
MOVEM T1,U.ENER(UOT)
RET
ENEDEL::IMULI T1,^D1000
SKIPGE AP,U.SHLD(UOT)
JRST EDL.1
SUB AP,T1
JUMPL AP,EDL.2
CAIG AP,^D100000
MOVN AP,AP
MOVEM AP,U.SHLD(UOT)
RET
EDL.1: MOVM AP,U.SHLD(UOT)
ADD T1,T1
SUB AP,T1
JUMPL AP,EDL.3
MOVNM AP,U.SHLD(UOT)
RET
EDL.2: ADD AP,AP
EDL.3: MOVM T1,AP
SETZM U.SHLD(UOT)
EXCH T1,U.ENER(UOT)
SUBM T1,U.ENER(UOT)
RET
EQEXEC::HRRZ UOT,EVNT.B(P1) ;Get the UOT of the 'object' ship.
HRRZ T1,EVNT.A(P1) ;Get the event code.
ANDI T1,77 ;Mask the event code fields.
CAIE T1,0 ;Return if zero.
JRST @XECDSP-1(t1) ;Notify planet has rebelled.
RET ;None of the above.
XECDSP: MOVOBJ ;Movement.
DELOBJ ;Delete an object.
DSPMSG ;Display ship-ship message
HITDSP ;Display a hit.
HITREQ ;Process a hit.
HITACK ;Acknowledge a hit.
HITDST ;Hit caused an object's destruction.
ENETRN ;Transfer energy.
DETMSG ;Notify detected or attacking.
DALERT ;Notify needs assistance.
REBMSG
SUBTTL Event Queue Routines -- Hit Request
;HITREQ
;
; Initiated by the PHASER, PHOTON, or AUTHIT routines. Determines
; whether an object has been hit. Two cases are handled:
;
; 1: Something hits us (UOT = SUOT).
; 2: We hit a non-ship (UOT not = SUOT).
;
; In both cases, only one ship processes a hit request (and therefore
; has exclusive control of the evnt data). Depending upon the outcome
; of this routine, the hit request is changed to a hit acknowledge
; (HITACK) or a hit destroy (HITDST), and the evnt.a ship mask is
; changed so that other ships can process it.
HITREQ::MOVEI AP,6 ;Hit acknowledge event code
HRRM AP,EVNT.A(P1)
CAME UOT,SUOT
JRST HR.OTH
HR.US: HLRZ AP,EVNT.A(P1)
ANDI AP,377
SKIPGE U.TAB(AP)
RET
CALL HITTST
RET
HLRZ T1,EVNT.B(P1)
CALL ENEDEL
CALL HITUS
MOVM AP,U.SHLD(UOT)
ADD AP,U.ENER(UOT)
SKIPGE AP
IFSKP.
CALL HITMSG
JRST HITCHG
ENDIF.
AOS EVNT.A(P1)
CALL HITCHG
JRST ZAPPED
;Ship hit by an attack in distance
HITDST::CALL EXPLOD
CALL DSTMSG
RET
SUBTTL Event Queue Routines -- Notification Of Attacks
ATTMSG::MOVE C,EVNT.A(P1)
TRNN C,1B18
RET
MOVE C,ALLY.U
TDNN C,U.TAB(UOT)
RET
MSPINI
SAVE UOT
HLRZ UOT,EVNT.A(P1)
ANDI UOT,377
CALL MSPNAM
MSPTYP < attacking >
REST UOT
CALL MSPNAM
MSPOUT
RET
SUBTTL Event Queue Routines -- Notification Of Ship Destruction
DSTMSG::HRRZ C,U.TAB(UOT)
ANDI C,17
CAIN C,7
RET
MSPINI
CALL MSPNAM
MSPTYP < destroyed>
MSPOUT
RET
SUBTTL Event Queue Routines -- Notification Of Enemy Detection
DETMSG::MSPINI
MOVE C,EVNT.A(P1)
TLNE C,1B27
JRST DET.A
DET.D: CALL MSPNAM
MSPTYP < detected by >
SAVE UOT
HLRZ UOT,EVNT.A(P1)
ANDI UOT,377
CALL MSPNAM
REST UOT
MSPOUT
RET
DET.A: SAVE UOT
HLRZ UOT,EVNT.A(P1)
ANDI UOT,377
CALL MSPNAM
REST UOT
MSPTYP < attacking >
CALL MSPNAM
MSPOUT
RET
SUBTTL Event Queue Routines -- Notification Of Planet Rebellion
REBMSG::MSPINI
MSPTYP <rebellion on >
MSPSTR @O.NAME(UOT)
MSPOUT
RET
SUBTTL Event Queue Routines -- Display Alert
DALERT::MSPINI
MSPSTR @O.NAME(UOT)
HLRZ C,EVNT.B(P1)
XCT [MSPTYP < needs assistance>
MSPTYP < on RED ALERT>
MSPTYP < on YELLOW ALERT>
MSPTYP < secure from alert>](C)
MSPOUT
RET
SUBTTL Unmanned Ship Control Missions
;STSHIP
;
; These routines control the activities of unmanned ships. Ship
; behavior is governed by a set of 'missions'.
STSH.2: CALL AI.REF
RET
CALL @[AC.ESH
AC.EBA
AC.CAP
AC.HLP]-2(T4)
RET
STSH.3: CALL AI.ESH
RET
CALL AI.HLP
RET
CALL AI.EBA
RET
CALL AI.CAP
RET
JRST AU.SEA
SUBTTL Ship Mask Setup
;ASETUP
;
; Sets up us-them masks for this ship.
SUBTTL Build Ranges For All Non-star Objects
;NRLOAD
;
; Builds a table of ranges from this ship for all non-star objects.
; saves the UOT and range of the nearest object of a class (planet,
; Fed base, Kli base, etc) and of the nearest neu, Fed, and Kli
; planet. Also catalogs objects within 1024 units (short range
; scan function).
SUBTTL Unmanned Ship Missions -- Travel to Planet/Base
;AU.SEA, MISSION 0
;
; The basic mission, performed when no other mission applies.
; A tour at warp 7 of all bases and friendly planets. Refuels
; at each stop.
SUBTTL Unmanned Ship Missions -- Allocate Energy to Shields
;SALLOC
;
; Allocates a percent of UOT's total energy to the shields. T1
; contains the integer percent, eg 50 for 50 percent.
SUBTTL Find Nearest Base
;AUBASE
;
; Returns UOT of nearest base in T1, range in T2. If no base exists,
; T1 < 0 and non-skip, otherwise a skip return.
SUBTTL Automatic Ship Movement
;AUTMOT
;
; Moves UOT toward or away from coor A.ABSn at warp factor T2.
; T2 > 0 moves toward, T2 < 0 moves away. Adjusts T2 down if
; insufficient energy for move, after 50/50 reallocation. Skip
; return if move okay. Non-skip return if ship needs energy.
; T1 must contain range from UOT to coordinates.
GCHK.4: MOVE T1,U.WAIT(UOT) ;Get the wait time.
SUB T1,T2 ;Subtract the current time.
IDIVI T1,^D1000 ;Convert to seconds.
JUMPLE T1,[SETZM U.TTY(UOT) ;if not > 0, reset the tty nr
RET] ;and return.
TYPE <
[H
[JRe-entry in > ;Must wait - TYPE the wait message.
IDIVI T1,^D60 ;Display the time in mins and secs.
PUSH P,T2 ;Routine displays minutes if minutes
SKIPN T1 ; are > 0, otherwise only displays
IFSKP. ; seconds.
PUSH P,T1
CALL TIMOUT
TYPE < minute>
MOVEI C,[ASCIZ /s, /]
POP P,T1
CAIN T1,1
MOVEI C,[ASCIZ /, /]
OUTSTR (C)
ENDIF.
MOVE T1,0(P)
CALL TIMOUT
TYPE < second>
POP P,T1
CAIE T1,1
TYPE <s>
CRLF
SETZM I.LOCK
HALTF%
INCHRW C
CAIN C,"Z"
RET
JRST FINI
SUBTTL Display Current Time
TIMOUT: IDIVI T1,^D10 ;Displays a number without leading
SAVE T2 ;zeroes.
SKIPE T1
CALL TIMOUT
REST T2
ADDI T2,"0"
OUTCHR T2
RET
SUBTTL Startup Interlock Routine
;INTLOK
;
; Prevents two players from starting up at the same time. If I.LOCK < 0
; hibers for a second and tries again. When other player is finished
; I.LOCK will be = 0. This routine then sets I.LOCK < 0 to exclude
; other players and returns.
INTLOK::TIME%
SETO C,
EXCH C,I.LOCK
JUMPE C,ILOK.2 ;Interlock set - exit
MOVE C,t1 ;Compares current time with I.TIME,
SUB C,I.TIME ;Which is the time the other player
SKIPGE C ;grabbed I.LOCK. if the difference
MOVN C,C ;If > 5 mins, assume something is
CAMLE C,[^D300000] ;wrong (crash during startup) and
JRST ILOK.2 ;give player control immediately.
TYPE <
[H
[JStart-up interlock, please stand by >
ILOK.1: EXCH C,T1
MOVEI T1,^D1000 ;Wait 1
DISMS%
EXCH T1,C
SETO C,
EXCH C,I.LOCK
JUMPN C,ILOK.1
ILOK.2: MOVEM T1,I.TIME ;Save for future use by other startups.
RET ;Player now controls interlock.
SUBTTL Display Ships in Play
;SU.PLA
;
; Displays ships currently in play.
SU.PLA::MOVEI T1,SH.MX+1
SU.PL0: SOJL T1,R
SKIPL C,U.TAB(T1)
TLNN C,1B19
JRST SU.PL0
CRLF
TYPEC <Ships in play:>
CALL SU.HED
MOVEI C,.CHCRT
MOVNI T1,2
MOVNI T2,1
SU.PL1: CRLF
SETZ T3,
SU.PL2: CAIL T1,6
JRST SU.PL3
ADDI T1,2
SKIPL T4,U.TAB(T1)
TLNN T4,1B19
JRST SU.PL2
OUTCHR C
TYPE < >
OUTSTR @O.NAME(T1)
OUTCHR C
TYPE <
[15C>
MOVE UOT,T1
CALL SU.USR
SETO T3,
SU.PL3: CAIL T2,7
JRST SU.PL4
ADDI T2,2
SKIPL T4,U.TAB(T2)
TLNN T4,1B19
JRST SU.PL3
OUTCHR C
TYPE <
[38C>
OUTSTR @O.NAME(T2)
OUTCHR C
TYPE <
[51C>
MOVE UOT,T2
CALL SU.USR
JRST SU.PL1
SU.PL4: JUMPN T3,SU.PL1
RET
SU.USR: TYPE <(>
SAVE T1,T2
MOVEI T1,.PRIOU
MOVE T2,U.NAMX(UOT)
DIRST%
JFCL
REST T1,T2
TYPE <)>
RET
SUBTTL Dsiplay Available Ships
;SU.AVA
;
; Displays ships currently available.
USRLOD: GJINF%
MOVEM T3,U.JOB(SUOT)
MOVEM T1,U.NAMX(SUOT)
MOVEM T4,U.TTY(SUOT)
RET
SUBTTL Random Rotation
ROTRAN::MOVEI C,^D360
MOVEM C,RAN.MX
SETZM RAN.MN
CALL RANDOM
FLTR T1,T1
MOVEM T1,B1
CALL RANDOM
FLTR T1,T1
MOVEM T1,E1
CALL ROT.ZY
RET
SUBTTL Select Ship At Startup
;SELECT
;
; First player in the game selects startup options. This routine
; initializes the game.
SELECT::TYPE <
[H
[JEnter a tournament number from 1 to 9 >
TYPEC <to load a tournament game;>
TYPE <Enter any other character to load a random game: _
[D
7>
INCHRW P2
OUTCHR P2
CRLF ;Display CRLF to acknowledge.
CAIL P2,"1"
CAILE P2,"9"
JRST SEL.RN
SEL.TR: MOVEM P2,GAM.NR ;Tournament game:
ANDI P2,17 ;cycle the randomizer 3 * tournament
IMULI P2,3 ;number times.
SELTR1: CALL RANDOM
SOJG P2,SELTR1
JRST SEL.LD
SEL.RN: SETZM GAM.NR ;Random game:
CALL RANSET ;Seed the randomizer with time (ms)
SEL.LD: CALL LOADQ ;Init the queue.
MOVEI C,^D8
MOVEM C,A.SHIPS
JRST LOADU ;Init the universal object table.
SUBTTL Load Universal Object Table
;***** LOADU
;
; Loads the universal object table. All objects are loaded,
; including inactive ships. Objects are spaced a minimum of
; 512 units from each other.
LOADU:: SETZ UOT,
LU.NXT: CALL LU.UOT
CAIN T1,7
JRST LOADU1
CALL LU.LIM ;Get range limits
LUNXT1: CALL LU.XYZ ;Get universal X, Y, and Z
CALL LU.TST ;Test 512 distances
JRST LUNXT1 ;Not 512 from all other objects
CALL LU.MOV ;Move universal X, Y, and Z to UOT
LOADU1: CAIGE UOT,217 ;All objects loaded?
AOJA UOT,LU.NXT ;No, repeat for next object
RET ;Table loaded
LU.LIM: MOVEI T2,1
CAIE T1,1 ;Star?
IFSKP.
MOVEI T1,^D4000
JRST LU.LM1
ENDIF.
CAIE T1,2 ;Planet?
IFSKP.
MOVEI T1,^D2000
JRST LU.LM1
ENDIF.
MOVEI T2,^D1250 ;Set narrow limits
MOVEI T1,^D2250 ;Assures a reasonable separation
LU.LM1: MOVEM T2,RAN.MN ;Save as random number generator
MOVEM T1,RAN.MX ;MIN and MAX range
AOS T2,XYZ.I
CAIL T2,10
SETZB T2,XYZ.I
RET ;Return to calling routine
LU.XYZ: CALL RANDOM ;Get random x (ran.nr is also in t1)
MOVEM T1,X1 ;Save as x
CALL RANDOM ;Get random y
MOVEM T1,Y1 ;Save as y
CALL RANDOM ;Get random z
MOVEM T1,Z1 ;Save as z
CALL LU.STR
JRST LU.XYZ
MOVE T2,XYZ.I
MOVE T2,XYZ.T(T2)
MOVE T1,X1
TRNN T2,4 ;Test if x is to be negative
MOVN T1,T1 ;(3 tests will select 1 of 8 sectors)
FLTR T1,T1 ;Convert to floating point
MOVEM T1,X1 ;Save as x
MOVE T1,Y1
TRNN T2,2 ;Test if y is to be negative
MOVN T1,T1 ;(the 2nd test)
FLTR T1,T1 ;Convert to floating point
MOVEM T1,Y1 ;Save as y
MOVE T1,Z1
TRNN T2,1 ;Test if z is to be negative
MOVN T1,T1 ;(the 3rd test)
FLTR T1,T1 ;Convert to floating point
MOVEM T1,Z1 ;Save as z
RET ;Return to calling routine
LU.STR: AOS (P)
MOVE T1,U.TAB(UOT)
ANDI T1,7
CAIE T1,1
RET
MOVEI T1,^D2000
CAMG T1,X1
RET
CAMG T1,Y1
RET
CAMLE T1,Z1
SOS (P)
RET
LU.TST: IFLE. UOT ;Don't test if 1st element
AOS (P) ;Form skip return
RET ;Return to calling routine
ENDIF.
MOVN T3,UOT
HRLZ T3,T3
DO.
MOVE T1,U.TAB(T3)
ANDI T1,7
CAIN T1,7
JRST LU.TS2
MOVE T1,X1 ;Distance formula:
FSBR T1,U.ABSX(T3) ; d ** 2 =
FMPR T1,T1 ; (x - ux) ** 2) +
MOVEM T1,T2 ; (y - uy) ** 2) +
MOVE T1,Y1 ; (z - uz) ** 2)
FSBR T1,U.ABSY(T3)
FMPR T1,T1
FADRM T1,T2
MOVE T1,Z1
FSBR T1,U.ABSZ(T3)
FMPR T1,T1
FADRM T1,T2
CAMG T2,[262144.0] ;Must be greater that 512 ** 2
RET ;Failed test
LU.TS2: AOBJN T3,TOP. ;Try the next entry
OD.
RETSKP ;Passed test for all entries
LU.MOV: MOVE T2,U.TAB(UOT)
ANDI T2,7
MOVE T1,X1 ;Get x
MOVEM T1,U.ABSX(UOT) ;Store x
CAIN T2,2
MOVEM T1,1+U.ABSX(UOT)
MOVE T1,Y1 ;Get y
MOVEM T1,U.ABSY(UOT) ;Store y
CAIN T2,2
MOVEM T1,2+U.ABSY(UOT)
MOVE T1,Z1 ;Get z
MOVEM T1,U.ABSZ(UOT) ;Store z
CAIN T2,2
MOVEM T1,3+U.ABSZ(UOT)
RET ;Return to calling routine
SUBTTL Random Number Generator Seeder
;RANSET
;
; Seeds the FORTRAN random number generator with the current
; time of day.
RANSET::TIME%
MOVEM T1,RAN.SD
PUSH SP,RS
PUSH SP,AP
MOVEI AP,[0,,RAN.SD]
CALL SETRAN##
POP SP,AP
POP SP,RS
RET
SUBTTL Get Random Number
;RANDOM
;
; Gets a random number RAN.NR between RAN.MN and RAN.MAX from the
; FORTRAN random number generator.
RANDOM::MOVE T1,RAN.MX ;The formula is
SUB T1,RAN.MN ;NBR = min + ran * (max - min + 1)
AOJ T1, ;where 0 < ran < 1
FLTR T1,T1
SAVE T1 ;RAN uses T1
SETZ RS,
CALL RAN## ;Number is returned in AC0
REST T1
FMPR T1,RS
FIX T1,T1
ADD T1,RAN.MN
MOVEM T1,RAN.NR
RET
SUBTTL Initialize The PSI System
;INIPSI
;
; Initializes CTRL-C trapping.
INIPSI::CIS% ;Clear interrupt system
MOVEI T1,ICTRAP ;Control-C routine name
HRRM T1,CHNTAB+1 ;Put it in the channel table
MOVEI T1,.FHSLF ;This fork
MOVE T2,[LEVTAB,,CHNTAB] ;Here's the level table and channel table
SIR% ;Set address for those tables
EIR% ;Enable interrupts
MOVX T2,<1B1+1B2> ;Channels 1 and 2
AIC% ;Activate these channels
MOVE T1,[.TICCC,,1] ;Put CTRL-C on channel 1
ATI% ;Do it
ERJMP .+1 ;In case user has disabled this
MOVE T1,[.TICTI,,2] ;Put typein on channel 2
ATI% ;Do it
ERJMP .+1
RET
SUBTTL Control C Trapping Routine
;Here if ^C during game startup
ICTRAP::TYPE <
[H
[J> ;Clear the screen
SETZM I.LOCK ;Clear game interlock
CALL TTYRST ;Reset original terminal characteristics
MOVEI AP,ICEND ;Debreak to here
MOVEM AP,LEV1PC ;Make sure it is seen
DEBRK% ;Done
ERJMP .+1 ;Just in case
ICEND: JRST FINI ;Game is over
;Here if ^C during game
CCTRAP::TYPE <
[H
[J>
CALL STWAIT
MOVE C,U.TAB(SUOT)
TLZ C,1B19
MOVEM C,U.TAB(SUOT)
AOS A.SHIPS ;Add 1 to auto ship count
CALL WRAPUP
MOVEI AP,CCEND
MOVEM AP,LEV1PC
DEBRK%
ERJMP .+1
CCEND: JRST FINI
SUBTTL Reentry Wait
;STWAIT
;
; Sets the time (ms) after which a player may reenter the game.
STWAIT::EXCH C,T1
TIME%
ADD T1,[DEC 120000] ;Add 2 minutes
EXCH T1,C
MOVEM C,U.WAIT(SUOT) ;Save as time to wait.
RET
SUBTTL Cleanup When We Leave (or Are Destroyed)
;WRAPUP
;
; Performs cleanup after a ship is destroyed, quits, or
; Control-C's.
WRAPUP::SKIPE .TTTYP ;Skip if not GIGI
TYPE <
PrVC3
\> ;Turn cursor back on
MOVSI C,2000
LSH C,@SUOT
ANDCAM C,MASK.Q
MOVS C,MASK.C
MOVS T1,MASK.A
MOVEI P1,Q.SIZE-6
WRUP.1: SKIPG EVNT.T(P1)
JRST WRUP.2
ANDCAM C,EVNT.A(P1)
TDNN T1,EVNT.A(P1)
SETZM EVNT.T(P1)
WRUP.2: SUBI P1,6
JUMPGE P1,WRUP.1
WRUP.3: MOVEI C,^D5000
MOVEM C,TIME.Q(SUOT)
MOVEI T1,.PRIIN
CFIBF%
OUTSTR V.ASC
TYPE <
[m>
CALL TTYRST
RET
OBLOAD::CALL OTABLD
CALL SCANLD
CALL TARUPD
CALL VIEWLD
RET
FATAN:: SAVE T1,T2,T3
MOVEM C,F.DATA
MOVEI C,F.LOC
CALL ATAN.##
REST T1,T2,T3
RET
SUBTTL Get Command Sequence From Terminal
;VTCMD
;
; Gets a command sequence from the terminal, returns the following:
;
; c.cmd - nbr of the command (0 = no cmd)
; c.dir - direction
; 0 = no direction
; 1 = up (FED or FWD)
; 2 = down (KLI or BAK)
; 3 = right (ALL)
; 4 = left (PLA)
; 5 = help
; c.nbr1 - 1st number
; c.nbr2 - 2nd number
; c.cnt - number of numbers entered
; c.imm - immediate execute flag
; 0 = no immediate command
; 1 = SR SCAN (FED)
; 2 = SR SCAN (KLI)
; 3 = SR SCAN (ALL)
; 4 = SR SCAN (PLA)
; 5 = LR SCAN
; 6 = RAPID FIRE PAHSER
; 7 = RAPID FIRE PHOTON
; -1 = more
VTCMD:: TYPE <
8>
OUTSTR V.ASC
SETZM C.IMM ;Reset the immediate flag
SKIPLE AP,C.DIR
CAIE AP,5
SKIPA
IFNSK.
SETZM C.DIR
TYPE <
[16;45H
[7m
8>
OUTSTR V.ASC
ENDIF.
VC.1ST: CALL VCGET ;Get 1st char of 1st field
JRST VC.EXE ;Execute entry comes back here
JRST VC.HLP ;Help requests come back here
JRST VC.CAN ;CMD cancel comes back here
JRST VC.CAN ;Backspace (delete) comes back here
CALL VC.IMM ;Test immediate entry (arrow)
JRST VC.EXE ;Immediate execute
SETZM C.CMD ;Reset the returned variables
SETZM C.DIR ;Can't reset these up front because
SETZM C.NBR1 ;An execute can mean repeat a previous
SETZM C.NBR2 ;Command
SETZM C.CNT
CAIE T1,.CHESC ;Escape sequence?
JRST VC.1C ;No - try letters
CALL VC.IFN ;Keypad function (escape followed by number)?
JRST VC.1A ;No - perhaps the keypad dash
ANDI T2,17 ;Convert ASCII to binary
AOJ T2, ;Increment to form command nbr
JRST VC.1B ;Jump to keypad routine
VC.1A: CAIE T2,"-" ;Was it the keypad dash?
JRST VC.1ER ;No - error
MOVEI T2,^D11 ;Yes - substitute 11
VC.1B: MOVEM T2,C.CMD ;Store the command nbr
CALL VC.KBD ;Display the abbr from the cmd table
JRST VC.2ND ;Go get the 2nd field
VC.1C: CAIE T1,0 ;Is the VCGET integer equal to zero?
JRST VC.1ER ;No - error
CALL VC.IFA ;Is the VCGET character a letter?
JRST VC.1ER ;No - error
TYPE <
[16;43H
[7m> ;Position the cursor
OUTCHR T2 ;Display the letter
TYPE <
8> ;Display space and restore cursor
LSH T2,7 ;Shift the letter left one ASCII position
MOVEM T2,I.CHAR ;Save the entry
CALL VCGET ;Get the next character
JRST VC.1D ;Must validate the cmd (exe return)
JRST VC.1D ;Must validate the cmd (hlp return)
JRST VC.CAN ;Cancel the command
JRST VC.CAN ;backspace is equivalent to cancel
CAIE T1,0 ;Is the VCGET integer a zero?
JRST VC.1D ;No - validate 1-char command
CALL VC.IFA ;Yes - is the VCGET char a letter?
JRST VC.1D ;Not a letter - validate 1-char
TYPE <
[16;44H
[7m> ;It was a letter - position cursor
OUTCHR T2 ;Display the letter (conditionally)
TYPE <
8> ;Restore the cursor
IORM T2,I.CHAR ;Combine it with the first letter
CALL VC.TAB ;Find both letters in the table
JRST VC.1ER ;Invalid command, cancel it
JRST VC.2ND ;Valid - go get 2nd field
VC.1D: MOVEI T3,.CHSPC ;Move space
IORM T3,I.CHAR ;Add it as the second cmd character
CALL VC.TAB ;Valid command?
JRST VC.1ER ;No - cancel the command
CAIN T1,^D13 ;Was execute the last entry?
JRST VC.EXE ;Yes (no params entered)
CAIN T2,"?" ;Was help the last entry?
JRST VC.HLP ;Yes
JRST VC.2A ;Assume the 1st letter of 2nd field
VC.1ER: TYPE <> ;Signal an error
TYPE <
[16;43H
[7m
8>
JRST VC.1ST ;Go back to 1st field
VC.2BK: TYPE <
[16;47H
[7m
8> ;(backspace function)
SETZM C.DIR ;Reset dir
SETZM C.NBR1 ;Reset nbr1
SETZM C.CNT ;Reset the count
VC.2ND: CALL VCGET ;Get 1st char of 2nd field
JRST VC.EXE ;No 2nd field - execute (no params)
JRST VC.HLP ;Request for help on given cmd
JRST VC.CAN ;Cancel command
JRST VC.CAN ;Backspace is equivalent to cancel here
VC.2A: MOVE T3,C.CMD
CAIN T3,^D20
JRST VC.2S
MOVEI T3,^D47 ;Entry point when input char is pending
CALL VC.COL ;Setup columns for 2nd field
SETZ T4, ;Zero the offset for arrow entries
CALL VC.ARR ;Test if arrow was entered
JRST VC.3RD ;Yes - go on to 3rd field
CALL VC.NUM ;Number or sign?
JRST VC.2B ;Yes - get rest of 2nd field
TYPE <> ;No - signal error
JRST VC.2ND ;Get the 1st char of 2nd field
VC.2S: CALL VC.SEN
JRST VC.EXE
TYPE <>
JRST VC.2ND
VC.2B: CALL VCGET ;Get the next char of 2nd field
JRST VC.2C ;Execute - must compute nbr1 first
JRST VC.2ER ;Help not allowed here
JRST VC.CAN ;Cancel the command
JRST VC.2BK ;Backspace to beginning of 2nd field
CALL VC.NUM ;Test for number or sign
JRST VC.2B ;Was a number or sign - get next char
VC.2C: MOVE T3,I.NBR ;Get the work number
SKIPE I.SIGN ;Is the sign negative?
MOVNS T3,I.NBR ;Yes - form the negative
MOVEM T3,C.NBR1 ;Store in 1st number
AOS C.CNT ;Increment the count
CAIN T1,^D13 ;Was the last command an execute?
JRST VC.EXE ;Yes - skip field 3
MOVEI T4,7 ;Setup 3rd field offset if arrow
SETZM I.PATH ;Reset direction flag - assume 2 nbrs
CALL VC.ARR ;No - was it an arrow?
JRST VC.4TH ;An arrow - get the terminator
CALL VC.BRK ;Was the entry a break character?
JRST VC.3RD ;Yes - start the 3rd field
VC.2ER: TYPE <> ;None of the above - therefore an error
JRST VC.2B ;Get another character
VC.3BK: TYPE <
[16;54H
[7m
8> ;(Backspace function)
SKIPE I.PATH ;Has a number been entered?
SETZM C.NBR1 ;No - reset nbr1
SETZM C.NBR2 ;Yes - reset nbr2 in any case
VC.3RD: CALL VCGET ;Get 1st char of 3rd field
JRST VC.EXE ;No 3rd field - execute
JRST VC.3X ;Help not allowed here
JRST VC.CAN ;Cancel the command
JRST VC.2BK ;Backspace to 2nd field
MOVEI T3,^D54 ;Setup columns for 3rd field
CALL VC.COL ;Starting at col 54
CALL VC.NUM ;Was the entry a number or a sign?
JRST VC.3B ;Yes - get the rest of 3rd field
SKIPE I.PATH ;Has an arrow been entered already?
JRST VC.3X ;Yes - skip the arrow test
SETZ T4, ;Zero the offset for arrow entries
CALL VC.ARR ;Was an arrow entered?
JRST VC.4TH ;An arrow - get the terminator
VC.3X: TYPE <> ;None of the above - signal an error
JRST VC.3RD ;Restart at 3rd field
VC.3B: CALL VCGET ;Get the next char of the 3rd field
JRST VC.3C ;Execute - must compute nbr first
JRST VC.3ER ;Help not allowed here
JRST VC.CAN ;Cancel the command
JRST VC.3BK ;Backspace to beginning of 3rd field
CALL VC.NUM ;Number or sign entered?
JRST VC.3B ;Yes - get more
VC.3C: MOVE T3,I.NBR ;Get the work nbr
SKIPE I.SIGN ;Is the sign negative?
MOVNS T3,I.NBR ;Yes - form a negative number
SKIPE I.PATH ;Is this the 2nd number?
JRST VC3C1 ;No - store in nbr1
MOVEM T3,C.NBR2 ;Yes - store it
SKIPA ;Skip the next
VC3C1: MOVEM T3,C.NBR1 ;Store in nbr1
AOS C.CNT ;Increment the count
CAIN T1,^D13 ;Was the last character entered an execute?
JRST VC.EXE ;Yes - skip the terminator
VC.3ER: TYPE <> ;None of the above - an error
JRST VC.3B ;Get the next character
VC.4ER: TYPE <> ;Signal an error
VC.4TH: CALL VCGET ;Get a terminator
JRST VC.EXE ;The desired response
JRST VC.4ER ;Help not allowed at this point
JRST VC.CAN ;Cancel the command
SKIPA ;Backspace to field 3
JRST VC.4ER ;Must be a terminator
SETZM C.DIR ;Reset the direction
SETZM I.PATH ;Reset the direction-entered flag
TYPE <
[16;54H
[7m
8>
JRST VC.3RD ;Go back to 3rd field
VC.HLP: TYPE <
[16;45h
[7m?
8> ;Display a "?"
MOVEI T1,5 ;Move 5 to direction, indicating
MOVEM T1,C.DIR ;Request for help
VC.EXE: TYPE <
8>
RET ;The end of the routine
VC.CAN: SETZM C.CMD ;Reset the command nbr
SETZM C.DIR ;Reset the direction
SETZM C.NBR1 ;Reset the 1st nbr
SETZM C.NBR2 ;Reset the 2nd nbr
SETZM C.CNT ;Reset the count
TYPE <
[16;43H
[7m
8>
JRST VC.1ST ;Go back to the beginning
VC.IMM: AOS (SP) ;Form skip - assume not immediate
CAIE T1,.CHESC ;Escape sequence?
RET ;No - can't be immediate (arrow)
CAIE T2,"0" ;Keypad zero? (LR SCAN)
IFSKP. ;Yes,
MOVEI T2,5
JRST VC.IMX
ENDIF.
CAIE T2,"." ;Keypad period? (MORE)
IFSKP.
SETO T2, ;Yes
JRST VC.IMX
ENDIF.
CAIL T2,"A" ;Is the character
CAILE T2,"D" ;One of the letters A, B, C, or D?
SKIPA ;No
IFNSK.
ANDI T2,7 ;Yes - mask out all but last three bits
JRST VC.IMX
ENDIF.
SKIPN R.FIRE ;Rapid fire enabled?
RET ;No - return
CAIE T2,"5" ;RF phasers?
CAIN T2,"6" ;RF photon torpedo?
SKIPA ;Yes
RET ;No
ANDI T2,7 ;Mask the bits
AOJ T2, ;Increment to form immediate cmd
VC.IMX: MOVEM T2,C.IMM ;Store as the immediate flag
SOS (SP) ;Cancel the skip
RET ;Return to calling routine
VC.KBD: TYPE <
[16;43H
[7m> ;Position the cursor at 1st field
MOVE T3,C.CMD ;Get the command nbr
HRRZ T3,C.TAB(T3) ;Move the command abbr
LSH T3,^D22 ;Form an ASCIZ literal
OUTSTR T3 ;Display it
TYPE <
[7m
8> ;Clear and restore cursor
RET ;Return to calling routine
VC.COL: MOVEM T3,I.SPOS ;Store sign position
AOJ T3, ;Add 1
MOVEM T3,I.POS ;Store as first nbr position
ADDI T3,3 ;Compute the last allowable position
MOVEM T3,I.MAX ;And store it
SETZM I.NBR ;Reset the work nbr
SETZM I.SIGN ;Reset the sign flag
RET ;Return to calling routine
VC.ARR: AOS (SP) ;Form skip - assume not an arrow
CAIE T1,.CHESC ;Escape sequence?
RET ;No - can't be an arrow
MOVE T3,I.SPOS ;Get the cursor position
ADD T3,T4 ;Add the offset, if any
CAIL T2,"A" ;Is the character
CAILE T2,"D" ;One of the letters A, B, C, or D?
RET ;No - return to calling routine
SOS (SP) ;Yes - cancel the skip - it's an arrow
CALL VPOS ;Position the cursor
ANDI T2,7 ;Convert char to a directional nbr
MOVEM T2,C.DIR ;Store the direction
MOVE T3,C.CMD ;Get the command nr
HLRZ T3,C.TAB(T3) ;Get the d.tab offset
ADD T3,T2 ;Add the direction
TYPE <
[7m>
OUTSTR D.TAB(T3) ;Display the direction literal
TYPE <
8> ;Display final spaces and restore cursor
SETOM I.PATH ;Set flag indicating arrow was entered
RET ;Return to calling routine
VC.SEN: AOS (SP)
CAIE T1,.CHESC
JRST VC.SN1
MOVSI T3,-4
VCSEN1: CAME T2,[EXP "A","B","C","D"](T3)
AOBJN T3,VCSEN1
SKIPL T3
RET
MOVE T3,[EXP 1, 2, 0, 0](T3)
JRST VC.SN2
VC.SN1: TRZ T2,1B30
MOVSI T3,-^D11
VCSN11: CAME T2,[EXP "A","F","K","E","C","I","H","L","P","V","R"](T3)
AOBJN T3,VCSN11
SKIPL T3
RET
VC.SN2: TYPE <
[16;48H
[7m>
HRRZ T3,T3
MOVEM T3,C.NBR1
AOS C.CNT
CAILE T3,2
JRST VC.SN3
IMULI T3,3
OUTSTR [ASCIZ/ALL /
ASCIZ/FEDERATION/
ASCIZ/KLINGON /](T3)
JRST VC.SN4
VC.SN3: MOVE UOT,T3
SUBI UOT,3
OUTSTR @O.NAME(UOT)
VC.SN4: SOS (SP)
RET
VC.TAB: MOVE T3,I.CHAR ;Move the two command characters
MOVSI T4,-C.SIZE ;Get the command table size
VCTAB1: HLL T3,C.TAB(T4)
CAME T3,C.TAB(T4) ;In the table?
AOBJN T4,VCTAB1 ;Bump the pointer, try again
IFL. T4 ;If not negative, it's not in the table
HRRZM T4,C.CMD ;Not zero - save the command nbr
RETSKP ;And skip return
ENDIF.
RET ;Return to calling routine
VC.NUM: AOS (SP) ;Form skip return - assume not a number
CALL VC.IFN ;Test numeric
JRST VC.SIG ;Not a number, try a sign
SOS (SP) ;Cancel the skip ret
MOVE T3,I.POS ;Get the column nbr
CAMG T3,I.MAX ;Greater than max allowed?
JRST VCNUM1 ;No - continue
TYPE <> ;Yes - signal the error
RET ;Return to calling routine
VCNUM1: CALL VPOS ;Position the cursor
TYPE <
[7m>
OUTCHR T2 ;Display the number
TYPE <
8> ;Restore the cursor
AOS I.POS ;Increase the column nbr
ANDI T2,17 ;Convert ASCII to binary nbr
MOVEI T3,^D10 ;Set the multiplier
IMULM T3,I.NBR ;Multiply the work number
ADDM T2,I.NBR ;Add the input number
RET ;Return to calling routine
VC.SIG: CAIN T2,"-" ;Minus sign?
JRST VCSIG1 ;Yes - continue
CAIE T2,"+" ;Plus sign?
RET ;Neither sign, ret
SETOM I.SIGN ;Set sign word to -1
VCSIG1: SETCMM I.SIGN ;Complement the sign
MOVE T3,I.SPOS ;Get column for sign
CALL VPOS ;Position the cursor
MOVEI T3,"-" ;Assume negative
SKIPL I.SIGN ;Skip if valid assumption
MOVEI T3,.CHSPC ;Wasn't negative after all, use space
TYPE <
[7m>
OUTCHR T3 ;Display the sign
TYPE <
8> ;Restore the cursor
SOS (SP) ;Cancel the skip ret
RET ;Return to calling routine
VC.BRK: CAIN T2,"." ;Is the character a period?
RET ;Yes - return
CAIN T1,.CHTAB ;Is the character a tab?
RET ;Yes - return
CAIE T1,0 ;Is the entry from the main keyboard?
RETSKP ;No - can't be a break, then RETSKP
CAIE T2,.CHSPC ;Is the character a space?
AOS (SP) ;Not a break - form skip ret
RET ;Return to calling program
VC.IFA: TRZ T2,1B30 ;Convert to uppercase
CAIL T2,"A" ;Is this a letter?
CAILE T2,"Z"
RET ;Not a letter
AOS (SP) ;It's a letter - form skip ret
RET ;It's out of range - no skip ret
VC.IFN: CAIL T2,"0" ;Is this a number?
CAILE T2,"9"
RET ;Not a number
AOS (SP) ;It's a number - form a skip ret
RET ;It's out of range - no skip ret
VCGET: CALL VTGET ;Get input integer and character
MOVE T1,C.INTE ;Load the integer
MOVE T2,C.CHAR ;Load the character
CAIN T1,.CHCRT ;Execute key? (carriage ret)
RET ;Yes - normal ret
AOS (SP) ;Form skip return 1
CAIN T2,"?" ;Help function?
RET ;Yes - skip return 1
AOS (SP) ;Form skip return 2
CAIN T2,.CHDEL ;Delete?
RET ;Yes - skip return 2
AOS (SP) ;Form skip return 3
CAIN T1,.CHBSP ;Backspace?
RET ;Yes - skip return 3
CAIN T2,"," ;Erase function? (same as backspace)
RET ;Yes - skip return 3
RETSKP ;Form skip return 4
SUBTTL Scans -- Jacket Routine
SCANLD::CALL SCNCLR
MOVEI UOT,217
SKIPE S.STAR ;Display stars?
MOVEI UOT,117 ;No - skip them then
SCNLD1: SKIPGE U.TAB(UOT)
JRST SCNLD2
CAME UOT,S.UOT
CALL SCNTST
SCNLD2: SOJGE UOT,SCNLD1
RET
SUBTTL Scans -- Test to See if Object is in Scanning Range
;SCNTST
;
; Tests whether an object is in scan range. If so, SCNUPD is
; called (updating scan tables) and ROW.2 is set = to the row
; containing the object.
SCNTST::SETZM ROW.2
SKIPG O.RELX(UOT) ;Object in front of us?
RET ;No - can't be in viewer
MOVM T1,O.ELEV(UOT) ;Object has a reasonable elevation?
CAMLE T1,[0.404026226]
RET ;No
MOVM T1,O.BEAR(UOT) ;Object has a reasonable bearing?
CAMLE T1,[1.625476800]
RET ;No
FIX T1,O.RANG(UOT)
CAIG UOT,117 ;If the object isn't a star,
CAIG T1,^D2048 ;Is it out of range?
SKIPA ;No - it's in range
RET ;Yes - it's out of range
MOVE AP,O.ELEV(UOT) ;Compute the exact row
CALL FATAN
FMPR RS,[14.32394488]
MOVE ROW,[7.0]
FSBR ROW,RS
FIXR ROW,ROW
SKIPLE ROW
CAILE ROW,^D13
RET ;Row not in viewer
MOVE AP,O.BEAR(UOT) ;Compute the exact column
CALL FATAN
FMPR RS,[35.80986218]
FADR RS,[41.0]
FIXR COL,RS
CAIL COL,6
CAILE COL,^D76
RET ;Column not in view
MOVEM ROW,ROW.2
CALL SCNUPD
RET
SUBTTL Scans -- Clear Scan Table
;SCNCLR
;
; Zeroes out the scanner table and moves zero to S.MAX, the
; number of elements in the table.
SCNCLR::MOVE T1,[SCAN.1,,SCAN.1+1]
SETZM SCAN.1
BLT T1,SCAN.1+^D289
SETZM S.MAX
RET
SUBTTL Scans -- Update Scan Table
;SCNUPD
;
; Updates the scanner table. Table is in ascending sequence
; by row and descending sequence by range within row. This
; allows VIEWLD to process a row at a time. Descending ranges
; allow VIEWLD to overlay the character elements in the viewer
; table; assures that closer objects will overlay farther objects.
;
; Uses the following:
; W.ROW - row on which object will be displayed
; W.COL - col on which the center of the object will display
; W.RANG - range as a floating point nbr
; W.ID - object id
; W.UOT - object nr (universal object idx)
SCNUPD::SETZ T1, ;T1 is the scan table index
FIX T2,O.RANG(UOT) ;Get the range
AOS S.MAX ;Increment the element count
SC.TST: HRRZ T3,SCAN.1(T1) ;Main loop - get a scanner element
TRZ T3,-1000 ;Mask everything but the row
CAML T3,ROW ;Scan row less than new object row?
JRST SCTST1 ;No - test same row
JUMPE T3,SC.UPD ;End of table? - if so, add to end
AOJA T1,SC.TST ;Try the next element
SCTST1: CAME T3,ROW ;Is there another object on this row?
JRST SC.SHF ;No - push the table and insert
CAMG T2,SCAN.2(T1) ;Range greater than new range?
AOJA T1,SC.TST ;No - try the next element
SC.SHF: MOVE T4,S.MAX ;Get the (new) table size
SCSHF1: MOVE T3,SCAN.1-1(T4) ;Shift the elements down one
MOVEM T3,SCAN.1(T4)
MOVE T3,SCAN.2-1(T4) ;Shift the ranges also
MOVEM T3,SCAN.2(T4)
SOJ T4, ;Decrement the table idx
CAMLE T4,T1 ;Are we at the insertion point?
JRST SCSHF1 ;No - shift the next element
SC.UPD: HRRZ T3,UOT ;Update - get the UOT idx (obj nr)
HRRZ T4,COL ;Get the column
LSHC T3,^D9 ;Shift T3 and T4 a quarter word left
MOVE AP,U.TAB(UOT) ;Get the U.TAB word
ANDI AP,17 ;Mask everything but the uid
IOR T3,AP ;Insert the object id
IOR T4,ROW ;Insert the row
HRL T4,T3 ;Combine T3 with T4
MOVEM T4,SCAN.1(T1) ;Store in SCAN.1
MOVEM T2,SCAN.2(T1) ;Store the range in SCAN.2
RET ;Return to calling routine
SUBTTL Scans -- Delete Object
;SCNDEL
;
; Searches for an object UOT in the scan tables and, if found,
; deletes it. If an object was found, its row is stored in
; ROW.1. If not found, ROW.1 will = 0.
SCNDEL::SETZB T1,ROW.1
DO.
SKIPN SCAN.1(T1) ;Search for the UOT
RET ;Not found
HLRZ T2,SCAN.1(T1)
LSH T2,-^D9
CAME T2,UOT
AOJA T1,TOP.
OD.
HRRZ T2,SCAN.1(T1)
TRZ T2,-1000
MOVEM T2,ROW.1
SOS S.MAX
SCD.2: MOVE T2,SCAN.2+1(T1) ;Close up the hole in the scan
MOVEM T2,SCAN.2(T1) ;table
MOVE T2,SCAN.1+1(T1)
MOVEM T2,SCAN.1(T1)
SKIPE T2
AOJA T1,SCD.2
RET
SUBTTL Scans -- Load Viewer From Scan Table
;VIEWLD
;
; Loads the viewer table from the scan table
VIEWLD::PUSH SP,P1
PUSH SP,P2
SETZM V.MOD
SETZM V.ROW
SETZB P1,ROW
HRRZ P2,SCAN.1(P1)
TRZ P2,-1000
VWL.1: AOJ ROW,
CALL VWRUPD
CAIGE ROW,^D13
JRST VWL.1
POP SP,P2
POP SP,P1
RET
SUBTTL Viewer -- Update Two Viewer Rows
;VWRTST
;
; Updates two viewer rows. Intended specifically for the case
; when an object moves. ROW.1 is the 'old' ROW, most probably
; set up by SCNDEL. ROW.2 is the 'new' ROW, set up by SCNTST.
; A row isn't processed if it equals zero. Also, if the new
; row = the old ROW, it's not necessary to process the new row.
VWRTST::SETZM V.RSET ;Will be set to -1 if a char is displayed.
SKIPN ROW,ROW.1
JRST VWT.1
CAMN ROW,T.ROW
CALL TARUPD
MOVE ROW,ROW.1
CALL VWRCHG
VWT.1: SKIPE ROW,ROW.2
CAMN ROW,ROW.1
JRST VWT.2
CAMN ROW,T.ROW
CALL TARUPD
MOVE ROW,ROW.2
CALL VWRCHG
VWT.2: SKIPE V.RSET ;Any characters displayed?
TYPE <
8> ;Yes, reset the cursor position.
OUTSTR V.ASC
MOVEI T1,7
MOVEM T1,V.COLR
RET
SUBTTL Viewer -- Update Single Viewer Row
;VWRCHG
;
; Changes a single viewer row after finding it in the scan
; table. Different from VIEWLD, which loads all rows
VWRCHG::PUSH SP,P1
PUSH SP,P2
SETZM V.MOD
SETZB P1,V.ROW
DO.
SKIPN P2,SCAN.1(P1)
EXIT.
HRRZ P2,P2
TRZ P2,-1000
CAMGE P2,ROW
AOJA P1,TOP.
OD.
CALL VWRUPD
POP SP,P2
POP SP,P1
RET
OBJOUT: SETZ T4,
TRZE T2,40
MOVEI T4,40
HLRZ T3,V.ELEM(T2) ;Get character set
TRZ T3,70 ;Remove color bits
IFN. T3
CAME T3,V.MOD
OUTSTR V.MOD(T3)
MOVEM T3,V.MOD
ENDIF.
SKIPE .TTTYP
CALL OBJCLR ;Get color if GIGI
HRRZ T3,V.ELEM(T2)
CAIE T4,0
CALL BLINK
TRNE T3,200
JRST OBJBRI
OBJDRK: SKIPE VT241F
TYPE <
PpT(A1)
\>
OUTCHR T3
SKIPE VT241F
TYPE <
PpT(A0)
\>
CAIE T4,0
JRST BLREST
SKIPE .TTTYP
JRST TAREDO
RET
OBJBRI: SKIPN .TTTYP
TYPE <
[1m>
OUTCHR T3
CAIE T4,0
JRST BLREST
SKIPE .TTTYP
JRST TAREDO
TYPE <
[m>
RET
SUBTTL Viewer -- GIGI Color For Objects in Viewer
;Called if GIGI, sets cursor color
OBJCLR: SKIPE VT241F ;VT241?
RET ;Yes, don't do this
HLRZ T3,V.ELEM(T2) ;Get color and mode
LSH T3,-3 ;Get color only
CAIN T3,0 ;If no color
MOVEI T3,7 ;Use white
CAIN T2,0 ;If space
MOVE T3,V.COLR ;Use previous color (no change)
CAME T3,V.COLR ;Is it same as before
OUTSTR @V.COLR(T3) ;No, set new color
MOVEM T3,V.COLR ;Save color
RET
SUBTTL Viewer -- Target Redo
;Redoes target if previous character and GIGI
TAREDO: MOVE T3,ROW
CAME T3,T.ROW
RET
MOVE T3,COL
SUB T3,T.COL
SOSE T3
RET
SOS T3,COL
CALL CORNER
AOS T3,COL
RET
BLINK: SKIPN .TTTYP
TYPE <
[;5;7m>
RET
BLREST: SKIPE .TTTYP
IFSKP.
TYPE <
[m>
RET
ENDIF.
CALL CORNER ;GIGI target
RET
SUBTTL Viewer -- Make Target Blink
;TARDSP
;
; Displays reverse-video blinking target at W.ROW and W.COL.
TARDSP::SETZ T1, ;T1 will flag a difference in position
CAMN ROW,T.ROW ;New row same as old?
CAME COL,T.COL ;New col same as old?
SETO T1, ;No - T1 < 0 implies difference
MOVE T2,T.VIEW ;Get viewer flag (0 = not in view)
JUMPE T2,TD.TST ;If wasn't in view, skip
JUMPE T1,TD.TST ;If in view but same location, skip
PUSH SP,ROW ;Save new row and col
PUSH SP,COL
MOVE ROW,T.ROW ;Get old row and col
MOVE COL,T.COL
CALL TD.GET ;Get the character number from viewer table
TRZ T2,40
DPB T2,T3
TYPE <
[m> ;Turn off blink and reverse
CALL TD.DSP ;Display the char as a normal character
POP SP,COL ;Retrieve new row and col
POP SP,ROW
TD.TST: SETZM T.VIEW ;Assume new target isn't in viewer
CAIL ROW,^D2 ;Test row
CAILE ROW,^D12 ;Row must be between 2 and 12
JRST TD.SAV
CAIL COL,^D8 ;Test col
CAILE COL,^D74 ;Column must be tween 8 and 74
JRST TD.SAV
SETOM T.VIEW ;Target in view, flip view flag
CALL TD.GET ;Get the char nbr at this row and pos
CAIN ROW,7
CAIN COL,^D41
IFSKP.
TRO T2,40
DPB T2,T3
TRZ T2,40
ENDIF.
JUMPN T1,TDTST1 ;Different position for target?
CAMN T2,T.ELEM ;No - different element number?
JRST TD.SAV ;No - don't bother to display it again
;..
TAR100: TYPE <
[;5;7m> ;Turn on blink and reverse
CALL TD.DSP ;Display the new cursor
SKIPA
TARGG: CALL CORNER ;GIGI target
; JRST TD.SAV
TD.SAV: MOVEM ROW,T.ROW ;Save the new target row and col
MOVEM COL,T.COL
MOVEM T2,T.ELEM ;Save the char nbr that was displayed
RET ;Return to calling routine
TD.GET: MOVE T3,ROW ;Get target character from viewer table
SOJ T3,
IMULI T3,^D78 ;Offset = (78 * (row - 1)) + col
ADD T3,COL
ADJBP T3,V.TABP ;Get and adjust viewer pointer
LDB T2,T3 ;Load the character number
RET ;Return to calling routine
TD.DSP: SKIPE .TTTYP ;if gigi display regardless of position
JRST TDDSP1
CAIN ROW,^D7 ;If target is at center of viewer
CAIE COL,^D41 ;(row = 7 and col = 41)
SKIPA ;don't display
RET
TDDSP1: CALL VTPOS ;Position the cursor
HLRZ T3,V.ELEM(T2) ;Get the mode of the element
TRZ T3,70 ;Ignore color
SKIPE T2 ;Mode important?
OUTSTR V.MOD(T3) ;Yes - change the mode
SKIPE .TTTYP
CALL OBJCLR ;Get color if GIGI
HRRZ T3,V.ELEM(T2) ;Get the character
TRNE T3,200 ;Bold character?
TYPE <
[1m> ;Yes - turn on increased intensity
OUTCHR T3 ;Display the character
TRNE T3,200 ;Bold character?
TYPE <
[m> ;Yes - turn off intensity
RET ;Return
SUBTTL Viewer -- Put Cursor on Status Line
;VPOS
;
; Positions the cursor on the 'status' line (row 16).
; Assumes column nr in T3; T3 and T4 are destroyed.
VPOS:: TYPE <
[16;> ;Start the positioning sequence
IDIVI T3,^D10 ;Divide by 10
TRO T3,"0" ;Convert tens to ASCII
TRO T4,"0" ;Convert units to ASCII
CAIE T3,"0" ;Skip tens if zero
OUTCHR T3 ;Display the tens digit
OUTCHR T4 ;Display the units digit
TYPE <H> ;End the sequence
RET ;Return to calling routine
VNEXTP::CAME ROW,V.ROW
SETZM V.COL
SKIPG V.COL
JRST VNXT.1
CAMG COL,V.COL
JRST VNXT.1
MOVE T3,COL
SUB T3,V.COL
SOJE T3,VNXT.2
TYPE <
[>
IDIVI T3,^D10
TRO T3,"0"
TRO T4,"0"
CAIE T3,"0"
OUTCHR T3
OUTCHR T4
TYPE <C>
SKIPA
VNXT.1: CALL VTPOS
VNXT.2: MOVEM ROW,V.ROW
MOVEM COL,V.COL
RET
SUBTTL Viewer -- Position Cursor
;VTPOS
;
; Positions cursor at ROW and COL. Works for 2-digit ROW
; and COL. Destroys T3 and T4.
; Also positions graphics cursor for GIGI terminals
VTPOS:: TYPE <
[> ;Display start of sequence
MOVE T3,ROW ;Move the row
IDIVI T3,^D10 ;Divide by 10 (remainder is in T4)
TRO T3,"0" ;Convert tens to ASCII
TRO T4,"0" ;Convert units to ASCII
CAIE T3,"0" ;Skip tens if zero
OUTCHR T3 ;Display tens
OUTCHR T4 ;Display units
TYPE <;> ;Display sequence delimiter
MOVE T3,COL ;Move the col
IDIVI T3,^D10 ;Divide by 10 (remainder is in T4)
TRO T3,"0" ;Convert tens to ASCII
TRO T4,"0" ;Convert units to ASCII
CAIE T3,"0" ;Skip tens if zero
OUTCHR T3 ;Display tens
OUTCHR T4 ;Display units
TYPE <H> ;Display final control sequence character
RET
GIPOS:: SKIPN .GRTYP ;If not graphics,
RET ;return
TYPE <
PpP[> ;Enter REGIS, position command
MOVE T3,COL ;Get column (x-axis)
SKIPN VT241F ;If VT241
IFSKP.
IMULI T3,^D10 ;10 pixels per column
ADDI T3,^D25 ;Account for later mal-adjustment
JRST GIPOS1
ENDIF.
SKIPE .TTTYP ;If GIGI
IMULI T3,^D9 ;9 pixels per column
SKIPN .TTTYP ;If VT125
IMULI T3,^D10 ;10 pixels per column
GIPOS1: SUBI T3,^D4 ;Center of column
SKIPN .TTTYP ;If VT125
SUBI T3,^D25 ;adjust position to left
IDIVI T3,^D100 ;Get hundreds
TRO T3,"0" ;Convert hundreds to ASCII
CAIE T3,"0" ;Skip hundreds if zero
OUTCHR T3
MOVE T3,T4 ;Get remainder
IDIVI T3,^D10 ;Get tens
TRO T3,"0" ;Convert to ASCII
OUTCHR T3 ;Display tens
TRO T4,"0" ;Convert ones to ASCII
OUTCHR T4 ;Display ones
TYPE <,> ;X-Y axis delimiter
MOVE T3,ROW ;Get row
IMULI T3,^D20 ;20 pixels per row
SUBI T3,^D10 ;Center of row
IDIVI T3,^D100 ;Get hundreds (remainder in T4)
TRO T3,"0" ;Convert hundreds to ASCII
CAIE T3,"0" ;Skip hndreds if zero
OUTCHR T3 ;Display hundreds
MOVE T3,T4 ;Get remainder
IDIVI T3,^D10 ;Get tens
TRO T3,"0" ;Convert to ASCII
OUTCHR T3
TYPE <0]
\> ;Ones should always be zero
;close position, exit REGIS
RET ;Return
SUBTTL Get Character From Terminal
;VTGET
;
;
; Gets a character from the terminal, returns C.INTE and
; C.CHAR as follows:
;
; Normal entries: 0 in C.INTE, character entered in C.CHAR.
; Control char: ADE nbr in C.INTE, space in C.CHAR
; (delete returns 127 in C.INTE, space in C.CHAR).
; Keypad keys: 27 (escape) in C.INTE, the following in C.CHAR:
; UP A
; DOWN B
; RIGHT C
; LEFT D
; PF1-4 A,B,D,C (note sequence)
; 0-9 0-9
; COMMA comma
; DASH dash
; PERIOD period
; ENTER M in C.CHAR, 13 in C.INTE (cr)
VTGET:: CALL VTIMED ;Get a character (timed interrupt)
TYPE <
8>
ANDI T4,177 ;Mask the last 8 bits
SETZM C.INTE ;Zero the integer
MOVEI T1,.CHSPC ;Move space to the char
CAIGE T4,.CHSPC ;Is it a ctrl char? (less than space)
JRST VT.CTL ;Yes
CAIE T4,.CHDEL ;No - is it a delete?
JRST CT.CHR ;No - it's just a normal character
MOVEM T4,C.INTE ;Yes, a delete - move it to integer
JRST VT.SAV ;Go to return
VT.CTL: MOVEM T4,C.INTE ;Move to integer
CAIE T4,.CHESC ;is it an escape?
JRST VT.SAV ;Go to return
VT.ESC: INCHRW T4 ;Get the next esc sequence character
ANDI T4,177 ;Mask the last 8 bits
CAIN T4,"[" ;Is it a keypad sequence?
JRST VT.KPD ;Yes - process it
CAIE T4,"O" ;An arrow?
JRST CT.CHR ;No - don't know what it is
;Yes - process the sequence
VT.KPD: INCHRW T4 ;Get the next character
ANDI T4,177 ;Mask the last 8 bits
CAIGE T4,"l" ;Is it lowercase L or greater?
JRST VT.UPR ;No - probably an uppercase letter
CAILE T4,"y" ;Is it lowercase Y or less?
JRST CT.CHR ;No - don't know what it is
ANDI T4,77 ;Make it a number or - , . character
JRST CT.CHR ;Go to return
VT.UPR: CAIE T4,"M" ;Was it the ENTER key?
JRST VT.PF ;No - test the pf keys
MOVEI T3,.CHCRT ;Generate a carriage ret
MOVEM T3,C.INTE ;Move CR to integer
JRST CT.CHR ;Go to return
VT.PF: CAIN T4,"P" ;Is it pf1?
MOVEI T4,"A" ;Yes - convert to up arrow
CAIN T4,"Q" ;Is it pf2?
MOVEI T4,"B" ;Yes - convert to down arrow
CAIN T4,"R" ;Is it pf3?
MOVEI T4,"D" ;Yes - convert to left arrow
CAIN T4,"S" ;Is it pf4? (if not, it's probably an arrow)
MOVEI T4,"C" ;Yes - convert to right arrow
CT.CHR: MOVEM T4,T1 ;Move T4 to T1
VT.SAV: MOVEM T1,C.CHAR ;Save the character
RET ;Return to calling routine
SUBTTL Timed Input From Terminal
VTIMED::CALL D.TIME
MOVEI T1,.PRIIN ;This device (terminal)
SIBE% ;Any input?
JRST VTINP ;Yes, handle it
MOVEI T1,^D500 ;No, sleep for a touch
DISMS% ;Drumm fingers
VTDSMS: MOVEI T1,.PRIIN ;This device again
SIBE% ;Input now?
JRST VTINP ;Yes, see what we got
CALL QTEST ;No - do Q-processing
JRST VTIMED ;And loop back up
VTINP: INCHRW T4 ;Get terminal character input
RET ;And return
SUBTTL Handle Tyepin Interrupts
;ITYPIN - Get typein interrupts
ITYPIN: SAVE T1
HRRZ T1,LEV2PC ;Check interrupt PC
CAIE T1,VTDSMS ;From this routine?
JRST ITYPIX ;Not waiting - exit
MOVSI T1,10000 ;User mode flag
IORM T1,LEV2PC ;DEBRK back to wakeup
ITYPIX: REST T1
DEBRK%
D.TIME: SOSLE D.TCNT
RET
MOVEI T1,^D120 ;Call approx every 500ms
MOVEM T1,D.TCNT
SKIPN .TTTYP ;GIGI?
IFSKP. ;Do special things if so
TRNE SUOT,1B35
OUTSTR @V.CYN
TRNN SUOT,1B35
OUTSTR @V.GRN
ENDIF.
TYPE <
[1;7m
[24;74H>
MOVEI T1,.PRIOU ;This output device (terminal)
SETO T2, ;Current time
MOVX T3,<OT%NDA+OT%NSC> ;Hour and minute
ODTIM% ;Display it
ERJMP .+1 ;Should not happen
SKIPE .TTTYP
TYPE <
[m>
TYPE <
8>
RET
SUBTTL Load GIGI Macrographs
;GILOAD
;
; Loads macrographs if on Graphics terminal
;
GILOAD::SKIPN .GRTYP ;If not graphics,
RET ;Return
SKIPE VT241F ;Set VT241 to not hurt the eyes
TYPE <
PpS(M0(AD)1(AM)2(AR)3(AY))
\>
SKIPE .TTTYP
TYPE <
PrVC0MB0AW0
\> ;Don't display cursor
;Disable margin bell
;No generation of <CR>
TYPE <
Pp> ;Enter regis
TYPE <S(EN0A)W(RA0S0M1N0P1(M2))T(A0D0S1)>
;Initialize ReGIS (mostly)
TYPE <P[100,440]T(I-10)(W(i2R,n1))'Please Stand By...'>
TYPE <t(i0)>
TYPE <@.> ;Clear macrograph storage
; exp01 macrograph e
TYPE <@:eW(cI6)v(b)[-5,-9][+3,+19][+6,-17][-2,+17]>
TYPE <[-6,-4][+8,-6][-8,-7][+7][-7,+17](e)@;>
; exp03 macrograph f
TYPE <@:fp(b)@ev[-11,-05][+21,+3][-21,+10][+22,-3]>
TYPE <[-22,-4][+21,-6](e)@;>
; exp05 macrograph g
TYPE <@:gp(b)@fv[-2,-16][+5,-2][-5,+34]>
TYPE <[+5,+3][-13,-20][+21,-4][,+12](e)@;>
; exp11 macrograph h
TYPE <@:hp(b)@gv[-19,+6][+30,+12][-22,-43][+29,+29]>
TYPE <[-28,+20][+21,-48][-31,+25][+39,-7][-39,-1]>
TYPE <[+29,+34](e)@;>
; exp16 macrograph i
TYPE <@:i@hp(b)v[-29,+8][+49,-29][-6,+47][-33,-4][+47,-17]>
TYPE <[-47,-31][+14,+55][+22,-54][-45,+25]>
TYPE <[+47,+16][-37,+10][+36,-51][+0,+34]>
TYPE <[-37,-34][+8,+52][+40,-33](e)@;>
; exp24 macrograph j
TYPE <@:jp(b)w(p5(m9))@iv[-26,-44][+04,+91][+48,-90][,+87]>
TYPE <[-70,-44][+44,-46][+44,+46][-44,+45][-18,-89]>
TYPE <[+55,+67][-72,+4][+72,-48][-82,+26][+92,-13][-34,+47]>
TYPE <[-9,-81][-38,+30][+61,-27](e)@iw(p1(m2))@;>
;some of torpedo macrograph o
TYPE <@:op[-11,-2]v[+11]s(T1)@;>
;Phaser shots (must be in pairs) macrograph p
TYPE <@:pp(b)[261,239]v(w(ci)e)p(b)[471,239]v(w(ci)e)@q@;>
; phaser flash when we shoot macrograph q
TYPE <@:qw(s[,+2]i6r)p(b)[-3,-4]@vp(e)w(s0)@;>
; flash red macrograph r
TYPE <@:rs(i2T1i0T1)@;>
; shake screen up and down macrograph s
TYPE <@:ss(w(m12))26622662@;>
; photon torpedoes macrograph t
TYPE <@:tW(I2c)p[+5,242]@o@o@o@o@o@o>
TYPE <p[-10,-2]>
TYPE <s(T3)v[+9]p0v[,+12][-10][,-10]>
TYPE <p[,+8]v[+9]p[-8,-11]s(t7)v[+7]p0v[,+9]>
TYPE <[-8][,-8]p[,+6]v[+7]p[-6,-10]>
TYPE <s(T10)v[+5]p0v[,+8][-6][,-6]>
TYPE <p6666v[+5]p[-4,-7]s(T14)v000p0v[,+5]>
TYPE <[-4]2222p66v000p[-2,-6]s(T17)v0p0v666644220s(T20)v2@;>
; target display macrograph u
TYPE <@:uw(ri2a1)p(b)[-5,-10]v[+9]>
TYPE <p[+1,+18]v[-9]p(e)w(a0)@;>
; phaser flash macrograph v
TYPE <@:vv[+6]p[-6]v(w(e))[+6]p[-6]@;>
; phaser when someone else shoots macrograph w
TYPE <@:ww(i6r)p(b)[-3,+4]@vs(T2)@vs(T2)@vs(T2)@vp(e)@;>
; pacman macrograph x
TYPE <@:xt"wz "p[-78]t"xz "p[-78]t"yz "p[-78]t"xz "p[-78]@;>
; flash yellow macrograph y
TYPE <@:ys(i6T1i0T1)@;>
; move pacman for 1 row macrograph z
TYPE <@:zp(b)t[+24,](s[24,50]m[3,5]a1)w(ri6)>
TYPE <@x@x@x@x@x@x@x@x@x@x@x@x@x@x@x@x@x@x>
TYPE <@x@x@x@x@x@x@x@x@x@x@x@x@x@x@x@x@x@xp(e)[,+50]@;>
TYPE <s(e)>
TYPE <
\> ;Exit REGIS
OUTSTR @SET241 ;Back to normal for VT241
RET
SUBTTL Display The Main Console Screen
;DSPCON
;
; Displays the TREK console. Positions cursor in middle of view
; screen and stores it.
; .TTTYP = 1 = GIGI
DSPGG: TYPE <
=
[?8h
[?5;7l
[H
[J>
OUTSTR V.ASC
TYPE <
[;37m
[7;41H
7>
MOVEI T1,7
MOVEM T1,V.COLR
TYPE <
Pp>
TYPE <s(i0)>
TRNE SUOT,1b35
TYPE <w(i5)W(S1[,479])P[0,0]V[+730]>
TRNN SUOT,1b35
TYPE <w(i4)W(S1[,479])P[0,0]V[+730]>
TRNE SUOT,1b35
TYPE <w(i1)>
TRNN SUOT,1b35
TYPE <w(i6)>
TYPE <w(s[,20])p[12,258]v[+13]p[55]>
TYPE <v[+618]p[+24]v[+12]>
TYPE <w(s[,280])p[12,458]v[+526]>
TYPE <W(ES[,241])P[23,20]V[+12]P[+24]V[+614]P[+24]V[+12]>
TYPE <W(S[,280])P[24,439]V[+516]P[+12,+20]V[+160]W(RS0)>
TYPE <w(i4)>
TYPE <P[,+40]P(B)V[+509]P(E)>
TYPE <@:AP(B)V[,-40]P(E)@;>
TYPE <P[+126]@A[+126]@A[+81]@A[+45]@A[+63]@A>
TYPE <@:ap(b)v[+144]p(e)[,+40]@;>
TYPE <p[561,288]@a@a@a@a@a>
TYPE <@:bp(b)v[,+160]p(e)[+36]@;>
TYPE <p[561,288]@b@b@b@b@b>
TYPE <p[597,408]v(w(c))[,+39]>
TYPE <p[669,408]v(w(c))[+35]>
TYPE <@:at(w(c))'48 40 32 24 16 8 0 8 16 24 32 40 48'@;>
TRNE SUOT,1b35
TYPE <w(i5)>
TRNN SUOT,1b35
TYPE <w(i4)>
TYPE <p[81,0]@a>
TYPE <p[81,260]@a>
TYPE <p[27,40]>
TYPE <t(w(c))'16'>
TYPE <@:bp[-9,+40]t(w(c))'8'>
TYPE <p[-9,+40]t(w(c))'0'>
TYPE <p[-9,+40]t(w(c))'8'@;>
TYPE <@bp[-18,+40]t(w(c))'16'>
TYPE <p[686,40]>
TYPE <t(w(c))'16'>
TYPE <p[-9]@b>
TYPE <p[-9,+40]t(w(c))'16'>
TYPE <@:cp[,+39]v(w(c))[][+1][,+1][-1]@;>
TRNE SUOT,1b35
TYPE <w(i1)>
TRNN SUOT,1b35
TYPE <w(i6)>
TYPE <p[54,10]@c@c@c@c@c>
TYPE <p[676,10]@c@c@c@c@c>
TYPE <@:dp[+44]v(w(C))[][,+1][+1][,-1]@;>
TYPE <p[51,251]@D@D@D@D@D@D@D@D@D@D@D@D@D>
TYPE <w(i4)>
TYPE <p[30,300]t'ENERGY'>
TYPE <p[+72]t'SHL'>
TYPE <p[+99]t'WARP'>
TYPE <p[567,300]t'MOV'>
TYPE <p[+9]t'ROT'>
TYPE <p[+9]t'WRP'>
TYPE <p[+9]t'LIS'>
TYPE <p[567,340]t'TAR'>
TYPE <p[+9]t'PHA'>
TYPE <p[+9]t'TOR'>
TYPE <p[+9]t'ERA'>
TYPE <p[567,380]t'LOK'>
TYPE <p[+9]t'REF'>
TYPE <p[+9]t'SHL'>
TYPE <p[+9]t'EXE'>
TYPE <p[567,420]t'LR SCAN'>
TYPE <p[+9]t'MOR'>
TYPE <
\>
RET
; .TTTYP = 0 = VT100 or VT125
DSP100: CALL DSPBRI ;Display the bright areas
CALL DSPDRK ;Display the dark areas
CALL DSPDSP ;Display the lower left area
CALL DSPPAD ;Display the keypad area
OUTSTR V.ASC
TYPE <
[m
[7;41H
7>
;Position the cursor at screen center
RET ;Return
DSPDSP: OUTSTR V.GRA
TYPE <
[15;4H>
TYPEC <
[mlqqqqqqqqqqqqqwqqqqqqqqqqqqqwqqqqqqqqwqqqqwqqqqqqwqqqqqqk>
TYPE <
[3Cx ENERGY x SHL x WARP >
TYPEC <x
[7m
[mx>
TYPEC <
[3Ctqqqqqqqqqqqqqvqqqqqqqqqqqqqvqqqqqqqqvqqqqvqqqqqqvqqqqqqu>
TYPEC <
[3Cx
[55Cx>
TYPEC <
[3Cx
[55Cx>
TYPEC <
[3Cx
[55Cx>
TYPEC <
[3Cx
[55Cx>
TYPE <
[3Cmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj>
RET
DSPPAD: TYPE <
[m>
OUTSTR V.GRA
TYPE <
[15;63Hlqqqwqqqwqqqwqqqk>
TYPE <
[16;63HxMOVxROTxWRPxLISx>
TYPE <
[17;63Htqqqnqqqnqqqnqqqu>
TYPE <
[18;63HxTARxPHAxTORxERAx>
TYPE <
[19;63Htqqqnqqqnqqqnqqqu>
TYPE <
[20;63HxLOKxREFxSHLxEXEx>
TYPE <
[21;63Htqqqvqqqnqqqu x>
TYPE <
[22;63HxLR SCANxMORx ` x>
TYPE <
[23;63Hmqqqqqqqvqqqvqqqj>
RET
SUBTTL Clear Screen
CLRSCR: TYPE <
[1;24r
=
[?8h
[?5;6;7l
[H
[J>
;set VT100 characteristics:
; 1;24r set scrolling region to full screen
; = turn on keypad
; 8h autorepeat on
; 5l white on black screen
; 6l absolute origin
; 7l no wraparound
; H home the cursor
; J clear the screen
; B alphanumeric character set
OUTSTR V.ASC
RET
SUBTTL Do VT100 Self Test
VTEST:: SKIPN VTFLAG
AOSA (SP)
TYPEC < >
RET
SUBTTL VT100 Initialization
;VTINI
;
; Call: enter routine VTINI using integer.
;
; Initializes and tests the terminal.
VTINI:: CALL TTYSET
CALL VTTEST
SKIPE VTFLAG
JRST VTERR
RET
SUBTTL Check Terminal Type
;VTTEST
;
; Call: enter routine VTTEST using integer.
;
; Determines whether the terminal is a VT100 with advanced
; video option. Returns 0 if this is the case, returns -1
; otherwise.
VTTEST::SETOM VTFLAG ;Assume not a VT100
SETZM V52FLG ;And not in VT52 mode
TYPE <
Z> ;Ask terminal to identify itself
MOVEI T3,^D100 ;Wait 100 * 100ms = 10 sec
VWAIT: MOVEI T1,^D100
DISMS%
MOVEI T1,.PRIIN
SIBE% ;Any input?
JRST VIDENT ;Yes - get it
SOJLE T3,R ;Return if timeout
JRST VWAIT ;Else, continue
VIDENT: INCHRW T3 ;Return char in T3
CAIE T3,.CHESC ;Is the character an escape?
RET ;No - error (id sequence begins w escape)
INCHRW T3 ;Get the next id character
CAIN T3,"[" ;Is it a [?
JRST VT100 ;Yes - assume a VT100
CAIE T3,"/" ;No - is it a /?
RET ;No - terminal is not a VT100
VT152: INCHRW T3 ;Get the 3rd character
CAIE T3,"Z" ;Is it a Z?
RET ;No - not a VT100 in VT52 mode
SETOM V52FLG ;Yes - remember that
OUTSTR [ASCIZ/
<
Z/] ;And change the mode to ANSI
INCHRW T3 ;And ask again for identification.
INCHRW T3 ;Skip the 1st 2 characters
VT100: INCHRW T3 ;Skip the ?
INCHRW T3 ;Get the terminal id nbr
CAIE T3,"5" ;Is it a GIGI
IFSKP.
AOS .TTTYP
AOS .GRTYP
JRST GIGI
ENDIF.
CAIN T3,"6" ;Is it a VT200 series or VT102
JRST VT220
CAIE T3,"1" ;Make sure it is a VT100
RET
SKIPA
;..
;..
GIGI: SETOM VKFLAG
INCHRW T3 ;Get next char
CAIN T3,"2" ;Is it a VT125
JRST VT125
INCHRW T1 ;Get options
INCHRW T3 ;Skip the final c
SETFNT: MOVEI T2,VKFNT1
SKIPN .TTTYP ;Skip if GIGI
MOVEI T2,VTFNT1
SETFN1: SKIPE VKFLAG ;Skip if not graphics
OUTSTR (T2)
SKIPN VKFLAG ;GIGI or
TRNE T1,1B34 ;Advanced video?
SKIPA
IFNSK.
OUTSTR [ASCIZ /
This VT100 does not have an advanced video option.
The game will be played anyhow even though the screen will be incomplete.
/]
MOVEI T1,^D5000
DISMS%
ENDIF.
SETZM VTFLAG ;Clear flag (TTY is a VT100)
RET ;Return
VT125: INCHRW T3 ;Skip input until c
CAIN T3,"7" ;Are we a VT241?
JRST VT241
CAIN T3,"C" ;At the end?
JRST VT125A
CAIE T3,"c"
JRST VT125
VT125A: AOS .GRTYP
SETOM VKFLAG
JRST SETFNT
VT220: INCHRW T3 ;Get next char
CAIN T3,"2" ;Is it a vT220
JRST VT221
CAIE T3,";" ;Is it a vT102
RET
INCHRW T1 ;Get options
VT221: INCHRW T3 ;Skip input until c
CAIN T3,"C" ;Is this a C?
JRST VTERR
CAIE T3,"c"
JRST VT221
JRST VTERR
VT241: MOVEI T2,.CTTRM ;Clear terminal input
CFIBF%
MOVE T1,[T241.R,,V.RED] ;Remap the color tables
BLT T1,V.WHT ;Do the rewrite
AOS .GRTYP ;And even say we have ReGIS graphics
SETOM VKFLAG ;Like a GIGI
SETOM VT241F ;But really a VT241
OUTSTR @SET241
MOVEI T2,VKFNT1 ;Set GIGI fonts
JRST SETFN1 ;And get going
VTERR: TYPEC < >
TYPEC < >
TYPEC <Sorry, this program only runs on VT100s, VT125s, and>
TYPEC <GIGIs, which gives full color and graphics! If you are>
TYPEC <using a VT241, set it in VT125 mode and you will be able>
TYPEC <to take advantage of graphic features too.>
FINI: HALTF%
JRST TREK
SUBTTL Set Terminal Control Words
TTYSET::MOVEI T1,.PRIOU ;This terminal
RFMOD% ;Get JFN mode word
MOVE T2,SAVMOD ;Save for later
TXZ T2,<TT%ECO+TT%DAM> ;Now set these for sure
SFMOD% ;Do it
MOVX T2,.MORSP ;Get terminal speed
MTOPR% ;Well?
ERJMP .+1 ;This sometimes no work
CAMN T3,[-1] ;Check for detached
MOVEI T3,0 ;If detached, then no terminal speed
HRRZM T3,TOTSP ;Stash speed here
RET
SUBTTL Reset Terminal Modes When Exit
TTYRST::SKIPE V52FLG ;Need to reset VT100 to VT52 mode?
OUTSTR [ASCIZ /
[?2l/] ;Yes, do it
SETZM V52FLG ;Say a VT52 again
MOVEI T1,.PRIOU ;This terminal
MOVE T2,SAVMOD ;Get old JFN mode words
SFMOD% ;Restore them
RET ;And done
FINTTY::CALL TTYRST
RET ;Return
SUBTTL Make .SHARE File & .EXE File
;Code to generate shareable segment and .EXE file
MAKIT: RESET% ;Start like all good programs
MOVX T1,<GJ%FOU+GJ%SHT> ;Short form
HRROI T2,[ASCIZ /DSK:VT241.SHARE/] ;This is the .SHARE file
GTJFN% ;Get a JFN for it
ERJMP MAKERR
MOVX T2,OF%WR ;Open for write
OPENF% ;Do it
ERJMP MAKERR
JSP SP,MAKSHR ;Move shareable pages, etc..
HRLI T1,.FBSIZ ;File page count
SETO T2,
MOVE T3,T4 ;Page count
LSH T3,^D9 ;Words
CHFDB% ;Change file's FDB
ERJMP .+1
HRLI T1,.FBBYV ;This word
MOVX T2,FB%BSZ ;This field
MOVX T3,<FLD (^D36,FB%BSZ)> ;Change byte size
CHFDB%
ERJMP .+1
SETZM BOOTF ;Boot flag
MOVEI T1,.FHSLF ;This fork
MOVE T2,[3,,EV] ;Get entry vector
SEVEC% ;Set entry vector
ERJMP .+1
;..
;..
SKIPN UOT,121 ;Make .EXE file if non-zero
JRST MAKIX
MOVEI UOT,(UOT) ;Higest location set by LINK
LSH UOT,-^D9
SETZM 120
SETZM 121
SETZM 44 ;Clear this TOPS10 stuff
MOVX T1,<GJ%FOU+GJ%SHT> ;Short form
HRROI T2,[ASCIZ /DSK:VT241.EXE/] ;Name of the .EXE file
GTJFN% ;Get a JFN for it
ERJMP MAKERR
HRLI T1,.FHSLF ;This process
MOVNI T2,1(UOT)
HRLZS T2
TXO T2,<SS%RD+SS%CPY+SS%EXE> ;Page protection (read, c-o-w, exe)
SETZ T3,
SSAVE% ;Make .EXE file be on disk
ERJMP MAKERR
MAKIX: HRROI T1,[ASCIZ /
Game successfully made. You must run the .EXE file it if you
would like to play.
/]
ERDUN: PSOUT
HALTF%
JRST .-1 ;Make user run new .EXE file
SUBTTL Code to Make Shareable Segment
;Common code to create shareable segment. JFN in T1, preserved.