;
**********  HYTERM PROCESSOR *****************
;
;	COPYRIGHT 1979 TSA SOFTWARE
;
;  SPECIAL CODE FOR HYTERM (DIABLO 1610/1620)
;
;	RLR 1977 REV 00.00
;	EPG 6/80 REV 00.05	FULL STATUS ON LOUTD ALSO
;	RLR 10/16/80 REV 01.00  SEPERATE MODULE
;	RLR 10/27/80 REV 01.01  PROTECT ESC SEQ'S PROPERLY
;
	NAM	HYTRMA
	ENT	HYINIT,HYRDY,HYOUT
;
	EXT	HYCINIT		; SPECIFIC HY USED
	EXT	HYCSTAT,HYCIN
	EXT	HYCRDY,HYCOUT
;
	EXT	PROCHR,DELAY
;
ESC	EQU	27
ETX	EQU	3
ACK	EQU	6
BS	EQU	8
RS	EQU	30
US	EQU	31
CR	EQU	13
LF	EQU	10
SPC	EQU	20H
DLYF	EQU	3500
;
; AT START - INIT DEVICE
;
HYINIT:	CALL	EXINIT	; CLEAR LOCAL FLAGS
	JMP	HYCINIT	; AND START DEVICE
;
;
;
	EJECT
;
; ESC PROCESSOR
;
AX	MAC	; ACTION [LETTER,ADDRESS]
[DB	'&1'
	DW	&2]
S	MAC	; SET [LETTER,ADDRESS]
[DB	80H+'&1'
	DW	&2]
;
ESCTAB:	DW	OTCHR
	#AX	[A,HYINIT]
	#AX	[B,DOTHIN]
	#AX	[C,REVLF]
	#AX	[M,DOWID]
	#AX	[N,DOHGHT]
	#S	[O,THINWD]
	#AX	[F,HALFSP]
	#AX	[R,RIBBON]
	#S	[P,BOLDFG]
	DB	-1
	EJECT
;
;
; SPECIAL FUNCTIONS
;
DOTHIN:	LDA	THINWD
	CALL	SETWID	; SET TO THIN HORZ MOTION INDEX
	MVI	A,SPC
	CALL	LOUTX	; DO A SPACE
	RET		;01.01  OTCHR WILL RESET WIDTH
;
DOWID:	MOV	A,L
	ADD	A	; CONVERT TO 1/120 THS
	STA	NORMWD
	JMP	SETWID	; SET WIDTH
;
DOHGHT:	MOV	A,L
	STA	NORMHT
	MVI	B,RS	; SET CHAR HEIGHT
	JMP	SETPRM
;
REVLF:	MOV	A,L	; REVERSE LINE FEEDS
	MVI	B,LF
;
REVLF1:	CALL	ESCODE
	DCR	A
	JNZ	REVLF1
	RET
;
; SET WIDTH (1/120THS)
;
SETWID:
	MVI	B,US
	STA	CURRWD	;01.01 SAVE CURR WIDTH
;
; SEND PARAM SET, PROTECTED
;
SETPRM:	PUSH AF		;01.01
	CALL	DOESC	;01.01 SET PARM
	POP	AF	;01.01
	INR	A
	CALL	LOUTX	;01.01 VALUE
	PUSH	AF	;01.01
	XRA	A	;01.01
	STA	PROTESC	;01.01
	POP	AF	;01.01
	RET		;01.01
	EJECT
;
; HALF SPACING (OFFSET BY 127)  CODE =F
;
HALFSP:	MOV	A,L
	SBI	127
	RZ
	MVI	B,'D'	; DOWN (MINUS)
	JGE	HALF1
;
	MVI	B,'U'	; UP (PLUS)
	CMA
	INR	A
;
HALF1:	CALL	ESCODE
	DCR	A
	JNZ	HALF1
;
	RET
;
; -R- RIBBON COLOR (0-BLACK,<>0-RED)
;
RIBBON:	MOV	A,L
	ORA	A
	MVI	B,'B'	; BLACK - CODE=B
	JZ	RIBN1
	DCR	B	; RED - CODE=A
RIBN1:	JMP	ESCODE
	EJECT
;
; SEND ESC CODE SEQUENCE (A=SAVED, B=CMD)
;
ESCODE:	PUSH	AF	;01.01
	CALL	DOESC	;01.01 SET ESC PROTECTED
	XRA	A	;01.01
	STA	PROTESC	;01.01 TURN PROTECT OFF
	POP	AF	;01.01
	RET		;01.01
;
;   ACTUAL SENDING OF ESC
;	STARTS PROTECT STATE (CALLER MUST TURN OFF)
;
DOESC:
	PUSH	B
; PROTECT 4 CHARS SO NEVER SEND ETX WHILE DOING ESC
	LDA	CHCT	; IF CHCT > FENCE
	CPI	78-4
	CGE	LACK	; THEN FORCE ETX SENDING
;
	MVI	A,-1	;01.01 START PROTECT
	STA	PROTESC	;01.01
     	MVI	A,ESC
	CALL	LOUTX
	POP	AF	; B -> A (HAS CMD)
	PUSH	AF
	CALL	LOUTX
	POP	B	;01.01
	RET		;01.01
;
;  SEND ETX AND SET STATE TO ACK PENDING
;
LACK:	LDA	EXCT
	ORA	A
	JZ      LACK3
	PUSH	H
     	LXI	H,DLYF
	SHLD	DEL5S
	POP	H
	XRA	A
	STA	LACKSW	;MARK HANDSHAKE NOT READY
	RET
;
LACK3:	XRA	A	;01.01
	STA	PROTESC	;01.01 FORCE UNPROTECT
	CMA		;01.01
	STA	LACKSW	;MARK HANDSHAKE READY
	MVI	A,ETX
	CALL	HYCOUT	;SEND ^C
	MVI	A,1
	STA	CHCT
	STA	EXCT
	RET
	EJECT
;
; CHECK RDY STATE FOR DATA READY AND NO ACK PENDING
;
HYRDY:
LRDY:	LDA	PROTESC	;01.01 PROTECT ESC SEQ
	ORA	A	;01.01 FROM ETX RE-SEND
	JNZ	HYCRDY	;01.01 W/ SENDING ESC
;
	CALL	HYCSTAT	; IF INPUT CHAR
	ORA	A
	JZ	LRDY2
;
	CALL	HYCIN	; AND (CHAR==ACK)
	CPI	ACK
	JNZ	LRDY2
;			THEN CLEAR ACK PENDING STATE
LRDY5:	CALL	LACK3
	JMP	HYCRDY	;NOW CHECK PORT STATUS
;
;
LRDY2:	LDA	LACKSW
	ORA	A
	JNZ	HYCRDY	;HANDSHAKE READY, CHECK PORT
;
;ELSE SERVICE HANDSHAKE AND RET TO OS W/ PRINTER STATUS NOT READY
;
LACK2:	MVI	A,1
	CALL	DELAY	;1 MSEC DELAY
	PUSH	H
	LHLD	DEL5S
	DCX	H
	SHLD	DEL5S
	MOV	A,L
	ORA	H
	POP	H
	JZ	LRDY5	;HANDSHAKE READY (4 SEC TIMEOUT)
	XRA	A	;PRINTER NOT READY
	RET
;
; CLEAR ACK PENDING STATE
;
EXINIT:	XRA	A
	STA	EXCT	; 0== ACK RCVD
	STA	PROTESC	;01.01 0== PROT ESC FLAG
	INR	A
	STA	CHCT	; 1== CHAR CNTER INIT
	CMA
	STA	LACKSW	; -1== HANDSHAKE RDY
	RET
	EJECT
;
; LIST DEVICE OUTPUT
;
HYOUT:
LOUT:	LXI	H,ESCTAB
	CALL	PROCHR
	RET
;
LOUTX:	PUSH	PSW
;
LOUTY:	CALL	LRDY
	ORA	A
	JZ	LOUTY	;WAIT FOR FULL PRINTER STATUS
;
	POP	PSW	;GET CHAR
	CALL	HYCOUT	;OUTPUT CHAR
	PUSH	AF
	PUSH	H
	LXI	H,CHCT
	INR	M
	MOV	A,M
	CPI	78
	CGE	LACK	;HANDSHAKE SERVICE
	POP	H
	POP	AF
	RET
;
;
; OUTPUT A NORMAL CHAR, DO BOLD
;
OTCHR:
	PUSH	AF	;01.01
;01.01 ONLY TRY BOLD ON NORMAL CHARS
     .IF		;01.01
	CPI	SPC+1	;01.01	IF SPC OR SPECIAL
	JLT	.THEN	;01.01
	LDA	BOLDFG	;01.01
	DCR	A	;01.01
	JZ	OTCHR2	;01.01 OR NOT 1-OFFSET BOLD
;01.01 RESET TO NORMAL WIDTH
     .THEN
	LXI	H,CURRWD ;01.01 IF CURR CHAR WIDTH
	LDA	NORMWD	;01.01 IS NOT NORMAL
	CMP	M	;01.01
	CNE	SETWID	;01.01 THEN RESET IT
     .ENDIF
;
	LDA	BOLDFG	;01.01
	ORA	A	;01.01
	JZ	OTCHR1	;01.01 0-NORMAL
;
; OTHERWISE: OVERSTRIKE BOLD
;
	POP	AF
	CPI	SPC+1	;01.01 NO BOLD ON SPECIALS
	JLT	LOUTX	;01.01
;
	PUSH	AF
	CALL	LOUTX
	MVI	A,BS	; BACKUP
	CALL	LOUTX
; FINAL CHAR
OTCHR1:	POP	AF
	JMP	LOUTX
;
; OFFSET BOLD
;
OTCHR2:	MVI	A,1	; WIDTH = 1/120
	CALL	SETWID
	POP	AF		; SEND CHAR
	PUSH	AF
	CALL	LOUTX
;
	LDA	NORMWD
	SUI	1	; WIDTH = (NORM - 1)
	CALL	SETWID
	POP	AF
	CALL	LOUTX		; TWICE
	RET		;01.01 OTCHR RESETS TO NORMAL
;
;01.01 CHECK FOR NORMAL WIDTH
;
RSNORM:	LXI	H,CURRWD ;01.01 IF CURR CHAR WIDTH
	LDA	NORMWD	;01.01 IS NOT NORMAL
	CMP	M	;01.01
	CNE	SETWID	;01.01 THEN RESET IT
	RET		;01.01
;
CHCT:	DB	0	; CHARACTER COUNT
EXCT:	DB	0	; ETX WAIT FLAG
DEL5S:	DW	0
LACKSW:	DB	-1	;HANDSHAKE READY
PROTESC:DB	0	;01.01 PROTECT ESC SEQ FLAG
;
THINWD:	DW	6	; THIN SPACE WIDTH
BOLDFG:	DW	0	; BOLD FLAG (0-NORM, 1-OFF, 2-OVER)
CURRWD:	DB	12	;01.01 CURRENTLY SET WIDTH
NORMWD:	DB	12
NORMHT:	DB	6
;
;
*********** END OF HYTERM  **************
;
