; Program to transmit a CP/M file through a serial port ; Accesses port directly, bypassing the BDOS ; Assumes an 8-bit word length and no parity ; ; Version of 9/2/83 ; ; BOOT EQU 0000H ;CP/M reboot address BDOS EQU 0005H ;CP/M BDOS entry point TFCB EQU 005CH ;FCB for file to be transmitted SIOSTA EQU 07H ;SIO status port SIODAT EQU 06H ;SIO data port IFLAG EQU 02H ;Input flag for serial port OFLAG EQU 01H ;Output flag for serial port BUFREC EQU 128 ;Buffer size (CP/M records) ; ; ORG 100H ; ; If required, place serial port initialization code here ; TX: LDA TFCB+1 CPI ' ' ;Check for filename JNZ OPEN LXI D,FNMER ;Print error message and reboot ABORT: MVI C,9 CALL BDOS MVI E,04H CALL XMTBYT ;Send EOT character JMP BOOT ;Return to CP/M OPEN: LXI D,TFCB MVI C,15 CALL BDOS ;Open file INR A JNZ FOUND ;File present LXI D,FNFER ;Point at error message JMP ABORT ;Print and reboot FOUND: XRA A STA TFCB+32 ;Set next record byte to zero MOV C,A ;Set record count in buffer to zero READY: PUSH B ;Save rerord count MVI C,11 CALL BDOS ;Get console status ORA A JZ READY ;No key pressed PUSH B MVI C,1 CALL BDOS POP B CPI 03H JNZ READY1 ENDXMT: LXI D,EOTMSG ;Print EOT message and abort JMP ABORT READY1: IN SIOSTA ;Read serial status port ANI IFLAG JZ READY ;Wait for character to be received IN SIODAT ;Get received character ANI 7FH ;Mask off bit 7 for ASCII codes CPI 04H JZ ENDXMT ;End transmission CPI 01H JZ XMTREC ;Transmit next record CPI 02H JNZ READY ;Ignore other characters LHLD DATPTR LXI D,-0080H DAD D ;Point at last record SHLD DATPTR INR C ;Go back one record XMTREC: DCR A STA RPTFLG ;Save repeat flag CZ COUNT ;Increase record message if new record XMTRC1: DCR C ;Decrease record count JP XMTRC2 ;More in buffer LDA EOFFLG ORA A JZ READFL ;More in file LXI D,EOFMSG MVI C,9 CALL BDOS ;Print EOF message MVI E,03H CALL XMTBYT ;Send EOF byte JMP BOOT READFL: LXI H,DATBUF SHLD DATPTR ;Point at beginning of data buffer XCHG INR C ;Initialize record count to zero READ: PUSH B PUSH D MVI C,26 CALL BDOS ;Set DMA address LXI D,TFCB MVI C,20 CALL BDOS ;Read next record POP D POP B ORA A JNZ NOMORE ;EOF detected LXI H,0080H DAD D ;Point at next record in buffer XCHG INR C ;Increase record count MVI A,BUFREC CMP C JNZ READ ;Stop at end of extent JMP XMTRC1 NOMORE: MVI A,1 STA EOFFLG ;Set EOF flag JMP XMTRC1 XMTRC2: LDA RPTFLG INR A MOV E,A CALL XMTBYT ;Send response to request for record LHLD DATPTR ;Point at next record to transmit MVI B,80H ;Character count for record MVI D,0 ;Checksun for record XMTRC3: MOV A,M ;Get next byte to send INX H ;Update pointer MOV E,A ;Save in E ADD D MOV D,A ;Update checksum DCR B JNZ XMTRC3 ;More in record MOV E,D CALL XMTBYT ;Send checksum PUSH B MVI C,4 MVI E,00H XMTRC4: CALL XMTBYT ;Send 4 NULs to replace any missed bytes DCR C JNZ XMTRC4 SHLD DATPTR ;Save pointer to next record LXI D,RECMSG MVI C,9 CALL BDOS ;Print record message LDA RPTFLG ORA A JZ NEXTLN ;Skip 'again' if successful first time LXI D,AGAIN MVI C,9 CALL BDOS ;Print 'again' if record repeated NEXTLN: LXI D,CRLF MVI C,9 CALL BDOS ;Print CRLF POP B JMP READY ;Go wait for next prompt to send COUNT: LXI H,RECCNT+4 COUNT1: INR M MVI A,'9' CMP M ;Over 9? RNC MVI M,'0' DCX H MOV A,M CPI ' ' JNZ COUNT1 MVI M,'0' JMP COUNT1 ;Put 0 in message XMTBYT: IN SIOSTA ;Transmit character through serial port ANI OFLAG JZ XMTBYT MOV A,E OUT SIODAT RET ; FNMER: DB 'File name missing',0DH,0AH,'$' FNFER: DB 'File not found',0DH,0AH,'$' EOFMSG: DB 'Transfer complete',0DH,0AH,07H,'$' EOTMSG: DB 'Transfer terminated',0DH,0AH,07H,'$' RECMSG: DB 'Record #' RECCNT: DB ' 0' ;Record # transmitted DB ' transmitted$' AGAIN: DB ' again$' ;Repeated record CRLF: DB 0DH,0AH,'$' ;CRLF sequence DATPTR: DW DATBUF ;Pointcr to next data byte to send EOFFLG: DB 0 ;Flag for EOF read RPTFLG: DB 0 ;Flag for repeated record DATBUF EQU $ ;Data buffer ; END