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