;
;		AMATEUR RADIO LINK PROGRAM
;			HAMLINK4
;		(LATEST VERSION 06/03/81)
;
;	AN ADAPTATION OF L.E. HUGHES'S PROGRAM PLINK
;	BY RODERICK W. HART WA3MEZ.
;	CWID ROUTINE BORROWED FROM DALE HEATHERINGTON'S
;	PROGRAM 'PACKET.ASM'.
;
;HAMLINK IS A CP/M TRANSIENT COMMAND WHICH ALLOWS THE USER TO
;ESTABLISH A COMMUNICATION LINK WITH A REMOTE AMATEUR RADIO
;SYSTEM TRANSMITING ASCII.
;
;HAMLINK CURRENTLY SUPPORTS TWO WAY TRANSFER OF TEXT FILES
;BETWEEN THE CP/M DISK SYSTEM AND THE REMOTE STATION. THE
;FOLLOWING CONTROL CODES MAY BE INITIATED FROM THE CONSOLE
;KEYBOARD:
;
;       ****************************************************
;       *                                                  *
;       *                 COMMANDS:                        *
;       *  CONTROL X   EXIT HAMLINK TO CP/M WARM BOOT      *
;       *  CONSROL S   TRANSMIT ASCII FILE TO MODEM.       *
;       *              ASK FOR DRIVE AND FILENAME.TYPE.    *
;       *  CONTROL C   ABORT FILE SEND TO MODEM            *
;       *  CONTROL O   SAVE INCOMING ASCII IN RAM BUFFER   *
;       *              FOR LATER TRANSFER TO DISK.        *
;       *  CONTROL Q   WRITE RAM BUFFER TO DISK - ASK     *
;       *              FOR DRIVE AND FILENAME.TYPE.       *
;       *  DELETE      BACKSPACE WHEN IN COMMAND MODE     *
;       *              ASKING FOR FILENAME.               *
;       *  CONTROL U   ABORT CURRENT LINE WHEN IN COMMAND *
;       *              MODE ASKING FOR FILENAME.          *
;       *  ESCAPE      PRINT MENUE                        *
;       *  CONTROL E   TRAP RECEIVE ERRORS                *
;       *  CONTROL D   PRINT ERROR SUMMARY                *
;       *  CONTROL W   RESET ERROR COUNTERS               *
;       *  CONTROL A   DEACTIVATE RECEIVE ERROR TRAP      *
;       *  CONTROL Y   RECONFIGURE MODEM                  *
;	*  CONTROL T   TURN TRANSMITTER ON                *
;	*  CONTROL R   TURN TRANSMITTER OFF               *
;	*  CONTROL I   TRANSMIT CWID                      *
;       *  (NOTE: ALL OTHER CONTROL CODES ARE PASSED TO   *
;       *         MODEM OUTPUT. THE EQUATE ERCHAR CAN BE  *
;       *         USED TO PRINT ANY CHOSEN ASCII CHARAC-  *
;       *         TER UPON RECEIPT OF AN ERROR. THIS FEA- *
;       *         TURE CAN BE USED TO PROPERLY SET MODEM  *
;       *         TO MATCH THE TRANSMITTING STATION'S MODE*
;       *         I.E. STOP BITS, DATA BITS, AND PARITY)  *
;       ***************************************************
;
;BDOS ENTRY POINT AND FUNCTION CODES
;
BDOS	EQU	0005H
RSFC	EQU	10	;READ STRING
RESDSK	EQU	13	;RESET DISK SYSTEM
OFFC	EQU	15	;OPEN FILE
CFFC	EQU	16	;CLOSE FILE
SFFC	EQU	17	;SEARCH FIRST
SNFC	EQU	18	;SEARCH NEXT
DFFC	EQU	19	;DELETE FILE
RRFC	EQU	20	;READ RECORD
WRFC	EQU	21	;WRITE RECORD
MFFC	EQU	22	;MAKE FILE
SAFC	EQU	26	;SET ADDRESS
;
;DEFAULT FCB AND FIELD DEFINITIONS
;
FCB	EQU	5CH
FN	EQU	1	;FILE NAME FIELD (REL)
FT	EQU	9	;FILE TYPE FIELD (REL)
EX	EQU	12	;FILE EXTENT FIELD (REL)
NR	EQU	32	;NEXT RECORD FIELD (REL)
DBUF	EQU	80H	;DEFAULT DISK BUFFER ADDRESS
;
;ASCII CONTROL CHARACTERS
;
CR	EQU	0DH	;CARRIAGE RETURN
LF	EQU	0AH	;LINE FEED
DEL	EQU	7FH	;DELETE (RUBOUT)
ESC	EQU	1BH	;ESCAPE
BELL	EQU	07H	;BELL SIGNAL
TAB	EQU	09H	;HORIZONTAL TAB
VT	EQU	0BH	;VERT TAB (CLEAR SCREEN)
HOME	EQU	0EH	;HOME CURSOR
CPUSPD	EQU	2	;CPU CLOCK SPEED IN MHZ

;
;WARNING CHARACTER FOR LOW MEMORY
;
WRNSIG	EQU	BELL	;IF YOU HAVE ONE, PUT 'BELL' HERE
			;...ELSE PUT '*' HERE.

;
;STATION CONTROLLER I/O PORT ADDRESS (AMSAT STA. CONTROLLER)
;
CONTLR	EQU	00H	;STA. CONTROLLER BASE PORT

;
;STATION CONTROLLER CONTROL CODES
;
TON	EQU	01H	;TRANSMITTER ON
IDON	EQU	02H	;ID TONE ON

;
;MODEM I/O PORT ADDRESSES (MITS 2SIO BOARD)
;
MODS	EQU	12H	;MODEM STATUS PORT
MODD	EQU	13H	;MODEM DATA PORT
MODINIT	EQU	16H	;INITIALIZE FOR 300 BAUD
			;8 DATA BITS, 1 STOP BITS, NO PARITY
;
;MODEM STATUS PORT BIT DEFINITIONS (MIT 2SIO BOARD)
;
MTBE	EQU	02H	;MODEM TRANS. BUFFER READY FLAG
MRDA	EQU	01H	;MODEM RECEIVE DATA AVAIL. FLAG
FE	EQU	10H	;FRAME ERROR
OE	EQU	20H	;OVERRUN ERROR
PE	EQU	40H	;PARITY ERROR
ERCHAR	EQU	0ABH	;PLACE CHAR. YOU WISH PRINTED UPON
			;RECEIPT OF PARITY, OVERRUN, AND 
			;FRAMING ERRORS. 00H PASSES ALL CHAR.
			;WHILE ANYTHING ELSE WILL SUBTITUTE
			;ERCHAR FOR EACH BAD CHAR. RECEIVED.
;
;MODEM INITIALIZATION BYTES (300 BAUD)
;
I72E	EQU	02H	;7BITS,2STOP BITS,EVEN PARITY
I72O	EQU	06H	;7BITS,2STOP BITS,ODD PARITY
I71E	EQU	0AH	;7BITS,1STOP BIT,EVEN PARITY
I71O	EQU	0EH	;7BITS,1STOP BIT,ODD PARITY
I820	EQU	12H	;8BITS,2STOP BITS,NO PARITY
I810	EQU	16H	;8BITS,1STOP BIT,NO PARITY
I81E	EQU	1AH	;8BITS,1STOP BIT,EVEN PARITY
I81O	EQU	1EH	;8BITS,1STOP BIT,ODD PARITY
;
;MODEM INITIALIZATION BYTES (1200 BAUD)
;
X72E	EQU	01H	;7BITS,2STOP BITS,EVEN PARITY
X72O	EQU	05H	;7BITS,2STOP BITS,ODD PARITY
X71E	EQU	09H	;7BITS,1STOP BIT,EVEN PARITY
X71O	EQU	0DH	;7BITS,1STOP BIT,ODD PARITY
X820	EQU	11H	;8BITS,2STOP BITS,NO PARITY
X810	EQU	15H	;8BITS,1STOP BIT,NO PARITY
X81E	EQU	19H	;8BITS,1STOP BIT,EVEN PARITY
X81O	EQU	1DH	;8BITS,1STOP BIT,ODD PARITY
;
;CONDITIONAL ASSEMBLY SWITCHES
;
INIT$REQUIRED	EQU	1	;PUT 0 HERE IF NO INIT. REQ.
INIT$CONTLR	EQU	1	;PUT 0 HERE IF NO INIT. REQ.
;
;	**MAIN PROGRAM**
;
	ORG	0100H
;
LINK	LXI	SP,STACK+64
	LHLD	1
	LXI	D,3
	DAD	D
	SHLD	CITCAL+1
	DAD	D
	SHLD	RCCAL+1
	DAD	D
	SHLD	WCCAL+1
;
	IF	INIT$CONTLR
	MVI	A,98H
	OUT	CONTLR+3
	MVI	A,0
	OUT	CONTLR+1
	ENDIF
;
	IF	INIT$REQUIRED
	CALL	ORGMOD
	ENDIF
;
	IN	MODD
	IN	MODD
	XRA	A
	STA	INCH
	STA	OUTCH
	STA	FLAG
	STA	ERROR
	STA	ERRFLG
	STA	CR1
	MVI	A,ERCHAR
	STA	ERROR
	LXI	H,0
	SHLD	PERR
	SHLD	OERR
	SHLD	FERR
	LXI	H,TBUF
	SHLD	PTR
	LXI	H,0
	SHLD	SIZE
	LXI	H,LINKMS
	CALL	WCS
;
;	MAIN LOOP
;
LINK3	CALL	CITEST
	JZ	LINK4
	CALL	RCC
	CPI	20H
	CC	PCC
	JC	LINK4
	ORI	80H
	STA	INCH
LINK4	LDA	OUTCH
	ORA	A
	JP	LINK5
	ANI	7FH
	CALL	WCC
	XRA	A
	STA	OUTCH
LINK5	CALL	MITEST
	JZ	LINK6
	CALL	RMC2
	CALL	SAVE
	ORI	80H
	STA	OUTCH
LINK6	CALL	MOTEST
	JZ	LINK7
	LDA	INCH
	ORA	A
	JP	LINK7
	ANI	7FH
	CPI	CR
	CZ	WMCLF		;AUTO LF/CR SEQUENCE
	CALL	WMC
	CALL	WCC
	XRA	A
	STA	INCH
LINK7	JMP	LINK3
;
LINKMS	DB	VT,'Amateur Radio Link as of 06/03/81'
	DB	' by: Roderick W. Hart WA3MEZ'
	DB	CR,LF,'Link established [8 data bits, 1 stop'
	DB	' bit, no parity - 300 baud]'
	DB	CR,LF,'                 Special Debug Version'
	DB	CR,LF,LF,BELL,0
;
;	PCC - PROCESS CONTROL CHARACTER
;
PCC	CPI	'X'-40H
	JNZ	PCC1
	PUSH	H
	LXI	H,AYS
	CALL	WCS
	POP	H
	CALL	RCC
	CALL	WCC
	ANI	5FH
	CPI	'Y'
	JZ	TERM
	CALL	WCCR
	STC
	RET
;
PCC1	CPI	'S'-40H
	JNZ	PCC2
	CALL	STF
	STC
	RET
;
PCC2	CPI	'O'-40H
	JNZ	PCC3
	MVI	A,1
	STA	FLAG
	LXI	H,PCCMR
	CALL	WCS
	STC
	RET
;
PCC3	CPI	'Q'-40H
	JNZ	PCC5
	XRA	A
	STA	FLAG
	CALL	WTB
	STC
	RET
;
PCC4	STC
	CMC
	RET
;
PCC5	CPI	ESC
	JNZ	PCC6
	LXI	H,MENUE	;PRINT MENUE
	CALL	WCS
	STC
	RET
;
PCC6	CPI	'E'-40H
	JNZ	PCC7
	MVI	A,1
	STA	ERRFLG
	LXI	H,ERRMSG
	CALL	WCS
	STC
	RET
;
PCC7	CPI	'D'-40H
	JNZ	PCC8
	CALL	PCD0
	STC
	RET
;
PCC8	CPI	'W'-40H
	JNZ	PCC9
	CALL	RESET
	LXI	H,RESMSG
	CALL	WCS
	STC
	RET
;
PCC9	CPI	'A'-40H
	JNZ	PCC9A
	MVI	A,0
	STA	ERRFLG
	LXI	H,ERR1MSG
	CALL	WCS
	STC
	RET
;
PCC9A	CPI	'T'-40H
	JNZ	PCC9B
	CALL	RFON
	LXI	H,XMTONMSG
	CALL	WCS
	STC
	RET
;
PCC9B	CPI	'R'-40H
	JNZ	PCC9C
	CALL	RFOFF
	LXI	H,XMTOFFMSG
	CALL	WCS
	STC
	RET
;
PCC9C	CPI	'I'-40H
	JNZ	PCC10
	CALL	CWID
	STC
	RET
;
PCC10	CPI	'Y'-40H
	JNZ	PCC4
	PUSH	H
	LXI	H,SPEED
	CALL	WCS
	POP	H
	CALL	RCC
	CALL	WCC
	CPI	'1'
	JNZ	S1200
S300	PUSH	H
	LXI	H,CONFMSG
	CALL	WCS
	POP	H
	CALL	RCC
	CALL	WCC
	CPI	'1'
	JNZ	A1
	MVI	A,I72E
	STA	CR1
	JMP	CONFIG
A1	CPI	'2'
	JNZ	A2
	MVI	A,I72O
	STA	CR1
	JMP	CONFIG
A2	CPI	'3'
	JNZ	A3
	MVI	A,I71E
	STA	CR1
	JMP	CONFIG
A3	CPI	'4'
	JNZ	A4
	MVI	A,I71O
	STA	CR1
	JMP	CONFIG
A4	CPI	'5'
	JNZ	A5
	MVI	A,I820
	STA	CR1
	JMP	CONFIG
A5	CPI	'6'
	JNZ	A6
	MVI	A,I810
	STA	CR1
	JMP	CONFIG
A6	CPI	'7'
	JNZ	A7
	MVI	A,I81E
	STA	CR1
	JMP	CONFIG
A7	CPI	'8'
	JNZ	EN1
	MVI	A,I81O
	STA	CR1
	JMP	CONFIG
EN1	STC
	RET
;
S1200	CPI	'2'
	JNZ	EN1
	PUSH	H
	LXI	H,CONFMG1
	CALL	WCS
	POP	H
	CALL	RCC
	CALL	WCC
	CPI	'1'
	JNZ	B1
	MVI	A,X72E
	STA	CR1
	JMP	CONFIG
B1	CPI	'2'
	JNZ	B2
	MVI	A,X72O
	STA	CR1
	JMP	CONFIG
B2	CPI	'3'
	JNZ	B3
	MVI	A,X71E
	STA	CR1
	JMP	CONFIG
B3	CPI	'4'
	JNZ	B4
	MVI	A,X71O
	STA	CR1
	JMP	CONFIG
B4	CPI	'5'
	JNZ	B5
	MVI	A,X820
	STA	CR1
	JMP	CONFIG
B5	CPI	'6'
	JNZ	B6
	MVI	A,X810
	STA	CR1
	JMP	CONFIG
B6	CPI	'7'
	JNZ	B7
	MVI	A,X81E
	STA	CR1
	JMP	CONFIG
B7	CPI	'8'
	JNZ	EN1
	MVI	A,X81O
	STA	CR1
	JMP	CONFIG
;
;
SPEED	DB	HOME,CR,LF,'Which Speed Do You Wish [1=300 Baud, 2=1200 Baud] ?',0
AYS	DB	HOME,CR,LF,'Exit To CP/M - Are You Sure (Y or N) ?',0
PCCMR	DB	HOME,CR,LF,'Saving Incoming Text In Memory',CR,LF,0
MENUE	DB	VT
	DB	'              * * *  H a m l i n k 3  * * *'
	DB	CR,LF,'CONTROL-I        TRANSMIT CWID'
	DB	CR,LF,'CONTROL-T        TURN TRANSMITTER ON'
	DB	CR,LF,'CONTROL-R        TURN TRANSMITTER OFF'
	DB      CR,LF,'CONTROL-X        EXIT TO CP/M'
	DB	CR,LF,'CONTROL-S        TRANSMIT ASCII FILE'
	DB	CR,LF,'CONTROL-O        RECEIVE ASCII FILE'
	DB	CR,LF,'CONTROL-Q        WRITE RECEIVED FILE TO DISK'
	DB	CR,LF,'CONTROL-C        ABORT FILE TRANSMISSION'
	DB	CR,LF,'CONTROL-U        ABORT CURRENT LINE (COMMAND MODE)'
	DB	CR,LF,'CONTROL-A        DEACTIVATE ERROR TRAP'
	DB	CR,LF,'CONTROL-E        ACTIVATE ERROR TRAP'
	DB	CR,LF,'CONTROL-D        PRINT RECEIVE ERROR SUMMARY'
	DB	CR,LF,'CONTROL-W        RESET RECEIVE ERROR COUNTERS'
	DB	CR,LF,'CONTROL-Y        RECONFIGURE MODEM'
	DB	CR,LF,'DELETE           BACKSPACE (COMMAND MODE)'
	DB	CR,LF,'ESCAPE           PRINT MENUE'
	DB	CR,LF
	DB	0
;
;	STF - SEND TEXT FILE (TO MODEM)
;
STF	CALL	GFN
	JC	STF6
	CALL	OPEN
	CPI	255
	JZ	STF7
STF1	CALL	READ
	CPI	1
	JZ	STF5
	LXI	H,DBUF
	MVI	C,128
STF2	MOV	A,M
	INX	H
	CPI	'Z'-40H
	JZ	STF5
	CALL	WMC
	CALL	WCC
	CPI	CR
	JNZ	STF4
STF3	CALL	CITEST
	JZ	STF3A
	CALL	RCC
	CPI	'C'-40H
	JZ	STF8
STF3A	CALL	WCCR		;SEND LFCR TO CONSOLE
STF4	DCR	C
	JNZ	STF2
	JMP	STF1
;
STF5	LXI	H,STFSM
	CALL	WCS
	RET
;
STF6	LXI	H,STFS1
	CALL	WCS
	RET
;
STF7	LXI	H,STFS2
	CALL	WCS
	RET
;
STF8	LXI	H,STFSA
	CALL	WCS
	RET
;
STFSM	DB	'File Transmission Completed',CR,LF,0
STFS1	DB	'File Name Error',CR,LF,0
STFS2	DB	'File Not Found',CR,LF,0
STFSA	DB	CR,LF,'File Transmission Aborted',CR,LF,0
;
;	SAVE - SAVE CHAR IN TEXT BUFFER IF FLAG ON
;
;
;	ENRTY CONDITIONS
;		A - CHAR TO SAVE
;
SAVE	PUSH	PSW
	LDA	FLAG
	ORA	A
	JNZ	SAVE1
	POP	PSW
	RET
;
SAVE1	POP	PSW
	CPI	DEL
	RZ
	CPI	20H
	JNC	SAVE2
	CPI	CR
	JZ	SAVE2
	CPI	LF
	JZ	SAVE2
	CPI	TAB
	JZ	SAVE2
	RET
;
SAVE2	PUSH	H
	LHLD	SIZE
	INX	H
	SHLD	SIZE
	LHLD	PTR
	MOV	M,A
	INX	H
	SHLD	PTR
	PUSH	PSW
	LDA	7
	CMP	H
	JZ	SAVEAB
	SUI	4
	CMP	H
	MVI	A,WRNSIG
	CC	WCC
	POP	PSW
	POP	H
	RET
;
;	SAVEAB - RAN OUT OF ROOM, ISSUE MESSAGE AND FLOW
;		 THROUGH TO DISK SAVE ROUTINE
;
SAVEND	DB	BELL,CR,LF,'Aborting - No Room Left',0
;
SAVEAB	LXI	SP,STACK+64
	LXI	H,SAVEND
	CALL	WCS
	LXI	H,LINK
	PUSH	H
;
;	WTB - WRITE TEXT BUFFER TO DISK
;
WTB	LHLD	SIZE
	MOV	A,L
	ORA	H
	JZ	WTB5
	MVI	C,RESDSK
	CALL	BDOS
	CALL	GFN
	JC	WTB6
	CALL	DELT
	CALL	MAKE
	LHLD	SIZE
	XCHG
	LXI	H,DBUF
	PUSH	H
	LXI	H,TBUF
WTB1	MVI	C,128
WTB2	MOV	A,M
	INX	H
	XTHL
	MOV	M,A
	INX	H
	XTHL
	DCX	D
	MOV	A,D
	ORA	E
	JZ	WTB3
	DCR	C
	JNZ	WTB2
	CALL	WRITE
	XTHL
	LXI	H,DBUF
	XTHL
	JMP	WTB1
;
WTB3	POP	H
WTB4	MVI	M,'Z'-40H
	INX	H
	DCR	C
	JNZ	WTB4
	CALL	WRITE
	CALL	CLOSE
	LXI	H,TBUF
	SHLD	PTR
	LXI	H,0
	SHLD	SIZE
	LXI	H,WTBSM
	CALL	WCS
	RET
;
WTB5	LXI	H,WTBS1
	CALL	WCS
	RET
;
WTB6	LXI	H,WTBS2
	CALL	WCS
	RET
;
WTBSM	DB	CR,LF,'Buffer Transferred To Disk',CR,LF
	DB	'Memory Save Cancelled',CR,LF,0
WTBS1	DB	'Text Buffer Empty',CR,LF,0
WTBS2	DB	'File Name Error',CR,LF,0
;
;	WCS - WRITE CONSOLE STRING
;
;	ENTRY CONDITIONS
;		HL - POINTS TO STRING (TERM BY ZERO BYTE)
;
WCS	MOV	A,M
	INX	H
	ORA	A
	RZ
	CALL	WCC
	JMP	WCS
;
;	WCCR - WRITE CONSOLE CARRIAGE RETURN (AND LINE FEED)
;
WCCR	MVI	A,LF
	CALL	WCC
	MVI	A,CR
;
;	WCC - WRITE CONSOLE CHARACTER
;
;	ENTRY CONDITIONS:
;		A - CHARACTER TO WRITE
;
WCC	PUSH	PSW
	PUSH	B
	PUSH	D
	PUSH	H
	MOV	C,A
WCCAL	CALL	$-$
	POP	H
	POP	D
	POP	B
	POP	PSW
	RET
;
;	RCS - READ CONSOLE STRING (WITH ECHO)
;
;	EXIT CONDITIONS
;		B - NUMBER OF CHARACTERS READ (<255)
;		HL - POINTS TO LAST CHAR STORED (CR)
;
RCS	LXI	H,IBUF
	MVI	B,0
RCS1	CALL	RCC
	CPI	DEL
	JNZ	RCS2
	INR	B
	DCR	B
	JZ	RCS1
	DCX	H
	MOV	A,M
	CALL	WCC
	DCR	B
	JMP	RCS1
;
RCS2	CPI	'U'-40H
	JNZ	RCS3
	CALL	WCCR
	JMP	RCS
;
RCS3	CALL	WCC
	MOV	M,A
	INR	B
	CPI	CR
	JZ	RCS4
	INX	H
	JMP	RCS1
;
RCS4	MVI	A,LF
	CALL	WCC
	RET
;
;	RCC - READ CONSOLE CHARACTER
;
;	EXIT CONDITIONS
;		A - CHARACTER READ
;
RCC	PUSH	B
	PUSH	D
	PUSH	H
RCCAL	CALL	$-$
	POP	H
	POP	D
	POP	B
	RET
;
;	WMC - WRITE MODEM CHARACTER
;
;	ENTRY CONDITIONS
;		A - CHARACTER TO WRITE
;
WMC	PUSH	PSW
WMCL	IN	MODS
	ANI	MTBE
	JZ	WMCL
	POP	PSW
	ANI	7FH
	OUT	MODD
	RET
;
;	RMC - READ MODEM CHARACTER
;
;	EXIT CONDITIONS
;		A - CHARACTER READ
;
RMC	IN	MODS
	ANI	MRDA
	JZ	RMC
RMC2	IN	MODD
	PUSH	PSW
	LDA	ERRFLG
	CPI	0
	JNZ	ERRCK
RMC3	POP	PSW
	ANI	7FH
	RET
;
;	ERRCK - CHECK FOR FRAME, OVERRUN, AND PARITY ERROR
;
ERRCK	PUSH	H
	IN	MODS		;JUMP IF NO FRAME ERROR
	ANI	PE
	JZ	ERRCK1
	LHLD	PERR
	INX	H
	SHLD	PERR
	JMP	ERRCK4
ERRCK1	IN	MODS		;JUMP IF NO OVERRUN ERRORS
	ANI	OE
	JZ	ERRCK2
	LHLD	OERR
	INX	H
	SHLD	OERR
	JMP	ERRCK4
ERRCK2	IN	MODS		;JUMP IF NO FRAMING ERRORS
	ANI	FE
	JZ	ERRCK5
	LHLD	FERR
	INX	H
	SHLD	FERR
ERRCK4	LDA	ERROR		;CHECK ERROR CODE
	ORA	A
	JZ	ERRCK5		;JUMP IF 00H
	POP	H		;GET RID OF PSW/A REG
	POP	H		;RESTORE REAL HL
	RET
ERRCK5	POP	H		;RESTORE HL
	POP	PSW		;GET CHARACTER
	ANI	7FH
	RET
;
;	PCD0 - PRINT ERROR SUMMARY MESSAGE
;
PCD0	LXI	H,MSG10
	CALL	WCS
	LHLD	PERR		;PRINT PARITY ERROR COUNT
	CALL	WDWC
	LXI	H,MSG11		;PRINT PARITY ERROR MSG.
	CALL	WCS
	LHLD	OERR		;PRINT OVERRUN ERROR COUNT
	CALL	WDWC
	LXI	H,MSG12		;PRINT OVERRUN ERROR MSG.
	CALL	WCS
	LHLD	FERR		;PRINT FRAME ERROR COUNT
	CALL	WDWC
	LXI	H,MSG13		;PRINT FRAME ERROR MSG.
	CALL	WCS
	JMP	PCC4		;EXIT
;
;	WDWC - WRITE DECIMAL WORD TO CONSOLE
;
;	ENTRY CONDITIONS:
;
;		HL	VALUE TO WRITE IN DECIMAL
;
WDWC	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,0		;CLEAR DIGIT PRINTED FLAG
	LXI	D,10000		;WRITE TEN THOUSANDS DIGIT
	CALL	WNDC
	LXI	D,1000		;WRITE THOUSANDS DIGIT
	CALL	WNDC
	LXI	D,100		;WRITE HUNDREDS DIGIT
	CALL	WNDC
	LXI	D,10		;WRITE TENS DIGIT
	CALL	WNDC
	LXI	D,1		;WRITE UNITS DIGIT
	MVI	C,1		;FORCE UNITS DIGIT TO PRINT
	CALL	WNDC
	POP	B
	POP	D
	POP	H
	RET
;
;	WNDC - WRITE NEXT DIGIT TO CONSOLE
;
;	ENTRY CONDITIONS:
;
;		HL	VALUE TO PRINT NEXT DIGIT OF
;
;		DE	DECIMAL ORDER OF MAGINTUDE
;
;		C	ZERO MEAN LEADING DIGIT NOT YET PRINTED
;
;	EXIT CONDITIONS
;
;		HL	OLD.HL - (OLD.HL / DE) * DE
;
;		C	SET IFF DIGIT PRINTED
;
WNDC	MVI	B,0		;CLEAR COUNT
WNDC1	MOV	A,L		;HL = HL - DE
	SUB	E
	MOV	L,A
	MOV	A,H
	SBB	D
	MOV	H,A
	JC	WNDC2		;BRANCH IF HL < 0
	INR	B		;ELSE INCREMENT COUNT
	JMP	WNDC1		;AND LOOP
WNDC2	DAD	D		;ADD DE BACK IN ONCE
	MOV	A,B		;GET COUNT
	ORA	A
	JNZ	WNDC3		;JUMP IF NON-ZERO
	INR	C		;JUMP IF DIGIT PRINTED ALREADY
	DCR	C
	JNZ	WNDC3
	MVI	A,' '		;PRINT A BLANK AND EXIT
	JMP	WCC
WNDC3	MVI	C,1		;SET DIGIT PRINTED FLAG
	ADI	'0'		;WRITE DIGIT IN ASCII
	JMP	WCC
;
;	RESET - RESET ERROR TRAP REGISTERS
;
RESET	LXI	H,0		;RESET ERROR TRAP REGISTERS
	SHLD	PERR
	SHLD	OERR
	SHLD	FERR
	JMP	PCC4		;EXIT
;
MSG10	DB	HOME,LF,CR,'*** ERROR SUMMARY ***',LF,CR
	DB	'                     ',LF,CR,0
MSG11	DB	'  Parity Errors ',LF,CR,0
MSG12	DB	'  Overrun Errors',LF,CR,0
MSG13	DB	'  Framing Errors',LF,CR,0
ERRMSG	DB	HOME,'*** Receive Error Trap Active ***',CR,LF,0
RESMSG	DB	HOME,'*** Receive Error Counters Reset ***',CR,LF,0
ERR1MSG	DB	HOME,'*** Receive Error Trap Deactivated ***',CR,LF,0
;
;	WMCLF - WRITE AUTO LF/CR SEQUENCE
;
WMCLF	PUSH	PSW
	MVI	A,LF
	CALL	WMC
	CALL	WCC
	POP	PSW
	RET
;
;	GFN - GET FILE NAME
;
GFN	LXI	H,GFNSD
	CALL	WCS
	CALL	RCC
	CALL	WCC
	ANI	5FH
	CPI	'A'
	JNZ	GFNA
	MVI	A,1
	STA	FCB
	JMP	GFNB
;
GFNA	CPI	'B'
	JNZ	GFN
	MVI	A,2
	STA	FCB
GFNB	LXI	H,GFNS1
	CALL	WCS
	CALL	RCS
	LXI	H,FCB+FN
	MVI	C,11
GFN1	MVI	M,' '
	INX	H
	DCR	C
	JNZ	GFN1
	LXI	H,IBUF
	LXI	D,FCB+FN
	MVI	C,9
GFN2	MOV	A,M
	INX	H
	CPI	61H
	JC	GFN2A
	SUI	20H
GFN2A	CPI	CR
	JZ	GFN5
	CPI	'.'
	JZ	GFN3
	STAX	D
	INX	D
	DCR	C
	JNZ	GFN2
	JMP	GFN6
;
GFN3	LXI	D,FCB+FT
	MVI	C,4
GFN4	MOV	A,M
	INX	H
	CPI	61H
	JC	GFN4A
	SUI	20H
GFN4A	CPI	CR
	JZ	GFN5
	STAX	D
	INX	D
	DCR	C
	JNZ	GFN4
	JMP	GFN6
;
GFN5	XRA	A
	STA	FCB+EX
	STA	FCB+NR
	STC
	CMC
	RET
;
GFN6	STC
	RET
;
GFNSD	DB	CR,LF,'Which Drive ? ',0
GFNS1	DB	CR,LF,'Filename ? ',0
;
;	OPEN - OPEN DISK FILE
;
OPEN	PUSH	H
	PUSH	D
	PUSH	B
	LXI	D,FCB
	MVI	C,OFFC
	CALL 	BDOS
	POP	B
	POP	D
	POP	H
	RET
;
;	READ - READ RECORD FROM DISK FILE
;
READ	PUSH	H
	PUSH	D
	PUSH	B
	LXI	D,FCB
	MVI	C,RRFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
;
;	CLOSE - CLOSE DISK FILE
;
CLOSE	PUSH	H
	PUSH	D
	PUSH	B
	LXI	D,FCB
	MVI	C,CFFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
;
;	DELT - DELETE DISK FILE
;
DELT	PUSH	H
	PUSH	D
	PUSH	B
	LXI	D,FCB
	MVI	C,DFFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
;
;	WRITE - WRITE RECORD TO DISK
;
WRITE	PUSH	H
	PUSH	D
	PUSH	B
	LXI	D,FCB
	MVI	C,WRFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
;
;	MAKE - MAKE NEW DISK FILE
;
MAKE	PUSH	H
	PUSH	D
	PUSH	B
	LXI	D,FCB
	MVI	C,MFFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
;
;	CITEST - CHECK CONSOLE INPUT STATUS
;
CITEST	PUSH	B
	PUSH	D
	PUSH	H
CITCAL	CALL	$-$
	ORA	A
	POP	H
	POP	D
	POP	B
	RET
;
;	MITEST - CHECK MODEM INPUT STATUS
;
MITEST	IN	MODS
	ANI	MRDA
	RET
;
;	MOTEST - CHECK MODEM OUTPUT STATUS
;
MOTEST	IN	MODS
	ANI	MTBE
	RET
;
;	INITMODEM
;
ORGMOD	MVI	A,003
	OUT	MODS
	MVI	A,MODINIT
	OUT	MODS
	RET

;
;TURN TRANSMITTER ON
;
RFON	LDA	CRX
	ORI	TON
	OUT	CONTLR+1
	STA	CRX
	RET

;
;TURN TRANSMITTER OFF
;
RFOFF	LDA	CRX
	ANI	NOT(TON) AND 255
	OUT	CONTLR+1
	STA	CRX
	RET

;
;TURN CWID TONE ON
;
TONEON	LDA	CRX
	ORI	IDON AND 255
	OUT	CONTLR+1
	STA	CRX
	RET

;
;TURN CWID TONE OFF
;
TONEOFF	LDA	CRX
	ANI	NOT(IDON)
	OUT	CONTLR+1
	STA	CRX
	RET

;CWID ROUTINE
;
CWID	LXI	H,IDONMSG
	CALL	WCS
	LXI	H,CALL$SIGN
CWID1	MOV	A,M
	ORA	A
	JZ	FINI
	PUSH	H
	MOV	C,A
	CALL	SEND$CW$CHAR
	POP	H
CWID2	INX	H
	JMP	CWID1
SEND$CW$CHAR
	PUSH	B
	CALL	TONEOFF
	MVI	C,2
	CALL	DELAYX
	POP	B
	LXI	H,ASCII$CW-2FH
	MOV	A,C
	CPI	20H
	JNZ	CW1
	MVI	C,7
	JMP	DELAYX
CW1	MVI	B,0
	DAD	B
	MOV	A,M
	ANI	7
	RZ
	MOV	B,A
	MOV	A,M
CW2	ADD	A
	MVI	E,1
	JNC	CW3
	MVI	E,3
CW3	PUSH	B
	PUSH	PSW
	CALL	TONEON
	MOV	C,E
	CALL	DELAYX
	CALL	TONEOFF
	MVI	C,1
	CALL	DELAYX
	POP	PSW
	POP	B
	DCR	B
	JNZ	CW2
	RET

FINI	LXI	H,IDOFFMSG
	CALL	WCS
	RET

DELAYX	MOV	A,C
	ORA	A
	RZ
	PUSH	B
	PUSH	D
DLY1	LXI	D,50
	CALL	DELAY
	DCR	C
	JNZ	DLY1
	POP	D
	POP	B
	RET

;
;ENTER THIS DELAY ROUTINE WITH DE CONTAINING
;THE DELAY VALUE IN MILLISECONDS.
;
DELAY	CALL	WAIT1
	DCX	D
	MOV	A,E
	ORA	D
	JNZ	DELAY
	RET
;

;
;1 MILLISECOND WAIT ROUTINE
;
WAIT1	MVI	A,55*CPUSPD
WAIT1X	DCR	A
	NOP
	JNZ	WAIT1X
	RET

;
;ASCII TO CW TRANSLATION TABLE
;
ASCII$CW
	DB	5+10010000B	;/ -..-.
	DB	5+11111000B	;ZERO
	DB	5+01111000B	;1
	DB	5+00111000B	;2
	DB	5+00011000B	;3
	DB	5+00001000B	;4
	DB	5+00000000B	;5
	DB	5+10000000B	;6
	DB	5+11000000B	;7
	DB	5+11100000B	;8
	DB	5+11110000B	;9
	DB	0		;: NOT USED
	DB	0		;; NOT USED
	DB	0		;< NOT USED
	DB	0		;= NOT USED
	DB	0		;> NOT USED
	DB	0		;? NOT USED
	DB	0		;@ NOT USED
	DB	2+01000000B	;A .-
	DB	4+10000000B	;B -...
	DB	4+10100000B	;C -.-.
	DB	3+10000000B	;D -..
	DB	1+00000000B	;E .
	DB	4+00100000B	;F ..-.
	DB	3+11000000B	;G --.
	DB	4+00000000B	;H ....
	DB	2+00000000B	;I ..
	DB	4+01110000B	;J .---
	DB	3+10100000B	;K -.-
	DB	4+01000000B	;L .-..
	DB	2+11000000B	;M --
	DB	2+10000000B	;N -.
	DB	3+11100000B	;O ---
	DB	4+01100000B	;P .--.
	DB	4+11010000B	;Q --.-
	DB	3+01000000B	;R .-.
	DB	3+00000000B	;S ...
	DB	1+10000000B	;T -
	DB	3+00100000B	;U ..-
	DB	4+00010000B	;V ...-
	DB	3+01100000B	;W .--
	DB	4+10010000B	;X -..-
	DB	4+10110000B	;Y -.--
	DB	4+11000000B	;Z --..


;
;	CONFIG - RECONFIGURE MODEM PARAMETERS
;
CONFIG	MVI	A,003
	OUT	MODS
	LDA	CR1
	OUT	MODS
	IN	MODD		;EAT UP GARBAGE
	IN	MODD
	IN	MODD
	IN	MODD
	STC
	RET
;
CONFMG1	DB	VT,CR,LF,LF
	DB	'          1200 Baud Config. Table'
	DB	CR,LF,'Config.  Data bits       Stop bits       Parity'
	DB	CR,LF
	DB	CR,LF,'1           7                2            Even'
	DB	CR,LF,'2           7                2            Odd'
	DB	CR,LF,'3           7                1            Even'
	DB	CR,LF,'4           7                1            Odd'
	DB	CR,LF,'5           8                2            None'
	DB	CR,LF,'6           8                1            None'
	DB	CR,LF,'7           8                1            Even'
	DB	CR,LF,'8           8                1            Odd'
	DB	CR,LF,LF
	DB	'Which Configuration Do You Wish ?',0
;
CONFMSG	DB	VT,CR,LF,LF
	DB	'          300 Baud Config. Table'
	DB	CR,LF,'Config.  Data bits       Stop bits       Parity'
	DB	CR,LF
	DB	CR,LF,'1           7                2            Even'
	DB	CR,LF,'2           7                2            Odd'
	DB	CR,LF,'3           7                1            Even'
	DB	CR,LF,'4           7                1            Odd'
	DB	CR,LF,'5           8                2            None'
	DB	CR,LF,'6           8                1            None'
	DB	CR,LF,'7           8                1            Even'
	DB	CR,LF,'8           8                1            Odd'
	DB	CR,LF,LF
	DB	'Which Configuration Do You Wish ?',0

;
XMTONMSG	DB	'Transmitter activated',CR,LF,0
XMTOFFMSG	DB	'Transmitter deactivated',CR,LF,0
IDONMSG		DB	'Sending identification',CR,LF,0
IDOFFMSG	DB	'Identification sent',CR,LF,0

;
TERM	MVI	A,0
	OUT	CONTLR+1
	JMP	0000	;RESTART CP/M
;
;	DATA AREA
;
CALL$SIGN	DB	'DE WA3MEZ',0
CRX	DS	1
CR1	DS	1
INCH	DS	1
OUTCH	DS	1
FLAG	DS	1
ERROR	DS	1
ERRFLG	DS	1
PTR	DS	2
SIZE	DS	2
PERR	DS	2
OERR	DS	2
FERR	DS	2
;
;	DATA BUFFER AREA
;
STACK	DS	64
IBUF	DS	256
TBUF	EQU	$
;
	END
