;
;===========================================
;
;	ASCII TO BAUDOT TO ASCII PROGRAM
;	WITH BUFFER TO DISK AND DISK TO BUFFER
;	ROUTINES TAKEN FROM 'LINK.ASM' BY L.E.HUGHS
;
;	RANDY SUESS 12/20/78
;============================================
;
;08/12/79 MODIFICATIONS BY JIM MILLS WB9KFP TO ALLOW
;OPERATION USING PMMI MM-103 DIRECT-CONNECT MODEM
;
;
;            CTRL-R    SEND TEXT FILE FROM DISK TO CYBER
;            CTRL-Y    ENABLE TEXT-FILE-LOADER (INTO MEMORY)
;            CTRL-Q    DISABLE TEXT FILE LOADER, WRITE MEMORY TO DISK
 
;         BDOS ENTRY POINT AND FUNCTION CODES
 
 BDOS     EQU    0005H
 OFFC     EQU    15             ;OPEN FILE
 CFFC     EQU    16             ;CLOSE FILE
 DFFC     EQU    19             ;DELETE FILE
 RRFC     EQU    20             ;READ RECORD
 WRFC     EQU    21             ;WRITE RECORD
 MFFC     EQU    22             ;MAKE FILE
 
;         DEFAULT FCB AND FIELD DEFINITIONS
 
 FCB      EQU    5CH
 FN       EQU    1              ;FILE NAME FIELD (REL)
 FT       EQU    9              ;FILE TYPE FIELD (REL)
 NR       EQU    32             ;NEXT RECORD FIELD (REL)
 DBUF     EQU    80H            ;DEFAULT DISK BUFFER ADDRESS
 
;         ASCII CONTROL CHARACTERS
 
 BEL      EQU    007Q           ;BELL
 LF       EQU    012Q           ;LINE FEED
 CR       EQU    015Q           ;CARRIAGE RETURN
 DEL      EQU    177Q           ;DELETE
 
;         I/O PORT ADDRESSES
 
 COND     EQU    005Q           ;CONSOLE DATA PORT
COND1	EQU	07H	;SECOND CONSOLE
 CONS     EQU    004Q           ;CONSOLE STATUS PORT
CONS1	EQU	06H	;2ND CONSOLE
 MODD     EQU    FF01H           ;MODEM DATA PORT
 MODS     EQU    FF00H           ;MODEM STATUS PORT
 
;	PMMI PORT ADDRESSES

PMMI	EQU	FF00H		;PMMI BASE ADDRESS
PMMIUS	EQU	PMMI		;PMMI UART STATUS
PMMIRD	EQU	PMMI+1		;PMMI RCV DATA
PMMIMS	EQU	PMMI+2		;PMMI MODEM STATUS
PMMIIM	EQU	PMMI+3		;PMMI INPUT MASK
PMMICON	EQU	PMMI		;PMMI UART/MODEM CONTROL
PMMIXD	EQU	PMMI+1		;PMMI XMIT DATA
PMMIT	EQU	PMMI+2		;PMMI TIMER
PMMIOM	EQU	PMMI+3		;PMMI OUTPUT MASK
PMMIMC	EQU	PMMI+4		;PMMI MODEM CONTROL

;         I/O SYMBOL DEFINITIONS
 
 CTBE     EQU    02H           ;CONSOLE TRANSMIT BUFFER EMPTY
 CRDA     EQU    01H           ;CONSOLE READ DATA AVAILABLE
 
 MTBE     EQU    080H           ;RTTY TRANSMIT BUFFER EMPTY
 MRDA     EQU    01H           ;RTTY READ DATA AVAILABLE
 
;         MAIN PROGRAM
 
          ORG    100H
 LINK:    LXI    H,0            ;SAVE OLD STACK POINTER
          DAD    SP
          SHLD   OLDSP
          LXI    SP,STACK+64    ;CREATE LOCAL STACK
 LINK2:   XRA    A              ;CLEAR CHAR BUFFERS
          STA    INCH
          STA    OUTCH
          STA    FLAG           ;CLEAR TEXT SAVE FLAG
          LXI    H,TBUF         ;SET PTR TO TBUF
          SHLD   PTR
          LXI    H,0            ;SIZE = 0
          SHLD   SIZE
          CALL   WCCR           ;WRITE CR/LF TO CONSOLE
          MVI    A,BEL          ;RING BELL ON CONSOLE, TO LET
          CALL   WCC            ;  CLONE KNOW WE'RE READY
 
;         MAIN LOOP
 
LINK3:
          IN     CONS           ;JUMP IF NO DATA FROM CONSOLE
          ANI    CRDA
          JZ     LINK44
          IN     COND           ;ELSE READ CONSOLE DATA
	OUT	COND		;ECHO TO TERMINAL
          ANI    177Q           ;CALL PCC IF CONTROL CHAR
          CPI    40Q
          CC     PCC
          JC     LINK4          ;JUMP IF PCC HANDLED CHAR
          ORI    200Q           ;ELSE SET VALID DATA BIT
          STA    INCH           ;AND STORE IN INPUT CHAR BUFFER
LINK44:
	IN	CONS1
	ANI	CRDA
	JZ	LINK4
	IN	COND1
	OUT	COND1
	ANI	07FH
	CPI	40Q
	CC	PCC
	JC	LINK4
	ORI	200Q
	STA	INCH
 LINK4:   IN     CONS1           ;JUMP IF CONSOLE XMIT BUFFER BUSY
          ANI    CTBE
          JZ     LINK5
          LDA    OUTCH          ;JUMP IF NO DATA FOR CONSOLE
          ORA    A
          JP     LINK5
          ANI    177Q           ;ELSE DISCARD VALID DATA BIT
          OUT    COND           ;  AND OUTPUT CHAR TO CONSOLE
	OUT	COND1
          XRA    A              ;  THEN CLEAR OUTPUT CHAR BUFFER
          STA    OUTCH
 LINK5:   IN     MODS           ;JUMP IF NO DATA FROM RTTY
          ANI    MRDA
          JNZ     LINK6
TTYREAD:
;				**** CALL
;				****RTTY READ ROUTINE
	CALL	RMC
          CALL   SAVE           ;SAVE CHAR IN TEXT BUFFER IF FLAG ON
          ORI    200Q           ;SET DATA VALID BIT
          STA    OUTCH          ;STORE IN OUTPUT CHAR BUFFER
 LINK6:   IN     MODS           ;JUMP IF RTTY XMIT BUFFER BUSY
          ANI    MTBE
          JNZ     LINK7
          LDA    INCH           ;JUMP IF NO DATA FOR RTTY
          ORA    A
          JP     LINK7
          ANI    177Q           ;ELSE DISCARD VALID DATA BIT
;	********* CALL RTTY OUT ROUTINE
;******		ADDED CODE TO SEND 2 CR'S AND 1 LF
;		FOR EACH CR
	CPI	CR
	JNZ	LNKX
	MVI	A,CR
	CALL	WMC
	MVI	A,LF
	OUT	1	;ECHO LF TO CONSOLE
	CALL	WMC
LNKX:
	CALL	WMC
          XRA    A              ;  THEN CLEAR INPUT CHAR BUFFER
          STA    INCH
 LINK7:   JMP    LINK3          ;END OF MAIN LOOP
 
LINKX:
          LHLD   OLDSP
          SPHL
	XRA	A
	OUT	202Q
          RET
 
;         PCC - PROCESS CONTROL CHARACTER
 
 PCC:     CPI    'D'-100Q       ;JUMP IF NOT CONTROL-D
          JNZ    PCC1
          LHLD   OLDSP          ;ELSE CLEAN UP ACT AND GO HOME
          SPHL
          RET
 PCC1:    CPI    'O'-100Q       ;JUMP IF NOT CONTROL-Q
          JNZ    PCC2
          CALL   STF            ;SEND TEXT FILE TO RTTY
          STC                   ;TELL LINK TO IGNORE THIS CHARACTER
          RET
 PCC2:    CPI    'Y'-100Q       ;JUMP IF NOT CONTROL-Y
          JNZ    PCC3
          MVI    A,1            ;TURN ON TEXT SAVE FLAG
          STA    FLAG
          STC
          RET
 PCC3:    CPI    'Q'-100Q       ;JUMP IF NOT CONTROL-Q
          JNZ    PCC4
          XRA    A              ;TURN OFF TEXT SAVE FLAG
          STA    FLAG
          CALL   WTB            ;WRITE TEXT BUFFER TO DISK
          LXI    H,TBUF         ;CLEAR TEXT BUFFER
          SHLD   PTR
          LXI    H,0
          SHLD   SIZE
          STC
          RET
 PCC4:    STC                   ;LET LINK HANDLE ALL OTHER CONTROL CODES
          CMC
          RET
        
;         STF - SEND TEXT FILE (TO RTTY)
 
 STF:     CALL   GFN            ;GET NAME OF DISK FILE TO SEND
          JC     STF6           ;JUMP IF FILE NAME ERROR
          CALL   OPEN           ;TRY TO OPEN SPECIFIED FILE
          CPI    255            ;JUMP IF FILE NOT FOUND
          JZ     STF7
          XRA    A              ;ELSE REWIND FILE AND GET ON WITH IT
          STA    FCB+NR
 STF1:    CALL   READ           ;READ NEXT RECORD INTO DBUF
          CPI    1              ;JUMP IF END-OF-FILE
          JZ     STF5
          LXI    H,DBUF         ;POINT TO DISK BUFFER
          MVI    C,128
 STF2:    MOV    A,M            ;FETCH NEXT CHAR FROM DBUF
          INX    H
          CPI    'Z'-100Q       ;JUMP IF END-OF-FILE CHARACTER
          JZ     STF5
          CALL   WMC            ;WRITE CHARACTER TO RTTY
          CALL   WCC            ;WRITE CHARACTER TO CONSOLE
	IN	01	;CHECK FOR CTRL D ABORT
	ANI	7FH
	CPI	04H
	JZ	STF5
 STF4:    DCR    C              ;LOOP THRU REST OF DBUF
          JNZ    STF2
          JMP    STF1           ;GO GET NEXT RECORD FROM DISK
 STF5:    CALL   CLOSE          ;CLEAN UP ACT AND GO HOME
          MVI    A,BEL          ;RING BELL TO LET CLONE
          CALL   WCC            ;  KNOW WE'RE THROUGH
          RET
 STF6:    LXI    H,STFS1        ;PRINT 'FILE NAME ERROR'
          CALL   WCS
          RET
 STF7:    LXI    H,STFS2        ;PRINT 'FILE NOT FOUND'
          CALL   WCS
          RET
 
 STFS1:   DB     'FILE NAME ERROR',CR,LF,0
 STFS2:   DB     'FILE NOT FOUND',CR,LF,0
 
;         SAVE - SAVE CHAR IN TEXT BUFFER IF FLAG ON
;
;         ENTRY CONDITIONS
;            A - CHARACTER TO SAVE
 
 SAVE:    PUSH   PSW
          LDA    FLAG
          ORA    A
          JNZ    SAVE1
          POP    PSW
          RET
 SAVE1:   POP    PSW
          PUSH   H
          LHLD   PTR
          ANI    7FH            ;DISCARD PARITY BIT
          JZ     SAVE2          ;JUMP IF CHAR IS A NULL
          MOV    M,A
          INX    H
 SAVE2:   CMA                   ;DISPLAY CHAR ON LIGHTS
          OUT    0FFH
          CMA
          SHLD   PTR
          LHLD   SIZE           ;SIZE = SIZE + 1
          INX    H
          SHLD   SIZE
          POP    H
          RET
 
;         WTB - WRITE TEXT BUFFER TO DISK
 
 WTB:     LHLD   SIZE           ;JUMP IF TEXT BUFFER EMPTY
          MOV    A,L
          ORA    H
          JZ     WTB5
          CALL   GFN            ;GET FILE NAME
          JC     WTB6           ;JUMP IF FILE NAME ERROR
          CALL   DELT           ;DELETE OLD FILE, IF ANY
          CALL   MAKE           ;MAKE NEW FILE
          XRA    A              ;REWIND FILE
          STA    FCB+NR
          LHLD   SIZE           ;DE = TBUF SIZE
          XCHG
          LXI    H,DBUF         ;TOP OF STACK POINTS TO DBUF
          PUSH   H
          LXI    H,TBUF         ;HL POINTS TO TBUF
 WTB1:    MVI    C,128          ;DISK BUFFER SIZE
 WTB2:    MOV    A,M            ;FETCH NEXT BYTE OF TBUF
          INX    H
          XTHL
          MOV    M,A            ;STORE IN DBUF
          INX    H
          XTHL
          DCX    D              ;SIZE = SIZE - 1
          MOV    A,D            ;EXIT LOOP IF SIZE = 0
          ORA    E
          JZ     WTB3
          DCR    C              ;LOOP UNTIL DBUF FULL
          JNZ    WTB2
          CALL   WRITE          ;WRITE FULL DBUF TO DISK
          XTHL                  ;TOP OF STACK POINTS TO DBUF
          LXI    H,DBUF
          XTHL
          JMP    WTB1           ;LOOP UNTIL END OF TBUF
 WTB3:    POP    H              ;HL POINTS TO CURRENT PLACE IN DBUF
 WTB4:    MVI    M,'Z'-100Q     ;STORE EOF CODE
          INX    H
          DCR    C              ;LOOP THRU REST OF DBUF
          JNZ    WTB4
          CALL   WRITE          ;WRITE LAST SECTOR TO DISK
          CALL   CLOSE          ;CLEAN UP ACT AND GO HOME
          MVI    A,BEL          ;RING BELL TO LET CLONE
          CALL   WCC            ;  KNOW WE'RE THROUGH
          RET
 WTB5:    LXI    H,WTBS1        ;PRINT 'TEXT BUFFER EMPTY'
          CALL   WCS
          RET
 WTB6:    LXI    H,WTBS2        ;PRINT 'FILE NAME ERROR'
          CALL   WCS
          RET
 
 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,CR
          CALL   WCC
          MVI    A,LF
 
;         WCC - WRITE CONSOLE CHARACTER
;
;         ENTRY CONDITIONS:
;            A - CHARACTER TO WRITE
 
 WCC:     PUSH   PSW
          IN     CONS
          ANI    CTBE
          JZ     $-4
          POP    PSW
          OUT    COND
	PUSH	PSW
	IN	CONS1
	ANI	CTBE
	JZ	$-4
	POP	PSW
	OUT	COND1
          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            ;READ NEXT CHAR FROM CONSOLE
          CPI    DEL            ;JUMP IF NOT DEL
          JNZ    RCS2
          INR    B              ;IGNORE DEL IF IBUF ALREADY EMPTY
          DCR    B
          JZ     RCS1
          DCX    H              ;ELSE DISCARD LAST CHAR
          MOV    A,M            ;ECHO DISCARDED CHAR TO CONSOLE
          CALL   WCC
          DCR    B              ;DECREMENT COUNT
          JMP    RCS1           ;  AND LOOP
 RCS2:    CPI    'U'-100Q       ;JUMP IF NOT CONTROL-U
          JNZ    RCS3
          CALL   WCCR           ;ELSE ABORT CURRENT LINE
          JMP    RCS            ;  AND START OVER
 RCS3:    CALL   WCC            ;ECHO CHAR TO CONSOLE
          MOV    M,A            ;STORE CHAR IN IBUF
          INR    B              ;INCREMENT COUNT
          CPI    CR             ;JUMP IF CARRIAGE RETURN
          JZ     RCS4
          INX    H              ;ELSE ADVANCE POINTER
          JMP    RCS1           ;  AND LOOP
 RCS4:    MVI    A,LF           ;ISSUE LINE FEED AND RETURN
          CALL   WCC
          RET
 
;         RCC - READ CONSOLE CHARACTER
;
;         EXIT CONDITIONS
;            A - CHARACTER READ
 
 RCC:     IN     CONS
          ANI    CRDA
          JZ     RCCC
          IN     COND
          ANI    177Q
          RET
RCCC:
	IN	CONS1
	ANI	CRDA
	JZ	RCC
	IN	COND1
	ANI	177Q
	RET
 
;         WMC - WRITE RTTY CHARACTER
;
;         ENTRY CONDITIONS
;            A - CHARACTER TO WRITE
WMC:
;	CALL	RTTYOUT		;***************************
	CALL	RTTYXMIT
	PUSH	PSW	;GONNA PRINT IT?
	IN	0FFH
	ANI	80H
	JNZ	DIABLO
	POP	PSW
	RET
;
 
;         RMC - READ RTTY CHARACTER
;
;         EXIT CONDITIONS:
;            A - CHARACTER READ
 
RMC:
;	CALL	RMC	;********************
	CALL	RTTYREAD
	PUSH	PSW
;	********* OUT TO PRINTER ALSO IF 80H UP
	IN	0FFH
	ANI	80H
	JNZ	DIABLO
	POP	PSW
	RET
DIABLO:
	POP	PSW
	PUSH	PSW
	PUSH	B
	PUSH	D
	PUSH	H
	MOV	E,A
	MVI	C,5
	CALL	BDOS
	POP	H
	POP	D
	POP	B
	POP	PSW
	RET
; 
;	ASCRCV(4), VER. 2
; BY KEITH PETERSEN, W8SDZ.  10/30/78.
; 
; THIS IS A PROGRAM TO CHANGE
; ASCII-CODED-BAUDOT TO ASCII.
; THE ROUTINE RETURNS WITH A 0FFH
; IN THE 'A' REGISTER IF CHARACTER
; IS TO BE IGNORED.  OTHERWISE IT
; RETURNS WITH THE ASCII CHARACTER
; IN THE 'A' REGISTER.  IT IS ASSUMED
; THAT A STATUS TEST HAS BEEN DONE BEFORE
; CALLING THIS ROUTINE TO DETERMINE THAT
; A BAUDOT CHARACTER IS AVAILABLE.
; 
; EQUATES
; 
BTTY:	EQU	05H	;BAUDOT UART DATA PORT
BELL:	EQU	07H	;ASCII BELL
LTRS:	EQU	1FH	;BAUDOT 'LTRS'
SPACE:	EQU	04H	;BAUDOT 'SPACE'
FIGS:	EQU	1BH	;BAUDOT 'FIGS'
APOS:	EQU	27H	;APOSTROPHE
CNTC:	EQU	03H	;CONTROL C
LARW:	EQU	5FH	;LEFT ARROW
ASPC:	EQU	20H	;ASCII SPACE
ATSN:	EQU	40H	;"AT" SIGN
CNTV:	EQU	16H	;CONTROL V
CNTO:	EQU	0FH	;CONTROL O
RUBT:	EQU	7FH	;RUBOUT
CNTE:	EQU	05H	;CONTROL E
PCT:	EQU	25H	;PERCENT SIGN
EQL:	EQU	3DH	;EQUALS SIGN
GRTH:	EQU	3EH	;GREATER-THAN SIGN
CNTH:	EQU	08H	;CONTROL H
LETH:	EQU	3CH	;LESS-THAN SIGN
CNTB:	EQU	02H	;CONTROL B
STAR:	EQU	2AH	;ASTERISK
CNTI:	EQU	09H	;CONTROL I
CNTZ:	EQU	1AH	;CONTROL Z
CNTA:	EQU	01H	;CONTROL A
CNTX:	EQU	18H	;CONTROL X
UARW:	EQU	5EH	;UP-ARROW
PLUS:	EQU	2BH	;PLUS SIGN
RESL:	EQU	5CH	;REVERSE SLANT
LBKT:	EQU	5BH	;LEFT BRACKET
RBKT:	EQU	5DH	;RIGHT BRACKET
ESCP:	EQU	1BH	;ESCAPE KEY
ALMD:	EQU	7DH	;ALTERNATE MODE KEY
; 
; PROGRAM STARTS HERE
; 
RTTYREAD:
; 
ASCRCV:	PUSH	H	;SAVE HL REGISTERS
	LHLD	CASAVE	;GET PRESENT CASE
; 
START:	IN	BTTY	;GET BAUDOT CHARACTER
	ANI	1FH	;BAUDOT CHARACTERS ONLY
	CPI	FIGS
	JZ	UCASE
	CPI	LTRS
	JZ	LCASE
	ORA	A	;BAUDOT 'BLANK' ?
	JZ	TCASE
	CPI	SPACE
	JNZ	START1
	LXI	H,LTABLE ;SPACE GIVES LOWER CASE
; 
START1:	SHLD	CASAVE	;SAVE PRESENT CASE
	ADD	L	;ADD CHAR. TO TABLE ADRS.
	MOV	L,A	;L POINTS TO ASCII CHAR.
	MOV	A,H	;GET H FOR CORRECTION
	ACI	0	;SEE IF CORRECTION NEEDED
	MOV	H,A	;H IS CORRECT NOW
	XRA	A	;PUT ZERO IN A REG.
	STA	FLAGR	;CLEAR LTRS-FIGS LAST FLAG
	MOV	A,M	;GET ASCII EQUIVALENT
	POP	H	;RESTORE HL REGISTERS
	ORA	A	;IS IT PRINTABLE?
	RNZ		;YES, VALID CHAR. RETURN
	CMA		;MAKE 0FFH 'IGNORE FLAG'
	RET		;RETURN TO CALLING PROGRAM
; 
LCASE:	LXI	H,LTABLE ;LOWER CASE TABLE ADDRESS
	JMP	SETFLG	;SET LTRS LAST FLAG, EXIT
; 
UCASE:	LXI	H,UTABLE ;UPPER CASE TABLE ADDRESS
	JMP	SETFLG	;SET FIGS LAST FLAG, EXIT
; 
TCASE:	LDA	FLAGR	;GET SHIFT REMINDER FLAG
	CPI	FIGS
	JNZ	FCASE
	LXI	H,TTABLE ;THIRD CASE TABLE ADDRESS
	JMP	CLRFLG
; 
FCASE:	CPI	LTRS	;CHECK FOR LTRS LAST
	JNZ	CLRFLG
	LXI	H,FTABLE ;FOURTH CASE TABLE ADDRESS
; 
CLRFLG:	XRA	A	;READY TO CLEAR FLAG
; 
SETFLG:	STA	FLAGR	;LTRS-FIGS LAST FLAG
	SHLD	CASAVE	;SAVE PRESENT CASE
	MVI	A,0FFH	;'IGNORE FLAG'
	POP	H	;RESTORE HL REGS.
	RET		;RETURN TO CALLING PROGRAM
; 
; THIS IS THE LOWER-CASE TABLE.
; 
LTABLE:	DB	0,'E',LF,'A SIU',CR,'DRJNFCK'
	DB	'TZLWHYPQOBG',FIGS,'MXV'
; 
; THIS IS THE UPPER-CASE TABLE.
; 
UTABLE:	DB	0,'3',LF,'- ',BELL,'87',CR,'$4'
	DB	APOS,',!:(5")2#6019?&',FIGS,'./;'
; 
; THIS IS THE THIRD-CASE TABLE.
; IT IS USED FOR SPECIAL CHARACTERS.
; THE FIRST COLUMN IN THE TABLE
; THE ASCII CHARACTER EQUIVALENT.
; THE SECOND COLUMN IS THE SPECIAL
; CASE BAUDOT CHARACTER FROM WHICH
; THE CONVERSION IS MADE.
; 
TTABLE:	DB	0,CNTC,LF	;BL  3   LF
	DB	LARW,ASPC,ATSN	;-   SP  BELL
	DB	CNTV,CNTO,CR	;8   7   CR
	DB	ALMD,CNTE,PCT	;$   4   '
	DB	RUBT,EQL,ESCP	;,   !   :
	DB	LETH,CNTH,LBKT	;(   5   "
	DB	GRTH,CNTB,STAR	;)   2   #
	DB	CNTI,CNTZ,CNTA	;6   0   1
	DB	CNTX,UARW,PLUS	;9   ?   &
	DB	0,RBKT,RESL	;FIG .   /
	DB	0	        ;;
; 
; THIS IS THE FOURTH CASE TABLE
; FOR LOWER-CASE ALPHA CHARACTERS.
; 
FTABLE:	DB	0,65H,LF,61H,ASPC,73H
	DB	69H,75H,CR,64H,72H,6AH
	DB	6EH,66H,63H,6BH,74H,7AH
	DB	6CH,77H,68H,79H,70H,71H
	DB	6FH,62H,67H,FIGS,6DH,78H
	DB	76H
; 
; TEMPORARY STORAGE AREA
; 
CASAVE:	DW	LTABLE	;PRESENT CASE REMINDER
FLAGR:	DB	0	;FIGS/LTRS LAST FLAG
; 
 
; 
;		ASCXMT(4) REV. 2
;	BY KEITH PETERSEN, W8SDZ.  10/29/78.
; 
; THIS PROGRAM IS FOR TRANSMITTING ASCII
; THROUGH A BAUDOT MEDIUM USE A SPECIAL
; FORMAT OF FIGURES BLANK (X) - WHERE (X)
; IS A SPECIAL BAUDOT CHARACTER USED TO
; CONVEY THE ASCII EQUIVALENT CHARACTER TO THE
; RECEIVING END WHERE IT IS THEN CONVERTED BACK
; TO ASCII AGAIN.  LOWER CASE ALPHA CHARACTERS
; ARE TRANSMITTED VIA A 4TH CASE, LTRS BLANK (X).
;
; EQUATES
; 
LTRSX:	EQU	1FH
FIGSX:	EQU	1BH
CRX:	EQU	48H
LFX:	EQU	42H
STATUS:	EQU	04H	;BAUDOT UART STATUS PORT
TBE:	EQU	80H	;UART TRANS. BUF. EMPTY FLAG
BTTY:	EQU	05H	;BAUDOT UART DATA PORT
ALTMOD:	EQU	7DH	;ALTERNATE MODE KEY
; 
;   	   PROGRAM STARTS HERE.
; CALL WITH ASCII CHARACTER IN ACCUMULATOR.
; 
; 
RTTYXMIT:
STARTX:	PUSH	PSW	;SAVE REGISTERS USED
	PUSH	B
	PUSH	H
; 
BAUDOT:	MVI	C,0	;SET UP COUNTER
	ANI	7FH	;STRIP PARITY BIT
	CPI	ALTMOD	;ALTERNATE MODE KEY?
	JNZ	BAUD2	;NO, IGNORE NEXT ROUTINE
	MVI	A,09H	;BAUDOT '$'
	JMP	BAUD3
; 
BAUD2:	CPI	7BH	;ABOVE L.C. 'Z' ?
	JNC	TTY0	;IF SO, IGNORE IT
	LXI	H,BTABLE ;POINT TO TABLE START
	ADD	L	;ADD CHARACTER VALUE
	MOV	L,A	;L POINTS TO BAUDOT CHAR.
	MOV	A,H	;GET H FOR CORRECTION
	ACI	0	;CORRECT IF NECESSARY
	MOV	H,A	;H IS NOW CORRECT
	MOV	A,M	;GET BAUDOT CHARACTER
	ORA	A	;IS IT A NON-PRINTING CHAR?
	JZ	TTY0	;IF SO IGNORE IT
	CPI	CRX	;IS IT A CARRIAGE RETURN?
	JZ	TTYOUT-1 ;YES, HANDLE WITHOUT CASE TEST
	CPI	LFX	;IS IT A LINE FEED?
	JNZ	BAUD3	;NO, IGNORE NEXT ROUTINE
	MVI	A,LTRSX	
	PUSH	PSW	;SAVE IT ON STACK
	MVI	A,LFX
	LXI	H,SCASE	;POINT TO PRESENT CASE REG.
	MVI	M,40H	;SET IT TO LOWER CASE
	JMP	TTYOUT-2 ;SEND LF AND LTRS
; 
BAUD3:	PUSH	PSW	;SAVE CHARACTER
	ANI	0C0H	;STRIP ALL BUT CASE BITS
	LXI	H,SCASE	;POINT TO PRESENT CASE REG.
	CMP	M	;SAME CASE AS PREVIOUS CHARACTER?
	JZ	TTYOUT	;YES NO CHANGE NECESSARY
	MOV	M,A	;UPDATE CASE REGISTER
	ORA	A
	JZ	TCASEX
	CPI	80H
	JZ	UCASEX
	CPI	0C0H
	JNZ	LCASSEX
; 
FCASEX:	XRA	A	;GET A BAUDOT 'BLANK'
	PUSH	PSW	;SAVE IT ON THE STACK
	INR	C	;INCREMENT CHARACTER COUNT
; 
LCASSEX:	MVI	A,LTRSX
	JMP	TTYOUT-2
; 
TCASEX:	XRA	A	;GET A BAUDOT 'BLANK'
	PUSH	PSW	;SAVE IT ON THE STACK
	INR	C	;INCREMENT CHARACTER COUNT
; 
UCASEX:	MVI	A,FIGSX
	INR	C	;INCREMENT CHARACTER COUNT
	PUSH	PSW	;SAVE IT ON THE STACK
; 
TTYOUT:	IN	STATUS	;BAUDOT UART STATUS
	ANI	TBE	;TRANS. BUFFER EMPTY?
	JNZ	TTYOUT	;IF NOT, LOOP AND WAIT
	POP	PSW	;GET CHARACTER
; 
; OMIT NSEXT THREE LINES IF NO LIGHTS.
; 
	CMA		;INVERT FOR LIGHTS
	OUT	0FFH	;PUT ON FRONT PANEL LIGHTS
	CMA		;INVERT BACK TO NORMAL
;
; OMIT ABOVE THREE LINES IF NO LIGHTS.
; 
	ORI	0E0H	;MAKE UPPER 3 BITS MARKING
	OUT	BTTY	;SEND TO BAUDOT UART PORT
	DCR	C	;MORE TO SEND?
	JP	TTYOUT	;YES, CONTINUE SENDING
; 
TTY0:	POP	H	;RESTORE REGISTERS
	POP	B
	POP	PSW
	RET		;RETURN TO CALLING PROGRAM
; 
BTABLE:	DB	5FH,17H,13H	;NUL SOH STX
	DB	1,0,0AH		;ETX EOT ENQ
	DB	0,85H,10H	;ACK BEL BS
	DB	15H,42H,0C2H	;HT  LF  VT
	DB	2,48H,0		;FF  CR  SO
	DB	7,0,0		;SI  DLE DC1
	DB	0,0,0		;DC2 DC3 DC4
	DB	0,6,0		;NAK SYN ETB
	DB	18H,0,16H	;CAN EM  SUB
	DB	0EH,0,0		;ESC FS  GS
	DB	0,0,44H		;RS  US  SPACE
	DB	8DH,91H,94H	;!   "   #
	DB	89H,0BH,9AH	;$   PCT &
	DB	8BH,8FH,92H	;'   (   )
	DB	14H,1AH,8CH	;AS  PL  ,
	DB	83H,9CH,9DH	;-   .   /
	DB	96H,97H,93H	;0   1   2
	DB	81H,8AH,90H	;3   4   5
	DB	95H,87H,86H	;6   7   8
	DB	98H,8EH,9EH	;9   :   ;
	DB	0FH,0DH,12H	;LT  EQ  GT
	DB	99H,5,43H	;?   AT  A
	DB	59H,4EH,49H	;B   C   D
	DB	41H,4DH,5AH	;E   F   G
	DB	54H,46H,4BH	;H   I   J
	DB	4FH,52H,5CH	;K   L   M
	DB	4CH,58H,56H	;N   O   P
	DB	57H,4AH,45H	;Q   R   S
	DB	50H,47H,5EH	;T   U   V
	DB	53H,5DH,55H	;W   X   Y
	DB	51H,11H,1DH	;Z   LB  LS
	DB	1CH,19H,3	;RB  UA  LA
; 
; THESE ARE THE LOWER CASE ALPHA CHARACTERS
; 
	DB	0,0C3H,0D9H	;'   A   B
	DB	0CEH,0C9H,0C1H	;C   D   E
	DB	0CDH,0DAH,0D4H	;F   G   H
	DB	0C6H,0CBH,0CFH	;I   J   K
	DB	0D2H,0DCH,0CCH	;L   M   N
	DB	0D8H,0D6H,0D7H	;O   P   Q
	DB	0CAH,0C5H,0D0H	;R   S   T
	DB	0C7H,0DEH,0D3H	;U   V   W
	DB	0DDH,0D5H,0D1H	;X   Y   Z
; 
; TEMPORARY STORAGE AREA
; 
SCASE:	DB	40H	;PRESENT CASE REGISTER
; 
  
 
 GFN:     CALL   WCCR
          LXI    H,GFNS1        ;PRINT 'FILENAME? '
          CALL   WCS
          CALL   RCS            ;READ RESPONSE INTO IBUF
          LXI    H,FCB+FN       ;BLANK FILL FN AND FT FIELDS
          MVI    C,11
 GFN1:    MVI    M,' '
          INX    H
          DCR    C
          JNZ    GFN1
          LXI    H,IBUF         ;POINT TO INPUT BUFFER
          LXI    D,FCB+FN       ;SCAN OFF FN FIELD
          MVI    C,9
 GFN2:    MOV    A,M            ;FETCH NSEXT CHAR FROM IBUF
          INX    H
          CPI    141Q           ;IF LC, CONVERT TO UC
          JC     $+5
          SUI    40Q
          CPI    CR             ;JUMP IF END OF LINE
          JZ     GFN5
          CPI    '.'            ;JUMP IF END OF NAME
          JZ     GFN3
          STAX   D              ;ELSE STORE CHAR IN FN FIELD
          INX    D
          DCR    C              ;LOOP IF 8 OR LESS CHARS SO FAR
          JNZ    GFN2
          JMP    GFN6           ;ELSE TAKE ERROR SEXIT
 GFN3:    LXI    D,FCB+FT       ;SCAN OFF FT FIELD
          MVI    C,4
 GFN4:    MOV    A,M            ;FETCH NSEXT CHAR FROM IBUF
          INX    H
          CPI    141Q           ;IF LC, CONVERT TO UC
          JC     $+5
          SUI    40Q
          CPI    CR             ;JUMP IF END OF LINE
          JZ     GFN5
          STAX   D              ;ELSE STORE CHAR IN FT FIELD
          INX    D
          DCR    C              ;LOOP IF 3 OR LESS CHARS SO FAR
          JNZ    GFN4
          JMP    GFN6           ;ELSE TAKE ERROR SEXIT
 GFN5:    STC                   ;CLEAR ERROR FLAG AND RETURN
          CMC
          RET
 GFN6:    STC                   ;SET ERROR FLAG AND RETURN
          RET
 
 GFNS1:   DB     '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
 
;         DATA AREA
 
 MCB:     DS     1              ;RTTY CONTROL BYTE
 
 INCH:    DS     1              ;INPUT CHAR BUFFER (TO CYBER)
 OUTCH:   DS     1              ;OUTPUT CHAR BUFFER (FROM CYBER)
 
 OLDSP:   DS     2              ;OLD STACK POINTER
 STACK:   DS     128             ;LOCAL STACK
 
IBUF:	DS	256
 
;         TSEXT BUFFER
 
 FLAG:    DS     1              ;TSEXT SAVE FLAG
 PTR:     DS     2              ;TSEXT BUFFER POINTER
 SIZE:    DS     2              ;TSEXT BUFFER SIZE
 TBUF     EQU    $              ;START OF TSEXT BUFFER
 
 NUM      EQU    TBUF           ;TEMPORARY BUFFER FOR PHONE NUMBER
 
          END    LINK
