home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / BEEHIVE / GAMES / MAZEBLD.ARC / MAZEBLD.Z80 < prev   
Text File  |  1980-01-01  |  23KB  |  1,149 lines

  1.  
  2.  
  3. ;                          MAZE BUILDER
  4. ;                        BY IAN JOHNSTONE
  5. ;                             13/9/87
  6. ;
  7.     ORG    100H
  8.     CALL    PROLOG  ;Relocate stack and pass control to MAIN
  9.     JP    WARM    ;Tidy up and exit
  10. ;
  11. BEL    EQU    7
  12. CLS    EQU    26
  13. CR    EQU    0DH
  14. CTRLC    EQU    3
  15. LF    EQU    0AH
  16. TAB    EQU    9
  17. TBUF    EQU    80H    ;Default buffer
  18. TFCB    EQU    05CH    ;Default TFCB
  19. MAZE    EQU    7000H    ;Buffer to hold model of maze
  20. SCREEN    EQU    0F000H    ;Start of video RAM
  21. OFFSET    EQU    8000H    ;Offset from maze to screen
  22. LASTLN    EQU    0F730H    ;Last line of screen
  23. GRAPH    EQU    0F810H    ;Start of PCG RAM + 10H
  24. MGRAPH    EQU    80H    ;Mask to convert digit to related graphic
  25. DOT    EQU    90H    ;  ditto but with dot in centre
  26. ;
  27. WARM    EQU    0
  28. BDOS    EQU    5
  29. ;
  30. DIRIO    EQU    6
  31. GETCH    EQU    1
  32. LINEIN    EQU    10
  33. STATUS    EQU    11
  34. ;
  35. MAIN:    CALL    PRESS    ;Press any key
  36. MAIN2:    CALL    INIT    ;Init & set up Graphics
  37.     CALL    USERIN    ;Get user input
  38.     CALL    SETMAZE    ;Set up Maze boundaries
  39.     CALL    GSTART    ;Select a random entry point into maze
  40.     CALL    MOVE    ;Random move thru Maze leaving trail of
  41.             ;open cells until all cells opened
  42.     CALL    CHOOSE    ;Play maze game or view auto-escape
  43.     JP    NZ,MAIN2 ;Round again if desired
  44.     RET        ;Return to PROLOG
  45. ;
  46. INIT:    ;***** Initialise Maze
  47.     LD    HL,MAZE ;Fill maze area with ones
  48.     LD    (HL),1
  49.     LD    DE,MAZE+1
  50.     LD    BC,800H
  51.     LDIR
  52.     LD    DE,GRAPH ;Write graphics into PCG area
  53.     LD    HL,MAZDAT
  54.     LD    BC,240
  55.     LDIR
  56.     LD    DE,GRAPH+100H ;And into next page
  57.     LD    HL,MAZDAT
  58.     LD    BC,240
  59.     LDIR
  60.     LD    B,15
  61.     LD    HL,GRAPH+104H ;But put a dot in centre
  62.     LD    DE,14
  63. PUTDOT:    LD    A,(HL)
  64.     OR    8
  65.     LD    (HL),A
  66.     INC    HL
  67.     LD    A,(HL)
  68.     OR    28
  69.     LD    (HL),A
  70.     INC    HL
  71.     LD    A,(HL)
  72.     OR    8
  73.     LD    (HL),A
  74.     ADD    HL,DE
  75.     DJNZ    PUTDOT
  76.     RET
  77. MAZDAT:    DB    129,129,129,129,129,129,129,129,129,129,255,0,0,0,0,0
  78.     DB    255,128,128,128,128,128,128,128,128,128,255,0,0,0,0,0
  79.     DB    128,128,128,128,128,128,128,128,128,128,255,0,0,0,0,0
  80.     DB    255,129,129,129,129,129,129,129,129,129,129,0,0,0,0,0
  81.     DB    129,129,129,129,129,129,129,129,129,129,129,0,0,0,0,0
  82.     DB    255,128,128,128,128,128,128,128,128,128,128,0,0,0,0,0
  83.     DB    128,128,128,128,128,128,128,128,128,128,128,0,0,0,0,0
  84.     DB    255,1,1,1,1,1,1,1,1,1,255,0,0,0,0,0
  85.     DB    1,1,1,1,1,1,1,1,1,1,255,0,0,0,0,0
  86.     DB    255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0
  87.     DB    0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0
  88.     DB    255,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
  89.     DB    1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
  90.     DB    255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  91.     DB    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  92. ;
  93. PROLOG: LD    HL,0    ;Re-locate stack
  94.     ADD    HL,SP    ;Get stack pointer
  95.     LD    (STAK),HL ;Save it
  96.     LD    HL,STAK
  97.      LD         SP,HL    ;SP is now at STAK
  98.     CALL       MAIN    ;Exedcutre program
  99.     JP    WARM    ;Return to CP/M
  100.     DS    40H    ;Buffer for stack
  101. STAK:    DW    0
  102. ;
  103. USERIN: ;Get user input
  104.     LD    DE,TBUF
  105.     CALL    SETDMA
  106.     CALL    RATE    ;Get & save delay timer
  107.     CALL    PRINT
  108.     DB    CR,LF,LF,'Enter Width, Height (Max 76,20)  '
  109.     DB    CR,LF,LF,'On error will default to 30,12 ',0
  110.     CALL    GETSTR    ;Get user input
  111.     LD    B,0    ;Digit counter
  112.     LD    HL,TBUF+2
  113.     LD    DE,WBUF    
  114.     CALL    ULP    ;Read width parameter into WBUF
  115.     OR    A
  116.     JR    Z,DFLT    ;Default if buffer empty
  117.     INC    HL
  118.     LD    DE,HBUF
  119.     LD    C,B    ;Save digit count
  120.     LD    B,0;Clear counter
  121.     CALL    ULP    ;Read Height parameter into HBUF
  122.     LD    HL,WBUF
  123.     CALL    TOBNRY    ;Convert ASCII width to binary
  124.     LD    (WIDTH),A
  125.     OR    A
  126.     JR    Z,DFLT
  127.     CP    77
  128.     JR    NC,DFLT    ;Default if under- or over-size
  129.     LD    HL,HBUF
  130.     LD    C,B    ;Count of height digits
  131.     CALL    TOBNRY    ;Now height
  132.     LD    (HEIGHT),A
  133.     OR    A
  134.     JR    Z,DFLT
  135.     CP    21
  136.     JR    NC,DFLT
  137.     JR    USRX    ;Exit to MAIN
  138. DFLT:    LD    A,30    ;Put default parameters in buffers
  139.     LD    (WIDTH),A
  140.     LD    A,12
  141.     LD    (HEIGHT),A
  142. USRX:    LD    A,CLS
  143.     CALL    PUTCH
  144.     RET
  145. ;
  146. SPEED:    DB    0
  147. WIDTH:    DW    0
  148. HEIGHT:    DW    0
  149. ;
  150. ULP:    ;Read contents of Input buff
  151.     LD    A,(HL)    ;HL -> start of text in buff
  152.     CP    ' '    ;Skip blanks
  153.     JP    NZ,ULP1
  154.     INC    HL
  155.     JP    ULP
  156. ULP1:      CP    0    ;Delimiter
  157.     RET    Z
  158.     CP    ','    ;Element seperator
  159.     RET    Z
  160.     INC    B    ;Digit count
  161.     LD    (DE),A    ;DE -> width or height buff
  162.     INC    DE
  163.     INC    HL
  164.     JR    ULP
  165. ;
  166. WBUF:    DW    0
  167. HBUF:    DW    0
  168. ;
  169. TOBNRY: ;Convert 2 ASCII digits -> by HL to binary
  170.     XOR    A
  171.     CP    (HL)
  172.     RET    Z    ;Abort if buffer empty
  173.     DEC    C    ;C=digit count
  174.     JR    Z,UUNITS
  175.     DEC    C
  176.     JR    Z,UTENS
  177.     JR    TBNRX
  178. UTENS:    LD    A,(HL)    ;Multiply tens digit
  179.     AND    0FH    ;Stripped of ASCII
  180.     ADD    A,A    ;by two
  181.     LD    C,A
  182.     ADD    A,A    ;by 4
  183.     ADD    A,A    ;by 8
  184.     ADD    A,C    ;by 10
  185.     LD    C,A
  186.     INC    HL
  187. UUNITS:    LD    A,(HL)
  188.     AND    0FH    ;Strip ASCII from units digit
  189.     ADD    A,C    ;& add to 10 times tens
  190. TBNRX:    RET
  191. ;
  192. SETMAZE: ;***** Set up maze in buffer and on screen
  193.     LD    A,(WIDTH)
  194.     OR    A    ;Reset carry
  195.     RRA
  196.     LD    L,A
  197.     LD    H,0
  198.     LD    (HALFW),HL ;Subtract half of width
  199.     LD    DE,MAZE+40 ;From centre of top line
  200.     OR    A
  201.     EX    DE,HL
  202.     SBC    HL,DE
  203.     LD    A,(HEIGHT)
  204.     PUSH    AF
  205.     OR    A
  206.     RRA
  207.     LD    B,A    ;Subtract half of height
  208.     LD    A,12    ;from half of maximum height
  209.     SUB    B
  210.     LD    B,A
  211.     LD    DE,80
  212. STM1:    ADD    HL,DE    ;and "line feed" this many lines
  213.     DJNZ    STM1
  214.     LD    (CORNER),HL ;Record top left corner
  215.     POP    BC    ;get height - 1
  216.     DEC    B
  217. STM2:    ADD    HL,DE    ;& calculate bottom left corner
  218.     DJNZ    STM2
  219.     LD    (BOTLEFT),HL
  220.     LD    HL,(CORNER)
  221.     OR    A
  222.     SBC    HL,DE
  223.     PUSH    HL    ;Tab up to balance later "line feed"
  224.     LD    A,(HEIGHT)
  225.     LD    C,A
  226. STM3:    POP    HL    ;Fill maze area of maze buff with zeros
  227.     ADD    HL,DE    ;"line feed"
  228.     PUSH    HL
  229.     LD    A,(WIDTH)
  230.     LD    B,A
  231. STM4:    LD    (HL),0
  232.     INC    HL
  233.     DJNZ    STM4    ;Zero fill one line
  234.     DEC    C
  235.     JR    NZ,STM3    ;LF and zero another, till done
  236.     POP    HL    ;Clear stack
  237.     LD    HL,(CORNER)
  238.     LD    DE,OFFSET-80 ;Now do the screen
  239.     ADD    HL,DE
  240.     LD    DE,80
  241.     PUSH    HL
  242.     LD    A,(HEIGHT)
  243.     LD    C,A
  244. STM5:    POP    HL
  245.     ADD    HL,DE
  246.     PUSH    HL
  247.     LD    A,(WIDTH)
  248.     LD    B,A
  249. STM6:    LD    (HL),'X'
  250.     INC    HL
  251.     DJNZ    STM6    ;Fill a line with 'X's
  252.     DEC    C
  253.     JR    NZ,STM5
  254.     POP    HL
  255.     ADD    HL,DE    ;Point to South boundary
  256.     LD    A,(WIDTH)
  257.     LD    B,A
  258. STM7:    LD    (HL),142
  259.     INC    HL
  260.     DJNZ    STM7    ;and draw a line
  261.     LD    HL,(CORNER)
  262.     LD    DE,OFFSET-80
  263.     ADD    HL,DE    ;Point to north boundary
  264.     LD    A,(WIDTH)
  265.     LD    B,A
  266. STM8:    LD    (HL),139
  267.     INC    HL
  268.     DJNZ    STM8    ;and draw a line
  269.     LD    HL,(CORNER)
  270.     LD    DE,OFFSET-1 ;Point to top of West boundary
  271.     ADD    HL,DE
  272.     LD    DE,80
  273.     LD    A,(HEIGHT)
  274.     LD    B,A
  275.     PUSH    BC
  276. STM9:    LD    (HL),141
  277.     ADD    HL,DE
  278.     DJNZ    STM9    ;and draw a line
  279.     LD    HL,(CORNER)
  280.     LD    DE,OFFSET
  281.     ADD    HL,DE
  282.     EX    DE,HL
  283.     LD    HL,(WIDTH)
  284.     ADD    HL,DE    ;point to top of east boundary
  285.     LD    DE,80
  286.     POP    BC
  287. STM10:    LD    (HL),135
  288.     ADD    HL,DE
  289.     DJNZ    STM10    ;and draw a line
  290.     RET
  291. ;
  292. HALFW:    DW    0
  293. HALFH:    DW    0
  294. CORNER:    DW    0
  295. BOTLEFT:DW    0
  296. ;
  297. GSTART:    ;Establish a random starting point
  298.     LD    HL,GSTX
  299.     PUSH    HL    ;Establish a return address
  300.     LD    A,4    ;Select a boundary for entry
  301.     CALL    RAND    ;Returns RND(4) + 1
  302.     DEC    A    ;1=N, 2=E, 3=S, 4=W
  303.     JR    Z,RNORTH
  304.     DEC    A
  305.     JR    Z,REAST
  306.     DEC    A
  307.     JR    Z,RSOUTH
  308.     JR    RWEST
  309. GSTX:    LD    (RNDSTART),HL ;Record selected starting point
  310.     LD    (HERE),HL ;twice
  311.     LD    (HL),A    ;Record direction code
  312.     ADD    HL,DE    ;DE=screen offset + offset to boundary
  313.     LD    (HL),' ' ;Punch a hole in the boundary
  314.     LD    (MZXIT),HL
  315.     RET
  316. RNORTH:    CALL    RHORIZ    ;Return RND(WIDTH-1)+1 in DE
  317.     LD    HL,(CORNER)
  318.     LD    A,2    ;Direction code for north
  319.     ADD    HL,DE    ;HL=starting point
  320.     LD    DE,OFFSET-80 ;Point to border on screen
  321.     RET
  322. RSOUTH:    CALL    RHORIZ
  323.     LD    HL,(BOTLEFT)
  324.     LD    A,8
  325.     ADD    HL,DE
  326.     LD    DE,OFFSET+80
  327.     RET
  328. RHORIZ:    LD    A,(WIDTH)
  329.     DEC    A
  330.     CALL    RAND    ;= RND(WIDTH-1)+1
  331.     LD    E,A
  332.     LD    D,0    ;= LD DE,A
  333.     RET
  334. REAST:    CALL    RVERT    ;Returns CORNER+RND(HEIGHT-1) LFs in HL
  335.     LD    DE,(WIDTH)
  336.     DEC    DE
  337.     LD    A,4    ;Direction code for east
  338.     ADD    HL,DE    ;HL=starting point
  339.     LD    DE,OFFSET+1 ;Point to screen border
  340.     RET
  341. RWEST:    CALL    RVERT
  342.     LD    A,16
  343.     LD    DE,OFFSET-1
  344.     RET
  345. RVERT:    LD    A,(HEIGHT)
  346.     DEC    A
  347.     CALL    RAND    ;Returns RND(HEIGHT-1)+1 in A
  348.     LD    B,A
  349.     LD    HL,0
  350.     LD    DE,80
  351. RVT1:    ADD    HL,DE    ;Multiply it by 80
  352.     DJNZ    RVT1
  353.     LD    DE,(CORNER)
  354.     ADD    HL,DE    ;& add to CORNER
  355.     RET
  356. MZXIT:    DW    0
  357. ;
  358. MOVE:    ;Move to an adjoining cell
  359.     LD    DE,OFFSET  ;Offset from maze to screen
  360.     LD    HL,(HERE) ;Mark current cell on screen
  361.     ADD    HL,DE
  362.     LD    (HL),'*'
  363.     LD    A,DIRIO    ;Scan for ^C
  364.     LD    DE,0FFH
  365.     CALL    HLBDOS
  366.     OR    A
  367.     CP    CTRLC
  368.     JP    NZ,MOVE0
  369.     POP    HL    ;Clear stack
  370.     RET        ;Exit on ^C
  371. MOVE0:    CALL    NEIGHB    ;Returns B=count of legal moves in array LOTTO
  372.     JR    NZ,MALL
  373.     INC    B    ;West move is legal so Inc count
  374.     LD    (HL),3    ;& put west code in array
  375. MALL:    LD    A,B
  376.     OR    A
  377.     JP    Z,BKTRK    ;If no legal exit, try a backtrack
  378.     CALL    RAND    ;Select a legal move
  379.     CALL    MKMOV    ;and make it
  380. MVBK:    LD    HL,(LAST) ;Put a dot graphic in previous cell
  381.     LD    A,(HL)
  382.     RRA
  383.     AND    0FH
  384.     OR    MGRAPH ;Mask for dot graphic
  385.     LD    DE,OFFSET
  386.     ADD    HL,DE
  387.     LD    (HL),A    ;Display dot
  388.     JP    MOVE    ;Try another move
  389. ;
  390. NEIGHB:    CALL    GOVERN    ;Delay loop
  391.     LD    B,0    ;Count of legal exits
  392.     LD    HL,LOTTO ;array "    "    "
  393.     PUSH    HL
  394.     LD    HL,(HERE)
  395.     LD    DE,-80    ;Test cell to north
  396.     ADD    HL,DE
  397.     LD    A,(HL)
  398.     POP    HL
  399.     OR    A
  400.     JR    NZ,ME    ;Is vacant if zero, else try east
  401.     INC    B    ;so inc count
  402.     LD    (HL),0    ;and put it in array (north=0)
  403.     INC    HL
  404. ME:    PUSH    HL    ;now try east
  405.     LD    HL,(HERE)
  406.     INC    HL
  407.     LD    A,(HL)
  408.     POP    HL
  409.     OR    A
  410.     JR    NZ,MS    ;If illegal, try south
  411.     INC    B
  412.     LD    (HL),1    ;put in array (east=1)
  413.     INC    HL
  414. MS:    PUSH    HL    ;now try south
  415.     LD    HL,(HERE)
  416.     LD    DE,80
  417.     ADD    HL,DE
  418.     LD    A,(HL)
  419.     POP    HL
  420.     OR    A
  421.     JR    NZ,MW
  422.     INC    B
  423.     LD    (HL),2    ;(south=2)
  424.     INC    HL
  425. MW:    PUSH    HL    ;now try west
  426.     LD    HL,(HERE)
  427.     DEC    HL
  428.     LD    A,(HL)
  429.     POP    HL
  430.     OR    A
  431.     RET
  432. LOTTO:    DB    0,0,0,0 ;Array of legal moves
  433. LAST:    DW    0    ;Location of last cell visited
  434. ;
  435. MKMOV:    LD    HL,(HERE) ;Get current cell
  436.     LD    (LAST),HL ;It's being superceded
  437.     LD    B,A      ;B=random choice
  438.     LD    HL,LOTTO  ;of array element
  439.     DEC    HL
  440. MKM1:    INC    HL    ;Locate chosen element
  441.     DJNZ    MKM1
  442.     LD    A,(HL)    ;Fetch it
  443.     OR    A    ;Zero=north
  444.     JR    Z,MVNOR
  445.     DEC     A    ;1=east
  446.     JR    Z,MVEAST
  447.     DEC    A    ;2=south
  448.     JR    Z,MVSOU
  449.     LD    HL,(HERE) ;else west
  450. MVWEST:    LD    A,(HL)
  451.     OR    16    ;West code = 16
  452.     LD    (HL),A    ;So mark cell
  453.     DEC    HL    ;Now move west
  454.     LD    (HERE),HL
  455.     LD    (HL),4    ;We can move east from new cell
  456.     RET
  457. MVNOR:    LD    HL,(HERE)
  458.     LD    A,(HL)
  459.     OR    2    ;North code = 2
  460.     LD    (HL),A
  461.     LD    DE,-80
  462.     ADD    HL,DE
  463.     LD    (HERE),HL
  464.     LD    (HL),8    ;We can move south from new cell
  465.     RET
  466. MVEAST:    LD    HL,(HERE)
  467.     LD    A,(HL)
  468.     OR    4    ;East code = 4
  469.     LD    (HL),A
  470.     INC    HL
  471.     LD    (HERE),HL
  472.     LD    (HL),16    ;We can move west from new cell
  473.     RET
  474. MVSOU:    LD    HL,(HERE)
  475.     LD    A,(HL)
  476.     OR    8    ;South code = 8
  477.     LD    (HL),A
  478.     LD    DE,80
  479.     ADD    HL,DE
  480.     LD    (HERE),HL
  481.     LD    (HL),2    ;We can move north from new cell
  482.     RET
  483. ;
  484. RATE:    CALL    PRINT
  485.     DB    CLS,CR,LF,LF,TAB,TAB,TAB,'RANDOM MAZE BUILDER'
  486.     DB    CR,LF,LF,'Do you want',CR,LF,TAB,'1. Fast',CR
  487.     DB    LF,TAB,'2. Medium',CR,LF,TAB,'3. Slow  ',0
  488.     CALL    DIRIN    ;Direct input
  489.     CP    CTRLC
  490.     JP    NZ,RATE1
  491.     POP    HL    ;Clear stack
  492.     RET
  493. RATE1:    AND    0FH    ;Strip ASCII
  494.     LD    (SPEED),A
  495.     RET
  496. GOVERN:    ;3 Speed delay loops (0, 4K & 8K loops)
  497.     PUSH    BC
  498.     LD    BC,0
  499.     LD    A,(SPEED)
  500.     DEC    A
  501.     JP    Z,ADJ2
  502.     LD    B,16
  503.     DEC    A
  504.     JP    Z,ADJ1
  505.     LD    B,64
  506. ADJ1:    DEC    BC
  507.     LD    A,B
  508.     OR    C
  509.     JP    NZ,ADJ1
  510. ADJ2:    POP    BC
  511.     RET    
  512. ;
  513. RNDSTART:DW    0 ;Starting entry to maze
  514. HERE:    DW    0 ;Location of current cell
  515. ;
  516. BKTRK:    ;Backtrack to an accessible cell
  517.     LD    DE,LOTTO ;Array of legal backtracks
  518.     LD    B,0     ;Count  "   "
  519.     LD    HL,(HERE)
  520.     LD    A,(HL)
  521.     AND    2    ;North = 2
  522.     JP    Z,BKT1
  523.     INC    B
  524.     LD    A,1
  525.     LD    (DE),A    ;Store 1=north
  526.     INC    DE
  527. BKT1:    LD    A,(HL)
  528.     AND    4    ;East=4
  529.     JP    Z,BKT2
  530.     INC    B
  531.     LD    A,2
  532.     LD    (DE),A    ;Store 2=east
  533.     INC     DE
  534. BKT2:    LD    A,(HL)
  535.     AND    8    ;South=8
  536.     JP    Z,BKT3
  537.     INC    B
  538.     LD    A,3
  539.     LD    (DE),A
  540.     INC    DE
  541. BKT3:    LD    A,(HL)
  542.     AND    16    ;West=16
  543.     JP    Z,BKALL
  544.     INC    B
  545.     LD    A,4
  546.     LD    (DE),A    ;Store 4=west
  547. BKALL:    LD    A,B    ;Legal backtrack count
  548.     OR     A
  549.     RET    Z    ;If no legal backtrack, all cells have
  550.             ;been visited
  551.     INC    (HL)    ;Set Lo bit to prevent more backtracks
  552.     LD    (LAST),HL ;Current cell will be superrceded
  553.     LD    A,(HL)
  554.     RRA
  555.     OR    MGRAPH ;Mask for non-dot graphic
  556.     LD    DE,OFFSET
  557.     ADD    HL,DE
  558.     LD    (HL),A    ;Remove dot from cell on screen
  559.     LD    HL,LOTTO-1
  560. BKA1:    INC    HL    ;Can new cell accept backtrack (i.e.Lo bit reset)
  561.     PUSH    HL
  562.     DEC    (HL)    ;1=north
  563.     JP    Z,BKN
  564.     DEC    (HL)    ;2=east
  565.     JP    Z,BKE
  566.     DEC    (HL)    ;3=south
  567.     JP    Z,BKS
  568.     JP    BKW    ;Only west left
  569. BKN:    LD    HL,(HERE)
  570.     LD    DE,-80
  571.     ADD    HL,DE    ;Goto north cell
  572.     LD    A,(HL)
  573.     AND    1    ;Entry illegal if Lo bit set
  574.     JP    BKTX    ;Zero flag set it so
  575. BKE:    LD    HL,(HERE)
  576.     INC    HL    ;visit east cell
  577.     LD    A,(HL)
  578.     AND    1
  579.     JP    BKTX
  580. BKS:    LD    HL,(HERE)
  581.     LD    DE,80
  582.     ADD    HL,DE    ;Visit south cell
  583.     LD    A,(HL)
  584.     AND    1
  585.     JP    BKTX
  586. BKW:    LD    HL,(HERE)
  587.     DEC    HL    ;Visit west cell
  588.     LD    A,(HL)
  589.     AND    1
  590.     JP    BKTX
  591. BKTX:    JP    NZ,BKTX1;Zero flag set if move not legal, try again
  592.     LD    (HERE),HL ;Record new cell
  593.     POP    HL    ;Clear stack
  594.     JP    MOVE    ;Try another move
  595. BKTX1:    POP    HL    ;Recover array pointer
  596.     DEC    B
  597.     JP    NZ,BKA1    ;Try again if more left
  598.     JP    BKALL    ;Else head for exit
  599. ;
  600. CHOOSE: ;Choose between Play, Auto escape & exit
  601.     LD    A,BEL
  602.     CALL    PUTCH
  603.     CALL    RNDCELL    ;Randomly select a cell to start from
  604.     LD    DE,SCREEN ;Display inverse text on top line of screen
  605.     CALL    HILITE
  606.     DB    'Choose from 1=Play, 2=Auto escape, 3=Exit ',0
  607.     CALL    DIRIN    ;Get direct input
  608.     CP    '1'
  609.     JP    Z,PLAY
  610.     CP    '2'
  611.     JP    Z,AUTO
  612.     AND    0FH
  613.     CP    3
  614.     RET        ;If 3 or ^C, return with zero set
  615. ;
  616. RNDCELL: ;Select a cell at random
  617.     LD    A,(WIDTH)
  618.     DEC    A
  619.     CALL    RAND    ;=RND(WIDTH-1)+1
  620.     LD    E,A
  621.     LD    D,0    ;Put it in DE
  622.     LD    HL,(CORNER)
  623.     ADD    HL,DE    ;Move along top line
  624.     LD    A,(HEIGHT)
  625.     DEC    A
  626.     PUSH    HL
  627.     CALL    RAND    ;=RND(HEIGHT-1)+1
  628.     POP    HL
  629.     LD    B,A    ;Use it as a counterA
  630.     LD    DE,80
  631. RCL1:    ADD    HL,DE    ;Line feed down
  632.     DJNZ    RCL1
  633.     LD    (HERE),HL ;Store the location
  634.     LD    (RCELL),HL ;twice
  635.     LD    DE,OFFSET
  636.     ADD    HL,DE
  637.     LD    (HL),'*' ;Display cell on screen
  638.     LD    (LASTSCR),HL ;Store screen location
  639.     LD    (HERESCR),HL
  640.     LD    (FSTSCR),HL
  641.     RET
  642. RCELL:    DW    0    ;Location of randomly selected cell
  643. FSTSCR    DW    0    ;Location of above on screen
  644. ;
  645. PLAY:    LD    DE,SCREEN ;Display inverse text
  646.     CALL    HILITE    ; on top line of screen
  647.     DB    'North=(N or 3), South=S, East=E, West=W,  '
  648.     DB    '^C=Abort',0
  649. PLAY1:    LD    HL,(FSTSCR)
  650.     LD    (HL),'*'
  651.     LD    HL,(HERESCR)
  652.     LD    (LASTSCR),HL
  653.     CALL    BLIP    ;Blink cursor, get user input
  654.     PUSH    AF
  655.     LD    HL,LASTLN ;Erase bottom line of screen
  656.     CALL    DELINE
  657.     POP    AF    ;Recover input
  658.     CP    CTRLC
  659.     RET    Z    ;Exit on ^C
  660.     LD    HL,(HERE) ;Get current cell
  661.     LD    (LAST),HL ;It will be superceded
  662.     CP    '3'    ;North?
  663.     JP    Z,PLN
  664.     AND    95    ;Make upper case
  665.     CP    'N'
  666.     JP    Z,PLN
  667.     CP    'E'
  668.     JP    Z,PLE
  669.     CP    'S'
  670.     JP    Z,PLS
  671.     CP    'W'
  672.     JP    Z,PLW
  673. ILLEG:    LD    A,BEL
  674.     CALL    PUTCH
  675.     LD    DE,LASTLN
  676.     CALL    HILITE
  677.     DB    'ILLEGAL MOVE',0
  678.     JP    PLAY1    ;Try again
  679. PLN:    LD    A,(HL)    ;Get cell data
  680.     AND    2    ;2=north
  681.     JP    Z,ILLEG ;Illegal if not north
  682.     LD    DE,-80    ;Else enter offset to north cell
  683.     JP    PLAYX    ;& update maze
  684. PLE:    LD    A,(HL)
  685.     AND    4    ;East
  686.     JP    Z,ILLEG
  687.     LD    DE,1
  688.     JP    PLAYX
  689. PLS:    LD    A,(HL)
  690.     AND    8    ;South
  691.     JP    Z,ILLEG
  692.     LD    DE,80
  693.     JP    PLAYX
  694. PLW:    LD    A,(HL)
  695.     AND    16    ;West
  696.     JP    Z,ILLEG
  697.     LD    DE,-1
  698. PLAYX:    ADD    HL,DE    ;Move to new location
  699.     LD    (HERE),HL ;& store it
  700.     LD    DE,OFFSET
  701.     ADD    HL,DE
  702.     LD    (HERESCR),HL ;Store screen location
  703.     LD    A,(HL)    ;Get screen graphic
  704.     CP    '*'    ;If '*' we are backtracking
  705.     CALL    Z,PLAYBK ;Remove dot from last cell
  706.     JP    Z,PLAY1 ;And try again
  707.     AND    16    ;Same if current cell is dot graphic
  708.     CALL    NZ,PLAYBK
  709.     LD    DE,(RNDSTART) ;Get exit location
  710.     LD    HL,(LAST) ;Compare to previous
  711.     CALL    CPHLDE
  712.     JP    NZ,PLAY1 ;If NE try another move
  713.     LD    HL,SCREEN ;If equal we are finished
  714.     CALL    DELINE    ;Delete top line of screen
  715.     LD    DE,SCREEN
  716.     CALL    HILITE
  717.     DB    'CONGRATULATIONS **** Try again Y/N ?',0
  718.     CALL    DIRIN
  719.     AND    95
  720.     CP    'N'
  721.     RET    Z
  722.     LD    HL,(HERESCR) ;Remove '*' marker
  723.     LD    (HL),' '
  724.     LD    HL,SCREEN
  725.     CALL    DELINE
  726.     LD    DE,SCREEN
  727.     CALL    HILITE
  728.     DB    'Do you want  1. Same Maze,  2. New Maze',0
  729.     CALL    DIRIN
  730.     CP    '1'
  731.     RET    NZ
  732.     LD    HL,SCREEN ;Clear dots from maze
  733.     LD    BC,1840
  734. AGIN:    LD    A,(HL)
  735.     AND    0EFH    ;Mask out the dot
  736.     LD    (HL),A
  737.     INC    HL
  738.     DEC    BC
  739.     LD    A,B
  740.     OR    C
  741.     JP    NZ,AGIN
  742.     LD    HL,(RCELL) ;Recover starting cell
  743.     LD    (HERE),HL
  744.     LD    DE,OFFSET ;& mark it on screen
  745.     ADD    HL,DE
  746.     LD    (HL),'*'
  747.     LD    (HERESCR),HL ;Store screen location of start
  748.     JP    PLAY    ;Play the maze
  749. BLIP:    ;Blink screen, await user input
  750.     LD    HL,(HERESCR)
  751.     LD    A,(HL)
  752.     LD    B,0
  753.     CP    '*'
  754.     JP    NZ,BLIP1
  755.     CALL    DIRIN
  756.     RET
  757. BLIP1:    OR    DOT
  758.     LD    C,A
  759.     AND    8FH    ;Mask out Dot bit
  760.     LD    (HL),A
  761. BLIP2:    CALL    BLIPIN
  762.     JP    NZ,BLIPX
  763.     DJNZ    BLIP2
  764.     LD    (HL),C
  765.     LD    B,0
  766. BLIP3:    CALL    BLIPIN
  767.     JP    NZ,BLIPX
  768.     DJNZ    BLIP3
  769.     LD    B,0
  770.     JP    BLIP
  771. BLIPX:    LD    (HL),C
  772.     RET
  773. BLIPIN:    LD    A,DIRIO
  774.     LD    DE,0FFH
  775.     CALL    HLBDOS
  776.     OR    A
  777.     RET
  778. ;
  779. PLAYBK:    PUSH    HL
  780.     PUSH    AF
  781.     LD    HL,(LASTSCR)
  782.     LD    A,(HL)
  783.     AND    8FH
  784.     LD    (HL),A
  785.     POP    AF
  786.     POP    HL
  787.     RET
  788. LASTSCR: DW    0    ;Screen pos'n of last cell
  789. HERESCR: DW    0    ;   "      "   " current cell
  790. ;
  791. AUTO:    CALL    ARATE    ;Get input - delay time
  792.     LD    A,4
  793.     CALL    RAND    ;Select starting direction
  794.     LD    (DIRECT),A
  795.     LD    C,4    ;Count of neighbouring cells
  796.     LD    HL,(HERE)
  797.     LD    (LAST),HL
  798.     DEC    (HL)    ;Lo bit reset means visited cell
  799. AUT1:    CALL    GOVERN    ;Delay loop
  800.     LD    A,STATUS
  801.     CALL    HLBDOS    ;Scan for keystroke
  802.     OR    A
  803.     RET    NZ    ;Exit on any key
  804.     LD    HL,(FSTSCR)
  805.     LD    (HL),'*' ;Refresh start display
  806.     LD    HL,(LAST) ;Compare last cell with exit cell
  807.     LD    DE,(RNDSTART)
  808.     CALL    CPHLDE
  809.     JP    NZ,AUT1A
  810.     LD    A,BEL    ;If equal, we have escaped
  811.     CALL    PUTCH
  812.     LD    DE,LASTLN
  813.     CALL    HILITE
  814.     DB    'Round again?  Y/N',0
  815.     CALL    DIRIN
  816.     AND    95
  817.     CP    'N'
  818.     RET
  819. AUT1A:    LD    HL,(HERE) ;Put graphic on screen
  820.     LD    (LAST),HL ;Record cell being exited
  821.     LD    A,(HL)    ;Get cell data
  822.     RRA        ;Get rid of Lo bit
  823.     AND    0FH
  824.     OR    DOT    ;Mask with graphic offset
  825.     LD    DE,OFFSET
  826.     ADD    HL,DE    ;Get screen location
  827.     LD    (LASTSCR),HL ;Save it
  828.     LD    (HL),A    ;& put a dot at screen location
  829. AUT2:    LD    A,(DIRECT) ;Get directio¢
  830.     LD    B,A
  831.     LD    HL,(HERE)
  832.     LD    A,(HL)    ;Get current cell data
  833.     DEC    B
  834.     JP    Z,AUTN    ;1=north
  835.     DEC    B
  836.     JP    Z,AUTE    ;2=east
  837.     DEC    B
  838.     JP    Z,AUTS    ;3=south
  839.     JP    AUTW    ;only west left
  840. AUTN:    LD    DE,-80    ;Displacement to north cell
  841.     AND    2    ;2=north
  842.     JP    Z,AUTX
  843.     ADD    HL,DE    ;Visit  north
  844.     LD    A,(HL)    ;Get new cell data
  845.     AND    1    ;1=entry permitted
  846.     JP    AUTX
  847. AUTE:    AND    4    ;4=east
  848.     JP    Z,AUTX
  849.     INC    HL    ;Visit east
  850.     LD    A,(HL)
  851.     AND    1
  852.     JP    AUTX
  853. AUTS:    AND    8    ;8=south
  854.     JP    Z,AUTX
  855.     LD    DE,80
  856.     ADD    HL,DE    ;Visit south
  857.     LD    A,(HL)
  858.     AND    1
  859.     JP    AUTX
  860. AUTW:    AND    16    ;16=west
  861.     JP    Z,AUTX
  862.     DEC    HL    ;Visit west
  863.     LD    A,(HL)
  864.     AND    1
  865. AUTX:    ;Zero flag has been reset if it's OK to move
  866.     LD    A,(DIRECT)
  867.     JP    NZ,OK    ;Complete move if OK
  868.     DEC    C    ;Else DEC cell count
  869.     JP    Z,AUTBAK ;Backtrack if all cells tried
  870.     DEC    A    ;Turn left (after failure)
  871.     JP    NZ,ATX2 ;Direction must be >0
  872.     ADD    A,4
  873. ATX2:    LD    (DIRECT),A
  874.     JP    AUT1    ;& try new direction
  875. OK:    LD    (HERE),HL
  876.     LD    C,4    ;Restore cell count
  877.     INC    A    ;Turn right (after success)
  878.     CP    5    ;Direction must be <5
  879.     JP    C,ATX3
  880.     SUB    4
  881. ATX3:    LD    (DIRECT),A
  882.     LD    (HERE),HL
  883.     DEC    (HL)    ;Lo bit was 1, now make it zero (no entry)
  884.     JP    AUT1    ;Try another move
  885. AUTBAK:    INC    A    ;Turn right (to restore original direct)
  886.     CP    5
  887.     JP    C,ATB1
  888.     SUB    4
  889. ATB1:    LD    (DIRECT),A
  890.     LD    HL,(HERE)
  891.     DEC    A
  892.     JP    Z,ATBN    ;1=North
  893.     DEC    A
  894.     JP    Z,ATBE    ;2=South
  895.     DEC    A
  896.     JP    Z,ATBS    ;3=North
  897.     JP    ATBW    ;Only west left
  898. ATBN:    LD    A,(HL)    ;Get cell data
  899.     LD    DE,-80    ;Displacement to north cell
  900.     AND    2    ;2=north
  901.     JP    Z,ATBX
  902.     ADD    HL,DE    ;Visit north
  903.     LD    A,(HL)    ;Get new cell data
  904.     AND    128    ;Hi bit set means no backtrack
  905.     SUB    128    ;Set zero flag if so
  906.     JP    ATBX
  907. ATBE:    LD    A,(HL)
  908.     AND    4    ;4=east
  909.     JP    Z,ATBX
  910.     INC    HL    ;Visit east cell
  911.     LD    A,(HL)
  912.     AND    128
  913.     SUB    128
  914.     JP    ATBX
  915. ATBS:    LD    A,(HL)
  916.     AND    8    ;8=south
  917.     JP    Z,ATBX
  918.     LD    DE,80
  919.     ADD    HL,DE    ;Visit south
  920.     LD    A,(HL)
  921.     AND    128
  922.     SUB    128
  923.     JP    ATBX
  924. ATBW:    LD    A,(HL)
  925.     AND    16    ;16=west
  926.     JP    Z,ATBX
  927.     DEC    HL    ;Visit west
  928.     LD    A,(HL)
  929.     AND    128
  930.     SUB    128
  931. ATBX:    JP    NZ,ATOK ;If OK, complete backtrack
  932.     LD    A,(DIRECT)
  933.     DEC    A    ;Turn left (after failure)
  934.     JP    NZ,ATBX1
  935.     ADD    A,4
  936. ATBX1:    JP    ATB1    ;& try again
  937. ATOK:    LD    C,4    ;Restore cell count
  938.     LD    (HERE),HL ;This completes the move
  939.     LD    HL,(LAST)
  940.     LD    A,(HL)    ;Get data for previous cell
  941.     OR    128    ;Set Hi bit to prevent backtrack
  942.     LD    (HL),A    ;Store it
  943.     RRA        ;Get rid of Lo bit
  944.     AND    0FH
  945.     OR    MGRAPH    ;Mask for graphic display (no dot)
  946.     LD    HL,(LASTSCR)
  947.     LD    (HL),A    ;Remove dot from screen
  948.     LD    A,(DIRECT)
  949.     INC    A    ;Turn right (after success)
  950.     CP    5
  951.     JP    C,ATOK1
  952.     SUB    4
  953. ATOK1:    LD    (DIRECT),A
  954.     JP    AUT1    ;& try another move
  955. ;
  956. DIRECT:    DB    0
  957. ARATE:    ;Get user's choice of speed
  958.     LD    HL,SCREEN ;Erase top line of screen
  959.     CALL    DELINE
  960.     LD    DE,SCREEN
  961.     CALL    HILITE
  962.     DB    'Enter speed ... 1=Fast, 2=Medium, 3=Slow',0
  963.     CALL    DIRIN
  964.     AND    0FH
  965.     LD    (SPEED),A
  966.     LD    HL,SCREEN ;Erase the message
  967.     CALL    DELINE
  968.     RET
  969. ;
  970. PRESS:    ;Get a keystroke, at the same time build a random seed
  971.     PUSH    HL
  972.     PUSH    DE
  973.     PUSH    BC
  974.     CALL    PRINT
  975.     DB    CR,LF,'Press any key  ',0
  976.     LD    HL,0
  977. PRS1:    INC    HL
  978.     LD    C,DIRIO
  979.     LD    DE,0FFH
  980.     CALL    BDOS
  981.     OR    A
  982.     JP    Z,PRS1
  983.     LD    (RANDY),HL
  984.     POP    BC
  985.     POP    DE
  986.     POP    HL
  987.     RET
  988. RANDY:    DW    0    ;Random seed
  989. ;
  990. RAND:    ;***** Get a random number (Mod A)
  991.     PUSH    AF
  992.     LD    HL,(RANDY)
  993.     LD    A,L
  994.     AND    0F0H
  995.     LD    L,A    ;Get Hi nybble of L
  996.     LD    A,H
  997.     AND    0FH
  998.     ADD    A,L    ;Add Lo nybble of H
  999.     LD    C,A    ;Multiply A
  1000.     LD    A,R    ;by contents of refresh register
  1001.     LD    B,A
  1002.     LD    H,0
  1003.     XOR    A
  1004. RND1:    ADD    A,B
  1005.     JR    NC,RND2
  1006.     INC     H
  1007. RND2:    DEC    C
  1008.     JR    NZ,RND1
  1009.     LD    L,A
  1010.     LD    (RANDY),HL ;Use result as next seed
  1011.     LD    A,H
  1012.     POP    BC    ;Get modulo in B
  1013. RND3:    SUB    B    ;& divide
  1014.     JR    NC,RND3
  1015.     ADD    A,L
  1016. RND4:    SUB    B
  1017.     JR    NC,RND4
  1018.     ADD    A,B
  1019.     INC    A    ;Return RND(A)+1
  1020.     RET
  1021. ;
  1022. HLBDOS:; BDOS call saving register pairs
  1023.     PUSH    HL
  1024.         PUSH   DE
  1025.     PUSH    BC
  1026.     LD    C,A    ;Receives BDOS function if A
  1027.         CALL   BDOS
  1028.     POP    BC
  1029.         POP    DE
  1030.         POP    HL
  1031.         RET
  1032. ;
  1033. PUTCH:  ; Output char in A to console
  1034.     PUSH    BC
  1035.     PUSH    DE
  1036.     PUSH    HL
  1037.         PUSH    AF
  1038.     LD    E,A
  1039.     LD    C,2
  1040.     CALL    BDOS
  1041.     POP    AF
  1042.     POP    HL
  1043.     POP    DE
  1044.     POP    BC
  1045.     RET
  1046. ;
  1047. PUTS:   ; Output string pointed to by HL to console
  1048.     LD    A,(HL)
  1049.     OR    A
  1050.     RET    Z
  1051.     CALL    PUTCH
  1052.     INC    HL
  1053.     JP    PUTS
  1054.     RET
  1055. ;
  1056. DIRIN:    ;Wait for direct input
  1057.     PUSH    DE
  1058.     PUSH    BC
  1059. DIN1:    LD    A,DIRIO
  1060.     LD    DE,0FFH
  1061.     CALL    HLBDOS
  1062.     OR    A
  1063.     JP    Z,DIN1
  1064.     POP    BC
  1065.     POP    DE
  1066.     RET
  1067. ;
  1068. PRINT:  ;Output a string pointed to by contents of top of stack
  1069. ;            delimited by zero, to console.
  1070.         EX    (SP),HL    ;Put pointer to string in HL 
  1071.     XOR    A    ;Clear register & flags
  1072.     ADD    A,(HL)    ;Put char in A set/reset Z flag
  1073.     INC    HL    ;Point to next char (or return addr
  1074.             ;if current char a zero)
  1075.     EX    (SP),HL    ;and save itè    RET    Z    ;Return on delimiter (zero)
  1076.     CALL    PUTCH    ;Display char
  1077.         JP      PRINT    ;and get another char.
  1078. ;
  1079. HILITE:    ;Output a highlighted string to screen area -> by DE
  1080.         EX    (SP),HL    ;Put pointer to string in HL 
  1081.     XOR    A    ;Clear register & flags
  1082.     ADD    A,(HL)    ;Put char in A set/reset Z flag
  1083.     INC    HL    ;Point to next char (or return addr
  1084.             ;if current char a zero)
  1085.     EX    (SP),HL    ;and save itè    RET    Z    ;Return on delimiter (zero)
  1086.     OR    128    ;Set Hilite bit
  1087.     LD    (DE),A    ;and display char
  1088.     INC    DE
  1089.         JP      HILITE    ;and get another char.
  1090. ;
  1091. DELINE: ;Delete line -> by HL
  1092.     LD    D,H
  1093.     LD    E,L
  1094.     INC    DE
  1095.     LD    (HL),' '
  1096.     LD    BC,80
  1097.     LDIR
  1098.     RET
  1099. ;
  1100. GETSTR: ; Input console message into buffer
  1101.     PUSH    BC
  1102.     PUSH    HL
  1103.     PUSH    DE
  1104.     LD    HL,TBUF+1 ;Clear  char counter
  1105.     LD    (HL),0
  1106.     DEC    HL    ;Set maximum line length
  1107.     LD    (HL),80 ;in first byte of buffer
  1108.     EX    DE,HL    ;Switch to DE for BDOS Call
  1109.     LD    A,LINEIN
  1110.     CALL    HLBDOS    ;Call BDOS line input function
  1111.     LD    HL,TBUF+1 ;Get char count
  1112.     LD    E,(HL)    ;into LSB of DE
  1113.     LD    A,(HL)    ;and into A for return data
  1114.     LD    D,0    ;and zero MSB
  1115.     ADD    HL,DE    ;Add length to start
  1116.     INC    HL    ;plus 1 points to end
  1117.     LD    (HL),0    ;Insert zero as delimiter
  1118.     POP    HL
  1119.     POP    DE
  1120.     POP    BC
  1121.     RET
  1122. ;
  1123. SETDMA: ; -> DE points to transient buffer
  1124.     LD    A,26
  1125.     CALL    HLBDOS
  1126.     RET
  1127. ;
  1128. CPHLDE:    ;Compare HL & DE registers
  1129.     PUSH    HL
  1130.     PUSH    DE
  1131.     OR    A
  1132.     SBC    HL,DE
  1133.     POP    DE
  1134.     POP    HL
  1135.     RET    
  1136. ;
  1137. TWOCR:    CALL    CRLF    ;Execute <CR> & <LF> twice
  1138. CRLF:    PUSH    AF
  1139.     LD    A,CR
  1140.     CALL    PUTCH    ;Execute <CR>
  1141.     LD    A,0AH
  1142.     CALL    PUTCH    ;Execute <LF>
  1143.     POP    AF
  1144.     RET
  1145. ;
  1146.  
  1147. LASTBUF: DB    0    ;Mark last byte of program
  1148. END
  1149.