![](/file/12652/www.mactech.com.tar/www.mactech.com/sites/all/themes/custom_front/images/you_are_here_red.gif)
![](/file/12652/www.mactech.com.tar/www.mactech.com/sites/default/files/beta-site.gif)
|
Volume Number: | 4 | |
Issue Number: | 8 | |
Column Tag: | Fortran World |
Fortran Printing Interface
By Jay Lieske, La Canada, CA
In Absoft FORTRAN version 2.3 one usually must employ Absoft’s special routine called PrPort.sub in order to use the Printing Manager on the Macintosh. PrPort.sub employs the old RAM-based printing manager, but recent trends suggest that it would be better to use the printing traps accessible through “_PrGlue” at $A8FD since these routines are now in ROM and contain special routines such as PrGeneral that are unavailable in the RAM-based printing manager. In addition, PrPort.sub, which is written in assembly language, is limited to the hard-coded routines which existed at the time Absoft developed the routine and is thus not extendible. Since usage of PrPort.sub will undoubtedly limit the development of FORTRAN programs on the Macintosh, it is of interest to see how one might use Absoft’s Toolbx.sub in order to implement the new ROM-based printing manager traps.
The Toolbx.sub routine from Absoft employs an encoded ‘trap dispatch’ LongInt to describe the toolbox or OS trap number, as well as to describe the parameters required for the toolbox or OS calls. The new printing traps accessible through the _PrGlue trap at $A8FD require that a special ‘routine selector’ be pushed onto the stack prior to the $A8FD trap instruction. Hence, if we are to succeed in using the print traps, we must be able to insert this routine selector number onto the stack.
By studying and disassembling Absoft’s Toolbx.sub it was found that the routine selector parameter could be put into the Toolbx.sub call as the final parameter (i.e. the parameter just before the final closing parenthesis) and that it would be pushed onto the stack just before Toolbx.sub executed the trap number. In order to instruct Toolbx.sub that there was another parameter for it to pass, however, the ‘trap dispatch’ code had to be modified. That is where the disassembly of Toolbx.sub became important because current Absoft documentation is not always correct on this matter.
We have developed the include files ‘prtrap.inc’ and ‘PrGenDefs.inc’ which can be used with Absoft Fortran’s Toolbx.sub in order to implement the print traps. A similar method could be employed for any other new traps (or traps and additional routine selectors’) that Apple develops. The file ‘prtrap.inc’ contains the encoded trap dispatch number and the routine selector for all the new print traps documented in Inside Macintosh Volume V. The routine selector for PrGeneral, which inadvertently was left out of Inside Mac, was found in Lightspeed Pascal’s equates as $70070480. We also include a file ‘PrGenDefs.inc’ which contains the equates required for use of the PrGeneral gateway, potentially a very useful new trap which enables one to check and to set the resolution of the printer in use.
To demonstrate how the Toolbx.sub traps are implemented in a program, first consider the Pascal calling-sequences as documented in Inside Mac. Suppose that a trap ‘PrRoutine’ is documented by Apple as being implemented like this in Pascal:
PrRoutine(Arg1, Arg2,...,Argn);
then the Toolbx.sub routine in Fortran would be employed as follows:
call Toolbx( PrRoutineCode, Arg1, Arg2,...,Argn, xPrRoutineCode)
if the toolbox trap is a procedure. If the toolbox call is a function then the Pascal version would be
Result := PrRoutine(Arg1, Arg2,...,Argn);
while the Toolbx.sub Fortran version would be
Result = Toolbx(PrRoutine,Arg1, Arg2,...,Argn,xPrRoutine).
The analogous calls using prport.sub for a subroutine would be: call PrPort(Code, Arg1, Arg2,..., Argn). Programs which currently employ PrPort could readily be changed simply by replacing PrPort with Toolbx and appending the ‘xPrRoutine’ parameter.
An example program ‘demotrap.for’ is included for implementing the new print manager trap-based calls. The program does not actually do any printing, but shows how one can access the print record and query the printer for variable resolutions. Just use the Chooser to select your ‘printer’ and then the usual dialogs will come up on screen to demonstrate that everything works as advertised. A colleague has employed these new traps in a large plotting package which was ported over to the Mac from a mainframe computer and the results are quite satisfactory.
Listing One: Demonstration Program program demotrap C See if can use ‘Printer traps’ via $A8FD PrGlue and TOOLBX.sub C A simple sample program demonstrating its capability for Absoft Fortran 2.3. C This program does not actually do any printing. C J. Lieske 12/87 C * * * * * * * * * * * FUNCTION PTR (ANYTYPE) : PTR; ; A ‘funny’ trap. INTEGER PTR ! from Absoft’s MISC.inc PARAMETER (PTR=Z’C0000000') integer NEWHANDLE ! from Absoft’s MEMORY.inc parameter (NEWHANDLE=Z’122000A8') integer iPrintSize ! The Print record size.[120 bytes] parameter (iPrintSize=120) ! from Absoft’s PRDEFS.inc C * * * * * * * * * * C GRXMX0 : default x size (pixels). These will be taken from the print record C GRYMX0 : default y size (pixels) C GRXPIN : pixels per inch in x C GRYPIN : pixels per inch in y REAL GRXPIN, GRYPIN INTEGER GRXMX0, GRYMX0 INTEGER*4 TOOLBX ! MAC TOOLBOX INTERFACE x integer*4 debugger ! just in case you want to use MacsBug x parameter (debugger=z’9FF00000') x call toolbx(debugger) ! put the call where it’s needed * * INITIALIZE THE PRINT RECORD FOR THE MACINTOSH * integer*2 iversion integer*2 ernum * PRINT MANAGER FUNCTION DEFINITIONS for toolbox-based traps include prtrap.inc include PrGenDefs.inc INTEGER PRRECHDL ! HANDLE TO THE PRINT RECORD. INTEGER POINT ! DEREFERENCED HANDLE LOGICAL OK write(*,*) ‘This program demonstrates printer traps in Fortran.’ write(*,*) ‘It won’’t actually print anything, but shows how to’ write(*,*) ‘access the printer traps in Absoft Fortran.’ write(*,*) ‘It will write the data out to ‘’output.fil’’’ write(*,*) ‘so you can read it.’ call toolbx(propen, xpropen) ! PrOpen PRRECHDL = TOOLBX(NEWHANDLE, IPRINTSIZE) ! GET A PRINT RECORD HANDLE. call toolbx(printdefault,PRRECHDL,xprintdefault) ! get defaults C get printer version number iversion = toolbx(prdrvrvers, xprdrvrvers ) write (*,*) ‘iversion = ‘, iversion open(15,file=’output.fil’, status=’NEW’) write (15,*) ‘iversion = ‘, iversion C see if PrGeneral will work gOpCode = 4 ! set iOpCode C--use PTR to get address of data record pGetRslData = toolbx(PTR,GetRslDataRec) call toolbx(PrGeneral, pGetRslData, xPrGeneral) C should now check for PrError also ernum = toolbx(PrError, xPrError) write(*,*) ‘PrError number = ‘, ernum write(15,*) ‘PrError number = ‘, ernum write(*,*) ‘Interpreted record’ write(*,*) ‘iOpCode= ‘,gOpCode write(*,*) ‘iError= ‘,gError write(*,*) ‘lReserved= ‘,gReserved write(*,*) ‘iRgType= ‘,iRgType write(*,*) ‘XRslRg= ‘,XRslRg write(*,*) ‘YRslRg= ‘,YRslRg write(*,*) ‘iRslRecCnt= ‘,iRslRecCnt write(*,*) ‘rgRslRec= ‘,((rgRslRec(i,j), i=1,2), j=1,iRslRecCnt) write(15,*) ‘Interpreted record’ write(15,*) ‘iOpCode= ‘,gOpCode write(15,*) ‘iError= ‘,gError write(15,*) ‘lReserved= ‘,gReserved write(15,*) ‘iRgType= ‘,iRgType write(15,*) ‘XRslRg= ‘,XRslRg write(15,*) ‘YRslRg= ‘,YRslRg write(15,*) ‘iRslRecCnt= ‘,iRslRecCnt write(15,*) ‘rgRslRec= ‘,((rgRslRec(i,j), i=1,2), j=1,iRslRecCnt) C now try to set it to 300 dpi pOpCode = 5 ! set iOpCode for SetRsl hPrint = PRRECHDL ! handle to print record iXRsl = 300 iYRsl = 300 pSetRsl = toolbx(PTR,SetRslRec) call toolbx(PrGeneral, pSetRsl, xPrGeneral) OK = toolbx(prstldialog,PRRECHDL,xprstldialog) ! std dialog OK=toolbx(prjobdialog,PRRECHDL,xprjobdialog) ! PrJobDialog if (.not. OK) STOP * NOW READ PLOT DIMENSION VALUES WITH THOSE FROM THE PRINTER INFO RECORD. * PRRECHDL IS A HANDLE TO THE PRINTER RECORD WHICH IS 120 BYTES * THE VALUES WE CARE ABOUT ARE THE VERTICAL AND HORIZONTAL RESOLUTION * AND THE PAGE RECTANGLE WHICH ARE AT OFFSETS 4,6, AND 8 INTO THE RECORD POINT=LONG(PRRECHDL) GRXMX0 = WORD(POINT+14) GRYMX0 = WORD(POINT+12) GRXPIN = FLOAT(WORD(POINT+6)) GRYPIN = FLOAT(WORD(POINT+4)) write(*,*) ‘resolutions’, GRXMX0,GRYMX0,GRXPIN,GRYPIN write(15,*) ‘resolutions’,GRXMX0,GRYMX0,GRXPIN,GRYPIN close(15) * * CLOSE UP THE PRINTER * call toolbx(prclose,xprclose) ! Close the printing grafport pause ‘Press return to exit’ stop end Listing Two: PrTrap.inc * File: prtrap.inc 29 Dec 1987 JHL * A replacement for Absoft’s prport.inc and prport.sub . * This implements traps for Fortran so that it can be used with toolbx.sub . * Called together by J. Lieske, Jet Propulsion Laboratory, based upon * Inside Mac V and Lightspeed Pascal equates. * * The general calling sequence for procedures is * CALL TOOLBX(PrRoutine, Args, xPrRoutine) * while that for a function is * TOOLBX(PrRoutine, Args, xPrRoutine) . * In the above parameters, PrRoutine is the encoded PrGlue (Printer Trap * $A8FD) parameter and xPrRoutine is the ‘call number’ as specified in * Inside Mac V Chapter 22. The ‘Args’ are the sequence of arguments to * the procedure or function as specified by Inside Mac. * Basically, the xPrRoutine ‘call number’ is placed on the stack * just ahead of the printer trap number ($A8FD) and the Fortran PrRoutine * parameter tells Fortran’s TOOLBX how to interpret the ‘Args’ and * ‘xPrRoutine’ values. * For example, the routine PrintDefault is called from * Fortran as follows: CALL TOOLBX( PRINTDEFAULT, hPrint, xPRINTDEFAULT) . * * * * * * * * * * * * * * * * * * * * * * * Modification history: * 12/87 JHL Developed basic parameters from Absoft’s documentation * of toolbx.sub and Apple’s Inside Mac V and Lightspeed * Pascal. * * * * * * * * * * * * * * * * * * * * * * PROCEDURE PrOpen; INTEGER*4 PROPEN, xPROPEN PARAMETER (PROPEN=Z’8FD10000', xPROPEN=Z’C8000000') * PROCEDURE PrClose; INTEGER*4 PRCLOSE, xPRCLOSE PARAMETER (PRCLOSE=Z’8FD10000', xPRCLOSE=Z’D0000000') * PROCEDURE PrintDefault (hPrint: THPrint); INTEGER*4 PRINTDEFAULT, xPRINTDEFAULT PARAMETER (PRINTDEFAULT=Z’8FD12000', xPRINTDEFAULT=Z’20040480') * FUNCTION PrValidate (hPrint: THPrint) : BOOLEAN; INTEGER*4 PRVALIDATE, xPRVALIDATE PARAMETER (PRVALIDATE=Z’8FDD2000', xPRVALIDATE=Z’52040498') * FUNCTION PrStlDialog (hPrint: THPrint) : BOOLEAN; INTEGER*4 PRSTLDIALOG, xPRSTLDIALOG PARAMETER (PRSTLDIALOG=Z’8FDD2000', xPRSTLDIALOG=Z’2A040484') * FUNCTION PrJobDialog (hPrint: THPrint) : BOOLEAN; INTEGER*4 PRJOBDIALOG, xPRJOBDIALOG PARAMETER (PRJOBDIALOG=Z’8FDD2000', xPRJOBDIALOG=Z’32040488') * PROCEDURE PrJobMerge (hPrintSrc, hPrintDst: THPrint); INTEGER*4 PRJOBMERGE, xPRJOBMERGE PARAMETER (PRJOBMERGE=Z’8FD12400', xPRJOBMERGE=Z’5804089C’) * FUNCTION PrOpenDoc (hPrint: THPrint; pPrPort: TPPrPort; * pIOBuf: Ptr) : TpPrPort; INTEGER*4 PROPENDOC, xPROPENDOC PARAMETER (PROPENDOC=Z’8FD92480', xPROPENDOC=Z’04000C00') * PROCEDURE PrCloseDoc (pPrPort: TPPrPort); INTEGER*4 PRCLOSEDOC, xPRCLOSEDOC PARAMETER (PRCLOSEDOC=Z’8FD12000', xPRCLOSEDOC=Z’08000484') * PROCEDURE PrOpenPage (pPrPort: TPPrPort; pPageFrame: TPRect); INTEGER PROPENPAGE, xPROPENPAGE PARAMETER (PROPENPAGE=Z’8FD12400', xPROPENPAGE=Z’10000808') * PROCEDURE PrClosePage (pPrPort: TPPrPort); INTEGER*4 PRCLOSEPAGE, xPRCLOSEPAGE PARAMETER (PRCLOSEPAGE=Z’8FD12000', xPRCLOSEPAGE=Z’1800040C’) * Note: prStatus should actually be passed as a pointer to a TPrStatus * record. * PROCEDURE PrPicFile (hPrint: THPrint; pPrPort: TPPrPort; pIOBuf: Ptr; * pDevBuf: Ptr; VAR prStatus: TPrStatus); INTEGER*4 PRPICFILE, xPRPICFILE PARAMETER (PRPICFILE=Z’8FD124B2', xPRPICFILE=Z’60051480') * FUNCTION PrError : INTEGER; INTEGER*4 PRERROR, xPRERROR PARAMETER (PRERROR=Z’8FD50000', xPRERROR=Z’BA000000') * PROCEDURE PrSetError(iErr : INTEGER); INTEGER*4 PRSETERROR, xPRSETERROR PARAMETER (PRSETERROR=Z’8FD0A000', xPRSETERROR=Z’C0000200') * PROCEDURE PrDrvrOpen; INTEGER*4 PRDRVROPEN, xPRDRVROPEN PARAMETER (PRDRVROPEN=Z’8FD10000', xPRDRVROPEN=Z’80000000') * PROCEDURE PrDrvrClose; INTEGER*4 PRDRVRCLOSE, xPRDRVRCLOSE PARAMETER (PRDRVRCLOSE=Z’8FD10000', xPRDRVRCLOSE=Z’88000000') * PROCEDURE PrCtlCall(iWhichCtl: Integer; lParam1, lparam2, lparam3: LongInt); INTEGER*4 PRCTLCALL, xPRCTLCALL PARAMETER (PRCTLCALL=Z’8FD0A490', xPRCTLCALL=Z’A0000E00') * FUNCTION PrDrvrDCE: Handle; INTEGER*4 PRDRVRDCE, xPRDRVRDCE PARAMETER (PRDRVRDCE=Z’8FD90000', xPRDRVRDCE=Z’94000000') * FUNCTION PrDrvrVers: Integer; INTEGER*4 PRDRVRVERS, xPRDRVRVERS PARAMETER (PRDRVRVERS=Z’8FD50000', xPRDRVRVERS=Z’9A000000') * PROCEDURE PrGeneral(pData: Ptr); INTEGER*4 PRGENERAL, xPRGENERAL PARAMETER (PRGENERAL=Z’8FD12000', xPRGENERAL=Z’70070480') * PrGeneral is the gateway to the calls documented in Inside Mac V * concerning added capabilities for printer resolution, etc. * See the file PrGenDefs.inc and the demo program for usage * PROCEDURE PrPurge; INTEGER*4 PRPURGE, xPRPURGE PARAMETER (PRPURGE=Z’8FD10000', xPRPURGE=Z’A8000000') * PROCEDURE PrNoPurge; INTEGER*4 PRNOPURGE, xPRNOPURGE PARAMETER (PRNOPURGE=Z’8FD10000', xPRNOPURGE=Z’B0000000') * FUNCTION PrStlInit (hPrint: THPrint): TPPrDlg; INTEGER*4 PRSTLINIT, xPRSTLINIT PARAMETER (PRSTLINIT=Z’8FD92000', xPRSTLINIT=Z’3C04040C’) * FUNCTION PrJobInit (hPrint: THPrint): TPPrDlg; INTEGER*4 PRJOBINIT, xPRJOBINIT PARAMETER (PRJOBINIT=Z’8FD92000', xPRJOBINIT=Z’44040410') * FUNCTION PrDlgMain(hPrint: THPrint; pDlgInit: ProcPtr): Boolean; INTEGER*4 PRDLGMAIN, xPRDLGMAIN PARAMETER (PRDLGMAIN=Z’8FDD2400', xPRDLGMAIN=Z’4A040894') * end of prtrap.inc listing Listing Three: PrGenDefs.inc * File: PrGenDefs.inc Definitions for calls to printer trap PrGeneral * 1/11/88 Jay Lieske * * Information for GetRsl * This file contains definitions for calls to PrGeneral with iOpCode=4 * (called gOpCode here) which is the GetRslData call. * * the GetRslData record is of length 128 bytes integer*1 GetRslDataRec(128) integer*2 gOpCode integer*2 gError integer*4 gReserved integer*2 iRgType integer*2 XRslRg(2) integer*2 YRslRg(2) integer*2 iRslRecCnt integer*2 rgRslRec(2,27) ! defined as ARRAY[1..27] of TRslRec equivalence (GetRslDataRec(1), gOpCode) equivalence (GetRslDataRec(3), gError) equivalence (GetRslDataRec(5), gReserved) equivalence (GetRslDataRec(9), iRgType) equivalence (GetRslDataRec(11), XRslRg) equivalence (GetRslDataRec(15), YRslRg) equivalence (GetRslDataRec(19), iRslRecCnt) equivalence (GetRslDataRec(21), rgRslRec) integer*4 pGetRslData C parameter (gOpCode = 4) * You must set the value of gOpCode * in program. Get pointer to GetRslDataRec via: pGetRslData = TOOLBX(PTR,GetRslDataRec ) * and then CALL toolbx(PrGeneral, pGetRslData, xPrGeneral) * end of data for GetRsl * Information for SetRsl * This file contains definitions for calls to PrGeneral with iOpCode=5 * (called pOpCode here) which is the SetRslData call. * * the SetRslData record is of length 16 bytes integer*1 SetRslRec(16) integer*2 pOpCode integer*2 pError integer*4 pReserved integer*4 hPrint integer*2 iXRsl integer*2 iYRsl equivalence (SetRslRec(1), pOpCode) equivalence (SetRslRec(3), pError) equivalence (SetRslRec(5), pReserved) equivalence (SetRslRec(9), hPrint) equivalence (SetRslRec(13), iXRsl) equivalence (SetRslRec(15), iYRsl) integer*4 pSetRsl C parameter (pOpCode = 5) * You must set the values of pOpCode = 5 and hPrint = handle to Print Record * in program. Get pointer to SetRslRec via: pSetRsl = TOOLBX(PTR,SetRslRec) * and then CALL toolbx(PrGeneral, pSetRsl, xPrGeneral) * end of data forSetRsl * end of file PrGenDefs.inc
![](/file/12652/www.mactech.com.tar/www.mactech.com/sites/all/themes/custom_front/img/search_text.gif)
- SPREAD THE WORD:
- Slashdot
- Digg
- Del.icio.us
- Newsvine