[comp.sources.amiga] v02i013: Tektronix 4695/4696 printer driver

phils@tekigm2.TEK.COM (Philip E Staub) (08/09/87)

By popular demand, and after receiving a note from Andy Finkel stating it
would be ok to do so, I'm posting the following sources for a Tektronix
4695/4696 printer driver I developed a while back. It was derived from the
sources in the RKM, and all files which have copyright notices in the RKM
have them in this source. All of my changes are freely redistributable in
any way you like. 

This source compiles/assembles with Manx 3.30c and later. You may need to
tweak the makefile to accommodate the path to where you keep things, etc.,
but otherwise, there shouldn't be any problems rebuilding it.


#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:    Shell Archiver
#	Run the following text with /bin/sh to create:
#	makefile
#	data.c
#	dospecial.c
#	include.c
#	render.c
#	macros.i
#	init.asm
#	printertag.asm
#	wait.asm
# This archive created: Wed Jul 22 10:14:35 1987
cat << \SHAR_EOF > makefile
OBJS = 	printertag.o init.o wait.o data.o dospecial.o render.o

AFLAGS = -D -I//include
CFLAGS = +D +Q +Iinclude.pre

Tektronix_4695:	$(OBJS)
	copy :lib/cl.lib ram:
	ln -o Tektronix_4695 $(OBJS) -lcl

inc:
	cc -a +D +Q +Hinclude.pre include.c
SHAR_EOF
cat << \SHAR_EOF > data.c
/* Tektronix 4695 command table */

/****** printer.device/printers/Tektronix_4695_functions ********************
 *
 *	Name
 *	Tektronix 4695 functions implemented:
 *
 *		aIND, aNEL,
 *		aSLPP,
 *		aTBC0, aTBC3, aTBCALL, aTBSALL
 *
 *		special functions implemented:
 *		aRIN, aSLRM, aSFC, aSBC
 *
 **************************************************************************/

char *CommandTable[] = {
	"\377",		 	/* reset 	RIS	*/
	"\377",			/* initialize 	RIN	*/
	"\012",			/* index	IND	*/
	"\015\012",		/* new line	NEL	*/
	"\377",			/* rev index	RI	*/
	"\377",			/* norm ch set  SGR0	*/
	"\377",			/* italics on	SGR3	*/
	"\377",			/* italics off	SGR23	*/
	"\022",			/* underline on	SGR4	*/
	"\021",			/* underlin off	SGR24	*/
	"\377",			/* bold on	SGR1	*/
	"\377",			/* bold off	SGR22	*/
	"\377",			/* set fore col	SFC	*/
	"\377",			/* set back col	SBC	*/
	"\377",			/* norm space	SHORP0	*/
	"\377",			/* elite on	SHORP2	*/
	"\377",			/* elite off	SHORP1	*/
	"\377",			/*  fine on	SHORP4	*/
	"\377",			/*  fine off	SHORP3	*/
	"\377",			/* enlarged on SHORP6	*/
	"\377",			/* enlarged off SHORP5	*/
	"\377",			/* shadow print on DEN6	*/
	"\377",			/* shadow print off DEN5	*/
	"\377",			/* double strike on DEN4	*/
	"\377",			/* double strike off DEN3	*/
	"\377",			/* NLQ on DEN2	*/
	"\377",			/* NLQ off DEN1	*/
	"\377",			/* superscript on SUS2	*/
	"\377",			/* superscript off SUS1	*/
	"\377",			/* subscript on SUS4	*/
	"\377",			/* subscript off SUS3	*/
	"\377",			/* normalize the line SUS0	*/
	"\377",			/* partial line up PLU	*/
	"\377",			/* partial line down PLD	*/
	"\377",			/* US Character Set FNT0	*/
	"\377",			/* French Character set FNT1	*/
	"\377",			/* German Character setFNT2	*/
	"\377",			/* UK character set FNT3	*/
	"\377",			/* Danish I character set FNT4	*/
	"\377",			/* Swedish character set FNT5	*/
	"\377",			/* Italian char set	FNT6	*/
	"\377",			/* Spanish char set	FNT7	*/
	"\377",			/* Jap char set		FNT8	*/
	"\377",			/* Norw char set	FNT9	*/
	"\377",			/* Danish II char set	FNT10	*/
	"\377",			/* Prop on		PROP2	*/
	"\377",			/* Prop off		PROP1	*/
	"\377",			/* prop 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 (justify) JFY3	*/
	"\377",			/* word fill (auto center) JFY1	*/
	"\377",			/* 8LPI			VERP0	*/
	"\377",			/* 6LPI			VERP1	*/
	"\377",			/* set lines/page	SLPP	*/
	"\377",			/* perf skip		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",			/* set t&b margin	STBM	*/
	"\377",			/* set l&r margin	SLRM	*/	
	"\0334",		/* clear all margins	CAM	*/
	"\377",			/* horizontal tab set	HTS	*/
	"\377",			/* vertical tab set	VTS	*/
	"\0338",		/* clear horiz tab	TBC0	*/
	"\0332",		/* clear all horiz tabs	TBC3	*/
	"\377",			/* clear vert tab	TBC1	*/
	"\377",			/* clear all vert tabs	TBC4	*/
	"\0332",		/* clear all tabs	TBCALL	*/
				/* set default tabs	TBSALL	*/
	"033H10100808080808080808080810",	
	"\377"			/* extended commands	EXTEND	*/
};
SHAR_EOF
cat << \SHAR_EOF > dospecial.c
/* Tektronix 4695 special printer functions */

/******* printer.device/printers/Tektronix_4695_special_functions **********
 *
 *	Name
 *	Tektronix 4695 special functions implemented:
 *
 *	aRIN, aSLRM, aSFC
 *************************************************************************/

#include	"exec/types.h"
#include	"devices/printer.h"
#include	"devices/prtbase.h"

extern struct PrinterData *PD;

long
DoSpecial(command,outputBuffer,vline,currentVMI,crlfFlag,Parms)
register char outputBuffer[];
register UWORD *command;

register BYTE *vline;
register UBYTE *currentVMI;	/* used for color on this printer */
BYTE *crlfFlag;
UBYTE Parms[];
{
	register int x = 0;
	register int y = 0;
	static BYTE ISOcolorTable[10] = 
		{'1','3','5','4','7','2','6','0','1','1'};
	static unsigned char initMarg[] = "\033H001090";

	if(*command==aRIN) {
		*currentVMI = 0x70;	/* white background, black text */
		outputBuffer[x++] = '\015';
		outputBuffer[x++] = '\012';

		Parms[0] = (PD->pd_Preferences.PrintLeftMargin);
		Parms[1] = (PD->pd_Preferences.PrintRightMargin);
		*command = aSLRM;
	}

	if(*command==aSLRM) {
		*Parms += 4;
		if (Parms[0]<5) 
			Parms[0] = 5;

		Parms[1] += 5;
		if (Parms[1]>90) 
			Parms[1] = 90;

		initMarg[4] = (char)((Parms[0]/10)+'0');
		initMarg[5] = (char)((Parms[0]-(UBYTE)(Parms[0]/10)*10)+'0');
		initMarg[6] = (char)((Parms[1]/10)+'0');
		initMarg[7] = (char)((Parms[1]-(UBYTE)(Parms[1]/10)*10)+'0');
		while (y<10) 
			outputBuffer[x++] = initMarg[y++];
		return(x);
	}

	if(*command==aSFC) {
		if (Parms[0]==39) 
			Parms[0] = 30;	/* set defaults */
		if (Parms[0]==49) 
			Parms[0] = 47;

		if (Parms[0]<40) 
			*currentVMI = ((*currentVMI)&240)+(Parms[0]-30);
		else 
			*currentVMI = ((*currentVMI)&15)+((Parms[0]-40)*16);

		outputBuffer[x++] = '\033';
		outputBuffer[x++] = 'C';
		outputBuffer[x++] = ISOcolorTable[(*currentVMI)&15];
		outputBuffer[x++] = ISOcolorTable[(((*currentVMI)&240)/16)];
		return(x);
	}

	if(*command==aRIS) 
		PD->pd_PWaitEnabled = 253;

	return(0);
}
SHAR_EOF
cat << \SHAR_EOF > include.c
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include "devices/printer.h"
#include "devices/prtbase.h"
#include <functions.h>
SHAR_EOF
cat << \SHAR_EOF > render.c
/**********************************************************************/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include "devices/printer.h"
#include "devices/prtbase.h"
#include <functions.h>

extern struct PrinterData *PD;

/* for the Tektronix 4695 */
long Render(ct,x,y,status)
register ULONG ct;	/* was UBYTE for Lattice compiler */
register ULONG x,y;	/* was UWORD for Lattice compiler */
ULONG status;	/* was UBYTE for Lattice compiler */
{
	static UWORD ROWSIZE;
	static UWORD COLORSIZE;
	static UWORD BUFSIZE;
	static UWORD colors[4];
	static BYTE huns,tens,ones;
	static UWORD bufptr;
	register struct PrinterData *pp = PD;
	register UBYTE *ptr;
	UWORD i;
	BYTE err; 

	switch((UBYTE)status) {

		case 0:	/* alloc memory for printer buffer (uses dbl buf) */
			ROWSIZE = ((UWORD)x+7)/8;
			huns = ROWSIZE/100;
			tens = (ROWSIZE - huns*100)/10;
			ones = (ROWSIZE - huns*100 - tens*10);
			ROWSIZE += 6;
			COLORSIZE = ROWSIZE*4;
			BUFSIZE = COLORSIZE*4+2;
			colors[0] = 6;
			colors[1] = COLORSIZE*2+6;
			colors[2] = COLORSIZE+6;
			colors[3] = COLORSIZE*3+6;
			pp->pd_PrintBuf = (UBYTE *)
				AllocMem((long)BUFSIZE*2,(long)MEMF_PUBLIC);
			if(err = (pp->pd_PrintBuf==0)) 
				return(err);
			if(err = (*(pp->pd_PWrite))("\0334",2L)) 
				return(err);
			if(err = PWait(1L,0L)) 
				return(err);
			bufptr = 0;
			return(0);
			break;

		case 1:	/* put pixel in buffer (called a max of 16384 
			 * times per print cycle */
			i = bufptr+(UWORD)x/8+((UWORD)y&3)*ROWSIZE+colors[(UBYTE)ct];
			pp->pd_PrintBuf[i] |= (1 << (7-((UWORD)x&7)));
			return(0);
			break;

		case 2: /* dump buffer to printer */
			if (err = (*(pp->pd_PWrite))(&pp->pd_PrintBuf[bufptr],
								(long)BUFSIZE))
				return (err);
			bufptr = BUFSIZE - bufptr;
			return(0);
			break;

		case 3: /* clear and init buffer */
			ptr = &pp->pd_PrintBuf[bufptr];
			i = BUFSIZE;
			while(i--) 
				*ptr++ = 0;
			for (i = 0; i < 16; i++) {
				ptr = &pp->pd_PrintBuf[bufptr+i*ROWSIZE];
				*ptr++ = 27;
				*ptr++ = 'I';
				*ptr++ = i+'0';
				*ptr++ = huns+'0';
				*ptr++ = tens+'0';
				*ptr++ = ones+'0';
			}
			pp->pd_PrintBuf[bufptr+BUFSIZE-2] = 27;
			pp->pd_PrintBuf[bufptr+BUFSIZE-1] = 'A';
			return(0);
			break;

		case 4:	/* free the print buffer memory */
			err = (*(pp->pd_PBothReady))();
			FreeMem(pp->pd_PrintBuf,(long)BUFSIZE*2L);
			return(err);
			break;

		default:
			return(0);
	}
}
SHAR_EOF
cat << \SHAR_EOF > macros.i
;**************************************************************************
;	printer device macro definitions
;**************************************************************************

;	external definition macros

XREF_EXE	macro
	XREF		_LVO\1
		endm

XREF_DOS	macro
	XREF		_LVO\1
		endm

XREF_GFX	macro
	XREF		_LVO\1
		endm

XREF_ITU	macro
	XREF		_LVO\1
		endm

;	library dispatch macros

CALLEXE	macro
	CALLLIB	_LVO\1
		endm

LINKEXE	macro
	LINKLIB	_LVO\1,_SysBase
		endm

CALLDOS	macro
	LINKLIB	_LVO\1,_DOSBase
		endm

LINKGFX	macro
	LINKLIB	_LVO\1,_GfxBase
		endm

LINKITU	macro
	LINKLIB	_LVO\1,_IntuitionBase
		endm

SHAR_EOF
cat << \SHAR_EOF > init.asm
;
;	Excerpt from Amiga ROM Kernel Reference Manual: Libraries and 
;	Devices.  Used by permission, 1987, Phil Staub.
;
;**************************************************************************
;                                                                         *
;	Copyright 1985, Commodore-Amiga Inc. All rights reserved.         *
;	No part of this program may be reproduced, transmitted            *
;	transcribed, stored in retrieval system, or translated into       *
;	any language or computer language, in any form or by any means,   *
;	electronic, mechanical, magnetic, optical, chemical,              *
;	manual or ohterwise, without the prior written permission of      *
;	Commodore-Amiga Incorporated, 983 University Ave. Building #D,    *
;	Los Gatos, California, 95030                                      *
;                                                                         *
;**************************************************************************
	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	_DOSBase
	XDEF	_GfxBase
	XDEF	_IntuitionBase

;***********************************************
	section	printer,data
_PD		DC.L	0
_PED		DC.L	0
_SysBase	DC.L	0
_DOSBase	DC.L	0
_GfxBase	DC.L	0
_IntuitionBase	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

;	open the dos library
	lea	DLName(pc),a1
	moveq	#0,d0
	CALLEXE	OpenLibrary
	move.l	d0,_DOSBase
	beq.l	initDLErr

;	open the graphics library
	lea	GLName(pc),a1
	moveq	#0,d0
	CALLEXE	OpenLibrary
	move.l	d0,_GfxBase
	beq.l	initGLErr

;	open the intuition library
	lea	ILName(pc),a1
	moveq	#0,d0
	CALLEXE	OpenLibrary
	move.l	d0,_IntuitionBase
	beq.l	initILErr

	moveq	#0,d0

pdiRTS:
	move.l	(a7)+,a6
	rts

initPAErr:
	move.l	_IntuitionBase,a1
	LINKEXE	CloseLibrary

initILErr:
	move.l	_GfxBase,a1
	LINKEXE	CloseLibrary

initGLErr:
	move.l	_DOSBase,a1
	LINKEXE	CloseLibrary

initDLErr:
	moveq	#-1,d0
	bra.s	pdiRTS

ILName:
	dc.b	'intuition.library'
	dc.b	0
DLName:
	dc.b	'dos.library'
	dc.b	0
GLName:
	dc.b	'graphics.library'
	dc.b	0
	ds.w	0

;
_Expunge:
	move.l	_IntuitionBase,a1
	LINKEXE	CloseLibrary

	move.l	_GfxBase,a1
	LINKEXE	CloseLibrary

	move.l	_DOSBase,a1
	LINKEXE	CloseLibrary

_Open:
	moveq	#0,d0
	rts

_Close:
	moveq	#0,d0
	rts

	end
SHAR_EOF
cat << \SHAR_EOF > printertag.asm
;
;	Excerpt from Amiga ROM Kernel Reference Manual: Libraries and 
;	Devices.  Used by permission, 1987, Phil Staub.
;
;**************************************************************************
;                                                                         *
;	Copyright 1985, Commodore-Amiga Inc. All rights reserved.         *
;	No part of this program may be reproduced, transmitted            *
;	transcribed, stored in retrieval system, or translated into       *
;	any language or computer language, in any form or by any means,   *
;	electronic, mechanical, magnetic, optical, chemical,              *
;	manual or ohterwise, without the prior written permission of      *
;	Commodore-Amiga Incorporated, 983 University Ave. Building #D,    *
;	Los Gatos, California, 95030                                      *
;                                                                         *
;**************************************************************************
	section	printer

	include	"exec/types.i"
	include	"exec/nodes.i"
	include	"exec/strings.i"
	include	"devices/prtbase.i"

	xref	_Init
	xref	_Expunge
	xref	_Open
	xref	_Close
	xref	_CommandTable
	xref	_DoSpecial
	xref	_Render

	xdef	_PEDData
	xdef	.begin
	xdef	_main

VERSION	EQU	31
REVISION	EQU	23
.begin:
_main:
	moveq	#0,d0
	rts
	dc.w	VERSION
	dc.w	REVISION
_PEDData:
	dc.l	printerName
	dc.l	_Init
	dc.l	_Expunge
	dc.l	_Open
	dc.l	_Close
	dc.b	PPC_COLORGFX
	dc.b	PCC_YMCB
	dc.b	80
	dc.b	1
	dc.w	4
	dc.l	1024
	dc.l	0
	dc.w	120
	dc.w	120
	dc.l	_CommandTable
	dc.l	_DoSpecial
	dc.l	_Render
	dc.l	60
	dc.l	0

printerName:
	dc.b	"Tektronix 4695"
	dc.b	0
	end
SHAR_EOF
cat << \SHAR_EOF > wait.asm
	section printer
	include	'exec/types.i'
	include	'exec/ports.i'
	include	'exec/devices.i'
	include	'exec/io.i'
	include	'devices/timer.i'

XREF_EXE	MACRO
	XREF	_LVO\1
	ENDM
XREF_DOS	MACRO
	XREF	_LVO\1
	ENDM
XREF_GFX	MACRO
	XREF	_LVO\1
	ENDM
XREF_ITU	MACRO
	XREF	_LVO\1
	ENDM

CALLEXE	MACRO
	CALLLIB	_LVO\1
	ENDM

LINKEXE	MACRO
	LINKLIB	_LVO\1,_SysBase
	ENDM

LINKDOS	MACRO
	LINKLIB	_LVO\1,_DOSBase
	ENDM

LINKGFX	MACRO
	LINKLIB	_LVO\1,_GfxBase
	ENDM

LINKITU	MACRO
	LINKLIB	_LVO\1,_IntuitionBase
	ENDM

	INCLUDE	'devices/prtbase.i'
	XREF_EXE	Forbid
	XREF_EXE	Permit
	XREF_EXE	WaitIO
	XREF	_SysBase

	XREF	_PD

	XDEF	_PWait

_PWait:
	movem.l	a4/a6,-(a7)
	move.l	_PD,a4
	move.l	pd_PBothReady(a4),a0
	jsr	(a0)
	tst.l	d0
	bne.s	error

	lea	pd_TIOR(a4),a1
	move.w	#TR_ADDREQUEST,IO_COMMAND(a1)
	move.l	12(a7),IOTV_TIME+TV_SECS(a1)
	move.l	16(a7),IOTV_TIME+TV_MICRO(a1)
	clr.b	IO_FLAGS(a1)
	move.l	IO_DEVICE(a1),a6
	jsr	DEV_BEGINIO(a6)
	LINKEXE	Forbid
	lea	pd_TIOR(a4),a1
	LINKEXE	WaitIO
	LINKEXE	Permit
	moveq	#0,d0
	tst.l	d0
error:
	movem.l	(a7)+,a4/a6
	rts
	end
SHAR_EOF
#	End of shell archive
exit 0
-- 
-------------------------------------------------------------------------------
Phil Staub              tektronix!tekigm2!phils    (206) 253-5634
Tektronix, Inc., ISI Engineering
P.O.Box 3500, M/S C1-904, Vancouver, Washington  98668