		COMMENT %

	GRAPHIC WORKSHOP DOT MATRIX PRINTER DRIVER
	COPYRIGHT (C) 1990 ALCHEMY MINDWORKS INC.
	VERSION 1.0

		%

PAGEWIDE	EQU	612		;PAGE WIDTH IN PIXELS
PAGEDEEP	EQU	756		;PAGE DEPTH IN PIXELS
LINEDEEP	EQU	8		;NUMBER OF BITS (PINS) IN A LINE
COLOURS		EQU	1		;ONLY ONE COLOUR SUPPORTED AS YET

VERSION		EQU	1		;VERSION NUMBER
SUBVERSION	EQU	0		;SUBVERSION NUMBER

_AOFF		EQU	6		;STACK OFFSET

CODE		SEGMENT PARA PUBLIC 'CODE'
		ASSUME	CS:CODE

		ORG	0000H		;ORIGIN FOR LOADABLE DRIVER

		DB	'ALCHPRDR'	;SIGNATURE - DON'T CHANGE THIS

;THE FOLLOWING ARE THE POINTERS TO THE CALLABLE ROUTINES AND THE COMMON
;DATA. THE SEGMENTS ARE FILLED IN BY GRAPHIC WORKSHOP. DON'T CHANGE ANYTHING.
DISPATCH	PROC	FAR
		DW      INIT_PRINTER	;FAR POINTER TO PRINTER INITIALIZATION
		DW      ?
		DW	PRINT_LINE	;FAR POINTER TO LINE PRINT
		DW	?
		DW	DEINIT_PRINTER	;FAR POINTER TO PRINTER DEINIT
		DW	?
		DW	PRINT_TEXT	;FAR POINTER TO TEXT PRINT
		DW	?
		DW	0,0		;NULL ONE
		DW	0,0		;NULL TWO
		DW	0,0		;NULL THREE
		DW	0,0		;NULL FOUR

V_PAGEWIDE	DW	PAGEWIDE
V_PAGEDEEP	DW	PAGEDEEP
V_LINEDEEP	DW	LINEDEEP
V_COLOURS	DW	COLOURS

;THESE VERSION NUMBERS REFLECT THE DRIVER TEMPLATE VERSION AND THE
;VERSION OF THE DRIVER ITSELF. YOU CAN CHANGE THE SUBVERSION VALUE
;TO REFLECT CHANGES IN YOUR DRIVER. THE VERSION VALUE MUST REMAIN
;UNCHANGED OR GRAPHIC WORKSHOP MAY REJECT YOUR DRIVER.
		DW	VERSION
		DW	SUBVERSION

;THIS SHOULD BE THE PRINTER NAME AS IT WILL APPEAR IN THE GWS MENU.
;THE FIRST BYTE MUST BE 01H AND THE NAME MUST BE EXACTLY 19 BYTES LONG
;PLUS ONE ZERO BYTE AT THE END.

		DB      01H,'Epson FX-80        ',0
DISPATCH        ENDP

;THIS PROCEDURE SHOULD INITIALIZE THE PRINTER. IT SHOULD ALSO STORE THE
;FIRST THREE INTS ON THE STACK FOR FUTURE USE. THESE ARE IMAGE_WIDTH,
;IMAGE_DEPTH AND IMAGE_BYTES RESPECTIVELY. ALSO ON THE STACK ARE A POINTER
;TO THE GWS CONFIGURATION STRUCT AND A POINTER TO THE CURRENT FILE NAME
INIT_PRINTER	PROC	NEAR
		PUSH	BP
		MOV	BP,SP

		MOV	AX,[BP + _AOFF + 0]
		MOV	CS:[IMAGE_WIDTH],AX

		MOV	AX,[BP + _AOFF + 2]
		MOV	CS:[IMAGE_DEPTH],AX

		MOV	AX,[BP + _AOFF + 4]
		MOV	CS:[IMAGE_BYTES],AX

		MOV	DX,OFFSET INIT_SEQ
		CALL	PRINT_STRING

		POP	BP
		RETF
INIT_PRINTER	ENDP

;THIS PROCEDURE SHOULD PRINT ONE LINE. A POINTER TO THE LINE IS
;ON THE STACK.
PRINT_LINE	PROC	NEAR
		PUSH	BP
		MOV	BP,SP
		PUSH	DS

		MOV	CX,CS:[IMAGE_WIDTH]
		CMP	CX,0
		JE	PRINT_L3
		CMP	CX,CS:[V_PAGEWIDE]
		JL	PRINT_L1
		MOV	CX,CS:[V_PAGEWIDE]

PRINT_L1:	MOV	CS:[START_LO],CL
		MOV	CS:[START_HI],CH
		MOV	DX,OFFSET START_SEQ
		CALL	PRINT_STRING

		MOV	SI,[BP + _AOFF + 0]
		MOV	DS,[BP + _AOFF + 2]

		MOV	DX,0
PRINT_L2:	PUSH	CX
		CALL	GET_BYTE
		CALL	PRINT_BYTE
		INC	DX
		POP	CX
		LOOP	PRINT_L2

		MOV	DX,OFFSET END_SEQ
		CALL	PRINT_STRING

PRINT_L3:	POP	DS
		POP	BP
		RETF
PRINT_LINE	ENDP

;THIS SHOULD DO ANYTHING NECESSARY TO FINISH THE PICTURE. IT SHOULD NOT
;ISSUE A FORM FEED, THOUGH.
DEINIT_PRINTER	PROC	NEAR
		PUSH	BP
		MOV	BP,SP
		PUSH	DS

		MOV	DX,OFFSET DEINIT_SEQ
		CALL	PRINT_STRING
		POP	DS
		POP	BP
		RETF
DEINIT_PRINTER	ENDP

;THIS WILL PRINT A LINE OF TEXT TO THE PRINTER. THE STRING IS ON THE
;STACK FOLLOWED BY THE LENGTH OF THE STRING
PRINT_TEXT	PROC	NEAR
		PUSH	BP
		MOV	BP,SP
		PUSH	DS

		MOV	SI,[BP + _AOFF + 0]
		MOV	DS,[BP + _AOFF + 2]
		MOV	CX,[BP + _AOFF + 4]
		CMP	CX,0
		JE	PRINT_T2

		CLD
PRINT_T1:	LODSB
		CALL	PRINT_BYTE
		LOOP    PRINT_T1

PRINT_T2:	POP	DS
		POP	BP
		RETF
PRINT_TEXT	ENDP

;GET ONE BYTE FROM THE LINE FIELD
GET_BYTE	PROC	NEAR
		PUSH	BX
		PUSH	CX
		PUSH	DX
		PUSH	SI

		MOV	BX,DX
		SHR	BX,1
		SHR	BX,1
		SHR	BX,1

		MOV	AH,80H
		MOV	CL,DL
		AND	CL,0007H
		SHR	AH,CL

		MOV	AL,0
		MOV	CX,CS:[V_LINEDEEP]

		MOV	DH,80H
GETBYTE1:	TEST	DS:[SI + BX],AH
		JNZ	GETBYTE2
		OR	AL,DH
GETBYTE2:	ADD     SI,CS:[IMAGE_BYTES]
		SHR	DH,1
		LOOP    GETBYTE1

		POP	SI
		POP	DX
		POP	CX
		POP	BX
		RET
GET_BYTE	ENDP

;PRINT A PASCAL STYLE STRING IN CS:DX
PRINT_STRING	PROC	NEAR
		PUSH	CX
		PUSH	BX
		MOV	BX,DX
		MOV	CX,0
		MOV	CL,CS:[BX]
PRINT_S1:	INC	BX
		MOV	AL,CS:[BX]
		CALL	PRINT_BYTE
		LOOP	PRINT_S1
		POP	BX
		POP	CX
		RET
PRINT_STRING	ENDP

;PRINT ONE BYTE IN AL
PRINT_BYTE	PROC	NEAR
		PUSH	AX
		PUSH	BX
		PUSH	CX
		PUSH	DX
		PUSH	SI
		PUSH	DS
		PUSH	AX

PRINT_B1:	MOV	AH,2
		MOV	DX,0
		INT	17H
		TEST	AH,80H
		JZ	PRINT_B1

		POP	AX

		MOV	AH,0
		MOV	DX,0
		INT	17H

		POP	DS
		POP	SI
		POP	DX
		POP	CX
		POP	BX
		POP	AX
		RET
PRINT_BYTE	ENDP

IMAGE_WIDTH	DW	0
IMAGE_DEPTH	DW	0
IMAGE_BYTES	DW	0

;
;	NOTE - ALL STRINGS START WITH A LENGTH BYTE
;

;THIS IS THE STRING SENT TO THE PRINTER AT THE START OF A GRAPHIC LINE
START_SEQ	DB      5,1BH,'*',06H
START_LO	DB	0
START_HI	DB	0

;THIS IS THE STRING SENT TO THE PRINTER AT THE END OF A GRAPHIC LINE
END_SEQ		DB	4,0DH,1BH,'J',18H

;THIS IS THE STRING SENT TO THE PRINTER TO INITIALIZE THE BEAST
INIT_SEQ	DB      2,1BH,'@'

;THIS IS THE STRING SENT TO THE PRINTER TO DIINITIALIZE THE BEAST
DEINIT_SEQ	DB      4,0DH,0AH,1BH,'@'

CODE		ENDS
		END

