home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 1 / GoldFishApril1994_CD1.img / d2xx / d248 / maze / maze.asm < prev    next >
Assembly Source File  |  1989-09-16  |  27KB  |  777 lines

  1.         TTL        Maze
  2. *
  3. *******************************************************************************
  4. *                                          *
  5. *    Maze                                      *
  6. *                                          *
  7. *    Copyright (c) 1989 by Michael Sinz    MKSoft Development          *
  8. *                                          *
  9. *    AmigaDOS EXEC release 1.2 or greater...                      *
  10. *                                          *
  11. *******************************************************************************
  12. *                                          *
  13. *    Reading legal mush can turn your bain into guacamole!              *
  14. *                                          *
  15. *        So here is some of that legal mush:                  *
  16. *                                          *
  17. * Permission is hereby granted to distribute this program's source          *
  18. * executable, and documentation for non-comercial purposes, so long as the    *
  19. * copyright notices are not removed from the sources, executable or          *
  20. * documentation.  This program may not be distributed for a profit without    *
  21. * the express written consent of the author Michael Sinz.              *
  22. *                                          *
  23. * This program is not in the public domain.                      *
  24. *                                          *
  25. * Fred Fish is expressly granted permission to distribute this program's      *
  26. * source and executable as part of the "Fred Fish freely redistributable      *
  27. * Amiga software library."                              *
  28. *                                          *
  29. * Permission is expressly granted for this program and it's source to be      *
  30. * distributed as part of the Amicus Amiga software disks, and the          *
  31. * First Amiga User Group's Hot Mix disks.                      *
  32. *                                          *
  33. *******************************************************************************
  34. *                                          *
  35. *    This program is not very usefull on its own, but it is an interesting *
  36. *    680x0 problem.  I have tried to make use of the registers as best     *
  37. *    as possible.  The speed of the generation of the maze is, it seems,   *
  38. *    limited by graphics.library and not the CPU.  I am running this on    *
  39. *    a 2620 and a base Amiga and see very little difference in speed...    *
  40. *                                          *
  41. *    The code is FULLY re-entrant and can be made resident.              *
  42. *                                          *
  43. *    I hope you enjoy the code...                          *
  44. *                                          *
  45. *******************************************************************************
  46. *                                          *
  47. * Options for assembling Maze.asm...  (Defines...)                  *
  48. *                                          *
  49. *    Xmax/Ymax    - Set the size of the window...                  *
  50. *    DOUBLE        - Uses the DOUBLE-LOOP reset random number...          *
  51. *    EASYMAZE    - Uses the old maze-making method...              *
  52. *    PRINT        - Add the code needed to print the maze...          *
  53. *                                          *
  54. *******************************************************************************
  55. *                                          *
  56. *    To assemble, I used the assembler that comes with MANX C68K          *
  57. *                                          *
  58. *    It should assemble without any problems on most 680x0 assemblers      *
  59. *                                          *
  60. *    Note to persons trying to assemble on other assemblers:              *
  61. *    I have a habbit for using bcc.s (bra.s, etc) for ALL jumps.          *
  62. *    This may be a problem in some assemblers/with certain options.          *
  63. *    Sorry...  (Bad habbits are hard to break...  ;-(  )              *
  64. *                                          *
  65. *******************************************************************************
  66. *
  67. * The following INCLUDE files are needed to make this program assemble.
  68. * They come with the Amiga Macro-Assembler Package.
  69. *
  70.     NOMLIST                    ; No macro expansion list
  71.     NOCLIST                    ; No conditional list
  72.     NOLIST                    ; No need to list these
  73.     INCLUDE    "EXEC/Types.i"
  74.     INCLUDE    "EXEC/Libraries.i"
  75.     INCLUDE    "EXEC/Ables.i"
  76.     INCLUDE    "EXEC/Memory.i"
  77.     INCLUDE    "EXEC/IO.i"
  78.     INCLUDE    "EXEC/Nodes.i"
  79.     INCLUDE    "EXEC/Lists.i"
  80.     INCLUDE    "Devices/Printer.i"
  81.     INCLUDE    "Graphics/GfxBase.i"
  82.     INCLUDE    "Graphics/RastPort.i"
  83.     INCLUDE    "Intuition/IntuitionBase.i"
  84.     INCLUDE    "Intuition/Intuition.i"
  85.     INCLUDE    "Libraries/DOSextens.i"
  86.     LIST                    ; Ok, lets start the listing
  87. *
  88. *******************************************************************************
  89. *
  90. * This is the only fixed address in the system...
  91. *
  92.         xref    _AbsExecBase
  93. *
  94. *******************************************************************************
  95. *
  96. * Some macros that make calling the system routines easier...
  97. *
  98. CALLSYS        MACRO
  99.         xref    _LVO\1        ; Set the external reference
  100.         CALLLIB    _LVO\1        ; Call the EXEC definied macro
  101.         ENDM
  102. *
  103. *******************************************************************************
  104. *
  105. * Offsets from the stack that contain the following...
  106. *
  107. my_Left        equ    0        ; Left 0
  108. my_Top        equ    2        ; Top 0
  109. my_Right    equ    4        ; Right MAX
  110. my_Bottom    equ    6        ; Left MAX
  111. intuitionBASE    equ    8        ; Where IntuitionBase is stored...
  112. *
  113. *******************************************************************************
  114. *
  115. * These are the sizes in X and Y of the 'Block' that is used...
  116. * X_Size/Y_Size should be ODD and less than 8...
  117. *
  118. X_Size        equ    5        ; Size in X
  119. Y_Size        equ    3        ; Size in Y
  120. *
  121. X_Size_Mod    equ    (X_Size-1)/2
  122. Y_Size_Mod    equ    (Y_Size-1)/2
  123. *
  124. *******************************************************************************
  125. *
  126. * These define the size of the window...  If not defined by assembler
  127. * parameter, these values are used...
  128. *
  129.     IFD Xmax
  130. XMax        equ    Xmax        ; Use the parameter from the user...
  131.     ELSE
  132. XMax        equ    509        ; X size for window...
  133.     ENDC
  134. *
  135.     IFD Ymax
  136. YMax        equ    Ymax        ; Use the parameter from the user...
  137.     ELSE
  138. YMax        equ    171        ; Y size for window...
  139.     ENDC
  140. *
  141. *******************************************************************************
  142. *
  143. BACKpen        equ    3        ; Pen for the background colour...
  144. *
  145. *******************************************************************************
  146. *
  147. * Bits for the different directions...
  148. *
  149. LEFT_Bit    equ    0
  150. RIGHT_Bit    equ    1
  151. UP_Bit        equ    2
  152. DOWN_Bit    equ    3
  153. *
  154. *******************************************************************************
  155. *                                          *
  156. * Register usage through this program...                      *
  157. *                                          *
  158. *    a0    - Scrap                                  *
  159. *    a1    - Scrap                                  *
  160. *    a2    - GFX Base saved...                          *
  161. *    a3    - RastPort...                              *
  162. *    a4    - Window pointer...                          *
  163. *    a5    - EXEC Base saved...                          *
  164. *    a6    - Library Base Register...                      *
  165. *    a7    - Stack...  (What else?)                      *
  166. *                                          *
  167. *    d0    - Scrap                                  *
  168. *    d1    - Scrap                                  *
  169. *    d2    - Random Number seed...                          *
  170. *    d3    - Bit Pattern of possible moves...                  *
  171. *    d4    - Current X                              *
  172. *    d5    - Current Y                              *
  173. *    d6    - Intuition Base (and ....)                      *
  174. *    d7    - Zero...                              *
  175. *                                          *
  176. *******************************************************************************
  177. *
  178. * Now, for the start of the code...
  179. *
  180. Maze:        move.l    _AbsExecBase,a6        ; Get the EXEC library base
  181.         move.l    a6,a5            ; Save it...
  182.         clr.l    d7            ; Clear d7...
  183. *
  184.         move.l    d7,a1        ; Clear a1
  185.         CALLSYS    FindTask    ; Get our task pointer...
  186.         move.l    d0,a4        ; Now, move it to a4 for addressing use
  187.         lea    pr_MsgPort(a4),a3
  188.         tst.l    pr_CLI(a4)    ; Check if this is a CLI task...
  189.         bne.s    QuickCLI    ; If so, skip the next section
  190. *
  191. *******************************************************************************
  192. *
  193. * This section deals with starting from the WorkBench...
  194. * It is just here for completeness...
  195. *
  196. QuickWorkBench:    move.l    a3,a0        ; Get message port
  197.         CALLSYS    WaitPort    ; Wait for the WorkBench message...
  198.         move.l    a3,a0        ; ...it's here, so let's get it
  199.         CALLSYS    GetMsg        ; off the message port...
  200.         bra.s    QuickCont    ; ...and go to the continue routine
  201. *
  202. *******************************************************************************
  203. *
  204. * The routine was started from the CLI  (prefered)
  205. * Let's store a NULL pointer so that there is no WB message...
  206. *
  207. QuickCLI:    move.l    d7,d0        ; No reply message...
  208. *
  209. *******************************************************************************
  210. *
  211. * Continue with the Quick initialization
  212. *
  213. QuickCont:    move.l    d0,-(sp)    ; Save the message pointer...
  214. *
  215. *******************************************************************************
  216. *
  217. * Ok, we are now ready to do some real work...
  218. *
  219.         lea    intuitionName(pc),a1    ; Get LIB name...
  220.         move.l    d7,d0            ; ANY version, I guess...
  221.         CALLSYS    OpenLibrary        ; Open it...
  222.         move.l    d0,d6            ; Quick way to check it...
  223.         beq.s    abortNoIntuit        ; No intuition, we abort...
  224.         lea    graphicsName(pc),a1    ; Get LIB name...
  225.         move.l    d7,d0            ; Any version...
  226.         CALLSYS    OpenLibrary        ; Open it...
  227.         move.l    d0,a2            ; Save it...
  228.         move.l    a2,d0            ; And check...
  229.         beq.s    abortNoGfx        ; Abort if we can't get it...
  230. *
  231. *******************************************************************************
  232. *
  233. * Now, open a window...
  234. *
  235.         lea    NewWindowStuff(pc),a0    ; Point to the NewWindow...
  236.         move.l    d6,a6            ; Set IntuitionBase...
  237.         CALLSYS    OpenWindow        ; Open it...
  238.         move.l    d0,a4            ; Save the pointer...
  239.         move.l    a4,d0            ; Check it...
  240.         beq.s    abortNoWindow        ; No window, so abort...
  241.         move.l    wd_RPort(a4),a3        ; Get rastport...
  242.         move.l    d6,-(sp)        ; Save the intuition pointer
  243. *
  244. *******************************************************************************
  245. *
  246. * Ok, now we fill the screen with the block pen...
  247. *
  248.         move.l    a2,a6            ; We will be doing Gfx stuff...
  249.         moveq.l    #BACKpen,d0        ; Pen number...
  250.         move.l    a3,a1            ; Get RPort...
  251.         CALLSYS    SetAPen            ; Set the pen...
  252.         move.w    wd_Height(a4),d3    ; Window Y size...
  253.         move.w    wd_Width(a4),d2        ; Window X size...
  254.         move.b    wd_BorderBottom(a4),d0    ; the bottom border...
  255.         ext.w    d0            ; Extend it to a word...
  256.         sub.w    d0,d3            ; subtract it from d3...
  257.         move.b    wd_BorderRight(a4),d0    ; the right border...
  258.         ext.w    d0            ; Extend it...
  259.         sub.w    d0,d2            ; Subtrack it from d2...
  260.         move.b    wd_BorderTop(a4),d1    ; Get top border...
  261.         ext.w    d1            ; Extend it...
  262.         move.b    wd_BorderLeft(a4),d0    ; Get left border...
  263.         ext.w    d0            ; Extend it...
  264.         subq.l    #1,d2            ; We need to adjust a bit...
  265.         subq.l    #1,d3
  266.         movem.w    d0-d3,-(sp)        ; Save these values...
  267.         move.l    a3,a1            ; Make sure we have RPort...
  268.         CALLSYS    RectFill        ; Fill it...
  269.         move.l    a3,a1            ; (It may have trashed it...)
  270.         move.l    d7,d0            ; Set pen to 0...
  271.         CALLSYS    SetAPen            ; (We will erase the bad areas)
  272. *
  273. *******************************************************************************
  274. *
  275. * The window is now pained and ready to rock...  We just need to do a few
  276. * adjustments on the limits...
  277. *
  278.         movem.w    (sp)+,d0-d3        ; Get the limits...
  279.         addq.l    #X_Size,d0        ; Adjust inwards...
  280.         subq.l    #X_Size,d2
  281.         addq.l    #Y_Size,d1
  282.         subq.l    #Y_Size,d3
  283.         movem.w    d0-d3,-(sp)        ; Save them again...
  284.         move.l    d0,d4            ; Get the initial X
  285.         move.l    d1,d5            ;    and Y
  286.         bsr    PutBlock        ; And put it down...
  287. *
  288. *******************************************************************************
  289. *
  290. * Ok, now we start the maze loop.  This should be interesting...
  291. *
  292. MazeLoop:    move.l    d7,d6            ; Clear the DONE flag...
  293.         move.w    my_Left(sp),d4        ; Get the starting X
  294. MazeLoop1:    move.w    my_Top(sp),d5        ; Get the starting Y
  295. *
  296. * Check this spot for more work...
  297. *
  298. MazeLoop2:    move.w    d4,d0            ; Get X
  299.         move.w    d5,d1            ;    and Y
  300.         move.l    a3,a1            ; RPort...
  301.         CALLSYS    ReadPixel        ; Check what it is...
  302.         tst.b    d0            ; If it is
  303.         beq.s    FoundSpot        ;   0 - Possible continue...
  304.         moveq    #1,d6            ; Empty means we come again...
  305. *
  306. * Move to next spot...
  307. *
  308. MazeNext:    addq.l    #Y_Size,d5        ; Go to next point...
  309.         addq.l    #Y_Size,d5        ;    (Y+ 2*Y_Size)
  310.         cmp.w    my_Bottom(sp),d5    ; Check if we went too far...
  311.         bcs.s    MazeLoop2        ; Try again...
  312.         addq.l    #X_Size,d4        ; Go to next column
  313.         addq.l    #X_Size,d4        ;    (X+ 2*X_Size)
  314.         cmp.w    my_Right(sp),d4        ; Check it...
  315.         bcs.s    MazeLoop1        ; Ok, so we continue...
  316.         tst.l    d6            ; Check our flag...
  317.         bne.s    MazeLoop        ; If not zero, go again...
  318.         bra.s    WaitForClose        ; All, done, wait for user...
  319. *
  320. *******************************************************************************
  321. *
  322. * Ok, we are at a possible spot.  Let's check it out...
  323. *
  324. FoundSpot:    move.l    d7,d3            ; Clear bit pattern...
  325. *
  326. * Check to the left...
  327. *
  328. CheckLeft:    move.l    d5,d1            ; Get Y...
  329.         move.l    d4,d0            ; Get X...
  330.         subq.l    #X_Size,d0        ; Adjust to the left...
  331.         subq.l    #X_Size,d0
  332.         cmp.w    my_Left(sp),d0        ; Check if out of bounds...
  333.         blt.s    CheckRight        ; If no good, skip...
  334.         move.l    a3,a1            ; Get RPort...
  335.         CALLSYS    ReadPixel        ; Get the pixel...
  336.         tst.b    d0            ; Check it...
  337.         beq.s    CheckRight        ; Skip to next check...
  338.         bset    #LEFT_Bit,d3        ; Set the bit...
  339. *
  340. * Check to the right...
  341. *
  342. CheckRight:    move.l    d5,d1            ; Get Y...
  343.         move.l    d4,d0            ; Get X...
  344.         addq.l    #X_Size,d0        ; Adjust to the right...
  345.         addq.l    #X_Size,d0
  346.         cmp.w    my_Right(sp),d0        ; Check if out of bounds...
  347.         bgt.s    CheckUp            ; If no good, skip...
  348.         move.l    a3,a1            ; Get RPort...
  349.         CALLSYS    ReadPixel        ; Get the pixel...
  350.         tst.b    d0            ; Check it...
  351.         beq.s    CheckUp            ; Skip to next check...
  352.         bset    #RIGHT_Bit,d3        ; Set the bit...
  353. *
  354. * Check up...
  355. *
  356. CheckUp:    move.l    d4,d0            ; Get X...
  357.         move.l    d5,d1            ; Get Y...
  358.         subq.l    #Y_Size,d1        ; Adjust to the left...
  359.         subq.l    #Y_Size,d1
  360.         cmp.w    my_Top(sp),d1        ; Check if out of bounds...
  361.         blt.s    CheckDown        ; If no good, skip...
  362.         move.l    a3,a1            ; Get RPort...
  363.         CALLSYS    ReadPixel        ; Get the pixel...
  364.         tst.b    d0            ; Check it...
  365.         beq.s    CheckDown        ; Skip to next check...
  366.         bset    #UP_Bit,d3        ; Set the bit...
  367. *
  368. * Check Down...
  369. *
  370. CheckDown:    move.l    d4,d0            ; Get X...
  371.         move.l    d5,d1            ; Get Y...
  372.         addq.l    #Y_Size,d1        ; Adjust to the left...
  373.         addq.l    #Y_Size,d1
  374.         cmp.w    my_Bottom(sp),d1    ; Check if out of bounds...
  375.         bgt.s    CheckDone        ; If no good, skip...
  376.         move.l    a3,a1            ; Get RPort...
  377.         CALLSYS    ReadPixel        ; Get the pixel...
  378.         tst.b    d0            ; Check it...
  379.         beq.s    CheckDone        ; Skip to next end of check...
  380.         bset    #DOWN_Bit,d3        ; Set the bit...
  381. *
  382. * Ok, we checked every-which-way, and now to see if any worked...
  383. *
  384. CheckDone:    tst.l    d3            ; Check if any bits were set...
  385.         beq.s    MazeNext        ; No match, on to the next...
  386.         moveq.l    #1,d6            ; Set Not-Done flag...
  387. *
  388. * So, there is a possible direction.  Let's see if we can find it...
  389. *
  390. TryToFind:    bsr.s    Random            ; Get a random number...
  391.         and.l    d3,d0            ; Mask with the directions...
  392.     IFD DOUBLE
  393.         bne.s    TryToFind1        ; There is a match...
  394.         bsr.s    Random            ; Try again...
  395.         and.l    d3,d0            ; Mask it...
  396.     ENDC
  397.     IFD EASYMAZE
  398.         beq.s    TryToFind        ; Look again...
  399.     ELSE
  400.         beq.s    MazeNext        ; If no match, Next...
  401.     ENDC
  402. TryToFind1:    btst    #UP_Bit,d0        ; Check if UP...
  403.         bne.s    Do_UP            ; Do the up...
  404.         btst    #LEFT_Bit,d0        ; Check if LEFT...
  405.         bne.s    Do_LEFT            ; Do the left...
  406.         btst    #RIGHT_Bit,d0        ; Check if RIGHT...
  407.         bne.s    Do_RIGHT        ; Do the right...
  408. *
  409. * We fall into this...  Do the DOWN...
  410. *
  411. Do_DOWN:    addq.l    #Y_Size,d5        ; Move down...
  412.         bsr.s    PutBlock        ; Put the block...
  413.         addq.l    #Y_Size,d5        ;   down to the next spot...
  414.         bsr.s    PutBlock        ; Put the block...
  415.         bra.s    FoundSpot        ; Go do another...
  416. *
  417. * Do the RIGHT...
  418. *
  419. Do_RIGHT:    addq.l    #X_Size,d4        ; Move over...
  420.         bsr.s    PutBlock        ; Put the block...
  421.         addq.l    #X_Size,d4        ;   over to the next spot...
  422.         bsr.s    PutBlock        ; Put the block...
  423.         bra.s    FoundSpot        ; Go do another...
  424. *
  425. * Do the UP...
  426. *
  427. Do_UP:        subq.l    #Y_Size,d5        ; Move up...
  428.         bsr.s    PutBlock        ; Put the block...
  429.         subq.l    #Y_Size,d5        ;   up to the next spot...
  430.         bsr.s    PutBlock        ; Put the block...
  431.         bra.s    FoundSpot        ; Go do another...
  432. *
  433. * Do the LEFT...
  434. *
  435. Do_LEFT:    subq.l    #X_Size,d4        ; Move over...
  436.         bsr.s    PutBlock        ; Put the block...
  437.         subq.l    #X_Size,d4        ;   over to the next spot...
  438.         bsr.s    PutBlock        ; Put the block...
  439.         bra.s    FoundSpot        ; Go do another...
  440. *
  441. *******************************************************************************
  442. *
  443. * Wait for the user to press the Close gadget...
  444. *
  445. WaitForClose:    lea    DoneTitle(pc),a0    ; Get the address...
  446.         move.l    a0,wd_Title(a4)        ; Set the title...
  447.         move.l    intuitionBASE(sp),a6    ; Get IntuitionBase...
  448.         move.l    a4,a0            ; Get window address...
  449.         CALLSYS    RefreshWindowFrame    ; Refresh it...
  450. WaitForClose1:    move.l    a5,a6            ; Get EXEC base...
  451.         move.l    wd_UserPort(a4),a0    ; Get message port...
  452.         CALLSYS    WaitPort        ; Wait for it...
  453.         move.l    wd_UserPort(a4),a0
  454.         CALLSYS    GetMsg            ; Get the message
  455.         move.l    d0,a1            ; Pointer
  456.         move.l    im_Class(a1),d2        ; Get the message type...
  457.         CALLSYS    ReplyMsg        ; Reply the message...
  458.         cmpi.l    #CLOSEWINDOW,d2        ; Check if it is correct...
  459.         bne.s    WaitForClose1        ; Wait for the close...
  460. *
  461. *******************************************************************************
  462. *
  463.     IFD PRINT
  464.         movem.w    (sp)+,d0-d3        ; Get the limits...
  465.         addq.l    #X_Size,d2        ; Adjust outwards for printing
  466.         subq.l    #X_Size,d0        ;  we need the border around
  467.         addq.l    #Y_Size,d3        ;  the maze grid...
  468.         subq.l    #Y_Size,d1
  469.         movem.w    d0-d3,-(sp)        ; Save them again...
  470.         move.l    intuitionBASE(sp),d6    ; Get IntuitionBase...
  471.         bsr.s    AskPrinting        ; Check if user wants to print
  472.     ENDC
  473. *
  474. *******************************************************************************
  475. *
  476. * The standard exit routines...
  477. * Close anything that we have opened...
  478. *
  479. NormalExit:    movem.l    (sp)+,d0-d1/d6    ; Restore space & intuition pointer...
  480.         move.l    a4,a0        ; Get window pointer...
  481.         move.l    d6,a6        ; Make sure intuitionbase...
  482.         CALLSYS    CloseWindow    ; Close the window...
  483. abortNoWindow:    move.l    a5,a6        ; Get EXECbase back...
  484.         move.l    a2,a1        ; Get GfxBase...
  485.         CALLSYS    CloseLibrary    ; Close it...
  486. abortNoGfx:    move.l    d6,a1        ; Get IntuitionBase...
  487.         CALLSYS    CloseLibrary    ; Close it...
  488. abortNoIntuit:    move.l    (sp)+,d0    ; Get that message back
  489.         beq.s    abortNoWB    ; If none, we are done
  490.         move.l    d0,a1        ; Get the pointer ready
  491.         FORBID            ; manual says we must forbid...
  492.         CALLSYS    ReplyMsg    ; ...when returning WB message
  493. abortNoWB:    rts            ; RTS out of this task...
  494. *
  495. *******************************************************************************
  496. *
  497. * Random number generator...  It uses the two EXECbase values Idle/DispCount
  498. * It will return a number in d0 that SHOULD be RELATIVELY random...  The
  499. * initial value of d0 is used as an extra seed...
  500. *
  501. Random:        add.l    IdleCount(a5),d0    ; Get the idle count...
  502.         add.l    DispCount(a5),d0    ; Pull the rest in...
  503.         eor.l    d2,d0            ; Add in the seed...
  504.         swap    d2            ; Flip the bytes...
  505.         add.l    d0,d2            ; Change the seed...
  506.         rts                ; Return...
  507. *
  508. *******************************************************************************
  509. *
  510. * Draws my 5x5 block at Current X/Y ...
  511. *
  512. PutBlock:    movem.l    d2/d3,-(sp)        ; Save what we mess with...
  513.         move.l    d4,d0            ; Get x...
  514.         subq.l    #X_Size_Mod,d0        ; Drop by 2...
  515.         move.l    d4,d2            ; And the other side...
  516.         addq.l    #X_Size_Mod,d2        ; Up by 2...
  517.         move.l    d5,d1            ; Get y...
  518.         subq.l    #Y_Size_Mod,d1        ; Drop by 2...
  519.         move.l    d5,d3            ; And the other side...
  520.         addq.l    #Y_Size_Mod,d3        ; Up by 2...
  521.         move.l    a3,a1            ; Get RPort...
  522.         CALLSYS    RectFill        ; Draw the block...
  523.         movem.l    (sp)+,d2/d3        ; Restore it...
  524.         rts                ; and return...
  525. *
  526. *******************************************************************************
  527. *                                          *
  528. * Register usage through the print section...                      *
  529. *                                          *
  530. *    a0    - Scrap                                  *
  531. *    a1    - Scrap                                  *
  532. *    a2    - Positive IntuiText...                          *
  533. *    a3    - Negative IntuiText...                          *
  534. *    a4    - PrinterIO union...                          *
  535. *    a5    - EXEC Base saved...                          *
  536. *    a6    - Library Base Register...                      *
  537. *    a7    - Stack...  (What else?)                      *
  538. *                                          *
  539. *    d0    - Scrap                                  *
  540. *    d1    - Scrap                                  *
  541. *    d2    - IntuiText size...                          *
  542. *    d3    - Scrap (Memory type during IntuiText allocations...)          *
  543. *    d4    - Body IntuiText...                          *
  544. *    d5    - RastPort...                              *
  545. *    d6    - Intuition Base (and ....)                      *
  546. *    d7    - Zero...                              *
  547. *                                          *
  548. *******************************************************************************
  549. *
  550. * Ask the user if s/he wishes to print the maze...
  551. *
  552. PrintOffset    equ    16    ; Number of bytes stack moves
  553. *                  due to bsr and the saving of a2/a3/a4...
  554. AskXsize    equ    162    ; AutoRequest X size...
  555. AskYsize    equ    45    ; AutoRequest Y size...
  556. WindowOffset    equ    8    ; Window pointer on stack...
  557. *
  558.     IFD PRINT
  559. AskPrinting:    movem.l    a2-a4,-(sp)        ; Save these...
  560.         move.l    a3,d5            ; Save RastPort pointer...
  561.         move.l    a5,a6            ; Get EXECbase...
  562.         move.l    #it_SIZEOF,d2        ; Size of IntuiText...
  563.         move.l    #MEMF_PUBLIC!MEMF_CLEAR,d3
  564. *
  565. * Now start getting the IntuiText structures...
  566. *
  567.         move.l    d2,d0            ; Get Size...
  568.         move.l    d3,d1            ; Get memory type...
  569.         CALLSYS    AllocMem
  570.         move.l    d0,d4            ; Save BodyText...
  571.         beq.s    NoBodyText        ; If none, exit...
  572.         move.l    d2,d0            ; Get Size...
  573.         move.l    d3,d1            ; Get memory type...
  574.         CALLSYS    AllocMem
  575.         move.l    d0,a2            ; Save PositiveText...
  576.         move.l    a2,d0            ; Check it...
  577.         beq.s    NoPositiveText        ; If none, exit...
  578.         move.l    d2,d0            ; Get Size...
  579.         move.l    d3,d1            ; Get memory type...
  580.         CALLSYS    AllocMem
  581.         move.l    d0,a3            ; Save NegativeText...
  582.         move.l    a3,d0            ; Check it...
  583.         beq.s    NoNegativeText        ; If none, exit...
  584. *
  585. * Now, set up the structures...
  586. *
  587.         move.l    d4,a1            ; Put it somewhere we can use
  588. *
  589.         moveq.l    #2,d0            ; Get it_FrontPen...
  590.         move.b    d0,it_FrontPen(a1)    ; Save in BodyText...
  591.         move.b    d0,it_FrontPen(a2)    ; Save in PositiveText...
  592.         move.b    d0,it_FrontPen(a3)    ; Save in NegativeText...
  593. *
  594.         moveq.l    #3,d0            ; Get it_BackPen...
  595.         move.b    d0,it_BackPen(a1)    ; Save in BodyText...
  596.         move.b    d0,it_BackPen(a2)    ; Save in PositiveText...
  597.         move.b    d0,it_BackPen(a3)    ; Save in NegativeText...
  598. *
  599.         moveq.l    #RP_JAM1,d0        ; Get it_DrawMode...
  600.         move.b    d0,it_DrawMode(a1)    ; Save in BodyText...
  601.         move.b    d0,it_DrawMode(a2)    ; Save in PositiveText...
  602.         move.b    d0,it_DrawMode(a3)    ; Save in NegativeText...
  603. *
  604.         moveq.l    #6,d0            ; Get LeftEdge...
  605.         move.w    d0,it_LeftEdge(a1)    ; Save in BodyText...
  606.         move.w    d0,it_LeftEdge(a2)    ; Save in PositiveText...
  607.         move.w    d0,it_LeftEdge(a3)    ; Save in NegativeText...
  608. *
  609.         moveq.l    #3,d0            ; Get TopEdge...
  610.         move.w    d0,it_TopEdge(a1)    ; Save in BodyText...
  611.         move.w    d0,it_TopEdge(a2)    ; Save in PositiveText...
  612.         move.w    d0,it_TopEdge(a3)    ; Save in NegativeText...
  613. *
  614.         lea    Text_Attr(pc),a0    ; Get address of font...
  615.         move.l    a0,it_ITextFont(a1)    ; Save in BodyText...
  616.         move.l    a0,it_ITextFont(a2)    ; Save in PositiveText...
  617.         move.l    a0,it_ITextFont(a3)    ; Save in NegativeText...
  618. *
  619.         lea    AskMessage(pc),a0    ; Get address of Body...
  620.         move.l    a0,it_IText(a1)        ; Save in BodyText...
  621.         lea    OkMessage(pc),a0    ; Get address of Positive...
  622.         move.l    a0,it_IText(a2)        ; Save in PositiveText...
  623.         lea    NoMessage(pc),a0    ; Get address of Negative...
  624.         move.l    a0,it_IText(a3)        ; Save in NegativeText...
  625. *
  626. AskTheUser:    move.l    WindowOffset(sp),a0    ; Get window...
  627.         move.l    d7,d0            ; Clear Positive Flags...
  628.         move.l    d7,d1            ; Clear Negative Flags...
  629.         move.l    d2,-(sp)        ; Save IntuiText Size...
  630.         move.l    #AskXsize,d2        ; Get X-size...
  631.         move.l    #AskYsize,d3        ; Get Y-size...
  632.         move.l    d6,a6            ; Get intuitionBASE...
  633.         CallSYS    AutoRequest        ; Ask the user...
  634.         move.l    a5,a6            ; Restore ExecBase...
  635.         move.l    (sp)+,d2        ; Restore...
  636.         tst.l    d0            ; Check the result...
  637.         beq.s    NoPrint            ; If FALSE, no-print...
  638. *
  639. *******************************************************************************
  640. *
  641. * Ok, we must print now.
  642. *
  643.         move.l    #iodrpr_SIZEOF,d0    ; Size of IODRPReq...
  644.         move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  645.         CallSYS    AllocMem        ; Get memory...
  646.         move.l    d0,a4            ; Get pointer...
  647.         move.l    a4,d0            ; Check it...
  648.         beq.s    ExitPrint        ; Can't get IODRPReq...
  649. *
  650.         move.l    d7,a1            ; Clear a1...
  651.         CallSYS    FindTask        ; Get our task...
  652.         move.l    d0,a1            ; Move it into a1...
  653.         lea    pr_MsgPort(a1),a1    ; Point to message port...
  654.         move.l    a1,MN_REPLYPORT(a4)    ; Save the reply port...
  655.         move.l    #iodrpr_SIZEOF-MN_SIZE,MN_LENGTH(a4)    ; Save size...
  656. *
  657.         lea    PrinterName(pc),a0    ; Get name of printer
  658.         move.l    d7,d0            ; Clear unit number...
  659.         move.l    d7,d1            ; Clear flags...
  660.         move.l    a4,a1            ; Get pointer to PrinterIO
  661.         CallSYS    OpenDevice        ; Open printer.device...
  662.         tst.l    d0            ; Check for error...
  663.         bne.s    PrinterError        ; Can't open printer...
  664. *
  665.         lea    ColourMap(pc),a0    : Pointer to colour map...
  666.         move.l    a0,io_ColorMap(a4)    ; Store it...
  667.         move.l    d5,io_RastPort(a4)    ; Pointer to RastPort...
  668. *        move.l    #V_HIRES,io_Modes(a4)    ; Set mode to HiRes...
  669. *
  670. * This sets the x/y start/end of the RastPort to dump...
  671. *
  672.         move.w    PrintOffset+my_Left(sp),d0
  673.         move.w    d0,io_SrcX(a4)        ; Start of rectangle-X
  674.         move.w    PrintOffset+my_Right(sp),d1
  675.         sub.w    d0,d1
  676.         move.w    d1,io_SrcWidth(a4)    ; Size of rectangle-X
  677. *
  678.         move.w    PrintOffset+my_Top(sp),d0
  679.         move.w    d0,io_SrcY(a4)        ; Start of rectangle-Y
  680.         move.w    PrintOffset+my_Bottom(sp),d1
  681.         sub.w    d0,d1
  682.         move.w    d1,io_SrcHeight(a4)    ; Size of rectangle-Y
  683. *
  684. * Set the special to FULL size
  685. *
  686.         move.w    #SPECIAL_FULLCOLS!SPECIAL_FULLROWS,io_Special(a4)
  687. *
  688. * And, finally, the DumpRPort command...
  689. *
  690.         move.w    #PRD_DUMPRPORT,IO_COMMAND(a4)    ; Printer command...
  691. *
  692.         move.l    a4,a1            ; Get PrinterIO....
  693.         CallSYS    DoIO            ; Send the command...
  694.         move.l    a4,a1            ; Get PrinterIO...
  695.         CallSYS    CloseDevice        ; Close it...
  696. PrinterError:    move.l    a4,a1            ; Pointer to PrinterIO
  697.         move.l    #iodrpr_SIZEOF,d0    ; Size of PrinterIO...
  698.         CallSYS    FreeMem            ; Release the memory...
  699. ExitPrint:    move.l    d4,a1            ; Get body text again...
  700.         bra.s    AskTheUser        ; Ask again...
  701. *
  702. *******************************************************************************
  703. *
  704. * Exit the print routine, freeing all memory that we have...
  705. *
  706. NoPrint:    move.l    a3,a1            ; Get address
  707.         move.l    d2,d0            ; Get Size
  708.         CallSYS    FreeMem
  709. NoNegativeText:    move.l    a2,a1            ; Get address
  710.         move.l    d2,d0            ; Get Size
  711.         CallSYS    FreeMem
  712. NoPositiveText:    move.l    d4,a1            ; Get address
  713.         move.l    d2,d0            ; Get Size
  714.         CallSYS    FreeMem
  715. NoBodyText:    movem.l    (sp)+,a2-a4        ; Restore them again...
  716.         rts
  717.     ENDC
  718. *
  719. *******************************************************************************
  720. *
  721. * The data section...
  722. *
  723. NewWindowStuff    dc.w    0,11,XMax,YMax    ; The window pos/size
  724.         dc.b    2,1        ; Window pens...
  725.         dc.l    CLOSEWINDOW    ; IDCMP setting...
  726.         dc.l    WINDOWCLOSE!WINDOWDEPTH!WINDOWDRAG    ; Smart refresh
  727.         dc.l    0,0        ; No gadgets/checkmark
  728.         dc.l    TheTitle    ; The title of the window...
  729.         dc.l    0,0        ; No screen/bitmap...
  730.         dc.w    0,0,0,0        ; No sizing stuff...
  731.         dc.w    WBENCHSCREEN    ; The window's screen...
  732. *
  733. DoneTitle:    dc.b    'Done!  '
  734. TheTitle:    dc.b    'MKSoft MAZE Maker',0
  735. intuitionName    dc.b    'intuition.library',0
  736. graphicsName    dc.b    'graphics.library',0
  737. *
  738. *******************************************************************************
  739. *
  740. * This is the data section if PRINT is defined...
  741. *
  742.     IFD PRINT
  743.         ds.l    0        ; Make sure we long-align...
  744. *
  745. * This colour map is used for the DumpRPort call to make the maze walls
  746. * black and all else white...
  747. *
  748. ColourMap:    dc.b    0
  749.         dc.b    0
  750.         dc.w    4        ; Number of entries
  751.         dc.l    ColourTable    ; Pointer...
  752. ColourTable:    dc.w    $0FFF        ; White for colours 0 to 2...
  753.         dc.w    $0FFF
  754.         dc.w    $0FFF
  755.         dc.w    $0000        ; Black for colour 3...
  756. *
  757. Text_Attr:    dc.l    FontName    ; Name of the font...
  758.         dc.w    8        ; Y-Size of font...
  759.         dc.b    0        ; No style flags...
  760.         dc.b    0        ; No flags...
  761. FontName:    dc.b    'topaz.font',0
  762. *
  763. AskMessage:    dc.b    'Print this maze?',0
  764. OkMessage:    dc.b    'Yes',0
  765. NoMessage:    dc.b    'No',0
  766. *
  767. PrinterName:    dc.b    'printer.device',0
  768.     ENDC
  769. *
  770. *******************************************************************************
  771. *
  772. * And, with that we come to the end of another full-length feature staring
  773. * that wonderful MC680x0 and the Amiga system.  Join us again next time
  774. * for more Wonderful World of Amiga...  Until then, keep boinging...
  775. *
  776.         end
  777.