-d(X; ==================================nX;x%X; A GRAPHICS PRINTING DEVICE'X; G: FOR EPSON OR GEMINI PRINTERSX;(X; ==================================X;X;!X; (c) 1985 by CHARLES JOHNSON X; and Little Green FootballsX;X; G1: --- 80 Column NormalX; G2: --- 40 Column Normal$X; G3: --- 40 Column Double-Width$X; G4: --- 60 Column Double-WidthX;X; XIO 16,#1,0,0,"G:" --- X; print a GRAPHICS 0 screen.#X; Any XIO command # larger than"!X; 16 will be used as the # of, X; screen lines to print +16.6X;@X; XIO 64,#1,0,0,"G:" ---J"X; print a GRAPHICS 8 or 7+ (E)T X; screen.^X;hX; Auxiliary byte 2 values:rX; (These go in ICAX2)|X;X; 0 - 8/72 in. line feedX; 1 - 9/72 in. LFX; 2 - 12/72 in. LF"X; 255 - INVERSE PRINT (XIO 64)X;"X; Any number (n) larger than 2!X; will be used as n/72 in. LFX;X;X; --------------X; System equatesX; --------------X; DOSVEC  DOSINI  ICDNOZ!& ICCOMZ"0 ICAX1Z*: ICAX2Z+D SAVMSCXN ZPOUTPX FNTPTRb SCRPTRl POINTRvX; RUNADINITAD MEMLO CHBASX;DDEVICHATABSPRNBUF SIOVYX;#X; -----------------------------#X; Make this routine RESET-proof#X; -----------------------------X; %X;  START *PILFERQDOSVEC4 PDVSAVE>QDOSVECHPDVSAVERQDOSINI;;Steal the DOS\PSTART;;init vectorsfPDVSAVE;;and put thempQDOSINI;;in my codez PSTARTPDVSAVEQ>4START;;Put addressPDOSINI;;of G: init codeQ>5START;;in DOSINIPDOSINI:X; INITADX; PILFERX;X; ---------------------X; Install the G: deviceX; ---------------------X; PILFER$X;.INSTAL$>8!SEARCHQHATABS9;;Look for theBFADDG;;end of theL2;;handler tableV2`2j HSEARCHtX;~ADDGQ> G;;Add G: to thePHATABS9;;device tableQ>4GDRIVERPHATABS9Q>5GDRIVERPHATABS9Q>4GDVEC;;Reset DOSPDOSVEC;;vectors Q>5GDVECPDOSVECQ>4PND;;Reset the MEMLOPMEMLO;;pointer Q>5PND PMEMLO :X;X; ----------------------(X; The table of addresses2X; ----------------------<X;FGDRIVER GOPENP GCLOSEZ GGETBd GPUTBn GSTATx GXIO !GINITX;"X; DOS commands go through hereX; GDVEC$>GDV2QDVSAVE9;;Restore DOSPDOSVEC9;;vectors0 IGDV2!@DOSVEC:;;Go to DOS!X;X; =======================X; THE G: HANDLER ROUTINESX; =======================X;X; ----------------"X; The OPEN routine,X; ----------------6X;@ GOPEN6JA;;Calling IOCB #TV?;;Divide by 16^V?;;to use as indexhV?rV?|?;;Move to Y1;;-1GSETERR;;<0 = error)>;;>6 = errorDGO2SETERR%>;;Bad IOCB # HGORTSX;GO2$ICDNOZ;;Get device #0;;Subtract 1&SPLIT;;Store itQGRNUM9;;Put gr mode inPGRTBL8;;tableQICAX2Z;;Get LF valueR>;;Inverse pic?HGO3;;No, skipQ>;;Reset for LF&GO3R>;;>=3?0ESETLFT;;Yes, skip:>;;Move index to XDQLFNUM9;;Get preset LFN"SETLFTPLNFEED;;Put LF in initXQICCOMZ;;Get command #bR>@;;Picture dump?lHCLP1;;No, skipvQICAX1Z;;Get widthR>;;Single width?ENOTSNG;;No, skipQ>;;Margin at 28 HSETMGNX;NOTSNGR>;;Double width?ENOTDBL;;No, skipQ>;;Margin at 14 HSETMGNX;NOTDBLQ>;;Margin at 1SETMGNPMARGN;;Set marginCLP1 CLPBUF;;Clear bufferPXIO?;;Clear XIO flag $>ICLENCCODESQICODES9;;Copy init PPRNBUF9;;codes to SIO* 0;;buffer4 ICCODES> DOSIO;;Send init codesHGGORTS;;Error, skipR INIT\%>f GORTS8p:zX;X; -----------------X; The CLOSE routineX; -----------------X;GCLOSE CLPBUFQ>;;Reset printerPPRNBUF;;and send oneQ>@;;line feedPPRNBUFQ>PPRNBUF DOSIO GSTAT GINIT%> GGETB: X;$ X; ----------------. X; PUT BYTE routine8 X; ----------------B X;L GPUTB6V &XSAVE` 5j $>t GP1QZPOUTP9;;Save zero page~ PZPSAVE9;;locations 0 IGP1 QOUTPTR;;Set zero page PZPOUTP;;pointer to QOUTPTR;;gr buffer PZPOUTP 7 %XIO?;;Is this XIO? FGP1.2;;No, skip )>@;;Gr 8 dump? HGP2;;No, skip QICAX2Z;;Set inverse PINVERS;;flag Q>4GRBUF;;Set pointer to PFNTPTR;;graphics buffer Q>5GRBUF( PFNTPTR2 HBYTE1< X;F GP1.2R>;;End of line?P HGP2;;No, skipZ !DOPRINT;;Go print it!d X;n GP2%>x 'INVERS 'FNTPTR T?;;Clear inverse WINVERS;;bit and save V? %XIO? HCONVERT R> ;;Convert from ECK2;;ATASCII to O>@;;internal code DCONVERT CK2R>` ECONVERT ; S>  X; CONVERT%>" GETINDEXT?;;Get index into, UFNTPTR;;char set table6 1@ HGETINDEXJ X;T PFNTPTR;;Set pointer to^ QCHBAS;;char storageh LFNTPTRr PFNTPTR| X; BYTE1%>;;Eight bytes 'BYTCNT;;per character "BYTELOOPQ@FNTPTR7;;Get a byte %INVERS;;Inverse char? FB2;;No, skip N>;;Reverse bits B2%>;;8 bits per byte BITLOOPV?;;Bit to carry 5;;Save byte Q@ZPOUTP7;;Roll bit W?;;sideways into P@ZPOUTP7;;each byte 7;;Restore byte 1;;Next bit IBITLOOP X;& "BYTCNT;;Count bytes0 %BYTCNT;;More?: IBYTELOOP;;Yes, go backD X;N %>X CKRETQ@ZPOUTP7b R>;;Check for EOLsl HNOTRET;;in outputv Q>;;Replace P@ZPOUTP7 NOTRET1 ICKRET X; , QZPOUTP;;Increment ptr O>;;to print buffer POUTPTR;;by 8 bytes PZPOUTP DSKIP #OUTPTR #ZPOUTP SKIP#OUTCNT;;Count chars $SPLIT;;Is this 80-col? FEXIT;;Yes, exit QOUTCNT;;Have we done RSPVAL9;;one line?* HEXIT;;No, more bytes4 X;> DOPRINT%>;;Put EOL at endH Q>;;of print bufferR P@ZPOUTP7\ 'DONE;;Clear done flagf $>p !MULT8TOUTCNT;;Multiply the #z UOUTCNT;;of characters 0;;by 8 to get the HMULT8;;# of gr bytes QXIO? R>@ HNOTPIC Q>L HSETM X; NOTPICQXSAVE;;Get IOCB # V?;;Divide by 16 V? V? V?>;;Move to X0;;-1QGRTBL9;;Get gr mode$SETMPGRMODE;;Put in header.Q>4HEADER;;Set pointer8PPOINTR;;to start ofBQ>5HEADER;;header andLPPOINTR;;print bufferV!SENDEM CLPBUF;;Clear SIO buf`?jSEND2Q@POINTR7;;Move charstPPRNBUF8;;40 at a time~R>;;to SIO bufferHSEND3;;(or until EOL)PDONE;;Set done flagFPRNT;;SkipX; SEND33)>( HSEND2,;;Increment zeroQPOINTR;;page pointer by O>(;;40 PPOINTR DPRNT#POINTR PRNT DOSIO;;Send 40 bytesQDONE;;Done?FSENDEM;;No, do the rest( INIT;;Re-init2 EXIT$><EX1QZPSAVE9;;Restore zeroFPZPOUTP9;;page locationsP0ZIEX1d8n%>;;=Successfulx:X;!X; ---------------------------!X; The XIO screen dump routine!X; ---------------------------X;GXIO&XSAVE;;Save IOCB # GOPEN;;Open G:)>;;Open OK?HGXXIT;;No, exitQ>;;Set line length PSPLITQSAVMSC;;Set pointersPSCRPTR;;to start ofPCOLPTR;;screen memory PROWPTRQSAVMSC"PSCRPTR,PCOLPTR6PROWPTR@QICCOMZ;;Get command #JPXIO?;;Store itTR>@;;Gr 8 dump?^FGR8;;Yes, go to ithR>;;Full screen?rESHORT;;No, skip|Q>;;Set 24 linesHSETLIN;;SkipX;SHORTS>;;Subtract 16"SETLINPLINNUM;;Set # of linesX;STLINEQ>;;Clear bytePLINIX;;index PRSCRN%LINIX;;Get byte fromQ@SCRPTR7;;screen mem $XSAVE GPUTB;;Send to G:#LINIX;;Inc index QLINIXR>(;;Done one line?HPRSCRN;;No, go back NEXTLN;;Inc pointer&"LINNUM;;Count lines0HSTLINE;;Not done yet:GXXIT!GCLOSEDX;NGR8QICAX1Z;;Get widthXR>;;Single?bDCKHT;;Yes, skiplR>;;Double width?vECKW2;;No, skipQ>;;Length indexHCKW3;;SkipX;CKW2Q>;;Length indexCKW3PSPLITCKHTQICDNOZR>;;>2=Dbl heightDNOT4;;Not dbl, skipPDBLHT;;Set flag$>4(;;Set offset to%>5(;;next rowQ>0;;Set # of rows HSETG8X; NOT4Q>;;Not dbl heightPDBLHT;;Clear flag $>4(;;Offset* %>5(4Q>;;# of rows>SETG8&ROWADDH'ROWADDR PENDROW\Q>;;Clear row countf PROWCNTpGR8.1Q>;;Set column to 0z PCOLCNT!GR8.2QCOLPTR;;Set pointer toPSCRPTR;;screenQCOLPTRPSCRPTR$> GET8B%>Q@SCRPTR7;;Move bytesPGRBUF9;;to buffer%DBLHT;;Double height?FGET8.1;;No, skipPGRBUF9;;Double it!GET8.1 NEXTLN;;Inc pointer2)>;;Double height?DGET8.2;;No, skip2$GET8.2(>;;Done 8 bytes?.HGET8B;;No, do the rest8QICAX1Z;;Get widthB R>;;>1?LDNOTDBW;;No, skipV EXPAND;;Expand 'em`$>j!DBW1QWIDBUF9;;These sectionstPGRBUF9;;copy the wide~0;;buffer to theIDBW1;;gr print buffer GPUTB;;& send it to G:$>DBW2QWIDBUF9 PGRBUF90 IDBW2 GPUTB QICAX1ZR> HNOTDB2$>DBW3QWIDBUF9  PGRBUF90 IDBW3(NOTDBW GPUTB;;Send to G:2#NOTDB2#COLPTR;;Move pointer to<HGR8.3;;next columnF#COLPTRP GR8.3#COLCNT;;Count columnsZ QCOLCNTdR>(;;Done 40?nHGR8.2;;No. Do the restx,QROWPTR;;Set row pointerOROWADD;;to the next row PROWPTRPCOLPTR;;Also store hereQROWPTROROWADDPROWPTRPCOLPTR#ROWCNT;;Count rows QROWCNTRENDROW;;Done all?FGR8XIT;;Yes, skip !GR8.1X;GR8XITQ>;;Reset margin PMARGN" !GCLOSE,X;6X; -----------@X; SubroutinesJX; -----------TX;^INITQ>;;Clear theh>;;output bufferrCLRBUFPOUTBUF9|POUTBUF9POUTBUF9POUTBUF9POUTBUF92 HCLRBUFPOUTCNT;;Clear characterPOUTCNT;;counterQ>4OUTBUF;;Set pointerPOUTPTR;;to buffer start Q>5OUTBUFPOUTPTR:X;CLPBUF$>';;Clear the SIOQ>;;print bufferCLP2PPRNBUF9&00 ICLP2::DX;N DOSIO$> XCOPYQPRNCOM9;;Copy printbPDDEVIC9;;commands tol 0;;the DCBv ICOPY !SIOVX;NEXTLN,;;Increment scrnQSCRPTR;;pointer by oneO>(;;line; 40 bytes PSCRPTR DNLN2#SCRPTR NLN2:X;EXPAND$>;;Clear the wideQ>;;bufferCLWBUFPWIDBUF90  ICLWBUF$>;;Expand 8 bytes EXP1Q>;;7 bits per byte* PBITCNT4QGRBUF9;;Get byte>EXP2V?;;Shift bitH5;;Save byteR%ICAX1Z;;Get width\EXP36;;Save status regfWWIDBUF9;;Roll carrypWWIDBUF9;;thru 3 byteszWWIDBUF98;;Restore status1;;Width countHEXP3;;Not done7;;Restore byte"BITCNT;;Count bitsIEXP2;;Not done yet0;;Count bytesIEXP1;;Not done yet! :;;DONE!!!X;X; ------------------X; Miscellaneous dataX; ------------------X;DVSAVE;;DOS vectorsPRNCOM @;;Printer$ ;;Device number. W;;Write8 ;;OutputB PRNBUF;;Buffer addressL ;;TimeoutV (;;Buffer length` N;;Normal printj ;;UnusedtZPSAVE ===~OUTPTR ;;Ptr to bufferXSAVE ;;Calling IOCB #BYTCNT ;;Byte counterBITCNT ;;Bit counterINVERS ;;Inverse flagSPLIT ;;Length indexDONE ;;Line done flagXIO? ;;XIO flagLINIX ;;Screen indexLINNUM ;;# of linesROWCNT ;;Row counterCOLCNT ;;Column counterROWPTR ;;Row pointerCOLPTR ;;Column pointer ROWADD ;;Offset to rowENDROW ;;# of rowsDBLHT ;;Dbl height flag(!GRBUF =======2"WIDBUF =======< ===FGRTBL ======PGRNUM L=L=K=KZLFNUM = = dSPVAL =&=&=<=(=P=xnICODES =@;;Init printerx =N=;;Skip perf =MMARGN ;;Left margin =ALNFEED ;;LF (n/72 in.)X;ICLEN ICODESX; HEADER  GRMODE  OUTCNT X;OUTBUF;;Print bufferX; PND X; RUNAD" INSTAL,