TTL Maze * ******************************************************************************* * * * Maze * * * * Copyright (c) 1989 by Michael Sinz MKSoft Development * * * * AmigaDOS EXEC release 1.2 or greater... * * * ******************************************************************************* * * * Reading legal mush can turn your bain into guacamole! * * * * So here is some of that legal mush: * * * * Permission is hereby granted to distribute this program's source * * executable, and documentation for non-comercial purposes, so long as the * * copyright notices are not removed from the sources, executable or * * documentation. This program may not be distributed for a profit without * * the express written consent of the author Michael Sinz. * * * * This program is not in the public domain. * * * * Fred Fish is expressly granted permission to distribute this program's * * source and executable as part of the "Fred Fish freely redistributable * * Amiga software library." * * * * Permission is expressly granted for this program and it's source to be * * distributed as part of the Amicus Amiga software disks, and the * * First Amiga User Group's Hot Mix disks. * * * ******************************************************************************* * * * This program is not very usefull on its own, but it is an interesting * * 680x0 problem. I have tried to make use of the registers as best * * as possible. The speed of the generation of the maze is, it seems, * * limited by graphics.library and not the CPU. I am running this on * * a 2620 and a base Amiga and see very little difference in speed... * * * * The code is FULLY re-entrant and can be made resident. * * * * I hope you enjoy the code... * * * ******************************************************************************* * * * Options for assembling Maze.asm... (Defines...) * * * * Xmax/Ymax - Set the size of the window... * * DOUBLE - Uses the DOUBLE-LOOP reset random number... * * EASYMAZE - Uses the old maze-making method... * * PRINT - Add the code needed to print the maze... * * * ******************************************************************************* * * * To assemble, I used the assembler that comes with MANX C68K * * * * It should assemble without any problems on most 680x0 assemblers * * * * Note to persons trying to assemble on other assemblers: * * I have a habbit for using bcc.s (bra.s, etc) for ALL jumps. * * This may be a problem in some assemblers/with certain options. * * Sorry... (Bad habbits are hard to break... ;-( ) * * * ******************************************************************************* * * The following INCLUDE files are needed to make this program assemble. * They come with the Amiga Macro-Assembler Package. * NOMLIST ; No macro expansion list NOCLIST ; No conditional list NOLIST ; No need to list these INCLUDE "EXEC/Types.i" INCLUDE "EXEC/Libraries.i" INCLUDE "EXEC/Ables.i" INCLUDE "EXEC/Memory.i" INCLUDE "EXEC/IO.i" INCLUDE "EXEC/Nodes.i" INCLUDE "EXEC/Lists.i" INCLUDE "Devices/Printer.i" INCLUDE "Graphics/GfxBase.i" INCLUDE "Graphics/RastPort.i" INCLUDE "Intuition/IntuitionBase.i" INCLUDE "Intuition/Intuition.i" INCLUDE "Libraries/DOSextens.i" LIST ; Ok, lets start the listing * ******************************************************************************* * * This is the only fixed address in the system... * xref _AbsExecBase * ******************************************************************************* * * Some macros that make calling the system routines easier... * CALLSYS MACRO xref _LVO\1 ; Set the external reference CALLLIB _LVO\1 ; Call the EXEC definied macro ENDM * ******************************************************************************* * * Offsets from the stack that contain the following... * my_Left equ 0 ; Left 0 my_Top equ 2 ; Top 0 my_Right equ 4 ; Right MAX my_Bottom equ 6 ; Left MAX intuitionBASE equ 8 ; Where IntuitionBase is stored... * ******************************************************************************* * * These are the sizes in X and Y of the 'Block' that is used... * X_Size/Y_Size should be ODD and less than 8... * X_Size equ 5 ; Size in X Y_Size equ 3 ; Size in Y * X_Size_Mod equ (X_Size-1)/2 Y_Size_Mod equ (Y_Size-1)/2 * ******************************************************************************* * * These define the size of the window... If not defined by assembler * parameter, these values are used... * IFD Xmax XMax equ Xmax ; Use the parameter from the user... ELSE XMax equ 509 ; X size for window... ENDC * IFD Ymax YMax equ Ymax ; Use the parameter from the user... ELSE YMax equ 171 ; Y size for window... ENDC * ******************************************************************************* * BACKpen equ 3 ; Pen for the background colour... * ******************************************************************************* * * Bits for the different directions... * LEFT_Bit equ 0 RIGHT_Bit equ 1 UP_Bit equ 2 DOWN_Bit equ 3 * ******************************************************************************* * * * Register usage through this program... * * * * a0 - Scrap * * a1 - Scrap * * a2 - GFX Base saved... * * a3 - RastPort... * * a4 - Window pointer... * * a5 - EXEC Base saved... * * a6 - Library Base Register... * * a7 - Stack... (What else?) * * * * d0 - Scrap * * d1 - Scrap * * d2 - Random Number seed... * * d3 - Bit Pattern of possible moves... * * d4 - Current X * * d5 - Current Y * * d6 - Intuition Base (and ....) * * d7 - Zero... * * * ******************************************************************************* * * Now, for the start of the code... * Maze: move.l _AbsExecBase,a6 ; Get the EXEC library base move.l a6,a5 ; Save it... clr.l d7 ; Clear d7... * move.l d7,a1 ; Clear a1 CALLSYS FindTask ; Get our task pointer... move.l d0,a4 ; Now, move it to a4 for addressing use lea pr_MsgPort(a4),a3 tst.l pr_CLI(a4) ; Check if this is a CLI task... bne.s QuickCLI ; If so, skip the next section * ******************************************************************************* * * This section deals with starting from the WorkBench... * It is just here for completeness... * QuickWorkBench: move.l a3,a0 ; Get message port CALLSYS WaitPort ; Wait for the WorkBench message... move.l a3,a0 ; ...it's here, so let's get it CALLSYS GetMsg ; off the message port... bra.s QuickCont ; ...and go to the continue routine * ******************************************************************************* * * The routine was started from the CLI (prefered) * Let's store a NULL pointer so that there is no WB message... * QuickCLI: move.l d7,d0 ; No reply message... * ******************************************************************************* * * Continue with the Quick initialization * QuickCont: move.l d0,-(sp) ; Save the message pointer... * ******************************************************************************* * * Ok, we are now ready to do some real work... * lea intuitionName(pc),a1 ; Get LIB name... move.l d7,d0 ; ANY version, I guess... CALLSYS OpenLibrary ; Open it... move.l d0,d6 ; Quick way to check it... beq.s abortNoIntuit ; No intuition, we abort... lea graphicsName(pc),a1 ; Get LIB name... move.l d7,d0 ; Any version... CALLSYS OpenLibrary ; Open it... move.l d0,a2 ; Save it... move.l a2,d0 ; And check... beq.s abortNoGfx ; Abort if we can't get it... * ******************************************************************************* * * Now, open a window... * lea NewWindowStuff(pc),a0 ; Point to the NewWindow... move.l d6,a6 ; Set IntuitionBase... CALLSYS OpenWindow ; Open it... move.l d0,a4 ; Save the pointer... move.l a4,d0 ; Check it... beq.s abortNoWindow ; No window, so abort... move.l wd_RPort(a4),a3 ; Get rastport... move.l d6,-(sp) ; Save the intuition pointer * ******************************************************************************* * * Ok, now we fill the screen with the block pen... * move.l a2,a6 ; We will be doing Gfx stuff... moveq.l #BACKpen,d0 ; Pen number... move.l a3,a1 ; Get RPort... CALLSYS SetAPen ; Set the pen... move.w wd_Height(a4),d3 ; Window Y size... move.w wd_Width(a4),d2 ; Window X size... move.b wd_BorderBottom(a4),d0 ; the bottom border... ext.w d0 ; Extend it to a word... sub.w d0,d3 ; subtract it from d3... move.b wd_BorderRight(a4),d0 ; the right border... ext.w d0 ; Extend it... sub.w d0,d2 ; Subtrack it from d2... move.b wd_BorderTop(a4),d1 ; Get top border... ext.w d1 ; Extend it... move.b wd_BorderLeft(a4),d0 ; Get left border... ext.w d0 ; Extend it... subq.l #1,d2 ; We need to adjust a bit... subq.l #1,d3 movem.w d0-d3,-(sp) ; Save these values... move.l a3,a1 ; Make sure we have RPort... CALLSYS RectFill ; Fill it... move.l a3,a1 ; (It may have trashed it...) move.l d7,d0 ; Set pen to 0... CALLSYS SetAPen ; (We will erase the bad areas) * ******************************************************************************* * * The window is now pained and ready to rock... We just need to do a few * adjustments on the limits... * movem.w (sp)+,d0-d3 ; Get the limits... addq.l #X_Size,d0 ; Adjust inwards... subq.l #X_Size,d2 addq.l #Y_Size,d1 subq.l #Y_Size,d3 movem.w d0-d3,-(sp) ; Save them again... move.l d0,d4 ; Get the initial X move.l d1,d5 ; and Y bsr PutBlock ; And put it down... * ******************************************************************************* * * Ok, now we start the maze loop. This should be interesting... * MazeLoop: move.l d7,d6 ; Clear the DONE flag... move.w my_Left(sp),d4 ; Get the starting X MazeLoop1: move.w my_Top(sp),d5 ; Get the starting Y * * Check this spot for more work... * MazeLoop2: move.w d4,d0 ; Get X move.w d5,d1 ; and Y move.l a3,a1 ; RPort... CALLSYS ReadPixel ; Check what it is... tst.b d0 ; If it is beq.s FoundSpot ; 0 - Possible continue... moveq #1,d6 ; Empty means we come again... * * Move to next spot... * MazeNext: addq.l #Y_Size,d5 ; Go to next point... addq.l #Y_Size,d5 ; (Y+ 2*Y_Size) cmp.w my_Bottom(sp),d5 ; Check if we went too far... bcs.s MazeLoop2 ; Try again... addq.l #X_Size,d4 ; Go to next column addq.l #X_Size,d4 ; (X+ 2*X_Size) cmp.w my_Right(sp),d4 ; Check it... bcs.s MazeLoop1 ; Ok, so we continue... tst.l d6 ; Check our flag... bne.s MazeLoop ; If not zero, go again... bra.s WaitForClose ; All, done, wait for user... * ******************************************************************************* * * Ok, we are at a possible spot. Let's check it out... * FoundSpot: move.l d7,d3 ; Clear bit pattern... * * Check to the left... * CheckLeft: move.l d5,d1 ; Get Y... move.l d4,d0 ; Get X... subq.l #X_Size,d0 ; Adjust to the left... subq.l #X_Size,d0 cmp.w my_Left(sp),d0 ; Check if out of bounds... blt.s CheckRight ; If no good, skip... move.l a3,a1 ; Get RPort... CALLSYS ReadPixel ; Get the pixel... tst.b d0 ; Check it... beq.s CheckRight ; Skip to next check... bset #LEFT_Bit,d3 ; Set the bit... * * Check to the right... * CheckRight: move.l d5,d1 ; Get Y... move.l d4,d0 ; Get X... addq.l #X_Size,d0 ; Adjust to the right... addq.l #X_Size,d0 cmp.w my_Right(sp),d0 ; Check if out of bounds... bgt.s CheckUp ; If no good, skip... move.l a3,a1 ; Get RPort... CALLSYS ReadPixel ; Get the pixel... tst.b d0 ; Check it... beq.s CheckUp ; Skip to next check... bset #RIGHT_Bit,d3 ; Set the bit... * * Check up... * CheckUp: move.l d4,d0 ; Get X... move.l d5,d1 ; Get Y... subq.l #Y_Size,d1 ; Adjust to the left... subq.l #Y_Size,d1 cmp.w my_Top(sp),d1 ; Check if out of bounds... blt.s CheckDown ; If no good, skip... move.l a3,a1 ; Get RPort... CALLSYS ReadPixel ; Get the pixel... tst.b d0 ; Check it... beq.s CheckDown ; Skip to next check... bset #UP_Bit,d3 ; Set the bit... * * Check Down... * CheckDown: move.l d4,d0 ; Get X... move.l d5,d1 ; Get Y... addq.l #Y_Size,d1 ; Adjust to the left... addq.l #Y_Size,d1 cmp.w my_Bottom(sp),d1 ; Check if out of bounds... bgt.s CheckDone ; If no good, skip... move.l a3,a1 ; Get RPort... CALLSYS ReadPixel ; Get the pixel... tst.b d0 ; Check it... beq.s CheckDone ; Skip to next end of check... bset #DOWN_Bit,d3 ; Set the bit... * * Ok, we checked every-which-way, and now to see if any worked... * CheckDone: tst.l d3 ; Check if any bits were set... beq.s MazeNext ; No match, on to the next... moveq.l #1,d6 ; Set Not-Done flag... * * So, there is a possible direction. Let's see if we can find it... * TryToFind: bsr.s Random ; Get a random number... and.l d3,d0 ; Mask with the directions... IFD DOUBLE bne.s TryToFind1 ; There is a match... bsr.s Random ; Try again... and.l d3,d0 ; Mask it... ENDC IFD EASYMAZE beq.s TryToFind ; Look again... ELSE beq.s MazeNext ; If no match, Next... ENDC TryToFind1: btst #UP_Bit,d0 ; Check if UP... bne.s Do_UP ; Do the up... btst #LEFT_Bit,d0 ; Check if LEFT... bne.s Do_LEFT ; Do the left... btst #RIGHT_Bit,d0 ; Check if RIGHT... bne.s Do_RIGHT ; Do the right... * * We fall into this... Do the DOWN... * Do_DOWN: addq.l #Y_Size,d5 ; Move down... bsr.s PutBlock ; Put the block... addq.l #Y_Size,d5 ; down to the next spot... bsr.s PutBlock ; Put the block... bra.s FoundSpot ; Go do another... * * Do the RIGHT... * Do_RIGHT: addq.l #X_Size,d4 ; Move over... bsr.s PutBlock ; Put the block... addq.l #X_Size,d4 ; over to the next spot... bsr.s PutBlock ; Put the block... bra.s FoundSpot ; Go do another... * * Do the UP... * Do_UP: subq.l #Y_Size,d5 ; Move up... bsr.s PutBlock ; Put the block... subq.l #Y_Size,d5 ; up to the next spot... bsr.s PutBlock ; Put the block... bra.s FoundSpot ; Go do another... * * Do the LEFT... * Do_LEFT: subq.l #X_Size,d4 ; Move over... bsr.s PutBlock ; Put the block... subq.l #X_Size,d4 ; over to the next spot... bsr.s PutBlock ; Put the block... bra.s FoundSpot ; Go do another... * ******************************************************************************* * * Wait for the user to press the Close gadget... * WaitForClose: lea DoneTitle(pc),a0 ; Get the address... move.l a0,wd_Title(a4) ; Set the title... move.l intuitionBASE(sp),a6 ; Get IntuitionBase... move.l a4,a0 ; Get window address... CALLSYS RefreshWindowFrame ; Refresh it... WaitForClose1: move.l a5,a6 ; Get EXEC base... move.l wd_UserPort(a4),a0 ; Get message port... CALLSYS WaitPort ; Wait for it... move.l wd_UserPort(a4),a0 CALLSYS GetMsg ; Get the message move.l d0,a1 ; Pointer move.l im_Class(a1),d2 ; Get the message type... CALLSYS ReplyMsg ; Reply the message... cmpi.l #CLOSEWINDOW,d2 ; Check if it is correct... bne.s WaitForClose1 ; Wait for the close... * ******************************************************************************* * IFD PRINT movem.w (sp)+,d0-d3 ; Get the limits... addq.l #X_Size,d2 ; Adjust outwards for printing subq.l #X_Size,d0 ; we need the border around addq.l #Y_Size,d3 ; the maze grid... subq.l #Y_Size,d1 movem.w d0-d3,-(sp) ; Save them again... move.l intuitionBASE(sp),d6 ; Get IntuitionBase... bsr.s AskPrinting ; Check if user wants to print ENDC * ******************************************************************************* * * The standard exit routines... * Close anything that we have opened... * NormalExit: movem.l (sp)+,d0-d1/d6 ; Restore space & intuition pointer... move.l a4,a0 ; Get window pointer... move.l d6,a6 ; Make sure intuitionbase... CALLSYS CloseWindow ; Close the window... abortNoWindow: move.l a5,a6 ; Get EXECbase back... move.l a2,a1 ; Get GfxBase... CALLSYS CloseLibrary ; Close it... abortNoGfx: move.l d6,a1 ; Get IntuitionBase... CALLSYS CloseLibrary ; Close it... abortNoIntuit: move.l (sp)+,d0 ; Get that message back beq.s abortNoWB ; If none, we are done move.l d0,a1 ; Get the pointer ready FORBID ; manual says we must forbid... CALLSYS ReplyMsg ; ...when returning WB message abortNoWB: rts ; RTS out of this task... * ******************************************************************************* * * Random number generator... It uses the two EXECbase values Idle/DispCount * It will return a number in d0 that SHOULD be RELATIVELY random... The * initial value of d0 is used as an extra seed... * Random: add.l IdleCount(a5),d0 ; Get the idle count... add.l DispCount(a5),d0 ; Pull the rest in... eor.l d2,d0 ; Add in the seed... swap d2 ; Flip the bytes... add.l d0,d2 ; Change the seed... rts ; Return... * ******************************************************************************* * * Draws my 5x5 block at Current X/Y ... * PutBlock: movem.l d2/d3,-(sp) ; Save what we mess with... move.l d4,d0 ; Get x... subq.l #X_Size_Mod,d0 ; Drop by 2... move.l d4,d2 ; And the other side... addq.l #X_Size_Mod,d2 ; Up by 2... move.l d5,d1 ; Get y... subq.l #Y_Size_Mod,d1 ; Drop by 2... move.l d5,d3 ; And the other side... addq.l #Y_Size_Mod,d3 ; Up by 2... move.l a3,a1 ; Get RPort... CALLSYS RectFill ; Draw the block... movem.l (sp)+,d2/d3 ; Restore it... rts ; and return... * ******************************************************************************* * * * Register usage through the print section... * * * * a0 - Scrap * * a1 - Scrap * * a2 - Positive IntuiText... * * a3 - Negative IntuiText... * * a4 - PrinterIO union... * * a5 - EXEC Base saved... * * a6 - Library Base Register... * * a7 - Stack... (What else?) * * * * d0 - Scrap * * d1 - Scrap * * d2 - IntuiText size... * * d3 - Scrap (Memory type during IntuiText allocations...) * * d4 - Body IntuiText... * * d5 - RastPort... * * d6 - Intuition Base (and ....) * * d7 - Zero... * * * ******************************************************************************* * * Ask the user if s/he wishes to print the maze... * PrintOffset equ 16 ; Number of bytes stack moves * due to bsr and the saving of a2/a3/a4... AskXsize equ 162 ; AutoRequest X size... AskYsize equ 45 ; AutoRequest Y size... WindowOffset equ 8 ; Window pointer on stack... * IFD PRINT AskPrinting: movem.l a2-a4,-(sp) ; Save these... move.l a3,d5 ; Save RastPort pointer... move.l a5,a6 ; Get EXECbase... move.l #it_SIZEOF,d2 ; Size of IntuiText... move.l #MEMF_PUBLIC!MEMF_CLEAR,d3 * * Now start getting the IntuiText structures... * move.l d2,d0 ; Get Size... move.l d3,d1 ; Get memory type... CALLSYS AllocMem move.l d0,d4 ; Save BodyText... beq.s NoBodyText ; If none, exit... move.l d2,d0 ; Get Size... move.l d3,d1 ; Get memory type... CALLSYS AllocMem move.l d0,a2 ; Save PositiveText... move.l a2,d0 ; Check it... beq.s NoPositiveText ; If none, exit... move.l d2,d0 ; Get Size... move.l d3,d1 ; Get memory type... CALLSYS AllocMem move.l d0,a3 ; Save NegativeText... move.l a3,d0 ; Check it... beq.s NoNegativeText ; If none, exit... * * Now, set up the structures... * move.l d4,a1 ; Put it somewhere we can use * moveq.l #2,d0 ; Get it_FrontPen... move.b d0,it_FrontPen(a1) ; Save in BodyText... move.b d0,it_FrontPen(a2) ; Save in PositiveText... move.b d0,it_FrontPen(a3) ; Save in NegativeText... * moveq.l #3,d0 ; Get it_BackPen... move.b d0,it_BackPen(a1) ; Save in BodyText... move.b d0,it_BackPen(a2) ; Save in PositiveText... move.b d0,it_BackPen(a3) ; Save in NegativeText... * moveq.l #RP_JAM1,d0 ; Get it_DrawMode... move.b d0,it_DrawMode(a1) ; Save in BodyText... move.b d0,it_DrawMode(a2) ; Save in PositiveText... move.b d0,it_DrawMode(a3) ; Save in NegativeText... * moveq.l #6,d0 ; Get LeftEdge... move.w d0,it_LeftEdge(a1) ; Save in BodyText... move.w d0,it_LeftEdge(a2) ; Save in PositiveText... move.w d0,it_LeftEdge(a3) ; Save in NegativeText... * moveq.l #3,d0 ; Get TopEdge... move.w d0,it_TopEdge(a1) ; Save in BodyText... move.w d0,it_TopEdge(a2) ; Save in PositiveText... move.w d0,it_TopEdge(a3) ; Save in NegativeText... * lea Text_Attr(pc),a0 ; Get address of font... move.l a0,it_ITextFont(a1) ; Save in BodyText... move.l a0,it_ITextFont(a2) ; Save in PositiveText... move.l a0,it_ITextFont(a3) ; Save in NegativeText... * lea AskMessage(pc),a0 ; Get address of Body... move.l a0,it_IText(a1) ; Save in BodyText... lea OkMessage(pc),a0 ; Get address of Positive... move.l a0,it_IText(a2) ; Save in PositiveText... lea NoMessage(pc),a0 ; Get address of Negative... move.l a0,it_IText(a3) ; Save in NegativeText... * AskTheUser: move.l WindowOffset(sp),a0 ; Get window... move.l d7,d0 ; Clear Positive Flags... move.l d7,d1 ; Clear Negative Flags... move.l d2,-(sp) ; Save IntuiText Size... move.l #AskXsize,d2 ; Get X-size... move.l #AskYsize,d3 ; Get Y-size... move.l d6,a6 ; Get intuitionBASE... CallSYS AutoRequest ; Ask the user... move.l a5,a6 ; Restore ExecBase... move.l (sp)+,d2 ; Restore... tst.l d0 ; Check the result... beq.s NoPrint ; If FALSE, no-print... * ******************************************************************************* * * Ok, we must print now. * move.l #iodrpr_SIZEOF,d0 ; Size of IODRPReq... move.l #MEMF_PUBLIC!MEMF_CLEAR,d1 CallSYS AllocMem ; Get memory... move.l d0,a4 ; Get pointer... move.l a4,d0 ; Check it... beq.s ExitPrint ; Can't get IODRPReq... * move.l d7,a1 ; Clear a1... CallSYS FindTask ; Get our task... move.l d0,a1 ; Move it into a1... lea pr_MsgPort(a1),a1 ; Point to message port... move.l a1,MN_REPLYPORT(a4) ; Save the reply port... move.l #iodrpr_SIZEOF-MN_SIZE,MN_LENGTH(a4) ; Save size... * lea PrinterName(pc),a0 ; Get name of printer move.l d7,d0 ; Clear unit number... move.l d7,d1 ; Clear flags... move.l a4,a1 ; Get pointer to PrinterIO CallSYS OpenDevice ; Open printer.device... tst.l d0 ; Check for error... bne.s PrinterError ; Can't open printer... * lea ColourMap(pc),a0 : Pointer to colour map... move.l a0,io_ColorMap(a4) ; Store it... move.l d5,io_RastPort(a4) ; Pointer to RastPort... * move.l #V_HIRES,io_Modes(a4) ; Set mode to HiRes... * * This sets the x/y start/end of the RastPort to dump... * move.w PrintOffset+my_Left(sp),d0 move.w d0,io_SrcX(a4) ; Start of rectangle-X move.w PrintOffset+my_Right(sp),d1 sub.w d0,d1 move.w d1,io_SrcWidth(a4) ; Size of rectangle-X * move.w PrintOffset+my_Top(sp),d0 move.w d0,io_SrcY(a4) ; Start of rectangle-Y move.w PrintOffset+my_Bottom(sp),d1 sub.w d0,d1 move.w d1,io_SrcHeight(a4) ; Size of rectangle-Y * * Set the special to FULL size * move.w #SPECIAL_FULLCOLS!SPECIAL_FULLROWS,io_Special(a4) * * And, finally, the DumpRPort command... * move.w #PRD_DUMPRPORT,IO_COMMAND(a4) ; Printer command... * move.l a4,a1 ; Get PrinterIO.... CallSYS DoIO ; Send the command... move.l a4,a1 ; Get PrinterIO... CallSYS CloseDevice ; Close it... PrinterError: move.l a4,a1 ; Pointer to PrinterIO move.l #iodrpr_SIZEOF,d0 ; Size of PrinterIO... CallSYS FreeMem ; Release the memory... ExitPrint: move.l d4,a1 ; Get body text again... bra.s AskTheUser ; Ask again... * ******************************************************************************* * * Exit the print routine, freeing all memory that we have... * NoPrint: move.l a3,a1 ; Get address move.l d2,d0 ; Get Size CallSYS FreeMem NoNegativeText: move.l a2,a1 ; Get address move.l d2,d0 ; Get Size CallSYS FreeMem NoPositiveText: move.l d4,a1 ; Get address move.l d2,d0 ; Get Size CallSYS FreeMem NoBodyText: movem.l (sp)+,a2-a4 ; Restore them again... rts ENDC * ******************************************************************************* * * The data section... * NewWindowStuff dc.w 0,11,XMax,YMax ; The window pos/size dc.b 2,1 ; Window pens... dc.l CLOSEWINDOW ; IDCMP setting... dc.l WINDOWCLOSE!WINDOWDEPTH!WINDOWDRAG ; Smart refresh dc.l 0,0 ; No gadgets/checkmark dc.l TheTitle ; The title of the window... dc.l 0,0 ; No screen/bitmap... dc.w 0,0,0,0 ; No sizing stuff... dc.w WBENCHSCREEN ; The window's screen... * DoneTitle: dc.b 'Done! ' TheTitle: dc.b 'MKSoft MAZE Maker',0 intuitionName dc.b 'intuition.library',0 graphicsName dc.b 'graphics.library',0 * ******************************************************************************* * * This is the data section if PRINT is defined... * IFD PRINT ds.l 0 ; Make sure we long-align... * * This colour map is used for the DumpRPort call to make the maze walls * black and all else white... * ColourMap: dc.b 0 dc.b 0 dc.w 4 ; Number of entries dc.l ColourTable ; Pointer... ColourTable: dc.w $0FFF ; White for colours 0 to 2... dc.w $0FFF dc.w $0FFF dc.w $0000 ; Black for colour 3... * Text_Attr: dc.l FontName ; Name of the font... dc.w 8 ; Y-Size of font... dc.b 0 ; No style flags... dc.b 0 ; No flags... FontName: dc.b 'topaz.font',0 * AskMessage: dc.b 'Print this maze?',0 OkMessage: dc.b 'Yes',0 NoMessage: dc.b 'No',0 * PrinterName: dc.b 'printer.device',0 ENDC * ******************************************************************************* * * And, with that we come to the end of another full-length feature staring * that wonderful MC680x0 and the Amiga system. Join us again next time * for more Wonderful World of Amiga... Until then, keep boinging... * end