;USR0:<BUDD>VTTREK.MAC.7 7-Mar-85 FM+1D.19H.44M.15S., by BUDD
; Make LINK with FORTRAN v7 + remove some once only kludgery
;<HESS>VTTREK.MAC.31 8-Jan-81 09:09:14, Edit by HESS
TOPS20==1 ;[BUDD]
; VT100 TREK Version 2.0
;
; TREK is a VT100 game for up to eight players. It's written in
; MACRO-10 for VT100s that are equipped with the Advanced Video
; Option.
;
; Each player runs the game from a separate tty and job. The
; jobs communicate via a sharable high segment.
;
; TREK.RNO contains a complete game description. The program
; uses a file of help texts named TREK.HLP. This file should be
; on the same device in the same ppn as the TREK.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. TREK.RNO describes
; Version 2.0 and the differences between the old and new versions.
;
; TREK timing is based on 1200 baud lines. Lower baud rates give a
; slow-motion effect and an advantage to interceptors and bases. There
; has been no opportunity to test the program at higher baud rates.
;
; Questions, comments, suggestions, etc, are welcome.
;
; For further information, contact:
;
; Cliff Zimmerman
; Manufacturing Planning Information Systems
; ML1-4, F16
; 223-6294 ((617)-493-6294)
;
; Revisions since release of version 1.0:
;
; 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.
ifndef tops20,<tops20==0> ;default to TOPS10
ifndef ftki10,<ftki10==0> ;Not KI10
title TREK
sall
twoseg
.TEXT "/SYMSEG:LOW" ;[BUDD] SYMBOL TABLE IN LOWSEG
.TEXT "SYS:FORLIB/SEGMENT:LOW/SEARCH" ;[BUDD] MATHLIB STUFF IN LOWSEG
%VER==:0 ;[BUDD] ??? FORLIB WANTS IT
ife tops20,<
search UUOSYM
>
ifn tops20,<
search monsym,macsym
.jbuuo==40
>
;Version definitions
tk.ver=2 ;Version 2
tk.min=0 ;Minor ver
tk.who=0 ;Who last edited
tk.edt=100 ;Edit #
; acs
rs=0
t1=1 ;temporary registers
t2=2
t3=3
t4=4
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 ;pdl pointer
sp=17 ; (p is sometimes called sp)
pdlsz=200 ;pdl size
pdl: block pdlsz ;push down list
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
vtflag: 1
v52flg: 0 ;-1 if vt100 in vt52 mode
dbugf: 0
ifn tops20,<
hlpjfn: z
savmod: z ;tty JFN mode saved here
d.tcnt: z ;counter to prevent time from being displayed too ofter
bootf: -1 ; once only flag for BOOTS
gjblk: gj%old
.nulio,,.nulio
-1,,tk.dev
-1,,tk.dir
-1,,tk.nam
0 ;file type - 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
>
ife tops20,<
l.hr: z ;last hour displayed
l.mn: z ;last minute displayed
>
d.line: z
d.last: z
f.data: z ;data for fortran calls
f.loc: 200,,f.data ;location of fortran data
f.max: z
f.hit: z
f.uot: z
max.en: dec 5000000
k256: 128.0
k181: 90.50966802
i.char: z
i.sign: z
i.nbr: z
i.path: z
i.pos: z
i.spos: z
i.max: z
sin.a: z
cos.a: z
tan.a: z
sin.b: z
cos.b: z
tan.b: z
time.f: 0
var.x: 0
var.y: ^d256
p.ener: z
p.time: z
p.save: z
p.rang: z
b1: z
e1: z
r1: z
x1: z
y1: z
z1: z
x2: z
y2: z
z2: z
comp.x: z
comp.y: z
comp.z: z
a.absx: z
a.absy: z
a.absz: z
ran.mn: 1
ran.mx: 100
ran.nr: z
ran.sd: z
r.fire: z ;= 0 rapid fire off
;< 0 rapid fire on
rf.pha: ^d200 ;rapid fire phaser energy
rf.pho: ^d1 ;rapid fire photon count
a.fire: z ;phaser/photon work area for bases, interceptors,
;and unmanned ships:
;
;lh - weapons code, bit 9: 0 = pha, 1 = pho.
;rh - energy to be applied.
; 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: z ;'us' for unmanned ships.
mska.t: z ;'them' for unmanned ships.
; 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: z ;'us' for unmanned ships.
alya.t: z ;'them' for unmanned ships.
chan.c: z
chan.f: z
chan.k: z
chan.a: z
u.side:: z ;side a player is on (used during startup)
eadd.t: z ;event queue add area
eadd.a: z
eadd.b: z
eadd.x: z
eadd.y: z
eadd.z: z
ewrk.t: z ;event queue work area
ewrk.a: z
ewrk.b: z
ewrk.x: z
ewrk.y: z
ewrk.z: z
m.time: z
work.q: block 600
reloc 400K
ifn tops20,<
SHRBEG::
segver: byte (3)tk.who (9)tk.ver (6)tk.min (18)tk.edt
;matched against EV+2 at startup
>
; high-segment information shared by all ships
gam.nr: z ;tournament game nbr or 0 if random
gam.tm: ^d120 ;minutes remaining in the game
gam.hr: z ;current hour
gam.mn: z ;current minute
i.lock: z ;initial (startup) lock. keeps 2 or more players
;from starting up simultaneously.
i.time: z ;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.
mask.q:: z ;8-bit mask (0-7) indicating active ships.
time.q:: block 120 ;mstime that an unmanned ship or a non-ship is to
;be activated. zero means the entry is empty.
rebel: block 120 ;mstime after which a planet may consider rebellion.
; event queue
q.size=600*6 ;size of the event queue
hq.min=0
hq.max=77*6
lq.min=100*6
lq.max=577*6
q:: block q.size
evnt.t==q ;mstime 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).
z
; 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.tab:: repeat 4,<exp 5,6> ;federation, klingon ships
repeat 4,<exp 3,4> ;federation, klingon bases
repeat 20,<exp 2,7,7,7> ;planets and their interceptors
repeat 100,<exp 1> ;stars
z
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 nr of player
ife tops20,<
u.ppn: block 10 ;ppn of player
u.nam1: block 10 ;12-char name of player
u.nam2: block 10
>
ifn tops20,<
u.namx: block 10 ;user number of player
>
u.time: block 10 ;mstime 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 nbr determines
;whether a player was previously in the
;game, hence is in the shared section.
u.wait: block 10 ;mstime 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.
; 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
; 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 automatic 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
ui.s2: dec 20000000
ui.s3: dec 5000000
ui.s4: dec 5000000
ui.s5: dec 2000000
ui.s6: dec 2000000
ui.s7: dec 499000
shrend: reloc ;end of shareable data base
; ship object tables
;
; object information from the perspective of the ship
n.ener: z ;total shield plus ship energy of unmanned ship.
n.pcnt: z ;count of captured planets, used by unmanned ships.
n.scnt: z ;count of near enemy ships, used by unmanned ships.
; 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.
xyz.i: 7
xyz.t: dec 0,1,3,2,5,4,6,7
; target list
l.idx: z
luot.a: exp -1,-1,-1,-1,-1
luot.b: exp -1,-1,-1,-1,-1
m.msg: block ^d11
m.ptr: point 7,m.msg
m.wptr: z
m.row: z
t.row: ^d7 ;target row and col, not necessarily within range of
t.col: ^d41 ;the viewer or the screen.
t.view: 1
t.elem: z
t.uot: -1 ;if not < 0, indicates target is locked on object t.uot
t.bear: z ;to confuse things, target b,e is kept in degrees, not
t.elev: z ;as tangents (floating point)
t.rmax: z ;some min and max values used when determining whether
t.rmin: z ;an object is pointed to by the target.
t.cmax: z
t.cmin: z
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
c.inte: z ;integer returned by VTGET
c.char: z ;character returned by VTGET
c.cmd: z ;command nbr returned by VTCMD
c.dir: z ;direction returned by VTCMD
c.nbr1: z ;1st number returned by VTCMD
c.nbr2: z ;2nd number returned by VTCMD
c.cnt: z ;nr of numbers entered
c.imm: z ;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
w.row: z
w.col: z
w.id: z
w.uot: z
w.bear: z
w.elev: z
w.rang: z
; 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.
scan.1: block ^d145
scan.2: block ^d145
s.max: z
s.star: z
v.pos: z
v.col: z
v.row: z
v.flag: z
v.rset: z
v.mod: z
v.gra: asciz "(0"
v.asc: asciz "(B"
; 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)05,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)17,22,10,22,17,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)05,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,17,23,00,00,00(6)1 ; kli ship
byte (5)30,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)13,15,14,00,00,00(6)1 ; 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)04,00,00,00,00,00(6)0 ; kli ship
byte (5)04,00,00,00,00,00(6)0 ; interceptor
byte (5)01,00,00,00,00,00(6)0 ;range 3 - rom ship
byte (5)05,00,00,00,00,00(6)0 ; star
byte (5)17,00,00,00,00,00(6)0 ; planet
byte (5)04,00,00,00,00,00(6)0 ; fed base
byte (5)04,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)06,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 0,"0." ;in the viewer area
xwd 0,"0-" ;
xwd 0,"1*" ;left half:
xwd 0,"0*" ; 0 - can be displayed in any mode
xwd 1,"0`" ; 1 - requires graphics mode
xwd 0,"00" ; 2 - requires ascii mode
xwd 0,"08" ;
xwd 0,"0=" ;right half - 1st character:
xwd 0,"0(" ; 0 - normal intensity
xwd 0,"0)" ; 1 - bold (increased) intensity
xwd 0,"0@" ;
xwd 1,"0f" ;right half - 2nd character:
xwd 2,"0o" ; character to be displayed
xwd 0,"0O"
xwd 1,"0p"
xwd 1,"0q"
xwd 1,"0r"
xwd 1,"0t"
xwd 1,"0u"
xwd 2,"0v"
xwd 0,"0V"
xwd 0,"0H"
DSPMSG::
imuli uot,^d11
type <>
mspini
mspstr u.msg(uot)
mspout
ret
DSPNAM::
move ap,u.tab(uot)
andi ap,7
jrst @[dnm.st
dnm.rs
dnm.bs
dnm.bs
dnm.rs
dnm.rs
dnm.in]-1(ap)
dnm.st: dsptyp <Star>
ret
dnm.in: dsptyp <Interceptor>
ret
dnm.bs: dsptyp <Starbase >
dnm.rs: dspstr @o.name(uot)
ret
MSPNAM::
move ap,u.tab(uot)
andi ap,7
jrst @[mnm.st
mnm.rs
mnm.bs
mnm.bs
mnm.rs
mnm.rs
mnm.in]-1(ap)
mnm.st: msptyp <Star>
ret
mnm.in: msptyp <Interceptor>
ret
mnm.bs: msptyp <Starbase >
mnm.rs: mspstr @o.name(uot)
ret
;***** 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
jumpl c,eda.1
caig c,^d100000
movn c,c ;shields down
movem c,u.shld(uot)
ret
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,[^d5000000]
move t1,[^d5000000]
add t1,c ;c is < 0 - this is a subtract
movem t1,u.ener(uot)
ret
;***** ENEDEL
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
EQSCAN::
setz p3,
eqs.1: skiple c,evnt.t(p1)
camle c,m.time
jrst eqs.2
move c,evnt.a(p1)
tlnn c,@mask.c
jrst eqs.2
movem p1,work.q(p3)
aoj p3,
eqs.2: addi p1,6
camg p1,p2
jrst eqs.1
eqs.3: move t1,p3
move t2,m.time
aoj t2,
seto t3,
eqs.4: sojl t1,eqs.5
skipge c,work.q(t1)
jrst eqs.4
camg t2,evnt.t(c)
jrst eqs.4
move t3,t1
move t2,evnt.t(c)
jrst eqs.4
eqs.5: skipge t3
ret
move p1,work.q(t3)
setom work.q(t3)
call eqexec
movs c,mask.c
andcab c,evnt.a(p1) tlnn c,@mask.a setzm evnt.t(p1) jrst eqs.3 ;***** EQEXEC 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. pjrst @[movobj ;movement. delobj ;delete an object. dspmsg ;display ship-ship msg. 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]-1(t1) ;notify planet has rebelled. ret ;none of the above. ;***** MOVOBJ MOVOBJ:: skipge u.tab(uot) ret call rbelod camn uot,t.uot call tarupd call scndel call scntst pjrst vwrtst ;***** DELOBJ DELOBJ:: ;; skipge u.tab(uot) ;; ret call scndel setzm row.2 pjrst vwrtst ;***** HITDSP HITDSP:: fix ap,o.rang(uot) caile ap,^d2048 ret call scansr ret
move ap,evnt.a(p1) tlnn ap,1b27 pjrst phadsp pjrst phodsp phadsp: caig t2,^d1024 call rctest ret call vtpos type <[1;7m> movei t1,^d10 type <(B [D(B> sojg t1,.-1 type <[m> call getvwr call dspvwr type <(B[m> type <8> ret phodsp: movei c,flsh03 caile t2,^d512 movei c,flsh01 movem c,flsh.p call flshld type <B[1;7m> call flshbr type <[m> call flshch type <8> ret ;***** 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
nt.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) skipl ap jrst [call hitmsg pjrst hitchg] aos evnt.a(p1) call hitchg jrst zapped hr.oth: skipge u.tab(uot) ret hlrz t1,evnt.b(p1) call enedel movm ap,u.shld(uot) add ap,u.ener(uot) skipl ap jrst [call attack call hitack pjrst hitchg] call dstroy hlrz ap,evnt.a(p1) andi ap,377 camn ap,suot jrst [setom t.uot setzm t.bear setzm t.elev call contrc call tardsp jrst .+1] call hitdst aos evnt.a(p1) pjrst hitchg HITCHG:: move c,evnt.a(p1) tlo c,@mask.a and c,mask.q tlz c,@mask.c tlne c,@mask.a movem c,evnt.a(p1) ret ATTACK:: hrrz c,u.tab(uot) andi c,17 caie c,7 cain c,2 jrst att.pl caie c,3 cain c,4 jrst [call att.ms jrst att.ex] ret att.pl: save uot trz uot,3 call att.ms hlrz c,evnt.a(p1) andi c,377 move c,u.tab(c)
b31 jrst [rest uot jrst att.ex] andi c,3b31 trc c,3b31 movem c,s.mask att.p1: move c,u.tab(uot) trz c,3b31 ior c,s.mask movem c,u.tab(uot) aoj uot, trne uot,3 jrst att.p1 rest uot att.ex: movei t1,^d2000 call tqins ret att.ms: movei c,1b18 move t1,u.tab(uot) tlon t1,3b28 iorm c,evnt.a(p1) movem t1,u.tab(uot) ret HITTST:: move t1,u.absx(uot) fsbr t1,evnt.x(p1) fmpr t1,t1 camle t1,[4096.0] ret move c,u.absy(uot) fsbr c,evnt.y(p1) fmpr c,c fadrm c,t1 camle t1,[4096.0] ret move c,u.absz(uot) fsbr c,evnt.z(p1) fmpr c,c fadrm ap,t1 camg t1,[4096.0] aos (p) ret HITUS:: type <[1;2;3;4q> type <[?5h[?5l> type <[?5h[?5l> type <[?5h[?5l> type <[?5h[?5l> type <[?5h[?5l[0q> call enedsp call shldsp ret HITMSG:: mspini hlrz t3,evnt.b(p1) call mspnbr msptyp < unit hit by > hlrz t1,evnt.a(p1) trnn t1,1b27 jrst [msptyp <phasers> jrst .+2] msptyp <photon torpedo> mspout ret ;***** HITACK HITACK:: hlrz c,evnt.a(p1) trne c,1b27
jrst [call phohit jrst .+2] call phahit call attmsg ret ;***** HITDST HITDST:: call explod call dstmsg ret 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 DSTMSG:: hrrz c,u.tab(uot) andi c,17 cain c,7 ret mspini call mspnam msptyp < destroyed> mspout ret 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 REBMSG:: mspini msptyp <rebellion on > mspstr @o.name(uot) mspout ret ;***** DALERT DALERT:: mspini mspstr @o.name(uot) hlrz c,evnt.b(p1) xct [msptyp < needs assistance> msptyp < on RED ALERT> msptyp < on YELLOW ALERT>
alert>](c) mspout ret ;***** STSHIP ; ; these routines control the activities of unmanned ships. ship ; behavior is governed by a set of 'missions'. STSHIP:: call asetup call nrload hrrz t4,n.mssn(uot) jrst @[stsh.0 stsh.1 stsh.2 stsh.2 stsh.2 stsh.2](t4) stsh.0: call ai.ref ret jrst stsh.3 stsh.1: call ac.ref ret jrst stsh.3 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 pjrst au.sea ;***** ASETUP ; ; sets up us-them masks for this ship. ASETUP:: movei c,1 dmove t1,mask.f tdne c,uot exch t1,t2 dmovem t1,mska.u dmove t1,ally.f tdne c,uot exch t1,t2 dmovem t1,alya.u movm c,u.shld(uot) add c,u.ener(uot) movem c,n.ener movei t1,^d50 pjrst salloc ;***** 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,
tc) and of the nearest neu, fed, and kli ; planet. also catalogs objects within 1024 units (short range ; scan function). NRLOAD:: save p1,p2,p3 setom n.rang move c,[xwd n.rang,n.rang+1] blt c,n.rang+117 setom n.nuot move c,[xwd n.nuot,n.nuot+1] blt c,n.nuot+7 seto c, tlz c,1b18 movem c,n.nran move c,[xwd n.nran,n.nran+1] blt c,n.nran+7 setzm n.pcnt setzm n.scnt move t1,u.absx(uot) move t2,u.absy(uot) move t3,u.absz(uot) movei t4,117 nrl.1: skipl p2,u.tab(t4) camn t4,uot jrst nrl.3 move p1,t1 fsbr p1,u.absx(t4) fmpr p1,p1 movem p1,f.data move p1,t2 fsbr p1,u.absy(t4) fmpr p1,p1 fadrm p1,f.data move p1,t3 fsbr p1,u.absz(t4) fmpr p1,p1 fadrm p1,f.data movei c,f.loc save t1 call sqrt.## rest t1 fixr rs,rs movem rs,n.rang(t4) andi p2,17 caig rs,^d1024 call ncatal caie p2,2 jrst nrl.2 move p2,u.tab(t4) trne p2,@alya.u aos n.pcnt trnn p2,@mska.u jrst nrl.3 andi p2,3b31 lsh p2,-4 nrl.2: caml rs,n.nran(p2) jrst nrl.3 movem rs,n.nran(p2)
uot(p2) nrl.3: sojge t4,nrl.1 move c,uot trne c,1 call nrswap rest p1,p2,p3 ret ;***** NCATAL ; ; the short range scan catalog routine. NCATAL:: caig t4,7 jrst [move c,alya.t tdnn c,u.tab(t4) ret aos n.scnt move c,u.absx(t4) movem c,u.lstx(t4) move c,u.absy(t4) movem c,u.lsty(t4) move c,u.absz(t4) movem c,u.lstz(t4) jrst ncat.1] caie p2,7 cain p2,1 ret skipg time.q(t4) call nqins ncat.1: move c,mska.u iorm c,u.tab(t4) ret ;***** NQINS NQINS:: move c,ally.n tdne c,u.tab(t4) ret getime c movem c,time.q(t4) skipe q.time camge c,q.time movem c,q.time ret ;***** NRSWAP ; ; swaps uots and ranges of near bases and ships. NRSWAP:: dmove t1,nrpl.u exch t1,t2 dmovem t1,nrpl.u dmove t1,nrsb.u exch t1,t2 dmovem t1,nrsb.u dmove t1,nrsh.u exch t1,t2 dmovem t1,nrsh.u dmove t1,nupl.u exch t1,t2 dmovem t1,nupl.u dmove t1,nusb.u exch t1,t2 dmovem t1,nusb.u dmove t1,nush.u exch t1,t2 dmovem t1,nush.u ret
; ; the basic mission, performed when no other mission applies. ; a tour at warp 7 of all bases and friendly planets. refuels ; at each stop. AU.SEA:: setzm n.mssn(uot) skipg t1,n.muot(uot) jrst au.se1 skipl c,u.tab(t1) trnn c,@alya.u jrst au.se1 jrst au.se2 au.se1: call aubase jrst au.se3 movem t1,n.muot(uot) au.se2: move c,n.rang(t1) caile c,^d512 pjrst a.mov7 move c,n.ener camge c,[^d5000K] pjrst a.reen call aunxtb jrst au.se3 movem t1,n.muot(uot) pjrst a.mov7 au.se3: movei t1,^d1000 pjrst tqins ;***** Ax.REF, MISSION 1 ; ; retreat to a base and refuel AI.REF:: move c,n.ener camge c,[^d2500K] call aubase retskp movem t1,n.muot(uot) movei c,1 ;REF mission code. movem c,n.mssn(uot) pjrst au.ref AC.REF:: move c,n.ener caml c,[^d5000K] pjrst askipr move t1,n.muot(uot) skipl c,u.tab(t1) trnn c,@alya.u jrst [call aubase pjrst askipr movem t1,n.muot(uot) jrst .+1] pjrst au.ref AU.REF:: hlrz c,n.mssn(uot) jumpg c,au.re2
n.rang(t1) caige c,^d512 jrst au.re9 jrst au.re8 au.re2: movei c,^d1024 camge c,nrpl.t caml c,nrpl.n jrst au.re5 caml c,nrsb.t jrst au.re5 skipg t2,n.scnt jrst au.re9 caile t1,sb.mx jrst au.re6 caile t2,1 jrst au.re4 move c,n.ener camge c,[^d2000K] jrst au.re9 movei c,0 hrlm c,n.mssn(uot) move t1,nush.t movei t2,^d400 pjrst a.phas au.re4: call aunxsb jrst au.re7 au.re5: caig t1,sb.mx jrst au.re8 au.re6: skipl t1,nusb.u jrst au.re7 move t1,n.muot(uot) call aunxtb skipa t1,n.muot(uot) au.re7: movem t1,n.muot(uot) au.re8: movei c,0 hrlm c,n.mssn(uot) caile t1,sb.mx skipe n.scnt pjrst a.mov8 pjrst a.mov7 au.re9: movei c,1 hrlm c,n.mssn(uot) pjrst a.reen ;***** Ax.ESH, MISSION 2 AI.ESH:: move c,nrsh.t caile c,^d1024 retskp move t1,nush.t movem t1,n.muot(uot) movei c,2 ;ESH mission code. movem c,n.mssn(uot) pjrst au.es2 AC.ESH:: move t1,n.muot(uot) move c,nrsh.t caig c,^d1024 jrst ac.es1 move c,n.rang(t1) caile c,^d1536
ipr hlrz c,n.mssn(uot) jumpe c,au.es3 skipg u.torp(uot) pjrst au.es3 pjrst au.es1 ac.es1: cain t1,nush.t jrst ac.es2 move t1,nush.t movem t1,n.muot(uot) pjrst au.es2 ac.es2: hlrz c,n.mssn(uot) jumpn c,au.es2 move c,n.rang(t1) caig c,^d256 pjrst au.es2 pjrst au.es3 AU.ES1:: movei c,0 hrlm c,n.mssn(uot) pjrst a.phot AU.ES2:: movei c,0 hrlm c,n.mssn(uot) movei t2,^d400 pjrst a.phas AU.ES3:: movei c,1 hrlm c,n.mssn(uot) pjrst a.mov7 ;***** Ax.EBA, MISSION 3 AI.EBA:: move c,n.pcnt caile c,8 skipg t1,nusb.t retskp movem t1,n.muot(uot) movei c,3 ;EBA mission code. movem c,n.mssn(uot) pjrst au.eba AC.EBA:: move t1,n.muot(uot) move c,n.pcnt caile c,8 skipge u.tab(t1) pjrst askipr movei c,^d1024 camle c,nrsh.t pjrst askipr camg c,nrpl.t camle c,nrpl.n pjrst askipr pjrst au.eba AU.EBA:: move c,n.rang(t1) cail c,^d2048 pjrst a.mov7 skiple u.torp(uot) pjrst a.phot cail c,^d1024 pjrst a.mov7 movei t2,^d400 pjrst a.phas
ISSION 4 ; ; capture a planet. AI.CAP:: move t1,nupl.t move t2,nrpl.t camg t2,nrpl.n jrst ai.ca1 move t1,nupl.n move t2,nrpl.n ai.ca1: skipge t1 retskp movei c,4 ;CAP mission code. movem c,n.mssn(uot) movem t1,n.muot(uot) pjrst au.cap AC.CAP:: move c,nrsh.t caig c,^d1024 pjrst askipr hrrz t1,n.muot(uot) move t2,n.rang(t1) pjrst au.cap AU.CAP:: move c,u.tab(t1) trne c,@alya.u pjrst askipr cail t2,^d512 pjrst a.mov7 tlnn c,100 jrst au.ca3 au.ca1: aoj t1, trnn t1,3 jrst au.ca2 skipge u.tab(t1) jrst au.ca1 movei t2,^d500 pjrst a.phas au.ca2: subi t1,4 save uot move uot,t1 setz t1, call tqins rest uot movei t1,^d750 pjrst tqins au.ca3: setzm n.mssn(uot) setom n.muot(uot) move c,u.tab(t1) trz c,7b31 ior c,alya.u movem c,u.tab(t1) movem t1,^d1000 pjrst tqins ;***** Ax.HLP, MISSION 5 AI.HLP:: move t3,u.alrt(uot) and t3,mska.u skipn t3 retskp movei t1,7 movei t2,1b18 ai.hl1: came t1,uot tdnn t3,t2 jrst ai.hl2 skipl u.tab(t1)
ai.hl3 ai.hl2: lsh t2,-1 sojge t1,ai.hl1 retskp ai.hl3: movem t1,n.muot(uot) hrlm t2,n.muot(uot) movei c,5 ;HLP mission code movem c,n.mssn(uot) pjrst au.hlp AC.HLP:: hrrz t1,n.muot(uot) came t1,uot skipge u.tab(t1) jrst ac.hl1 hlrz t2,n.muot(uot) tdnn t2,u.alrt(uot) jrst ac.hl1 pjrst au.hlp ac.hl1: andcam t2,u.alrt(uot) pjrst askipr AU.HLP:: move c,n.rang(t1) caile c,^d256 pjrst a.mov7 skiple c,u.shld(t1) jrst au.hl9 movm c,c add c,u.ener(t1) camle c,[^d200K] jrst au.hl9 move c,mask.a hrli c,4 movsm c,eadd.a movem uot,eadd.b setzm eadd.t save t1,t2 call lqins rest t1,t2 move c,u.ener(t1) add c,[^d400K] movem c,u.ener(t1) move c,u.ener(uot) sub c,[^d400K] movem c,u.ener(uot) move c,t2 ior c,uot hrli c,10 movsm c,eadd.a movem t1,eadd.b move c,n.rang(t1) movem c,eadd.t save t2 call lqins rest t2 andcam t2,u.alrt(uot) setzm n.mssn(uot) setom n.muot(uot) movei t1,^d3000 pjrst tqins au.hl9: andcam t2,u.alrt(uot) pjrst askipr ;***** SALLOC
; allocates a percent of UOT's total energy to the shields. T1 ; contains the integer percent, eg 50 for 50 percent. SALLOC:: save t2,t3 move c,n.ener move t2,c imul t2,t1 idivi t2,^d100 sub c,t2 movem c,u.ener(uot) caig t2,^d100000 movn t2,t2 movem t2,u.shld(uot) rest t2,t3 ret ;***** AUNXSB AUNXSB:: save t2,t3,t4 move t2,uot andi t2,1 addi t2,sb.mn setz t3, seto t4, tlz t4,1b18 ans.1: came t2,t1 skipge u.tab(t2) jrst ans.2 camg t4,n.rang(t2) jrst ans.2 move t3,t2 move t4,n.rang(t2) ans.2: addi t2,2 caig t2,sb.mx jrst ans.1 skipe t3 move t1,t3 rest t2,t3,t4 ret ;***** AUBASE ; ; returns uot of nearest base in T1, range in T2. if no base exists, ; T1 < 0 and non-skip, otherwise a skip ret. AUBASE:: move t1,nupl.u move t2,nrpl.u camg t2,nrsb.u jrst .+3 move t1,nusb.u move t2,nrsb.u skipl t1 aos (p) ret ;***** AUNXTB AUNXTB:: movei t2,sb.mn move t3,t1 call aunxb jrst [sos t2,t1 movei t3,pl.mx call aunxb ret jrst .+1]
e t1,t3 aos (p) ret aunxb: soj t3, camge t3,t2 ret skipl c,u.tab(t3) trnn c,@alya.u jrst aunxb andi c,17 cail c,2 caile c,4 jrst aunxb aos (p) ret ;***** A.REEN A.REEN:: move t2,t1 move t1,uot call reener movei t1,^d1500 pjrst tqins ;***** A.PHOT, A.PHAS A.PHOT:: sos u.torp(uot) movsi c,1b27 hrri c,^d200 movem c,a.fire skipa A.PHAS:: movem t2,a.fire hrrz c,a.fire imul c,c exch c,u.ener(uot) subm c,u.ener(uot) call authit movei t1,^d3000 pjrst tqins ;***** A.MOV7, A.MOV8, A.MOVE A.MOV7:: movei t2,7 pjrst a.move A.MOV8:: movei t2,8 pjrst a.move A.MOVE:: call autxyz move t1,n.rang(t1) call autmot skip movei t1,^d1000 pjrst tqins ;***** 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.
:: save t1,t2 movm t3,t2 move c,u.ener(uot) am.1: caml c,wf.ene(t3) jrst am.2 sojge t3,am.1 rest t1,t2 ret am.2: rest t1,t2 move c,wf.ene(t3) exch c,u.ener(uot) subm c,u.ener(uot) move c,wf.dis(t3) skipge t2 movn c,c move t2,c call autmov aos (p) ret ;***** AUTXYZ ; ; moves abs coordinates of object T1 to A.ABSn. AUTXYZ:: move c,u.absx(t1) movem c,a.absx move c,u.absy(t1) movem c,a.absy move c,u.absz(t1) movem c,a.absz ret ;***** AUTDIS (not referenced 1/8/81) ; ; computes T1 = range between UOT and coordinates A.ABSn. AUTDIS:: move c,u.absx(uot) fsbr c,a.absx fmpr c,c movem c,f.data move c,u.absy(uot) fsbr c,a.absy fmpr c,c fadrm c,f.data move c,u.absz(uot) fsbr c,a.absz fmpr c,c fadrm c,f.data movei c,f.loc call sqrt.## fixr t1,rs ret ;***** AUTMOV ; ; move object UOT toward (or away from) coordinates A.ABSX, A.ABSY, ; A.ABSZ at warp T2. T2 > 0 moves toward, T2 < 0 moves away. T1 ; must contain range from UOT to coordinates. AUTMOV:: skipg t1
t save p1,p2,p3 fltr t3,t2 fltr c,t1 fdvr t3,c move t4,[1.0] fsbr t4,t3 fmprm t3,a.absx move p1,u.absx(uot) fmpr p1,t4 fadr p1,a.absx fmprm t3,a.absy move p2,u.absy(uot) fmpr p2,t4 fadr p2,a.absy fmprm t3,a.absz move p3,u.absz(uot) fmpr p3,t4 fadr p3,a.absz movem p1,u.absx(uot) movem p2,u.absy(uot) movem p3,u.absz(uot) rest p1,p2,p3 hrlz c,mask.a hrri c,1 movem c,eadd.a movem uot,eadd.b setzm eadd.t pjrst lqins ;***** ASKIPR ASKIPR:: setzm n.mssn(uot) setom n.muot(uot) RSKP:: aos (p) R:: ret ;***** SETUP SETUP:: setom u.side call intlok call gamchk setz t1, movei suot,sh.mx set.a: move c,u.tab(suot) tlne c,3b19 aoj t1, sojge suot,set.a cail t1,sh.ct jrst [typec <[H[JAll ships in play, try again later> setzm i.lock gexit] type <[H[J> skipe gam.nr jrst [type <Tournament Game > outchr gam.nr crlf jrst .+2] typec <Random Game> call su.pla call su.ava crlf crlf type <Enter the initial of the ship you wish to command: _[D7>
st set.g set.e: type <[D_[D> type <> ife tops20,<clrbfi> ifn tops20,< movei t1,.priin cfibf > set.g: inchrw t1 caig t1," " jrst set.e+1 outchr t1 trz t1,1b30 movem t1,c.char movei suot,7 set.h: move t2,[point 7,o.init(suot)] ildb t2,t2 camn t2,c.char jrst set.n sojge suot,set.h jrst set.e set.n: move t2,u.tab(suot) tlne t2,3b19 jrst set.e skipl u.side jrst [hrrz c,suot andi c,1 came c,u.side jrst set.e jrst .+1] tlo t2,1b19 movem t2,u.tab(suot) getime c setzm time.q(suot) movem suot,s.uot call usrlod movei t2,2000 lsh t2,@suot movem t2,mask.c andcam t2,mask.o tso t2,mask.q movsm t2,mask.q move t2,mask.f move c,suot andi c,1 movem t2,mask.u(c) move t2,ally.f movem t2,ally.u(c) set.x: setzm i.lock ;release the interlock (set in the ret ; intlok routine) and ret. GAMCHK:: ife tops20,<mstime t2,> ifn tops20,< time move t2,t1 > movei uot,sh.mx+1 gchk.1: sojl uot,[setzm u.tty move c,[xwd u.tty,u.tty+1] blt c,u.tty+sh.mx
t] skipl c,u.tab(uot) tlnn c,1b19 jrst gchk.1 move c,u.time(uot) sub c,t2 skipg c movn c,c camle c,[^d300000] jrst gchk.1 ife tops20,<getlin c,> ifn tops20,< save t2 gjinf move c,t4 rest t2 > movei uot,sh.mx+1 gchk.2: sojl uot,r came c,u.tty(uot) jrst gchk.2 move c,uot andi c,1 movem c,u.side gchk.3: skipl u.tab(c) jrst gchk.4 addi c,2 caig c,sh.mx jrst gchk.3 movei t1,[asciz /Federation/] trne c,1 movei t1,[asciz /Klingon Empire/] type <[H[JThe > outstr (t1) type < has been defeated!> setzm i.lock gexit 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 ret. 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 skipe t1 ; are > 0, otherwise only displays jrst [push p,t1 ; seconds.
timout type < minute> movei c,[asciz /s, /] pop p,t1 cain t1,1 movei c,[asciz /, /] outstr (c) jrst .+1] move t1,0(p) call timout type < second> pop p,t1 caie t1,1 type <s> crlf setzm i.lock ife tops20,<exit 1,> ;exit from the game. ifn tops20,<haltf> inchrw c cain c,"Z" ret gexit timout: idivi t1,^d10 ;displays a number without leading save t2 ; zeroes. skipe t1 call timout rest t2 addi t2,"0" outchr t2 ret ;***** 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:: ife tops20,<mstime t1,> ifn tops20,<time> skipn i.lock jrst ilok.2 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
d300000] ; wrong (crash during startup) and jrst ilok.2 ; give player control immediately. type <[H[JStart-up interlock, please stand by > ilok.1: ife tops20,< movsi c,1b18 ;causes immediate swap out. tro c,1 ;wait a jiffy. hiber c, skip ;hiber failure - ignore. > ifn tops20,< exch c,t1 movei t1,^d1000 ;wait 1 disms exch t1,c > skipe i.lock jrst ilok.1 ilok.2: setom i.lock ;lock others out. movem t1,i.time ;save for future use by other startups. ret ;player now controls interlock. ;***** 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,15 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
4,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 <(> ife tops20,< move p4,u.nam1(uot) call su.six move p4,u.nam2(uot) call su.six > ifn tops20,< save t1,t2 movei t1,.priou move t2,u.namx(uot) dirst jfcl rest t1,t2 > type <)> ret ife tops20,< su.six: movei p1,6 setz p3, lshc p3,6 addi p3,40 outchr p3 sojg p1,.-4 ret > ;***** SU.AVA ; ; displays ships currently available. SU.AVA:: crlf typec <Available ships:> call su.hed movei c,15 movni t1,2 movni t2,1 su.av1: crlf setz t3, su.av2: skipg u.side cail t1,6 jrst su.av3 addi t1,2 move t4,u.tab(t1) tlne t4,3b19 jrst su.av2 outchr c type < > outstr @o.name(t1) seto t3, su.av3: skipe u.side cail t2,7 jrst su.av4 addi t2,2 move t4,u.tab(t2) tlne t4,3b19 jrst su.av3 outchr c type <[38C> outstr @o.name(t2) jrst su.av1 su.av4: jumpn t3,su.av1 ret su.hed: crlf
tr su.ln1 crlf outstr su.ln2 ret usrlod: ife tops20,< pjob t1, movem t1,u.job(suot) getlin t1, movem t1,u.tty(suot) move t1,[xwd -1,31] gettab t1, skip movem t1,u.nam1(suot) move t1,[xwd -1,32] gettab t1, skip movem t1,u.nam2(suot) move t1,[xwd -1,2] gettab t1, skip movem t1,u.ppn(suot) > ifn tops20,< gjinf movem t3,u.job(suot) movem t1,u.namx(suot) movem t4,u.tty(suot) > ret ;***** ROTRAN 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 ;***** 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: _[D7> inchrw p2 outchr p2 ife tops20,< cain p2,15 jrst .-3 ;if CR, get the LF. > crlf ;display CRLF to acknowledge. cail p2,"1" caile p2,"9" jrst sel.rn
gam.nr ;tournament game: andi p2,17 ; cycle the randomizer 3 * tournament imuli p2,3 ; number times. call random sojg p2,.-1 jrst sel.ld sel.rn: setzm gam.nr ;random game: call ranset ; seed the randomizer with mstime. sel.ld: call loadq ;init the queue. pjrst loadu ;init the universal object table. ;***** LOADQ ; ; Initializes the event queue. LOADQ:: move c,[xwd 1777,777777] movem c,mask.q setzm q move c,[xwd q,q+1] blt c,q+q.size-1 setzm time.q move c,[xwd time.q,time.q+1] blt c,time.q+117 ret ;***** 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 .+6 call lu.lim ;get range limits call lu.xyz ;get universal x, y, and z call lu.tst ;test 512 distances jrst .-2 ;not 512 from all other objects call lu.mov ;move universal x, y, and z to uot caige uot,217 ;all objects loaded?
repeat for next object ret ;table loaded lu.uot: move t1,u.tab(uot) andi t1,7 move c,ui.t0(t1) movem c,u.tab(uot) move c,ui.e0(t1) movem c,u.ener(uot) move c,ui.s0(t1) movem c,u.shld(uot) caile uot,7 ret movei c,^d10 movem c,u.torp(uot) movei c,^d10000 movem c,time.q(uot) move c,uot tro c,10 movem c,n.muot(uot) setzm n.mssn(uot) setzm u.absx(uot) setzm u.absy(uot) setzm u.absz(uot) setzm u.alrt(uot) setzm u.time(uot) setzm u.job(uot) setzm u.tty(uot) ife tops20,< setzm u.ppn(uot) setzm u.nam1(uot) setzm u.nam2(uot) > ifn tops20,< setzm u.namx(uot) > ret lu.lim: movei t2,1 cain t1,1 ;star? jrst [movei t1,^d4000 jrst lu.lm1] cain t1,2 ;planet? jrst [movei t1,^d2000 jrst lu.lm1] 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
dom 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: jumpg uot,.+3 ;don't test if 1st element aos (p) ;form skip ret ret ;return to calling routine movn t3,uot hrlz t3,t3 lu.ts1: 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,lu.ts1 ;try the next entry aos (p) ;passed test for all entries ret lu.mov: move t2,u.tab(uot) andi t2,7 move t1,x1 ;get x movem t1,u.absx(uot) ;store x ; caig uot,7 ; movem t1,u.begx(uot) cain t2,2 movem t1,1+u.absx(uot) move t1,y1 ;get y movem t1,u.absy(uot) ;store y ; caig uot,7 ; movem t1,u.begy(uot) cain t2,2 movem t1,2+u.absy(uot) move t1,z1 ;get z movem t1,u.absz(uot) ;store z ; caig uot,7 ; movem t1,u.begz(uot) cain t2,2 movem t1,3+u.absz(uot) ret ;return to calling routine ;***** RANSET ; ; Seeds the Fortran random number generator with the current ; time of day. RANSET::
s20,<mstime t1,> ifn tops20,<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 ;***** 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 reted in AC0 rest t1 fmpr t1,rs fix t1,t1 add t1,ran.mn movem t1,ran.nr ret ;***** INIPSI ; ; Initializes ctrl-c trapping. INIPSI:: ife tops20,< movei ap,ivb piini. ap, jrst [typec <PIINI error> exit 1, exit] move ap,[exp ps.fac+ps.fon+ccarg] pisys. ap, jrst [typec <PISYS error (CCTRAP)> exit 1, exit] > ifn tops20,< cis ;clear int system movei t1,ictrap hrrm t1,chntab+1 movei t1,.fhslf move t2,[levtab,,chntab] sir eir ;enable ints movx t2,1b1!1b2 ;chls 1 and 2 aic move t1,[.ticcc,,1] ;put ctrl-c on chl 1 ati
.+1 ; in case user has disabled this move t1,[.ticti,,2] ;put typein on chl 2 ati > ret ;***** ICTRAP ICTRAP:: type <[H[J> setzm i.lock call ttyrst movei ap,icend ife tops20,< movem ap,ivb+1 debrk. skip > ifn tops20,< movem ap,lev1pc debrk erjmp .+1 > icend: gexit ;***** CCTRAP CCTRAP:: type <[H[J> call stwait move c,u.tab(suot) tlz c,1b19 movem c,u.tab(suot) call wrapup movei ap,ccend ife tops20,< movem ap,ivb+1 debrk. skip > ifn tops20,< movem ap,lev1pc debrk erjmp .+1 > ccend: gexit ;**** STWAIT ; ; Sets the mstime after which a player may reenter the game. STWAIT:: ife tops20,< mstime c, ;get current time. add c,[dec 120000] ;add 2 minutes. caml c,[dec 86400000] ;check whether past midnight. sub c,[dec 86400000] ;it is - subtract 24 hrs. > ifn tops20,< 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 ;***** WRAPUP ; ; Performs cleanup after a ship is destroyed, quits, or
ol-c's. WRAPUP:: 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) ife tops20,< clrbfi type <(B[m> releas ttychn, skip > ifn tops20,< movei t1,.priin cfibf type <(B[m> > call ttyrst ret ;***** OBLOAD OBLOAD:: call otabld call scanld call tarupd call viewld ret ;***** OTABLD OTABLD:: movei uot,217 skipge u.tab(uot) jrst [move ap,[9999.0] movem ap,o.rang(uot) jrst .+3] came uot,suot call rbelod sojge uot,.-4 ret ;***** RBELOD RBELOD:: move t1,u.absx(uot) movem t1,x1 move t1,u.absy(uot) movem t1,y1 move t1,u.absz(uot) movem t1,z1 call rbecmp move t1,x1 movem t1,o.relx(uot) move t1,y1 movem t1,o.rely(uot) move t1,z1 movem t1,o.relz(uot) move t1,r1 movem t1,o.rang(uot) move t1,b1 movem t1,o.bear(uot) move t1,e1
o.elev(uot) ret ;***** RBECMP RBECMP:: move t1,x1 fsbr t1,u.absx(suot) movem t1,x2 move t1,y1 fsbr t1,u.absy(suot) movem t1,y2 move t1,z1 fsbr t1,u.absz(suot) movem t1,z2 move t1,x2 fmpr t1,s.11 movem t1,x1 move t1,y2 fmpr t1,s.12 fadrm t1,x1 move t1,z2 fmpr t1,s.13 fadrm t1,x1 move t1,x2 fmpr t1,s.21 movem t1,y1 move t1,y2 fmpr t1,s.22 fadrm t1,y1 move t1,z2 fmpr t1,s.23 fadrm t1,y1 move t1,x2 fmpr t1,s.31 movem t1,z1 move t1,y2 fmpr t1,s.32 fadrm t1,z1 move t1,z2 fmpr t1,s.33 fadrm t1,z1 move t1,x1 fmpr t1,t1 movem t1,x2 movem t1,f.data move t1,y1 fmpr t1,t1 movem t1,y2 fadrm t1,f.data move t1,z1 fmpr t1,t1 movem t1,z2 fadrm t1,f.data movei c,f.loc call sqrt.## movem rs,r1 move t1,y1 fdvr t1,x1 movem t1,b1 move t1,x2 fadr t1,y2 movem t1,f.data movei c,f.loc call sqrt.## move t1,z1 fdvr t1,rs movem t1,e1 ret ;***** ROT.ZY ROT.ZY:: move t1,b1 call sincos call rot.z move t1,e1 call sincos call rot.y ret ;***** ROT.X ROT.X::
ll savmat move t1,a.21 ;s.21 = (a.31 * sin.a) + (a.21 * cos.a) fmpr t1,cos.a movem t1,s.21 move t1,a.31 fmpr t1,sin.a fadrm t1,s.21 move t1,a.21 ;s.31 = (a.31 * cos.a) - (a.21 * sin.a) fmpr t1,sin.a movem t1,s.31 move t1,a.31 fmpr t1,cos.a fsbrm t1,s.31 move t1,a.22 ;s.22 = (a.32 * sin.a) + (a.22 * cos.a) fmpr t1,cos.a movem t1,s.22 move t1,a.32 fmpr t1,sin.a fadrm t1,s.22 move t1,a.22 ;s.32 = (a.32 * cos.a) - (a.22 * sin.a) fmpr t1,sin.a movem t1,s.32 move t1,a.32 fmpr t1,cos.a fsbrm t1,s.32 move t1,a.23 ;s.23 = (a.33 * sin.a) + (a.23 * cos.a) fmpr t1,cos.a movem t1,s.23 move t1,a.33 fmpr t1,sin.a fadrm t1,s.23 move t1,a.23 ;s.33 = (a.33 * cos.a) - (a.23 * sin.a) fmpr t1,sin.a movem t1,s.33 move t1,a.33 fmpr t1,cos.a fsbrm t1,s.33 ret ;***** ROT.Y ROT.Y:: call savmat move t1,a.11 ;s.11 = (a.31 * sin.a) + (a.11 * cos.a) fmpr t1,cos.a movem t1,s.11 move t1,a.31 fmpr t1,sin.a fadrm t1,s.11 move t1,a.11 ;s.31 = (a.31 * cos.a) - (a.11 * sin.a)
a movem t1,s.31 move t1,a.31 fmpr t1,cos.a fsbrm t1,s.31 move t1,a.12 ;s.12 = (a.32 * sin.a) + (a.12 * cos.a) fmpr t1,cos.a movem t1,s.12 move t1,a.32 fmpr t1,sin.a fadrm t1,s.12 move t1,a.12 ;s.32 = (a.32 * cos.a) - (a.12 * sin.a) fmpr t1,sin.a movem t1,s.32 move t1,a.32 fmpr t1,cos.a fsbrm t1,s.32 move t1,a.13 ;s.13 = (a.33 * sin.a) + (a.13 * cos.a) fmpr t1,cos.a movem t1,s.13 move t1,a.33 fmpr t1,sin.a fadrm t1,s.13 move t1,a.13 ;s.33 = (a.33 * cos.a) - (a.13 * sin.a) fmpr t1,sin.a movem t1,s.33 move t1,a.33 fmpr t1,cos.a fsbrm t1,s.33 ret ;***** ROT.Z ROT.Z:: call savmat move t1,a.11 ;s.11 = (a.21 * sin.a) + (a.11 * cos.a) fmpr t1,cos.a movem t1,s.11 move t1,a.21 fmpr t1,sin.a fadrm t1,s.11 move t1,a.11 ;s.21 = (a.21 * cos.a) - (a.11 * sin.a) fmpr t1,sin.a movem t1,s.21 move t1,a.21 fmpr t1,cos.a fsbrm t1,s.21 move t1,a.12 ;s.12 = (a.22 * sin.a) + (a.12 * cos.a) fmpr t1,cos.a movem t1,s.12 move t1,a.22 fmpr t1,sin.a fadrm t1,s.12
;s.22 = (a.22 * cos.a) - (a.12 * sin.a) fmpr t1,sin.a movem t1,s.22 move t1,a.22 fmpr t1,cos.a fsbrm t1,s.22 move t1,a.13 ;s.13 = (a.23 * sin.a) + (a.13 * cos.a) fmpr t1,cos.a movem t1,s.13 move t1,a.23 fmpr t1,sin.a fadrm t1,s.13 move t1,a.13 ;s.23 = (a.23 * cos.a) - (a.13 * sin.a) fmpr t1,sin.a movem t1,s.23 move t1,a.23 fmpr t1,cos.a fsbrm t1,s.23 ret savmat: move t1,[s.11,,a.11] blt t1,a.11+^d8 ret ;***** SINCOS SINCOS:: save t1,t2 movei ap,f.loc movem t1,f.data call sind.## movem rs,sin.a call cosd.## movem rs,cos.a rest t1,t2 ret ;***** CONUOT CONUOT:: move t1,o.bear(uot) movem t1,b1 move t1,o.elev(uot) movem t1,e1 move t1,o.rang(uot) movem t1,r1 move t1,o.relx(uot) movem t1,x1 move t1,o.rely(uot) movem t1,y1 move t1,o.relz(uot) movem t1,z1 call conang ret ;***** CONANG CONANG:: move ap,e1 call atana movem rs,e1 move ap,b1 call atana skipl x1 jrst .+5 move ap,[-180.0] skipg rs movm ap,ap fadr rs,ap movem rs,b1 ret ;***** CONTRC
CONTRC:: move row,t.elev fmpr row,[-0.25] fadr row,[7.0] fixr row,row move col,t.bear fmpr col,[0.625] fadr col,[41.0] fixr col,col ret ;***** CONURC CONURC:: move row,e1 fmpr row,[-0.25] fadr row,[7.0] fixr row,row move col,b1 fmpr col,[0.625] fadr col,[41.0] fixr col,col ret ;***** ATANA ATANA:: call fatan fmpr rs,[57.29577951] ret ;***** FATAN FATAN:: save t1,t2,t3 movem c,f.data movei c,f.loc call atan.## rest t1,t2,t3 ret ;***** 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)
SCAN ; 6 = RAPID FIRE PAHSER ; 7 = RAPID FIRE PHOTON ; -1 = more VTCMD:: type <8> setzm c.imm ;reset the immediate flag skiple ap,c.dir caie ap,5 skipa jrst [setzm c.dir type <[16;45H[7m 8> jrst .+1] 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 reted 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,"" ;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
ne 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 ret) jrst vc.1d ;must validate the cmd (hlp ret) 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?
har 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," " ;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)
lp ;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?
ive 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
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 .+3 ;no - store in nbr1 movem t3,c.nbr2 ;yes - store it jrst .+2 ;skip the next movem t3,c.nbr1 ;store in nbr1 aos c.cnt ;increment the count
? 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 jrst .+2 ;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
ate caie t1,"" ;escape sequence? ret ;no - can't be immediate (arrow) cain t2,"0" ;keypad zero? (LR SCAN) jrst [movei t2,5 ;yes jrst vc.imx] cain t2,"." ;keypad period? (MORE) jrst [seto t2, ;yes jrst vc.imx] cail t2,"A" ;is the character caile t2,"D" ; one of the letters A, B, C, or D? skipa ;no jrst [andi t2,7 ;yes - mask out all but last three bits jrst vc.imx] skipn r.fire ;rapid fire enabled? ret ;no - ret caie t2,"5" ;rf phasers? cain t2,"6" ;rf photon torpedo? skipa ;yes ret ;no andi t2,7 ;mask the bits aoj t2, ;incr 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
ol: 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,"" ;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
ndicating arrow was entered ret ;return to calling routine vc.sen: aos (sp) caie t1,"" jrst vc.sn1 movsi t3,-4 came t2,[exp "A","B","C","D"](t3) aobjn t3,.-1 skipl t3 ret move t3,[exp 1, 2, 0, 0](t3) jrst vc.sn2 vc.sn1: trz t2,1b30 movsi t3,-^d11 came t2,[exp "A","F","K","E","C","I","H","L","P","V","R"](t3) aobjn t3,.-1 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 hll t3,c.tab(t4) came t3,c.tab(t4) ;in the table? aobjn t4,.-2 ;bump the pointer, try again jumpge t4,.+3 ;if not negative, it's not in the table hrrzm t4,c.cmd ;not zero - save the command nbr aos (sp) ;form the skip ret ret ;return to calling routine
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 .+3 ;no - continue type <> ;yes - signal the error ret ;return to calling routine 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 .+4 ;yes - continue caie t2,"+" ;plus sign? ret ;neither sign, ret setom i.sign ;set sign word to -1 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
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 char a period? ret ;yes - ret cain t1,^d9 ;is the inte a tab? ret ;yes - ret caie t1,0 ;is the entry from the main keyboard? jrst .+2 ;no - can't be a break, then caie t2," " ;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,^d13 ;execute key? (carriage ret) ret ;yes - normal ret
;form skip return 1 cain t2,"?" ;help function? ret ;yes - skip return 1 aos (sp) ;form skip return 2 cain t2,^d127 ;delete? ret ;yes - skip return 2 aos (sp) ;form skip return 3 cain t1,^d8 ;backspace? ret ;yes - skip return 3 cain t2,"," ;erase function? (same as backspace) ret ;yes - skip return 3 aos (sp) ;form skip return 4 ret ;none of the above - skip return 4 ;***** SCANLD SCANLD:: call scnclr movei uot,217 skipge u.tab(uot) jrst .+3 came uot,s.uot call scntst sojge uot,.-4 ret ;***** 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)
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 col call fatan fmpr rs,[35.80986218] fadr rs,[41.0] fixr col,rs cail col,6 caile col,^d76 ret ;col not in view movem row,row.2 call scnupd ret ;***** 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 ;***** 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
arther 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 ;incr 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 .+3 ;no - test same row jumpe t3,sc.upd ;end of table? - if so, add to end aoja t1,sc.tst ;try the next element 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 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
3,scan.2(t4) ; soj t4, ;decr the table idx camle t4,t1 ;are we at the insertion point? jrst .-6 ;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 ;***** 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 scd.1: skipn scan.1(t1) ;search for the uot ret ;not found hlrz t2,scan.1(t1) lsh t2,-^d9 came t2,uot aoja t1,scd.1 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
em t2,scan.2(t1) ; table move t2,scan.1+1(t1) movem t2,scan.1(t1) skipe t2 aoja t1,scd.2 ret ;***** 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 ;***** 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?
> ;yes, reset the cursor position. ret ;***** 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 vwc.1: skipn p2,scan.1(p1) jrst vwc.2 hrrz p2,p2 trz p2,-1000 camge p2,row aoja p1,vwc.1 vwc.2: call vwrupd pop sp,p2 pop sp,p1 ret VWRUPD:: came row,t.row jrst vwu.1 call vwrini camn row,p2 call vwrrow call vwrtar jrst vwu.2 vwu.1: came row,p2 jrst vwu.3 call vwrini call vwrrow vwu.2: skipl v.flag jrst .+3 call vwrins skipa call vwrdsp jrst vwu.4 vwu.3: skipge v.flag jrst .+3 call vwrnul skipa call vwrdel vwu.4: setzm v.flag ret ;***** VWRDEL VWRDEL:: call vr.tst ret call vr.ini setz t3, aoj col, idpb t3,v.tptr caige col,^d74 jrst .-3 ret VWRINI:: move t1,[v.wrk,,v.wrk+1] setzm v.wrk blt t1,v.wrk+^d13 ret VWRROW:: move t1,scan.2(p1) lsh t1,-5 cail t1,100 movei t1,77 trz t1,7 hlrz t2,scan.1(p1) trz t2,-10
t2 hrrz t2,v.obj(t1) trz t2,-10 cail t2,7 jrst vr.nxt hrrz t3,scan.1(p1) lsh t3,-^d9 sub t3,t2 soj t3, adjbp t3,v.wrkp movem t3,v.wptr move t2,v.obj(t1) lshc t1,5 andi t1,37 trnn t1,37 jrst vr.nxt idpb t1,v.wptr jrst .-5 vr.nxt: aoj p1, hrrz p2,scan.1(p1) trz p2,-1000 camn p2,row jrst vwrrow ret VWRTAR:: move col,t.col cain row,7 caie col,^d41 skipa ret cail col,2 caile col,^d74 ret adjbp col,v.wrkp ldb t1,col tro t1,40 dpb t1,col ret VWRCLR:: move t1,[v.tab,,v.tab+1] setzm v.tab blt t1,v.tab+^d172 ret VWRINS:: call vr.tst ret call vr.ini adjbp t3,v.wrkp movem t3,v.wptr vi.nxt: aoj col, ildb t2,v.wptr trz t2,40 idpb t2,v.tptr caige col,^d74 jrst vi.nxt ret VWRDSP:: call vr.tst ret call vr.ini adjbp t3,v.wrkp movem t3,v.wptr vr.dsp: aos t1,col ildb t2,v.wptr ildb t3,v.tptr came t2,t3 call vr.out caige t1,^d74 jrst vr.dsp ret vr.out: setom v.rset ;a char will be displayed, must reset later. call vnextp dpb t2,v.tptr setz t4,
t2,40 movei t4,40 ;; dpb t2,v.tptr hlrz t3,v.elem(t2) jumpe t3,.+4 came t3,v.mod outstr v.mod(t3) movem t3,v.mod hrrz t3,v.elem(t2) caie t4,0 type <[5;7m> trne t3,200 jrst vr.bri vr.drk: outchr t3 caie t4,0 type <[m> ret vr.bri: type <[1m> outchr t3 type <[m> ret VWRNUL:: call vr.tst ret call vr.ini vr.nu1: aoj col, ildb t3,v.tptr jumpe t3,vr.nu2 setz t3, dpb t3,v.tptr call vnextp type < > setom v.rset ;will reset the cursor later. vr.nu2: caige col,^d74 jrst vr.nu1 ret vr.tst: move t2,row caig t2,1 ret caig t2,^d12 aos (sp) ret vr.ini: move t3,row soj t3, imuli t3,^d78 addi t3,^d7 adjbp t3,v.tabp movem t3,v.tptr movei t3,7 movem t3,col ret ;***** TARUPD TARUPD:: move uot,t.uot jumpge uot,tu.chg move row,t.row move col,t.col ret tu.chg: fix t1,o.rang(uot) caile t1,^d1536 jrst tu.brk call conuot move t1,b1 movem t1,t.bear move t1,e1 movem t1,t.elev call contrc movem row,t.row movem col,t.col setzm t.view call rctest ret
m t.view ret tu.brk: mspini msptyp <target no longer locked> mspout setom t.uot setzm t.bear setzm t.elev movei row,7 movei col,^d41 movem row,t.row movem col,t.col setom t.view ret ;***** 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
le row,^d12 ; row must be between 2 and 12 jrst td.sav cail col,^d8 ;test col caile col,^d74 ; col 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 caie col,^d41 jrst [tro t2,40 dpb t2,t3 trz t2,40 jrst .+1] jumpn t1,.+3 ;different position for target? camn t2,t.elem ;no - different element number? jrst td.sav ;no - don't bother to display it again type <[;5;7m> ;turn on blink and reverse call td.dsp ;display the new cursor 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
s at center of viewer caie col,^d41 ; (row = 7 and col = 41) skipa ; don't display ret call vtpos ;position the cursor hlrz t3,v.elem(t2) ;get the mode of the element skipe t2 ;mode important? outstr v.mod(t3) ;yes - change the mode 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 ;ret ;***** 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 VNEXTP:: came row,v.row setzm v.col skipg v.col
1 camg col,v.col jrst vnxt.1 move t3,col sub t3,v.col soje t3,vnxt.1+1 type <[> idivi t3,^d10 tro t3,"0" tro t4,"0" caie t3,"0" outchr t3 outchr t4 type <C> skipa vnxt.1: call vtpos movem row,v.row movem col,v.col ret ;***** VTPOS ; ; Positions cursor at row and col. Works for 2-digit row ; and col. Destroys t3 and t4. 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 ;ret ;***** VTGET ; ;
rminal, 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," " ;move space to the char caige t4," " ;is it a ctrl char? (less than space) jrst vt.ctl ;yes caie t4,177 ;no - is it a delete? jrst vt.chr ;no - it's just a normal character movem t4,c.inte ;yes, a delete - move it to integer jrst vt.sav ;go to ret vt.ctl: movem t4,c.inte ;move to integer cain t4,33 ;is it an escape?
ife tops20,< cain t4,15 ;not an escape - is it a carriage ret? inchrw t3 ;yes - ignore the linefeed > jrst vt.sav ;go to ret 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 vt.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 vt.chr ;no - don't know what it is andi t4,77 ;make it a number or - , . character jrst vt.chr ;go to ret vt.upr: caie t4,"M" ;was it the ENTER key? jrst vt.pf ;no - test the pf keys movei t3,15 ;generate a carriage ret movem t3,c.inte ;move cr to integer jrst vt.chr ;go to ret vt.pf: cain t4,"P" ;is it pf1? movei t4,"A" ;yes - convert to up arrow cain t4,"Q" ;is it pf2?
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 vt.chr: movem t4,t1 ;move t4 to t1 vt.sav: movem t1,c.char ;save the character ret ;return to calling routine ;***** VTIMED VTIMED:: call d.time ife tops20,< seto t1, wake t1, skip movsi t1,1b32 hrri t1,^d500 move t2,t1 hiber t2, skip hiber t1, skip inchrs t4 jrst [call qtest jrst vtimed] ret > ifn tops20,< movei t1,.priin sibe jrst vtinp movei t1,^d500 disms vtdsms: movei t1,.priin sibe ;input now? jrst vtinp call qtest ;no - do q-processing jrst vtimed vtinp: inchrw t4 ret ;***** ITYPIN - get typein interrupts itypin: save t1 hrrz t1,lev2pc ;check interrupt PC caie t1,vtdsms jrst itypix ;not waiting - exit movsi t1,10000 ;user mode flag iorm t1,lev2pc ;debrk back to wakeup itypix: rest t1 debrk > ife tops20,< d.time: mstime t1,
iv t1,[^d60000] idiv t1,[^d60] came t1,l.hr pjrst d.hour came t2,l.mn pjrst d.min ret d.hour: movem t1,l.hr movem t2,l.mn type <[1;7m[24;74H> call d.out type <:> move t1,l.mn call d.out type <8> ret d.min: movem t2,l.mn move t1,t2 type <[1;7m[24;77H> call d.out type <8> ret d.out: idivi t1,^d10 addi t1,"0" addi t2,"0" outchr t1 outchr t2 ret > ifn tops20,< d.time: sosle d.tcnt ret movei t1,^d120 ;call approx every 500ms movem t1,d.tcnt type <[1;7m[24;74H> movei t1,.priou seto t2, movx t3,ot%nda!ot%nsc odtim type <8> ret > ;***** DSPCON ; ; Displays the TREK console. Positions cursor in middle of view ; screen and stores it. DSPCON:: call clrscr ;clear the screen 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 type <(B[m[7;41H7> ;position the cursor at screen center ret ;ret dspbri: type <[H[;1;7m(0> call dspbr1
br2 typec <[C [C16 [67C 16[C > call dspbr2 typec <[C [C 8 [67C 8 [C > call dspbr2 typec <[C [C 0 [67C 0 [C > call dspbr2 typec <[C [C 8 [67C 8 [C > call dspbr2 typec <[C [C16 [67C 16[C > call dspbr2 call dspbr3 typec < > call dspbr1 movei c,10 typec <[C [57C [17C > sojg c,.-1 type <[C> type < > typec <[17C > call dspbr3 type < > ret dspbr1: type <[C > type <48 40 32 24 16 8 0 8 16 24 32 40 48> typec < > ret dspbr2: typec <[C [C [67C [C > ret dspbr3: type <[C > type < > ret dspdrk: type <[2;1H[;7m> movei c,5 typec <[2C [3C [67C [3C > typec <[2C [3C~[67C~[3C > sojg c,.-2 typec <[2C [3C [67C [3C > type <[2C/ [2C> type </ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ \> type <[2C \> type <[15;1H>
vei c,10 typec <[2C [57C > sojg c,.-1 type <[2C/ \>
ret
dspdsp: type <(0[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(0>
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
clrscr: type <[1;24r=[?8h[?5;6;7l[H[J(B>
;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
ret
;***** VTEST
VTEST::
skipn vtflag
aosa (sp)
typec < >
ret
;***** VTINI
;
; Call: enter macro vtini using integer.
;
; Initializes and tests the terminal.
ife tops20,<
move t1,[xwd -1,2] ;.GTPPN
gettab t1,
skip
camn t1,[1106020002]
ret
came t1,[452003562]
>
skipe vtflag
jrst vterr
ret
;***** VTTEST
;
; Call: enter macro 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
IFN TOPS20,<
MOVEI T1,.PRIIN ;PRIMARY INPUT
GTTYP ;GET TYPE
ERJMP VTERR
CAIN T1,.TT100 ;VT100?
JRST VT100 ; YEP
CAIE T1,.TT125 ;VT125?
CAIN T1,.TTK10 ; OR VK100 == GIGI
JRST VT100 ; YESSIR
CAIE T1,.TTV52 ;VT52 (MIGHT BE IN COMPATIBILITY MODE)
JRST VTERR ; NOPE
> ;IFN TOPS20
type <Z> ;ask terminal to identify itself
ife tops20,<
mstime t2, ;get the current time in msecs
addi t2,^d2000 ;add 2000 msecs
movem t2,wtime ;save as end time
jrst vhiber ;jump to hiber
vwait: mstime t2, ;get the current time
caml t2,wtime ;less than the end time?
ret ;no - error (time limited exceeded)
vhiber: movsi t1,(1b14) ;set wake on character ready
iori t1,^d2000 ;set 2000 msec hiber time
hiber t1, ;hiber
skip ;hiber error - abort
inchrs t3 ;character ready?
jrst vwait ;no - test time limit
>
ifn tops20,<
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,"" ;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
IFN 1,<
outstr [asciz/</] ;>and change the mode to ANSI
vt100: setzm vtflag
ife tops20,<clrbfi>
ifn tops20,<
movei t1,.priin
cfibf
> ;TOPS20
> ;IFN 1
IFN 0,<
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,"1" ;make sure it is a VT100
ret
inchrw t3 ;skip the ;
inchrw t1 ;get options
inchrw t3 ;skip the final c
trnn t1,1b34 ;advanced video?
outstr [asciz /This VT100 does not have an advanced video option.
/]
> ;IFN 0
setzm vtflag ;clear flag (TTY is a VT100)
ret ;ret
vterr: typec < >
typec < >
typec <Sorry, this program only runs on a VT100 with Advanced Video Option>
ife tops20,<
exit
>
ifn tops20,<
haltf
jrst .-1
>