Compucolor.org – Virtual Media

Listing of file='MAZEG1.SRC;01' on disk='vmedia/mazes_2-sector.ccvf'

;MAZE:	THIS PROGRAM GENERATES A 63 X 31 MAZE THEN THE
;	USE IS ABLE TO TRAVEL THROUGH IT EITHER FROM THE
;	HUMAN POINT OF VIEW (TOP) OR A RATS POINT OF VIEW.

;					GREG ALLEN  7/17/81

;V2.1	THIS VERSION HAS A NEW (AND HOPEFULLY IMPROVED) INPUT
;	ROUTINE.

BASOUT		EQU	33H
OUTSTRING	EQU	33F4H
DIVDEBYHL	EQU	3581H

MAZE		EQU	9700H

INITINPUT	EQU	8F10H
RESTOREINPUT	EQU	8F42H
GETCHAR		EQU	8F81H

FIXWALLS	EQU	8A1DH
PRINTWALL	EQU	8AA2H

CLEARSCREEN	EQU	12

		ORG	8200H
START:		LXI	H,0
		DAD	SP
		SHLD	FCSSP

		CALL	INITINPUT

SETUPMAZE:	LHLD	MAXMEMORY
		SPHL

		MVI	A,CLEARSCREEN
		CALL	BASOUT

		CALL	FIXWALLS

		MVI	A,8
		MVI	B,16
		LXI	H,MAZE		;SET THE MAZE = 16
		LXI	D,0
LOOP:		MOV	M,B		;MAZE(HL)=B
		INX	H
		INX	D		;I=I+1
		CMP	D		;IF DE = 800H
		JNZ	LOOP		;DO UNTIL DE=800H

		CALL	INITSEED	;INITIALIZE RND SEED
		CALL	REPLOT		;PRINT THE INIT SETUP

		;GET THE INITIAL STARTING SPOT
FINDINITX:	CALL	RANDOMIZE
		LDA	SEED+1
		ANI	00111111B
		CPI	XBORDER
		JP	FINDINITX
		STA	XCOR
		MOV	B,A

FINDINITY:	CALL	RANDOMIZE
		LDA	SEED+2
		ANI	00011111B
		CPI	YBORDER
		JP	FINDINITY
		STA	YCOR
		MOV	C,A

		CALL	DETABSPOS
		MVI	M,0

		CALL	RANDOMIZE
		LDA	SEED+3
		ANI	11B
		MOV	D,A

		;NOW HL-> MAZE(INIT X,INIT Y)
		;B=X=INIT X
		;C=Y=INIT Y
		;D=INIT DI
		;A & E ARE GARBAGE
		;MAZE(INIT X,INIT Y) = 0

		PUSH	D
		PUSH	H

CHECKAROUND:	MVI	E,11100100B	;FOR I=0 TO I:DI(I)=3

		MOV	A,D
		XRI	10B		;REVERSE DI 00->10 ETC
		MOV	D,A

		CALL	RANDOMIZEDI

SEARCH:		MOV	A,E
		RRC
		RRC
		MOV	E,A

		ANI	11B		;DI = NEW DIRECTION
		CMP	D		;  THEN ALL SEARCHED
		JZ	DONESEARCH

		PUSH	D
		MOV	D,A
		PUSH	H
		SHLD	TEMPHL		;SAVE ADDR. OF CURRENT

		LXI	H,DELTAX
LOOP1:		DCR	A		;DETERMINE DELTA X(DI)
		JM	END1
		INX	H
		JMP	LOOP1

END1:		MOV	A,M		;X=X+DELTAX(DI)
		ADD	B		;IF NEW X<0
		JM	NEXTI		;   THEN OFF BOARD
		CPI	XBORDER		;IF X >= XBORDER
		JP	NEXTI		;   THEN OFF BOARD
		MOV	B,A		;X = NEW X

		MOV	A,D
		LXI	H,DELTAY	;NOW CHECK THE NEW Y
LOOP2:		DCR	A		;DETERMINE DELTA_Y(DI)
		JM	END2
		INX	H
		JMP	LOOP2

END2:		MOV	A,M
		ADD	C		;IF NEW Y<0
		JM	NEXTI		;   THEN OFF BOARD
		CPI	YBORDER		;IF Y >= YBORDER
		JP	NEXTI		;   THEN OFF BOARD
		MOV	C,A		;Y = NEW Y

					;CALC THE OFFSET IN
		RRC			; MAZE FOR THE NEW X,Y.
		RRC
		MOV	H,A		;NEW HL = MAZE+Y*64+X
		ANI	11000000B
		ORA	B		;CONCAT THE 2 LSBITS OF
		MOV	L,A		;OF Y TO X IN L
		MOV	A,H		;THE 3 MSBITS OF Y GO
		ANI	111B		;GO IN H
		MOV	H,A

		PUSH	B
		LXI	B,MAZE		;HL = MAZE + OFFSET
		DAD	B
		POP	B

		MOV	A,M		;IF MAZE(X,Y) <> 16
		CPI	16		;  THEN NOT NEW
		JNZ	NEXTI		;       TRY NEW DIR

		PUSH	H		;MAZE(HL) IS FREE
		MVI	M,0		;MARK MAZE(X,Y) AS USED
		LXI	H,DIBTAB	;FIX WALL
		MOV	A,D
		RLC			;ACC=2*DI
		ADD	L		;BTAB(DI)
		MOV	L,A
		JNC	READY
		INR	H
READY:		PUSH	D
		MOV	E,M
		INX	H
		MOV	D,M
		XCHG
		POP	D
		PCHL

DIBTAB:		DW	CASE0
		DW	CASE1
		DW	CASE2
		DW	CASE3

CASE0:					;REMOVE RIGHT WALL
		LHLD	TEMPHL		;RESTORE THE CURRENT HL
		INR	M		;MAZE(HL)=MAZE(HL)+2
		INR	M
		CALL	CALCXY		;GET THE XY POSI FOR HL
		MVI	A,BLUE		;COLOR IT BLUE
		CALL	ADDCOLOR
		CALL	PRINTSPOT	;PRINT THE UPDATED SPOT
		POP	H
		CALL	CALCXY
		JMP	ENDCASEDI

CASE1:		LHLD	TEMPHL
		INR	M		;SAME AS CASE0 EXCEPT
					; MAZE(X,Y)=MAZE(X,Y)+1
		CALL	CALCXY
		MVI	A,BLUE
		CALL	ADDCOLOR
		CALL	PRINTSPOT
		POP	H
		CALL	CALCXY
		JMP	ENDCASEDI

CASE2:		POP	H
		INR	M		;MAZE(NEW XY)=MAZE+2
		INR	M
		MVI	A,BLUE
		CALL	ADDCOLOR
		CALL	PRINTSPOT
		JMP	ENDCASEDI

CASE3:		POP	H
		INR	M		;MAZE(NEW XY)=MAZE+1
		MVI	A,BLUE
		CALL	ADDCOLOR
		CALL	PRINTSPOT

ENDCASEDI:	JMP	CHECKAROUND	;SP -> HL
					;      DE

NEXTI:		POP	H
		POP	D
		CALL	CALCXY
		JMP	SEARCH

DONESEARCH:	MVI	A,BLACK
		CALL	ADDCOLOR
		CALL	PRINTSPOT
		XRA	A
		POP	H
		CALL	CALCXY
		POP	D
		CMP	E
		JNZ	SEARCH

;HOPEFULLY THE MAZE HAS BEEN EXPLORED AND THE SP POINTS TO
; THE RETURN ADDRESS
		LXI	H,XCOR
		MVI	M,XBORDER-1
		INX	H
		MVI	M,YBORDER-1
		CALL	DETABSPOS
		;HL SHOULD NOW POINT TO THE LOWWER RIGHT CORNER.
		MVI	M,1		;REMOVE THE BOTTOM WALL

		CALL	REPLOT

		JMP	MOVEAROUND

FINI:		CALL	RESTOREINPUT

		LHLD	FCSSP
		SPHL
		LXI	H,POSSCUR
		CALL	OUTSTRING
		RET

;SUBROUTINES

PRINTSPOT2:	;FOR TIME WHEN B,C OR HL ARE SET
		;A - SCRATCH
		;B - IS ASSIGNED THE X COORDINATE FROM XCOR
		;C - IS ASSIGNED THE Y COORDINATE FROM YCOR
		;DE - UNUSED
		;HL - IS ASSIGNED TO -> MAZE(X,Y) FROM ABSPOS

		PUSH	PSW
		PUSH	B
		PUSH	H

		LXI	H,XCOR
		MOV	B,M
		INX	H
		MOV	C,M
		LHLD	ABSPOS
		CALL	PRINTSPOT

		POP	H
		POP	B
		POP	PSW
		RET


PRINTSPOT:	;A  - SCRATCH
		;B  - X COORDINATE
		;C  - Y COORDINATE
		;DE - UNUSED
		;HL -> MAZE(X,Y)

		PUSH	B
		PUSH	H

		MOV	A,M		;DETERMINE THE COLOR
		ANI	11100000B
		RRC
		RRC
		ORI	6
		STA	SPOTCOLOR

		MOV	A,M
		ANI	11B
		LXI	H,WALLCHAR-1
PRTLOOP:	INX	H	;DETERMINE THE WALL CHARACTER
		DCR	A
		JP	PRTLOOP

END3:		MOV	A,M
		STA	SPOTCHAR

		LXI	H,SPOTXCOR
		MOV	M,B		;X COORDINATE = X
		INR	M
		INX	H
		MOV	M,C		;Y COORDINATE = Y
		INR	M

		LXI	H,PRTSPOT	;PRINT THE SPOT
		CALL	OUTSTRING

		POP	H
		POP	B
		RET

PRINTHL:	DS	2
CALCFLAG:	DS	1
PRTSPOT:	DB	6
SPOTCOLOR:	DS	1
		DB	30
		DB	3
SPOTXCOR:	DS	1
SPOTYCOR:	DS	1
SPOTCHAR:	DS	1
		DB	29
		DB	239

;COLORS TO GO IN THE 3 MSB OF MAZE(X,Y)
;ADD COLOR TAKES CARE OF THE SHIFTING

BLACK		EQU	0
RED		EQU	1
GREEN		EQU	2
YELLOW		EQU	3
BLUE		EQU	4
MAGENTA		EQU	5
CYAN		EQU	6
WHITE		EQU	7

WALLCHAR:	DB	109,98,127,32


INITSEED:	;A - SCRATCH
		;H - ADDRESING SEED AND TIME
TIMEADDR	EQU	33208

		PUSH	PSW		;PRESERVE REGS USED
		PUSH	H

		LXI	H,TIMEADDR	;HL->MILLISECS
		XRA	M		;ALSO USE GARBAGE IN A
		RLC
		RLC			;SINCE TIME IS ONLY
		RLC			;4 BITS LONG, SHFT TO
		RLC			;RANDOMNESS
		INX	H		;HL->SECS
		XRA	M
		INX	H		;HL->MINUTES
		XRA	M
		LXI	H,SEED		;STORE NEW SEED(O SEED)
		XRA	M
		XRI	MASK1
		MOV	M,A
		INX	H	;2ND BYTE
		XRA	M
		XRI	MASK2
		MOV	M,A
		INX	H	;3RD BYTE
		XRA	M
		XRI	MASK3
		MOV	M,A
		INX	H	;4TH BYTE
		XRA	M
		XRI	MASK4
		MOV	M,A

		POP	H	;DONE
		POP	PSW
		RET

RANDOMIZEDI:	;A - SCRATCH
		;B - THE TEMPORARY DIRECTION
		;	DI 1ST; RND(3)-1 2ND; RND(2)-1 3RD;
		;D - DIRECTION PASSED TO ROUTINE
		;E - THE LIST OF DIRECTIONS
		;	INPUT AS '11 10 01 00'B
		;	OUTPUT AS 'RD(3) RD(2) RD(1) DI'
				;WHERE RD(N)<>DI
		;HL NOT USED

		PUSH	PSW
		PUSH	B

		MOV	B,D		;1ST DI
		CALL	RND1ELEMENT

GET2NDDI:	CALL	RANDOMIZE	;SEED=RND(SEED)
		LDA	SEED+1
		ANI	11B		;RD(1) MUST BE < 3
		JZ	GET2NDDI	;IF RD(1) < 3
					; THEN TRY AGAIN
		DCR	A
		MOV	B,A
		CALL	RND1ELEMENT

		CALL	RANDOMIZE	;SEED=RND(SEED)
		LDA	SEED+2
		ANI	1B		;RD(2)= 1 OR 0
		MOV	B,A
		CALL	RND1ELEMENT

		MOV	A,E		;RD(3) IS FINE
		RRC
		RRC			;CORRECT E'S FORMAT
		MOV	E,A		;  FOR RETURN

		POP	B		;RESTORE REGS
		POP	PSW
		RET

RND1ELEMENT:	;A - SCRATCH
		;B - COUNTER (PASSED FROM CALLING ROUTINE
		;C - ANTI COUNT (GENERATED)
		;D - NOT CHANGED
		;E - DIRECTION LIST	F(N)=FILED; NF=NOTFILED
		;			DI=START DI; B=COUNT
		;	IN E = 'F1 DI B FN' FILED=EXTRACTED
		;	OUT E= 'F2 F1 DI FN'
		;HL - TEMP STORAGE

		PUSH	PSW
		PUSH	B
		PUSH	H

		MOV	A,E	;PLACE IN IN THE WORK AREA
		DCR	B	;IF COUNT = 0
		JM	DONEORDER	;THEN RETURN

		MOV	C,B
		ANI	11B	;SAVE THE DIRECTION BEING
		MOV	H,A	;   REPLACED
		MOV	A,E

SHIFTAGAIN:	RRC		;SHIFT OVER TILL THE DIRECTION
		RRC		;POINTED TO BY B IS REACHED.
		DCR	B
		JP	SHIFTAGAIN

		MOV	L,A	;THE DIRECTION HAS BEEN FOUND
				;SAVE IT IN L (UNEXTRACTED)
		ANI	11111100B
		ORA	H	;PLACE H IN THE UNTOUCHED SECT.

SHIFTBACK:	RLC		;SHIFT BACK INTO POSITION
		RLC
		DCR	C	;USING THE ANTI COUNTER
		JP	SHIFTBACK

		ANI	11111100B	;MAKE ROOM FOR DI(B)
		MOV	E,A
		MOV	A,L
		ANI	11B	;EXTRACT DI(B)
		ORA	E	;AND PUT IT IN THE LIST

DONEORDER:	RRC		;THE DIRECTION HAS BEEN
		RRC		;REPOSITIONED NOW PUT THE LIST
		MOV	E,A	;IN THE PROPER ORIENTATION
				;MOVE THE RESULTS TO E
		POP	H
		POP	B	;RESTORE THE MACHINE
		POP	PSW
		RET

RANDOMIZE:	;A - SCRATCH
		;B - USED TO ADDRESS SEED
		;B - USED FOR A COUNTER
		;HL- USED TO ADDRESS SEED
MASK1		EQU	11011101B
MASK2		EQU	11111111B
MASK3		EQU	01010101B
MASK4		EQU	MASK2

		PUSH	PSW
		PUSH	B
		PUSH	D
		PUSH	H

		MVI	B,3
		LXI	H,SEED+3
		MOV	A,M
		XRI	10000000B    ;MAKE SURE SEED<>0 FOREVER
RNDLOOP1:	RAL		;SHIFT SEED LEFT 1 PLACE
		MOV	M,A
		DCX	H
		DCR	B
		JNZ	RNDLOOP1

		MOV	A,M
		RAL
		MOV	M,A
		JNC	DONERND

		MVI	B,4	;IF CARRY WAS SET
				;   THEN FLIP THE BITS
		LXI	D,MASKLIST
RNDLOOP2:	MOV	A,M	;A=SEED(4-1)
		XCHG
		XRA	M	;A = XR(A,MASK(B))
		XCHG
		MOV	M,A
		INX	H
		INX	D
		DCR	B
		JNZ	RNDLOOP2

DONERND:	POP	H
		POP	D
		POP	B
		POP	PSW
		RET
MASKLIST:	DB	MASK1,MASK2,MASK3,MASK4


REPLOT:		PUSH	PSW
		PUSH	B
		PUSH	D
		PUSH	H

		LXI	H,TOPWALL
		MVI	C,-1
		MVI	B,1
CONTTOP:	MOV	A,B
		CPI	XBORDER
		JP	PRTLEFT
		CALL	PRINTSPOT
		INR	B
		JMP	CONTTOP

PRTLEFT:	LXI	H,LEFTWALL
		MVI	B,-1
		MVI	C,0
CONTLEFT:	MOV	A,C
		CPI	YBORDER
		JP	PRTMAZE
		CALL	PRINTSPOT
		INR	C
		JMP	CONTLEFT

PRTMAZE:	LXI	H,MAZE
		MVI	D,64-XBORDER	;THE DIFF BETWEEN XMAX
					;  AND XBORDER
		MVI	C,0
		MOV	B,C
CONTPRT:	CALL	PRINTSPOT
		INX	H
		INR	B
		MOV	A,B
		CPI	XBORDER
		JM	CONTPRT
		MOV	A,L		;FIX THE HL POINTER
		ADD	D
		MOV	L,A
		MOV	A,H
		ACI	0
		MOV	H,A
		MVI	B,0
		INR	C
		MOV	A,C
		CPI	YBORDER
		JM	CONTPRT

		LXI	H,POSSCUR
		CALL	OUTSTRING

		POP	H
		POP	D
		POP	B
		POP	PSW
		RET

TOPWALL:	DB	2
LEFTWALL:	DB	1

;STORAGE AREAS
MAXMEMORY	EQU	32940
FCSSP:		DS	2
TEMPHL:		DS	2

CALCXY:		;A - SCRATCH
		;BC - WILL CONTAIN THE RETURNED VALUES OF X & Y
		;DE - USED IN DIVIDE
		;HL - POINTS TO THE ABSOLUTE ADR IN MAZE

		PUSH	PSW
		PUSH	D
		PUSH	H

		LXI	D,MAZE
		MOV	A,L
		SUB	E
		MOV	L,A
		MOV	A,H
		SBB	D
		MOV	H,A
		XCHG
		LXI	H,64
		CALL	DIVDEBYHL
		MOV	B,E	;THE REMAINDER IS X
		MOV	C,L	;THE QUOTIENT IS Y

		POP	H
		POP	D
		POP	PSW
		RET

ADDCOLOR:	;A - IS THE INPUT COLOR
		;BC - UNUSED
		;D - IS USED AS TEMP STORAGE
		;E - UNUSED
		;HL -USED FOR ADDRESSING

		PUSH	PSW
		PUSH	D

		RRC
		RRC		;PLACE THE COLOR IN THE 3 MSB'S
		RRC
		MOV	D,A
		MOV	A,M
		ANI	11111B	;REMOVE THE OLD COLOR
		ORA	D	;ADD THE NEW
		MOV	M,A

		POP	D
		POP	PSW
		RET

;THESE FOLLOWING ROUTINES ARE FOR MOVING IN THE MAZE

KEYBRDCHAR	EQU	33278
ONESEC		EQU	-1

CMDPROMPT:	DB	27,24,6,2,3,0,31,11,'CMD>',239
BANGMESS:	DB	6,5,3,0,31,11,'OUCH!  BANGED A WALL',239
INVCMDMESS:	DB	6,1,3,0,31,11,'INVALID COMMAND.',239

XCOR:		DS	1
YCOR:		DS	1
ABSPOS:		DS	2
COLOR:		DS	1

MOVEAROUND:	PUSH	PSW
		PUSH	B
		PUSH	D
		PUSH	H

		;INITIALIZE VARIOUS THINGS
		XRA	A
		STA	XCOR	;X=0:Y=0:COLOR=RED
		STA	YCOR
		LXI	H,MAZE	;ABSPOS -> MAZE(0,0)
		SHLD	ABSPOS
		MVI	A,RED
		STA	COLOR
		CALL	ADDCOLOR
TOPVIEW:	CALL	PRINTSPOT2

GETCMD:		LXI	H,CMDPROMPT	;PRINT PROMPT
		CALL	OUTSTRING
		CALL	GETCHAR		;A RETURNS WITH INP CHAR
		CPI	29
		JM	CMDELSE1
CMDINVALID:	CALL	INVCMD
		JMP	GETCMD

CMDELSE1:	SUI	8
		JM	CMDINVALID

		;THE COMMAND IS IN THE CORRECT RANGE(0-(28-8)).
		;NOW PROCESS IT
		LXI	H,MOVEBT	;HL->BT & ACC=OFFSET
		CALL	USEBT
		JMP	GETCMD


USEBT:		;THIS ROUTINE SIMULATES A BRANCH TABLE CALL!
		;A ROUTINE CALLS THIS ONE AND THE ROUTINE IS
		;FOUND AND JMPED TO.  THAT ROUTINE MERELY HAS
		;TO RET TO RETURN TO THE SPOT THAT CALLED
		;USEDBT.  UP TO 127 ROUNTINES IN THE BT.

		;ACC = BRANCH TABLE OFFSET
		;HL -> BT
		;DE - USED INTERNALLY FOR ADDRESSING
		;BC - NOT USED
		;** NOTE  **  HL IS NOT RECOVERED

		PUSH	PSW
		PUSH	D

		RLC		;ACC = ACC*2 (ADDRESS OFFSET)
		LXI	D,0
		MOV	E,A	;DE = ADDRESS OFFSET
		DAD	D

		;NOW HL->THEN ADDRESS OF THE SUBROUTINE
			;LOW ADDR, HIGH ADDR
		MOV	E,M
		INX	H
		MOV	D,M
		XCHG		;HL-> DESIRED SUBROUTINE
		POP	D	;RESTORE WHAT CAN BE SAVED
		POP	PSW
		PCHL		;'CALL' THE SUBROUTINE



MOVEBT:		;ASSUME 0 <= ACC <= (28-8)
		DW	INVCMD		;8 - HOME
		DW	SETUPMAZE	;9 - TAB
		DW	MOVEDOWN	;10 - LINEFEED
		DW	INVCMD		;11
		DW	REPLOT		;12 - ERASE PAGE
		DW	RATSVIEW	;13 - RETURN
		DW	INVCMD		;14
		DW	INVCMD		;15
		DW	CHANGECOLOR	;16 - BLACK
		DW	CHANGECOLOR	;17 - RED
		DW	CHANGECOLOR	;18 - GREEN
		DW	CHANGECOLOR	;19 - YELLOW
		DW	CHANGECOLOR	;20 - BLUE
		DW	CHANGECOLOR	;21 - MAGENTA
		DW	CHANGECOLOR	;22 - CYAN
		DW	CHANGECOLOR	;23 - WHITE
		DW	INVCMD		;24
		DW	MOVERIGHT	;25 - ->
		DW	MOVELEFT	;26 - <-
		DW	FINI		;27 - ESC
		DW	MOVEUP		;28 - CURSOR UP


MOVEDOWN:	;IF POSSIBLE THE Y-COORD IS INCREMENTED AND
		;A NEW ABSPOS IS DETERMINED.

		;A - SCRATCH
		;BC & DE - UNUSED
		;HL - USED INTERNALLY FOR ADDRESSING

		PUSH	PSW
		PUSH	H

		LHLD	ABSPOS
		MOV	A,M
		ANI	1B
		JNZ	DWNELSE1
		CALL	BANGEDWALL
		JMP	DWNDONE

DWNELSE1:	LXI	H,YCOR
		INR	M
		CALL	DETABSPOS
		SHLD	ABSPOS
		LDA	COLOR
		CALL	ADDCOLOR
		CALL	PRINTSPOT2

DWNDONE:	POP	H
		POP	PSW
		RET


MOVEUP:		;THIS TIME DCR Y

		;A - SCRATCH
		;BC & DE - UNUSED
		;HL - USED INTERNALLY FOR ADDRESSING

		PUSH	PSW
		PUSH	H

		LXI	H,YCOR
		DCR	M
		JM	CANTGOUP
		CALL	DETABSPOS	;HL -> MAZE(X,Y-1)
		MOV	A,M
		ANI	1B
		JNZ	UPELSE1

		LXI	H,YCOR
CANTGOUP:	INR	M	;RESTORE THE Y COORDINATE
		CALL	BANGEDWALL
		JMP	UPDONE

UPELSE1:	;MOVE OK
		SHLD	ABSPOS
		LDA	COLOR
		CALL	ADDCOLOR
		CALL	PRINTSPOT2

UPDONE:		POP	H
		POP	PSW
		RET


MOVERIGHT:	;A - SCRATCH
		;BC & DE UNUSED
		;HL - USED INTERNALLY FOR ADDRESSING

		PUSH	PSW
		PUSH	H

		LHLD	ABSPOS
		MOV	A,M
		ANI	10B
		JNZ	RTELSE1

		CALL	BANGEDWALL
		JMP	RTDONE

RTELSE1:	INX	H	;HL -> MAZE(X+1,Y)
		SHLD	ABSPOS	;ABSPOS -> MAZE(X+1,Y)
		LDA	XCOR
		INR	A	;X=X+1
		STA	XCOR
		LDA	COLOR
		CALL	ADDCOLOR
		CALL	PRINTSPOT2

RTDONE:		POP	H
		POP	PSW
		RET


MOVELEFT:	;A - SCRATCH
		;BC & DE UNUSED
		;HL - USED INTERNALLY FOR ADDRESSING

		PUSH	PSW
		PUSH	H

		LXI	H,XCOR
		DCR	M
		JM	CANTGOLEFT

		CALL	DETABSPOS
		MOV	A,M
		ANI	10B
		JNZ	LFTELSE

		LXI	H,XCOR
CANTGOLEFT:	INR	M	;RESTORE X
		CALL	BANGEDWALL
		JMP	LFTDONE

LFTELSE:	SHLD	ABSPOS	;ABSPOS -> MAZE(X-1,Y)
		LDA	COLOR
		CALL	ADDCOLOR
		CALL	PRINTSPOT2

LFTDONE:	POP	H
		POP	PSW
		RET


CHANGECOLOR:	;ACC = DESIRED COLOR + 8
		;BC & DE NOT USED
		;HL - USED INTERNALLY FOR ADDRESSING

		PUSH	PSW
		PUSH	H

		SUI	8
		STA	COLOR
		LHLD	ABSPOS
		CALL	ADDCOLOR
		CALL	PRINTSPOT2

		POP	H
		POP	PSW
		RET


INVCMD:		PUSH	PSW	;SAVE STATUS
		PUSH	H

		LXI	H,INVCMDMESS
		CALL	OUTSTRING
		MVI	A,1
		CALL	STALL

		POP	H
		POP	PSW
		RET


BANGEDWALL:	PUSH	PSW
		PUSH	H

		LXI	H,BANGMESS
		CALL	OUTSTRING
		MVI	A,1
		CALL	STALL

		POP	H
		POP	PSW
		RET


STALL:		;ACC - # OF SECONDS TO STALL
		;B - KEEPS A INTERNALLY
		;C - UNUSED
		;DE - USED TO COUNT FOR A PSUEDO SECOND
		;HL - GET A BREAK FOR A CHANGE

		PUSH	PSW
		PUSH	B
		PUSH	D

		MOV	B,A
SECONDCOUNTER:	DCR	B
		JM	DONESTALL

		LXI	D,ONESEC
INNERCOUNTER:	DCX	D
		NOP
		MOV	A,D
		CPI	0
		JNZ	INNERCOUNTER

		MOV	A,E
		CPI	0
		JNZ	INNERCOUNTER

		JMP	SECONDCOUNTER

DONESTALL:	POP	D
		POP	B
		POP	PSW
		RET


DETABSPOS:	;XCOR HOLDS THE X COORDINATE
		;YCOR HOLDS THE Y COORDINATE
		;FROM THESE CALCULATE ABSPOS AND STORE IN HL.

		;A - SCRATCH
		;B - TEMPERARALY HOLDS THE X COORDINATE
		;C - LIKE WISE HOLDS THE Y COORDINATE
		;DE - UNUSED
		;HL - IS RETURNED WITH THE VALUE OF ABSPOS

		PUSH	PSW
		PUSH	B

		LDA	YCOR
		RRC
		RRC
		MOV	B,A
		ANI	11000000B
		LXI	H,XCOR
		ORA	M
		MOV	C,A
		MOV	A,B
		ANI	111B
		MOV	B,A
		LXI	H,MAZE
		DAD	B

		POP	B
		POP	PSW
		RET

RATSVIEW:	;A  - SCRATCH
		;BC - THE X & Y COORDINATES
		;DE - UNUSED
		;HL - MISC. ADDRESSING

		XRA	A
		STA	DEPTH
		STA	DIRECTION

MOVERAT:	LXI	H,SETRATSVIEW
		CALL	OUTSTRING
		LXI	H,XCOR
		MOV	B,M
		INX	H
		MOV	C,M
		LDA	DIRECTION
		LXI	H,VIEWBT
		CALL	USEBT

		LXI	H,CMDPROMPT
		CALL	OUTSTRING
		CALL	GETCHAR

		CPI	29
		JP	RATCMDINVALID
		SUI	8
		JM	RATCMDINVALID
		LXI	H,RATCMDBT
		CALL	USEBT
		JMP	MOVERAT

RATCMDINVALID:	CALL	INVCMD
		JMP	MOVERAT

NORTHVIEW:	PUSH	H
		LXI	H,DEPTH
		INR	M
		CALL	CHECKNC1
		CALL	CHECKNL1
		CALL	CHECKNR1
		DCR	M
		POP	H
		RET

EASTVIEW:	PUSH	H

		LXI	H,DEPTH
		INR	M
		CALL	CHECKEC1
		CALL	CHECKEL1
		CALL	CHECKER1
		DCR	M

		POP	H
		RET

SOUTHVIEW:	PUSH	H

		LXI	H,DEPTH
		INR	M
		CALL	CHECKSC1
		CALL	CHECKSL1
		CALL	CHECKSR1
		DCR	M

		POP	H
		RET

WESTVIEW:	PUSH	H

		LXI	H,DEPTH
		INR	M
		CALL	CHECKWC1
		CALL	CHECKWL1
		CALL	CHECKWR1
		DCR	M

		POP	H
		RET

CHECKNC1:	PUSH	PSW
		PUSH	B

		DCR	C	;Y=Y-1
		MVI	A,SOUTHWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTC1
		CP	C1OPEN

		POP	B
		POP	PSW
		RET

CHECKEC1:	PUSH	PSW
		PUSH	B

		;X & Y OK
		MVI	A,EASTWALL
		CALL	GETWALL
		CPI	1
		JP	EC1ELSE
		CALL	PRINTC1
		JMP	EC1DONE

EC1ELSE:	INR	B
		CALL	C1OPEN

EC1DONE:	POP	B
		POP	PSW
		RET


CHECKSC1:	PUSH	PSW
		PUSH	B

		;X & Y OK
		MVI	A,SOUTHWALL
		CALL	GETWALL
		CPI	1
		JP	SC1ELSE
		CALL	PRINTC1
		JMP	SC1DONE

SC1ELSE:	INR	C
		CALL	C1OPEN

SC1DONE:	POP	B
		POP	PSW
		RET

CHECKWC1:	PUSH	PSW
		PUSH	B

		DCR	B	;X=X-1
		MVI	A,EASTWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTC1
		CP	C1OPEN

		POP	B
		POP	PSW
		RET

C1OPEN:		PUSH	PSW
		PUSH	H

		LDA	DEPTH
		CPI	3
		JP	C1DONE

		LDA	DIRECTION
		LXI	H,VIEWBT
		CALL	USEBT

C1DONE:		POP	H
		POP	PSW
		RET

CHECKNL1:	PUSH	PSW
		PUSH	B

		DCR	B
		MVI	A,EASTWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTL1
		CP	NL1OPEN

		POP	B
		POP	PSW
		RET

NL1OPEN:	PUSH	PSW
		PUSH	B

		DCR	C
		MVI	A,SOUTHWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTL2
		;ELSE LEAVE OPEN

		POP	B
		POP	PSW
		RET

CHECKEL1:	PUSH	PSW
		PUSH	B

		DCR	C	;Y=Y-1
		MVI	A,SOUTHWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTL1
		CP	EL1OPEN

		POP	B
		POP	PSW
		RET

EL1OPEN:	PUSH	PSW

		;XY OK
		MVI	A,EASTWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTL2
		;ELSE LEAVE OPEN

		POP	PSW
		RET

CHECKSL1:	PUSH	PSW

		;XY OK
		MVI	A,EASTWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTL1
		CP	SL1OPEN

		POP	PSW
		RET

SL1OPEN:	PUSH	PSW
		PUSH	B

		INR	B	;X=X+1
		MVI	A,SOUTHWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTL2
		;ELSE LEAVE OPEN

		POP	B
		POP	PSW
		RET

CHECKWL1:	PUSH	PSW

		;XY OK
		MVI	A,SOUTHWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTL1
		CP	WL1OPEN

		POP	PSW
		RET

WL1OPEN:	PUSH	PSW
		PUSH	B

		DCR	B	;X=X-1
		INR	C	;Y=Y+1
		MVI	A,EASTWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTL2

		POP	B
		POP	PSW
		RET

CHECKNR1:	PUSH	PSW

		;XY OK
		MVI	A,EASTWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTR1
		CP	NR1OPEN

		POP	PSW
		RET

NR1OPEN:	PUSH	PSW
		PUSH	B

		INR	B	;X=X+1
		DCR	C	;Y=Y-1
		MVI	A,SOUTHWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTR2

		POP	B
		POP	PSW
		RET

CHECKER1:	PUSH	PSW

		;XY OK
		MVI	A,SOUTHWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTR1
		CP	ER1OPEN

		POP	PSW
		RET

ER1OPEN:	PUSH	PSW
		PUSH	B

		INR	C
		MVI	A,EASTWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTR2

		POP	B
		POP	PSW
		RET

CHECKSR1:	PUSH	PSW
		PUSH	B

		DCR	B
		MVI	A,EASTWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTR1
		CP	SR1OPEN

		POP	B
		POP	PSW
		RET

SR1OPEN:	PUSH	PSW

		MVI	A,SOUTHWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTR2

		POP	PSW
		RET

CHECKWR1:	PUSH	PSW
		PUSH	B

		DCR	C
		MVI	A,SOUTHWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTR1
		CP	WR1OPEN

		POP	B
		POP	PSW
		RET

WR1OPEN:	PUSH	PSW
		PUSH	B

		DCR	B
		MVI	A,EASTWALL
		CALL	GETWALL
		CPI	1
		CM	PRINTR2

		POP	B
		POP	PSW
		RET

GETWALL:	PUSH	B
		PUSH	D
		PUSH	H

		MOV	D,A
		MOV	A,B
		CPI	0
		JM	OFFBOARD
		CPI	XBORDER
		JP	OFFBOARD
		MOV	A,C
		CPI	0
		JM	OFFBOARD
		CPI	YBORDER
		JP	OFFBOARD

		MOV	A,D

		LXI	H,XCOR
		MOV	D,M
		MOV	M,B
		INX	H
		MOV	E,M
		MOV	M,C
		CALL	DETABSPOS
		CPI	SOUTHWALL
		JZ	FIXSOUTH
		MOV	A,M
		ANI	10B
		RRC
		JMP	DONEWALL

FIXSOUTH:	MOV	A,M
		ANI	1B
		JMP	DONEWALL

OFFBOARD:	XRA	A
		JMP	WALLDETERED

DONEWALL:	LXI	H,XCOR
		MOV	M,D
		INX	H
		MOV	M,E

WALLDETERED:	POP	H
		POP	D
		POP	B
		RET

C1W		EQU	0
L1W		EQU	1
L2W		EQU	2
R1W		EQU	3
R2W		EQU	4

PRINTC1:	PUSH	PSW
		MVI	A,C1W
		CALL	PRINTWALL
		POP	PSW
		RET

PRINTL1:	PUSH	PSW
		MVI	A,L1W
		CALL	PRINTWALL
		POP	PSW
		RET

PRINTL2:	PUSH	PSW
		MVI	A,L2W
		CALL	PRINTWALL
		POP	PSW
		RET

PRINTR1:	PUSH	PSW
		MVI	A,R1W
		CALL	PRINTWALL
		POP	PSW
		RET

PRINTR2:	PUSH	PSW
		MVI	A,R2W
		CALL	PRINTWALL
		POP	PSW
		RET

DEPTH		EQU	96FFH
DIRECTION:	DS	1

SOUTHWALL	EQU	1
EASTWALL	EQU	0

RATCMDBT:	;ASSUME 0<= ACC <= (28-8)
		DW	INVCMD		;8 - HOME
		DW	SETUPMAZE	;9 - TAB
		DW	TURNAROUND	;10 - LINEFEED
		DW	INVCMD		;11
		DW	INVCMD		;12 - ERASE PAGE
		DW	TOPVIEW		;13 - RETURN
		DW	INVCMD		;14
		DW	INVCMD		;15
		DW	CHANGECOLOR	;16 - BLACK
		DW	CHANGECOLOR	;17 - RED
		DW	CHANGECOLOR	;18 - GREEN
		DW	CHANGECOLOR	;19 - YELLOW
		DW	CHANGECOLOR	;20 - BLUE
		DW	CHANGECOLOR	;21 - MAGENTA
		DW	CHANGECOLOR	;22 - CYAN
		DW	CHANGECOLOR	;23 - WHITE
		DW	INVCMD		;24
		DW	TURNRIGHT	;25
		DW	TURNLEFT	;26
		DW	FINI		;27 - ESC
		DW	MOVEAHEAD	;28 - CURSOR UP


TURNAROUND:	PUSH	PSW
		LDA	DIRECTION
		ADI	2
		ANI	11B
		STA	DIRECTION
		POP	PSW
		RET

TURNRIGHT:	PUSH	PSW
		LDA	DIRECTION
		ADI	1
		ANI	11B
		STA	DIRECTION
		POP	PSW
		RET

TURNLEFT:	PUSH	PSW
		LDA	DIRECTION
		SUI	1
		ANI	11B
		STA	DIRECTION
		POP	PSW
		RET

MOVEAHEAD: 	PUSH	PSW
		PUSH	H

		LDA	DIRECTION
		LXI	H,AHEADBT
		CALL	USEBT

		POP	H
		POP	PSW
		RET

AHEADBT:	DW	MOVEUP
		DW	MOVERIGHT
		DW	MOVEDOWN
		DW	MOVELEFT

VIEWBT:		DW	NORTHVIEW
		DW	EASTVIEW
		DW	SOUTHVIEW
		DW	WESTVIEW

DELTAX:		DB	1,0,-1,0
DELTAY:		DB	0,1,0,-1
XBORDER		EQU	63
YBORDER		EQU	30

POSSCUR:	DB	6,6,3,0,31,11,239
SETRATSVIEW:	DB	6,6,30,12,239

SEED:		DS	4
		END