;********************************* 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 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 & WITH CONSOLE INP CALL MAKEUC ;MAKE UC LD (USROPT),A ;USER OPTION: S/R CP 'S' ;SEND? JP NZ,CHKRCV ;NO CALL DCONIO ;PRINT 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 TO CONS CALL GFNRCV ;RECEIVE FILES ; ; LOOP FOR 'X' (EXIT)/'C' (CONTINUE) ; GETOPT: CALL GETCON ;LD & WITH CONSOLE INP CALL MAKEUC ;MAKE UC CP 'C' JP NZ,CHKXIT CALL DCONIO ;PRINT 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 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 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 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 ('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 ('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 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 (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 (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 TO CONS LD A,B CP 04 ;4 CHARS LEFT? JP NZ,DONPRD ;NO LD E,'.' ;YES, PRINT '.' TO CONS CALL DCONIO ;PRINT 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 (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 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 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 (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 (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 (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 (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 (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 ('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 TO CONS ; ; BAD FN...SEND 'X' ; BADFLN: LD E,'X' CALL SENDE ;SEND CHAR IN (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 (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 (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 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 & WITH CONSOLE INP CALL MAKEUC ;MAKE UC CP 'N' JP NZ,CKOWOK ;NO CALL DCONIO ;PRINT 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 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 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 (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 ('N' -->) JP GETSTX ;WAIT FOR 'stx' ; ;---------------------------------------------- ; ; SEND 'P'roceed TO SENDER ; SNDPCD: LD E,'P' ;P(ROCEED) CALL SENDE ;SEND CHAR IN ('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 TO CONS LD E,'B' CALL SENDE ;SEND CHAR IN ('B'AD -->) JP GETBLK ; ;---------------------------------------------- ; ; LOOP FOR NEXT RECEIVE SECTOR ; CKSMOK: LD E,'.' CALL DCONIO ;PRINT TO CONS LD C,SETDMA LD DE,DBUF CALL BDOS LD C,WRTNXT ;WRITE BLOCK TO DISK CALL DOBDOS ;DO BDOS CALL IN 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 ('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 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 TO CONS LD A,B CP 04 ;AT TYPE? JP NZ,PTFLN1 ;NO LD E,'.' ;YES, PRINT '.' CALL DCONIO ;PRINT TO CONS PTFLN1: INC HL DEC B JP NZ,PRTFLN RET ; ;********************************************** ; ; LD & WITH CONSOLE INP ; GETCON: LD E,0FFH CALL DCONIO ;GET CONS CHAR OR A ;ANY CONSOLE CHAR? JP Z,GETCON ;NO, LD & 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 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 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 DE=FCB ; DOBDOS: LD DE,FCB ; ; DO BDOS CALL IN ; 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 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 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 TO CONS LD E,LF CALL DCONIO ;PRINT 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 ; 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 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 TO CONS ; ; WAIT FOR CONSOLE INPUT ; CONWAT: CALL GETCON ;LD & 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 =CHAR COUNT ; ; LOOP FOR FILENAME CHARS ; GTFNT1: LD HL,FLNLST ;FILENAME LIST BUFFER CALL GETCON ;LD & 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 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+ LD A,C ;GET COUNT CP 14 ;14 CHARS? JP NZ,GTFNT1 ;NO, GET NEXT LD E,BS ;YES, BS ONE CALL DCONIO ;PRINT 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 ; ; =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+ ; PTUSTO: CALL DCONIO ;GET CONS CHAR LD A,E ;GET CHAR CALL MAKEUC ;MAKE UC ADD HL,BC LD (HL),A INC C RET ; ;********************************************** ; ; MAKE 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 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 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