From eab1abbfb0b5d64472338b4afc9bc9f8b18f47c9 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Sat, 31 Dec 2016 17:07:34 +0100 Subject: [PATCH] MAZE - Imlac side of Maze War. This is assembled with MIDAS, and then translated with IMTRAN to an ASCII form suitable for uploading to an Imlac terminal. MOUSE is enabled to ensure the MSW opcode is defined. --- build/misc.tcl | 10 + src/imsrc/maze.3 | 3498 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3508 insertions(+) create mode 100644 src/imsrc/maze.3 diff --git a/build/misc.tcl b/build/misc.tcl index 62b8207d..e5153548 100644 --- a/build/misc.tcl +++ b/build/misc.tcl @@ -896,6 +896,16 @@ respond "*" ":link sys1; ts imprin, sys1; ts imprnt\r" respond "*" ":link sys1; ts ardprn, sys1; ts imprnt\r" respond "*" ":link sys1; ts tekprn, sys1; ts imprnt\r" +# Maze War +respond "*" ":midas /t sysbin;_imsrc; maze\r" +respond "with ^C" "MOUSE==1\r\003" +respond "with ^C" "MOUSE==1\r\003" +expect ":KILL" +respond "*" ":imtran\r" +respond "@" "imlac; m iml_sysbin; maze bin\r" +respond "@" "\032" +type ":kill\r" + # TJ6 respond "*" ":midas sysbin;_tj6;tj6\r" expect ":KILL" diff --git a/src/imsrc/maze.3 b/src/imsrc/maze.3 new file mode 100644 index 00000000..02f49aa8 --- /dev/null +++ b/src/imsrc/maze.3 @@ -0,0 +1,3498 @@ +TITLE MAZE.3 GREG THOMPSON (GAT) 04/11/74 + +; MAZE + +; Maze is a experiment in 3 dimensional graphics and intertask +; teleconferencing. It is a hunt and seek game that can involve up to +; eight Imlacs. The Imlac user is placed in a 16 by 32 square maze and +; attempts to hunt down and destroy the other inhabitents of the maze (the +; other Imlac users) before they do the same to him. Each player is +; represented by his uname (1 through 8 characters) as he moves through the +; maze. The various keys that are used to move through the maze and to +; fire are described below. +; +; UP ARROW - Move forward 1 square. +; DOWN ARROW - Back up one square. +; LEFT ARROW - Turn 90 degrees to the left. +; RIGHT ARROW- Turn 90 degrees to the right. +; FUNCTION 4 - Turn 180 degrees around. +; PAGE XMIT - Peek around the corner to the left. +; XMIT - Peek around the corner to the right. +; ESC - Fire. +; CTRL -Z - Exit maze program. +; FORM - Erase dispay buffer. +; FUNCTION 7 - Look at maze from top. +; +; The player enters the maze by typing MAZE to monit or MAZE^k to +; DDT, while at an imlac. The screen will be blank for a minute or two +; while the imlac side of the maze program is loaded after which the player +; is placed in to the maze along with any other players. A letter on the +; top of the screen indicates the direction you are currently facing. The +; unames of the other players are listed on the sides followed their score +; and the number of times they were shot. Anytime a player is shot the +; bell will ring and an "!" will be placed next to the shooting players +; score and an "*" will be placed next to the number of times shot counter +; of the player that was just shot. Holding down the up or down arrow keys +; will cause them to repeat. After a shot is fired the player who is being +; shot at has two seconds to get out of view of the position that the +; shooting player was at at the time he fired the shot. All other +; characters typed are placed in a display buffer at the bottom of all the +; imlac's screen. Holding the Function-7 (or TAB as the case my be) will +; allow you to view your position in the maze from the top. +; The 3 buttons on the mouse and the 5 keyset buttons may be used as +; controls and have the following functions, starting from the left of the +; mouse; peek left, fire, peek right, turn around, turn left, move +; forward, turn right, and move backwards. +; Users may specify their own mazes if they are the first player in a +; maze by giving a file name after "maze to use: ". Just a CR will default +; to the standard maze. User mazes must have a specific format if they are +; to be able to work. They must begin with a LOC 10020 followed by the label +; MAZE: on the first of 32. octal words which form a bit map for the +; maze. The maze must end with LOC 17713, JMP @.+1, 101, and an END. +; After assembling the maze must be imtraned by using the "IMTRAN" command. +; A muddle function exists for printing out formated source mazes. It is +; initiated by floading "imlac;maze print" in muddle and then issuing +; $ where the output file +; spec defaults to the TTY. An example of a formated source maze is given +; below: + +;.INSRT IMSRC;IMDEFS > +; +; LOC 10020' +; +; MAZE: 177777 ; HERE IS THE 32 WORD MAZE. +; 106401 ; NO FOUR SQUARES MAY BE EMPTY. +; 124675 ; AND SHARE A COMMON CORNER. +; 121205 ; ALL OUTSIDE WALLS MUST BE FILLED IN. +; 132055 ; THIS IS THE DEFAULT MAZE. +; 122741 +; 106415 +; 124161 +; 121405 +; 135775 +; 101005 +; 135365 +; 121205 +; 127261 +; 120205 +; 106765 +; 124405 +; 166575 +; 122005 +; 107735 +; 120001 +; 135575 +; 105005 +; 125365 +; 125225 +; 121265 +; 105005 +; 135375 +; 100201 +; 135675 +; 110041 +; 177777 +; +; END 101' ; AUTO START BACK INTO CONSOLE PROGRAM +; +; Players start in random loctions. + +; The current default maze is: +; +; N O R T H +; +; +; $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +; $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +; $$$ $$$$$$ $$$ $$$ +; $$$ $$$$$$ $$$ $$$ +; $$$ $$$ $$$ $$$$$$ $$$$$$$$$$$$ $$$ +; $$$ $$$ $$$ $$$$$$ $$$$$$$$$$$$ $$$ +; $$$ $$$ $$$ $$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$ $$$ +; $$$ $$$$$$ $$$ $$$ $$$$$$ $$$ +; $$$ $$$$$$ $$$ $$$ $$$$$$ $$$ +; $$$ $$$ $$$ $$$$$$$$$$$$ $$$ +; $$$ $$$ $$$ $$$$$$$$$$$$ $$$ +; $$$ $$$$$$ $$$ $$$$$$ $$$ +; $$$ $$$$$$ $$$ $$$$$$ $$$ +; $$$ $$$ $$$ $$$$$$$$$ $$$ +; $$$ $$$ $$$ $$$$$$$$$ $$$ +; $$$ $$$ $$$$$$ $$$ $$$ +; $$$ $$$ $$$$$$ $$$ $$$ +; $$$ $$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$ $$$ +; $$$ $$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$ $$$ +; $$$ $$$ $$$ $$$ +; $$$ $$$ $$$ $$$ +; $$$ $$$$$$$$$ $$$ $$$$$$$$$$$$ $$$ $$$ +; $$$ $$$$$$$$$ $$$ $$$$$$$$$$$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$ $$$ +; W $$$ $$$ $$$$$$$$$ $$$ $$$$$$ $$$ E +; $$$ $$$ $$$$$$$$$ $$$ $$$$$$ $$$ +; E $$$ $$$ $$$ $$$ $$$ A +; $$$ $$$ $$$ $$$ $$$ +; S $$$ $$$$$$ $$$$$$$$$$$$$$$ $$$ $$$ S +; $$$ $$$$$$ $$$$$$$$$$$$$$$ $$$ $$$ +; T $$$ $$$ $$$ $$$ $$$ $$$ T +; $$$ $$$ $$$ $$$ $$$ $$$ +; $$$$$$$$$ $$$$$$ $$$ $$$$$$$$$$$$$$$ $$$ +; $$$$$$$$$ $$$$$$ $$$ $$$$$$$$$$$$$$$ $$$ +; $$$ $$$ $$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$ +; $$$ $$$$$$$$$$$$$$$$$$ $$$$$$$$$ $$$ +; $$$ $$$$$$$$$$$$$$$$$$ $$$$$$$$$ $$$ +; $$$ $$$ $$$ +; $$$ $$$ $$$ +; $$$ $$$$$$$$$ $$$$$$ $$$$$$$$$$$$$$$ $$$ +; $$$ $$$$$$$$$ $$$$$$ $$$$$$$$$$$$$$$ $$$ +; $$$ $$$ $$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$$$$$$$$$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$$$$$$$$$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$$$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$$$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$ +; $$$ $$$ $$$ $$$ $$$ +; $$$ $$$$$$$$$ $$$ $$$$$$$$$$$$$$$$$$ $$$ +; $$$ $$$$$$$$$ $$$ $$$$$$$$$$$$$$$$$$ $$$ +; $$$ $$$ $$$ +; $$$ $$$ $$$ +; $$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$$$$ $$$ +; $$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$$$$ $$$ +; $$$ $$$ $$$ $$$ +; $$$ $$$ $$$ $$$ +; $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +; $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +; +; +; S O U T H +; + +; MAZE PROTOCOL: MESSAGES ARE SENT TO ALL OTHER IMLACS +; DO NOT SEND TO ORIGINATING IMLAC +; +; 001 -- PLAYER LEAVES GAME +; +; +; 002 -- PLAYER MOVED +; +; +; +; +; +; 003 -- PLAYER DIED +; +; +; +; 004 -- ANNOUNCE NEW PLAYER +; +; <6 CHARS OF ID NAME> +; <2 CHAR # OF HITS WITH 100 BIT ON> (HIGH ORDER 6 BITS THEN LOW ORDER 6 BITS) +; <2 CHAR # OF DEATHS WITH 100 BIT ON> +; +; 014 -- ERASE DISPLAY RING BUFFER +; +; +; IDS MUST BE >= 1 AND <= 8. +; +; ALL INCOMING MESSAGES ARE CHECKED FOR LEGALITY. BAD MESSAGES ARE FLUSHED. +; A NUMBER IN THE STATUS LINE INDICATES THE NUMBER OF BAD MESSAGES RECIEVED. +; INFORMATION CONCERNING THE LAST BAD MESSAGE RECIEVED IS SAVED FOR LATER EVALUATION. +; +; ALL CHARACTERS SUBROUTINES AND THE DJMS TABLE IS UP IN THE CONSOLE PROGRAM (SSV). +; THE DJMS TABLE IS ACCESSED THROUGH LOCATION 24 OCTAL WHICH STARTS WITH THE ENTRY +; FOR OCTAL CODE 40 (SPACE). +; +; ANY CHARACTERS TYPED ON CONSOLE (>014') ARE SENT TO PDP-10 AND SHOULD +; BE ECHOED TO ALL! CONSOLES INCLUDING THE ORIGINATOR. +; +; ANY OTHER CHARACTERS RECEIVED BY IMLAC ARE DISPLAYED IN A +; RING BUFFER AT THE BOTTOM OF THE PICTURE. +; +; THE FIRST ANNOUNCE NEW PLAYER MESSAGE THE IMLAC RECIEVES DEFINES ITS ID. +; +; THIS VERSION REQUIRES A GRAPHICS IMLAC WITH LONG VECTOR HARDWARE +; MULTI-LEVEL SUBROUTINING, AND 8K DISPLAY ADDRESSING MOD. +; +; THE MESSAGE SWITCHING PROGRAM ON THE 10 MUST ALSO KEEP TRACK +; OF THE CURRENT SCORES OF ALL THE PLAYERS SO WHEN A NEW PLAYER +; JOINS INTO A ALREADY EXISTING GAME HE MAY RECIEVE THE CURRECT +; SCORES OF ALL THE PLAYERS. +; +; WHEN AN IMLAC WANTS TO JOIN AN EXISTING MAZE THE FOLLOWING OCCURS: +; 1) THE MAZE PROGRAM IS LOADED INTO HIS IMLAC. +; 2) THE CURRENT MAZE IS LOADED ON TOP OF THE DEFAULT MAZE +; IF THE DEFAULT MAZE IS NOT BEING USED. +; 3) A TYPE 4 MESSAGE IS SENT TO ALL IMLACS ANOUNCING THE +; NEW IMLAC. THE NEW IMLAC GETS HIS ID FROM THIS MESSAGE. +; 4) TYPE 4 MESSAGES FOR ALL THE OTHER PLAYERS ARE SENT TO +; THE NEW IMLAC. +; +; WRITTEN BY: +; +; HOWARD PALMER STANFORD ORIGINAL IDEA & STAND-ALONE VERSION OF MAZE +; STEVE COLLEY CAL TECH ORIGINAL IDEA OF MAZE, STAND-ALONE MAZE +; & CRUDE MULTIPLE PLAYERS +; GREG THOMPSON M.I.T. FULL MULTIPLE PLAYERS ADDITIONS +; DAVE LEBLING M.I.T. PDP-10 MESSAGE SWITCHER AND ROBOTS +; KEN HARRENSTEIN M.I.T. PDP-10 part of fast interaction protocol +; CHARLES FRANKSTON M.I.T. IMLAC part of fast interaction protocol. + +; actual program begins here + +.INSRT IMSRC;IMDEFS > + ; To keep midas from barfing "RES" at use of these syms in prg. +IF1 EXPUNGE FIX,MOVE,PTR,EXP + +FAST==1 ; to assemble fast-protocol version. +CHEAT==0 ; conditional to assemble cheater stuff + +.MLLIT==1 + + LOC 10000' + +.ADDR.=1 ; 8k addressing for display opcodes + + JMP START ; starting point + JMP RESTART ; restarting entry point + JMP LEAVE ; entry to return to ssv (on error) + JMP RETN ; reenter maze main loop + + ; auto increment register definitions +DPTR=10' ; index loc 10 used as pointer +VISPT=11' +VISPT2=12' +VISPT3=13' +VISPT4=14' +VISPT5=15' + ; index location 16' and 17' used by interupt routine + + LOC 10020' + +; here is the 32 word maze: no four squares may be empty and share a +; common corner, and all outside walls must be filled in + +MAZE: 177777 ? 106401 ? 124675 ? 121205 ? 132055 ? 122741 ? 106415 ? 124161 + 121405 ? 135775 ? 101005 ? 135365 ? 121205 ? 127261 ? 120205 ? 106765 + 124405 ? 166575 ? 122005 ? 107735 ? 120001 ? 135575 ? 105005 ? 125365 + 125225 ? 121265 ? 105005 ? 135375 ? 100201 ? 135675 ? 110041 ? 177777 + + +; here to wait for the loader signal + +LOADER: RSF + JMP .-1 + CLA + RRC + AND [177] + SAM [^A] + JMP LOADER + RSF + JMP .-1 + CLA + RRC + AND [177] + SAM [^A] + JMP LOADER + JMP @[40] + +; dstat, dx, dy, dir is my position and point into info table + +DSTAT: 0 ; status flag +DX: 0 ; x position of this imlac +DY: 0 ; y position of this imlac + ; start out big so we won't show up on map +DIR: 0 ; direction he is pointing + ; bits 14 and 15 have meaning + ; bit 14,bit 15 + ; 0 0 north + ; 0 1 east + ; 1 0 south + ; 1 1 west + +NEXTBIT:0 +ETEM: 0 +WPTR: 0 +WPTR2: 0 +CNT: 0 ; counters +CNT2: 0 +KILL: 0 ; last player killed by this imlac +PTR4: 0 ; pointers +PTR3: 0 +PTR2: 0 +PTR: 0 +XDELTA: 0 +YDELTA: 0 +BEAMBIT:0 +LASTRIG:0 +LASTLEF:0 +HALLNGTH:0 +MYREAL: 0 ; the real id of this imlac +MYBIT: 0 ; the id of this imlac +MYBIT1: 0 ; mybit-1 (normalize to 0-7) +IID: 0 ; temporary imlac id used for see routine +MPTR: 0 +BIT: 0 + + ; keyboard and keyset input data + +KEY: 0 ; last key read in +KEYSET: 0 ; last value from keyset +KSCNT: 0 ; keyset repeat counter + +HOME: 1372' ; ctrl z [exits program] +BACKUP: 204' ; down arrow (backup one square) +RTURN: 205' ; right arrow (turn 90 degrees right) +MOVE: 206' ; up arrow (move forward one square) +LTURN: 210' ; left arrow (turn 90 degrees left) +TURNA: 234' ; function 4 (turn 180 degrees around) +PEEKR: 202' ; xmit (peek to the right) +FIRE: 233' ; esc (fire) +PEEKL: 216' ; page xmit (peek to the left) +ERING: 214' ; form (erase ring buffer) +TOPVW: 211' ; tab (get a top view of maze) + +TEM1: 0 ; temporarys +TEM2: 0 +TEM3: 0 + +TOPSW: -1 ; indicates whether a top or inside view + +IFN FAST,[ +RELCNT: 0 ;counter of rel positions between abs +] + +; start of game + +START: IOF ; disable any interupts + CLA + DAC ICNT ; set no message pending + DAC MYBIT ; indicate we have no id + MSW ; set initial keyset value + DAC KEYSET + LAC [7776'] ; limit ssv's display list + DAC @[25'] + JMS ERASE ; reset ring buffer + LAC [MESAGE-1] ; set up you were shot message + DAC 11' + LAC [YWSB-1] + DAC 12' + LWC 17. + DAC CNT2 +SETUPN: LAC @12' + JMS GETCHR + DAC @11' + ISZ CNT2 + JMP SETUPN +; +; now wait for our id +; + JMS CHARIN + LAC MYBIT ; wait for identifier message to come in + ASN ; has it been set yet? + JMP .-3 ; no, keep waiting + STA + DAC TOPSW ; display top view +; +; place player in maze +; +RESTART:KCF ; reset keyboard +RESET1: JMS RANDOM + AND [17'] + DAC @DX + JMS RANDOM + AND [37'] + DAC @DY + JMS PNTBIT + LAC @MPTR + AND BIT + ASZ + JMP RESET1 + JMS RANDOM + AND [3] + DAC @DIR + LAC [AD1] ; reset to main screen + DAC WHICHD +IFN FAST,[ + CLA + DAC RELCNT ; force abs. position out first thing. +] + JMP RETN4 + +RETN2: CLA ; look from inside maze + DAC TOPSW +; +; send new position to 10 +; +RETN4: STA ; set to playing status + DAC @DSTAT + JMS PRINT ; build current display +IFE FAST,[ + JMS ABSMSG ; send out absolute position + JMP RETN +] +IFN FAST,[ + LAC RELCNT + ASM ; if ge 0, something wants an abs pos sent out. + JMS ABSMSG ; sigh, send absolute + JMP RETN ; and continue + +RELMSG: 0 + IOR MYBIT1 + JMS SEND1 + ISZ RELCNT + NOP + JMP @RELMSG + +] ;end of ifn fast + +; send new absolute position +ABSMSG: 0 +IFN FAST,[ + LWC 20 ;number of rel messages before an abs + DAC RELCNT ;set counter +] + LAW 2 ; send moved message code + JMS SEND1 + LAC MYBIT ; send my id + JMS SEND1 + LAC @DIR ; send new direction + AND [3] ; send only lower 2 bits! + IOR [100'] + JMS SEND1 + LAC @DX ; send new x location + IOR [100'] + JMS SEND1 + LAC @DY ; send new y location + IOR [100'] + JMS SEND1 + JMP @ABSMSG ;return + +; +; main loop +; +RETN: JMS CHARIN ; get stuff from ten + JMS DISP ; maintain display +RETN3: KSF ; no, is there a key down? + JMP KSCHK ; no, now check keyset + CAL ; yes, read the key + KRC + DAC KEY + LWC 8. ; set up to rept key (time before start repeating) + DAC REPTCNT +REPT: LAC KEY +KEYREPT:SAM HOME ; is it ctrl-z? + JMP KEYCHK + LAC MYBIT ; remove me from maze + DAC ININFO + JMP GONER +; +; check keyset +; +KSCHK: CLA + MSW + SAM KEYSET ; has it changed? + JMP .+2 ; yes, so do something about it + JMP RETN ; no, re-enter main loop + DAC KEYSET ; save new value + LWC 15. ; set up to repeat + DAC KSCNT +KSREPT: LAC [BACKUP] ; now figure which key to simulate + DAC PTR + LAC KEYSET + IOR [174340'] ; turn on bits to ignore + CMA\CLL + ASN + JMP RETN + RAR 1 + LSZ + JMP GOTIT + XAM PTR + IAC + XAM PTR + JMP .-6 + +GOTIT: LAC @PTR ; get appropriate key + DAC KEY + JMP KEYREPT +; +; see if we are blowing up +; +KEYCHK: LAC BIGEXP ; if so then ignore keys + ASZ + JMP RETN ; yes, so wait it out +; +; check for various keyboard commands +; +KEY1: LAC KEY + SAM RTURN ; turn right? + JMP KEY2 + ISZ @DIR + NOP +IFN FAST,[ + LAC [20'] ; new protocol for right turn + JMS RELMSG +] + JMP RETN2 + +KEY2: SAM LTURN ; left turn? + JMP KEY3 + LAC @DIR + SUB [1] + DAC @DIR +IFN FAST,[ + LAC [30'] ; new protocol for left turn + JMS RELMSG +] + JMP RETN2 + +KEY3: SAM MOVE ; move forward? + JMP KEY4 + JMS MOVER + JMP RETN +IFN FAST,[ + LAC [150'] ; new protocol for move forward + JMS RELMSG +] + JMP RETN2 + +KEY4: SAM PEEKL ; peek left? + JMP KEY5 + JMS MOVER + JMP RETN +;ifn fast,[ +; lac [150'] ; new protocol for move forward +; ior mybit1 ; insert id +; jms send1 +;] + LAC @DIR + SUB [1] + DAC @DIR + JMS HOLD + LAC @DIR + SUB [1] + DAC @DIR +PEEKER: JMS MOVER + JMP RETN + JMS ADIR2 + JMP RETN2 + +KEY5: SAM PEEKR ; peek right? + JMP KEY6 + JMS MOVER + JMP RETN + ISZ @DIR + NOP + JMS HOLD + ISZ @DIR + NOP + JMP PEEKER + +KEY6: SAM TURNA ; turn around? + JMP KEY7 + JMS ADIR2 +IFN FAST,[ + LAC [140'] ; new protocol for turn-around + JMS RELMSG +] + JMP RETN2 + +KEY7: SAM BACKUP ; back up? + JMP KEY8 + JMS ADIR2 + JMS MOVER + JMP KEY7NP + JMS ADIR2 +IFN FAST,[ + LAC [160'] ; new protocol for move backwards. + JMS RELMSG +] + JMP RETN2 + +KEY7NP: JMS ADIR2 ; can't move backwards, restore direction. + JMP RETN + +ADIR2: 0 + LAC @DIR + ADD [2] + DAC @DIR + JMP @ADIR2 + +KEY8: SAM FIRE ; fire? + JMP KEY9 +; +; look for visible opponent to shoot at +; + LAC [THING+4] ; set display list pointer + DAC PTR + LWC 8. ; 8 possible imlacs + DAC CNT2 + LAC [IM1+4] ; set info table pointer + DAC VISPT + IAC + DAC PTR2 +CHKNEXT:LAC @PTR ; get display body + SAM [DNOP] ; is he visible? + JMP NOTDNOP +NOTHIM: LAC VISPT ; no, bump pointers to next player + ADD [11.] +BUMPTRS:DAC VISPT + IAC + DAC PTR2 + LAC PTR + ADD [6] + DAC PTR + ISZ CNT2 ; did we check them all + JMP CHKNEXT ; no + JMP RETN ; yes, return + +NOTDNOP:SAM JMSEXP ; could he already be exploding? + JMP FOUNONE ; no, so we found a opponent to shoot at + JMP NOTHIM ; yes, so don't fire at him +FOUNONE:LAC @PTR2 ; are we already firing on this guy? + ASZ ; if so then don't fire again + JMP NOTHIM + LWC 80. ; set 2 second delay to allow player to dodge it + DAC @VISPT + LAC @DIR + DAC @VISPT + LAC @DX ; save our location + DAC @VISPT + LAC @DY + DAC @VISPT + LAC VISPT ; now check next player + ADD [7] + JMP BUMPTRS +; +; does he want screen erased? +; +KEY9: SAM ERING + JMP VIEWTOP ; no + JMS ERASE ; yes, so erase it + JMP RETN ; then return to main loop +; +; look at maze from top +; +VIEWTOP:SAM TOPVW ; look at maze from top? +IFE CHEAT, JMP SENDIT +IFN CHEAT, JMP CHNGP + STA ; yes, set flag for top view + DAC TOPSW + JMS PRINT ; and build display +VTWAIT: JMS CHARIN + JMS DISP + CAL + KRB + SAM TOPVW ; display top view as long + JMP .+2 ; as key is held down + JMP VTWAIT + CLA ; look inside again + DAC TOPSW + JMS PRINT + JMP RETN + +IFN CHEAT,[ +; +; secret id switching keys +; +; ctrl-rept 0 to : +; 0 return to original id +; n changes to id n +; : complement forward square +; +CHNGP: SUB [3260'] + ASP + JMP SENDIT + SAM [10.] ; ctrl-rept : ? + JMP .+2 ; no + JMP ZAP ; yes + ASN ; ctrl-repeat 0? + LAC MYREAL ; if so get my real id + SUB [9.] + ASM + JMP RETN + ADD [9.] + DAC TEM1 + SAL 3 + ADD [IML1-8.] ; see if this player is playing + DAC TEM2 ; by seeing if his name exists + LAC [DJMS D040,] + SAM @TEM2 + JMP .+2 + JMP RETN + LAC TEM1 + JMS GETD ; change us to new id + JMS PRINT ; display new view + JMP RETN + +ZAP: JMS MOV ; set up ptrs to next square + LAC @MPTR ; now flip bit + XOR BIT + DAC @MPTR + JMS PRINT ; rebuild display + JMP RETN +] ;end of ifn cheat. + +; +; send other characters to 10 +; +SENDIT: +IFN CHEAT, ADD [3260'] + AND [177'] + SAM [15'] ; cr? + JMP .+2 + JMP SENDOK + SUB [40'] ; control code? + ASP + JMP RETN ; yes, so ignore it + SUB [100'] ;it's a 40-177 char, see if it's 140-177 + ASP + ADD [40'] ;no, it's 40-137, get char back. + ADD [100'] ;yes, 140-177. make it uppercase. + +SENDOK: JMS SEND1 ; now send it to 10. char is either 40-137 or 15. + JMP RETN +; +; hold a position for as long as the same key is held down +; +HOLD: 0 + JMS PRINT ; update display +HOLD1: JMS CHARIN ; get stuff from ten + JMS DISP ; maintain display + CAL + KRB + SAM KEY ; is the same key down? + JMP .+2 ; no, test key set for key still down + JMP HOLD1 ; yes, hold this location +TSTKS: CLA + MSW + ASN ; do we have the hardware? + JMP @HOLD ; no, just return + AND [2400'] ; if either peek left or right still + XOR [2400'] + ASZ ; down then hold position + JMP HOLD1 + JMP @HOLD ; return + +; +; point mptr to appropriate word maze (y) +; and bit to appropriate bit in word for our +; current location +; +PNTBIT: 0 + LAC [MAZE] + ADD @DY + DAC MPTR + LAC @DX + ASZ + JMP PNT1 + LAC [100000'] + JMP PNT2 + +PNT1: CIA + DAC CNT + CLL + LAC [100000'] + RAR 1 + ISZ CNT + JMP .-2 +PNT2: DAC BIT + JMP @PNTBIT +; +; move forward one square +; +MOV: 0 + CLA ; clear out increments + DAC TEM1 ; y increment + DAC TEM2 ; x increment + JMS PNTBIT ; position to current position + LAC @DIR ; see which direction we are heading + AND [1] + ASZ + JMP MOVEWE + JMS CREMENT ; move north or south + DAC TEM1 + ADD MPTR + DAC MPTR + JMP @MOV ; return + +MOVEWE: JMS CREMENT ; move west or east + AND [20'] + IOR [RAL 1] + DAC NOPER + LAC BIT + CLL +NOPER: NOP + DAC BIT + JMS CREMENT + CIA + DAC TEM2 ; set x increment + JMP @MOV + +MOVER: 0 + JMS MOV ; move forwards one square + LAC @MPTR ; see if it is a wall + AND BIT + ASZ + JMP @MOVER ; a open square + LAC TEM2 ; update x to this square + ADD @DX + DAC @DX + LAC TEM1 ; update y + ADD @DY + DAC @DY + ISZ MOVER ; and indicate we moved by skipping + JMP @MOVER +; +; return 1 or -1 according to which direction we are heading +; +CREMENT: 0 + LAC @DIR + SAR 1 + AND [1] + ASN + LAC [-1] + JMP @CREMENT + +; +; refreshing routine +; +REFR: 0 + DSF + SSF + JMP @REFR + SCF + LAC WHICHD ; get appropriate display list address + DLA + DON + STA ; indicate 40 cycle sync + DAC SYNC + JMP @REFR + +WHICHD: AD1 ; contains address of current display +SYNC: 0 ; 40 cycle sync flag +BIGEXP: 0 ; our explosion counter +JMSEXP: DJMS EXPLOSIN + +EXP: DDSP + DDSP + DDSP +INC1: DDSP +INC2: DDSP +INC3: DDSP + DRJM + +EXPLOSIN:DLXA 1000 + DJMS WAIT + DSTS 3 + INC E,D03 + INC D03,100' + DJMS EXP + INC E,D00 +INC4: INC D00,D00 + INC 100',100' + DJMS EXP + INC E,D00 +INC5: INC D00,D00 +INC6: INC D00,D00 + INC 100',100' + DJMP EXP +; +; keep display and timed occurances running +; +DISP: 0 + JMS REFR ; keep up display + LAC SYNC ; has the 40 cycle sync occured yet? + ASM + JMP @DISP ; no, just return + CLA ; yes, reset it + DAC SYNC +; +; check for our blowing up +; + LAC BIGEXP ; are we blowing up? + ASN + JMP CHKOPP ; no + ISZ BIGEXP ; is it finshed? + JMP UPDTBIG ; no, update it + JMP RESTART ; yes, now restart the imlac +; +; update 4 pointers +; +BUMPPTS:0 + LAC VISPT2 + ADD [5] + DAC VISPT2 + LAC VISPT3 + ADD [5] + DAC VISPT3 + LAC VISPT4 + ADD [5] + DAC VISPT4 + LAC VISPT5 + ADD [5] + DAC VISPT5 + JMP @BUMPPTS +; +; update a dlxa or dlya +; +UPDTSUB:0 + LAC @VISPT2 ; get old dlxa or dlya + ADD @VISPT ; add in increment + AND [1777'] ; mask to position bits + DAC TEM2 ; save new position + LAC @VISPT3 ; get old dlxa or dlya again + AND [30000'] ; get dlxa or dlya opcode bit + IOR TEM2 ; or in position + DAC @VISPT4 ; store it back on top of old dlxa or dlya + JMP @UPDTSUB ; return +; +; update our explosion routine +; +UPDTBIG:LWC 8. ; eight pieces to update + DAC CNT ; set counter + LAC [BIGX1INC-1] ; set pointer to update list + DAC VISPT + LAC [BIGX1-1] ; set pointers to display list + DAC VISPT2 + DAC VISPT3 + DAC VISPT4 +UPDTLOOP:JMS UPDTSUB ; update x + JMS UPDTSUB ; update y + JMS BUMPPTS ; update pointers + ISZ CNT ; have i done all 8 bits? + JMP UPDTLOOP ; no, do next one +; yes, fall through +; opponents explosion routine +; +CHKOPP: LAC [THING-2] ; check explosion timers + DAC PTR + LAC [IM1-2] + DAC PTR2 + LWC 9. + DAC CNT2 +OPPBUMP:LAC PTR + ADD [6.] + DAC PTR + LAC PTR2 + ADD [11.] + DAC PTR2 + SUB [9.] + DAC PTR3 + ISZ CNT2 + JMP OPPLOOP + JMP UPDATE + +OPPLOOP:LAC @PTR2 ; see if there is an explosion on this player + ASN + JMP OPPBUMP + ISZ @PTR2 ; yes, but has it run out? + JMP OPPBUMP + CLA + DAC @PTR3 ; yes, so indicate player unactive + LAC [DNOP] + DAC @PTR ; turn his explosion off + JMP OPPBUMP +; +; keep updateing random explosion +; +UPDATE: JMS RANDOM ; update explosion (get random number) + AND [77'] + DAC TEM1 + IOR [INC E,B00] + DAC INC1 + AND [77'] + SAL 3 + SAL 3 + SAL 2 + DAC TEM2 + ADD TEM1 + XOR [INC 344,344] + DAC INC2 + LAC TEM2 + IOR [INC B00,100'] + DAC INC3 + JMS RANDOM + AND [77'] + DAC TEM1 + SAL 3 + SAL 3 + SAL 2 + IOR TEM1 + IOR [140300'] + DAC INC4 + XOR [22044'] + DAC INC5 + DAC INC6 + ; falls through to bullet checking routine + +; +; check for bullet fired and if it hits its mark +; +CHKBULL:LAC [THING+3] + DAC PTR2 + IAC + DAC PTR3 + LAC [IM1+5] + DAC PTR + SUB [5] + DAC SEEPT + LWC 8. ; 8 imlacs to check + DAC CNT2 +DISP1: LAC @PTR + ASZ + JMP DISP2 +DISPNO: LAW 11. + ADD PTR + DAC PTR + SUB [5] + DAC SEEPT + LAW 6 + ADD PTR2 + DAC PTR2 + IAC + DAC PTR3 + ISZ CNT2 + JMP DISP1 +; +; now check for repting keys +; + LAC REPTCNT ; rept on? + ASN + JMP CHKKS ; no, but check for keyset repeat + ISZ REPTCNT + JMP CHKKS + CLA + KRB + SAM KEY + JMP CHKKS + SAM MOVE ; only repeat : move forwards? + JMP .+2 + JMP .+3 + SAM BACKUP ; move backwards? + JMP CHKKS + LWC 3. + DAC REPTCNT + JMP REPT ; do key again + +REPTCNT:0 + +CHKKS: LAC KSCNT ; keyset rept on? + ASN + JMP @DISP ; no, so return + ISZ KSCNT + JMP @DISP + CLA + MSW + SAM KEYSET ; is it the same?? + JMP @DISP + SAM [3433'] ; move forwards? + JMP .+2 + JMP .+3 + SAM [3436'] ; move backwards? + JMP @DISP + LWC 3. + DAC KSCNT + JMP KSREPT +; +; if there is still a player visible then kill it +; +DISP2: ISZ @PTR ; is it totally fired yet? + JMP DISPNO + LAC @SEEPT ; is he still alive + ASM + JMP DISPNO + ISZ PTR + LAC @PTR ; get our old direction + AND [3] + DAC @[SAVEDIR] + ISZ PTR + LAC @PTR ; get our old x + DAC @[SAVEDX] + ISZ PTR + LAC @PTR ; get our old y + DAC @[SAVEDY] + LAC PTR ; reset pointer + SUB [3] + DAC PTR + SUB [5] + DAC PTR4 ; set up pointer for see routine + LAW 9. + ADD CNT2 + DAC KILL + DAC IID + JMS @[SEE] ; see if player hasn't moved out of the way + JMP DISPNO ; he made it in time + COA ; no, so shoot him down + DAC @PTR4 ; indicate that he is now dying + LAW 3 ; send player killed message + JMS SEND1 + LAC MYBIT ; send my id + JMS SEND1 + LAC KILL ; send id of player killed + JMS SEND1 + LAC [DNOP] + DAC @PTR2 ; turn off eyes + LAC JMSEXP ; put in explosion in place of id + DAC @PTR3 + LAC PTR4 ; point to explosion count + ADD [9.] + DAC PTR4 + LWC 60. ; set explosion to last 1 1/2 sec. + DAC @PTR4 + LAC MYBIT ; bump our score + JMS UPSCORE + JMP DISPNO + +; +; send a word to the 10 +; +SEND1: 0 + DAC TEM1 ; save character + JMS REFR ; keep display up + TSF ; wait for output flag + JMP .-2 ; not ready yet + LAC TEM1 ; get character back + TPC ; transmit character + LAC TEM1 + JMP @SEND1 ; return +; +; random number generator +; +RANDOM: 0 + LAC RND + ADD MYBIT + RAL 2 + DAC RND + XOR @RND + DAC RND + JMP @RANDOM + +RND: 0 + +; +; update score in info tables and in display list +; enter with id in ac +; +UPSCORE:0 + DAC SAVEID ; save id + LWC 8. ; now turn all ! and  * off + DAC UPCNT + LAC [SCORE+3] + DAC PTSCORE +CLRALL: LAC [DNOP] + DAC @PTSCORE + LAW 5 + ADD PTSCORE + DAC PTSCORE + LAC [DNOP] + DAC @PTSCORE + LAW 9. + ADD PTSCORE + DAC PTSCORE + ISZ UPCNT + JMP CLRALL + LAC SAVEID ; now bump shooting players score + JMS POSITION ; position us to correct table + LAC ITEMP1 ; bump pointer to count + ADD [4] + DAC ITEMP1 + ISZ @ITEMP1 ; bump score by one + NOP + LAC SAVEID ; point to shooting players score in display + JMS POINTSC + JMS SCOREIT + LAW 41' ; insert exclamation mark + JMS GETCHR + DAC @PTSCORE + LAC KILL ; now do shot player shot count + JMS POSITION + ADD [10.] + DAC ITEMP1 + ISZ @ITEMP1 ; bump it also + NOP + LAC KILL ; next update the shot count in display + JMS POINTSC + ADD [5] + DAC PTSCORE + JMS SCOREIT + LAW 52' ; insert asteric + JMS GETCHR + DAC @PTSCORE + BEL ; ring bell indicating player shot + JMP @UPSCORE ; return + +POINTSC:0 + CIA + DAC UPCNT + LAC [SCORE-14.] ; point to display list to update score + ADD [14.] + ISZ UPCNT + JMP .-2 + DAC PTSCORE + JMP @POINTSC +; +; score generator subroutine +; enter with itemp1 -> score to be converted +; ptscore -> 3 words where djmses are to be placed +; leave with ptscore -> word 4 (one past the 3 djmses) +; +SCOREIT:0 + CLA + DAC HUNDR + DAC TENS + DAC ONES + LAC @ITEMP1 ; get current score + SUB [1000.] ; make it mod 1000 + ASM + JMP .-2 + ADD [1000.] + DAC @ITEMP1 ; store it back for posterity + SUB [100.] + ASP + JMP DOTENS + ISZ HUNDR + JMP .-4 + +DOTENS: ADD [100.] + SUB [10.] + ASP + JMP DOONES + ISZ TENS + JMP .-4 + +DOONES: ADD [10.] + DAC ONES + LAC HUNDR + ASN + JMP ZROSUP + JMS DODIGIT + LAC TENS +DTENS: JMS DODIGIT + LAC ONES + JMS DODIGIT + JMP @SCOREIT +ZROSUP: LWC 20' + JMS DODIGIT + LAC TENS + ASN + LWC 20' + JMP DTENS + +DODIGIT:0 + ADD [60'-40'] + ADD @[24'] + DAC UPCNT + LAC @UPCNT +DACIT: DAC @PTSCORE + ISZ PTSCORE + JMP @DODIGIT + +SAVEID: 0 +PTSCORE:0 +UPCNT: 0 +ONES: 0 +TENS: 0 +HUNDR: 0 + +; +; build a long vector instruction +; +LV: 0 + LAC XDELTA + AND [40000'] + DAC TEM3 + LAC XDELTA + ASP + CIA + DAC XDELTA + LAC YDELTA + AND [20000'] + IOR TEM3 + DAC TEM3 + LAC YDELTA + ASP + CIA + DAC YDELTA + SUB XDELTA + ASM + JMP LV1 + AND [7777'] + IOR [40000'] + DAC @DPTR + LAC XDELTA + IOR BEAMBIT + DAC @DPTR + LAC YDELTA + JMP LV2 + +LV1: CIA + AND [7777'] + IOR [40000'] + DAC @DPTR + LAC YDELTA + IOR BEAMBIT + DAC @DPTR + LAC XDELTA + IOR [10000'] +LV2: IOR TEM3 + DAC @DPTR + JMP @LV + +; +; generate new display +; send i moved message to 10 +; set up possible visible opponents +; +PRINT: 0 + LAC @DSTAT ; check status of player + ASZ ; is he not playing? + JMP INGAME ; no + LAW 116' ; yes, display a "n" then + JMP SETST + +HEACT: LAC [DJMS D040,] ; if he is active then don't display anything + JMP SETST2 + +INGAME: ASP ; is he dying? + JMP HEACT ; no, then he is active! + LAW 104' ; yes, then display a "d" for dead +SETST: JMS GETCHR ; get the character +SETST2: DAC @[DEAD] ; put it in display + LAC @DIR ; first do direction letter + AND [3] + ADD [DIRLET] + DAC TEM1 + LAC @TEM1 + JMS GETCHR + DAC @[LETTER] + LAC TOPSW ; see if top or inside view + ASN + JMP INSIDE +TOPV: LAC [DLIST-1] ;write over maze display list + DAC DPTR + LAC [DLYA 1600',] + DAC @DPTR + LAC [DJMS DNL3,] + DAC @DPTR + LWC 32. + DAC CNT + LAC [MAZE-1] + DAC PTR + LAC @DY + SAL 3 + SAL 1 + ADD @DX + IAC + CIA + DAC PTR4 +NXTW: LWC 16. + DAC CNT2 + LAC [100000'] + DAC BIT + ISZ PTR +NXTB: ISZ PTR4 ; have we reached our location? + JMP .+2 + JMP ME + LAC @PTR ; see is square open or closed + AND BIT + ASZ + JMP ON + LAC [DJMS SPMAZE,] + JMP ON+1 + +ME: LAC @DIR ; figure out which arrow to use + AND [3] + ADD [ARROWS] + DAC PTR3 + LAC @PTR3 + JMP ON+1 + +ON: LAC [DJMS CHARMZE,] + DAC @DPTR + CLL + LAC BIT + RAR 1 + DAC BIT + ISZ CNT2 ; this line done? + JMP NXTB + LAC [DJMS DNL3,] + DAC @DPTR + ISZ CNT + JMP NXTW ; this row done? + CLA ; dhlt at end + DAC @DPTR + JMP @PRINT + +INSIDE: JMS PNTBIT + LAC [WALLS] + DAC WPTR + IAC + DAC WPTR2 + CLA + DAC CNT + LAC [DLIST-1] + DAC DPTR + LAC [20000'] + DAC BEAMBIT + DSN + JMP .-1 + LAC @DIR + AND [1] + ASZ + JMP EW + JMS CREMENT + DAC TEM1 + CIA + AND [20'] + IOR [RAL 1] + DAC NOP2 + XOR [20'] + DAC NOP3 +PRNT1: LAC MPTR + ADD TEM1 + DAC NEXTBIT + LAC @NEXTBIT + AND BIT + DAC NEXTBIT + LAC BIT + CLL +NOP2: NOP + AND @MPTR + JMS LBIT + LAC BIT + CLL +NOP3: NOP + AND @MPTR + JMS RBIT + LAC MPTR + ADD TEM1 + DAC MPTR + LAC NEXTBIT + JMS ENDCHECK + LAC CNT + SAM [31.] ; special check + JMP .+2 + JMP CLOSEOUT + ISZ WPTR + ISZ WPTR2 + ISZ CNT + JMP PRNT1 +EW: JMS CREMENT + DAC TEM1 + AND [20'] + IOR [RAL 1] + DAC NOP4 + DAC NOP5 +PRNT2: LAC BIT + CLL +NOP5: NOP + AND @MPTR + DAC NEXTBIT + LAC MPTR + ADD TEM1 + DAC TEM2 + LAC BIT + AND @TEM2 + JMS LBIT + LAC MPTR + SUB TEM1 + DAC TEM2 + LAC BIT + AND @TEM2 + JMS RBIT + LAC BIT + CLL +NOP4: NOP + DAC BIT + LAC NEXTBIT + JMS ENDCHECK + ISZ WPTR + ISZ WPTR2 + ISZ CNT + JMP PRNT2 + +LBIT: 0 + DAC LASTLEF + ASZ + JMP LB1 + LAC @WPTR ; hallway + CIA + ADD WALLS + IOR [10000'] + DAC @DPTR + LAC @WPTR + ADD WALLS + IOR [20000'] + DAC @DPTR + LAC [DJMS WAIT,] + DAC @DPTR + LAC CNT + ASN + JMP LB2 + CAL + DAC XDELTA + LAC @WPTR + SAL 1 + CIA + DAC YDELTA + JMS LV +LB2: LAC @WPTR2 + CIA + ADD WALLS + IOR [20000'] + DAC @DPTR + LAC [DJMS WAIT,] + DAC @DPTR + CAL + DAC YDELTA + LAC @WPTR + SUB @WPTR2 + DAC XDELTA + JMS LV + JMS FIX + CAL + DAC XDELTA + LAC @WPTR2 + SAL 1 + DAC YDELTA + JMS LV + LAC [20000'] + DAC BEAMBIT + CAL + DAC YDELTA + LAC @WPTR2 + SUB @WPTR + DAC XDELTA + JMS LV + JMP @LBIT + +LB1: LAC @WPTR2 ; wall + CIA + ADD WALLS + IOR [10000'] + DAC @DPTR + LAC @WPTR2 + ADD WALLS + IOR [20000'] + DAC @DPTR + LAC [DJMS WAIT,] + DAC @DPTR + LAC @WPTR + SUB @WPTR2 + DAC YDELTA + CIA + DAC XDELTA + JMS LV + LAC @WPTR + CIA + ADD WALLS + IOR [10000'] + DAC @DPTR + XOR [30000'] + DAC @DPTR + LAC [DJMS WAIT,] + DAC @DPTR + LAC @WPTR + SUB @WPTR2 + DAC XDELTA + DAC YDELTA + JMS LV + JMP @LBIT + +RBIT: 0 + DAC LASTRIG + ASZ + JMP RB1 + LAC @WPTR ; hallway + ADD WALLS + IOR [10000'] + DAC @DPTR + XOR [30000'] + DAC @DPTR + LAC [DJMS WAIT,] + DAC @DPTR + LAC CNT + ASN + JMP RB2 + CAL + DAC XDELTA + LAC @WPTR + SAL 1 + CIA + DAC YDELTA + JMS LV +RB2: LAC @WPTR2 + CIA + ADD WALLS + IOR [20000'] + DAC @DPTR + LAC [DJMS WAIT,] + DAC @DPTR + CAL + DAC YDELTA + LAC @WPTR2 + SUB @WPTR + DAC XDELTA + JMS LV + JMS FIX + CAL + DAC XDELTA + LAC @WPTR2 + SAL 1 + DAC YDELTA + JMS LV + LAC [20000'] + DAC BEAMBIT + CAL + DAC YDELTA + LAC @WPTR + SUB @WPTR2 + DAC XDELTA + JMS LV + JMP @RBIT + +RB1: LAC @WPTR2 ; wall + ADD WALLS + IOR [10000'] + DAC @DPTR + XOR [30000'] + DAC @DPTR + LAC [DJMS WAIT,] + DAC @DPTR + LAC @WPTR + SUB @WPTR2 + DAC XDELTA + DAC YDELTA + JMS LV + LAC @WPTR2 + ADD WALLS + IOR [10000'] + DAC @DPTR + LAC @WPTR2 + CIA + ADD WALLS + IOR [20000'] + DAC @DPTR + LAC [DJMS WAIT,] + DAC @DPTR + LAC @WPTR + SUB @WPTR2 + DAC XDELTA + CIA + DAC YDELTA + JMS LV + JMP @RBIT + +FIX: 0 + CLL + LAC NEXTBIT + ASN + STL + CLA + RAR 3 + DAC BEAMBIT + JMP @FIX + +ENDCHECK:0 + ASN + JMP @ENDCHECK +CLOSEOUT:LAC CNT ; set length of hallway + DAC HALLNGTH + LAC @WPTR2 + ADD WALLS + IOR [20000'] + DAC @DPTR + XOR [30000'] + DAC @DPTR + LAC [DJMS WAIT,] + DAC @DPTR + CAL + DAC YDELTA + LAC @WPTR2 + SAL 1 + DAC ETEM + CIA + DAC XDELTA + JMS LV + LAC LASTLEF + ASZ + LAC [20000'] + DAC BEAMBIT + CAL + DAC XDELTA + LAC ETEM + CIA + DAC YDELTA + JMS LV + LAC [20000'] + DAC BEAMBIT + CAL + DAC YDELTA + LAC ETEM + DAC XDELTA + JMS LV + LAC LASTRIG + ASN + JMP EN1 + CAL + DAC XDELTA + LAC ETEM + DAC YDELTA + JMS LV +EN1: CAL + DAC @DPTR ; insert the dhlt + JMS VISIBLE ; now check for visible opponents + JMP @PRINT + +; +; check for visible opponents +; +VISIBLE:0 + LWC 9. ; 8 imlacs to do + DAC CNT2 + LAC [DSPTCH-1] ; set pointer to imlac info tables + DAC VISPT + LAC [THING-1] ; set up pointer to dlya's + DAC VISPT2 + IAC ; point to dsts's + DAC VISPT3 + ADD [2] ; point to djms's eyes + DAC VISPT4 + IAC ; point to djms's body (name) + DAC VISPT5 +VISLOOP:ISZ CNT2 ; have we checked all 8? + JMP .+2 ; no + JMP @VISIBLE ; yes, return + LAC @VISPT ; get address of imlac's info table + DAC SEEPT + DAC PTR4 + LAC @SEEPT ; may change it on us, so get status + ASZ ; is this imlac playing? + JMP PLAYING ; yes + JMP .+3 +BLOWING:LAC JMSEXP + JMP .+2 +NOSEE: LAC [DNOP] ; no, so make him invisble or exploding + ISZ VISPT2 ; don't change y + ISZ VISPT3 ; don't change dsts + DAC @VISPT5 ; set to invisible or exploding + LAC [DNOP] ; no eyes wanted + DAC @VISPT4 +BUMP: JMS BUMPPTS ; update pointers to next imlac + JMP VISLOOP ; now do next imlac +; +; active player +; +PLAYING:LAW 9. ; set id + ADD CNT2 + DAC IID + JMS SEEUS ; see if it can be seen + JMP NOSEE ; can't be seen + LAC @PTR4 ; could he be blowing up? + ASP + JMP HEVIS ; he is visible + JMP BLOWING ; he is blowing up + +SEEUS: 0 + LAC @DIR + AND [3] + DAC @[SAVEDIR] + LAC @DX + DAC @[SAVEDX] + LAC @DY + DAC @[SAVEDY] + JMS @[SEE] + JMP @SEEUS + ISZ SEEUS + JMP @SEEUS + +SEEPT: 0 +FTEMP: 0 + +; +; visible opponnent! +; +FIGX: 0 + LAC @[DISTAN] ; now i know i see him + ADD [WALLS] ; get currect position for name + DAC FTEMP + LAC @FTEMP + CIA + ADD WALLS + IOR [20000'] ; make it a dlya + JMP @FIGX +HEVIS: JMS FIGX ; figure the new dlxa + DAC @VISPT2 ; stick it in + LAC @[DISTAN] ; get distance to opponent + SAR 3 ; scale it to 2 significant bits + XOR [3] ; complement meanning + IOR [DSTS 0] ; make it a dsts instruction + DAC @VISPT3 ; stick it in display + JMS FIGEYES ; figure out whether or not eyes should be displayed + DAC @VISPT4 + LAC IID ; now see which opponent we can see + ADD [TNUM-1] ; get appropriate name + DAC TEM2 + LAC @TEM2 + DAC @VISPT5 ; stick appropriate djmp to name in display list + JMP BUMP ; now do next opponent + +FIGEYES:0 + LAC @DIR ; see if we are facing each other + AND [3] + ADD [4] + SUB @[IDIR] + AND [3] + ADD [EYTAB] + DAC FTEMP + LAC @FTEMP + JMP @FIGEYES +; +; shift to the left 13 subroutine +; +SAR13: 0 + SAR 3 + SAR 3 + SAR 3 + SAR 3 + SAR 1 + ASN + LAW 1 + JMP @SAR13 +; +; blow us up and start again +; +ENDER: CLA ; return to inside display + DAC TOPSW + LAC [AD2] ; set blow up display as current display + DAC WHICHD + LAC [BIGX1INC-1] ; set pointer to increment table + DAC VISPT + LWC 4. ; 8 pieces to do but we will set up 2 at a time + DAC CNT +BLOWLOOP:JMS RANDOM ; get random number + JMS SAR13 ; scale it to 2 +- sig bits + DAC TEM1 ; save for next bit + DAC @VISPT ; store delta in first x + JMS RANDOM ; get another random number + JMS SAR13 ; scale it too + DAC TEM2 ; also save it + DAC @VISPT ; store delta in first y + LAC TEM1 ; get back first delta x + CIA ; we want to balance explosion so + DAC @VISPT ; make next bit go opposite direction + LAC TEM2 ; store second y also in opposite direction + CIA + DAC @VISPT + ISZ CNT ; are we done with setting up deltas + JMP BLOWLOOP ; no, do next 2 + LAC [BIGX1-1] ; now reset display list dlxas and dlyas + DAC TEM1 + LWC 8. ; eight bits to do + DAC CNT +CLRLOOP:JMS CLRSUB ; reset the dlxa + JMS CLRSUB ; reset the dlya + LAC TEM1 ; update pointer to next bit of explosion + ADD [5] + DAC TEM1 + ISZ CNT ; did we do all eight bits? + JMP CLRLOOP ; no, do the rest + JMP RETN ; wait explosion out + +CLRSUB: 0 + ISZ TEM1 ; position pointer + LAC @TEM1 ; get dlxa or dlya + AND [30000'] ; get opcode bits + IOR [1000'] ; position to center of screen + DAC @TEM1 ; stuff it back + JMP @CLRSUB ; return + +; +; tty input handler +; +CHARIN: 0 + RSF ; tty input? + JMP EXIT ; no, so ignore interupt + CLA + RRC ; get character + AND [177'] ; mask to 7 characters + DAC INCHAR ; save it +; +; check to see if we are waiting for characters +; + LAC ICNT + ASN + JMP SETUP ; no so interpret character we got + LAC INCHAR ; yes, so stuff character in info table + DAC @17' + ISZ ICNT ; was that all we wanted? + JMP EXIT ; no, wait for more + JMP @IDSPTCH ; yes, go to routine now + +SETUP: LAC [ININFO-1] ; set up input buffer + DAC 17` +; +; check for imlac wants out message +; if he does then do the following: +; 1) indicate imlac non-active in info table +; 2) dnop his score, body, eyes and name +; +CHK1: LAC INCHAR ; get character read back + SAM [1] ; is it type 1? + JMP CHK2 ; no, check next type + LWC 1 ; wait for one more word [id] + DAC ICNT + LAC [DTYP1] ; set up dispatch address +SETOUT: DAC IDSPTCH + JMP EXIT ; wait for characters to come in + +DTYP1: JMS TESTID ; get id of imlac that wants out +GONER: ASN + JMS ERROR ; error if id = 0 + JMS POSITION ; get position into info table + DAC 17' + LWC 10. + DAC ICNT2 ; clear info entry + CLA + DAC @ITEMP1 ; clear status + DAC @17' ; clear the rest + ISZ ICNT2 + JMP .-2 + JMS GETCNT ; now clear display list score + LAC [SCORE-15.] + ADD [14.] + ISZ ICNT2 + JMP .-2 + DAC 17' + LAC [DNOP] ; dnop all digits + DAC @17' + DAC @17' + DAC @17' + DAC @17' + ISZ 17' + DAC @17' + DAC @17' + DAC @17' + DAC @17' + JMS GETCNT ; now clear displayed name + LAC [IML1-9.] + ADD [8.] + ISZ ICNT2 + JMP .-2 + DAC 17' + LAC [DJMS D040,] ; get space + DAC @17' + DAC @17' + DAC @17' + DAC @17' + DAC @17' + DAC @17' + DAC @17' + JMS GETCNT ; finally make him invisible + LAC [THING-4] + ADD [6] + ISZ ICNT2 + JMP .-2 + DAC 17' + LAC [DNOP] + DAC @17' ; clear eyes + DAC @17' ; clear body (name) + LAC ININFO ; see if it is my real it that is leaving + SAM MYREAL ; if so then exit program, return to ssv + JMP CHKNR +; +; exit routine +; send player wants out to 10 +; then return to ssv +; + LAW 1 ; send i want out code + JMS SEND1 + LAC MYREAL ; send my id + JMS SEND1 + LAC [17776'] ; restore ssv's buffer to full buffer + DAC @[25'] +LEAVE: IOF ; turn off interupts + JMP @.+1 ; now exit to ssv + 101' ; address of where to exit to + +CHKNR: SAM MYBIT ; see if it is the guy we are sim. + JMP EXIT ; if not then we are done + LAW 1 ; sent leaving message to 10 for him + JMS SEND1 + LAC MYBIT + JMS SEND1 + LAC MYREAL ; return to our real id + JMS GETD + JMS PRINT ; rebuild display + JMP EXIT +; +; check for moved to new location message +; if it is then do the folowing: +; 1) indicate player active in info table +; 2) update dir, x, and y in info table +; 3) check visibility and set it correctly +; +CHK2: +IFN FAST,[ + SUB [20'] ; no chance of move if <20 + ASP ; skip if 0 or + + JMP CHK23 ; negative, not a new protocol move. + SUB [20'] ; a move if 17< x <40 + ASP + JMP CHK22 ;ah, if 20=< and <40, definitely new-ptcl move. + SUB [100'] ; a move if ge 140 + ASP + JMP INSRTCH ; 40=< and <140, a char. +CHK22: LAC INCHAR + JMP @[CHKI20] ;new ptcl move. go hack. +CHK23: +] + LAC INCHAR + SAM [2] ; is it type 2? + JMP CHK3 ; no but see if it is type 3 + LWC 4 ; 4 more words to come + DAC ICNT + LAC [DTYP2] ; set up dispatch location + JMP SETOUT + +DTYP2: JMS TESTID + DAC IID + JMS POSITION ; indicate player is active in info tables + LAC @ITEMP1 ; get current status + ASZ + ASP ; ignore message if he is exploding + JMP .+2 + JMP EXIT + STA + DAC @ITEMP1 ; say player is active + ISZ ITEMP1 + LAC ININFO+1 ; save new direction + IOR [100'] + AND [103'] + SAM ININFO+1 + JMS ERROR ; direction greater than 3 + AND [3] ; or not in 10n format + DAC @ITEMP1 + ISZ ITEMP1 + LAC ININFO+2 ; save new x location + JMS TESTLOC ; make sure it is legal + DAC @ITEMP1 + ISZ ITEMP1 + LAC ININFO+3 ; save new y location + JMS TESTLOC + DAC @ITEMP1 + + ;re-entry pt from higher 2k + +CHK25: JMS GETCNT ; set up pointer to his display list slot + LAC [THING-7] + ADD [6] + ISZ ICNT2 + JMP .-2 + DAC 17' + JMS SEEUS ; can he be seen? + JMP NOTVIS ; no + JMS FIGX ; yes, now figure dlxa + DAC @17' ; store it away + LAC @[DISTAN] ; now figure dsts + SAR 3 + XOR [3] + IOR [DSTS 0] + DAC @17' + ISZ 17' ; skip over wait + JMS FIGEYES ; next do eyes + DAC @17' ; store them + LAC IID ; last is name + ADD [TNUM-1] + DAC ITEMP1 + LAC @ITEMP1 + DAC @17' + JMP MCHK ; see if id is ours +NOTVIS: LAC [DNOP] ; if not visible then make it so + ISZ 17' ; skip dlxa + ISZ 17' ; skip dsts + ISZ 17' ; skip over wait + DAC @17' ; clear eyes + DAC @17' ; clear body (name) +MCHK: LAC IID ; see if it is us + SAM MYBIT + JMP EXIT ; no, done + JMS PRINT ; if so then update display + JMP EXIT ; done + +; +; check for player shot message +; if so then do the following: +; 1) indicate in table that he is blowing up +; 2) bump shooting players score +; 3) generate explosion if visible +; 4) if this imlac got hit then: +; a) set life flag to shot +; b) put name of who shot us in whodidit +; +CHK3: SAM [3] ; type 3? + JMP CHK4 ; no, but try type 4 + LWC 2 ; two words to wait for + DAC ICNT + LAC [DTYP3] ; set dispatch address + JMP SETOUT + +DTYP3: JMS TESTID + LAC ININFO+1 + ASN + JMS ERROR ; id zero + SUB [9.] + ASP + JMP .+3 + ADD [9.] + JMS ERROR ; id greater than 8 + ADD [9.] + DAC KILL ; save dying id for upscore + JMS POSITION ; indicate player is dying + COA + DAC @ITEMP1 + LAC ITEMP1 + ADD [5] + DAC ITEMP1 + ADD [4] + DAC ITEMP2 + CAL ;turn off any firing we have on him + DAC @ITEMP1 + LWC 60. ; set explosion to last 1 1/2 sec + DAC @ITEMP2 + LAC ININFO+1 ; see if i was shot + SAM MYBIT + JMP NOTME + LAC ININFO + ADD [TNUM-1] ; say who did it in whodidit + DAC ITEMP2 + LAC @ITEMP2 + DAC @[WHODIDIT] + LAC ININFO ; wait longer in big + DAC BIGEXP ; explosion if we are playing ourselves + SAM MYREAL ; so our new starting loc will be in effect + JMP .+3 + LWC 120. + JMP .+2 + LWC 80. + XAM BIGEXP + JMS UPSCORE ; update scores + JMP ENDER + +NOTME: LAC ININFO+1 ; now point into display list + CIA + DAC ICNT2 + LAC [THING-2] + ADD [6] + ISZ ICNT2 + JMP .-2 + DAC ITEMP2 + SUB [1] ; set pointer to eyes + DAC ITEMP1 + LAC @ITEMP2 ; is he currently visible? + SAM [DNOP] + JMP VIS1 ; yes + JMP NOEXPLO ; no + +VIS1: LAC [DNOP] + DAC @ITEMP1 ; yes, clear eyes + LAC JMSEXP ; stick in jms to explosion + DAC @ITEMP2 +NOEXPLO:LAC ININFO ; bump scores + JMS UPSCORE ; and update scores in display list + JMP EXIT + +; +; check to see if new name specified +; if so then do the following: +; 1) fill in approprate name display subroutine +; 2) if mybit = 0 then assign the id to mybit +; +CHK4: SAM [4] ; type 4? + JMP ERASER ; no, keep looking + LWC 11. ; 11. more characters to wait for + DAC ICNT + LAC [DTYP4] ; set dispatch address + JMP SETOUT + +DTYP4: JMS TESTID + LAC MYBIT ; see if mybit is zero + ASZ + JMP GOTMINE + LAC ININFO ; yes, so set our id + DAC MYREAL + JMS GETD +IFE FAST, DAC @[ORIG] ; indicate origional id in display +GOTMINE:LAC [ININFO] ; set up pointers for transfer + DAC 16' + JMS GETCNT + LAC [IML1-8.] ; remember 1st char is offset char + ADD [8.] + ISZ ICNT2 + JMP .-2 + DAC 17' + DAC ITEMP2 + CLA + DAC SPACES + LWC 6 ; move 6 character name + DAC ICNT2 +CONVNXT:LAC @16' + SUB [140'] ; translate to lower case + ASM + SUB [40'] + ADD [140'] + SAM [40'] ; space? + JMP .+2 ; no + ISZ SPACES ; yes count them for offset char + JMS GETCHR ; convert to djms + DAC @17' + ISZ ICNT2 + JMP CONVNXT + LAC SPACES ; now fix offset character + ADD [CENTER] + DAC ITEMP1 + LAC @ITEMP1 + DAC @ITEMP2 + LAC ININFO ; now store scores + JMS POSITION + ADD [4] + DAC ITEMP1 + JMS FIXSCO ; do # of opponents shot + LAC ININFO + JMS POINTSC + JMS SCOREIT + LAC ITEMP1 + ADD [6] + DAC ITEMP1 + JMS FIXSCO ; now do # of times shot + LAC ININFO + JMS POINTSC + ADD [5] + DAC PTSCORE + JMS SCOREIT + JMP EXIT + +FIXSCO: 0 + LAC @16' + AND [77'] + SAL 3 + SAL 3 + DAC ITEMP2 + LAC @16' + AND [77'] + IOR ITEMP2 + DAC @ITEMP1 + JMP @FIXSCO + +SPACES: 0 + +; +; set up our id +; +; enter with id in ac +; +GETD: 0 + DAC MYBIT + SUB [1] + DAC MYBIT1 ; store normalized 0-7 id. + ADD [DSPTCH] + DAC ITEMP1 + LAC @ITEMP1 ; set up dstat, dx, dy, and dir ptrs + DAC DSTAT + IAC + DAC DIR + IAC + DAC DX + IAC + DAC DY +IFE FAST,[ + LAC MYBIT ; now get our id in character + IOR [60'] + JMS GETCHR + DAC @[CURENT] ; say our current id in display +] + JMP @GETD +; +; +; erase ring buffer? +; +ERASER: SAM [14'] ; type 4? + JMP INSRTCH ; no, just insert into ring buffer + JMS ERASE + JMP EXIT + +ERASE: 0 + LWC 4 ; reset line count + DAC RINGLC + LAC [RINGST] ; reset both pointers + DAC RNGPT + IAC + DAC RNGPT2 + LAC [DJMS D012,] ; replace djmp to curser + DAC @RNGPT + LAC [DJMS CUR,] + DAC @RNGPT2 + LAC [DJMP RINGST,] + DAC @[RING] + DAC @[RINGEND] + JMP @ERASE + +; +; get djms for a character +; +GETCHR: 0 + AND [177'] ; mask to 7 bits + SAM [12'] ; line feed? + JMP .+3 + LAC [DJMS D012,] + JMP STORECH + SAM [10'] ; back space? + JMP .+3 + LAC [DJMS D010,] + JMP STORECH + SAM [15'] ; cr? + JMP .+3 + LAC [DJMS D015,] + JMP STORECH + SUB [40'] ; don't allow anything below 40 + ASP + CLA + ADD [40'] + SUB [140'] ; translate to lower case + ASM + SUB [40'] + ADD [140'-40'] + ADD @[24'] ; convert to djms + DAC ITEMP1 + LAC @ITEMP1 +STORECH:DAC ITEMP1 + JMP @GETCHR +; +; insert character into ring buffer +; +INSRTCH:JMS FORWARD + LAC INCHAR + JMS GETCHR ; get djms for character + SAM [DJMS D012,] + JMP NOTNL ; no + ISZ RINGLC ; yes, but is there room on screen? + JMP NOTNL + JMS ROLL + JMP OK + +NOTNL: LAC RNGPT2 + SAM RNGPT ; have we filled entire buffer? + JMP OK ; no + JMS ROLL ; yes, roll top line off +OK: LAC [DJMP CUR,] + DAC @RNGPT2 + JMS BACK ; back up pointer + LAC ITEMP1 ; get djms again + DAC @RNGPT2 ; stick in on top of old djmp cur + JMS FORWARD ; move pointer back up + LAC INCHAR + SAM [15'] + JMP EXIT ; done + LAW 12' + DAC INCHAR + JMP INSRTCH + +FORWARD:0 ; roll rngpt2 forward one slot + LAC RNGPT2 + IAC + SAM [RINGEND] + JMP .+2 + LAC [RINGST] + DAC RNGPT2 + JMP @FORWARD + +BACK: 0 + STA + ADD RNGPT2 + SAM [RING] + JMP .+2 + LAC [RINGEND-1] + DAC RNGPT2 + JMP @BACK + +ROLL: 0 ; roll ringpt forward one line +LOOK: LAC RNGPT + IAC + SAM [RINGEND] + JMP .+2 + LAC [RINGST] + SAM RNGPT2 + JMP .+4 + JMS ERASE + JMS FORWARD + JMP @ROLL + DAC RNGPT + LAC @RNGPT + SAM [DJMS D012,] + JMP LOOK +MOVED: LAC RNGPT + AND [7777'] + IOR [160000'] + DAC @[RING] + STA + ADD RINGLC + DAC RINGLC + JMP @ROLL + +; +; return from character read +; +EXIT: JMP @CHARIN + +GETCNT: 0 + LAC ININFO ; get id of message originator + CIA ; make it into a count + DAC ICNT2 + JMP @GETCNT + +POSITION:0 + ADD [DSPTCH-1] ; point to correct status indicator + DAC ITEMP1 + LAC @ITEMP1 + DAC ITEMP1 + DAC SEEPT ; also set seept for type 2 command + JMP @POSITION + +TESTID: 0 ; test for valid id in ininfo + LAC ININFO + ASN ; also can't be zero + JMS ERROR ; id zero or same as mybit + SUB [9.] ; can't be > or = to 9. + ASP + JMP TESTOK + LAC ININFO + JMS ERROR ; id greater than 8 +TESTOK: LAC ININFO ; all ok so return with id in ac + JMP @TESTID + +TESTLOC:0 ; test to see if legal location + AND [77'] ; minimum is location 1 + ASN + JMS ERROR ; location zero + SUB [32.] + ASP + JMP .+3 + ADD [32.] + JMS ERROR ; location greater than 31. + ADD [32.] + JMP @TESTLOC +; +; error handling routine +; +ERROR: 0 ; address of where the error was found + DAC ERRAC ; save ac error message + LAC IDSPTCH ; save dispatch address + DAC ERRDSP + LWC 11. + DAC ICNT2 ; now save info area + LAC [ININFO-1] + DAC 17' + LAC [ERRINFO-1] + DAC 16' +SVELOP: LAC @17' + DAC @16' + ISZ ICNT2 + JMP SVELOP + ISZ ERRCNT ; bump the error count + NOP + LAC ERRCNT ; now display it + JMS GETCHR + DAC @[ERRCHAR] + JMP EXIT ; now ignore bad message + +ERRAC: 0 ; saved ac +ERRDSP: 0 ; saved dispatch address +ERRCNT: 60' ; error count + +; +; routines variables +; +INCHAR: 0 ; last character read in +ICNT: 0 ; the number of characters we are waiting for +ICNT2: 0 ; general purpose counter used in routine +ITEMP1: 0 ; temporary locations +ITEMP2: 0 ; another temporary location +IDSPTCH:0 ; dispatching address for command routines +RNGPT: RINGST ; first character of ring buffer pointer +RNGPT2: RINGST+1 ; last character of ring buffer pointer +RINGLC: -4 ; ring buffer line counter +ININFO: 0 ; input information from 10 buffer + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +; +; constants go here at end of this 2k !!!!! any refs to or from +; succeeding 2k must be indirect-address! bleah!!!!!! (klh) +; + + CONSTANTS + +;loc 14000 ;happens about here anyway, just needs precision. + +; +; distances to walls table +; +WALLS: 511. ; distances to walls + 450. + 358. + 281. + 225. + 184. + 155. + 133. + 116. + 103. + 92. + 83. + 75. + 70. + 64. + 60. + 56. + 53. + 50. + 47. + 45. + 43. + 41. + 39. + 37. + 35. + 33. + 31. + 29. + 27. + 25. +; +; error saving of info information area +; +ERRINFO:0 ; holds 2nd character of last bad message + 0 ; holds the rest of the message + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +; +; n direction letter table +; e +; s +; w +; +DIRLET: 116' + 105' + 123' + 127' +; +; you were shot by: message +; +YWSB: 131' + 117' + 125' + 40' + 127' + 105' + 122' + 105' + 40' + 123' + 110' + 117' + 124' + 40' + 102' + 131' + 72' +; +; eyes and arrows table +; +EYTAB: DJMS AWAY + DJMS TOLEFT + DJMS EYES + DJMS TORIGHT +; +; offset for name table +; +CENTER: DJMS OFF6 + DJMS OFF5 + DJMS OFF4 + DJMS OFF3 + DJMS OFF2 + DJMS OFF1 + DNOP +OFF6: INC E,DM30 + INC DM30,100' +OFF5: INC E,DM30 + INC DM20,100' +OFF4: INC E,DM30 + INC DM30,100' +OFF3: INC E,DM30 + INC DM20,100' +OFF2: INC E,DM30 + INC DM30,100' +OFF1: INC E,DM30 + INC DM20,140' +; +; djmses to name labels routines +; +TNUM: DJMS IML1 + DJMS IML2 + DJMS IML3 + DJMS IML4 + DJMS IML5 + DJMS IML6 + DJMS IML7 + DJMS IML8 +; +; big explosion info table +; +BIGX1INC:0 +BIGY1INC:0 +BIGX2INC:0 +BIGY2INC:0 +BIGX3INC:0 +BIGY3INC:0 +BIGX4INC:0 +BIGY4INC:0 +BIGX5INC:0 +BIGY5INC:0 +BIGX6INC:0 +BIGY6INC:0 +BIGX7INC:0 +BIGY7INC:0 +BIGX8INC:0 +BIGY8INC:0 +; +; imlac information tables +; +DSPTCH: IM1 + IM2 + IM3 + IM4 + IM5 + IM6 + IM7 + IM8 + +IM1: 0 ; status word: -1 active, 1 dying, 0 not in game + 0 ; direction + 0 ; x location + 0 ; y location + 0 ; players score + 0 ; bullet counter + 0 ; my direction at time of fire + 0 ; my x location at time of fire + 0 ; my y location at time of fire + 0 ; explosion timer + 0 ; shot dead counter + +IM2: REPEAT 11., 0 +IM3: REPEAT 11., 0 +IM4: REPEAT 11., 0 +IM5: REPEAT 11., 0 +IM6: REPEAT 11., 0 +IM7: REPEAT 11., 0 +IM8: REPEAT 11., 0 + +; +; test to see if player whose id is in iid is visible +; seept should point to status word in info table +; distan will contain distance to opponent on return if visible +; skips if player seen +; +SEE: 0 + CLA + DAC DISTAN + LAC @[SEEPT] ; set up local seept + DAC SEEPT2 + ISZ SEEPT2 ; point to direction + LAC @SEEPT2 + DAC IDIR ; save direction in idir + ISZ SEEPT2 ; point to x location + LAC @SEEPT2 + DAC IX ; save it in ix + ISZ SEEPT2 + LAC @SEEPT2 ; now get y loc + DAC IY + LAC SAVEDIR ; see which way we are pointing + AND [1] + ASZ + JMP WEAST ; west or east +SNORTH: LAC IX ; south or north check his x to my x + SAM SAVEDX ; does it match? + JMP @SEE ; no + LAC IY ; yes, now get the y difference + SUB SAVEDY + ASN ; is he in my square? + JMP @SEE ; yes, then i can't see him + DAC SEEPT2 ; save distance to him + ASP ; see if distance positive + JMP HENORTH ; no, he must be north of me + CIA ; yes, so he is south of me + DAC SEEPT2 ; make distance negative + JMP HESOUTH + +HEEAST: LAW 2 +HENORTH=HEEAST + AND SAVEDIR ; see if i am looking north + ASZ ; if not then i can't see him + JMP @SEE ; i look south so i can't see him + JMP CHKLN ; ok so far, now check length of hall + +HESOUTH:LAW 2 +HEWEST=HESOUTH + AND SAVEDIR ; see if i am looking south + ASN ; if not then i can't see him + JMP @SEE ; i no see him + JMP CHKLN ; so far so good, but check hallway length + +WEAST: LAC IY ; check his y to my y + SAM SAVEDY ; it must match + JMP @SEE ; can't see him + LAC IX ; now get the x difference + SUB SAVEDX + ASN ; is he in my square? + JMP @SEE ; yes, so i can't see him + DAC SEEPT2 ; save the distance to him + ASP ; but see if positive distance + JMP HEWEST ; no, negative so he is west of me + CIA + DAC SEEPT2 + JMP HEEAST ; he is east of me + +CHKLN: LAC SEEPT2 + CIA ; set distance to opponent + DAC DISTAN +CHKLN1: LAW 1 + AND SAVEDIR + ASZ + JMP CHKLN3 + JMS CREM2 + ADD SAVEDY + DAC SAVEDY +CHKLN2: LAC [MAZE] + ADD SAVEDY + DAC MPTR2 + LAC SAVEDX + ASZ + JMP PT1 + LAC [100000'] + JMP PT2 + +PT1: CIA + DAC MCNT + CLL + LAC [100000'] + RAR 1 + ISZ MCNT + JMP .-2 +PT2: DAC BIT2 + LAC @MPTR2 + AND BIT2 ; see if it is an open square + ASZ + JMP @SEE + ISZ SEEPT2 ; are we as far as the opponent? + JMP CHKLN1 ; no + LAC @[IID] ; yes, see if he is me + SAM @[MYBIT] + ISZ SEE ; don't skip if so (can't see me) + JMP @SEE +CHKLN3: JMS CREM2 + CIA + ADD SAVEDX + DAC SAVEDX + JMP CHKLN2 + +CREM2: 0 + LAC SAVEDIR + SAR 1 + AND [1] + ASN + LAC [-1] + JMP @CREM2 + +DISTAN: 0 +SAVEDIR:0 +SAVEDX: 0 +SAVEDY: 0 +SEEPT2: 0 +MCNT: 0 +MPTR2: 0 +IY: 0 ; object id y location +IX: 0 ; object id x location +IDIR: 0 ; object id imlac direction +BIT2: 0 + +; chki20 -- routine to handle new-protocol checking and munching, +; as well as old. +; put here since no room in lower 2k of core. + +IFN FAST,[ + +CHKI20: AND [7] ;get normalized id, no need to test range! + IAC ;make it 1-8. + DAC @[IID] ;store for what wants it. + JMS @[POSITION] ;set up itemp1 and seept pointers into info tabs + LAC @[ITEMP1] + DAC CTEMP1 ;get itemp1 into a var within our 2k. + LAC @CTEMP1 ;get current status + ASZ + ASP ;ignore this msg if he's exploding + JMP .+2 + JMP @[EXIT] + STA + DAC @CTEMP1 ;say player is active + LAC CTEMP1 + IAC + DAC PLRD ;save ptr to direction + IAC + DAC PLRX ;save ptr to x coord + IAC + DAC PLRY ;save ptr to y coord + DAC CTEMP1 + DAC @[ITEMP1] + ;itemp1 is now satisfactorily updated, and + ;indices into position tables done, now do function. + LAC @[INCHAR] + AND [70'] ;only interested in function digit + SAR 3 + ADD [JMP PLRVEC] + DAC PLRJMP + +PLRJMP: 0 + +PLRVEC: JMP BADVEC + JMP BADVEC + JMP PLRTRN ; 2 - right turn + JMP PLLTRN ; 3 - left turn + JMP PLFLIP ; 4 - turn around + JMP PLMOVE ; 5 - move forward + JMP PLBACK ; 6 - move backward +BADVEC: JMS @[ERROR] ; 7 - bad + JMP @[EXIT] + +PLRD: 0 ;pointer to direction +PLRX: 0 ;pointer to x coord +PLRY: 0 ;guess what + +PLRTRN: LAC @PLRD ;get direction + IAC ;right turn + AND [3] + DAC @PLRD + JMP PLRDON + +PLLTRN: LAC @PLRD + SUB [1] ;left turn + AND [3] + DAC @PLRD + JMP PLRDON + +PLFLIP: LAC @PLRD + ADD [2] ;turn right twice to turn-around + AND [3] + DAC @PLRD + JMP PLRDON + +PLBACK: LAC @PLRD ;backward-- reverse direction then move. + ADD [2] + JMP .+2 + +PLMOVE: LAC @PLRD + AND [3] + ADD [JMP PLDVEC] + DAC PLMJMP + +PLMJMP: 0 + +PLDVEC: JMP PLMNOR ;north + JMP PLMEA ;east + JMP PLMSOU ;south + JMP PLMWES ;west + +PLMNOR: LAC @PLRY + SUB [1] ;decrement y coord for north moving + JMS @[TESTLOC] + DAC @PLRY + JMP PLRDON + +PLMEA: LAC @PLRX + IAC ;increment x coord for east + JMS @[TESTLOC] + DAC @PLRX + JMP PLRDON + +PLMSOU: LAC @PLRY + IAC ; incrment y coord for south + JMS @[TESTLOC] + DAC @PLRY + JMP PLRDON + +PLMWES: LAC @PLRX + SUB [1] ; decrement x coord for west + JMS @[TESTLOC] + DAC @PLRX + JMP PLRDON + +PLRDON: LAC @[IID] ;get player id again + DAC @[ININFO] ;and fake out stupid routine + JMP @[CHK25] ;done with new ptcl handling. + +CTEMP1: 0 ;pointer substi. for itemp1 +] ;end of ifn fast + + ; high 2k constants + CONSTANTS + +; +; name subroutines +; 5 character name +; +IML1: DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DRJM ; return jump +IML2: DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DRJM +IML3: DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DRJM +IML4: DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DRJM +IML5: DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DRJM +IML6: DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DRJM +IML7: DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DRJM +IML8: DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DJMS D040 + DRJM + +; +; gsv character subroutines +; +CUR: INC E,D0M1 + INC D0M3,B30 + INC B30,B30 + INC D03,D20 + INC D01,T + DJMP DLIST +WAIT: INC E,P ; 40 microsecond wait + INC P,P + INC P,P + INC P,P + INC P,P + INC P,P + INC P,P + INC P,P + INC P,P + INC P,140 +D010: INC E,DM30 + INC DM30,DM30 + INC DM20,140' +D012: INC E,D0M3 ; end_of_line + INC D0M3,D0M3 + INC D0M3,D0M3 + INC D0M3,D0M3 + INC X,X +D015: DLXA 200 + DJMS WAIT + DRJM +DNL3: DLXA 540 + DJMP DNL+1 +DNL2: DLXA 1710 + DJMP .+2 +DNL: DLXA 10 + DJMS WAIT + DJMP D012 +D040: INC E,D30 ; space + INC D30,D30 + INC D20,X +EYES: INC E,D03 ; eyes + INC D03,D03 + INC D03,DM33 + INC B00,B00 + INC D30,D30 + INC B00,B00 + INC DM30,D00 + INC D0M3,D0M3 + INC D0M3,D0M3 + INC D0M3,140' +CMZE: INC E,B03 + INC B03,B03 + INC B03,B03 + INC B03,B02 + INC B30,B30 + INC B30,B10 + INC B0M3,B0M3 + INC B0M3,B0M3 + INC B0M3,B0M3 + INC B0M2,BM30 + INC BM30,BM30 + INC BM10,B12 + INC B12,B12 + INC B12,B12 + INC B12,B12 + INC B12,B12 + INC B12,DM30 + INC DM30,DM30 + INC DM10,B1M2 + INC B1M2,B1M2 + INC B1M2,B1M2 + INC B1M2,B1M2 + INC B1M2,B1M2 + INC B1M2,D10 + INC 140',140' +CHARMZE:DJMS CMZE + DJMP CMZE +SPMAZE: INC E,D30 + INC D30,D30 + INC D30,D30 + INC D30,D30 + INC D10,140' +ARROWS: DJMS UPARR + DJMS RIGHTARR + DJMS DOWNARR + DJMS LEFTARR +RIGHTARR:INC E,D33 + INC D03,D33 + INC B30,B30 + INC B30,B10 + INC BM2M2,B02 + INC B02,B2M2 + INC D3M3,D3M3 + INC D0M3,140' +LEFTARR:INC E,D33 + INC D03,D33 + INC B22,B0M2 + INC B0M2,BM22 + INC B30,B30 + INC B30,B10 + INC D3M3,D3M3 + INC D0M3,140' + +UPARR: INC E,D30 + INC D30,D30 + INC D23,B03 + INC B03,B03 + INC B01,BM2M2 + INC B20,B20 + INC BM22,D00 + INC D3M3,D3M3 + INC D3M3,D2M3 + INC D0M1,140' + +DOWNARR:INC E,D30 + INC D30,D30 + INC D23,B12 + INC BM20,B1M2 + INC B03,B03 + INC B03,B01 + INC D3M3,D3M3 + INC D3M3,D2M3 + INC D0M1,140' + +AWAY: DLV D,0,20. + DLV B,0,15. + DLV B,-2,-5. + DLV B,4.,0 + DLV B,-2.,5. + DLV D,0,-35. + DRJM + +TOLEFT: DLV D,0,20. + DLV B,-15.,0 + DLV B,5.,2 + DLV B,0,-4. + DLV B,-5.,2 + DLV D,15.,-20. + DRJM + +TORIGHT:DLV D,0,20. + DLV B,15.,0 + DLV B,-5.,2. + DLV B,0,-4. + DLV B,5.,2. + DLV D,-15.,-20. + DRJM + +; +; +; big explosion display list +; +AD2: DHVS 2 + DADR ; turn on 8k display addressing + DLXA 500 + DLYA 1200 + DJMS WAIT +; +; you were shot by: +; +MESAGE: DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DJMS DNOP + DLXA 1000 + DLYA 1000 + DJMS WAIT +; +; djms to player who did the killing +; +WHODIDIT:DJMS D040 + DSTS 3 +BIGX1: DLXA 1000 +BIGY1: DLYA 1000 + DJMS WAIT + DNOP + DNOP + DNOP + DJMS EXPLOSIN+2 +BIGX2: DLXA 1000 +BIGY2: DLYA 1000 + DJMS WAIT + DNOP + DNOP + DNOP + DJMS EXPLOSIN+2 +BIGX3: DLXA 1000 +BIGY3: DLYA 1000 + DJMS WAIT + DNOP + DNOP + DNOP + DJMS EXPLOSIN+2 +BIGX4: DLXA 1000 +BIGY4: DLYA 1000 + DJMS WAIT + DNOP + DNOP + DNOP + DJMS EXPLOSIN+2 +BIGX5: DLXA 1000 +BIGY5: DLYA 1000 + DJMS WAIT + DNOP + DNOP + DNOP + DJMS EXPLOSIN+2 +BIGX6: DLXA 1000 +BIGY6: DLYA 1000 + DJMS WAIT + DNOP + DNOP + DNOP + DJMS EXPLOSIN+2 +BIGX7: DLXA 1000 +BIGY7: DLYA 1000 + DJMS WAIT + DNOP + DNOP + DNOP + DJMS EXPLOSIN+2 +BIGX8: DLXA 1000 +BIGY8: DLYA 1000 + DJMS WAIT + DNOP + DNOP + DNOP + DJMS EXPLOSIN+2 + DHLT + +; +; start of main display list +; +AD1: DHVS 1 + DADR ; turn on 8k display addressing + ; (use 0 bit to indicate which 4k) + DLXA 50 + DLYA 1300 + DJMS WAIT + DJMS IML1 + DJMS DNL +SCORE: DNOP ; display names and scores here + DNOP + DNOP + DNOP + DJMS DNL + DNOP + DNOP + DNOP + DNOP + DLXA 50 + DLYA 1100 + DJMS WAIT + DJMS IML2 + DJMS DNL + DNOP + DNOP + DNOP + DNOP + DJMS DNL + DNOP + DNOP + DNOP + DNOP + DLXA 50 + DLYA 700 + DJMS WAIT + DJMS IML3 + DJMS DNL + DNOP + DNOP + DNOP + DNOP + DJMS DNL + DNOP + DNOP + DNOP + DNOP + DLXA 50 + DLYA 500 + DJMS WAIT + DJMS IML4 + DJMS DNL + DNOP + DNOP + DNOP + DNOP + DJMS DNL + DNOP + DNOP + DNOP + DNOP + DLXA 1724 + DLYA 1300 + DJMS WAIT + DJMS IML5 + DJMS DNL2 + DNOP + DNOP + DNOP + DNOP + DJMS DNL2 + DNOP + DNOP + DNOP + DNOP + DLXA 1724 + DLYA 1100 + DJMS WAIT + DJMS IML6 + DJMS DNL2 + DNOP + DNOP + DNOP + DNOP + DJMS DNL2 + DNOP + DNOP + DNOP + DNOP + DLXA 1724 + DLYA 700 + DJMS WAIT + DJMS IML7 + DJMS DNL2 + DNOP + DNOP + DNOP + DNOP + DJMS DNL2 + DNOP + DNOP + DNOP + DNOP + DLXA 1724 + DLYA 500 + DJMS WAIT + DJMS IML8 + DJMS DNL2 + DNOP + DNOP + DNOP + DNOP + DJMS DNL2 + DNOP + DNOP + DNOP + DNOP + DLYA 1720 +; +; status line +; + DLXA 60 + DJMS WAIT +IFE FAST,[ +ORIG: DJMS D040 ; origional id + DJMS D040 +CURENT: DJMS D040 ; current id + DJMS D040 +] +DEAD: DJMS D040 ; status of player + DJMS D040 +ERRCHAR:DJMS D040 ; number of messages in error +; +; +; n, s, e, or w letter +; + DLXA 1000 + DJMS WAIT + DSTS 3 +LETTER: DJMS D040 +; +; this is where the 8 possible players appear +; +; dlxa 1000 +; dlya +; dsts +; djms wait +; djms +; djms +; + DLXA 1000 +THING: DJMS D040 + DJMS D040 + DJMS WAIT + DJMS D040 + DJMS D040 + DLXA 1000 + DJMS D040 + DJMS D040 + DJMS WAIT + DJMS D040 + DJMS D040 + DLXA 1000 + DJMS D040 + DJMS D040 + DJMS WAIT + DJMS D040 + DJMS D040 + DLXA 1000 + DJMS D040 + DJMS D040 + DJMS WAIT + DJMS D040 + DJMS D040 + DLXA 1000 + DJMS D040 + DJMS D040 + DJMS WAIT + DJMS D040 + DJMS D040 + DLXA 1000 + DJMS D040 + DJMS D040 + DJMS WAIT + DJMS D040 + DJMS D040 + DLXA 1000 + DJMS D040 + DJMS D040 + DJMS WAIT + DJMS D040 + DJMS D040 + DLXA 1000 + DJMS D040 + DJMS D040 + DJMS WAIT + DJMS D040 + DJMS D040 +; +; ring buffer +; + DSTS 1 + DLXA 200 + DLYA 130 + DJMS WAIT +RING: DJMP RINGST +RINGST: DJMS D012 + DJMP CUR + + BLOCK 160. + +RINGEND:DJMP RINGST +; +; display list for maze starts here +; +DLIST: DHLT +; +; return to console program after loading +; + END LOADER