home *** CD-ROM | disk | FTP | other *** search
- #include <exec/types.h>
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <exec/memory.h>
- #include <devices/printer.h>
- #include <devices/prtbase.h>
-
- extern struct PrinterData *PD;
- extern struct PrinterExtendedData *PED;
-
- #define PWrite (*(PD->pd_PWrite)) /* write data to device */
- #define PReady (*(PD->pd_PBothReady)) /* wait for both buffers ready */
-
- #define LEAD 4 /* bytes to start each complete cycle */
- #define EXTRA 9 /* bytes to prefix each pass of the head */
- #define TAIL 2 /* bytes to end each complete cycle */
-
- void *AllocMem();
-
- /* these two tables wouldn't normally be bothered with but in light of
- * the number of times that these operations need to be performed
- * for each pass of the print head I thought they'd be worthwhile
- */
-
- /*
- * this table simulates the operation (1<<(5-(y%6)))
- * for values of y between 0 and 23 (the number of pixels in a printer pass)
- *
- */
-
- UBYTE bit_table[] = {
- 32,16,8,4,2,1,
- 32,16,8,4,2,1,
- 32,16,8,4,2,1,
- 32,16,8,4,2,1
- };
-
- /* this table simulates y/6 for values of y between 0 and 23 */
- /* saves a long division opeation */
- UBYTE div_table[] = {
- 0,0,0,0,0,0,
- 1,1,1,1,1,1,
- 2,2,2,2,2,2,
- 3,3,3,3,3,3
- };
-
- UBYTE *GfxBuffer;
-
- ULONG Render(ct,x,y,status)
- register UBYTE ct;
- register UWORD x,y;
- register UBYTE status;
- {
- static ULONG ROWSIZE;
- static ULONG COLOURSIZE;
- static ULONG BUFSIZE;
- static ULONG colours[4];
- static ULONG centre;
- static ULONG bufptr;
- static UBYTE *ptr;
- static ULONG psize;
- int i,filler;
- int err;
-
- /* Aztec doesn't preserve a6, we need this in a printer driver */
- #asm
- move.l a6,-(sp)
- #endasm
- err = 0;
-
- switch (status) {
-
- case 0: /* alloc memory for printer buffer */
-
- filler = (centre) ? ((PED->ped_MaxXDots -x ) / 2 ) : 0;
- ROWSIZE = ((x+filler)<<2) + EXTRA;
- COLOURSIZE = ROWSIZE<<2;
- BUFSIZE = COLOURSIZE+LEAD+TAIL+1; /* plus 1 for NULL */
-
- colours[0] = LEAD + EXTRA + filler + ROWSIZE*0;
- colours[1] = LEAD + EXTRA + filler + ROWSIZE*1;
- colours[2] = LEAD + EXTRA + filler + ROWSIZE*2;
- colours[3] = LEAD + EXTRA + filler + ROWSIZE*3;
- psize = x+filler;
-
- dbprintf("Size Data:\n");
- dbprintf("\tfiller: %d\n",filler);
- dbprintf("\tROWSIZE: %d\n",ROWSIZE);
- dbprintf("\tCOLOURSIZE: %d\n",COLOURSIZE);
- dbprintf("\tBUFSIZE: %d\n",BUFSIZE);
- dbprintf("\tcolours: %d %d %d %d\n",
- colours[0],colours[1],colours[2],colours[3]);
-
- GfxBuffer = AllocMem(BUFSIZE*2,MEMF_PUBLIC);
-
- if (err = (GfxBuffer==0)) break;
- if (err = PWrite("\x1b\x1a\x49",3)) break;
- if (err = PWait(1,0)) break;
-
- /* set to first buffer */
- bufptr = 0;
- break;
-
- case 1: /* render pixel */
- y %= 24; /* blecch, I wanted to avoid this calculation */
- i = bufptr + (x<<2) + div_table[y] + colours[3-ct];
- GfxBuffer[i] |= bit_table[y];
- break;
-
- case 2: /* write a buffer */
- dbprintf("Writing a buffer\n");
-
- /* BUFSIZE-1 is so that we don't send the trailing null */
- if (err=PWrite(&GfxBuffer[bufptr],BUFSIZE-1)) break;
- bufptr = BUFSIZE-bufptr;
- break;
-
- case 3: /* initialize the current buffer */
- dbprintf("Performing initialization\n");
-
- ptr = &GfxBuffer[bufptr];
-
- for (i=BUFSIZE;i--;) *ptr++ = 0; /* clear buffer */
-
- ptr = &GfxBuffer[bufptr];
- sprintf(ptr,"\x1bL07");
- sprintf(ptr+LEAD ,"\r\x1bc\x1b;%04d",psize); /* c */
- sprintf(ptr+LEAD+ROWSIZE ,"\r\x1bm\x1b;%04d",psize); /* m */
- sprintf(ptr+LEAD+ROWSIZE*2,"\r\x1by\x1b;%04d",psize); /* y */
- sprintf(ptr+LEAD+ROWSIZE*3,"\r\x1bb\x1b;%04d",psize); /* b */
- sprintf(ptr+LEAD+ROWSIZE*4,"\r\n"); /* crlf + NULL */
-
- break;
-
- case 4: /* cleanup -- release memory */
- dbprintf("Print finished -- cleanup\n");
- dbprintf("waiting for printer\n");
-
- err = PReady();
-
- dbprintf("Freeing memory\n");
-
- FreeMem(GfxBuffer,BUFSIZE*2);
-
- dbprintf("Returning\n");
-
- break;
-
- case 5: /* handle any special commands */
- centre = x & SPECIAL_CENTER;
- dbprintf("special: %d %d %d %d\n",ct,x,y,status);
-
- break;
-
- default:
- break;
- }
- #asm
- move.l (sp)+,a6
- #endasm
- return(err);
- }
-