.TITLE WUMPUS .NLIST BEX .ENABL LC ; ; HUNT THE WUMPUS ; ; DGC ; .GLOBL .WUMP .MCALL QIO$, DIR$, WTSE$S, EXIT$S, CALL, RETURN .MCALL GTIM$S, FDBDF$, FDRC$A, FDOP$A, FSRSZ$ .MCALL OPEN$R, CLOSE$, GET$S ; ; THIS PROGRAM REQUIRES THE FOLLOWING LUN ASSIGNMENTS ; TI: ON LUN 1 ; SY: ON LUN 2 ; ; ; LOCAL EQUATES ; NCAVES = 32. ;WATCH THIS!!!! ; ; LOCAL DATA ; CURCAV: .WORD 0 ;CURRENT CAVE POINTER DSPT: .WORD 0,0 ;USE DEFAULT DEVICE .WORD 6.,RULUIC ;HELP FILE IS IN [1,54] .WORD 10.,RULFIL ;AND IS CALLED WUMPUS.TXT IOSTAT: .BLKW 2 ;IO STATUS BLOCK WUMPUS: .WORD 0 ;POINTER TO THE WUMPUS PIT1: .WORD 0 ;POINTER TO PIT 1 PIT2: .WORD 0 ;POINTER TO PIT 2 BAT1: .WORD 0 ;POINTER TO BAT 1 BAT2: .WORD 0 ;POINTER TO BAT 2 WFLAG: .WORD 0 ;WUMPUS FLAG BATFLG: .WORD 0 ;BAT FLAG PITFLG: .WORD 0 ;BOTTOMLESS PIT FLAG ARROWS: .WORD 0 ;NUMBER OF ARROWS LEFT TTYBUF: .BLKW 90. ;THE TTY INPUT BUFFER OLDRN: .WORD 13507 ;RANDOM NUMBER SEED TIMBLK: .BLKW 8. ;PARAMETER BLOCK FOR GTIM$ CAVES: .BLKW 8.*NCAVES ;THE CAVES ECAVES: .BLKW 0 ;END OF THE CAVES MOVTAB: .BLKW 3 ;MOVE TABLE FOR SHOOTING ENDTAB: .BLKW 0 ;END OF THE TABLE ; ; RSX DPB'S ; ATTBLK: QIO$ IO.ATT,1,1,,IOSTAT ;FOR THE TI: ATTACH TTYDPB: QIO$ IO.WLB,1,1,,IOSTAT,,<0,0,0> ;FOR TI: WRITES REDDPB: QIO$ IO.RLB,1,1,,IOSTAT,, ; ; FCS INFORMATION ; FSRSZ$ 1 ;NEED 1 FILE OPEN FDB: FDBDF$ ;DEFINE AN FDB FDRC$A ,TTYBUF,90. ;POINT AT THE TTY BUFFER FDOP$A 2,DSPT ;SET UP POINTER TO DSPT RULUIC: .ASCII '[1,54]' ;UIC FOR THE RULES FILE RULFIL: .ASCII 'WUMPUS.TXT' ;THE ACTUAL RULE FILE ; ; MESSAGES ; .EVEN MESG1: .WORD MESG2-.-2 .ASCII "Cannot attach the TI:" .EVEN MESG2: .WORD MESG3-.-2 .ASCII "Do you require the rules? " MESG3: .ASCII "You are in cave " MESG3A: .ASCII 'XX' .EVEN MESG4: .WORD MESG5-.-2 .ASCII "You have been eaten by the wumpus" .EVEN MESG5: .WORD MESG6-.-2 .ASCII "You have fallen into a bottomless pit" .EVEN MESG6: .WORD MESG7-.-2 .ASCII "There is a super bat in your cave" .EVEN MESG7: .WORD MESG8-.-2 .ASCII "(M)ove or (S)hoot? " .EVEN MESG8: .WORD MESG9-.-2 .ASCII "You cannot get there from here" .EVEN MESG9: .WORD MESG10-.-2 .ASCII "Missed" .EVEN MESG10: .WORD MESG11-.-2 .ASCII "You are out of arrows" .EVEN MESG11: .WORD MESG12-.-2 .ASCII "You have just shot yourself" MESG12: .ASCII "The dreaded wumpus was in " MESA12: .ASCII 'XX' .EVEN MESG13: .WORD MESG14-.-2 .ASCII "You have shot the wumpus" .EVEN MESG14: .WORD MESG15-.-2 .ASCII "Another game? " .EVEN MESG15: .WORD MESG16-.-2 .ASCII "What?" .EVEN MESG16: .WORD MESG17-.-2 .ASCII "I smell a wumpus" .EVEN MESG17: .WORD MESG18-.-2 .ASCII "I feel a draft" .EVEN MESG18: .WORD MESG19-.-2 .ASCII "Bats nearby" .EVEN MESG19: .WORD MESG20-.-2 .ASCII "There are not that many caves" .EVEN MESG20: .ASCII "Pathways lead to" MESA20: .BLKB 24. .EVEN MESG21: .WORD MESG22-.-2 .ASCII "Error during help I/O" MESG22: .BLKW 0 .EVEN ;+ ; ** .WUMP -- THE WUMPUS MAINLINE ; ; INPUTS: ; ; NONE ; ; OUTPUTS: ; ; DISATISFIED PLAYERS ;- .WUMP: DIR$ #ATTBLK ;ATTACH THE TI: LUN WTSE$S #1 ;WAIT FOR THE ATTACH CMPB IOSTAT,#IS.SUC ;DID IT WORK BEQ 10$ ;BR IF OK MOV #MESG1,R0 ;GET ADDRESS OF THE DIAGNOSTIC CALL PUTMES ;WRITE IT OUT EXIT$S ;THEN QUIT 10$: GTIM$S #TIMBLK ;GET THE TIME FROM THE SYSTEM MOV TIMBLK+G.TIMI,R0 ;GET TIME IN MINUTES SWAB R0 ;THROW IT TO THE UPPER HALF BISB TIMBLK+G.TISC,R0 ;OR IN THE SECONDS BIS #1,R0 ;FORCE IT ODD MOV R0,OLDRN ;SET UP BASE FOR RANDOM NUMBERS MOV #MESG2,R0 ;ASK IF WE WANT RULES CALL PROMPT ;ASK IF WE WANT RULES CALL GETSTR ;GET THE REPLY BCS 10$ ;BR IF ERROR ON THE READ BISB #40,TTYBUF ;FORCE LOWER CASE CMPB TTYBUF,#171 ;IS THE ANSWER "Y" BNE NGAME ;BR IF NOT CALL RULES ;OTHERWISE PRINT THE RULES ; ; NEW GAME -- GENERATE NEW CAVES ; NGAME: CALL GCAVES ;GENERATE NEW CAVES ; ; THE TOP OF THE GAME LOOP ; .ENABL LSB GLOOP: MOV CURCAV,R0 ;GET WHERE I AM NOW CALL CAVENO ;CONVERT TO CAVE NUMBER MOV #MESG3A,R1 ;GET ADDRESS OF THE MESSAGE TEXT CALL PUTNUM ;STUFF THE CAVE NUMBER SUB #MESG3,R1 ;GET THE RECORD LENGTH MOV #MESG3,R0 ;GET THE MESSAGE HEADER CALL MESOUT ;AND TYPE IT ; ; LOOK AROUND FOR WUMPI, PITS AND BATS ; MOV CURCAV,R0 ;GET WHERE I AM CMP R0,WUMPUS ;IS THE WUMPUS HERE BNE 10$ ;BR IF NOT MOV #MESG4,R0 ;GET "EATEN BY WUMPUS" MESSAGE CALL PUTMES ;WRITE IT OUT JMP ANOGAM ;ASK IF WANTS TO TRY AGAIN 10$: CMP R0,PIT1 ;A PIT BEQ 20$ ;BR IF YES CMP R0,PIT2 ;THE OTHER PIT BNE 40$ ;BR IF NOT 20$: MOV #MESG5,R0 ;GET ADDRESS OF THE BAD NEWS CALL PUTMES ;TYPE IT OUT JMP TELWMP ;THEN GO TELL WHERE THE WUMPUS WAS 40$: CMP R0,BAT1 ;LOOK FOR SUPER BATS BEQ 50$ ;FOUND A BAT CMP R0,BAT2 ;TRY THE OTHER BAT BNE 60$ ;NO BATS 50$: MOV #MESG6,R0 ;TELL ABOUT THE BAT CALL PUTMES ;TELL ABOUT THE BAT CALL RANCAV ;GET A RANDOM CAVE CMP CURCAV,BAT1 ;WHICH BAT? BEQ 55$ ;BAT ONE GOT ME MOV R0,BAT2 ;MUST HAVE BEEN BAT 2 BR 57$ ;SKIP 55$: MOV R0,BAT1 ;MOVE BAT 1 57$: CALL RANCAV ;GET A RANDOM CAVE MOV R0,CURCAV ;MOVE THE PLAYER THERE BR GLOOP ;GO BACK TO MAIN LOOP ; ; LIST THE PATHWAYS ; 60$: MOV #MESA20,R1 ;GET POINTER TO THE BUFFER MOV CURCAV,R2 ;GET CURRENT CAVE MOV #8.,R3 ;GET LINK COUNTER 63$: MOV (R2)+,R0 ;GET ENTRY FROM LINKS BEQ 65$ ;NULL LINK MOVB #40,(R1)+ ;PUT A BLANK IN THE BUFFER CALL CAVENO ;CONVERT TO CAVE NUMBER CALL PUTNUM ;STORE DOWN CAVE NUMBER 65$: DEC R3 ;ANY MORE IN THIS CAVE BNE 63$ ;BR IF MORE SUB #MESG20,R1 ;GET BYTE COUNT MOV #MESG20,R0 ;GET MESSAGE ADDRESS CALL MESOUT ;WRITE IT OUT ; ; READ IN HIS MOVE ; CALL HAZARD ;TYPE OUT THE HAZARDS MOS: MOV #MESG7,R0 ;ASK MOVE OR SHOOT CALL PROMPT ;ASK MOVE OR SHOOT CALL GETSTR ;GET REPLY BCS MOS ;BR ON IO ERROR MOV #TTYBUF,R0 ;GET BUFFER POINTER 80$: MOVB (R0)+,R1 ;GET CHAR FROM THE INPUT CMPB R1,#40 ;IS IT A BLANK BEQ 80$ ;YES -- IGNORE IT CMPB R1,#15 ;IS IT A NULL LINE BEQ MOS ;BR IF YES BISB #40,R1 ;MAKE IT LOWER CASE CMPB R1,#163 ;S -- SHOOT BEQ SHOOT ;BR IF YES CMPB R1,#155 ;M -- MOVE BNE MOS ;NEITHER -- ASK AGAIN .DSABL LSB ; ; MOVE ; MOVE: MOVB (R0)+,R1 ;GET THE NEXT CHARACTER CMPB R1,#40 ;IS IT A BLANK BEQ MOVE ;YES - IGNORE IT CMPB R1,#15 ;NEWLINE? BEQ SHERR ;YES - ERROR CALL GETNUM ;GET WHERE TO MOVE TO CALL CCAVPT ;GET CAVE PTR IN R2 BCS 30$ ;BR ON ERROR MOV CURCAV,R0 ;GET CURRENT CAVE MOV #8.,R1 ;GET SIZE 10$: CMP (R0)+,R2 ;IT IT HERE BEQ 20$ ;BR IF I CAN GET THERE DEC R1 ;ANY MORE BNE 10$ ;BR IF YES MOV #MESG8,R0 ;ERROR - YOU CAN' GET THERE CALL PUTMES ;ERROR - YOU CAN'T GET THERE BR 30$ ;GO TO EXIT 20$: MOV R2,CURCAV ;RESET CURRENT CAVE JMP GLOOP ;THEN GO TO MAIN LOOP 30$: JMP MOS ;ERROR - ASK AGAIN ; ; SHOOT ; .ENABL LSB SHOOT: MOVB (R0)+,R1 ;GET A CHAR CMPB R1,#40 ;FLUSH BLANKS BEQ SHOOT ;FLUSH BLANKS CMPB R1,#15 ;HOW ABOUT A CR BEQ SHERR ;IF SO, ERROR MOV #MOVTAB,R3 ;GET ADDRESS OF THE MOVE TABLE 10$: CALL GETNUM ;GET A CAVE NUMBER CALL CCAVPT ;CONVERT TO CAVE POINTER BCS 45$ ;BR IF ERROR CMP R3,#ENDTAB ;ANY MORE ROOM IN THE TABLE BHIS SHERR ;ERROR IF MORE THAN 3 MOV R2,(R3)+ ;STUFF IN THE BUFFER CMPB R1,#15 ;END OF THE LIST BEQ 30$ ;BR IF YES CMPB R1,#40 ;HOW ABOUT A BLANK BNE SHERR ;ERROR IF NOT 20$: MOVB (R0)+,R1 ;GET THE NEXT CHAR CMPB R1,#40 ;SKIP BLANKS BEQ 20$ ;SKIP BLANKS CMPB R1,#15 ;A SECRET CR BEQ 30$ ;BR IF YES BR 10$ ;GET THE NEXT NUMBER SHERR: MOV #MESG15,R0 ;GET ERROR POINTER CALL PUTMES ;WRITE OUT ERROR BR 45$ ;GO TO COMMON EXIT 30$: MOV #MOVTAB,R1 ;GET MOVE TABLE ADDRESS MOV CURCAV,R0 ;GET WHERE I AM 35$: MOV #8.,R2 ;GET COUNTER 40$: CMP (R0)+,(R1) ;IN THIS BEQ 50$ ;BR IF FOUND DEC R2 ;ANY MORE BNE 40$ ;BR IF YES MOV #MESG8,R0 ;ERROR - YOU CAN'T GET THERE CALL PUTMES ;TYPE IT OUT 45$: JMP MOS ;GO ASK AGAIN 50$: MOV (R1)+,R0 ;GET THE NEXT ENTRY CMP R1,R3 ;ANY MORE BLO 35$ ;BR IF YES MOV #MOVTAB,R0 ;GET MOVE TABLE ADDRESS 60$: CMP (R0)+,CURCAV ;LOOK FOR SHOOTING SELF BEQ 90$ ;BR IF YES CMP R0,R3 ;END OF TABLE BLO 60$ ;BR IF NOT MOV #MOVTAB,R0 ;GET IT AGAIN 70$: CMP (R0)+,WUMPUS ;IS THE WUMPUS HERE BEQ 110$ ;BR IF YES CMP R0,R3 ;TEST FOR TABLE END BLO 70$ ;BR IF NOT THERE YET MOV #MESG9,R0 ;MISSED CALL PUTMES ;MISSED DEC ARROWS ;ANY MORE ARROWS BEQ 80$ ;BR IF OUT OF ARRPWS CALL RANCAV ;GENERATE A RANDOM CAVE MOV R0,WUMPUS ;THE WUMPUS MOVES JMP GLOOP ;GO TO MAIN LOOP 80$: MOV #MESG10,R0 ;OUT OF ARROWS BR 100$ ;GO TO COMMON CODE 90$: MOV #MESG11,R0 ;SHOT SELF 100$: CALL PUTMES ;WRITE OUT THE MESSAGE TELWMP: MOV #MESA12,R1 ;GET MESSAGE ADDRESS MOV WUMPUS,R0 ;GET WUMPUS ADDRESS CALL CAVENO ;CONVERT TO CAVE NUMBER CALL PUTNUM ;CONVERT TO ASCII SUB #MESG12,R1 ;GET BYTE COUNT MOV #MESG12,R0 ;GET START OF THE MESSAGE CALL MESOUT ;TYPE IT BR ANOGAM ;GO TO ANOTHER GAME 110$: MOV #MESG13,R0 ;YOU HAVE SLAIN THE WUMPUS CALL PUTMES ;WRITE IT OUT ANOGAM: MOV #MESG14,R0 ;GET QUESTION ADDRESS CALL PROMPT ;ASK THE QUESTION CALL GETSTR ;READ THE REPLY BISB #40,TTYBUF ;FORCE LOWER CASE CMPB TTYBUF,#171 ;Y BEQ 130$ ;BR IF YES EXIT$S ;LEAVE IF NOT 130$: JMP NGAME ;BR TO NEW GAME CODE .DSABL LSB ;+ ; ** MESOUT -- TYPE MESSAGES ; ; INPUTS: ; ; R0=POINTER TO STRING ; R1=LENGTH IN BYTES ; ; ** PUTMES -- TYPE MESSAGES ; ; INPUTS: ; ; R0=POINTER TO STANDARD MESSAGES ; ; ** PROMPT -- DO PROMPT I/O ; ; INPUTS: ; ; R0=POINTER TO STANDARD MESSAGES ;- .ENABL LSB MESOUT: MOV R1,TTYDPB+Q.IOPL+2 ;STORE LENGTH BR 10$ ;GO TO COMMON CODE PUTMES: MOV (R0)+,TTYDPB+Q.IOPL+2 ;STORE LENGTH 10$: MOV #40,TTYDPB+Q.IOPL+4 ;STORE SLEW BR 20$ ;MORE COMMON CODE PROMPT: MOV (R0)+,TTYDPB+Q.IOPL+2 ;STORE LENGTH MOV #'$,TTYDPB+Q.IOPL+4 ;STORE SLEW 20$: MOV R0,TTYDPB+Q.IOPL ;SAVE THE POINTER DIR$ #TTYDPB ;DO THE WRITE WTSE$S #1 ;WAIT UNTIL ALL DONE RETURN ;GO HOME .DSABL LSB ;+ ; ** GETSTR -- READ STRING INTO TTYBUF ; ; GETSTR ALSO ADDS A CR TO THE END ; ; INPUTS: ; ; NONE ; ; OUTPUTS: ; ; C BIT SET ON I/O ERROR ; R0 IS DESTROYED ;- GETSTR: DIR$ #REDDPB ;DO THE TTY READ WTSE$S #1 ;WAIT FOR IT TO COMPLETE CMP IOSTAT,#IS.CR ;GOOD STATUS BNE 10$ ;BR IF NOT MOV IOSTAT+2,R0 ;GET ACTUAL BYTE COUNT MOVB #15,TTYBUF(R0) ;PUT CR ON THE END CLC ;CLEAR C BIT ON GOOD RETURN RETURN ;RETURN 10$: SEC ;SET C BIT ON ERROR RETURN RETURN ;RETURN ;+ ; ** CAVENO -- CONVERT CAVE POINTER TO CAVE NUMBER ; ; INPUTS: ; ; R0=CAVE POINTER ; ; OUTPUTS: ; ; R0=CAVE NUMBER ;- CAVENO: SUB #CAVES,R0 ;REMOVE FIXED BASE ASR R0 ;TO WORDS ASR R0 ;TO CAVE OFFSET ASR R0 ;TO CAVE OFFSET ASR R0 ;TO CAVE OFFSET INC R0 ;MAKE IT ORIGIN 1 RETURN ;RETURN ;+ ; ** PUTNUM -- PUT NUMBER INTO BUFFER ; ; INPUTS: ; ; R0=NUMBER ; R1=BUFFER ADDRESS ; ; OUTPUTS: ; ; R0=CRAP ; R1=UPDATED BUFFER ADDRESS ;- PUTNUM: CMP R0,#9. ;IS IT A SINGLE DIGIT NUMBER BLOS 30$ ;BR IF YES MOVB #60,(R1) ;NO -- BEGIN WITH 0 10$: SUB #10.,R0 ;TRY FOR A TIME BMI 20$ ;BR IF NO MORE INCB (R1) ;ADD A DIGIT BR 10$ ;AND KEEP TRYING 20$: INC R1 ;MOVE THE BUFFER POINTER ADD #10.,R0 ;ADD BACK THE 10 30$: ADD #60,R0 ;CONVERT TO ASCII MOVB R0,(R1)+ ;PUT IN THE BUFFER RETURN ;RETURN ;+ ; ** CCAVPT -- CONVERT CAVE NUMBER TO POINTER ; ; INPUTS: ; ; R2=CAVE NUMBER ; ; OUTPUTS: ; ; R2=CAVE POINTER ;- CCAVPT: DEC R2 ;CONVERT TO ORIGIN 0 BMI 10$ ;ERROR IF -VE CMP R2,#NCAVES ;LEGAL CAVE NUMBER BHIS 10$ ;ERROR IF TOO BIG ASL R2 ;CONVERT TO BYTES ASL R2 ASL R2 ASL R2 ADD #CAVES,R2 ;GET ACTUAL ADDRESS CLC ;CLEAR C BIT ON GOOD RETURN RETURN ;RETURN 10$: MOV #MESG19,R0 ;GET ERROR MESSAGE NUMBER CALL PUTMES ;TYPE IT OUT SEC ;SET C BIT ON ERROR RETURN ;HOME ;+ ; ** GETNUM -- GET A NUMBER ; ; INPUTS: ; ; R0=STRING POINTER ; R1=INITIAL CHARACTER ; ; OUTPUTS: ; ; R0=UPDATED ; R1=DELIMITER ; R2=NUMBER ;- GETNUM: CLR R2 ;SET VALUE TO 0 10$: CMPB R1,#'0 ;TEST LOW SIZE BLO 20$ ;BR IF OUT CMPB R1,#'9 ;TEST HIGH SIZE BHI 20$ ;BR IF TOO HIFH SUB #60,R1 ;GET ACTUAL VALUE ASL R2 ;MULT OLD BY 10 MOV R2,-(SP) ASL R2 ASL R2 ADD (SP)+,R2 ;10X = 2X + 8X ADD R1,R2 ;ACCUMULATE MOVB (R0)+,R1 ;GET NEXT CHARACTER BR 10$ ;GO CONVERT 20$: RETURN ;RETURN ;+ ; ** HAZARD -- PRINT HAZARDS IN RANGE ; ; USES ALL THE REGISTERS ;- HAZARD: CLR WFLAG ;CLEAR ALL FLAGS CLR BATFLG CLR PITFLG MOV CURCAV,R0 ;GET POINTER TO WHERE I AM MOV #8.,R1 ;GET A COUNTER 10$: MOV (R0)+,R2 ;GET ENTRY FROM TABLE BEQ 25$ ;BR IF NULL CALL CHECK ;CHECK FOR HAZARDS MOV R2,R3 ;SAVE THE PALCE MOV #8.,R4 ;GET ANOTHER COUNTER 15$: MOV (R3)+,R2 ;GET ENTRY BEQ 20$ ;BR IF NULL CALL CHECK ;CHECK FOR HAZARDS 20$: DEC R4 ;ANY MORE TO DO BNE 15$ ;BR IF YES 25$: DEC R1 ;ANY MORE AT THE TOP BNE 10$ ;BR IF YES TST WFLAG ;FIND A WUMPUS BEQ 30$ ;BR IF NOT MOV #MESG16,R0 ;GET MESSAGE ADRESS CALL PUTMES ;TYPE IT 30$: TST PITFLG ;ANY PITS BEQ 40$ ;BR IF NOT MOV #MESG17,R0 ;GET MESSAGE TEXT CALL PUTMES ;TYPE IT 40$: TST BATFLG ;ANY BATS BEQ 50$ ;BR IF NOT MOV #MESG18,R0 ;GET MESSAGE CALL PUTMES ;TYPE IT OUT 50$: RETURN ;+ ; ** CHECK -- CHECK IF SQUARE IS A HAZARD ; ; INPUTS: ; ; R2=CAVE POINTER ; ; OUTPUTS: ; ; SETS WFLAG, PITFLG, BATFLG ;- CHECK: CMP R2,WUMPUS ;IS THERE A WUMPUS HERE BNE 10$ ;NO INC WFLAG ;SET WUMPUS FLAG 10$: CMP R2,PIT1 ;TEST FOR PITS BEQ 20$ ;FOUND PIT CMP R2,PIT2 ;TRY FOR ANOTHER PIT BNE 30$ ;BR IF NO PIT 20$: INC PITFLG ;SET PIT FLAG 30$: CMP R2,BAT1 ;TEST FOR BATS BEQ 40$ ;BR IF FOUND ONE CMP R2,BAT2 ;TEST FOR ANOTHER BAT BNE 50$ ;BR IF NO BATS 40$: INC BATFLG ;SET BAT FLAG 50$: RETURN ;HOME ;+ ; ** IMUL -- INTEGER MULTIPLY ; ; INPUTS: ; ; R1=MULTIPLIER ; R2=MULTIPLICAND ; ; OUTPUTS: ; ; R0-R1=PRODUCT ; R2=UNCHANGED ;- IMUL: MOV #16.,-(SP) ;SETUP LOOP COUNT CLR R0 ;ZERO UPPER HALF OF PRODUCT 10$: BIT #1,R1 ;NEED TO ADD BEQ 20$ ;BR IF NOT ADD R2,R0 ;OTHERWISE ADD IT IN 20$: CLC ;DO LONG RIGHT SHIFT ROR R0 ;DO LONG RIGHT SHIFT ROR R1 ;DO LONG RIGHT SHIFT DEC (SP) ;NEED TO DO MORE BNE 10$ ;BR IF YES TST (SP)+ ;CLEAR LOOP COUNT RETURN ;GO HOME ;+ ; ** RANCAV -- GENERATE A RANDOM CAVE POINTER ; ; INPUTS: ; ; NONE ; ; OUTPUTS: ; ; R0=CAVE POINTER ;- RANCAV: MOV R1,-(SP) ;SAVE REGISTERS MOV R2,-(SP) ;SAVE REGISTERS MOV OLDRN,R1 ;GET OLD RANDOM NUMBER MOV #403,R2 ;GET MULTIPLIER CALL IMUL ;GENERATE A NEW NUMBER BIC #100000,R1 ;FORCE POSITIVE MOV R1,OLDRN ;SAVE THE OLD NUMBER SWAB R1 ;EXTRACT TOP 5 BITS BIC #177603,R1 ;EXTRACT TOP 5 BITS ASL R1 ;GET CORRECT POSITION ASL R1 ;GET CORRECT POSITION ADD #CAVES,R1 ;GET POINTER MOV R1,R0 ;IN CORRECT REGISTER MOV (SP)+,R2 ;RESTORE MOV (SP)+,R1 ;RESTORE RETURN ;+ ; ** CAVES -- SET UP THE CAVES ; ; USES A BUNCH OR REGISTERS ;- GCAVES: MOV #10.,ARROWS ;SET UP 10 ARROWS LEFT MOV #CAVES,R1 ;GET POINTER TO CAVES MOV #NCAVES*8.,R2 ;AND A COUNT 10$: CLR (R1)+ ;MARK UNUSED DEC R2 ;ANY MORE BNE 10$ ;BR IF YES MOV #CAVES,R1 ;RESET CAVE POINTER 15$: MOV R1,R2 ;GET A WORKING COPY MOV #8.,R3 ;AND A COUNTER 20$: TST (R2) ;IS IT NULL BNE 30$ ;BR IF NOT EMPTY CALL RANCAV ;GENERATE A RANDOM CAVE MOV R0,R4 ;SAVE IT MOV #8.,R5 ;GET A COUNT 23$: TST (R4)+ ;NULL BEQ 25$ ;BR IF YES DEC R5 ;ANY MORE TO DO BNE 23$ ;BR IF YES BR 30$ ;BR IF ALL FULL 25$: MOV R1,-(R4) ;SET UP CAVE LINKS MOV R0,(R2)+ ;SET UP CAVE LINKS BR 35$ ;THEN SKIP 30$: TST (R2)+ ;JUST GOVE UP 35$: DEC R3 ;ANY MORE IN THIS BLOCK BNE 20$ ;BR IF YES ADD #16.,R1 ;MOVE TO NEXT CAVES CMP R1,#ECAVES ;ALL DONE BLO 15$ ;BR IF NOT CALL RANCAV ;SET UP WUMPUS MOV R0,WUMPUS CALL RANCAV ;THE PITS MOV R0,PIT1 CALL RANCAV MOV R0,PIT2 CALL RANCAV ;THE BATS MOV R0,BAT1 CALL RANCAV MOV R0,BAT2 CALL RANCAV ;THE PLAYER MOV R0,CURCAV RETURN ;ALL SET UP ;+ ; ** RULES -- TYPE OUT THE RULES ; ; INPUTS: ; ; NONE ; ; OUTPUTS: ; ; NONE ;- RULES: OPEN$R #FDB ;TRY TO OPEN THE RULES BCS 40$ ;BR ON OPEN ERROR CLR WFLAG ;USE WUMPUS FLAG AS PAGE COUNTER 10$: GET$S #FDB ;GET A RECORD FROM THE FILE BCS 20$ ;ERROR SHOULD BE EOF MOV F.NRBD(R0),R1 ;GET RECORD SIZE MOV #TTYBUF,R0 ;RECORD ADDRESS CALL MESOUT ;TYPE THE LINE OUT INC WFLAG ;ADD UP 1 MORE LINE BIT #17,WFLAG ;CHECK FOR A PAGE OF STUFF BNE 10$ ;BR IF WE NEED MORE CALL GETSTR ;OTHERWISE WAIT FOR A CR BR 10$ ;GO GET MORE HELP STUFF 20$: CMPB F.ERR(R0),#IE.EOF ;IS THE ERROR END OF FILE BNE 30$ ;BR IF NOT CLOSE$ ;CLOSE THE FILE BR 50$ ;BR TO COMMON EXIT 30$: CLOSE$ ;CLOSE THE FILE NOW 40$: MOV #MESG21,R0 ;GET ERROR MESSAGE ADDRESS CALL PUTMES ;TYPE OUT THE ERROR 50$: RETURN ;THEN RETURN .END .WUMP