0000187b PRTR5            00001867 PRTR1            0000167d RAND             
00001741 FILL             00000020 VIDEN            00005000 ROMHDR           
00005067 MODATA           0000501e RTAB             00005069 START            
00005068 BKGDATA          0000501c CARDTAB          00005020 TITLE            
00005055 TITLE.titlelp    0000505d HANDTAB          00000300 START.xc         
00000301 START.xp         00000302 START.yc         00000303 START.yp         
00000304 START.dir        00000305 START.tdir       00000305 START.move       
00000306 START.axis       00005077 START.newmaze    00005099 START.mazelp     
000050a3 START.dly        000050bc START.pickdir1   000050c1 START.trystraig  
000050b6 START.pickdir    00005129 START.trapped    000050cc START.pick1      
000050d1 START.pick0      00005101 START.xmove      000050fb START.ymove      
00005106 START.pmove      00005105 START.nmove      0000510e START.domove     
00005124 START.domask     0000514c START.xtmove     00005151 START.ptmove     
0000515d START.here       
			;
			; MAZE DEMO:  Draws mazes using recursive-descent maze generation algorithm
			; Copyright 1999, Joseph Zbiciak
			;
			; ROM header and function stubs adapted from SHELL.SRC by Carl Mueller, Jr.
			; This version has been modified to work with as1600.
			;

 0x5000                         ORG     $5000
			        ROMW    10                      ; rom is 10-bits wide

			;       EXEC routine equates
 0x187b                 PRTR5   EQU     $187B           ; ASCIIZ string @R5 to screen @R4
 0x1867                 PRTR1   EQU     $1867           ; ASCIIZ string @R1 to screen @R4
 0x167d                 RAND    EQU     $167D           ; Random number.
 0x1741                 FILL    EQU     $1741           ; Fill R0 locations @R4 w/ value in R1

			;       System-wide  equates
 0x20                   VIDEN   EQU     $0020           ; Video enable handshake

			; EXEC-ROM HEADER

 0x5000                 ROMHDR:
5000 00 67 00 50 	        WORD    MODATA
5002 00 1e 00 50 	        WORD    RTAB
5004 00 69 00 50 	        WORD    START
5006 00 68 00 50 	        WORD    BKGDATA
5008 00 1c 00 50 	        WORD    CARDTAB
500a 00 20 00 50 	        WORD    TITLE

500c 00 9f 		        BYTE    $9F             ; run code after title, clicks on
500d 00 00 		        BYTE    $00             ; -> to STIC $32
500e 00 00 		        BYTE    $00             ; 0 = color stack, 1 = f/b mode
500f 00 09 00 09 00 09 	        BYTE    9, 9, 9, 9      ; color stack elements 1 - 4
5015 00 09 
5013 00 09 		        BYTE    $09             ; border color

			        ; Moving Object offsets = last 16 pictures in GRAM
			        ; [What is this for?  Do I need it for this program? --JZ]
5014 01 80 01 90 01 a0 	        DECLE   $180, $190, $1A0, $1B0, $1C0, $1D0, $1E0, $1F0
501a 01 b0 01 c0 01 d0 01 e0 01 f0 
501c 00 01 00 00 	CARDTAB DECLE   $1, $0
501e 00 00 00 00 	RTAB:   DECLE   $0, $0

			; TITLE
			;
			; Copyright date, title, and code to patch title.

 0x5020                 TITLE:  PROC
5020 00 63 00 4d 00 61 	        BYTE    99, 'Maze Demo', 0
5026 00 7a 00 65 00 20 00 44 00 65 00 6d 00 6f 00 00 
502b 02 75 		        BEGIN

			        ; Cyan screen
502c 02 b8 00 09 	        MVII    #$09,   R0      ; Color 9 is Cyan (pastels.)
502e 02 40 00 28 	        MVO     R0,     $28     ; Color stack 0 = Cyan
5030 02 40 00 29 	        MVO     R0,     $29     ; Color stack 1 = Cyan
5032 02 40 00 2a 	        MVO     R0,     $2A     ; Color stack 2 = Cyan
5034 02 40 00 2b 	        MVO     R0,     $2B     ; Color stack 3 = Cyan
5036 02 40 00 2c 	        MVO     R0,     $2C     ; Border color = Cyan

			        ; Patch the title string to say '=JRMZ=' instead of Mattel.
5038 01 db 		        CLRR    R3              ; Black
5039 02 bc 02 3d 	        MVII    #$23D,  R4      ; First 'Mattel' in top-left
503b 00 04 01 18 00 7b 	        CALL    PRTR5           ; Write string (ptr in R5)
503e 00 3d 00 4a 00 52 	        STRING  '=JRMZ='        ; Guess who?  :-)
5044 00 4d 00 5a 00 3d 
5044 00 00 		        BYTE    0     

5045 00 b9 		        MOVR    PC,     R1
5046 03 39 00 08 	        SUBI    #8,     R1      ; Point to '=JRMZ=' above (save 4 words)
5048 01 db 		        CLRR    R3              ; Black
5049 02 bc 02 d5 	        MVII    #$2D5,  R4      ; Second 'Mattel' in lower-right
504b 00 04 01 18 00 67 	        CALL    PRTR1           ; Write string (ptr in R1)

			        ; Make all the rest of the text black to match
504e 02 bb 02 43 	        MVII    #$243,  R3      ; Start after first JRMZ
5050 02 b8 00 07 	        MVII    #7,     R0      ; Mask = 0xFFF8.  That's the 1s complement...
5052 00 18 		        COMR    R0              ; ...of 7.  (Saves an SDBD.)
5053 02 ba 00 92 	        MVII    #146,   R2      ; We only need to touch 146 words.

 0x5055                 @@titlelp:
5055 02 99 		        MVI@    R3,     R1      ; Read a word from the display
5056 01 81 		        ANDR    R0,     R1      ; Mask the foreground color
5057 02 59 		        MVO@    R1,     R3      ; Write the word back
5058 00 0b 		        INCR    R3              ; Point to next word
5059 00 12 		        DECR    R2              ; Decrement our loop count
505a 02 2c 00 06 	        BNEQ    @@titlelp       ; Iterate.

			        ; Done.
505c 02 b7 		        RETURN                  ; Return to caller

			        ENDP

			; HANDTAB
			; Vector table for handling the controllers.
505d 00 00 00 00 	HANDTAB WORD    0            ; Disc handler
505f 00 00 00 00 	        WORD    0            ; Keypad handler
5061 00 00 00 00 	        WORD    0            ; Upper action btn
5063 00 00 00 00 	        WORD    0            ; Lower Right act btn
5065 00 00 00 00 	        WORD    0            ; Lower Left act btn

			; Moving Objects bitmaps
5067 00 00 		MODATA: DCW     $0

			; Background Cards bitmaps

5068 00 00 		BKGDATA: DCW     $0



			;===========================================================================
			; START:  Code which runs after title screen.             
 0x5069                 START:  PROC
5069 02 75 		        BEGIN                   ; Save return address on stack

			        ; "Local" variables
 0x300                  @@xc    EQU     $300            ; X card position
 0x301                  @@xp    EQU     $301            ; X pixel position
 0x302                  @@yc    EQU     $302            ; Y card position
 0x303                  @@yp    EQU     $303            ; Y pixel position
 0x304                  @@dir   EQU     $304            ; Direction 
 0x305                  @@tdir  EQU     $305            ; Directions we've tried at this intersection
 0x305                  @@move  EQU     $305            ; Updated pixel coordinate
 0x306                  @@axis  EQU     $306            ; Pointer to axis that was updated

506a 00 03 		        DIS   ; This demo has no interaction and no need for interrupts.

506b 01 c0 		        CLRR    R0
506c 02 40 00 2c 	        MVO     R0,     $2C     ; Black border.
506e 02 40 00 28 	        MVO     R0,     $28

			        ; Shift display over 3 pixels, down 4 pixels.
5070 02 b8 00 03 	        MVII    #3,     R0
5072 02 40 00 30 	        MVO     R0,     $30     ; Horizontal delay = 3
5074 00 08 		        INCR    R0
5075 02 40 00 31 	        MVO     R0,     $31     ; Vertical delay = 4


			        ; Draw maze as a set of black passages.  Seed pixel is at (1,1)
			        ; Each 2x2 block of colored squares will end up being one of
			        ; the following with this algorithm:
			        ;
			        ;       ##   #.  ##  #.
			        ;       #.   #.  ..  ..

 0x5077                 @@newmaze:
5077 02 b8 00 f0 	        MVII    #$00F0, R0
5079 02 bc 02 00 	        MVII    #$0200, R4
507b 00 01 02 b9 00 92 	        MVII    #$1492, R1      ; 
5081 00 14 
507f 00 04 01 14 03 41 	        CALL    FILL            ; Fill screen w/ red colored squares

5082 02 ba 02 6d 	        MVII    #$26D,  R2      ; Start in middle

5084 02 bb 00 13 	        MVII    #19,    R3
5086 02 43 03 01 	        MVO     R3,     @@xp
5088 00 63 		        SLR     R3,     1
5089 02 43 03 00 	        MVO     R3,     @@xc
508b 02 bb 00 0b 	        MVII    #11,    R3
508d 02 43 03 03 	        MVO     R3,     @@yp
508f 00 63 		        SLR     R3,     1
5090 02 43 03 02 	        MVO     R3,     @@yc

5092 02 b8 00 02 	        MVII    #2,     R0
5094 00 04 01 14 02 7d 	        CALL    RAND
5097 02 40 03 04 	        MVO     R0,     @@dir

 0x5099                 @@mazelp:
			        ; Clear the pixel at the current position.
5099 02 90 		        MVI@    R2,     R0
509a 00 01 03 b8 00 ff 	        ANDI    #$D1FF, R0
50a0 00 d1 
509e 03 f8 02 00 	        XORI    #$0200, R0
50a0 02 50 		        MVO@    R0,     R2

			        ; delay loop
50a1 02 bb 03 ff 	        MVII    #$3FF,  R3
50a3 02 40 00 20 	@@dly:  MVO     R0,     VIDEN
50a5 00 13 		        DECR    R3
50a6 02 2c 00 04 	        BNEQ    @@dly


			        ; Pick a direction to exit by.
50a8 01 db 		        CLRR    R3

			        ; Straightness factor:  We can control how twisty the maze is
			        ; by controlling how often we just try to go straight.
50a9 02 b8 00 04 	        MVII    #4,     R0
50ab 00 04 01 14 02 7d 	        CALL    RAND
50ae 03 78 00 03 	        CMPI    #3,     R0      ; Try straight-ahead 3/16th of the time
50b0 02 0e 00 0a 	        BGT     @@pickdir1

50b2 02 80 03 04 	        MVI     @@dir,  R0
50b4 02 00 00 0b 	        B       @@trystraight

 0x50b6                 @@pickdir:
50b6 03 7b 00 0f 	        CMPI    #$F,    R3      ; If we've tried all four dirs, we're trapped
50b8 02 04 00 6f 	        BEQ     @@trapped

50ba 02 40 00 20 	        MVO     R0,     VIDEN   ; vid enable

 0x50bc                 @@pickdir1:
50bc 02 b8 00 02 	        MVII    #2,     R0
50be 00 04 01 14 02 7d 	        CALL    RAND
 0x50c1                 @@trystraight:
50c1 03 b8 00 03 	        ANDI    #3,     R0      ; bit 1 is 'x/y', bit 0 is '-1 / +1'
50c3 02 40 03 04 	        MVO     R0,     @@dir

			        ; See if we've already tried this direction.  
50c5 02 b9 00 01 	        MVII    #1,     R1
50c7 03 b8 00 02 	        ANDI    #2,     R0
50c9 02 04 00 01 	        BEQ     @@pick1
50cb 00 4d 		        SLL     R1,     2
 0x50cc                 @@pick1:
50cc 03 c0 03 04 	        XOR     @@dir,  R0
50ce 02 04 00 01 	        BEQ     @@pick0
50d0 00 c9 		        ADDR    R1,     R1
 0x50d1                 @@pick0:
50d1 02 41 03 05 	        MVO     R1,     @@tdir
			        ; Ok, R1 is now 1, 2, 4 or 8 depending on which direction we're
			        ; trying.  See if that bit is already set in R3.
50d3 01 99 		        ANDR    R3,     R1
50d4 02 2c 00 19 	        BNEQ    @@pickdir1      ; Yes it was, pick another.

			        ; No it wasn't.  Add it to the set of directions we've tried.
50d6 03 c3 03 05 	        XOR     @@tdir, R3


			        ; Update X and Y according to the direction we're trying.
50d8 02 80 03 04 	        MVI     @@dir,  R0                                

			        ; Select X or Y based on bit 1
50da 02 bc 03 00 	        MVII    #$300,  R4      
50dc 03 b8 00 02 	        ANDI    #2,     R0      ; Get bit 2.
50de 00 c4 		        ADDR    R0,     R4      ; $300 or $302 ==> X or Y

			        ; Add or subtract 1 based on bit 0.
50df 03 c0 03 04 	        XOR     @@dir,  R0      ; Get bit 0
50e1 00 c0 		        ADDR    R0,     R0      ; Multiply it by 2.
50e2 02 e0 		        ADD@    R4,     R0      ; Add it to the value
50e3 00 10 		        DECR    R0              ; Subtract 1.  val' = val + 2 * bit0 - 1.

			        ; Are we within the screen borders?
50e4 02 2b 00 2f 	        BMI     @@pickdir       ; Yes:  Off top/left

50e6 03 60 		        CMP@    R4,     R0      ; Check right/bottom
50e7 02 2d 00 32 	        BGE     @@pickdir       ; Yes:  Off right/bottom

50e9 03 3c 00 02 	        SUBI    #2,     R4      ; Reset R4
50eb 02 40 03 05 	        MVO     R0,     @@move  ; Store candidate coordinate update
50ed 02 44 03 06 	        MVO     R4,     @@axis  ; ... and which coordinate to update


			        ; Ok, update our cardtab address and test the pixel there.

			        ; Assume a horizontal move, and see if it's really a vertical move.
50ef 02 80 03 04 	        MVI     @@dir,  R0      ; Our random number
50f1 02 b9 00 01 	        MVII    #1,     R1      ; Default to +/- 1 update on pointer.
50f3 00 01 02 bc 00 3f 	        MVII    #$D83F, R4      ; horiz move: mask pixels 2, 3
50f9 00 d8 
50f7 03 b8 00 02 	        ANDI    #2,     R0
50f9 02 04 00 06 	        BEQ     @@xmove         
 0x50fb                 @@ymove:
50fb 02 b9 00 14 	        MVII    #20,    R1      ; +/- 20 update for vertical move.
50fd 00 01 02 bc 00 c3 	        MVII    #$F1C3, R4      ; vert move: mask pixels 1, 3
5103 00 f1 
 0x5101                 @@xmove:

5101 03 c0 03 04 	        XOR     @@dir,  R0      ; Now look at bit 0 to see if negative dir.
5103 02 0c 00 01 	        BNEQ    @@pmove
 0x5105                 @@nmove:
5105 00 21 		        NEGR    R1              ; Negate movement if bit 0 clear.
 0x5106                 @@pmove:
5106 00 d1 		        ADDR    R2,     R1      ; R1 has candidate CARDTAB address.

5107 02 88 		        MVI@    R1,     R0      ; Load word from candidate destination
5108 00 01 03 b8 00 00 	        ANDI    #$2400, R0      ; Look at lower-right pixel.
510e 00 24 
			                                ; (Hack:  Ignore bit 0 so we can use the
			                                ;  blue pixel as a "status" pixel.)

510c 02 24 00 57 	        BEQ     @@pickdir       ; Zero?  This intersection's already taken.

			        ; Non zero?  Ok, we can advance into this square (whoo hoo!)
 0x510e                 @@domove:
			        ; Move the candidate x/y position into our actual x/y position
510e 02 85 03 06 	        MVI     @@axis, R5
5110 02 80 03 05 	        MVI     @@move, R0
5112 02 68 		        MVO@    R0,     R5

			        ; Record the move in the new square (for backtrack purposes)
5113 02 80 03 04 	        MVI     @@dir,  R0
5115 02 8b 		        MVI@    R1,     R3
5116 00 4f 		        SLL     R3,     2
5117 00 74 		        RRC     R0,     2       ; Move two lsbs into to msbs
5118 00 77 		        RRC     R3,     2
5119 02 4b 		        MVO@    R3,     R1      ; Store in bits 14, 15 of word.

			        ; Clear blue 'location' pixel
511a 00 01 02 b8 00 ff 	        MVII    #$FDFF, R0
5120 00 fd 
511e 03 90 		        AND@    R2,     R0
511f 02 50 		        MVO@    R0,     R2

			        ; Clear pixels (drawing the maze)

			        ; If we're moving in a negative direction, mask the current
			        ; word.  If we're moving in a positive direction, mask the
			        ; new word.

5120 00 5f 		        SLLC    R3,     2
5121 02 0a 00 01 	        BNOV    @@domask        ; Mask old position if negative dir move.
5123 00 8a 		        MOVR    R1,     R2      ; Make "new position" current position.
 0x5124                 @@domask:
5124 03 94 		        AND@    R2,     R4      ; Mask the pixel.
5125 02 54 		        MVO@    R4,     R2      ; Display it.

5126 00 8a 		        MOVR    R1,     R2      ; Make new position current position for sure.

			        ; Continue recursing down the maze.
5127 02 20 00 8f 	        B       @@mazelp

 0x5129                 @@trapped:
			        ; Recurse back a level
5129 02 90 		        MVI@    R2,     R0      ; Get current pixel.
512a 00 81 		        MOVR    R0,     R1      ; Copy it.
512b 00 01 03 b8 00 ff 	        ANDI    #$11FF, R0      ; Mask away our blue "location pixel"
5131 00 11 
512f 02 50 		        MVO@    R0,     R2      ; Display it.

5130 00 55 		        RLC     R1,     2       ; Grab the top two bits
5131 00 55 		        RLC     R1,     2       ; Put them in the bottom two bits.
5132 03 b9 00 03 	        ANDI    #3,     R1      ; Throw away the rest of the bits.
5134 02 41 03 04 	        MVO     R1,     @@dir 

			        ; Decode the direction bits in R1/@@dir, and update coordinates.
			        ; This is similar to how "pickdir" does it, except that we
			        ; interpret the positive/negative bit the opposite way since
			        ; we're backtracking now.
5136 02 bb 03 00 	        MVII    #$300,  R3
5138 03 b9 00 02 	        ANDI    #2,     R1      ; Bit 1 selects between X or Y
513a 00 cb 		        ADDR    R1,     R3      ; $300 is X, $302 is Y

513b 02 98 		        MVI@    R3,     R0      ; Get the coordinate that we need to update.
513c 03 c1 03 04 	        XOR     @@dir,  R1      ; Get bit 0.
513e 00 c9 		        ADDR    R1,     R1      ; Multiply bit 0 by 2.
513f 01 08 		        SUBR    R1,     R0      ; Subtract it from the coordinate
5140 00 08 		        INCR    R0              ; Add 1.  val' = val - 2*bit0 + 1.
5141 02 58 		        MVO@    R0,     R3      ; Store updated coordinate.


			        ; Decode direction bits and update CARDTAB pointer.
5142 02 80 03 04 	        MVI     @@dir,  R0
5144 02 b9 00 01 	        MVII    #1,     R1      ; Assume horiz move by default.  +/- 1 update.
5146 03 b8 00 02 	        ANDI    #2,     R0      ; Vertical move if bit 1 set.
5148 02 04 00 02 	        BEQ     @@xtmove        ; Yes:  Horizontal move.
514a 02 b9 00 14 	        MVII    #20,    R1      ; Vertical move.  +/- 20 update.
 0x514c                 @@xtmove:
514c 03 c0 03 04 	        XOR     @@dir,  R0      ; Get bit 0.

514e 02 04 00 01 	        BEQ     @@ptmove        ; If bit 0's set, negate the update amount.
			                                ; This is opposite of what pickdir does.
5150 00 21 		        NEGR    R1
 0x5151                 @@ptmove:
5151 00 ca 		        ADDR    R1,     R2      ; Now update the pointer.


			        ; Check to see if we're at the starting location.  This is the
			        ; termination condition for our recursion.
5152 03 7a 02 6d 	        CMPI    #$26D,  R2      
5154 02 2c 00 bc 	        BNEQ    @@mazelp        ; Not at start?  Keep recursing!

			        ; We're back at the start.  The maze is done.
5156 02 b8 00 09 	        MVII    #$9,    R0
5158 02 40 00 28 	        MVO     R0,     $28     ; Make border cyan to signify completion.
515a 02 40 00 2c 	        MVO     R0,     $2C

515c 01 db 		        CLRR    R3              ; Sit around awhile.
515d 02 40 00 20 	@@here: MVO     R0,     VIDEN
515f 02 40 00 20 	        MVO     R0,     VIDEN
5161 02 40 00 20 	        MVO     R0,     VIDEN
5163 02 40 00 20 	        MVO     R0,     VIDEN
5165 00 13 		        DECR    R3
5166 02 2c 00 0a 	        BNEQ    @@here

5168 02 43 00 2c 	        MVO     R3,     $2C     ; Make border black again.
516a 02 43 00 28 	        MVO     R3,     $28
516c 02 20 00 f6 	        B       @@newmaze       ; Make a new maze.

			        ENDP
 ERROR SUMMARY - ERRORS DETECTED 0
               -  WARNINGS       0
