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