TweetFollow Us on Twitter

PrLink
Volume Number:1
Issue Number:9
Column Tag:Programmer's Forum

"PrLink Source for MacAsm"

By Paul F. Snively, MacTutor Contributing Editor

Well, if you have been following MacTutor for any length of time, you are probably aware that we are dedicated to the proposition that the Mac can be programmed with any of a number of languages that are available for the Mac, on the Mac.

What does it mean to program the Mac, though? Much has been made of the "standard user interface guidelines," which is a fancy way of saying that Apple Computer, Inc. thinks that all Mac applications should bear at least a passing resemblance to each other. From the user's point of view, this is a Godsend.

If you have read Inside Macintosh you are aware that there are at least three things that Apple says should be consistent from application to application: the apple menu, the file menu, and the edit menu.

Several people have gone into detail as to how to create a full-featured apple menu and edit menu for Mac applications. More recently, the "Open..." option (i.e. the standard file interface) has gotten a close look. Until now, however, no one has really looked at the obvious remaining element in a Mac application, namely, the "Print..." option.

I'm going to dodge the menu setup; I detest reinventing the wheel. If you are unsure as to how to create a "Print..." menu option which prints the current document associated with your application, I suggest that you get some MacTutor back issues and start reading. I am only going to concern myself here with the actual printing of text and graphics from within an assembly language application.

PrLink Source Missing

If you are using the release version of MDS, you are probably wondering what the big deal is. After all, MDS includes a file called PrLink.Rel which can simply be linked into your application and provides support for all of the printing manager routines. This is entirely true. If you are using MDS, don't bother to continue reading unless the theory behind the printing manager interface interests you, because the code is written for MacASM owners, who weren't blessed with a canned interface to the printing manager. [Note that Apple did not supply the source code to PrLink.Rel. How come? -Ed.]

Allow me to editorialize for a moment here. (Contributing editors can do that, can't they)? There is probably no area of the toolbox (if it can properly be called "part of the toolbox") that is so shrouded in mystery as the printing manager. The only program that I own that actually works through the printing manager is MacWrite (well, perhaps MacPaint does too, although I think it works at a lower level than MacWrite does). Of all of the development tools that I own, NOT ONE of them uses the printing manager -they simply open the serial port and start sending ASCII codes out. This is hardly the most device- independent way of doing things; as David Smith has noticed, that technique tends not to work with the LaserWriter, for example. So, it is important to work through the printing manager for reasons of compatibility, as well as to have the ability to use the font manager and Quickdraw to create graphics on the printer.

The primary reason that the printing manager is so neglected is that, unlike most areas of the toolbox, there is virtually no correlation between how the printing manager is accessed in PASCAL and how it is accessed in assembler (once again, unless you are using MDS - but even at that PrLink.Rel won't win any awards for being well-documented). In PASCAL, you simply use the appropriate functions and/or procedures, giving the proper parameters - no big deal. In assembly, though, you must deal with the printing resource file, overlays, dialog boxes, and so on - right down at the nuts and bolts level. The code that follows is my attempt to provide much the same easy access to the printing manager routines as PrLink.Rel does for MDS users.

Code Resources

If you have been following the whole discussion about resources, you have probably become aware that they are found (for the most part) in two places: within the application's file and within the system resource file (called, aptly, "System"). What you may or may not be aware of is that your application can also open other resource files to draw needed resources from. Opening resource files creates entries in a linked list - the most recently opened resource file is the first one searched, with the application itself being second to last, and the system resource file last.

The printing manager routines exist as resources in the printing resource file. Since resources can be executable code, Apple decided to use that approach (probably in order to allow for device independence as far as printers go - it'd be mighty hard to support a laser printer if the printing manager routines were in ROM). Interfacing to the printing manager consist of loading these resources as necessary and executing the code within them.

My Own PrLink Source

The "Print.Asm" code takes care of all of the dirty work for us by giving us the same routines as PASCAL users have. These routines can be described as follows:

The PrOpen routine opens the printing resource file and also opens the printer driver for us. We can then use the driver directly or through the high-level printing manager routines.

The PrStlDialog function is most commonly associated with the "Page Setup..." menu option. It allows the user to describe the page to the computer.

The PrJobDialog function is the one that is actually invoked upon choosing "Print..." and consists of the usual choices regarding pages to print, type of paper to use, and quality of printing.

The PrintDefault procedure simply fills in the PrintRec with the default values associated with that printer. This is useful for preventing weird values from popping up in PrintRec and for making it possible to set up a commonly used set of values (the default changes every time you answer the dialogs).

PrValidate makes sure that the PrintRec you pass to it is valid as far as the printing manager is concerned. This is handy if your application expects to find the PrintRec for a document within the document itself (yes, you can do that). Simply read the PrintRec from the document and do a PrValidate on it. PrValidate will fail (returning a boolean "false") if the PrintRec is not compatible with the current printing manager software.

PrJobMerge is useful if your application allows for printing of multiple documents in succession (in other words, if it allows the user to select several document icons from the Finder and use the "Print..." option in the Finder's file menu -technically, any application that allows printing should allow this). PrJobMerge copies the results of the dialogs into all of the PrintRecs for the documents that were passed to it, so that the user's selections will be used for all of the documents.

Asm Routines Mimic Pascal Interface

PrOpenDoc is the procedure that is actually responsible for preparing the printing manager to accept printer instructions. What this routine actually does depends upon whether the user selected draft printing or not. In draft, all operations are sent to the printer without further ado. With standard or high quality printing, the pages are sent to disk first, and then are printed using the PrPicFile procedure.

PrOpenPage starts a new page. This is particularly important in non-draft printing, since what essentially happens is that Quickdraw draws the "page" as a picture, except that it stores it on disk instead of putting it in a bitmap in RAM. PrOpenPage is then the printing equivalent of the OpenPicture toolbox trap.

PrClosePage is the printing equivalent of ClosePicture. It lets Quickdraw know that this picture (page) is done.

PrCloseDoc lets the printing manager know that the document is finished. The primary purpose of this seems to be for non-draft printing. It removes the special routing of Quickdraw traps and allows Quickdraw to work with bitmaps again instead of the printer.

PrPicFile is the procedure that prints non-draft quality documents. It allows for background processing (which usually consists of popping up a dialog box pointing out that printing is taking place and can be cancelled by holding down the command and period keys, and, upon return from the printing manager, removing the dialog).

All of these assembly language routines are intended to look exactly like their PASCAL counterparts in setup. The rule is that whenever a PASCAL function or procedure is described, the assembly equivalent takes its parameters in the same order as the PASCAL routine (in other words, the first parameter to a PASCAL routine is the first thing pushed for the assembly routine). This code obeys that particular rule, as you will see upon examining the sample program "PrintExamp.Asm." In the meantime, here is the MacASM code that links you, the programmer, to the printing manager.

00010 ;SAVE "Print.Asm"

00020 PrOpen     BSR      DOPEN                    ;Open the printer 
driver
00030            BNE.S    NOERR                    ;If an error occured, 
exit
00040            MOVEQ    #$00,D1                  ;Flag for open
00050            BRA.S    GETNAME            ;Get printer resource filename

00060 PrClose    MOVEQ    #$01,D1                  ;Flag for close

00070 GETNAME    SUBQ     #$04,SP                  ;Make room for result
00080            MOVE.L   #$53545220,-(SP)   ;Resource type "STR "
00090            MOVE.W   #$E000,-(SP)       ;ID # $E000
00100            TBX      GetResource              ;Self-explanatory
00110            MOVE.L   (SP)+,D0                 ;Get handle
00120            BEQ.S    NILHAND            ;Error if handle = NIL
00130            MOVEA.L  D0,A1                    ;Put handle in A1
00140            SUBQ     #$02,SP                  ;Make space for result
00150            BSET     #$0007,(A1)              ;Lock the master pointer
00160            MOVE.L   (A1),-(SP)               ;Move master pointer 
to stack
00170            TBX      OpenResFile              ;Open printer resource 
file
00180            MOVE.W   (SP)+,D0                 ;Get result
00190            BCLR     #$0007,(A1)              ;Unlock master pointer
00200            BSR.S    ERRCHK                   ;Was there a problem?
00210            TST.W    D1                       ;OPEN or CLOSE call?
00220            BEQ.S    NOERR                    ;If OPEN, we're done
00230            MOVE.W   D0,-(SP)                 ;Else drop result 
back on stack
00240            TBX      CloseResFile             ;And close the printer 
res file

00250 ERRCHK     MOVE.W   $0A60,$0944        ;Move resource err to PrErr
00260            BEQ.S    NOERR                    ;If there was no problem, 
return
00270            ADDQ.W   #$04,SP                  ;Else drop return 
address
00280 NOERR      RTS                               ;Return to caller

00290 NILHAND    MOVE.W   #$FF40,$0944       ;Out of memory error
00300            RTS                               ;Return to caller

00310 PrintDefault      MOVE.W   #$8000,D1         ;Offset 0
00320            BRA.S    OVL4                     ;Execute overlay code

00330 PrStlDialog       MOVE.W   #$8004,D1         ;Offset 4
00340            BRA.S    OVL4                     ;Execute overlay code

00350 PrJobDialog       MOVE.W   #$8008,D1         ;Offset 8
00360            BRA.S    OVL4                     ;Execute overlay code

00370 PrValidate        MOVE.W   #$8018,D1         ;Offset $18
00380            BRA.S    OVL4                     ;Execute overlay code

00390 PrJobMerge        MOVE.W   #$801C,D1         ;Offset $1C
00400            BRA.S    OVL4                     ;Execute overlay code

00410 PrOpenDoc         MOVEA.L  $000C(SP),A0      ;Get handle to print 
record
00420            MOVEA.L  (A0),A0                  ;Dereference handle
00430            MOVEQ    #$03,D0                  ;Mask for all possible 
ptypes
00440            AND.B    $0044(A0),D0       ;Which bit in record is 
set?
00450            MOVEQ    #$FFFFFFFC,D1      ;All bits but lowest 2
00460            AND.B    D1,$0946                 ;Mask off lowest 2 
bits
00470            OR.B     D0,$0946                 ;Set correct ptype 
bit
00480            MOVEQ    #$00,D1                  ;Offset 0
00490            BRA.S    OVL3                     ;Adjust for proper 
overlay

00500 PrCloseDoc        MOVE.W   #$8004,D1         ;Offset 4
00510            BRA.S    OVL3                     ;Adjust for proper 
overlay

00520 PrOpenPage        MOVEQ    #$08,D1           ;Offset 8
00530            BRA.S    OVL3                     ;Adjust for proper 
overlay

00540 PrClosePage       MOVEQ    #$0C,D1           ;Offset $C
00550            BRA.S    OVL3                     ;Adjust for proper 
overlay

00560 PrPicFile         MOVEQ    #$00,D1           ;Offset 0
00570            MOVEQ    #$05,D0                  ;Overlay 5
00580            BRA.S    EXECOVL            ;Execute overlay code

00590 OVL4       MOVEQ    #$04,D0                  ;Overlay 4
00600            BRA.S    EXECOVL            ;Execute overlay code

00610 OVL3       MOVEQ    #$03,D0                  ;Mask for overlay 
bit
00620            AND.B    $0946,D0                 ;Mask off all but 
correct bit

00630 EXECOVL    LEA      SAVEREGS(PC),A0    ;Register save area
00640            MOVEM.L  D4/A3/A4,(A0)      ;Save pertinent registers
00650            MOVE.L   D1,D4                    ;Copy offset
00660            MOVEA.L  (SP)+,A3                 ;Get return address
00670            LEA      SAVESTK(PC),A0     ;Point to stack save area
00680            MOVE.L   SP,(A0)                  ;Save current stack 
address
00690            SUBQ.L   #$04,SP                  ;Make room for result
00700            MOVE.L   #$50444546,-(SP)   ;"PDEF" type resource
00710            MOVE.W   D0,-(SP)                 ;Which overlay?
00720            TBX      GetResource               ;Get that overlay
00730            MOVE.L   (SP)+,D0                 ;Handle to overlay
00740            BEQ.S    OVLERR                   ;If no handle, overlay 
error
00750            MOVEA.L  D0,A4                    ;Put handle in address 
reg 4
00760            BSET     #$0007,(A4)              ;Lock master pointer
00770            MOVEA.L  (A4),A0                  ;Get master pointer 
in A0
00780            MOVEQ    #$00,D0                  ;Zero out D0
00790            MOVE.B   D4,D0                    ;Move offset to D0
00800            ADDA.L   D0,A0                    ;Add offset to master 
pointer
00810            MOVE.L   A0,-(SP)                 ;Put result on stack
00820            CLR.B    (SP)                     ;Zero out first byte's 
garbage
00830            MOVEA.L  (SP)+,A0                 ;Get real address 
in A0
00840            JSR      (A0)                     ;Execute overlay code
00850            TST.W    D4                       ;Check out D4
00860            BPL.S    NOUNLOCK     ;Go if no unlock needed
00870            BCLR     #$0007,(A4)              ;Else unlock master 
pointer
00880 NOUNLOCK   MOVEA.L  A3,A1                    ;Return address to 
A1
00890            LEA      SAVEREGS(PC),A0    ;Point to register save 
area
00900            MOVEM.L  (A0),D4/A3/A4            ;Get regs contents 
back
00910            JMP      (A1)                     ;And return to caller

00920 OVLERR     MOVE.W   #$FF40,$0944       ;Put error code in PrintVars
00930            MOVEA.L  SAVESTK(PC),SP     ;Get pristine stack back
00940            BRA.S    NOUNLOCK           ;Back to calling program

00950 SAVEREGS   DEFS     12                       ;12 bytes for registers
00960 SAVESTK    DEFS     4                        ;4 bytes for the stack 
pointer

00970 DOPEN      MOVEQ    #$18,D0                  ;Clear $19 words on 
stack
00980 CLEAR      CLR.W    -(SP)
00990            DBRA     D0,CLEAR
01000            LEA      DVRNAME(PC),A0     ;Pointer to driver name
01010            MOVE.L   A0,$0012(SP)       ;Place in data structure
01020            MOVEA.L  SP,A0                    ;Point to beginning 
of data
01030            OST      Open                     ;Open the driver
01040 CLEANUP    ADDA.W   #$32,SP                  ;Remove data from 
stack
01050            MOVE.W   D0,$0944                 ;Save result in PrintVars
01060            RTS                               ;And return to caller

01070 DCLOSE     SUBA.W   #$32,SP                  ;Make room for data 
structure
01080            MOVEA.L  SP,A0                    ;Point to data structure
01090            MOVE.W   #$FFFD,$0018(A0)   ;Move reference number to 
data
01100            OST      Close                    ;Close the driver
01110            BRA.S    CLEANUP            ;Clean up stack and return

01120 DVRNAME    STR      ".Print"                 ;Name of printer driver
01130            ADJST

The printing manager interface listed above took a lot of reading about memory management, device driver management, and the printing manager to work out. You may notice that the only low level operations performed are opening and closing the printer driver (and some of you may be wondering why I tossed in the printer driver close). I have found no use for the low level printer driver routines, so I didn't include them. Feel free to add them if you wish.

I added the printer driver close because I'm kind of a neatnik when it comes to what I leave lying around in my code. If I need to open the driver, then I prefer to close it when I am through with it. Since PrClose does not close the driver (it only closes the printer resource file, in accordance with IM), I added DCLOSE out of my own sense of propriety.

Apple's Printing Example

Now that you can see how to get from the description of the PASCAL routines to the assembly language equivalent, how do you use these routines? Answering that question is the purpose of the next program, "PrintExamp.Asm."

"PrintExamp.Asm" is simply the MacASM version of the "TestPrint.Asm" source code that was included with MDS. THIS CODE IS ORIGINAL ONLY INASMUCH AS I REWROTE IT FOR MACASM! (Program starts on the next page.)

Print Example in Assembly

The PrintExamp program teaches us several things about the interface to the printing manager. First, it succeeds at working exactly like PASCAL routines (the first parameters listed are the first ones on the stack). Second, it is self-contained (you need not define any globals or what have you for the interface per se ). Third, it works.

Most importantly, PrintExamp shows how to determine how much Quickdraw material will fit on a page. Examine lines 590-690 of PrintExamp closely. This code calculates the pertinent info about the size of the page by using the GetFontInfo toolbox trap (plus a little simple mathematics). If you are dealing with graphics objects other than fonts, the pertinent information to remember is that there are 72 dots per inch both on the Macintosh screen and on the printer (which is how the coordinates for a 5" by 5" oval become 0,0,5*72,5*72).

The major data structure associated with the printing manager routines is the PrintRec. For the most part, all you have to worry about is allocating it and keeping track of the handle (see PrintExamp.Asm and IM for more information).

Your application's file menu should ideally have both "Page Setup..." and "Print..." options. "Page Setup..." is associated with the PrStlDialog. "Print..." is associated with the PrJobDialog, and then with the routines necessary to actually do the printing.

Your application should also check the Finder info block upon startup to see if it needs to print more than one document. If it does, it should use PrJobMerge to apply the results of the dialogs to all documents in the batch.

Well, that wraps up my coverage of the printing manager! If you have any further questions, please drop me a line c/o MacTutor. Enjoy!


00010 ;SAVE "PrintExamp.Asm"
00020          LIST    OFF
00030 *--------------------------------
00040 ; Macintosh printing manager example program
00050 ; Copyright (c) 1985 MacTutor
00060 *--------------------------------
00070 ; Example source code translated from MDS format by Paul F. Snively
00080 *--------------------------------
00090 ; "Print.Asm" include file (interface to printing manager) written 
by 
00100 ; Paul F. Snively
00110 *--------------------------------
00120 charCount    EQU    120                      ;Characters to print 
per line 
00130 countAndLen       EQU   charCount+2    ;charCount and length byte 

00140 monaco            EQU   4                    ;Monaco is font # 
4
00150 ascent            EQU   0                    ;Offset into font 
info record
00160 descent        EQU  2                        ;ditto
00170 leading           EQU   6                    ;ditto
00180 prInfo            EQU   2                    ;Offset into printer 
info rec
00190 rPage             EQU   6                    ;ditto
00200 bottom            EQU   4                    ;Offset into rect 
structure
00210 iPrintSize        EQU   120                  ;Print Record size
00220 iPrStatSize       EQU   26                   ;Size of printer status 
record 00230 *--------------------------------
00240            INCLUDE  "Library.Asm"
00250 *--------------------------------
00260            GLOBAL   L+iPrStatSize,$CE
00270            DEFV     L,hPrintRec
00280            DEFV     iPrStatSize,prStatus
00290            ENDG
00300 *--------------------------------
00310            TFILE    "Buffer.Bin"       ;Target file for assembly
00320            RFILE    "PrintExamp",APPL,PRTX,$2000    ;Resource file
00330 *--------------------------------
00340            SEG     1,52
00350 *--------------------------------
00360 Start      BSR      InitManagers       ;Initialize managers
00370            BSR      PrOpen             ;Open print manager
00380            BRA      EventLoop  ;Go start event loop
00390 *--------------------------------
00400 InitManagers     PEA  -4(A5)                 ;Standard init sequence
00410            TBX      InitGraf                 ;Init Quickdraw
00420            TBX      InitFonts                ;Init Font manager
00430            MOVE.L   #$0000FFFF,D0      ;Flush all events
00440            TBX      FlushEvents
00450            TBX      InitWindows        ;Init Window manager
00460            TBX      InitMenus                ;Init Menu manager
00470            CLR.L    -(SP)                    ;No restart procedure
00480            TBX      InitDialogs              ;Init Dialog manager
00490            TBX      TEInit                   ;Init Text Edit
00500            TBX      InitCursor               ;Turn on arrow cursor
00510            RTS
00520 *--------------------------------
00530 MyDrawPage   MOVEM.L  D3-D6/A3-A4,-(SP)      ;Save registers
00540            PEA      tRect(PC)                ;Push tRect
00550            TBX      FrameOval                ;Draw a 5" by 5" oval
00560            MOVE     #monaco,-(SP)      ;Push monaco font #
00570            TBX      TextFont                 ;Set font (default 
size)

00580 ;Get font info to determine line spacing

00590            LINK     A6,#-8                   ;Make room for fontInfo
00600            MOVE.L   SP,A4                    ;A4 points to fontInfo
00610            MOVE.L   A4,-(SP)                 ;Push pointer to fontInfo
00620            TBX      GetFontInfo              ;Get the fontInfo 
record
00630            MOVE     ascent(A4),D4      ;Calculate line height
00640            ADD      descent(A4),D4
00650            ADD      leading(A4),D4           ;D4 has line height
00660            MOVE.L   hPrintRec(A5),A0   ;Point to print record
00670            MOVE.L   (A0),A0                  ;dereference handle
00680            MOVE     prInfo+rPage+bottom(A0),D6      ;Get page bottom 
coord.
00690            SUB      descent(A4),D6           ;Adjust for font descent
00700 *--------------------------------
00710 ;Print a page of characters.
00720 ;
00730 ;A3 points to the print string
00740 ;
00750 ;D3 has current line position
00760 ;D4 has vertical distance between lines
00770 ;D5 has current line number
00780 ;D6 has bottom (vertical) coordinate of page
00790 ;
00800            MOVE     #1,D5                    ;Set initial line 
no.
00810            MOVE     D4,D3                    ;Set initial line 
position
00820            LINK     A6,#-countAndLen   ;Space for char string
00830            MOVE.L   SP,A3                    ;A3 points to string
00840            MOVE.B   #charCount,(A3)    ;Set length byte

00850 ;Fill print string with characters.

00860            MOVE     #$20,D0                  ;ASCII value for space
00870            MOVE     #charCount-1,D1          ;Count-1
00880            MOVE.L   A3,A0                    ;Point to string
00890            ADDQ     #1,A0                    ;Bump past length 
byte
00900 .1         MOVE.B   D0,(A0)+                 ;Fill in string
00910            ADDQ     #1,D0                    ;Next char
00920            DBRA     D1,.1                    ;Loop until done
00930 Ploop      MOVE     #0,-(SP)                 ;MoveTo start of line
00940            MOVE     D3,-(SP)
00950            TBX      MoveTo
00960            MOVE.L   A3,-(SP)                 ;Draw string
00970            TBX      DrawString
00980            MOVE     #charCount-1,D1          ;Count-1
00990            MOVE.L   A3,A0              ;Point to string
01000            ADDQ     #1,A0                    ;Bump past length 
byte
01010 .1         ADD.B    #1,(A0)+                 ;Increment each byte
01020            DBRA     D1,.1                    ;Loop until done

01030            ADD      #1,D5                    ;Bump current line 
no.
01040            ADD      D4,D3                    ;Bump line position
01050            CMP      D6,D3                    ;Past end of page?
01060            BLE      Ploop                    ;No, loop until done.
01070            UNLK     A6                       ;Reclaim stack space
01080            UNLK     A6                       ;(for two LINKs)
01090            MOVEM.L (SP)+,D3-D6/A3-A4       ;Restore registers
01100            RTS
01110 *--------------------------------
01120 EventLoop         NOP                        ;MAIN PROGRAM
01130 Init       MOVE.L   #iPrintSize,D0           ;Allocate print record
01140            OST      NewHandle
01150            MOVE.L   A0,hPrintRec(A5)         ;Save handle in hPrintRec
01160            MOVE.L   A0,-(SP)                 ;Push it
01170            BSR      PrintDefault             ;Call PrintDefault
01180 *--------------------------------
01190 Style      SUBQ     #2,SP                    ;Space for function 
result
01200            MOVE.L   hPrintRec(A5),-(SP)     ;Push hPrintRec
01210            BSR      PrStlDialog              ;Call PrStlDialog
01220            MOVE.B   (SP)+,D0                 ;Pop result
01230 *--------------------------------
01240 Job        SUBQ     #2,SP                    ;Space for function 
result
01250            MOVE.L   hPrintRec(A5),-(SP)     ;Push hPrintRec
01260            BSR      PrJobDialog              ;Call PrJobDialog
01270            MOVE.B   (SP)+,D0                 ;Pop result
01280            BEQ      PrintDone                ;Exit to Finder if 
cancel
01290 *--------------------------------
01300 Spool      SUBQ     #4,SP                    ;Space for result
01310            MOVE.L   hPrintRec(A5),-(SP)     ;Push hPrintRec
01320            CLR.L     -(SP)                         ;NIL pPrPort
01330            CLR.L    -(SP)                    ;NIL pIOBuf
01340            BSR      PrOpenDoc                ;Call PrOpenDoc
01350            MOVE.L   (SP)+,A4                 ;Get pPrPort in A4
01360 *--------------------------------
01370 ;Start of page
01380            MOVE.L   A4,-(SP)                 ;Push pPrPort
01390            CLR.L    -(SP)                    ;NIL pPageFrame
01400            BSR      PrOpenPage         ;Call PrOpenPage
01410 *--------------------------------
01420 ;Draw page here
01430            BSR      MyDrawPage
01440 *--------------------------------
01450 ;End of page
01460            MOVE.L   A4,-(SP)                 ;Push pPrPort
01470            BSR      PrClosePage              ;Call PrClosePage
01480 *--------------------------------
01490 ;End of document
01500            MOVE.L   A4,-(SP)                 ;Push pPrPort
01510            BSR      PrCloseDoc               ;Call PrCloseDoc
01520 *--------------------------------
01530 Print      MOVE.L   hPrintRec(A5),-(SP)      ;hPrintRec
01540            CLR.L    -(SP)                    ;pPrPort
01550            CLR.L    -(SP)                    ;pIOBuf
01560            CLR.L    -(SP)                    ;pDevBuf
01570            PEA      prStatus(A5)             ;prStatus
01580            BSR      PrPicFile                ;Call PrPicFile
01590            MOVE.L   hPrintRec(A5),A0   ;Get printRec handle
01600            OST      DisposHandle       ;Dispose it
01610            BRA      EventLoop                ;Go start over
01620 PrintDone         BSR   PrClose              ;Done. Close print 
manager 
01630            RTS                               ;then exit to Finder
01640 *--------------------------------
01650 ;Data constants
01660 tRect      DATA     /0                       ;top
01670            DATA     /0                       ;left
01680            DATA     /5*72                    ;bottom
01690            DATA     /5*72                    ;right
01700 *--------------------------------
01710          INCLUDE "Print.Asm"
01720 *--------------------------------
01730            ENDR
01750            SEG     0,32,VAR.LEN,$20
01770 SEG0
01780 SEG_1      JP       Start,1
01790 END_1
01800 END0
01810            ENDR
01830            END
MacAsm to MDS Syntax
MDS users may find the non-standard syntax of the Mac Asm source code a bit confusing. 
Here is a short table of some of the differences found in the code in this article. 

                ADJST:              Adjust boundary (.ALIGN)
                ASC:                 String definition (DC)
                DATA:               Data definition (DC)
                DEFS:               Define Storage (DCB)
                ENDM:              End macro def. (|, .ENDM)
                ENDR:              End resource def. 
                RSRC:               Start resource def.
                GLOBAL:           Storage (A5) as in (DS)
                TBX:                 Trap Macro ( _Open)
                OST:                 OS Macro (_Open)
                STR:                 String with length (DC)
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

TotalFinder 1.12.2 - Adds tabs, hotkeys,...
TotalFinder is a universally acclaimed navigational companion for your Mac. Enhance your Mac's Finder with features so smart and convenient, you won't believe you ever lived without them. Features... Read more
Duet 2.3.0.3 - Use your iPad as an exter...
Duet is the first app that allows you to use your iDevice as an extra display for your Mac using the Lightning or 30-pin cable. Note: This app requires a $9.99 iOS companion app. Version 2.3.0.3:... Read more
FileMaker Pro Advanced 18.0.3 - Powerful...
FileMaker Pro Advanced is the tool you use to create a custom app. You also use FileMaker Pro Advanced to access your app on a computer. Start by importing data from a spreadsheet or using a built-in... Read more
OsiriX Lite 10.0.6 - 3D medical image pr...
OsiriX Lite is an image processing software dedicated to DICOM images (".dcm" / ".DCM" extension) produced by medical equipment (MRI, CT, PET, PET-CT, ...) and confocal microscopy (LSM and BioRAD-PIC... Read more
Ableton Live 10.1.5 - Record music using...
Ableton Live lets you create and record music on your Mac. Use digital instruments, pre-recorded sounds, and sampled loops to arrange, produce, and perform your music like never before. Ableton Live... Read more
Burn 2.7.8 - Easily burn data, audio, vi...
Burn... There are a lot of ways to approach burning discs. Burn keeps it simple, but still offers a lot of advanced options. Create data discs with advanced data settings like, file permissions, the... Read more
Malwarebytes 4.0.30.3073 - Adware remova...
Malwarebytes (was AdwareMedic) helps you get your Mac experience back. Malwarebytes scans for and removes code that degrades system performance or attacks your system. Making your Mac once again your... Read more
Acorn 6.5.3 - Bitmap image editor.
Acorn is a new image editor built with one goal in mind - simplicity. Fast, easy, and fluid, Acorn provides the options you'll need without any overhead. Acorn feels right, and won't drain your bank... Read more
Fantastical 2.5.13 - Create calendar eve...
Fantastical is the Mac calendar you'll actually enjoy using. Creating an event with Fantastical is quick, easy, and fun: Open Fantastical with a single click or keystroke Type in your event... Read more
A Better Finder Rename 11.05 - File, pho...
A Better Finder Rename is the most complete renaming solution available on the market today. That's why, since 1996, tens of thousands of hobbyists, professionals and businesses depend on A Better... Read more

Latest Forum Discussions

See All

Eternal Warfare is a new idle clicker fo...
Idle games are a popular genre on mobile, they might not be to everyone's taste but they're made with such regularity and receive a lot of downloads, so it's hard to argue it's not big business. Eternal Warfare is set to join the sea of idle games... | Read more »
New heroes and balance updates set to ar...
It feels like Hearthstone: Battlegrounds only launched yesterday, and already the auto batter addition to Blizzard's megahit card game is set to receive new heroes and balance updates. [Read more] | Read more »
Pre-register for Hello Kitty AR: Kawaii...
Hello Kitty — the cute cat that launched a multi-billion-pound franchise — has been brought to life… sort of. Sanrio has teamed up with the Bublar Group to create a new mobile game that uses AR tech to turn the real world into Hello Kitty’s... | Read more »
Gorgeous and tranquil puzzler Spring Fal...
One-man indie studio SPARSE//GameDev has now launched its tranquil puzzler, Spring Falls. It's described as "a peaceful puzzle game about water, erosion, and watching things grow". [Read more] | Read more »
Black Desert Mobile gets an official rel...
Pearl Abyss has just announced that its highly-anticipated MMO, Black Desert Mobile, will launch globally for iOS and Android on December 11th. [Read more] | Read more »
Another Eden receives new a episode, cha...
Another Eden, WFS' popular RPG, has received another update that brings new story content to the game alongside a few new heroes to discover. [Read more] | Read more »
Overdox guide - Tips and tricks for begi...
Overdox is a clever battle royale that changes things up by adding MOBA mechanics and melee combat to the mix. This new hybrid game can be quite a bit to take in at first, so we’ve put together a list of tips to help you get a leg up on the... | Read more »
Roterra Extreme - Great Escape is a pers...
Roterra Extreme – Great Escape has been described by developers Dig-It Games as a mini-sequel to their acclaimed title Roterra: Flip the Fairytale. It continues that game's tradition of messing with which way is up, tasking you with solving... | Read more »
Hearthstone: Battlegrounds open beta lau...
Remember earlier this year when auto battlers were the latest hotness? We had Auto Chess, DOTA Underlords, Chess Rush, and more all gunning for our attention. They all had their own reasons to play, but, at least from where I'm standing, most... | Read more »
The House of Da Vinci 2 gets a new gamep...
The House of Da Vinci launched all the way back in 2017. Now, developer Blue Brain Games is gearing up to deliver a second dose of The Room-inspired puzzling. Some fresh details have now emerged, alongside the game's first official trailer. [Read... | Read more »

Price Scanner via MacPrices.net

B&H offers $100 discounts on 4-Core and 6...
B&H Photo has new 4-Core and 6-Core Mac minis in stock and on sale today for $100 off Apple’s MSRP. Prices start at $699. Overnight shipping is free to many addresses in the US: – 3.6GHz Quad-... Read more
Save $200 today on a 2019 13″ MacBook Air wit...
Apple has a full line of Certified Refurbished 2019 13″ MacBook Airs available starting at only $929 and up to $200 off the cost of new Airs. Each MacBook features a new outer case, comes with a... Read more
New Verizon Pre-Black Friday 2019 deal: Buy o...
Buy one new Apple iPhone 11 model or 2018 iPhone XS model at Verizon and get a second one for free. One new line of service required. Offer is valid from November 21, 2019 to November 27, 2019. Here... Read more
AirPods with Wireless Charging Case on sale t...
Abt Electronics has 2019 AirPods with the Wireless Charging Case on sale today for $163 shipped. Their price is $36 off Apple’s MSRP, and it’s currently the cheapest price for these AirPods from any... Read more
Apple continues to offer 2017 13″ Dual-Core n...
Apple has Certified Refurbished 2017 13″ 2.3GHz Dual-Core non-Touch Bar MacBook Pros still available starting at $1019. An standard Apple one-year warranty is included with each model, outer cases... Read more
Save up to $120 on the new 16″ MacBook Pro at...
Apple’s resellers are starting to receive stock of new 16″ MacBook Pros, and the first set of sales & deals are now available: (1) Amazon 16″ MacBook Pros start on sale for $100-$116 off Apple’s... Read more
Apple Watch Series 3 models on sale at Amazon...
Amazon has Apple Watch Series 3 GPS models on sale for $30 off MSRP, starting at only $169. There prices are the lowest we’ve ever seen for these models from any Apple reseller. Choose Amazon as the... Read more
The ‘Mac Potpourri’ Mailbag: Edition #1- Info...
COMMENTARY: 11.20.19- Welcome to the inaugural edition of the “Mac Potpourri” Mailbag where we take a look at correspondence received from readers of this column from all over the world who write in... Read more
13″ 2.4GHz MacBook Pros available for up to $...
Apple has a full line of Certified Refurbished 2019 13″ 2.4GHz 4-Core Touch Bar MacBook Pros available starting at $1529 and up to $300 off MSRP. Apple’s one-year warranty is included, shipping is... Read more
New at T-Mobile: Switch to T-Mobile, and get...
T-Mobile is offering a free 64GB iPhone 8 for new customers who switch to T-Mobile and open a new line of service. Eligible trade-in required, and discount applied over a 24 month period. The fine... Read more

Jobs Board

Best Buy *Apple* Computing Master - Best Bu...
**747303BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Sales **Store NUmber or Department:** 001413-Cypress-Store **Job Description:** **What Read more
*Apple* Mobility Pro - Best Buy (United Stat...
**743221BR** **Job Title:** Apple Mobility Pro **Job Category:** Store Associates **Store NUmber or Department:** 000230-Greenwood-Store **Job Description:** At Best Read more
*Apple* Mobility Pro - Best Buy (United Stat...
**747338BR** **Job Title:** Apple Mobility Pro **Job Category:** Store Associates **Store NUmber or Department:** 000254-Superstition Springs-Store **Job Read more
Best Buy *Apple* Computing Master - Best Bu...
**745516BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Store Associates **Store NUmber or Department:** 001101-Manhattan-Store **Job Read more
Best Buy *Apple* Computing Master - Best Bu...
**746655BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Sales **Store NUmber or Department:** 002518-Atlantic Center-Store **Job Description:** Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.