home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
epson
/
epslink.asm
< prev
next >
Wrap
Assembly Source File
|
1994-07-13
|
39KB
|
1,670 lines
;********************************* EPSNLINK.ASM
; EPSON FILINK FOR CP/M SYSTEMS *
;**********************************************
;
; 12/23/84
;
; EPSNLINK (EPSLNK.ASM ON COMPUSERVE) is a communications
; program for CP/M machines that allows them to communicate
; with the EPSON PX-8 GENEVA using it's built-in program
; FILINK.COM permitting file transfer between machines
; using the ROM program in the GENEVA thereby always having
; available on board the GENEVA a means of communications
; without using valuable ram for a separate program. It
; presents the same options in the same manner as FILINK
; making the human interface to each machine the same.
; Provisions are made in this source code to change the
; baud rate of the CP/M machine on entry to those of the
; GENEVA and to re-establish a default baud rate on exit.
; This requires software control of the baud rate on the
; CP/M machine which in this code requires the output of
; several bytes to several different ports. Since my 'BIG'
; CP/M machine has a DCE serial port I use the 724 cable
; between the GENEVA and a switch box which is connected
; to the CP/M port. If your CP/M thinks it is 'DATA
; TERMINAL EQUIPMENT' (DTE) use the 725 cable.
; The program can be assembled using DRI's standard
; ASM.COM. A knowledge of your machines ports & ready
; masks is required. The I/O routines are at the beginning
; of the code ala XMODEM. Any one who has configured one
; of the XMODEM programs should have no problem...novices
; will need some help.
; Community Business Systems
; Jim Dorsey (75765,317)
;
; 12/23/84...CONVERTED FROM Z80 TO 8080 MNEMONICS.
; 12/22/84...MOVE PORT I/O TO PROGRAM FRONT FOR
; USER PATCHING IF NO ACCESS TO SOURCE CODE.
; 12/20/84...RENAME SYMBOLS.
; 10/20/84...INITIAL ASSY.
;
.ORG 0100H
;
JP START
;
;**********************************************
;
; ASCII EQUATES
;
STX .EQUAL 02
ETX .EQUAL 03
EOT .EQUAL 04
ENQ .EQUAL 05
BELL .EQUAL 07
BS .EQUAL 08
TAB .EQUAL 09
LF .EQUAL 0AH
CR .EQUAL 0DH
XOFF .EQUAL 13H
EOF .EQUAL 1AH
ESC .EQUAL 1BH
RUB .EQUAL 7FH
TRUE .EQUAL 0FFFFH
FALSE .EQUAL TRUE+01
;
; CP/M COMMANDS
;
DIRCON .EQUAL 06
DRESET .EQUAL 13
SELDRV .EQUAL 14
OPNFIL .EQUAL 15
CLSFIL .EQUAL 16
SCHFIL .EQUAL 17
SCHNXT .EQUAL 18
DELFIL .EQUAL 19
REDNXT .EQUAL 20
WRTNXT .EQUAL 21
MAKFIL .EQUAL 22
RENFIL .EQUAL 23
SETDMA .EQUAL 26
;
; CP/M ADDRESSES
;
BOOT .EQUAL 0000
CURDSK .EQUAL 0004
BDOS .EQUAL 0005
FCB .EQUAL 005CH
DBUF .EQUAL 0080H
TPA .EQUAL 0100H
;
; PROGRAM DEPENDENT EQUATES
;
WAITIM .EQUAL 5000 ;TIME TO WAIT FOR OTHER CHAR
MAXDRV .EQUAL 'C' ;MAX DRIVE ON SYSTEM
;
;----------------------------------------------
;
; MODEM PORT EQUATES
;
MSTATP .EQUAL 06H ;MODEM STATUS PORT
MDMTBE .EQUAL 04H ;MODEM SEND BIT MASK (TBE)
SNDRDY .EQUAL 00H ;MODEM SEND READY
;00/MDMTBE=RDYHI/RDYLO
MDMRDA .EQUAL 01H ;MODEM RECEIVE BIT MASK (RDA)
RECRDY .EQUAL 00H ;MODEM RECEIVE READY
;00/MDMRDA=RDYHI/RDYLO
MIDATA .EQUAL 04H ;MODEM DATA IN PORT
MODATA .EQUAL 04H ;MODEM DATA OUT PORT
;
;**********************************************
;
; MODEM PORT I/O ROUTINES
;
; RETURN 00/NZ = MODEM INPUT NOT/READY
;
MDMIST: IN A,(MSTATP) ;GET STATUS BYTE
AND MDMRDA ;GET STATUS BIT
XOR RECRDY ;TEST...RECEIVE DATA AVAILABLE?
LD A,00 ;SET NO
RET Z ;NO
DEC A ;SET NZ...
RET ;YES
;
;----------------------------------------------
;
; GET MODEM CHAR
;
GTMCHR: IN A,(MIDATA)
RET
;
;----------------------------------------------
;
; RETURN 00/NZ = MODEM OUTPUT PORT NOT/READY
;
MDMOST: IN A,(MSTATP) ;GET STATUS BYTE
AND MDMTBE ;GET STATUS BIT
XOR SNDRDY ;TEST...TRANSMIT BUF EMPTY?
LD A,00 ;SET NO
RET Z ;NO
DEC A ;SET NZ...
RET ;YES
;
;----------------------------------------------
;
; SEND CHR IN <E> TO MODEM
;
MDMOUT: LD A,E
OUT (MODATA),A
RET
;
;**********************************************
;
; AUTOMATIC BAUD RATE SET PROCEDURE & TABLE
;
; If your system supports software baud rate
; control EPSNLINK can set the system baud rate to
; match the GENEVA's baud rate at run time and
; reset the host system to it's normal setting
; when it terminates. In this system the normal
; baud is 1200 for a printer and the GENEVA is
; set for 9600. Look at 'IF DOBAUD' for the
; manner in which the program uses the following
; table. Also change the 'BITMS1' & 'BITMS2'
; messages to reflect the bauds that you use.
;
DOBAUD .EQUAL FALSE ;IF BAUD SET ACTIVE
;
; BAUD RATE STRINGS
;
;B###: DEFB BYTE COUNT,PORT1,BYTE1,PORT2,BYTE2,etc
;
B110: .BYTE 04,084H,001H,085H,001H,000H,000H
B300: .BYTE 04,084H,001H,085H,004H,000H,000H
B1200: .BYTE 04,084H,001H,085H,008H,000H,000H ;2 STPBITS
B2400: .BYTE 04,084H,001H,085H,010H,000H,000H
B4800: .BYTE 04,084H,001H,085H,020H,000H,000H
B9600: .BYTE 04,084H,011H,085H,088H,000H,000H ;1 STPBIT
B19200: .BYTE 04,084H,011H,085H,010H,000H,000H
;
BAUD1 .EQUAL B9600 ;START BAUD
BAUD2 .EQUAL B1200 ;END BAUD
;
;**********************************************
:START1
;
; NOTE: The following code intercepts the CP/M
; boot vector at 0000H to trap any '^C's for
; an orderly exit after resetting the original
; baud rate. If the host machine detects '^C's
; and reboots from ROM as does the GENEVA a more
; complex boot intercept is required. I have
; code that will intercept a warm start in the
; GENEVA which can give a clue for doing it in
; other ROM based CP/M systems. If you are running
; standard RAM based CP/M the following code should
; be ok.
;
;
;**********************************************
START: LD C,6 ;INIT PORT
LD A,(L03D1) ;BYTE COUNT
LD B,A
LD HL,L03D2 ;03D2H
;
; 8080 EMULATOR FOR Z80 OTIR INSTRUCTION
;
OTIR: LD A,C
LD (PORT+1),A ;MODIFY PGM
;
; LOOP & OUTPUT
;
OUTLOP: LD A,(HL)
INC HL
PORT: OUT (00),A ;MODIFIED ABOVE TO PORT ADDR
DEC B
JP Z,OUTLOP ;NO
JP P,START1 ;NOW START PROGRAM
;
; KAYPRO PORT INIT BYTES
;
L03D1: .BYTE 09H ;# BYTES TO OUTPUT
;
L03D2: .BYTE 00011000B ;RESET
.BYTE 04H ;REGISTER 04
.BYTE 01000111B ;X16 CLOCK, 1 STOP BIT, EVEN PARITY
.BYTE 01H ;REGISTER 01
.BYTE 00000000B ;FOR SAFETY, RESET IT (?)
.BYTE 03H ;REGISTER 03
.BYTE 10000001B ;7 BIT, READ ENABLE
.BYTE 05H ;REGISTER 05
.BYTE 00101000B ;7 BIT, TRANSMIT ENABLE
;
; OLD START LOCATION
START1
: LD HL,(BOOT+01) ;GET BOOT ADDR
INC HL
LD (BOTADR+01),HL ;SAVE IT
LD BC,EXIT ;EXIT ADDR
LD E,(HL) ;GET BOOT VECTOR...
LD (HL),C ;STO EXIT VECTOR...
INC HL
LD D,(HL) ;TO TRAP '^C'S
LD (HL),B
EX DE,HL ;GET VECTOR
LD (BOTVEC+01),HL ;SAVE IT
LD SP,STACK
;
; RESTART ON ESC
;
RESTRT: LD DE,HELLO ;'FILINK (c) Copyright 1983'
CALL PRTDE ;PRINT DE->'$'
LD B,05 ;TIME TO WAIT
LD C,0FFH ;WAIT FOR CONS INP
CALL CKOTHR ;DO TIME OUT
.IFNZ DOBAUD
LD DE,STATMS ;'The RS-232C status is :'
CALL PRTDE ;PRINT DE->'$'
LD DE,BITMS1 ;'bit rate =...'
CALL PRTDE ;PRINT DE->'$'
LD HL,BAUD1 ;POINT TO START BAUD STRING
LD A,(HL) ;GET LGT
OR A ;CLR CRY
RRCA ;LGT/2
LD B,A
INC HL
JP C,OPTLOP ;ODD # NO GOOD
JP Z,OPTLOP ;NO STRING
CALL OUTI ;LOOP & SET BAUD
.ENDIF
;
; LOOP FOR NEXT OPERATION
;
OPTLOP: LD SP,STACK
LD DE,HLPMS1 ;0,0,'Press ESC to restart,'
CALL PRTDE ;PRINT DE->'$'
LD DE,SRMSG ;'Send or Receive (S/R) ? $'
CALL PRTDE ;PRINT DE->'$'
;
; LOOP FOR VALID OPTION
;
BADOPT: CALL GETCON ;LD <A> & <E> WITH CONSOLE INP
CALL MAKEUC ;MAKE <A> UC
LD (USROPT),A ;USER OPTION: S/R
CP 'S' ;SEND?
JP NZ,CHKRCV ;NO
CALL DCONIO ;PRINT <E> TO CONS
CALL GFNSND ;GET FILENAME(S) & SEND
JP GETOPT ;DONE A SEND, GET C/X
;
;----------------------------------------------
;
; NOT S(end)
;
CHKRCV: CP 'R' ;RECEIVE?
JP NZ,BADOPT ;NO, GET 'S'/'R'
CALL DCONIO ;YES, PRINT <E> TO CONS
CALL GFNRCV ;RECEIVE FILES
;
; LOOP FOR 'X' (EXIT)/'C' (CONTINUE)
;
GETOPT: CALL GETCON ;LD <A> & <E> WITH CONSOLE INP
CALL MAKEUC ;MAKE <A> UC
CP 'C'
JP NZ,CHKXIT
CALL DCONIO ;PRINT <E> TO CONS
JP OPTLOP ;LOOP FOR NEXT OPERATION
;
;----------------------------------------------
;
; NOT 'C'ontinue...CHECK FOR EXIT
;
CHKXIT: CP 'X' ;EXIT?
JP NZ,GETOPT ;NO, WAIT FOR 'X'/'C'
CALL DCONIO ;PRINT <E> TO CONS
JP CLCXIT ;CLEAR CONS INP & QUIT
;
;**********************************************
;
; SEND FILE(S)
;
GFNSND: CALL GETFNT ;GET REQ FN.T & PARSE INTO SYSFCB
CALL CRLF ;PRINT CRLF
LD C,SCHFIL
CALL DOBDOS ;DO BDOS CALL IN <C> DE=FCB
CP 04 ;FILE FOUND?
JP C,FILFND ;YES
LD DE,NFILMS ;' File not found$'
CALL PRTDE ;PRINT DE->'$'
JP GFNSND ;LOOK AGAIN
;
;----------------------------------------------
;
; FOUND 1ST FILE...STORE LIST OF FN.T'S TO SEND
;
FILFND: LD HL,FLNLST ;FILENAME LIST BUFFER
LD (FLNPTR),HL ;FILENAME LIST POINTER
;
; LOOP FOR NEXT FILE & ADD TO LIST
;
FILOOP: ADD A,A
ADD A,A
ADD A,A
ADD A,A
ADD A,A ;PNT TO ENTRY...
LD C,A
LD B,00
LD HL,DBUF+01 ;PNT TO DIR REC START
ADD HL,BC ;WITH HL
PUSH HL
EX DE,HL
LD HL,(FLNPTR) ;PNT TO NEXT STO POSN
EX DE,HL
POP HL
LD BC,0011
CALL LDIR ;STORE NAME
PUSH HL
EX DE,HL
LD (FLNPTR),HL ;NEXT STORAGE POSN
EX DE,HL
POP HL
LD A,(FILCNT) ;EXT COUNT
INC A ;+01
LD (FILCNT),A ;EXTENT COUNT
CP 65 ;DONE 64?
JP NC,DONALL ;YES, DONE PRINT '#T$' & CLOSE FILES
LD C,SCHNXT ;NO
CALL DOBDOS ;DO BDOS CALL IN <C> DE=FCB
CP 04 ;FOUND FILE
JP C,FILOOP ;YES, STORE NEXT
LD HL,FLNLST ;RE-INIT...
LD (FLNPTR),HL ;FILENAME LIST POINTER
LD B,10 ;TIME TO WAIT
LD C,'R' ;CHECK FOR 'S'END...(RCR RDY)
CALL CKOTHR ;WAIT/TIME OUT
OR A ;RECEIVER READY?
JP NZ,SENDAG ;YES, SEND 'G'
LD DE,RNRMSG ;'Receiver is not ready.',0,'$'
CALL PRTDE ;PRINT DE->'$'
;
; LOOP & SEND 'R'eady & WAIT FOR 'S'end
;
GETSOK: LD E,'R'
CALL SENDE ;SEND CHAR IN <E> ('R'EADY-->)
CALL CHKABT
CALL MDMIST ;GET OTHER'S INPUT STATUS
JP Z,GETSOK ;OTHER NOT READY
CALL GTOTHR ;WAIT FOR CHR FRM OTHER ('S'END <--)
CP 'S' ;OK TO SEND?
JP NZ,GETSOK ;NO
;
; RECEIVER READY...SEND 'G'ood
;
SENDAG: LD E,'G'
CALL SENDE ;SEND CHAR IN <E> ('G'OOD-->)
;
; LOOP FOR NEXT FILE TO SEND
;
SNDLOP: LD HL,(FLNPTR) ;FILENAME LIST POINTER
LD DE,FCB+01
LD BC,0011
CALL LDIR ;GET NEXT FILENAME
LD (FLNPTR),HL ;FILENAME LIST POINTER
CALL CLRFCB ;CLR SYS FCB 'ex' -> 'nc'
LD C,OPNFIL ;OPEN SEND FCB
CALL DOBDOS ;DO BDOS CALL IN <C> DE=FCB
INC A ;FOUND IT?
LD DE,CRMSG
JP Z,CLFILS ;NO, DONE
;
; CURRENT FN.T OPEN...SEND 'eot'
;
SNDEOT: CALL CHKABT ;QUIT IF TOO LONG
LD E,EOT ;GET 'eot'...FILENAME NEXT
CALL SENDE ;SEND CHAR IN <E> (EOT -->)
CALL GTOTHR ;WAIT FOR CHR FRM OTHER (08/'X' <--)
CP 08 ;SEND FILENAME?
JP NZ,SNDEOT ;NO, SEND 'eot'
CALL CRLF ;YES, PRINT CRLF
LD HL,FCB+01
LD B,11
;
; LOOP, SEND FN.TYP & PRINT TO CONSOLE
;
SNDFNT: LD E,(HL)
CALL SENDE ;SEND CHAR IN <E> (FN.T -->)
CALL GTOTHR ;WAIT FOR CHR FRM OTHER (FN.T <--)
CP E ;SAME?
JP NZ,SAYWHA ;NO, PRINT '?'
LD A,E ;GET CHAR
AND 7FH ;STRIP PARITY
LD E,A ;GET CHAR
CALL DCONIO ;PRINT <E> TO CONS
LD A,B
CP 04 ;4 CHARS LEFT?
JP NZ,DONPRD ;NO
LD E,'.' ;YES, PRINT '.' TO CONS
CALL DCONIO ;PRINT <E> TO CONS
;
; ANY '.' PRINTED TO CONS
;
DONPRD: INC HL
DEC B
JP NZ,SNDFNT ;NOT 11 CHARS, NOT DONE
LD E,ENQ ;END OF FN SEND 'enq'
CALL SENDE ;SEND CHAR IN <E> (ENQ -->)
CALL GTOTHR ;WAIT FOR CHR FRM OTHER (09 <--)
CP 09 ;09...READY FOR FILE?
JP NZ,SNDEOT ;NO...RESEND FN.T
JP PRTSND ;YES, SEND FILE
;
;----------------------------------------------
;
; BAD FILENAME CHAR ECHOED BACK
;
SAYWHA: LD E,'?'
CALL DCONIO ;PRINT <E> TO CONS
JP SNDEOT ;RESEND FN.T
;
;----------------------------------------------
;
; PRINT 'SENDING' & SEND
;
PRTSND: LD DE,SNDMSG ;' Sending $'
CALL PRTDE ;PRINT DE->'$'
;
; LOOP FOR NEXT SECTOR TO SEND
;
SNXTSC: LD C,SETDMA
LD DE,DBUF
CALL BDOS
LD C,REDNXT
CALL DOBDOS ;DO BDOS CALL IN <C> DE=FCB
OR A ;OK READ?
JP NZ,DONSND ;NO, DONE
;
; LOOP & SEND 'stx' & SAME BLOCK
;
SNDSTX: LD E,STX
CALL SENDE ;SEND CHAR IN <E> (STX -->)
CALL GTOTHR ;WAIT FOR CHR FRM OTHER ('N'/'P'ROCEED <--)
CP 'P' ;'P'ROCEED?
JP NZ,SNDSTX ;NO
LD E,'.' ;YES
CALL DCONIO ;TELL CONSOLE
LD HL,DBUF
LD C,00 ;INIT CHKSUM
LD B,128 ;BYTE COUNT
;
; LOOP & SEND 128 BYTES
;
SNDBLK: LD E,(HL) ;GET CHAR
CALL SENDE ;SEND CHAR IN <E> (BLOCK -->)
LD A,E ;GET CHAR
XOR C ;TO CHKSUM
LD C,A ;RESTO CHKSUM
INC HL ;BUMP PNTR
DEC B
JP NZ,SNDBLK ;NOT 128 YET
LD E,C ;GET CHKSUM
CALL SENDE ;SEND CHAR IN <E> (CHKSUM -->)
;
; LOOP & WAIT FOR 'B'/'G'
;
GODBAD: CALL GTOTHR ;WAIT FOR CHR FRM OTHER ('B'/'G' <--)
CP 'B' ;'B'AD?
JP Z,SNDSTX ;YES, RESEND 'stx' & SAME BLOCK
CP 'G' ;NO, 'G'OOD?
JP Z,SNXTSC ;YES, GET NEXT SECTOR
JP GODBAD ;WAIT SOME MORE
;
;----------------------------------------------
;
; END OF FILE
;
DONSND: LD E,ETX ;'etx'...END OF FILE
CALL SENDE ;SEND CHAR IN <E> (ETX -->)
CALL FILCLS ;CLOSE FILE
JP NZ,SENDOK ;OK CLOSE
;
; BAD CLOSE...LOOP FOR CONS CHAR
;
SNDNOK: LD E,0FFH
CALL DCONIO ;GET CONS INP
OR A ;ANY CHAR?
JP Z,SNDNOK ;NO
;
; CURRENT FILE CLOSED
;
SENDOK: LD HL,FILCNT ;FILE COUNT
DEC (HL) ;DONE?
JP NZ,SNDLOP ;NO
LD E,XOFF ;YES, 'xoff'...DONE
CALL SENDE ;SEND CHAR IN <E> (XOFF -->)
CALL CRLF ;PRINT CRLF
LD DE,DONMSG ;'Done',00,EXIT OR CONTINUE'
CALL PRTDE ;PRINT DE->'$'
RET
;
;**********************************************
;
; RECEIVE FILE(S)
;
GFNRCV: CALL GETFNT ;GET REQ FN.T & PARSE INTO SYSFCB
CALL CRLF ;PRINT CRLF
LD C,DRESET
CALL BDOS ;RESET SYSTEM
LD C,SELDRV
LD HL,CURDSK
LD E,(HL)
CALL BDOS ;SELECT CCP DRIVE
LD HL,FCB ;PNT TO REQUESTED FN.T
LD DE,CURFNT ;PLACE TO STORE IT
LD BC,0012
CALL LDIR ;GET REQ FN.T FCB TO CURFNT
LD A,(FNTOUS) ;00/NZ=USE SENT/REQ FN.T
LD (ENTFLG),A ;CUR FN.T TO USE FLAG
LD B,10 ;TIME TO WAIT
LD C,00 ;WAIT FOR 'R' (SNDR RDY) FROM OTHER
CALL CKOTHR ;WAIT/TIME OUT
OR A ;SENDER READY?
JP NZ,SNDSND ;YES
LD DE,SNDRMS ;'Sender $'
CALL PRTDE ;PRINT DE->'$'
LD DE,NRDYMS ;'is not ready.',0,'$'
CALL PRTDE ;PRINT DE->'$'
;
; LOOP FOR 'R'eady FROM SENDER
;
GETRDY: CALL MDMIST ;GET OTHER'S INPUT STATUS
JP Z,GETRDY ;PORT NOT READY
CALL CHKABT
CALL GTOTHR ;WAIT FOR CHR FRM OTHER ('R'EADY <--)
CP 'R' ;'R'EADY?
JP NZ,GETRDY ;NO
;
; SENDER READY...SEND 'S'end TO SENDER
;
SNDSND: LD E,'S'
CALL SENDE ;SEND CHAR IN <E> ('S'END -->)
;
; LOOP FOR 'G' FROM SENDER
;
GTGOOD: CALL CHKABT
CALL GTOTHR ;WAIT FOR CHR FRM OTHER ('G'OOD <--)
CP 'G'
JP NZ,GTGOOD
;
; LOOP FOR NEXT FILE RECEIVE
;
GTFLOP: CALL GTOTHR ;WAIT FOR CHR FRM OTHER (XOFF/EOT <--)
CP XOFF ;'xoff'...END OF XFRS?
JP NZ,GTAFIL ;NO
CALL CRLF ;YES, PRINT CRLF
LD DE,DONMSG ;'Done',00,EXIT OR CONTINUE'
CALL PRTDE ;PRINT DE->'$'
RET ;DONE RECEIVE SESSION
;
;----------------------------------------------
;
; READY TO RECEIVE (NEXT) FILE...SET UP SYSTEM FCB
;
GTAFIL: LD DE,FCB ;SYSTEM FCB
LD HL,CURFNT ;PNT TO REQ FN.T
LD BC,0012
CALL LDIR ;GET IT TO SYSFCB
PUSH AF ;SAVE CHAR
LD A,(ENTFLG) ;CUR FN.T TO USE FLAG
LD (FNTOUS),A ;00/NZ=USE SENT/REQ FN.T
POP AF
CP EOT ;'eot'?
JP Z,FNNEXT ;YES, GET SNDRS FCB TO SNDFCB
LD E,A ;NO, GET CHAR (?)
CALL DCONIO ;PRINT <E> TO CONS
;
; BAD FN...SEND 'X'
;
BADFLN: LD E,'X'
CALL SENDE ;SEND CHAR IN <E> (X -->)
JP GTFLOP ;RESTART FILE TRANSFER
;
;----------------------------------------------
;
; GOT 'eot'...FN.T NEXT
;
FNNEXT: LD E,08 ;SEND 08...RDY FOR FN.T
CALL SENDE ;SEND CHAR IN <E> (08 -->)
LD HL,SNDFCB+01 ;SENDERS FILENAME FCB
LD B,11 ;MAX FN.T CHARS
;
; LOOP & GET FN.T FROM SENDER TO SNDFCB
;
FNLOOP: CALL GTOTHR ;WAIT FOR CHR FRM OTHER (FN.T <--)
CP ' ' ;VALID FN.T CHAR?
JP C,BADFLN ;NO
LD (HL),A ;YES, SAVE IT
LD E,A ;& ECHO
CALL SENDE ;SEND CHAR IN <E> (FN.T -->)
INC HL
DEC B
JP NZ,FNLOOP ;NOT 11 CHARS YET
CALL GTOTHR ;WAIT FOR CHR FRM OTHER (ENQ <--)
CP ENQ ;'enq', END FN?
JP NZ,BADFLN ;NO
;
; GOT SENDERS FN.T & 'enq' MOVE IT TO SYSFCB IF USING SND NAME
;
MOVFCB: LD DE,FCB+01 ;DESTINATION
LD HL,SNDFCB+01 ;SENDERS FILENAME FCB
LD B,11
;
; LOOP & STO FN
;
STOFN: LD A,(FNTOUS) ;00/NZ=USE SENT/REQ FN.T
OR A ;USE SENDERS FN.T?
JP Z,STOFN1 ;YES
LD A,(DE)
CP '?' ;WILD CARD?
JP NZ,STOFN2 ;NO
;
; STORE SENDERS FN.T IN SYSTEM FCB
;
STOFN1: LD A,(HL) ;SENDERS FN.T CHR
LD (DE),A ;TO SYSTEM FCB
;
; SENDERS FN.T CHAR STORED IF USING HIS FN.T
;
STOFN2: INC DE ;BUMP PUT PNTR
INC HL ;& GET PNTR
DEC B
JP NZ,STOFN ;NOT 11 CHARS YET
CALL CRLF ;PRINT CRLF
LD HL,SNDFCB+01 ;SENDERS FILENAME FCB
CALL PRTFNT ;PRINT FN TO CONSOLE
LD A,(FNTOUS) ;00/NZ=USE SENT/REQ FN.T
OR A ;USING SENDERS FN.T?
JP Z,PRTARW ;YES, PRINT ARROW & IT'S NAME
LD HL,FCB+11 ;NO...
LD B,03 ;'TYP' LENGTH
CALL FILSPC ;FILL ANY EMBEDDED SPACES
LD B,08 ;'FILENAME' LENGTH
CALL FILSPC ;FILL ANY EMBEDDED SPACES
JP PRTARW ;PRINT ' ==> '
;
;----------------------------------------------
;
; FILL ANY EMBEDDED FN.T SPACES WITH '$'S
;
FILSPC: LD A,(HL)
DEC HL
CP ' ' ;AT SPACE?
JP NZ,NOTSPC ;NO, SOLID
DEC B ;END OF FN/T?
JP NZ,FILSPC ;NO
RET ;YES
;
;----------------------------------------------
;
; END STRING AT SOLID
;
ENDSTR: LD A,(HL)
DEC HL
CP ' ' ;EMBEDDED SPACE?
JP NZ,NOTSPC ;NO
INC HL ;YES, PNT BACK TO IT
LD (HL),'$' ;FILL IT
DEC HL ;GO ON TO NEXT
;
; ANY EMBEDDED SPACE FILLED WITH '$'
;
NOTSPC: DEC B ;END OF FN/T?
JP NZ,ENDSTR ;NO
RET ;YES, DONE
;
;----------------------------------------------
;
; PRINT ' ==> ' & RECEIVE FN.T
;
PRTARW: LD DE,ARWMSG ;' ==> $'
CALL PRTDE ;PRINT DE->'$'
LD HL,FCB+01 ;PNT TO RECEIVE FILE NAME
CALL PRTFNT ;PRINT FN TO CONSOLE
CALL CLRFCB ;CLR SYS FCB 'ex' -> 'nc'
XOR A ;SET NO OVERWRITE
LD (OVWFLG),A ;00/NZ=NO OVERWRITE
LD C,SCHFIL
CALL DOBDOS ;DO BDOS CALL IN <C> DE=FCB
INC A ;FOUND IT?
JP Z,NEWFIL ;NO
LD DE,OVWMSG ;YES, 'Overwrite (Y/N) ? $'
CALL PRTDE ;PRINT DE->'$'
;
; LOOP FOR FILENAME OVERWRITE OK
;
ASKOVW: CALL GETCON ;LD <A> & <E> WITH CONSOLE INP
CALL MAKEUC ;MAKE <A> UC
CP 'N'
JP NZ,CKOWOK ;NO
CALL DCONIO ;PRINT <E> TO CONS
CALL GETFNT ;GET REQ FN.T & PARSE INTO SYSFCB
JP MOVFCB
;
;**********************************************
;
; CHECK FOR OVERWRITE
;
CKOWOK: CP 'Y' ;OVERWRITE?
JP NZ,ASKOVW ;NO
CALL DCONIO ;PRINT <E> TO CONS
LD HL,OVWFLG ;00/NZ=NO OVERWRITE
LD (HL),01 ;SET OVERWRITE OK
LD DE,SPCMSG ;' $'
CALL PRTDE ;PRINT DE->'$'
;
; ANY OVERWRITE QUESTION TAKEN CARE OF OR NO FILE TO OVERWRITE
;
NEWFIL: LD HL,FCB+09 ;PNT TO 'TYP'
LD DE,SNDFCB+09 ;SENDERS FILENAME FCB
LD B,03
;
; LOOP & STORE RECEIVE TYPE IN SNDFCB 'TYP' LOC
; AND SET SYSTEM FCB TO FILENAME.$$$
;
FILTYP: LD A,(HL) ;GET ORIG TYPE
LD (HL),'$' ;MAKE TYPE = TEMP
LD (DE),A ;SAVE ORIG TYPE
INC HL
INC DE ;BUMP
DEC B
JP NZ,FILTYP
CALL FILDEL ;DELETE ANY TEMP FILE @ FCB
LD C,MAKFIL ;MAKE FN.$$$
CALL DOBDOS ;DO BDOS CALL IN <C> DE=FCB
INC A
LD DE,DIRFMS ;' Directory full$'
JP Z,PRTCLS ;DE->$, CLOSE & WAIT TO CNT
LD A,0FFH
LD (MORFLG),A ;00/NZ=NO/MORE FILES
LD E,09 ;SAY 'READY FOR FILE'
CALL SENDE ;SEND CHAR IN <E> (09 -->)
LD DE,RCVMSG ;' Receiving $'
CALL PRTDE ;PRINT DE->'$'
;
; LOOP FOR BLOCKS
;
GETBLK: LD HL,DBUF ;PLACE TO GET BLOCK
LD C,00 ;INIT CHKSUM
LD D,128 ;BLOCK LGT
;
; LOOP FOR 'stx'S & GET BLOCKS
;
GETSTX: CALL GTOTHR ;WAIT FOR CHR FRM OTHER (STX/ETX <--)
CP STX ;'stx'...ANOTHER BLOCK?
JP Z,SNDPCD ;YES, SEND 'P' TO SENDER
CP ETX ;'etx'...EOF?
JP Z,GOTETX ;YES
LD E,'N'
CALL SENDE ;SEND CHAR IN <E> ('N' -->)
JP GETSTX ;WAIT FOR 'stx'
;
;----------------------------------------------
;
; SEND 'P'roceed TO SENDER
;
SNDPCD: LD E,'P' ;P(ROCEED)
CALL SENDE ;SEND CHAR IN <E> ('P'ROCEED -->)
;
; LOOP & GET 128 BYTES
;
GTABLK: CALL GTOTHR ;WAIT FOR CHR FRM OTHER (BLOCK <--)
LD (HL),A ;STO CHAR
XOR C ;TO CHKSUM
LD C,A ;RESTO IT
INC HL ;PNTR
DEC D ;DONE 128?
JP NZ,GTABLK ;NO
CALL GTOTHR ;WAIT FOR CHR FRM OTHER (CHKSUM <--)
XOR C ;CKSUM OK
JP Z,CKSMOK ;YES
LD E,'B' ;NO
CALL DCONIO ;PRINT <E> TO CONS
LD E,'B'
CALL SENDE ;SEND CHAR IN <E> ('B'AD -->)
JP GETBLK
;
;----------------------------------------------
;
; LOOP FOR NEXT RECEIVE SECTOR
;
CKSMOK: LD E,'.'
CALL DCONIO ;PRINT <E> TO CONS
LD C,SETDMA
LD DE,DBUF
CALL BDOS
LD C,WRTNXT ;WRITE BLOCK TO DISK
CALL DOBDOS ;DO BDOS CALL IN <C> DE=FCB
OR A ;OK WRITE?
JP Z,SNDGOD ;YES
CALL FILCLS ;NO, CLOSE FILE
XOR A
LD (MORFLG),A ;00/NZ=NO/MORE FILES
LD DE,DSKFMS ;' Disk full$'
JP PRTCLS ;DE->$, CLOSE & WAIT TO CNT
;
;**********************************************
;
; GOT OK WRITE
;
SNDGOD: LD E,'G' ;SEND 'G'OOD
CALL SENDE ;SEND CHAR IN <E> ('G'OOD -->)
JP GETBLK
;
;**********************************************
;
; GOT 'etx'...EOF
;
GOTETX: CALL FILCLS ;CLOSE FILE
JP NZ,CLOSOK ;OK CLOSE
;
; LOOP FOR CONSOLE CHAR
;
GTCNCH: CALL CHKABT ;CHECK CONS FOR ABORT
LD E,0FFH
CALL DCONIO ;GET CONS CHAR
OR A ;ANY CHAR?
JP Z,GTCNCH ;NO
;
; OK CLOSE/GOT RESPONSE TO 'CLOSE ERROR'
;
CLOSOK: LD HL,FCB ;RECEIVE FN.$$$
LD DE,SNDFCB ;SENDERS FILENAME FCB
LD BC,0009
CALL LDIR
XOR A
LD (SNDFCB+12),A ;CLEAR EXTENT AND...
LD (SNDFCB+15),A ;RECORD COUNT
LD A,(OVWFLG) ;00/NZ=NO/OVERWRITE
OR A ;OVER WRITE?
JP Z,DELOK ;NO, RENAME TO FN @ SNDFCB
LD C,DELFIL ;YES
LD DE,SNDFCB
CALL BDOS ;DELETE SENDERS FN.T
CP 0FFH ;OK DELETE?
JP NZ,DELOK ;YES
LD DE,DELMSG ;' Delete error$'
JP PRTRST ;PRINT DE->$ & RESTART
;
;**********************************************
;
; OK TO RENAME TO FN @ SNDFCB
;
DELOK: LD HL,SNDFCB ;RECEIVE (SENDERS) FN.T FCB
LD DE,FCB+16
LD BC,0016
CALL LDIR ;TO SYSFCB+16 FOR RENAME
LD C,RENFIL ;FN.$$$ -> FN.TYP
CALL DOBDOS ;DO BDOS CALL IN <C> DE=FCB
INC A
JP Z,RNMERR ;RENAME ERROR...RESTART
XOR A ;SET NO MORE
LD (MORFLG),A ;00/NZ=NO/MORE FILES
JP GTFLOP ;RESTART FILE XFR FOR NEXT FILE
;
;**********************************************
;
; RENAME ERROR...RESTART
;
RNMERR: LD DE,RENMSG ;' Rename error$'
;
; PRINT DE->$ & RESTART
;
PRTRST: CALL PRTDE ;PRINT DE->'$'
CALL CRLF ;PRINT CRLF
CALL FILDEL ;DELETE FILE @ FCB
XOR A
LD (MORFLG),A ;00/NZ=NO/MORE FILES
JP OPTLOP ;RESTART
;
;**********************************************
;
; PRINT FN TO CONSOLE
;
PRTFNT: LD B,11 ;MAX CHARS
;
; LOOP & PRINT NAME
;
PRTFLN: LD A,(HL) ;GET CHAR
AND 7FH ;STRIP PARITY
LD E,A ;GET CHAR
CALL DCONIO ;PRINT <E> TO CONS
LD A,B
CP 04 ;AT TYPE?
JP NZ,PTFLN1 ;NO
LD E,'.' ;YES, PRINT '.'
CALL DCONIO ;PRINT <E> TO CONS
PTFLN1: INC HL
DEC B
JP NZ,PRTFLN
RET
;
;**********************************************
;
; LD <A> & <E> WITH CONSOLE INP
;
GETCON: LD E,0FFH
CALL DCONIO ;GET CONS CHAR
OR A ;ANY CONSOLE CHAR?
JP Z,GETCON ;NO, LD <A> & <E> WITH CONSOLE INP
CP 'C'-40H ;ABORT?
LD DE,ABTMSG ;' Aborted $'
JP Z,PRTQIT ;YES, PRINT DE->$ & QUIT
CP ESC
LD E,A ;STO IN <E>
RET NZ ;NOT ESC
CALL CRLF ;PRINT CRLF
JP RESTRT ;RESTART
;
;**********************************************
;
; CLEAR SYSTEM FCB 'ex' -> 'nc'
;
CLRFCB: LD HL,FCB+12
LD DE,FCB+13
LD (HL),00
LD BC,0023
CALL LDIR
RET
;
;**********************************************
;
; CLOSE FILE, 00/NZ = BAD/OK CLOSE
;
FILCLS: LD C,CLSFIL
CALL DOBDOS ;DO BDOS CALL IN <C> DE=FCB
INC A ;OK CLOSE?
RET NZ ;YES
LD DE,CLSMSG ;' Close error$'
CALL PRTDE ;PRINT DE->'$'
XOR A
RET
;
;**********************************************
;
; DELETE FILE @ FCB
;
FILDEL: LD C,DELFIL
;
; DO BDOS CALL IN <C> DE=FCB
;
DOBDOS: LD DE,FCB
;
; DO BDOS CALL IN <C>
;
DBDOS1: PUSH DE
PUSH HL
CALL BDOS
POP HL
POP DE
RET
;
;**********************************************
;
; DIRECT CONSOLE I/O
;
DCONIO: PUSH BC
LD C,DIRCON
CALL DBDOS1 ;DO BDOS CALL IN <C>
POP BC
RET
;
;**********************************************
;
; PRINT DE->'$' WITH CR'S AT 00'S
;
PRTDE: LD A,(DE)
CP '$'
RET Z
OR A ;TIME FOR CR?
PUSH DE
LD E,A ;GET CHAR
PUSH AF ;SAVE IT
CALL NZ,DCONIO ;PRINT <E> TO CONS
POP AF
CALL Z,CRLF ;PRINT CRLF
POP DE
INC DE
JP PRTDE
;
;**********************************************
;
; PRINT CRLF
;
CRLF: PUSH AF
LD E,CR
CALL DCONIO ;PRINT <E> TO CONS
LD E,LF
CALL DCONIO ;PRINT <E> TO CONS
POP AF
RET
;
;**********************************************
;
; DONE...CRLF & CLOSE FILES
;
DONALL: LD DE,CRMSG
JP CLFILS ;DONE...CLOSE FILES
;
;**********************************************
;
; WAIT FOR CHR FRM OTHER
;
GTOTHR: CALL MDMIST ;GET MODEM INPUT STAT
JP NZ,GTMCHR ;DATA AVAILABLE GET IT
CALL CHKABT ;SEE IF QUIT
JP GTOTHR ;NOTHING THERE
;
;**********************************************
;
; SEND CHAR IN <E>
;
SENDE: PUSH DE ;CHAR TO SEND
LD DE,WAITIM ;TIME TO WAIT
;
; LOOP & WAIT FOR CHAR
;
WAITCH: CALL CHKABT ;CHECK CONS FOR ABORT
CALL MDMOST ;RETURN MODEM OUTPUT STATUS
JP NZ,SNDCHR ;PORT IS READY
DEC DE ;PORT NOT READY...
LD A,D
OR E ;TIME UP?
JP NZ,WAITCH ;NO
LD DE,PNRMSG ;'RS-232C is not ready.',0,'$'
CALL PRTDE ;PRINT DE->'$'
;
; WAIT FOR OUTOK
;
OTOKLP: CALL MDMOST ;RETURN MODEM OUTPUT STATUS
JP NZ,SNDCHR
CALL CHKABT ;CHECK CONS FOR ABORT
JP OTOKLP
;
;----------------------------------------------
;
; MODEM OUT READY, RECOVER CHR & SEND TO MODEM
;
SNDCHR: POP DE ;CHR IN <E>
JP MDMOUT ;SEND IT
;
;**********************************************
;
; PRINT DE->$, CLOSE FILES & WAIT TO CONTINUE
;
PRTCLS: CALL PRTDE ;PRINT DE->'$'
LD A,(MORFLG) ;00/NZ=NO/MORE FILES
OR A
CALL NZ,FILCLS ;CLOSE FILE
XOR A
LD (MORFLG),A ;00/NZ=NO/MORE FILES
LD DE,HLPMS1 ;0,0,'Press ESC to restart,'
CALL PRTDE ;PRINT DE->'$'
LD E,'.'
CALL DCONIO ;PRINT <E> TO CONS
;
; WAIT FOR CONSOLE INPUT
;
CONWAT: CALL GETCON ;LD <A> & <E> WITH CONSOLE INP
JP CONWAT
;
;**********************************************
;
; GET REQUESTED FILENAME & PARSE INTO SYSFCB
;
GETFNT: LD DE,ENTRMS ;'Enter file name $'
CALL PRTDE ;PRINT DE->'$'
LD HL,FLNLST ;FILENAME LIST BUFFER
LD DE,FLNLST+01 ;TO BE USED FOR INPUT
LD (HL),00
LD BC,0014
CALL LDIR ;CLEAR LOCAL FCB
LD HL,FCB
LD DE,FCB+01
LD (HL),' '
LD BC,0011
CALL LDIR ;CLEAR SYSTEM FCB FN.T
XOR A
LD (FCB+12),A ;CLR EX...
LD (FCB+15),A ;RC
LD (FCB+32),A ;& NR
LD BC,0000 ;INIT <C>=CHAR COUNT
;
; LOOP FOR FILENAME CHARS
;
GTFNT1: LD HL,FLNLST ;FILENAME LIST BUFFER
CALL GETCON ;LD <A> & <E> WITH CONSOLE INP
CP CR ;END OF INPUT?
JP Z,ENDINP ;YES
CP BS ;ERASE?
JP Z,GOTBS ;YES
CP RUB ;ERASE?
JP NZ,NORUB ;NO
LD E,BS
;
; GOT BS/RUB...ERASE
;
GOTBS: LD A,C ;GET COUNT
OR A ;0 CHARS?
JP Z,GTFNT1 ;YES
DEC C ;NO, DEC COUNT
ADD HL,BC ;PNT TO CHAR
LD (HL),00 ;KILL IT
CP 14 ;14 CHARS
JP Z,CHRIGN ;YES, ERASE CHAR
CALL DCONIO ;NO, PRINT <E> TO CONS
;
; OVER 14 CHARS IGNORED
;
CHRIGN: LD DE,BSMSG ;' ',BS,'$'
CALL PRTDE ;PRINT DE->'$'
JP GTFNT1 ;GET NEXT
;
;----------------------------------------------
;
; NOT A BS
;
NORUB: CP ' '+01 ;VALID CHAR?
JP C,GTFNT1 ;NO, GET ANOTHER
LD A,C ;GET COUNT
CP 14 ;14 CHARS?
JP NZ,GETMOR ;NO
DEC C ;YES, DEC COUNT
;
; NOT 14 CHARS
;
GETMOR: CALL PTUSTO ;GET CONS CHR, UC & STO @ HL+<C>
LD A,C ;GET COUNT
CP 14 ;14 CHARS?
JP NZ,GTFNT1 ;NO, GET NEXT
LD E,BS ;YES, BS ONE
CALL DCONIO ;PRINT <E> TO CONS
JP GTFNT1 ;GET NEXT
;
;----------------------------------------------
;
; GOT REQUESTED FN.T TO FLNLST...PARSE INTO SYSTEM FCB
;
ENDINP: LD A,(FLNLST+01) ;GET 2ND CHAR
CP ':' ;DRIVE?
LD A,'A'-01
JP NZ,NODRIV ;NO
LD A,(HL) ;YES, GET IT
INC HL
INC HL ;TO FILENAME
LD A,(FLNLST) ;GET DRIVE
CP 'A'-01 ;<'A'
JP Z,SELERR ;DRIVE SELECT ERROR
;
; <A>=00/DRV=DEFAULT/DRIVE
;
NODRIV: SUB 'A'-01 ;OK DRIVE?
JP C,SELERR ;NO, DRIVE SELECT ERROR
CP MAXDRV-'A'+01 ;> MAX DRIVE?
JP NC,SELERR ;YES, DRIVE SELECT ERROR
LD (FCB),A ;STO DRIVE
LD B,08 ;FN LENGTH
LD DE,FCB+01
LD A,(HL)
CP '0' ;<#?
JP C,OKCHAR ;YES
CP '9'+01 ;#?
JP C,BDSPEC ;YES, BAD FILE DESC
;
; LOOP FOR 8 FILENAME CHARS
;
OKCHAR: LD A,(HL) ;GET FN.T CHAR
CP '*' ;WILD CARD?
JP Z,PUT8QS ;PUT 8 '?'S
CP '.' ;END OF FN?
JP NZ,NOTFNE ;NO
LD A,B ;YES
CP 08 ;8 CHARS LEFT?
JP Z,BDSPEC ;YES, BAD FILE DESC
JP DOTYPE ;DONE FILENAME...TO TYP
;
;----------------------------------------------
;
; CHECK FOR END OF STRING
;
NOTFNE: OR A ;NULL...END?
JP NZ,NONULL ;NO
LD A,B ;FN LGT
CP 08 ;STILL 8 CHARS LEFT?
JP NZ,DONFNT ;NO, DONE FN
LD A,(USROPT) ;YES, USER OPTION: S/R
CP 'S' ;NO FILENAME...SEND?
JP Z,NFNINP ;YES, 'NO FILENAME SPECIFIED'
JP DONFNT ;DONE
;
;----------------------------------------------
;
; NOT NULL, STO CHAR
;
NONULL: LD (DE),A ;STO IN SYSFCB
INC DE ;PUT PNTR
INC HL ;GET PNTR
DEC B
JP NZ,OKCHAR ;NOT 8 CHARS YET
;
; LOOP TO NULL/'.'
;
FNDNUL: LD A,(HL)
OR A ;NULL?
JP Z,DONFNT ;YES, DONE
CP '.' ;END OF FN?
JP Z,DOTYPE ;GOT TO TYPE
JP BDSPEC ;BAD FILE DESC
;
;----------------------------------------------
;
; GOT '*'
;
PUT8QS: PUSH BC ;FN/TYP COUNT
;
; LOOP & INSERT '?'S
;
DOQLOP: LD A,'?'
LD (DE),A
INC DE
DEC B
JP NZ,DOQLOP
POP BC ;FN.TP BAL
DEC B
;
; LOOP TO END OF FN
;
EFNLOP: INC HL
LD A,(HL)
CP '.' ;END OF FN?
JP Z,DOTYPE ;YES
OR A ;NULL?
JP Z,DONFNT ;YES, DONE
DEC B
JP NZ,EFNLOP
INC HL
JP FNDNUL ;GET TO NULL/'.'
;
;----------------------------------------------
;
; END OF FN (.)
;
DOTYPE: INC HL
LD B,03 ;MAX TYP CHARS
LD DE,0065H
;
; LOOP FOR 3 TYP CHARS
;
DOTYP1: LD A,(HL)
LD C,A
AND 80H ;GET BIT 7
JP Z,NTSPCL ;NOT SPECIAL
LD A,B
CP 01 ;'Y' BYTE?
JP NZ,BDSPEC ;NO, SYSTEM FILE...BAD FILE DESC
;
; NOT SYSTEM FILE
;
NTSPCL: LD A,C
CP '.'
JP Z,BDSPEC ;BAD FILE DESC
CP '*'
JP Z,DOTPQS ;FILL 'TYP' WITH '?'S
OR A ;NULL?
JP Z,DONFNT ;YES, DONE
LD (DE),A
INC DE
INC HL
DEC B
JP NZ,DOTYP1 ;LOOP FOR 3 CHARS
JP DONTYP ;FINISHED TYPE
;
;----------------------------------------------
;
; FILL 'TYP' WITH '?'S
;
DOTPQS: PUSH BC
;
; LOOP & FILL TYP WITH '?'S
;
DTPQS1: LD A,'?'
LD (DE),A
INC DE
DEC B
JP NZ,DTPQS1 ;LOOP FOR 3 CHRS BALANCE
POP BC
;
; LOOP & FINISH FN.TYP
;
FINTYP: INC HL
DEC B
JP NZ,FINTYP
;
; END OF 'TYP'
;
DONTYP: LD A,(HL) ;GET LAST
OR A ;END WITH NULL?
JP NZ,BDSPEC ;NO, BAD FILE DESC
;
; END OF FN.TYP...RETURN
;
DONFNT: LD A,(FCB+01) ;GET 1ST CHAR
SUB 20H ;-20H=00/NZ=USE SENT/REQ FN.T
LD (FNTOUS),A ;00/NZ=USE SENT/REQ FN.T
XOR A ;INIT...
LD (FILCNT),A ;FILE COUNT
RET
;
;----------------------------------------------
;
; NO FILENAME SPECIFIED
;
NFNINP: LD DE,NNAMSG ;' No file name specified$'
JP PRTERR ;PRINT ERR MSG @ DE
;
;----------------------------------------------
;
; DRIVE SELECT ERROR
;
SELERR: LD DE,DSELMS ;' Drive select error$'
JP PRTERR ;PRINT ERR MSG @ DE
;
;----------------------------------------------
;
; BAD FILE DESC
;
BDSPEC: LD DE,BDFLMS ;' Bad file descriptor$'
;
; PRINT ERROR MSG @ DE AND REGET A FN.T FROM CONSOLE
;
PRTERR: CALL PRTDE ;PRINT DE->'$'
JP GETFNT ;GET REQ FN.T & PARSE INTO SYSFCB
;
;**********************************************
;
; GET CONS CHAR, MAKE UC & STO @ HL+<C>
;
PTUSTO: CALL DCONIO ;GET CONS CHAR
LD A,E ;GET CHAR
CALL MAKEUC ;MAKE <A> UC
ADD HL,BC
LD (HL),A
INC C
RET
;
;**********************************************
;
; MAKE <A> UC
;
MAKEUC: CP 'a'
RET C
CP 'z'+01
RET NC
AND 5FH
RET
;
;**********************************************
;
; C=00/FF/'R'=CHK FOR 'R'/CONS INPT/'S' IN <B> COUNTS
;
CKOTHR: PUSH DE
PUSH HL
;
; LOOP IF OTHER NOT READY
;
CKOTH1: CALL CHKABT ;CHECK CONS FOR ABORT
DEC B ;MAX WAIT?
LD A,B ;SET Z IF YES
JP NZ,CKOTH2 ;NO
JP CKOTH6 ;Z, RETURN OTHER NOT READY
;
;----------------------------------------------
;
; WAIT NOT UP
;
CKOTH2: LD A,C
CP 0FFH ;CHECK CONSOLE?
JP NZ,CKOTH3 ;NO
LD E,0FFH ;YES
PUSH BC
CALL DCONIO ;GET CONS CHAR
POP BC
OR A ;ANY CONS INPUT?
JP Z,CKOTH1 ;NO, RELOOP
JP CKOTH5 ;SET OTHER READY
;
;----------------------------------------------
;
; NOT CONSOLE CHECK
;
CKOTH3: OR A ;CHECK FOR 'S'END?
JP Z,CKOTH4 ;NO
LD E,'R' ;YES
CALL SENDE ;SEND CHAR IN <E>
CALL MDMIST ;INPUT FROM OTHER?
JP Z,CKOTH1 ;NO
CALL GTOTHR ;YES, WAIT FOR CHR FRM OTHER
CP 'S' ;'S'END?
JP NZ,CKOTH1 ;NO
JP CKOTH5 ;SET OTHER READY
;
;----------------------------------------------
;
; RECEIVING...CHK FOR 'R' FROM OTHER
;
CKOTH4: CALL MDMIST ;GET OTHER'S INPUT STATUS
JP Z,CKOTH1 ;NOT READY
CALL GTOTHR ;WAIT FOR CHR FRM OTHER
CP 'R'
JP NZ,CKOTH1 ;NOT READY
;
; SET OTHER IS READY
;
CKOTH5: LD A,0FFH
;
; RETURN OTHER NOT READY
;
CKOTH6: POP HL
POP DE
RET
;
;**********************************************
;
; CLEAR ANY PENDING CONSOLE INPUT CHARS
;
CLRCIN: LD E,0FFH
CALL DCONIO ;GET CONS CHAR
OR A
JP NZ,CLRCIN
RET
;
;**********************************************
;
; CHECK CONS FOR ABORT
;
CHKABT: PUSH BC
PUSH DE
PUSH HL
LD E,0FFH
CALL DCONIO ;DIRECT CONSOLE I/O
CP 'C'-40H
JP Z,EXIT ;ABORT...SAY SO & CLOSE FILES
POP HL
POP DE
POP BC
CP ESC ;RESTART?
JP Z,RESTRT ;YES
RET
;
;----------------------------------------------
;
; ABORT...SAY SO & CLOSE FILES
;
EXIT: CALL CLRCIN ;CLEAR ANY CONS INP CHARS
LD DE,ABTMSG ;' Aborted $'
;
; DONE SEND...CLOSE FILES
;
CLFILS: PUSH DE
LD A,(MORFLG) ;00/NZ=NO/MORE FILES
OR A
JP Z,SNTALL ;DONE ALL
CALL FILCLS ;CLOSE FILE
LD A,(USROPT) ;USER OPTION: S/R
CP 'R'
CALL Z,FILDEL ;BAD CLOSE...DELETE FILE @ FCB
;
; SENT ALL FILES
;
SNTALL: POP DE
;
;**********************************************
;
; PRINT DE->$ & QUIT
;
PRTQIT: CALL PRTDE ;PRINT DE->'$'
CALL CLRCIN ;CLR ANY CONS INP CHARS
LD B,02 ;TIME TO WAIT
LD C,0FFH ;WAIT FOR CONSOLE
CALL CKOTHR ;WAIT/TIME OUT
;
; CLEAR CONS INPUT & QUIT
;
CLCXIT: CALL CLRCIN ;CLR ANY CONS INP CHARS
.IFNZ DOBAUD
LD DE,STATMS ;0,0,'The RS-232C status is :$'
CALL PRTDE ;PRINT DE->'$'
LD DE,BITMS2 ;' bit rate = 1200'
CALL PRTDE ;PRINT DE->'$'
LD HL,BAUD2 ;POINT TO END BAUD STRING
LD A,(HL) ;GET LGT
OR A ;CLR CRY
RRCA ;LGT/2
LD B,A
INC HL
JP C,DONBD2 ;ODD # NO GOOD
JP Z,DONBD2 ;NO STRING
CALL OUTI ;LOOP & SET BAUD
.ENDIF
BOTADR: LD HL,0000 ;GET BOOT ADDR
BOTVEC: LD DE,0000 ;BOOT VECTOR
LD (HL),E
INC HL
LD (HL),D ;RESTORE IT
DONBD2: JP BOOT
;
;**********************************************
;
; 8080-Z80 SUPPORT ROUTINES
;
; DO Z80 'LDIR'
;
LDIR: PUSH AF
;
; LOOP & TRANSFER
;
LDIR1: LD A,C
OR B
JP Z,POPRET
LD A,(HL)
LD (DE),A
DEC BC
INC DE
INC HL
JP LDIR1
;
; DONE, RECOVER AF
;
POPRET: POP AF
RET
;
;----------------------------------------------
;
; DO Z80 'OUTI'
;
OUTI: PUSH AF
;
OUTI1: LD A,(HL) ;GET PORT ADDRESS
LD (OUTPRT),A ;STORE IT
INC HL ;TO COMMAND BYTE
LD A,(HL) ;GET IT
OUTPRT .EQUAL $+1 ;PORT LOCATION
OUT (00),A ;SEND IT
INC HL ;NEXT PORT ADDR
DEC B ;DONE ALL?
JP NZ,OUTI1 ;NO
POP AF
RET
;
;**********************************************
;
; MESSAGES
;
HELLO: .BYTE 00,'EPSNLINK by Community Business Systems'
.BYTE ' 12/23/84',00
.BYTE 'A file transfer program to communicate with'
.BYTE ' the EPSON PX-8 and QX-10$'
;
.IFNZ DOBAUD
STATMS: .BYTE 0,0,'The RS-232C status is :$'
;
BITMS1: .BYTE ' bit rate = 9600'
.BYTE ' data bits = 8'
.BYTE ' stop bits = 1$'
;
BITMS2: .BYTE ' bit rate = 1200'
.BYTE ' data bits = 8'
.BYTE ' stop bits = 2',0,'$'
.ENDIF
;
HLPMS1: .BYTE 0,0,'Press ESC to restart,'
.BYTE ' or CTRL/C to exit from EPSNLINK$'
SRMSG: .BYTE 0,'Send or Receive (S/R) ? $'
SNDRMS: .BYTE 0,'Sender $'
RNRMSG: .BYTE 0,'Receiver '
NRDYMS: .BYTE 'is not ready.',0,'$'
ENTRMS: .BYTE 0,'Enter file name $'
DONMSG: .BYTE 'Done',00,'eXit or Continue'
.BYTE ' (X/C) ? $'
NNAMSG: .BYTE 0,' No file name specified$'
NFILMS: .BYTE ' File not found$'
SNDMSG: .BYTE ' Sending $'
ABTMSG: .BYTE 0,0,' Aborted $'
DIRFMS: .BYTE 0,' Directory full$'
SPCMSG: .BYTE ' $'
RCVMSG: .BYTE ' Receiving $'
ARWMSG: .BYTE ' ==> $'
OVWMSG: .BYTE 0,'Overwrite (Y/N) ? $'
DSKFMS: .BYTE 0,' Disk full$'
RENMSG: .BYTE 0,' Rename error$'
DELMSG: .BYTE 0,' Delete error$'
CLSMSG: .BYTE 0,' Close error$'
DSELMS: .BYTE 0,' Drive select error$'
BDFLMS: .BYTE 0,' Bad file descriptor$'
PNRMSG: .BYTE 0,'RS-232C is not ready.',0,'$'
BSMSG: .BYTE ' ',BS,'$'
CRMSG: .BYTE 0,'$'
FNTOUS: .BYTE 00 ;00/NZ=USE SENT/REQ FN.T
ENTFLG: .BYTE 00 ;CUR FN.T TO USE FLAG
USROPT: .BYTE 00 ;USER OPTION: S/R
MORFLG: .BYTE 00 ;00/NZ=NO/MORE FILES
OVWFLG: .BYTE 00 ;00/NZ=NO/OVERWRITE
FILCNT: .BYTE 00 ;# OF FILES TO SEND
FLNPTR: .WORD FLNLST ;FILENAME LIST POINTER
;
STACK .EQUAL (($+100H)/100H*100H)+64
;
CURFNT .EQUAL STACK ;'DRFILENAMTYP'...REQ FN.T
;
SNDFCB .EQUAL CURFNT+12 ;SENDERS FN.T FCB
;
FLNLST .EQUAL SNDFCB+36 ;LIST OF FILENAMES TO SEND
;& FN.T INPUT BUFFER
;
.END
MSG: .BYTE 0,0,' Aborted $'
DIRFMS: .BYTE 0,' Directory full$'
SPCMSG: .BYTE ' $'
RCVMSG: