>CdX; ------------------------nX; CRASH DIVE! (TM)xX; by Brian MoriartyX; ANALOG Computing #18X; (C)1984 ANALOG ComputingX; ------------------------X;X; MACRO DEFINITIONSX; -----------------X;X; POSITION MACROX; -------------- X; SYNTAX:X; POSITION xpos,yposX;POSITION  3 '3  APOS parametersA"   ,%> 6 POSIT13@J$> T%> ^ POSIThr|X;X; PRINT MACROX; ----------- X; SYNTAX:+X; PRINT X; PRINT    APRINTE parametersA Q>4  %>5  EPRINTX;&X; TEXT MACRO0X; ----------: X; SYNTAX:DX; TEXT <"string">NX;X TEXT b 3 l ATEXT parametersAv =EOLX;X; SYSTEM EQUATESX; ---------------X;X; ZERO-PAGEX; ---------BOOT? ;; OS boot flagPOKMSK;; interrupt maskRTCLOK;; system clockLMARGNR;; left marginRMARGNS;; right margin ROWCRST;; cursor rowCOLCRSU;; cursor column RAMTOPj;; # pages of RAM*$FR0;; floating point register4CIX;; FP index register>INBUFF;; FP pointerHX;RX; PAGES 2-3\X; ---------fVDSLST;; DLI vectorp!SRTIMR+;; key repeat timerzSDMCTL/;; DMA controlSDLSTL0;; D-list addrCOLDSTD;; coldstart flagGPRIORo;; PMG priorityPCOLR0;; player 0 colorPCOLR1;; player 1 colorPCOLR2;; player 2 colorPCOLR3;; player 3 color"COLOR0;; playfield 0 color"COLOR1;; playfield 1 color"COLOR2;; playfield 2 color!COLOR4;; background colorCRSINH;; cursor inhibitCH;; keypress registerICCOMB;; CIO commandICBADRD;; CIO addrICBLENH;; CIO length$ICAUX1J;; AUX byte 1.ICAUX2K;; AUX byte 28X;BX; CTIA/GTIALX; ---------VHPOSP0;; h-pos player 0`HPOSP1;; " " 1jHPOSP2;; " " 2tHPOSP3;; " " 3~SIZEP0;; width player 0SIZEP1 ;; " " 1SIZEP2 ;; " " 2SIZEP3 ;; " " 3"GRAFP0 ;; graphics player 0"GRAFP1;; " " 1"GRAFP2;; " " 2"GRAFP3;; " " 3!COLPF2;; color register 2CONSOL;; console keysX;X; POKEYX; -----#AUDF1;; frequency channel 1 "AUDC1;; vol/dist channel 1AUDCTL;; audio control#RANDOM ;; random # generator( IRQEN;; interrupt enable2X;<X; ANTICFX; -----PDMACTL;; DMA controlZ"WSYNC ;; wait for horz syncdNMIEN;; NMI enablenX;xX; FLOATING POINTX; --------------FASC;; FP-to-ATASCIIIFP;; integer-to-FPZFR0D;; clear FR0X;X; OS ROUTINESX; -----------CIOVV;; CIO entry#SETVBV\;; set v-blank vectorSYSVBV_;; OS VBI entrySIOINVe;; SIO initX;X; INTERNAL EQUATESX; ----------------X; X; MEMORY ALLOCATION" X; -----------------,"INLINE;; text input buffer6GAMEDATA:;; working area@)EDLIST <;; start of E: display listJ$SCREEN@<;; start of screen RAMTX;^X; Game play databasehX;r GAMEDATA|X;EVENT ;; event #PLACE ;; locationSLAT ;; ship's latitude SLON ;; ship's longitude MLAT ;; missile latitude!MLON ;; missile longitudeDEPTH ;; sub's depth$GREEN ;; green button on/off RED ;; red button on/off&SWITCH ;; arming switch on/off!BREATH ;; holding breath?HATCH ;; hatch opened?&UNIT ;; unit dropped in rm 17?CRASHED ;; sub crashed?BULLET ;; bullet used?SUIT ;; suit searched?&$CAPTAIN ;; captain searched?0'BHOLD ;; breath holding counter:'TRAITOR ;; traitor wait counterD%HOLDINGS ;; current inventoryN'VECTORS ;; current vector tableX'OBJECTS ;; current object tableb,NTRANS &;; current translation matrixlX;vX; MISCELLANEOUSX; ------------- EOL SPACE X;X; ZERO-PAGEX; ---------X;X; Cursor controlX;$CURSEN ;; cursor on/off flag&CSHAPE ;; current cursor shape#BLINK ;; cursor blink timerX; X; Keyboard handlerX; "CLICK ;; key click counter*&LENGTH ;; line length register4X;>X; DLI controlHX;R!DLICOL ;; DLI color index\X;fX; Screen clearingpX;z'CLPOINT ;; screen clear pointer$CINDEX ;; window clear indexX; X; ParserX;PBUFF ;; parsing bufferPDEX ;; scanning index$LBREAK ;; pos. of space charVCODE ;; verb code #)UCODE ;; untranslated noun code #'NCODE ;; translated noun code #'DOVECT ;; verb execution vector'CURVECT ;; current room vectors'CUROBJS ;; current room objects $NEWPLACE ;; next room code # (VPNT ;; addr of current v-buffer (OPNT ;; addr of current o-buffer$ .INVPOS ;; position in inventory buffer. *ROOMPOS ;; position in room buffer8 'ANY? ;; flag for empty room/invB &LATSHOW ;; latitude to displayL 'LONSHOW ;; longitude to displayV VLAST ;; last verb` ULAST ;; last nounj X;t X; Event counter~ X; EBUFF ;; printing buffer X; X; INITIALIZATION X; -------------- X;  X; ENTRY $> &COLDST 2;; = 1 &BOOT?  SIOINV;; for sound init !TITLE X; !X; CUSTOM DISPLAY LIST( !X; -------------------2 DLIST< p=p=p=p;; blank 32 linesF % B=4SCREEN=5SCREEN;; text w/LMSP  =;; blank 4 w/DLIZ  ;; text (location)d  =;; blank 4 w/DLIn  ;; text (exits)x  =;; blank 4 w/DLI & =====;; text (v-items)  =;; blank 4 w/DLI  =;; text (events)  =;; blank 4 w/DLI  =;; text (response)  ==;; blank 4 w/DLIs & =====;; text (i-items)  p;; blank 8  A=4DLIST=5DLIST;; JVB X; X; TITLE SCREEN X; ------------ TITLE $> B  NEWSCREEN;; reset E:" POSITION  =, #PRINT T0;; "Brian Moriarty's"6 POSITION =@ PRINT T1;; "CRASH DIVE"J POSITION = T +PRINT T2;; "(C)1984 ANALOG Computing"^ X;h STARTOPr POSITION =| 1PRINT T3;; "Press Ԡ to play new game" POSITION = 5PRINT T4;; "Press Π to restore old game" X; Q> PEDLIST ;; modify PEDLIST ;; display list X; Q>" PSDMCTL;; restore screen BEEP X; X; Wait for selection X; POLL QCONSOL R>;; scan until a& FPOLL;; key is pressed0 LETGO: $CONSOLD (>N HLETGOX R>;; START pressed?b !FNEWGAME;; yes, do a new gamel R>;; OPTION pressed?v $FRESTORE;; yes, restore old game BADPOLL  BOOP;; else !POLL;; resume scan X; X; Start new game X; NEWGAME INITDATA !PLAYSCREEN X; X; Restore a previous game X; RESTORE POSITION = -PRINT T5;; "Restore from Disk or Tape?" BEEP DORT* GETKEY4 R> D;; disk?> FGETDISKH R> C;; tape?R FGETAPE\ DORTERRf CLOSE1p BOOPz !DORT X; X; Get game from disk X; GETDISK DPOINT !READOPEN X; X; Get game from tape X; GETAPE TPOINT X; READOPENQ>;; OPEN command PICCOM9Q>;; READ$ PICAUX19.Q>8 PICAUX29B CIOVL GDORTERRVX;` X; Get game data thru IOCB #1jX;t GETDATA~$>Q>4GAMEDATA PICBADR9Q>5GAMEDATAPICBADR9Q>H PICBLEN9Q>PICBLEN9Q>;; GET RECORD PICCOM9 CIOV GDORTERR CLOSE1 X;X; PLAYSCREEN INITX; ---------------(PLAYSCREEN2 NEWSCREEN;; reset E:<X;F X; Enable custom display listPX;Z Q>4DLISTd PSDLSTLn Q>5DLISTxPSDLSTLX;X; Print title & labelsX;+PRINT T6;; "CRASH DIVE! (TM) EVENT #"Q> ;; set right marginPRMARGN;; for wraparound!PRINT T7;; "LOCATION/EXITS" PRINT T8;; "VISIBLE ITEMS" BAR BAR BAR BAR;; 4 blank bars SAYWHAT;; "WHAT")PRINT T11;; "HAPPENS/YOUR RESPONSE" SAYWHAT;; "WHAT"$PRINT T12;; "YOU ARE CARRYING"" BAR, BAR;; more blank bars6Q>'@PRMARGN;; resetJX;TQ>;; green^PPCOLR0;; cursorhX;rX; Setup P/M borders & mask|X;Q>0PHPOSP1;; position left Q>;; andPHPOSP2;; right borders Q>@;; andPHPOSP3;; title cover$>&GRAFP1;; set up&GRAFP2;; side borders and&GRAFP3;; title mask 2;; = 0&SIZEP0;; set cursor width 2;; = 1!&GPRIOR;; set player priorityQ>PSIZEP1;; set border&PSIZEP2;; and mask0PSIZEP3;; widths:X;DQ>;; initNPCSHAPE;; cursor shapeX Q>;; andbPBLINK;; blink timerlX;vQ> PLMARGN;; init left marginX;%>4IMMVBI;; set VBI vector,$>5IMMVBI;; specifyingQ>;; immediate-mode SETVBVX; Q>4DLIPVDSLST;; tell OS whereQ>5DLI;; we put our$PVDSLST;; DLI service routine!Q>;; set bits 6 & 7 of NMIEN$PNMIEN;; to enable DLIs and VBIsX;  QPLACE !REENTRY X;*X; EVENT GENERATOR4X; --------------->X;H NEXTEVENTR$>;; empty stack\B;; just in case!f SHOWEV;; show event #p#EVENT;; updatezHRADIO;; event#EVENT;; counterX;X; Handle room 0X; RADIO QPLACE HENEMYQ> ;; got suit? OWNIT? FENEMY NEWSCREENPOSITION =,PRINT T79;; "A blast of radioactivity" !KILLSX;X; Check for enemy takeover$X;. ENEMY8 QEVENTBR> L HLUNGSV QEVENT` HLUNGSj QDEPTHt HLUNGS~ NEWSCREENPOSITION =.PRINT T67;; "Enemy captures the sub and" !KILLSX;X; Limit breath-holdingX; LUNGSQBREATH;; holding it?FPOISON;; no - skip this!"BHOLD;; else decrement countHPOISON;; continue if NZQ>;; elsePBREATH;; release hold X;X; Handle poison atmosphereX;( POISON2QHATCH;; hatch opened?<FDOTRAIT;; not yetFQ>;; got theP OWNIT?;; mask?Z FDOTRAIT;; yup - you're safedQBREATH;; holding breath?n(HDOTRAIT;; good thing, otherwise ...x NEWSCREENPOSITION =,PRINT T62;; "A cloud of poisonous gas" !KILLSX;X; Handle traitorX; DOTRAIT QTRAITOR INTRAIT NEWSCREENPOSITION  =*PRINT T77;; "Traitor shoots you and" !KILLS NTRAITQPLACE;; is thisR>;; room 18?"HTRESET;; we're safe,Q>;; is the traitor6 INROOM?;; lurking?@HTRESET;; thankfully notJ$"TRAITOR;; else reduce wait timeT !DOCRASH^ TRESEThQ>r PTRAITOR|X;%X; Change sub coords, handle crashX; DOCRASH QCRASHED HPARSER QRANDOMM> PSLAT QRANDOMM> PSLONQRED FPARSER QDEPTH,-&O>0 PDEPTH: IPARSERD PCRASHEDN CLWHXPRINT T45;; "BANG!"b$PRINT T78;; "Sub hits bottom!"lX;vX; INPUT PARSERX; ------------X; PARSERQ>" PSDMCTL# GETLINE;; put line into INLINE CLWH $LENGTH(>;; if length is 1"HDOCLAUSE;; check for legalityX;+X; Check for a legal single-char commandX;QINLINE;; get the character $>;; init search index LEGSING  RSCOMS9*FEXSING;; matched! go do it40;; otherwise>ILEGSING;; keep searchingH SYNERR;; error, so printR#PRINT T14;; "Invalid command"\!BADPARSE;; and try againfX;p#X; Execute a single-char commandzX; EXSINGQSVECTL9;; fetch the lsbPDOVECT;; andQSVECTH9;; msb of thePDOVECT;; execution addr!@DOVECT:;; and do it!X;"X; Find the 1st space characterX; in the user's responseX; DOCLAUSE Q>SPACE PPBUFF PPBUFF$> FIND1$QINLINE9;; length is in X.R>SPACE;; is it a space?8FENDV;; yes!B2;; else keep scanningL (LENGTHV DFIND1` BADVERBj' SYNERR;; verb is no good, so printt'PRINT T15;; "Verb not recognized"~!BADPARSE;; and try againX;%X; Space char found, so record its&X; position and move the first half+X; of the clause into the parsing bufferX;ENDV &LBREAK(> DTOVB$>TOVB QINLINE9 PPBUFF9 0 ITOVBX;(X; Check for a legal verb2X;<$>;; init verb indexF &VCODEP VNEXTZ &PDEXd %>;; init buffer char indexn VSCANx$QPBUFF8;; get a char from bufferRVERBS9;; match?%HNEXTRY;; nope - try another verb23)>!DVSCAN;; if all 3 chars matchELEGALV;; the verb is legal NEXTRY #VCODE $PDEX222(>NV;; out of verbs?!DVNEXT;; nope - keep scanning%EBADVERB;; else verb is worthless"X;,+X; Verb is legal, so fetch its execution6 X; vector@X;J LEGALVTQVCODE;; fetch verb #^R>;; if it's GO,hHMOVE2;; warn user:r'PRINT T29;; "Type N S E W U or D"| !BADPARSEX;!X; Move the second half of the$X; clause into the parsing bufferX; MOVE2&$LBREAK;; fetch pos. of space char 2;; plus 1 %>;; init buffer char index MOVENQINLINE9;; fetch characterPPBUFF8;; stuff into buffer23)>;; until 3 charactersDMOVEN;; have been movedX;&X; Check for a legal noun0X;:$>;; init noun indexD &UCODEN NNEXTX &PDEXb %>;; init buffer char indexl NSCANv$QPBUFF8;; get a char from bufferRNOUNS9;; match?&HNEXTRY2;; nope - try another noun23)>!DNSCAN;; if all 3 chars matchELEGALN;; the noun is legal NEXTRY2 #UCODE $PDEX222(>NN;; out of nouns? !DNNEXT;; nope - keep scanning" SYNERR;; else noun is garbage *PRINT T16;; "Noun not in vocabulary"* !BADPARSE4X;> X; Noun's code # is in UCODE;H X; verb's code # is in VCODE;R&X; verb execution addr is in DOVECT\X;f LEGALNpQVCODE;; fetchz PVLASTT?;; execution addr >;; andQVVECTS9;; save itPDOVECT;; in DOVECT2 QVVECTS9PDOVECT QUCODE PULASTR>';; was it BUTTON? FDOBUTTR>(;; was it INVENTORY? FDOINVE>QNTRANS9;; translate noun PNCODE$!@DOVECT:;; execute verb.X;8X; Handle BUTTONBX;L DOBUTTV(PRINT T30;; "Refer to it by color"` !BADPARSEjX;tX; Handle INVENTORY~X; DOINVE(PRINT T31;; "Type I for inventory" !BADPARSEX;*X; EXECUTE SINGLE-CHAR COMMANDS*X; ----------------------------X;#X; COMMAND VECTOR TABLES#X; --------------------- SVECTL! 4DOM=4DOM=4DOM=4DOM=4DOM 4DOM=4DOQ=4DOX=4DOA SVECTH ! 5DOM=5DOM=5DOM=5DOM=5DOM 5DOM=5DOQ=5DOX=5DOAX;(X; HANDLE "Q" (QUIT)2X; -----------------<DOQFPOSITION  = P(PRINT T19;; "Type Y to quit game:"ZPOSITION "= d&CURSEN;; enable cursorn BEEPx GETKEYR> Y FDOQUIT$>  ERASE !BADPARSE DOQUIT !TITLEX;X; HANDLE MOVEMENTX; ---------------X; ENTRY: Vector (0-5) in XX;DOM QCURVECT9 IEXMOVE CANTGO"*PRINT T18;; "You can't go that way.", !BADPARSE6 EXMOVE@-;; for safetyJ PNEWPLACE;; save destinationT SAVELOC;; save status^ QNEWPLACE;; get destination,h!PPLACE;; make it current, andr REENTRY|& BPOINT;; point to the new buffersX;X; Get new buffer dataX;%> RLOOP Q@VPNT7 PCURVECT8 Q@OPNT7 PCUROBJS81 IRLOOPX;X; Refresh screen X; SHOWPLACE $>& " ERASE;; clear location window0 POSITION  =: $PLACE;; get loc #D QRDLS9;; fetch lsb andN !%RDHS9;; msb of text addr andX  EPRINT;; print itb X;l $ SHOWVIS;; display visible itemsv $ SHOWVECTS;; display new vectors  SHOWINV;; show inventory !POKAY;; congratulations! X; "X; POINT TO NEW BUFFERS "X; -------------------- !X; ENTRY: Buffer # (0-23) in A X; BPOINT T?;; * 2 PNCODE;; save it T?;; * 4 , ONCODE;; *2 + *4 = *6!PNCODE;; save it !,!O>4VECTORS ! PVPNT*!Q>5VECTORS4!O>>! PVPNTH!,R! QNCODE\!O>4OBJECTSf! POPNTp!Q>5OBJECTSz!O>! POPNT!:!X;!$X; HANDLE "X" (SAVE GAME)!$X; ----------------------!DOX!" SAVELOC;; save current status! NEWSCREEN!POSITION = !2PRINT T82;; "Save game to Disk or Cassette?"!Q>"! PSDMCTL! BEEP" SAVEPOLL" GETKEY"R> D$" FDSAVE."R> C8" FCSAVEB" BADWRITEL" CLOSE1V" BOOP`" !SAVEPOLLj"X;t"X; Save to disk~"X;" DSAVE" DPOINT" !GSAVE"X;"X; Save to cassette"X;" CSAVE" TPOINT"X;" GSAVE"Q>" PICCOM9#Q> # PICAUX19#Q># PICAUX29(# CIOV2# GBADWRITE<#X;F#X; Write out game dataP#X;Z# WRITEd#$>n#Q>4GAMEDATAx# PICBADR9#Q>5GAMEDATA#PICBADR9#Q>H# PICBLEN9#Q>#PICBLEN9#Q> # PICCOM9# CIOV# GBADWRITE# CLOSE1#!PLAYSCREEN#X;$ X; HANDLE "A" (AGAIN)$ X; ------------------$DOA"$QVLAST;; restore old verb,$ PVCODE6$QULAST;; and noun@$ PUCODEJ$!LEGALN;; and do it again!T$X;^$X; SAVE LOC STATUSh$X; ---------------r$ SAVELOC|$ QPLACE$ BPOINT$%>$ SLOOP$ QCURVECT8$ P@VPNT7$ QCUROBJS8$ P@OPNT7$1$ ISLOOP$:$X;