glu@gypsy.UUCP (03/09/86)
Here is a printer driver for Okidata ML92 printers. I use it with my parallel printer. It does both alpha and graphics and is written according to the guidelines in ROM Kernel Manual 1.1. I also included a routine to dump an entire workbench screen on the printer (copied from Fred Fish's disk #5, added routines to make it link and run). You have to separate the following file into 11 different files (including a makefile to compile and link it). I will probably improve the printer driver (i.e. optimize graphics printing because it's real slooooow, provide italics fonts for alpha printing and support some more of the suggested escape sequences in ROM Kernel Manual) If somebody else enhances it, please let me participate in your improvements My address is Raimund Gluecker 26 Trafalgar Court Lawrenceville, NJ 08648 (609) 896-4860 (nights) (609) 734-6536 (days - eastern time) Since I'm not a UNIX Guru, I can't figure out my electronic mail address. If you do not have a C compiler, you might as well send me $6 and I'll copy the stuff on a disk and send it to you. ----- cut ----- cut ----- cut ----- cut ----- cut ----- cut ----- cut ----- ***************************************************************************** /* data.c data.c data.c data.c data.c data.c data.c data.c data.c data.c */ ***************************************************************************** /* Command Table Data for Okidata ML92 */ char *CommandTable[] = { "\030\033\011\n\033%C000", /* reset RIS */ "\377", /* initialize RIN */ "\012", /* lf IND */ "\015\012", /* return, lf NEL */ "\377", /* reverse lf RI */ "\033I\033D", /* normal character set SGR0 */ "\377", /* italics on SGR3 */ "\377", /* italics off SGR23 */ "\033C", /* underline on SGR4 */ "\033D", /* underline off SGR24 */ "\033H\033T", /* boldface on SGR1 */ "\033I", /* boldface off SGR22 */ "\377", /* set foreground color SFC */ "\377", /* set background color SBC */ "\036", /* normal pitch SHORP0 */ "\034", /* elite on SHORP2 */ "\036", /* elite off SHORP1 */ "\035", /* condensed (fine) on SHORP4 */ "\036", /* condensed off SHORP3 */ "\037", /* enlarged on SHORP6 */ "\036", /* enlarged off SHORP5 */ "\377", /* shadow print on DEN6 */ "\377", /* shadow print off DEN5 */ "\377", /* doublestrike on DEN4 */ "\377", /* doublestrike off DEN3 */ "\0331", /* Near Letter Quality on DEN2 */ "\0330", /* Near Letter Quality off DEN1 */ "\033J", /* superscript on SUS2 */ "\033K", /* superscript off SUS1 */ "\033L", /* subscript on SUS4 */ "\033M", /* subscript off SUS3 */ "\033K\033M", /* normalize SUS0 */ "\377", /* partial line up PLU */ "\377", /* partial line down PLD */ "\377", /* US char set FNT0 */ "\377", /* French char set FNT1 */ "\377", /* German char set FNT2 */ "\377", /* UK char set FNT3 */ "\377", /* Danish I char set FNT4 */ "\377", /* Swedish char set FNT5 */ "\377", /* Italian char set FNT6 */ "\377", /* Spanish char set FNT7 */ "\377", /* Japanese char set FNT8 */ "\377", /* Norweign char set FNT9 */ "\377", /* Danish II char set FNT10 */ "\377", /* proportional on PROP2 */ "\377", /* proportional off PROP1 */ "\377", /* proportional clear PROP0 */ "\377", /* set prop offset TSS */ "\377", /* auto left justify JFY5 */ "\377", /* auto right justify JFY7 */ "\377", /* auto full justify JFY6 */ "\377", /* auto justify off JFY0 */ "\377", /* letter space JFY3 */ "\377", /* auto center on JFY1 */ "\0338", /* 1/8" line spacing VERP0 */ "\0336", /* 1/6" line spacing VERP1 */ "\033F", /* set form length SLPP */ "\377", /* Perf skip on PERF */ "\377", /* Perf skip off PERF0 */ "\377", /* left margin set LMS */ "\377", /* right margin set RMS */ "\377", /* top margin set TMS */ "\377", /* bottom margin set BMS */ "\377", /* top & bottom margin set STBM */ "\377", /* left & right margin set SLRM */ "\033%C000", /* clear margins CAM */ "\377", /* set horizontal tab HTS */ "\377", /* set vertical tab VTS */ "\377", /* clear horizontal tab TBC0 */ "\033\011\015", /* clear all horizontal tabs TBC3 */ "\377", /* clear vertical tab TBC1 */ "\377", /* clear all vertical tabs TBC4 */ "\033\011\015", /* clear all h & v tabs TBCALL */ "\377", /* set default tabs TBSALL */ "\377" /* entended command EXTEND */ }; ***************************************************************************** /* dospecial.c dospecial.c dospecial.c dospecial.c dospecial.c dospecial.c */ ***************************************************************************** /* Okidata ML 92 special commands */ #include "exec/types.h" #include "devices/printer.h" #include "devices/prtbase.h" extern struct PrinterData *PD ; DoSpecial(command,OutputBuffer,vline,currentVMI,crlfFlag,Parms) UWORD *command ; /* command number as defined in printer.h */ char OutputBuffer[] ; /* buffer into which to return converted command */ BYTE *vline ; /* value of the current line position */ BYTE *currentVMI ; /* value of the current line spacing */ BYTE *crlfFlag ; /* setting of the add <lf> after <cr> flag */ UBYTE Parms[] ; /* parameters that came with ANSI command */ { int i, x = 0 ; static char initTabs[]="\033\011008,016,024,032,040,048,056,064,072\n" ; static char initPrinter[]="\0331\0336" ; if (*command == aRIN ) { /* initialize output buffer */ for (i=0; i < 4; i++) OutputBuffer[x++] = initPrinter[i] ; /* get preferences settings */ if ( (PD->pd_Preferences.PrintQuality) == DRAFT ) OutputBuffer[1] = '0' ; *currentVMI = 36 ; /* initially 1/6" line spacing */ if ( (PD->pd_Preferences.PrintSpacing) == EIGHT_LPI ) { OutputBuffer[3] = '8' ; *currentVMI = 27 ; } if ( (PD->pd_Preferences.PrintPitch) == ELITE ) OutputBuffer[x++] = '\034' ; else if ( (PD->pd_Preferences.PrintPitch) == FINE ) OutputBuffer[x++] = '\035' ; /* what else? */ *command = aTBSALL ; } if (*command == aTBSALL) { for (i=0; i < 38; i++ ) OutputBuffer[x++] = initTabs[i] ; return(x) ; } /* other special functions? -> later italics in downloadable character set */ return(0) ; } ***************************************************************************** /* Dump.h Dump.h Dump.h Dump.h Dump.h Dump.h Dump.h Dump.h Dump.h Dump.h */ ***************************************************************************** union printerIO { struct IOStdReq ios; struct IODRPReq iodrp; struct IOPrtCmdReq iopc; }; ***************************************************************************** /* DumpRPort.c DumpRPort.c DumpRPort.c DumpRPort.c DumpRPort.c DumpRPort.c */ ***************************************************************************** #include "exec/types.h" #include "intuition/intuition.h" #include "devices/printer.h" #include "Dump.h" int DumpRPort(req, rastPort, colorMap, modes, sx, sy, sw, sh, dc, dr, s) union printerIO *req ; struct RastPort *rastPort; struct ColorMap *colorMap; ULONG modes; UWORD sx, sy, sw, sh; LONG dc, dr; UWORD s; { req->iodrp.io_Command = PRD_DUMPRPORT; req->iodrp.io_RastPort = rastPort; req->iodrp.io_ColorMap = colorMap; req->iodrp.io_Modes = modes; req->iodrp.io_SrcX = sx; req->iodrp.io_SrcY = sy; req->iodrp.io_SrcWidth = sw; req->iodrp.io_SrcHeight = sh; req->iodrp.io_DestCols = dc; req->iodrp.io_DestRows = dr; req->iodrp.io_Special = s; return(DoIO(req)); } int OpenPrinter(request) union printerIO *request; { return(OpenDevice("printer.device", 0, request, 0)); } int ClosePrinter(request) union printerIO *request; { return(CloseDevice(request)); } ***************************************************************************** /* DumpWB.c DumpWB.c DumpWB.c DumpWB.c DumpWB.c DumpWB.c DumpWB.c DumpWB.c */ /* The following is a copy of program "printer.c" from Fred Fish's Disk #5 */ /* It links together with the object produced from "DumpRPort.c" */ ***************************************************************************** /* * * DISCLAIMER: * * This program is provided as a service to the programmer * community to demonstrate one or more features of the Amiga * personal computer. These code samples may be freely used * for commercial or noncommercial purposes. * * Commodore Electronics, Ltd ("Commodore") makes no * warranties, either expressed or implied, with respect * to the program described herein, its quality, performance, * merchantability, or fitness for any particular purpose. * This program is provided "as is" and the entire risk * as to its quality and performance is with the user. * Should the program prove defective following its * purchase, the user (and not the creator of the program, * Commodore, their distributors or their retailers) * assumes the entire cost of all necessary damages. In * no event will Commodore be liable for direct, indirect, * incidental or consequential damages resulting from any * defect in the program even if it has been advised of the * possibility of such damages. Some laws do not allow * the exclusion or limitation of implied warranties or * liabilities for incidental or consequential damages, * so the above limitation or exclusion may not apply. * */ /* printer.c - program to do a raster dump to whatever printer is specified * by Preferences, of the Workbench Screen. * * Author: Rob Peck, 12/1/85 * * This code may be freely utilized to develop programs for the Amiga */ #include "exec/types.h" #include "intuition/intuition.h" #include "devices/printer.h" #include "Dump.h" #define INTUITION_WONT_OPEN 1000 union printerIO *request; /* a pointer to a request block */ extern int DumpRPort(); extern int OpenPrinter(); extern int ClosePrinter(); extern struct IORequest *CreateExtIO(); extern struct Window *OpenWindow(); extern struct Port *CreatePort(); struct IntuitionBase *IntuitionBase; struct NewWindow nw = { 0, 0, 100, 40, 0, 1, 0, 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN }; main() { struct Window *w; struct Screen *screen; struct RastPort *rp; struct ViewPort *vp; struct ColorMap *cm; union printerIO sizeDummy; int modes,width,height,error; struct Port *printerPort; /* at which to receive reply */ IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 0); if (IntuitionBase == NULL) exit(INTUITION_WONT_OPEN); w = OpenWindow(&nw); if(w == NULL) goto cleanup1; screen = w->WScreen; /* get screen address from window */ CloseWindow(w); /* once have screen address, no * more need for window, close it. */ vp = &screen->ViewPort; /* get screen's ViewPort, from * which the colormap will be gotten */ rp = &screen->RastPort; /* get screen's RastPort, which * is what gets dumped to printer */ cm = vp->ColorMap; /* retrieve pointer to colormap for * the printer dump */ modes = vp->Modes; /* retrieve the modes variable */ width = vp->DWidth; /* retrieve width to print */ height = vp->DHeight; /* retrieve height to print */ printerPort = CreatePort("my.print.port",0); request = (union printerIO *)CreateExtIO(printerPort, sizeof(sizeDummy)); error = OpenPrinter(request); if(error != 0) goto cleanup2; Delay(300); /* 300/60 = 6 seconds delay before it starts */ error = DumpRPort( request,/* pointer to initialized request */ rp, /* rastport pointer */ cm, /* color map pointer */ modes, /* low, high res, etc (display modes)*/ 0, 0, /* x and y offsets into rastport */ width,height, /* source size */ width,(height * 2), /* dest rows, columns */ SPECIAL_FULLROWS | SPECIAL_FULLCOLS | SPECIAL_ASPECT /* io Special value, says print * as pixels only, direct copy */ ); ClosePrinter(request); cleanup2: DeleteExtIO(request, sizeof(sizeDummy)); DeletePort(printerPort); cleanup1: CloseLibrary(IntuitionBase); } /* end of demo screen dump */ ***************************************************************************** * init.asm init.asm init.asm init.asm init.asm init.asm init.asm init.asm * ***************************************************************************** **** initialization for Okidata ML 92 ***************************** SECTION printer *---- Included files ---------------------------------------------- INCLUDE "exec/types.i" INCLUDE "exec/nodes.i" INCLUDE "exec/lists.i" INCLUDE "exec/memory.i" INCLUDE "exec/ports.i" INCLUDE "exec/libraries.i" INCLUDE "macros.i" *---- Imported Functions ------------------------------------------ XREF_EXE CloseLibrary XREF_EXE OpenLibrary XREF _AbsExecBase XREF _PEDData *---- Exported Globals -------------------------------------------- XDEF _Init XDEF _Expunge XDEF _Open XDEF _Close XDEF _PD XDEF _PED XDEF _SysBase XDEF _GfxBase ******************************************************************* SECTION printer,DATA _PD DC.L 0 _PED DC.L 0 _SysBase DC.L 0 _GfxBase DC.L 0 ******************************************************************* SECTION printer,CODE _Init: MOVE.L 4(A7),_PD LEA _PEDData(PC),A0 MOVE.L A0,_PED MOVE.L A6,-(A7) MOVE.L _AbsExecBase,A6 MOVE.L A6,_SysBase LEA GLName(PC),A1 MOVEQ #0,D0 CALLEXE OpenLibrary MOVE.L D0,_GfxBase BEQ initGLErr MOVEQ #0,D0 pdiRts: MOVE.L (A7)+,A6 RTS initGLErr: MOVEQ #-1,D0 BRA.S pdiRts GLName: DC.B 'graphics.library' DC.B 0 DS.W 0 *---------------------------------------------------------------- _Expunge: MOVE.L _GfxBase,A1 LINKEXE CloseLibrary *---------------------------------------------------------------- _Open: _Close: MOVEQ #0,D0 RTS END ***************************************************************************** * macros.i macros.i macros.i macros.i macros.i macros.i macros.i macros.i * ***************************************************************************** **************************************************************** * Printer Device Macros **************************************************************** *---- external definition macros ------------------------------- XREF_EXE MACRO XREF _LVO\1 ENDM XREF_GFX MACRO XREF _LVO\1 ENDM *---- library dispatch macros ---------------------------------- CALLEXE MACRO CALLLIB _LVO\1 ENDM LINKEXE MACRO LINKLIB _LVO\1,_SysBase ENDM LINKGFX MACRO LINKLIB _LVO\1,_GfxBase ENDM ***************************************************************************** makefile makefile makefile makefile makefile makefile makefile makefile ***************************************************************************** # works with make/pdmake from Fred Fish's disk #2 # I use the Lattice C 3.03 from a disk called "CC" and the assembler from a # disk called "ASM". After you have modified the 3 macros at the beginning # of the makefile you should copy the makefile to RAM: and then cd to RAM: # This way I have the minimum disk changes with just one drive. # It compiles and links both the Okidata ML92 printer driver and the Dump # Workbench routines. SOURCE = C-work:printer # redefine with the destination of your # source directory CCDISK = cc: # redefine with name of your cc disk ASMDISK = ASM: # redefine with name of your asm disk CFLAGS1 = -iRAM: -i$(CCDISK)include/ -i$(CCDISK)include/lattice/ ASMOPT = -i RAM:+$(ASMDISK)include CC1 = $(CCDISK)c/lc1 $(CFLAGS1) RAM: CC2 = $(CCDISK)c/lc2 RAM: ASM = $(ASMDISK)c/Assem RAM: OBJS1 = $(SOURCE)/data.o $(SOURCE)/dospecial.o $(SOURCE)/init.o OBJS2 = $(SOURCE)/tag.o $(SOURCE)/render.o OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) doit : clear $(SOURCE)/Okidata_ML92 $(SOURCE)/DumpWB init init : assign CWD: $(SOURCE) assign cclib: $(CCDISK)lib assign ASMlib: $(ASMDISK)lib copy CWD:macros.i RAM: copy CWD:Dump.h RAM: clear : assign ASMlib: assign cclib: assign CWD: $(SOURCE)/Okidata_ML92 : $(OBJS) $(SOURCE)/printer.link delete RAM:macros.i copy $(SOURCE)/printer.link to RAM: $(CCDISK)c/alink WITH RAM:printer.link copy RAM:Okidata_ML92 DEVS:printers copy RAM:Okidata_ML92 CWD: delete RAM:Okidata_ML92 RAM:printer.link $(SOURCE)/data.o : $(SOURCE)/data.c copy $(SOURCE)/data.c RAM: $(CC1)data $(CC2)data copy RAM:data.o CWD: delete RAM:data.? $(SOURCE)/dospecial.o : $(SOURCE)/dospecial.c copy $(SOURCE)/dospecial.c RAM: $(CC1)dospecial $(CC2)dospecial copy RAM:dospecial.o CWD: delete RAM:dospecial.? $(SOURCE)/render.o : $(SOURCE)/render.c copy $(SOURCE)/render.c RAM: $(CC1)render $(CC2)render copy RAM:render.o CWD: delete RAM:render.? $(SOURCE)/init.o : $(SOURCE)/init.asm $(SOURCE)/macros.i copy $(SOURCE)/init.asm RAM: $(ASM)init.asm -o init.o $(ASMOPT) copy RAM:init.o CWD: delete RAM:init.\#? $(SOURCE)/tag.o : $(SOURCE)/tag.asm copy $(SOURCE)/tag.asm RAM: $(ASM)tag.asm -o tag.o $(ASMOPT) copy RAM:tag.o CWD: delete RAM:tag.\#? $(SOURCE)/DumpWB : $(SOURCE)/DumpWB.o $(SOURCE)/DumpRPort.o $(CCDISK)c/alink cclib:Lstartup.obj+cwd:DumpWB.o+cwd:DumpRPort.o TO RAM:DumpWB LIBRARY cclib:lc.lib,cclib:amiga.lib copy RAM:DumpWB CWD: delete RAM:DumpWB $(SOURCE)/DumpWB.o : $(SOURCE)/DumpWB.c Dump.h copy $(SOURCE)/DumpWB.c RAM: $(CC1)DumpWB $(CC2)DumpWB copy RAM:DumpWB.o CWD: delete RAM:DumpWB.? $(SOURCE)/DumpRPort.o : $(SOURCE)/DumpRPort.c Dump.h copy $(SOURCE)/DumpRPort.c RAM: $(CC1)DumpRPort $(CC2)DumpRPort copy RAM:DumpRPort.o CWD: delete RAM:DumpRPort.? ***************************************************************************** printer.link printer.link printer.link printer.link printer.link printer.link ***************************************************************************** FROM CWD:tag.o,CWD:init.o,CWD:data.o,CWD:dospecial.o,CWD:render.o TO RAM:Okidata_ML92 LIBRARY cclib:lc.lib,cclib:amiga.lib ***************************************************************************** /* render.c render.c render.c render.c render.c render.c render.c render.c */ ***************************************************************************** /* Graphics render for Okidata ML 92 */ #include "exec/types.h" #include "exec/nodes.h" #include "exec/lists.h" #include "exec/memory.h" #include "devices/prtbase.h" extern struct PrinterData *PD; int Render(ct, x, y, status) UBYTE ct ; /* color type = 0 for b&w printers */ UWORD x, y ; /* x and y coordinates of pixel */ /* or pc and pr print values, or special */ UBYTE status ; /* print status (0-init, 1-enter_pixel, 2-dump) */ { static UWORD BUFSIZE; static char *SpoolBuffer ; char *malloc() ; UWORD i, k; /* mics. var */ BYTE err; /* the error # */ switch(status) { case 0 : /* allocate memory for printer buffer */ BUFSIZE = x; PD->pd_PrintBuf = (UBYTE *)AllocMem(BUFSIZE,MEMF_PUBLIC); SpoolBuffer = (char *)AllocMem(BUFSIZE*2+5,MEMF_PUBLIC); /* used to actually print */ if (err=(PD->pd_PrintBuf == 0)) return(err); (*(PD->pd_PWrite))("\30\33%C000\34",8); /* non graphic, clear, clear left margin, 72 DPI */ return(0) ; break ; case 1 : /* put pixel in buffer */ PD->pd_PrintBuf[x] = PD->pd_PrintBuf[x] | (1 << (y % 7)); return(0) ; /* flag all ok */ break ; case 2 : /* dump buffer to printer */ k = 1 ; for (i=0 ; i < BUFSIZE; i++ ) { SpoolBuffer[k] = PD->pd_PrintBuf[i]&127 ; if (SpoolBuffer[k++] == '\3') /* double ETX */ SpoolBuffer[k++] = '\3' ; } SpoolBuffer[0] = '\03' ; /* Begin graphic mode */ SpoolBuffer[k++] = '\03' ; /* Graphic linefeed */ SpoolBuffer[k++] = '\16' ; SpoolBuffer[k++] = '\03' ; /* End graphic mode */ SpoolBuffer[k++] = '\02' ; (*(PD->pd_PWrite))(SpoolBuffer,k); /* write out Buffer */ return(0) ; /* flag all ok */ break ; case 3 : /* clear and init buffer */ for (i=0; i< BUFSIZE; i++) PD->pd_PrintBuf[i] = 0 ; return(0) ; /* flag all ok */ break ; case 4 : /* free print buffer memory */ (*(PD->pd_PBothReady))() ; FreeMem(PD->pd_PrintBuf,BUFSIZE) ; FreeMem(SpoolBuffer,BUFSIZE*2+5) ; return(0) ; break ; default: return(0) ; } } ***************************************************************************** * tag.asm tag.asm tag.asm tag.asm tag.asm tag.asm tag.asm tag.asm tag.asm * ***************************************************************************** ***** printer device dependent code tag *************************** SECTION printer *---- Included files ---------------------------------------------- INCLUDE "exec/types.i" INCLUDE "exec/nodes.i" INCLUDE "exec/strings.i" INCLUDE "devices/prtbase.i" *---- Imported Names ---------------------------------------------- XREF _Init XREF _Expunge XREF _Open XREF _Close XREF _CommandTable XREF _PrinterSegmentTable XREF _DoSpecial XREF _Render *---- Exported Names ---------------------------------------------- XDEF _PEDData ******************************************************************* MOVEQ #0,D0 ; show error for OpenLibrary() RTS DC.W 1 ; Version DC.W 0 ; Revision _PEDData: DC.L printerName DC.L _Init DC.L _Expunge DC.L _Open DC.L _Close DC.B PPC_BWGFX ; Printer Class black & white graphic DC.B PCC_BW ; Color Class black & white DC.B 80 ; Max Columns DC.B 1 ; Number of Character Sets DC.W 7 ; Number of rows DC.L 576 ; Maximum of X dots DC.L 0 ; Maximum of Y dots = infinite DC.W 72 ; X Dots per inch DC.W 72 ; Y Dots per inch DC.L _CommandTable ; as defined in data.c DC.L _DoSpecial ; as defined in dospecial.c DC.L _Render ; as defined in render.c DC.L 10 ; Timeout printerName: STRING <'Okidata_ML92'> END
lbg@gitpyr.UUCP (03/12/86)
Is it possible to get the screen dump routine out of here for use with a printer other than the Okidata? The file is too big to go through at 1200 baud and there is no good search field to help you get to the start of each embeded file! Thanks. Lee
perry@leopard.UUCP (Perry S. Kivolowitz) (03/14/86)
> Is it possible to get the screen dump routine out of here for use with > a printer other than the Okidata? The file is too big to go through at Cheer Up! The 3rd issue of amazing computing will contain a rather nice asynchronous screen image printer (SCRIMPER) for any printer capable of printing raw dot matrices. The program (runable from WB or CLI) will also be available soon on a future Fish Disk. Perry