home *** CD-ROM | disk | FTP | other *** search
- ;
- ; UKM7
- ;This program was originally written in 1977 by Ward Christensen.
- ;Ward's comments were removed, Terminal File and Batch Mode were
- ;added in 1980 by Mark Zeiger and James Mills. The original CRC
- ;checks were added by Paul Hansknecht in June 1981.
- ;Improved terminal file facilities, menus and a general tidy
- ;up of a very untidy program, removal of all modem dependent
- ;features, many bugs and adaptation for the UK CP/M Users
- ;Group Library by David Back. 4 May 1983.
- ;Version 1.5 includes many additional facilities, including a
- ;printer buffer, active toggling of terminal and secondary
- ;options, faster CRC's etc. David Back. 21 February 1984
- ;
- ;The file exchange protocols are compatible with the MODEMX
- ;series of programs in the US CP/M UG Library.
- ;UKM7 is compatible with CP/M 1.4 and CP/M 2.2.
- ;
- FALSE EQU 0
- TRUE EQU 0FFH
-
- ORG 100H
- ;********* SYSTEM DEPENDENT OVERLAY **************
- ;**** This is a general purpose overlay applicable to many systems ****
- JMP 300H ;absolute start of program
-
- MODCTLP EQU 0ECH ;MODEM CONTROL PORT
- MODDATP EQU 0EDH ;MODEM DATA PORT FOR SEND
- MODDRCV EQU 0EDH ;MODEM DATA PORT FOR RECEIVE
- MSNDB EQU 1 ;MODEM SEND BIT (XMIT BUFF EMPTY)
- MSNDR EQU 1 ;MODEM SEND READY
- MRCVB EQU 2 ;MODEM RECEIVE BIT (DAV)
- MRCVR EQU 2 ;MODEM RECEIVE READY
- BAUD EQU 2 ;enter 1 for 1X, or 2 for 16X, or 3 for 64X
- ;It is important not to alter the addresses of labels below
- OLID: DB 1 ;overlay identifier
- TWIDTH: DB 70 ;max. terminal columns
- FASTCLK: DB TRUE ;4 MHz or greater processor speed
- BAKUPBYTE: DB TRUE ;true=make .BAK file
- XPRFLG: DB TRUE ;true=menu initially off
- SAVCCP: DB TRUE ;true=do not overwrite CCP
- SAVEFLG: DB TRUE ;true=terminal filesave initially on
- ECHOFLG: DB FALSE ;true=terminal echo initially on
- INITFLG: DB FALSE ;true=modem port already initialised
- ANSBAK: DB TRUE ;true=answerback on ^E
- INMODCTLP: IN MODCTLP ;get port status
- RET
- DB 0 ;space for memory mapped I/O's
- OUTCTLP: OUT MODCTLP ;control
- RET
- DB 0
- OUTMODDATP: OUT MODDATP ;send data
- RET
- DB 0
- ANISND: ANI MSNDB ;bit to test for send ready
- RET
- CPISND: CPI MSNDR ;value of send bit when ready
- RET
- INMODDATP: IN MODDRCV ;get data
- RET
- DB 0
- ANIRCV: ANI MRCVB ;bit to test for receive ready
- RET
- CPIRCV: CPI MRCVR ;value of receive bit when ready
- RET
- LOGMSSG: DB 'David;Back;Shepperton Middx',CR,LF,0
- ORG 150H ;do not alter this org
- ;The routine below should work in most systems which use an 8251 USART
- ;Modem port must be initialised for 8 data bits and no parity
- INITMOD:LXI D,CPMS ;finish signon message
- MVI C,9
- CALL BDOS
- LDA INMODCTLP+1
- CALL HEXPRT
- LXI D,DPMS
- MVI C,9
- CALL BDOS
- LDA OUTMODDATP+1
- CALL HEXPRT
- LXI D,HMS
- MVI C,9
- CALL BDOS
- LDA INITFLG
- ORA A ;return if already initialsed
- RNZ
- MVI A,0EH
- CALL OUTCTLP ;force command instruction
- PUSH PSW
- POP PSW
- MVI A,40H
- CALL OUTCTLP ;internal reset
- PUSH PSW
- POP PSW
- MVI A,6CH OR (BAUD AND 3)
- CALL OUTCTLP ;8 bits no parity
- PUSH PSW
- POP PSW
- MVI A,37H ;modem connected
- CALL OUTCTLP
- CALL INMODDATP
- CALL INMODDATP ;clear buffers
- RET
- ;necessary because location of HEXO is not fixed
- HEXPRT: PUSH PSW
- RAR
- RAR
- RAR
- RAR
- CALL NIB
- POP PSW
- NIB: ANI 0FH
- CPI 10
- JC NU
- ADI 7
- NU: ADI '0'
- MOV E,A
- MVI C,2
- CALL BDOS
- RET
- CPMS: DB 'Control port=0$'
- DPMS: DB 'H Data port=0$'
- HMS: DB 'H',CR,LF,'$'
- ;********** END OF OVERLAY AREA ************
-
- DBUFSIZ EQU 2 ;S & R BUFFER SIZE IN KBYTES
- ;2K is the normally accepted optimum
- RING EQU 8 ;print ring buffer size, K bytes
- ERRLIM EQU 10 ;NUMBER OF TIMES TO RETRY
- ;SEND/RECEIVE ERRORS BEFORE QUIT
- COMPUT EQU 'C'-40H ; ^C = Computer mode
- DMENU EQU 'D'-40H ; ^D = display terminal menu
- EXITCHR EQU 'E'-40H ; ^E = exit terminal mode
- TRANCHR EQU 'T'-40H ; ^T = TRANSFER FILE
- SAVECHR EQU 'Y'-40H ; ^Y = memory save toggle
- PRNCHR EQU 'P'-40H ; ^P = printer toggle
- EXTCHR EQU '^'-40H ;SEND NEXT CHAR LITERALLY
- SAVON EQU 12H ;^R Terminal filesave on
- SAVOFF EQU 14H ;^T Terminal filesave off
- ;
- ;PROGRAM FOLLOWING IS NOT SYSTEM DEPENDENT,
- ;PLEASE DO NOT INTRODUCE ANY SYSTEM DEPENDENT FEATURES BELOW
- ;
- XOFF EQU 'S'-40H ; ^S = XOFF CHARACTER
- XON EQU 'Q'-40H ; ^Q = XON CHARACTER
- CAN EQU 'X'-40H ; ^X = CANCEL SEND/RECEIVE
- EOFCHAR EQU 'Z'-40H ; ^Z = END OF FILE
- ENQ EQU 5 ; ^E Auto ID
- SOH EQU 1 ; START OF HEADER
- EOT EQU 4 ; END OF TEXT
- ACK EQU 6 ; ACKNOWLEDGE
- NAK EQU 15H ; NOT ACKNOWLEDGE
- CRC EQU 'C' ;USED TO RQST CRC INSTEAD OF CKSUM
- BDNMCH EQU 75H ; BAD NAME MATCH
- LF EQU 10 ; LINEFEED
- CR EQU 13 ; CARRIAGE RETURN
- BELL EQU 7 ; BELL CHARACTER
- WRCON EQU 2
- LIST EQU 5 ;printer o/p
- PRINT EQU 9 ;string o/p to console
- OPEN EQU 15
- CLOSE EQU 16
- SRCHF EQU 17
- SRCHN EQU 18
- ERASE EQU 19
- READ EQU 20
- WRITE EQU 21
- MAKE EQU 22
- REN EQU 23
- STDMA EQU 26
- FILSIZ EQU 35
- BDOS EQU 5
- FCB EQU 5CH
- FCBEXT EQU FCB+12
- FCBRNO EQU FCB+32
-
- ORG 300H ;do not alter this org
- LXI H,0
- DAD SP ;GET CP/M'S STACK
- SHLD STAK ;SAVE IT
- LXI SP,STAK ;LOCAL STACK
- CALL INITADR ;INITIALIZE BIOS ADDRESSES
- CALL INITCRC ;initialise crc table
- CALL ILPRT
- DB 'UK MODEM7 D.R. Back Version 1.5',CR,LF,0
- CALL INITMOD ;INITIALISE MODEM PORTS
- LXI H,80H
- LXI D,CMDBUF+1
- MVI B,80H
- CALL MOVE ;default buffer to cmdbuf
- MVI A,TRUE
- STA NFILFLG
- CALL PROCOPT ;PROCESS CONTROL OPTIONS
- RESTART:LDA OPTION ;GET MAIN OPTION
- CPI ' ' ;NO OPTION SPEC'D?
- JZ MENU
- CPI 'M' ;MENU
- JZ MENU2
- CALL MOVEFCB ;MOVE 2ND HALF FCB TO FIRST HALF
- CALL INMODDATP ;GOBBLE UP GARBAGE..
- CALL INMODDATP ;..CHARACTERS ON LINE
- LDA OPTION ;PROCESS MAIN OPTION
- CPI 'T' ;TERMINAL MODE?
- JZ DSKSAVE
- CPI 'S' ;SEND A FILE?
- JZ SENDFIL
- CPI 'R' ;RECEIVE A FILE?
- JZ RCVFIL
- MENU: LXI SP,STAK ;RESTORE STACK
- LXI H,RESTSN ;RESTORE SECTOR NUMBERS..
- LXI D,SECNOB ;..FOR NEW FILE TRANSFER.
- MVI B,SECNOE-SECNOB
- CALL MOVE
- LXI H,RESTROPT ;RESTORE OPTION TABLE
- LXI D,OPTBL
- MVI B,OPTBE-OPTBL
- CALL MOVE
- LDA LSTFLG
- STA LSTRET ;save print toggle
- MVI A,0
- STA LSTFLG ;printer off
- STA MFFLG1 ;RESET MFACCESS ROUTINE..
- CMA ;..AND MULTI TRANS IN CASE..
- STA FSTFLG ;..OF ABORT.
- MENU1: LDA XPRFLG ;TEST IF MENU SHOULD BE SHOWN
- ORA A
- JNZ XPRT
- MENU2: CALL ILPRT
- DB CR,LF
- DB 'SYNTAX: primaryoption[secondaryoptions] [d:][filename] [ afn]'
- DB CR,LF,CR,LF
- DB ' PRIMARY OPTIONS:',CR,LF
- DB ' S Send binary files, afn list',CR,LF
- DB ' R Receive binary files, drive:',CR,LF
- DB ' T Terminal mode. Terminal filename optional',CR,LF
- DB ' DEL Delete Terminal file',CR,LF
- DB ' DIR Directory list, afn optional',CR,LF
- DB ' CPM Exit to CP/M.',CR,LF
- DB ' X Expert, toggle menus on/off',CR,LF
- DB ' M Menu display',CR,LF,CR,LF
- DB ' SECONDARY OPTIONS: (for primary options S and R)'
- DB CR,LF
- DB ' N Non batch mode, send or receive file'
- DB CR,LF
- DB ' Q Quiet mode, remote system Send/Receive',CR,LF
- DB 'S,R,V Monitor data Sent, Received or View file',CR,LF
- DB ' T Go to Terminal mode after file transfers',CR,LF,0
- XPRT: CALL ILPRT
- DB CR,LF,0
- MVI C,25 ;CURRENT DISK FUNCTION
- CALL BDOS
- ADI 41H ;MAKE ASCII
- CALL CTYPE
- CALL ILPRT
- DB ' ==>>',0
- LXI D,CMDBUF ;ENTER COMMAND
- CALL INBUFF
- CALL CRLF
- LXI D,CMDBUF+2 ;POINT TO COMMAND
- CALL ILCOMP
- DB 'CPM',0
- JNC EXIT
- CALL ILCOMP
- DB 'DIR',0
- JNC DIR
- CALL ILCOMP
- DB 'DEL',0
- JNC NEWFILE
- LXI D,CMDBUF
- LXI H,FCB
- CALL CPMLINE ;LOAD FCB
- CALL PROCOPT
- JMP RESTART
-
- DIR: CALL DIRLST
- JMP XPRT
-
- EXIT: LDA NFILFLG
- CPI TRUE
- CNZ TFILWR ;write and close terminal file
- LXI D,80H
- MVI C,STDMA
- CALL BDOS
- LHLD STAK
- SPHL
- LDA SAVCCP
- ORA A
- JZ 0 ;WARM BOOT
- RET ;to CCP
-
- NEWFILE:LDA NFILFLG
- CPI TRUE
- JZ MENU1 ;IF NO FILE, DON'T ERASE
- LXI D,FCB3
- MVI C,ERASE
- CALL BDOSRT
- MVI A,TRUE ;DO NOT ALLOW TERMINAL..
- STA NFILFLG ;..SAVE SINCE NO FILE..
- JMP MENU1
- ;======================================
- ;TERMINAL ROUTINE ALLOWING MEMORY SAVE
- DSKSAVE:LDA FCB+1 ;FIRST CHAR OF FILENAME
- CPI ' ' ;FILE SPEC'D
- LHLD HLSAVE
- JZ TERM1
- LDA NFILFLG
- CPI TRUE
- CNZ TFILWR ;write & close existing file
- CALL TFLERAS
- CALL MOVE2 ;move FCB to FCB3
- LXI D,FCB3
- MVI C,MAKE
- CALL BDOS
- INR A
- JNZ TERM0
- CALL ILPRT
- DB 'Can''t make file',CR,LF,0
- JMP TERM1
- TERM0: LXI H,BOTTRAM
- SHLD HLSAVE
- MVI A,FALSE
- STA NFILFLG
- STA CTRLR ;cancel any previous ^R
- TERM1: LDA LSTRET
- STA LSTFLG ;restore printer toggle
- LDA XPRFLG
- ORA A
- JNZ TERM3
- TERM2: LDA NFILFLG
- CPI TRUE
- JZ NOTFIL
- PUSH H
- LXI H,FCB3
- LXI D,TFILE
- MOV A,M
- ORA A
- JNZ PUTDRV
- MVI A,' '
- STAX D
- INX D
- JMP NAME1
- PUTDRV: ADI 40H
- STAX D
- INX D
- MVI A,':'
- NAME1: STAX D
- INX D
- INX H
- MVI B,8
- CALL MOVE
- INX D
- MVI B,3
- CALL MOVE
- POP H
- CALL ILPRT
- DB CR,LF,' ^Y Terminal file '
- TFILE: DB ' toggle save on/off '':'' =on',0
- NOTFIL: CALL ILPRT
- DB CR,LF
- DB ' ^P Printer, toggle on/off',CR,LF
- DB ' ^T Transfer (Send) ASCII file without checks',CR,LF
- DB ' ^X Abort transfer initiated above',CR,LF
- DB ' ^C Computer mode, toggle echo on/off',CR,LF
- DB ' ^^ Send following character literally',CR,LF
- DB ' ^E Exit to command menu',CR,LF
- DB ' ^D Display terminal menu',CR,LF,0
- TERM3: LDA NFILFLG
- ORA A
- JNZ TERM
- LDA SAVEFLG
- ORA A
- JZ TERM
- MVI A,':' ;indicate filesave is on
- CALL TYPE ;dont print or inc col count
- TERM: CALL STAT ;o/p to print & check keypress
- JZ TERML ;NO, CHECK LINE
- CALL KEYIN ;GET CHAR FROM KBD
- MOV B,A
- LDA EXACFL
- ORA A
- MVI A,FALSE
- STA EXACFL
- MOV A,B
- JNZ NOTOG
- CPI EXITCHR ;^E?
- JZ MENU ;YES, RETURN TO MENU
- CPI COMPUT ;^C Computer mode with echo
- JNZ NOECH
- LDA ECHOFLG
- CMA
- STA ECHOFLG
- JMP TERML
- NOECH: CPI DMENU ;^D display terminal menu
- JZ TERM2
- CPI EXTCHR ;literal
- JZ EXTFLG
- CPI TRANCHR ;TEST FOR TRANSFER REQUEST (^T)
- CZ TRANSFER ;SEND-A-FILE
- JZ TERM3 ;LOOP
- CPI PRNCHR
- JNZ NOTLST
- LDA LSTFLG
- CMA
- STA LSTFLG
- JMP TERML
- NOTLST: CPI SAVECHR
- JNZ NOTOG
- LDA NFILFLG ;DO NOT ALLOW SAVE IF..
- CPI TRUE ;..THIS FLAG IS SET.
- JZ TERML
- LDA SAVEFLG
- CMA
- STA SAVEFLG
- JMP TERM3
- EXTFLG: MVI A,TRUE
- STA EXACFL
- JMP TERML
- NOTOG: MOV B,A
- LDA ECHOFLG
- ORA A
- MOV A,B
- JZ TSEND
- CPI LF
- JZ TERML ;ignore LF
- CALL OUTMODDATP
- CALL CTYPE ;local echo
- PUSH PSW
- CALL MSAVE ;local save in terminal file
- POP PSW
- CPI CR
- JNZ TERML
- MVI A,LF
- CALL CHRSND ;send to remote
- CALL CTYPE ;append LF
- CALL MSAVE
- JMP TERML
- TSEND: CALL OUTMODDATP
- TERML: CALL INMODCTLP
- CALL ANIRCV
- CALL CPIRCV
- JNZ TERM
- CALL INMODDATP
- ANI 7FH ;strip parity
- JZ TERM ;ignore null
- CPI ENQ ;auto logon
- JNZ NOLOG
- LDA ANSBAK
- ORA A
- JZ TERM
- LXI D,LOGMSSG
- NXCHAR: LDAX D
- INX D
- ORA A
- JZ TERM
- CALL CHRSND ;send to remote
- MOV B,A
- LDA ECHOFLG
- ORA A
- MOV A,B
- JNZ CHRSAV
- PUSH D
- MVI D,0 ;init count
- CALL INMODEM ;wait 100ms for echo
- DCR D
- POP D
- JNZ NXCHAR
- CHRSAV: CALL CTYPE
- CALL MSAVE
- JMP NXCHAR
- NOLOG: CPI SAVON ;auto filesave on
- JNZ TRYT
- LDA SAVEFLG
- ORA A
- JNZ TERM ;save already on
- MVI A,TRUE
- STA SAVEFLG ;turn on save
- STA CTRLR ;remember
- JMP TERM3
- TRYT: CPI SAVOFF ;auto save off
- JNZ ONWRD
- LDA CTRLR
- ORA A
- JZ TERM ;turn save off only
- MVI A,FALSE ;if it was turned on
- STA SAVEFLG ;by ^R from remote
- STA CTRLR
- JMP TERM
- ONWRD: MOV B,A
- LDA ECHOFLG
- ORA A
- MOV A,B
- JZ TERM5
- CPI LF
- JZ TERM ;ignore LF
- CALL OUTMODDATP ;echo to distant terminal
- CPI CR
- JNZ TERM5
- CALL CTYPE
- CALL MSAVE ;save in terminal file
- MVI A,LF
- CALL CHRSND ;send LF
- TERM5: CALL CTYPE
- CALL MSAVE ;save in terminal file
- JMP TERM
- CTRLR: DB FALSE
- LASTB1: DB 0
- LASTB2: DB 0
- ;=========================================
- ;SEND A CP/M FILE
- SENDFIL:LDA BATCHFLG ;CHECK IF MULTIPLE FILE..
- ORA A ;..MODE IS SET.
- JZ SENDC1
- MVI A,TRUE ;INDICATE BATCH SEND
- STA SENDFLG
- LDA FSTFLG ;IF FIRST TIME THRU..
- ORA A ;..SCAN THE COMMAND LINE..
- CNZ TNMBUF ;..FOR MULTIPLE NAMES.
- CALL SENDFN ;SENDS FILE NAME TO RECEIVER
- JNC SENDC2 ;CARRY SET MEANS NO MORE FILES.
- MVI A,0 ;STOP BATCH..
- STA BATCHFLG ;..MODE OPTION.
- MVI A,EOT ;FINAL XFER END
- CALL SEND
- JMP DONE
- SENDC1: LDA FCB+1
- CPI ' '
- JZ BLKFILE
- CALL AMBGTS ;test for ambiguous filename
- SENDC2: CALL CNREC ;GET NUMBER OF RECORDS
- CALL OPENFIL
- MVI E,80
- CALL WAITNAK ;if a 'C' is received instead of NAK
- SENDLP: CALL RDSECT ;then CRC mode is enabled
- JC SENDEOF
- CALL INCRSNO
- XRA A
- STA ERRCT
- SENDRPT:CALL SENDHDR
- CALL SENDSEC
- LDA CRCFLG
- ORA A
- CZ SENDCRC
- CNZ SENDCKS
- CALL GETACK
- JC SENDRPT
- JMP SENDLP
- SENDEOF:MVI A,EOT
- CALL SEND
- CALL GETACK
- JC SENDEOF
- JMP DONE
- ;===============================
- ;RECEIVE A FILE
- RCVFIL: XRA A ;default to CRC mode
- STA CRCFLG
- RCV1FIL:LDA BATCHFLG ;CHECK IF MULT..
- ORA A ;..FILE MODE.
- JZ RCVC1
- MVI A,FALSE ;FLAG WHERE TO RETURN..
- STA SENDFLG ;..FOR NEXT FILE TRANS.
- CALL GETFN ;GET THE FILE NAME.
- JNC RCVC2 ;CARRY SET MEANS NO MORE FILES.
- MVI A,0 ;STOP BATCH..
- STA BATCHFLG ;..MODE OPTION.
- JMP DONE
- RCVC1: LDA FCB+1 ;MAKE SURE FILE IS NAMED
- CPI ' '
- JZ BLKFILE
- JMP RCVC3
- RCVC2: CALL CKCPM2
- CALL CKBAKUP
- RCVC3: CALL ERASFIL
- CALL MAKEFIL
- LDA QFLG
- ORA A
- JZ RCVFST
- RCVC4: CALL ILPRT ;first comment
- DB 'File open, ready to receive',CR,LF,0
- RCVFST: LDA CRCFLG
- ORA A
- MVI A,NAK
- JNZ RCV2FIL
- MVI A,CRC ;indicate to Tx that CRC is wanted
- RCV2FIL:CALL SEND ;by sending a 'C' instead of NAK
- LDA QFLG
- ORA A
- JZ RCVLP
- LDA CRCFLG
- ORA A
- JNZ RCVNAKM ;if in CRC mode
- CALL ILPRT ;then say so
- DB 'CRC in effect',cr,lf,0
- JMP RCVLP
- RCVNAKM:CALL ILPRT ;else say checksum mode
- DB 'Checksum in effect',cr,lf,0
- RCVLP: CALL RCVSECT
- JC RCVEOT
- CALL WRSECT ;sends CAN if error
- CALL INCRSNO
- CALL SENDACK
- JMP RCVLP
- RCVEOT: CALL WRBLOCK ;sends CAN if error
- CALL SENDACK
- CALL CLOSFIL
- JMP DONE
- ;===================================
- BLKFILE:CALL ILPRT ;fatal error
- DB CR,LF,'No file specified',CR,LF,BELL,0
- JMP MENU
- ;===============================
- DONE: LDA BATCHFLG
- ORA A
- JZ DONETB
- LDA QFLG
- ORA A
- JZ NMSTRNS
- LXI H,FCB+1 ;PUT FILE NAME IN..
- LXI D,FTRNMSG ;..SPACES IN MESSAGE..
- MVI B,8 ;..BELOW.
- CALL MOVE
- INX D ;PUT FILE TYPE AFTER..
- MVI B,3 ;..SKIPPING ONE SPACE..
- CALL MOVE ;..BELOW.
- CALL ILPRT ;final comment
- DB CR,LF
- FTRNMSG:DB ' transferred',CR,LF,CR,LF,0 ;13 SPACES
- NMSTRNS:LDA FCB ;SAVE DRIVE NO.
- STA DISKNO
- LXI H,FCB ;BLANK OUT FILE CONTROL BLOCKS
- CALL INITFCBS
- LDA DISKNO ;PUT DRIVE NUMBER BACK
- STA FCB
- LXI H,RESTSN ;RESTORE SECTOR NUMBERS..
- LXI D,SECNOB ;..FOR NEW FILE TRANSFER.
- MVI B,SECNOE-SECNOB ;ROUTINE ALSO DONE IN MENU.
- CALL MOVE
- LDA SENDFLG ;GOES TO EITHER SEND OR..
- ORA A ;..RECEIVE FILE, DEPENDING..
- JNZ SENDFIL ;..UPON WHICH ROUTINE SET..
- JMP RCV1FIL ;..THE FLAG IN MULTI-FILE MODE.
-
- DONETB: MVI A,TRUE ;INDICATE NO FILES BEING..
- STA FSTFLG ;RESET MULTIFILE TRANS
- LDA QFLG
- ORA A
- JZ DONETA
- CALL ILPRT ;final comment
- DB CR,LF,'All transfers completed'
- DB CR,LF,BELL,0
- DONETA: LXI SP,STAK ;restore stack
- MVI A,CRC
- STA CRCFLG ;turn off CRC option
- MVI A,0FFH
- STA FIRSTME ;set first-time flag
- LDA TERMFLG ;SEE IF RETURN TO..
- ORA A ;..TERMINAL MODE..
- JNZ MENU ;..AFTER X'FER.
- CALL CRLF
- MVI A,'T'
- STA OPTION
- MVI A,' '
- STA FCB+1 ;too late to specify filename
- CALL INMODDATP
- CALL INMODDATP;clear usart
- JMP DSKSAVE
- ;============================= SUBROUTINES ===============
- MSAVE: PUSH PSW
- LDA NFILFLG
- CPI TRUE
- JZ NOSAVE ;CANT SAVE IF NO FILE
- LDA SAVEFLG
- CPI FALSE
- JZ NOSAVE
- POP PSW
- CPI EOFCHAR ;dont save EOF's in file
- RZ ;CP/M doesn't like them
- LHLD HLSAVE
- MOV M,A
- INX H
- SHLD HLSAVE ;MENU COMMAND DESTROYS HL-REG..
- CPI LF
- JNZ NOCOLON ;TYPE ":" AFTER EACH LINE FEED..
- MVI A,':' ;..WHEN MEMORY SAVE ACTIVE.
- CALL TYPE ;dont increment col count
- NOCOLON:LDA SAVCCP
- ORA A
- JZ SUB1
- LDA 7
- SBI 8 ;..PAGE BELOW CCP ..
- JMP SUB1A
- SUB1: LDA 7
- SUB1A: DCR A ;..OR BDOS HAS BEEN..
- CMP H ;..REACHED AND DISKSAVE IS NEEDED.
- CZ INTDSKSV
- RET
- NOSAVE: POP PSW
- RET
- ;==================================
- PROCOPT:LXI D,FCB+1
- LDAX D
- STA OPTION ;primary option
- OPTLP: INX D
- LDAX D
- CPI ' '
- JZ CKPRI
- LXI H,OPTBL
- MVI B,OPTBE-OPTBL
- OPTCK: CMP M
- JNZ OPTNO
- MVI M,0 ;INSERT SECONDARY OPTION
- JMP OPTLP
- OPTNO: INX H
- DCR B
- JNZ OPTCK
- JMP BDOPT
- CKPRI: LDA FCB+1 ;CHECK ON THE PRIMARY OPTION
- CPI 'X'
- JZ EXPRT
- CPI ' '
- RZ
- CPI 'M'
- RZ
- CPI 'T'
- RZ
- CPI 'S'
- JZ CKFILE
- CPI 'R'
- JNZ BDOPT
- LDA BATCHFLG ;IF MULT FILE MODE, THEN..
- ORA A ;..RECV OPT MUST NOT BE NAMED
- JZ CKFILE
- LDA FCB+17
- CPI ' '
- RZ
- BDOPT: CALL ILPRT ;fatal error
- DB '++Bad Syntax++',CR,LF,0
- JMP MENU
- EXPRT: LDA XPRFLG
- CMA
- STA XPRFLG
- JMP MENU
- CKFILE: LDA FCB+17 ;IF OPTION THAT NEEDS FILE NAME,..
- CPI ' ' ;..THEN CHECK TO SEE IF NAME..
- RNZ ;..EXISTS.
- JMP BDOPT
- ;==================================
- TFILWR: LHLD HLSAVE
- CALL NUMRECS ;DISK WRITE ROUTINE AS USED IN..
- CALL WRTDSK ;..IN THE INTDSKSV ROUTINE.
- LXI D,FCB3
- MVI C,CLOSE
- CALL BDOS
- MVI A,TRUE
- STA NFILFLG
- RET
- ;================================
- INTDSKSV:
- MVI A,XOFF ;SEND A CTRL-S TO STOP..
- CALL OUTMODDATP ;..REMOTE COMPUTER OUTPUT.
- MVI D,0 ;D IS THE BUFFER COUNT
- CALL INMODEM ;GET LAST BYTES SENT..
- STA LASTB1 ;..AFTER CTRL-S.
- CALL INMODEM ;ADD MORE CALLS TO INMODEM..
- STA LASTB2 ;..AND STA LASTBYT# IF YOU ARE..
- ;..LOSING BYTES WHEN MEMORY IS FULL.
- PUSH D
- CALL NUM1REC
- CALL WRTDSK ;WRITE THE RECORDS
- POP D
- LXI H,BOTTRAM
- INR D
- DCR D ;TEST BUFFER COUNT FOR ZERO
- JZ CTRLQ
- LDA LASTB1 ;GET THE LAST BYTES THAT WERE..
- MOV M,A ;..SAVED AND PUT THEM IN..
- INX H ;..BOTTRAM.
- CALL CTYPE
- DCR D
- JZ CTRLQ
- LDA LASTB2
- MOV M,A
- INX H
- CALL CTYPE
- CTRLQ: SHLD HLSAVE
- MVI A,XON ;SEND START CHARACTER..
- CALL OUTMODDATP ;..TO REMOTE COMPUTER.
- RET
- ;======================================
- ;SUBROUTINE LOOPS UNTIL THE MODEM RECEIVES A CHARACTER OR 100ms
- ;RETURNS BYTE COUNT IN D OR ZERO FOR TIMEOUT
- ;if ^S is received it waits until ^Q is received
- INMODEM:LDA FASTCLK
- ORA A
- LXI B,1250
- JZ CHKMOD
- LXI B,2500
- CHKMOD: CALL INMODCTLP
- CALL ANIRCV
- CALL CPIRCV
- JZ GETBYTE
- DCX B
- MOV A,B
- ORA C
- JNZ CHKMOD
- RET
- GETBYTE:CALL INMODDATP
- ANI 7FH ;clear parity
- CPI XOFF
- JNZ TWAIT4
- PUSH H
- CALL ILPRT
- DB CR,LF,'XOFF received, type ^Q to force continuation',CR,LF,0
- TWAIT1: CALL INMODCTLP
- CALL ANIRCV
- CALL CPIRCV
- JZ TWAIT2
- CALL STAT ;local key?
- JZ TWAIT1
- CALL KEYIN ;get char
- CPI XON
- JZ TWAIT3
- JMP TWAIT1
- TWAIT2: CALL INMODDATP
- ANI 7FH
- CPI XON ;remote XON?
- JNZ TWAIT1
- CALL ILPRT
- DB 'XON received',CR,LF,0
- TWAIT3: POP H
- JMP INMODEM
- TWAIT4: INR D
- RET
- ;================================
- NUMRECS:MVI M,EOFCHAR
- INX H
- LXI D,127
- DAD D
- NUM1REC:LXI D,-(BOTTRAM)
- DAD D
- MOV A,L ;DIVIDE HL BY 128..
- ORA A
- RAL ;..TO GET THE..
- MOV L,H ;..NUMBER OF SECTORS
- MVI H,0
- PUSH PSW
- DAD H
- POP PSW
- MVI A,0
- ADC L
- MOV L,A ;RETNS WITH NUMBER OF..
- RET ;..128 BYTE RECORDS IN HL.
- ;======================================
- WRTDSK: LXI D,BOTTRAM
- NEXTWRT:MVI C,STDMA
- CALL BDOSRT
- PUSH D
- LXI D,FCB3
- MVI C,WRITE
- CALL BDOSRT
- POP D
- INR A
- JZ WRTERR
- XCHG
- PUSH D
- LXI D,128
- DAD D
- POP D
- XCHG
- DCX H
- MOV A,H
- ORA L
- JNZ NEXTWRT
- CALL RSDMA ;for CP/M 1.4
- RET
- WRTERR: CALL ILPRT
- DB 'Terminal file write error',CR,LF,0
- RET
- ;==========================
- BDOSRT: PUSH B
- PUSH D
- PUSH H
- CALL BDOS
- POP H
- POP D
- POP B
- RET
- ;============================
- MOVE2: LXI H,FCB3
- CALL INITFCBS
- LXI H,FCB
- LXI D,FCB3
- MVI B,12
- CALL MOVE
- RET
- ;=============================
- ;FILE TRANSFER ROUTINE - CALLED WITH
- ;CONTROL-T FROM TERMINAL ROUTINE.
- ;TRANSFER MAY BE CANCELLED WHILE SENDING BY USING CONTROL-X.
- TRANSFER:
- SHLD HLSAVE
- PUSH D
- PUSH B
- PUSH PSW
- LXI H,FCB4
- CALL INITFCBS ;INITIALIZES FCBS POINTED..
- LXI H,FCB+16 ;..TO BY HL REG.
- CALL INITFCBS
- GET: CALL ILPRT
- DB CR,LF,'Enter file name to be transferred - C/R TO QUIT: ',0
- LXI D,CMDBUF
- CALL INBUFF
- CALL CRLF
- LDA CMDBUF+2 ;WAS FILE ENTERED
- CPI 20H
- JZ TRANCAN
- LXI D,CMDBUF
- LXI H,FCB4
- CALL CPMLINE
- LXI D,FCB4
- MVI C,OPEN
- CALL BDOS
- CPI 0FFH ;RETURN WITH 0FFH MEANS
- JNZ CONTIN ;FILE DOES NOT EXIST
- CALL ILPRT
- DB '++File does not exist++',CR,LF,0
- TRANS2L:CALL ILPRT
- DB 'Type "^X" to cancel transfer',CR,LF
- DB 'Type "A" to re-enter name: ',BELL,0
- CALL KEYIN
- CALL UCASE
- CALL CTYPE ;ECHO RESPONSE
- CALL CRLF
- CPI 'A'
- JZ GET
- CPI CAN
- JZ TRANCAN
- JMP TRANS2L
- CONTIN: LXI D,80H
- MVI C,STDMA
- CALL BDOS
- LDA ECHOFLG ;computer mode ?
- ORA A
- JZ READMR
- MVI A,SAVON ;activate remote save
- CALL CHRSND ;computer mode only
- READMR: LXI D,FCB4
- MVI C,READ
- CALL BDOS
- ORA A
- JNZ RETNS
- CALL SEND80C
- CPI EOFCHAR ;END OF FILE
- JZ RETNS
- CPI CAN ;CANCELLATION?
- JZ TRANC1
- JMP READMR
- RETNS: LDA ECHOFLG
- ORA A
- JZ RETN1
- MVI A,SAVOFF
- CALL CHRSND ;deactivate remote save
- RETN1: CALL ILPRT
- DB CR,LF,'++File transfer completed++',CR,LF,BELL,0
- JMP RETURN
- TRANC1: LDA ECHOFLG
- ORA A
- JZ TRANCAN
- MVI A,SAVOFF
- CALL CHRSND ;deactivate remote save
- TRANCAN:CALL ILPRT
- DB CR,LF,'++ Transfer cancelled ++',CR,LF,BELL,0
- RETURN: POP PSW
- POP B
- POP D
- LHLD HLSAVE
- RET
- ;=============================
- INITFCBS: ;ENTRY AT +2 WILL LEAVE..
- MVI M,0 ;..DRIVE NO. INTACT.
- INX H ;WILL INITIALIZE AN FCB..
- MVI B,11 ;..POINTED TO BY HL-REG. FILLS 1ST POS
- LOOP10: MVI M,' ' ;..WITH 0, NEXT 11 WITH..
- INX H ;..WITH BLANKS, AND LAST..
- DCR B ;..21 WITH NULLS.
- JNZ LOOP10
- MVI B,21
- LOOP11: MVI M,0
- INX H
- DCR B
- JNZ LOOP11
- RET
- ;===========================
- CHRSND: PUSH PSW
- REDY: CALL INMODCTLP
- CALL ANISND
- CALL CPISND
- JNZ REDY
- POP PSW
- CALL OUTMODDATP
- RET
- ;===============================
- ;used by ^T transfer
- SEND80C:MVI B,80H
- LXI H,80H
- SEND81: MOV A,M ;get next char
- ANI 7FH ;remove top bit
- CPI EOFCHAR ;end of file?
- RZ
- CALL FILTER ;ignore non printing ASCII
- JC SEND85
- MOV C,A
- LDA ECHOFLG
- ORA A
- MOV A,C
- JNZ SEND83
- CPI LF ;ignore lf's in terminal mode
- JZ SEND85
- MOV A,C
- CALL CHRSND ;send to remote
- CPI CR
- JZ SEND82
- PUSH B
- MVI D,0
- CALL INMODEM ;wait 100ms for echo
- POP B
- JZ SEND85 ;zero indicates no echo
- JMP SEND84
- SEND83: CALL CHRSND
- PUSH PSW
- PUSH B
- LXI B,1 ;zero delay
- CALL CHKMOD ;check for XOFF from remote
- POP B
- POP PSW
- SEND84: CALL CTYPE ;local console
- PUSH B
- PUSH H
- CALL MSAVE ;save to memory
- POP H
- POP B
- JMP SEND85
- SEND82: PUSH B
- MVI D,0
- CALL INMODEM ;wait 100ms for echo
- POP B
- JZ SEND85 ;loop until timeout
- PUSH B
- CALL CTYPE
- PUSH PSW ;save inmodem flag
- PUSH H
- CALL MSAVE
- POP H
- POP PSW
- POP B
- JMP SEND82
- SEND85: CALL STAT ;TEST TO SEE IF
- ORA A ;CANCELLATION REQUESTED
- JZ SKIP12
- CALL KEYIN
- CPI CAN ;cancel?
- RZ
- CPI SAVECHR ;memory save toggle
- JNZ SEND86
- LDA NFILFLG
- CPI TRUE ;cant save if no file
- JZ SEND86
- LDA SAVEFLG
- CMA
- STA SAVEFLG
- SEND86: CPI PRNCHR
- JNZ SKIP12
- LDA LSTFLG
- CMA
- STA LSTFLG ;print toggle
- SKIP12: INX H
- DCR B
- JNZ SEND81
- RET
- ;=================================-
- ;send filename
- SENDFN: LDA QFLG
- ORA A
- JZ SWNAK
- CALL ILPRT ;first comment
- DB 'Awaiting name NAK',CR,LF,0
- SWNAK: MVI E,80 ;80 second timeout
- CALL WAITNLP
- MVI A,ACK ;GOT NAK, SEND ACK
- CALL SEND
- LXI H,FILECT
- DCR M
- JM NOMRNM
- LHLD NBSAVE ;GET FILE NAME..
- LXI D,FCB ;..IN FCB
- MVI B,12
- CALL MOVE
- SHLD NBSAVE
- CALL SENDNM ;SEND IT
- ORA A ;CLEAR CARRY
- RET
- NOMRNM: MVI A,EOT
- CALL SEND
- STC
- RET
- ;======================================
- SENDNM: PUSH H
- SEND1NM:MVI D,11 ;COUNT CHARS IN NAME
- MVI C,0 ;INIT CHECKSUM
- LXI H,FCB+1 ;ADDRESS NAME
- NAMLPS: MOV A,M ;SEND NAME
- ANI 7FH ;STRIP HIGH ORDER BIT SO CP/M 2..
- CALL SEND ;..WON'T SEND R/O FILE DESIGNATION.
- LDA SSEEFLG
- ORA A
- JZ ACKLP ;already typed by SEND
- LDA QFLG ;SHOW NAME IF..
- ORA A ;..QFLG NOT SET.
- MOV A,M
- CNZ TYPE ;first comment
- ACKLP: PUSH B ;SAVE CKSUM
- MVI B,1 ;WAIT FOR RECEIVER..
- CALL RECV ;..TO ACKNOWLEDGE..
- POP B ;..GETTING LETTER.
- JC SCKSER
- CPI ACK
- JNZ ACKLP
- INX H ;NEXT CHAR
- DCR D
- JNZ NAMLPS
- MVI A,EOFCHAR ;TELL RECEIVER END OF NAME
- CALL SEND
- LDA QFLG
- ORA A
- CNZ CRLF ;first comment
- MOV D,C ;SAVE CHECKSUM
- MVI B,1
- CALL RECV ;GET CHECKSUM..
- CMP D ;..FROM RECEIVER.
- JZ NAMEOK
- SCKSER: MVI A,BDNMCH ;BAD NAME-TELL RECEIVER
- CALL SEND
- LDA QFLG
- ORA A
- JZ SKCSER1
- CALL ILPRT ;error message
- DB 'Checksum error',CR,LF,0
- SKCSER1:MVI E,80 ;DO HANDSHAKING OVER
- CALL WAITNLP ;DON'T PRINT "AWAITING NAK" MSG
- MVI A,ACK
- CALL SEND
- JMP SEND1NM
- NAMEOK: MVI A,ACK ;GOOD NAME-TELL RECEIVER
- CALL SEND
- POP H
- RET
- ;============================
- ;get filename
- GETFN: LXI H,FCB
- CALL INITFCBS+2 ;DOES NOT INITIALIZE DRIVE
- LDA QFLG
- ORA A
- JZ GNAMELP
- CALL ILPRT ;first comment
- DB 'Awaiting file name',CR,LF,0
- GNAMELP:CALL HSNAK
- JC GNAMELP
- CALL GETNM ;GET THE NAME
- CPI EOT ;IF EOT, THEN NO MORE FILES
- JZ NOMRNG
- ORA A ;CLEAR CARRY
- RET
- NOMRNG: STC
- RET
- ;================================
- GETNM: PUSH H
- GETNM1: MVI C,0 ;INIT CHECKSUM
- LXI H,FCB+1
- NAMELPG:MVI B,5
- CALL RECV ;GET CHAR
- JNC GETNM3
- LDA QFLG
- ORA A
- JZ GETNM2
- CALL ILPRT ;error message
- DB 'Time out receiving filename',CR,LF,0
- GETNM2: JMP GCKSER
- GETNM3: CPI EOT ;IF EOT, THEN NO MORE FILES
- JZ GNRET
- CPI EOFCHAR ;GOT END OF NAME
- JZ ENDNAME
- MOV M,A ;PUT NAME IN FCB
- LDA RSEEFLG
- ORA A
- JZ GETNM4 ;already typed by RECV
- LDA QFLG ;TYPE IT IF NO QFLG
- ORA A
- MOV A,M
- CNZ CTYPE ;first comment
- GETNM4: PUSH B ;SAVE CKSUM
- MVI A,ACK ;ACK GETTING LETTER
- CALL SEND
- POP B
- INX H ;GET NEXT CHAR
- MOV A,L ;DON'T LET NOISE...
- CPI 7FH ;..CAUSE OVERFLOW..
- JZ GCKSER ;..INTO PROGRAM AREA.
- JMP NAMELPG
- ENDNAME:LDA QFLG
- ORA A
- CNZ CRLF ;first comment
- MOV A,C ;SEND CHECKSUM
- CALL SEND
- MVI B,1
- CALL RECV ;CHECKSUM GOOD?
- CPI ACK ;YES IF ACK SENT..
- JZ GNRET ;..ELSE DO OVER.
- GCKSER: LXI H,FCB ;CLEAR FCB (EXCEPT DRIVE)..
- CALL INITFCBS+2 ;..SINCE IT MIGHT BE DAMAGED..
- LDA QFLG ;..BY TOO MANY CHARS.
- ORA A
- JZ GCK1SER
- CALL ILPRT ;error message
- DB 'Checksum error',CR,LF,0
- GCK1SER:CALL HSNAK ;DO HANDSHAKING OVER
- JC GCK1SER
- JMP GETNM1
- GNRET: POP H
- RET
- ;==============================
- HSNAK: MVI A,NAK ;SEND NAK UNTIL..
- CALL SEND ;..RECEIVING ACK.
- CALL CKABORT ;DON'T GET HUNG UP HERE
- MVI B,2 ;WAIT 2 SECONDS..
- CALL RECV ;..IN RECEIVE.
- CPI ACK ;IF ACK,RETURN WITH..
- RZ ;..CARRY CLEAR.
- STC
- RET
- ;============================
- TNMBUF: MVI A,FALSE ;CALL FROM SENDFIL ONLY ONCE.
- STA FSTFLG
- STA FILECT
- CALL SCAN
- LXI H,NAMEBUF
- SHLD NBSAVE ;SAVE ADDR OF 1ST NAME
- TNLP1: CALL TRTOBUF
- LXI H,FCB
- LXI D,FCBBUF
- CALL CPMLINE ;PARSE NAME TO CP/M FORMAT
- TNLP2: CALL MFNAME ;SEARCH FOR NAMES (* FORMAT)
- JC NEXTNM
- LDA FCB+10 ;IF CP/M 2 $SYS FILE..
- ANI 80H ;..DON'T SEND
- JNZ TNLP2
- LHLD NBSAVE ;GET NAME
- LXI D,FCB ;MOVE IT TO FCB
- XCHG
- MVI B,12
- CALL MOVE
- XCHG
- SHLD NBSAVE ;ADDR OF NEXT NAME
- LXI H,FILECT ;COUNT FILES FOUND
- INR M
- JMP TNLP2
- ;
- NEXTNM: LXI H,NAMECT ;COUNT NAMES FOUND
- DCR M
- JNZ TNLP1
- LXI H,NAMEBUF ;SAVE START OF BUFFER
- SHLD NBSAVE
- LDA FILECT
- ORA A
- JZ NOBFILE
- CPI 65 ;NO MORE THAN 64 TRANSFERS
- RC
- MVI A,64 ;ONLY X'FER FIRST 64
- STA FILECT
- RET
- NOBFILE:CALL ILPRT ;fatal error
- DB 'No file',CR,LF,0
- JMP MENU
- ;==============================================-
- ;SCANS CMDBUF COUNTING NAMES AND PUTTING DELIMITER (SPACE)
- ;AFTER LAST NAME
- SCAN: PUSH H
- LXI H,NAMECT
- MVI M,0
- LXI H,CMDBUF+1 ;FIND END OF CMD LINE..
- MOV C,M ;..AND PUT SPACE THERE.
- MVI B,0
- LXI H,CMDBUF+2
- DAD B
- MVI M,20H
- LXI H,CMDBUF+1
- MOV B,M
- INR B
- INR B
- CALL EAT ;eat spaces
- JZ DNSCAN
- SCAN1LP:INX H
- DCR B
- JZ DNSCAN
- MOV A,M
- CPI 20H
- JNZ SCAN1LP
- CALL EAT
- JZ DNSCAN
- SHLD BGNMS ;SAVE START OF NAMES IN CMDBUF
- INR B
- DCX H
- SCAN3LP:INX H
- DCR B
- JZ DNSCAN
- MOV A,M
- CPI 20H
- JNZ SCAN3LP
- LDA NAMECT ;COUNTS NAMES
- INR A
- STA NAMECT
- CALL EAT
- JZ DNSCAN
- JMP SCAN3LP
- ;
- DNSCAN: MVI M,20H ;SPACE AFTER LAST CHAR
- POP H
- RET
- ;==================================
- ;Space eater
- EAT: INX H
- DCR B
- RZ
- MOV A,M
- CPI ' '
- JZ EAT
- RET
- ;==========================================
- ;PLACES NEXT NAME IN BUFFER SO CPMLINE MAY PARSE IT
- TRTOBUF:LHLD BGNMS
- MVI B,0
- LXI D,FCBBUF+2
- TBLP: MOV A,M
- CPI 20H
- JZ TRBFEND
- STAX D
- INX H
- INX D
- INR B ;COUNT CHARS IN NAME
- JMP TBLP
- ;
- TRBFEND:INX H
- MOV A,M ;EAT EXTRA SPACES
- CPI 20H
- JZ TRBFEND
- SHLD BGNMS
- LXI H,FCBBUF+1 ;PUT # CHARS BEFORE NAME
- MOV M,B
- RET
- ;====================================
- ;IN CP/M V.2, IF FILE IS R/O OR SYS, IT IS CHANGED TO 'BAK'.
- CKCPM2: MVI C,12
- CALL BDOS
- ORA A ;RETURN 0 MEANS CP/M 1
- RZ
- MVI C,STDMA
- LXI D,80H
- CALL BDOS
- MVI C,SRCHF ;SEARCH FOR FILE
- LXI D,FCB
- CALL BDOS
- CPI 0FFH
- RZ
- ADD A
- ADD A ;MULT A-REG BY..
- ADD A
- ADD A ;..32 TO FIND..
- ADD A ;..NAME IN DMA.
- LXI H,80H
- ADD L
- MOV L,A ;HL POINTS TO DIR NAME
- LXI D,9
- DAD D ;POINT TO R/O ATTRIB BYTE
- MOV A,M
- ANI 80H ;TEST MSB
- JNZ MKCHG ;IF SET, MAKE CHANGE
- INX H ;CHECK SYSTEM ATTRIB BYTE
- MOV A,M
- ANI 80H
- RZ ;NOT $SYS OR $R/O
- DCX H
- MKCHG: LXI D,-8
- DAD D ;POINT HL TO FILENAME + 1
- LXI D,FCB+1 ;MOVE DIR NAME TO FCB..
- MVI B,11 ;..WITHOUT CHANGING DRIVE.
- CALL MOVE
- LXI H,FCB+9 ;R/O ATTRIB
- MOV A,M
- ANI 7FH ;STRIP R/O ATTRIB
- MOV M,A
- INX H ;SYS ATTRIB
- MOV A,M
- ANI 7FH
- MOV M,A
- LXI D,FCB
- MVI C,30 ;SET NEW ATTRIBS IN DIR
- CALL BDOS
-
- ;MAY BE CALLED BY CKBAKUP BELOW. ITS RETURN DONE HERE
- PLANCHG:LXI H,FCB ;CHANGE NAME TO TYPE "BAK"
- LXI D,6CH
- MVI B,9 ;MOVE DRIVE AND NAME (NOT TYPE)
- CALL MOVE
- LXI H,75H ;START OF TYPE IN FCB2
- MVI M,'B'
- INX H
- MVI M,'A'
- INX H
- MVI M,'K'
- LXI D,6CH
- MVI C,ERASE ;ERASE ANY PREV BACKUPS
- CALL BDOS
- LXI H,6CH ;FCB2 DR FIELD SHOULD..
- MVI M,0 ;..0 FOR RENAME.
- LXI D,FCB
- MVI C,REN
- CALL BDOS
- RET
-
- CKBAKUP:LDA BAKUPBYTE
- ORA A
- RZ
- MVI C,SRCHF
- LXI D,FCB
- CALL BDOS
- INR A
- RZ ;FILE NOT FOUND
- JMP PLANCHG ;IN "CKCPM2" - RET DONE THERE
- ;====================================
- ;receive a sector
- RCVSECT:XRA A
- STA ERRCT
- RCVRPT: CALL VORQ
- JZ RCVSQ
- CALL CRLF ;clear col count
- CALL ILPRT ;comment message
- DB 'Awaiting # ',0
- PUSH H ;SAVE IT
- LHLD SECNO ;GET SECTOR NUMBER
- INX H ;BUMP IT
- CALL DECOUT ;PRINT SECTOR NUMBER IN DECIMAL
- CALL ILPRT
- DB ' (', 0
- CALL DHXOUT ;16 BIT HEX CONVERSION & OUTPUT
- CALL ILPRT
- DB 'H)',0
- POP H ;RESTORE IT
- ; If CRC is in effect, there is only a 7 second wait
- ; for the first SOH. If the SOH is not received within
- ; this time, then a NAK is sent which tells the sender
- ; to use checksum checking instead of CRC. This allows
- ; automatic compatability with versions of MODEM that
- ; do not implement Cyclic Redundancy Checking(CRC).
- RCVSQ: LDA FIRSTME ;first SOH...
- ORA A ;...been received?
- JZ RCVSQ2 ;yes, go get next SOH
- XRA A ;turn off...
- STA FIRSTME ;...first soh recvd switch
- LDA CRCFLG ;CRC in...
- ORA A ;...effect?
- JNZ RCVSQ2 ;no, do long wait for first SOH
- MVI B,7 ;wait for upto 7 seconds
- CALL RECV ;get a character from modem
- JNC RCVSQ3 ;got a char, go see if SOH
- LDA QFLG
- ORA A
- JZ CRCM
- CALL ILPRT ;first comment
- DB CR,LF,'++Switching to CHECKSUM MODE++',CR,LF,0
- CRCM: MVI A,'C' ;turn off...
- STA CRCFLG ;...CRC mode.
- MVI A,NAK ;send NAK to tell sender checksum
- CALL SEND ;...is in effect & to start sending.
- JMP RCVSECT ;go start receiving sector
- ;
- RCVSQ2: MVI B,7 ;10 IN ORIG PROG
- CALL RECV
- JC RCVSTOT
- RCVSQ3: CPI SOH
- JZ RCVSOH
- ORA A ;IGNORE NULLS
- JZ RCVSQ
- CPI EOT
- STC
- RZ
- MOV B,A
- LDA QFLG
- ORA A
- JZ RCVSERR
- MOV A,B
- CALL CRLF
- CALL HEXO
- CALL ILPRT ;error message
- DB 'H recv''d, not SOH',CR,LF,0
- RCVSERR: MVI B,1
- CALL RECV
- JNC RCVSERR
- MVI A,NAK
- CALL SEND
- LDA ERRCT
- INR A
- STA ERRCT
- CPI ERRLIM
- JC RCVRPT
- LDA QFLG
- ORA A
- JZ RCVSABT
- CALL CKQUIT
- JZ RCVSECT
- RCVSABT:CALL CLOSFIL
- CALL ERXIT ;fatal error
- DB CR,LF,'++Unable to receive block - Aborting++$'
- RCVSTOT:LDA QFLG
- ORA A
- JZ RCVSERR
- CALL ILPRT ;error message
- DB CR,LF,'++ Timeout ++ ',0
- RCVPRN: LDA ERRCT
- CALL HEXO
- CALL CRLF
- JMP RCVSERR
- RCVSOH: MVI B,1
- CALL RECV
- JC RCVSTOT
- MOV D,A
- MVI B,1
- CALL RECV
- JC RCVSTOT
- CMA
- CMP D
- JZ RCVDATA
- LDA QFLG
- ORA A
- JZ RCVSERR
- CALL ILPRT ;error message
- DB CR,LF,'++ Bad sector # in Hdr',CR,LF,0
- JMP RCVSERR
- RCVDATA:MOV A,D
- STA RCVSNO
- MVI A,1
- STA DATAFLG
- MVI C,0 ;clear checksum
- CALL CLRCRC ;clear crc counter
- LXI H,80H
- RCVCHR: MVI B,1
- CALL RECV
- JC RCVSTOT
- MOV M,A
- INR L
- JNZ RCVCHR
- XRA A
- STA DATAFLG
- LDA CRCFLG
- ORA A
- JZ RCVCRC
- MOV D,C
- MVI B,1
- CALL RECV
- JC RCVSTOT
- CMP D
- JNZ RCVCERR
- CHKSNUM:LDA RCVSNO
- MOV B,A
- LDA SECNO
- CMP B
- JZ RECVACK
- INR A
- CMP B
- JNZ ABORT
- RET
- RCVCRC: MVI E,2 ;nr of crc bytes
- RCV2CRC:MVI B,1
- CALL RECV
- JC RCVSTOT
- DCR E
- JNZ RCV2CRC
- CALL CHKCRC
- ORA A
- JZ CHKSNUM
- LDA QFLG
- ORA A
- JZ RCVSERR
- CALL ILPRT ;error message
- DB CR,LF,'++CRC error++',0
- JMP RCVPRN
- RCVCERR:LDA QFLG
- ORA A
- JZ RCVSERR
- CALL ILPRT ;error message
- DB '++Cksum error++ ',0
- JMP RCVPRN
- RECVACK:CALL SENDACK
- JMP RCVSECT
- ;===============================
- SENDACK:MVI A,ACK
- CALL SEND
- RET
- ;===========================
- ;send header
- SENDHDR:CALL VORQ
- JZ SENDHNM
- CALL CRLF ;clear col count
- CALL ILPRT ;comment message
- DB 'Send # ',0
- PUSH H
- LHLD SECNO ;GET SECTOR NUMBER
- CALL DECOUT ;PRINT IT IN DECIMAL
- CALL ILPRT
- DB ' (',0
- CALL DHXOUT ;16 BIT HEX CONVERSION & OUTPUT
- CALL ILPRT
- DB 'H)',0
- POP H
- SENDHNM:MVI A,SOH
- CALL SEND
- LDA SECNO
- CALL SEND
- LDA SECNO
- CMA
- CALL SEND
- RET
- ;========================
- SENDSEC:MVI A,1
- STA DATAFLG
- MVI C,0
- CALL CLRCRC
- LXI H,80H
- SENDC: MOV A,M
- CALL SEND
- INR L
- JNZ SENDC
- XRA A
- STA DATAFLG
- RET
- ;===============================
- SENDCKS:MOV A,C
- CALL SEND
- RET
- ;==============================
- SENDCRC:PUSH H
- LHLD CRCVAL
- MOV A,H
- CALL SEND
- MOV A,L
- CALL SEND
- POP H
- XRA A
- RET
- ;===============================
- GETACK: MVI B,7 ;10 IN ORIG PROG
- CALL RECVDG
- JC GETATOT
- CPI ACK
- RZ
- MOV B,A
- LDA QFLG
- ORA A
- JZ ACKERR
- MOV A,B
- CALL CRLF
- CALL HEXO
- CALL ILPRT ;error message
- DB 'H Recv''d, not ACK',CR,LF,0
- ACKERR: LDA ERRCT
- INR A
- STA ERRCT
- CPI ERRLIM
- RC
- LDA QFLG
- ORA A
- JZ CSABORT
- CALL CKQUIT
- STC
- RZ
- CSABORT:CALL ERXIT ;fatal error
- DB CR,LF,'Can''t send sector -- Aborting$'
- GETATOT:LDA QFLG
- ORA A
- JZ ACKERR
- CALL ILPRT ;error message
- DB CR,LF,'Timeout on ACK',CR,LF,0
- JMP ACKERR
- ;================================
- CKABORT:LDA QFLG
- ORA A
- RZ
- CALL STAT
- RZ
- CALL KEYIN
- CPI CAN
- JZ ABORT ;local abort
- RET
- ERXIT: POP D ;print message and abort
- MVI C,PRINT
- CALL BDOS ;does not update col count
- CALL CRLF ;reset col count
- ABORT: LXI SP,STAK
- ABORTL: MVI B,1
- CALL RECV ;wait until sender finishes
- JNC ABORTL
- MVI A,CAN
- CALL SEND
- ABORTW: MVI B,1
- CALL RECV ;wait until sender finishes
- JNC ABORTW
- MVI A,' ' ;send a space to clear out ^X
- CALL SEND
- CALL ILPRT
- DB CR,LF,'Routine cancelled',CR,LF,BELL,0
- LXI H,RESTROPT
- LXI D,OPTBL
- MVI B,OPTBE-OPTBL-2
- CALL MOVE ;clear options except T
- XRA A
- STA BATCHFLG;clear N option
- JMP DONETA
- ;===================================
- INCRSNO:PUSH H
- LHLD SECNO ;GET SECTOR NUMBER
- INX H ;BUMP IT
- SHLD SECNO ;STORE IT
- POP H
- RET
- ;===============================
- AMBGTS: LXI H,FCB+1
- MVI C,11
- AMBIG: MOV A,M
- INX H
- CPI '?' ;test for ambiguous name
- JNZ NOTAMB
- CALL ILPRT ;fatal error
- DB 'Ambiguous filename not allowed',CR,LF,0
- JMP MENU
- NOTAMB: DCR C
- JNZ AMBIG
- RET
- ;=============================
- ERASFIL:LDA BATCHFLG ;DON'T ASK FOR ERASE..
- ORA A ;..IN MULTI-FILE MODE,..
- JNZ NOASK
- LDA QFLG
- ORA A
- JZ NOASK ;dont hang up in Q mode
- TFLERAS:CALL AMBGTS ;ambiguous name ?
- LXI D,FCB
- MVI C,SRCHF ;see if file exists already
- CALL BDOS
- INR A
- RZ
- CALL ILPRT
- DB 'File exists -- Type ''Y'' to erase: ',BELL,0
- CALL KEYIN
- PUSH PSW
- CALL CTYPE
- POP PSW
- CALL UCASE
- CPI 'Y'
- CALL CRLF
- JNZ MENU
- NOASK: LXI D,FCB
- MVI C,ERASE
- CALL BDOS
- RET
- ;===========================
- MAKEFIL:LXI D,FCB
- MVI C,MAKE
- CALL BDOS
- INR A
- RNZ
- CALL ERXIT ;fatal error
- DB 'Error - Can''t make file',CR,LF
- DB 'Directory must be full$'
- ;==================================
- CNREC: MVI C,12
- CALL BDOS
- ORA A ;0 means CP/M 1
- JZ CNREC14
- MVI C,FILSIZ ;COMPUTE FILE SIZE FUNCTION IN CP/M 2.x
- LXI D,FCB ;POINT TO FILE CONTROL BLOCK
- CALL BDOS
- LHLD FCB+33 ;GET RECORD COUNT
- SHLD RCNT ;STORE IT
- LXI H,0 ;ZERO HL
- SHLD FCB+33 ;RESET RANDOM RECORD IN FCB
- RET
- CNREC14:MVI A,'?' ;MATCH ALL EXTENTS
- STA FCBEXT
- MVI A,0FFH
- STA MAXEXT ;INIT MAX EXT NO.
- MVI C,SRCHF ;GET 'SEARCH FIRST' FNC
- LXI D,FCB
- CALL BDOS ;READ FIRST
- INR A ;WERE THERE ANY?
- JNZ SOME ;GOT SOME
- CALL ERXIT ;fatal error
- DB '++File not found++$'
- ;POINT TO DIRECTORY ENTRY
- SOME: DCR A ;UNDO PREV 'INR A'
- ANI 3 ;MAKE MODULUS 4
- ADD A ;MULTIPLY...
- ADD A ;..BY 32 BECAUSE
- ADD A ;..EACH DIRECTORY
- ADD A ;..ENTRY IS 32
- ADD A ;..BYTES LONG
- LXI H,80H ;POINT TO BUFFER
- ADD L ;POINT TO ENTRY
- ADI 15 ;OFFSET TO RECORD COUNT
- MOV L,A ;HL NOW POINTS TO REC COUNT
- MOV B,M ;GET RECORD COUNT
- DCX H
- DCX H ;BACK DOWN TO EXTENT NUMBER
- DCX H
- LDA MAXEXT ;COMPARE WITH CURRENT MAX.
- ORA A ;IF NO MAX YET
- JM BIGGER ;THEN SAVE RECORD COUNT ANYWAY
- CMP M
- JNC MOREDIR
- BIGGER: MOV A,B ;SAVE NEW RECORD COUNT
- STA RCNT
- MOV A,M ;SAVE NEW MAX. EXTENT NO.
- STA MAXEXT
- MOREDIR:MVI C,SRCHN ;SEARCH NEXT
- LXI D,FCB
- CALL BDOS ;READ DIR ENTRY
- INR A ;CHECK FOR END (0FFH)
- JNZ SOME ;NOT END OF DIR...PROCESS EXTENT
- LDA MAXEXT ;HIT END...GET HIGHEST EXTENT NO. SEEN
- MOV L,A ;WHICH GIVES EXTENT COUNT -1
- MVI H,0
- MOV D,H
- LDA RCNT ;GET RECORD COUNT OF MAX EXTENT SEEN
- MOV E,A ;SAVE IT IN DE
- DAD H
- DAD H ;MULTIPLY # OF EXTENTS -1
- DAD H ; TIMES 128
- DAD H
- DAD H
- DAD H
- DAD H
- DAD D ;ADD IN SIZE OF LAST EXTENT
- SHLD RCNT ;SAVE TOTAL RECORD COUNT
- RET
- ;==================================
- OPENFIL:XRA A
- STA FCBEXT
- LXI D,FCB
- MVI C,OPEN
- CALL BDOS
- INR A
- JNZ OPENOK
- CALL ERXIT ;fatal error
- DB 'Can''t open file$'
- OPENOK: CALL VORQ
- RZ
- CALL ILPRT ;comment message
- DB 'File open, size: ',0
- LHLD RCNT ;GET RECORD COUNT
- CALL DECOUT ;PRINT NUMBER OF SECTORS IN DECIMAL
- CALL ILPRT ;PRINT
- DB ' (',0
- CALL DHXOUT
- CALL ILPRT
- DB 'H) sectors',CR,LF,0
- RET
- ;=============================
- CLOSFIL:LXI D,FCB
- MVI C,CLOSE
- CALL BDOS
- INR A
- RNZ
- CALL ERXIT ;fatal error
- DB 'Can''t close file$'
- ;================================
- RDSECT: LDA SECINBF
- DCR A
- STA SECINBF
- JM RDBLOCK
- LHLD SECPTR
- LXI D,80H
- CALL MOVE128
- SHLD SECPTR
- RET
- RDBLOCK:LDA EOFLG
- CPI 1
- STC
- RZ
- MVI C,0
- LXI D,DBUF
- RDSECLP:PUSH B
- PUSH D
- MVI C,STDMA
- CALL BDOS
- LXI D,FCB
- MVI C,READ
- CALL BDOS
- POP D
- POP B
- ORA A
- JNZ REOF
- LXI H,80H
- DAD D
- XCHG
- INR C
- MOV A,C
- CPI DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS
- JZ RDBFULL
- JMP RDSECLP
- REOF: MVI A,1
- STA EOFLG
- MOV A,C
- RDBFULL:STA SECINBF
- LXI H,DBUF
- SHLD SECPTR
- LXI D,80H
- MVI C,STDMA
- CALL BDOS
- JMP RDSECT
- ;==================================
- WRSECT: LHLD SECPTR
- XCHG
- LXI H,80H
- CALL MOVE128
- XCHG
- SHLD SECPTR
- LDA SECINBF
- INR A
- STA SECINBF
- CPI DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS
- RNZ
- WRBLOCK:LDA SECINBF
- ORA A
- RZ
- MOV C,A
- LXI D,DBUF
- DKWRLP: PUSH H
- PUSH D
- PUSH B
- MVI C,STDMA
- CALL BDOS
- LXI D,FCB
- MVI C,WRITE
- CALL BDOS
- POP B
- POP D
- POP H
- ORA A
- JNZ WRERR
- LXI H,80H
- DAD D
- XCHG
- DCR C
- JNZ DKWRLP
- XRA A
- STA SECINBF
- LXI H,DBUF
- SHLD SECPTR
- RSDMA: LXI D,80H ;required by CP/M 1.4
- MVI C,STDMA
- CALL BDOS
- RET
- WRERR: CALL RSDMA
- MVI A,CAN
- CALL SEND
- CALL ERXIT ;fatal error
- DB 'Error writing file$'
- ;===========================================
- ;RECV: Receive a character
- ;Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage
- ;characters on the line. For example, having just sent a sector, calling
- ;RECVDG will delete any line noise induced characters LONG before the
- ;ACK/NAK would be received.
- RECVDG: CALL INMODDATP
- CALL INMODDATP
- RECV: PUSH D
- LDA FASTCLK
- ORA A
- JZ MSEC
- MOV A,B
- ADD A
- MOV B,A
- MSEC: LXI D,15000 ;60% OF ORIG 50000
- CALL CKABORT
- MWTI: CALL STAT ;check keyboard
- ORA A
- JZ MWTJ
- CALL KEYIN ;get char
- CALL UCASE
- CALL FLGTGL ;toggle appropriate flag
- MWTJ: CALL INMODCTLP
- CALL ANIRCV
- CALL CPIRCV ;wait for modem char
- JZ MCHAR
- DCR E
- JNZ MWTI
- DCR D
- JNZ MWTI
- DCR B
- JNZ MSEC
- POP D
- STC
- RET
- MCHAR: CALL INMODDATP
- POP D
- PUSH PSW
- CALL UPDCRC ;calc crc
- ADD C
- MOV C,A
- LDA RSEEFLG
- ORA A
- JZ MONIN
- LDA VSEEFLG
- ORA A
- JNZ NOMONIN
- LDA DATAFLG
- ORA A
- JZ NOMONIN
- MONIN: POP PSW
- PUSH PSW
- CALL SHOW
- NOMONIN:POP PSW
- ORA A
- RET
- ;==============================
- ;set/reset secondary options
- FLGTGL: PUSH B
- PUSH D
- PUSH H
- LXI H,OPTBL ;flag
- LXI D,RESTROPT
- MVI C,5 ;do Q,R,S,V,T but NOT N
- MOV B,A
- DOCMP: LDAX D ;get reference
- CMP B
- JNZ DOCMP1
- MOV A,B
- CMP M ;current setting
- MOV M,A ;clear flag
- JNZ DOCMP1
- XRA A
- MOV M,A ;set flag
- DOCMP1: INX D
- INX H
- DCR C
- JNZ DOCMP
- POP H
- POP D
- POP B
- RET
- ;=================================
- SEND: PUSH PSW
- LDA SSEEFLG
- ORA A
- JZ MONOUT
- LDA VSEEFLG
- ORA A
- JNZ NOMONOT
- LDA DATAFLG
- ORA A
- JZ NOMONOT
- MONOUT: POP PSW
- PUSH PSW
- CALL SHOW
- NOMONOT:POP PSW
- PUSH PSW
- CALL UPDCRC ;calc crc
- ADD C
- MOV C,A
- POP PSW
- CALL CHRSND ;send to remote
- CALL STAT ;check for keypress
- ORA A
- RZ
- CALL KEYIN ;get char
- CALL UCASE
- CALL FLGTGL ;toggle appropriate flag
- RET
- ;==================================
- WAITNAK:LDA QFLG
- ORA A
- JZ WAITNLP
- CALL ILPRT ;first comment
- DB 'Awaiting initial NAK',CR,LF,0
- WAITNLP:CALL CKABORT
- MVI B,1
- CALL RECV
- CPI NAK
- RZ
- CPI CRC ;crc request?
- JZ WAITCRC ;yes, go set crc flag
- DCR E
- JZ ABORT
- JMP WAITNLP
- WAITCRC:XRA A
- STA CRCFLG
- LDA QFLG
- ORA A
- RZ
- CALL ILPRT ;first comment
- DB 'CRC request received',CR,LF,0
- RET
- ;===============================
- ;return zero = no message display
- ;use ahead of comment messages except first and final
- VORQ: LDA VSEEFLG
- ORA A
- RZ
- LDA QFLG
- ORA A
- RET
- ;==================================
- INITADR:LHLD 1
- LXI D,3
- DAD D
- SHLD VSTAT+1
- DAD D
- SHLD VKEYIN+1
- DAD D
- SHLD VTYPE+1
- LXI D,33
- DAD D
- SHLD LISTST+1
- RET
- ;=================================
- MOVEFCB:LXI H,FCB+16
- LXI D,FCB
- MVI B,16
- CALL MOVE
- XRA A
- STA FCBRNO
- STA FCBEXT
- RET
- ;=========================
- CMPDEHL:MOV A,E
- CMP L
- RNZ
- MOV A,D
- CMP H
- RET
- ;=============================
- ;carry set for non printing ASCII chars + VT & FF
- FILTER: CPI 8 ;BS
- RC ;Byte is less than 08H
- CPI LF+1 ;
- CMC ;invert carry flag
- RNC ;get rid of VT & HT, invert BS & LF carry flag
- CPI CR ;
- RC ;Byte is less than 0D
- RZ ;byte = LF,CR or BS, no carry
- CPI ' ' ;CPI space
- RC ;Byte is between 0E & 0F, reject
- CPI 7FH ;Del char
- CMC ;printable chars to no carry, DEL to carry
- RET
- ;==============================
- ;put C into print buffer, if buffer full byte is lost
- LISTOUT:MOV A,C
- ANI 7FH ;remove top bit
- CALL FILTER ;ignore non printing chars
- RC
- LSTBUF: LHLD BUFEND
- XCHG
- LHLD BUFRIN
- INX H
- CALL CMPDEHL
- JNZ LBUFF1 ;test for end of buffer
- LHLD BUFBEG ;reset to start
- LBUFF1: XCHG
- LHLD BUFROUT
- CALL CMPDEHL
- RZ ;buffer full
- XCHG
- SHLD BUFRIN
- MOV M,C ;save byte in buffer
- RET
- ;==========================
- ;Check printer status, if busy return, else print one char
- LISTST: CALL $-$
- ORA A
- RZ ;see if printer is busy
- LHLD BUFRIN
- XCHG
- LHLD BUFROUT
- CALL CMPDEHL
- RZ ;return if buffer empty
- INX H
- PUSH H
- LHLD BUFEND
- XCHG
- POP H
- CALL CMPDEHL
- JNZ PRBUF2
- LHLD BUFBEG ;reset to start
- PRBUF2: SHLD BUFROUT
- MOV E,M
- MVI C,LIST ;CP/M print function
- CALL BDOS
- RET
- ;=============================
- CONO: MOV C,A
- CPI 9
- JNZ CONSOP
- TAB: MVI A,' '
- CALL CONSOP ;expand tabs
- LDA COLCNT
- ANI 7
- JNZ TAB
- RET
- CONSOP: MOV C,A
- LDA LSTFLG
- ORA A
- CNZ LISTOUT ;no tabs left by now
- MOV A,C
- CALL TYPE
- MOV C,A
- LXI H,COLCNT
- CPI 7FH
- RZ
- INR M
- CPI ' '
- RNC
- DCR M
- MOV A,M
- ORA A
- RZ
- MOV A,C
- CPI 8
- JNZ TRYCR
- DCR M
- RET
- TRYCR: CPI CR
- RNZ
- MVI M,0
- RET
- ;=============================
- SHOW: CPI LF
- JZ CTYPE
- CPI CR
- JZ CTYPE
- PUSH PSW
- PUSH H
- LXI H,TWIDTH
- LDA COLCNT ;check terminal width
- CMP M
- CNC CRLF ;force CR,LF
- POP H
- POP PSW
- CPI 9
- JZ CTYPE
- CPI ' '
- JC SHOWHEX
- CPI 7FH
- JC CTYPE
- SHOWHEX:PUSH PSW
- MVI A,'('
- CALL CTYPE
- POP PSW
- CALL HEXO
- MVI A,')'
- CTYPE: PUSH PSW
- PUSH B
- PUSH D
- PUSH H
- ANI 7FH ;ensure parity bits are suppressed
- CALL CONO ;type with tabs expanded
- POP H
- POP D
- POP B
- POP PSW
- RET
- ;=============================
- CRLF: PUSH PSW
- MVI A,CR
- CALL CTYPE
- MVI A,LF
- CALL CTYPE
- POP PSW
- RET
- ;==========================
- TYPE: PUSH PSW
- PUSH B
- PUSH D
- PUSH H
- ANI 7FH ;ensure parity bits are suppressed
- MOV C,A
- VTYPE: CALL $-$
- POP H
- POP D
- POP B
- POP PSW
- RET
- ;=========================
- STAT: PUSH B
- PUSH D
- PUSH H
- CALL LISTST ;o/p next char to printer
- VSTAT: CALL $-$ ;get keyboard status
- POP H
- POP D
- POP B
- ORA A
- RET
- ;===============================
- KEYIN: PUSH B
- PUSH D
- PUSH H
- VKEYIN: CALL $-$
- POP H
- POP D
- POP B
- RET
- ;===========================
- UCASE: CPI 61H ;CHANGES LOWER CASE CHARACTER..
- RC ;..IN A-REG TO UPPER CASE.
- CPI 7BH
- RNC
- ANI 5FH
- RET
- ;============================
- DECOUT: PUSH PSW
- PUSH B
- PUSH D
- PUSH H
- LXI B,-10
- LXI D,-1
- DECOU2: DAD B
- INX D
- JC DECOU2
- LXI B,10
- DAD B
- XCHG
- MOV A,H
- ORA L
- CNZ DECOUT
- MOV A,E
- ADI '0'
- CALL CTYPE
- POP H
- POP D
- POP B
- POP PSW
- RET
- ;======================================
- ; - double precision hex output routine.
- DHXOUT: PUSH H
- PUSH PSW
- MOV A,H ;GET MS BYTE
- ORA A
- CNZ HEXO ;suppress high order if zero
- MOV A,L ;GET LS BYTE
- CALL HEXO ;OUTPUT LOW ORDER BYTE
- POP PSW
- POP H
- RET
- ;===============================
- HEXO: PUSH PSW
- RAR
- RAR
- RAR
- RAR
- CALL NIBBL
- POP PSW
- NIBBL: ANI 0FH
- CPI 10
- JC ISNUM
- ADI 7
- ISNUM: ADI '0'
- JMP CTYPE
- ;=====================================
- ;RETNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN
- ;NO QUESTIONS ASKED, JUST QUIT
- CKQUIT: LDA BATCHFLG
- ORA A
- JZ CKQTASK ;ASK FOR RETRY
- INR A ;RESET ZERO FLG
- RET
- CKQTASK:XRA A
- STA ERRCT
- CALL ILPRT
- DB 'Multiple errors encountered.',CR,LF
- DB 'Type Q to quit, R to retry: ',BELL,0
- CALL KEYIN
- PUSH PSW
- CALL CTYPE
- CALL CRLF
- POP PSW
- CALL UCASE
- CPI 'R'
- RZ
- CPI 'Q'
- JNZ CKQUIT
- ORA A
- RET
- ;==============================
- ILPRT: XTHL
- ILPLP: MOV A,M
- ORA A
- JZ ILPRET
- CALL TYPE
- INX H
- JMP ILPLP
- ILPRET: XTHL
- RET
- ;=========================
- MOVE128:MVI B,128
- MOVE: MOV A,M
- STAX D
- INX H
- INX D
- DCR B
- JNZ MOVE
- RET
- ;==================================
- ;Cyclic Redundancy Check Subroutines.
- ;The generator is X^16 + X^12 + X^5 +1 as
- ;recommended by CCITT
- ;Generate table for fast CRC calculation
- INITCRC:LXI H,CRCTBL
- MVI C,0
- GLOOP: XCHG
- LXI H,0
- MOV A,C
- PUSH B
- MVI B,8
- XRA H
- MOV H,A
- LLOOP: DAD H
- JNC LSKIP
- MVI A,10H
- XRA H
- MOV H,A
- MVI A,21H
- XRA L
- MOV L,A
- LSKIP: DCR B
- JNZ LLOOP
- POP B
- XCHG
- MOV M,D
- INR H
- MOV M,E
- DCR H
- INX H
- INR C
- JNZ GLOOP
- RET
- ;=================================
- ;Reset CRC Accumulator for a new message.
- CLRCRC: PUSH H
- LXI H,0
- SHLD CRCVAL
- POP H
- RET
- ;====================================
- ;Update CRC Accumulator using byte in (A).
- UPDCRC: PUSH PSW
- PUSH B
- PUSH D
- PUSH H
- LHLD CRCVAL
- XCHG
- MVI B,0
- XRA D
- MOV C,A
- LXI H,CRCTBL
- DAD B
- MOV A,M
- XRA E
- MOV D,A
- INR H
- MOV E,M
- XCHG
- SHLD CRCVAL
- POP H
- POP D
- POP B
- POP PSW
- RET
- ;==================================
- ; Check CRC bytes of received message.
- CHKCRC: PUSH H
- LHLD CRCVAL
- MOV A,H
- ORA L
- POP H
- RZ
- MVI A,0FFH
- RET
- ;
- CRCVAL: DW 0
- ;======================================
- ;INBUFF - DUPLICATES READ BUFFER ROUTINE
- ;SAME AS CP/M FUNCTION 10, BUT DOES
- ;NOT USE CTRL-C (REASON FOR ROUTINE).
- ;DOES ALLOW CONTROLS U, R, E, AND H (BACKSPACE).
- INBUFF: PUSH PSW
- PUSH H
- PUSH B
- PUSH D ;DE REGISTERS MUST BE PUSHED LAST
- ISTART: CALL ICLEAR ;CLEAR THE BUFFER AREA
- POP D ;GET ADDRESS OF BUFFER ON RETRIES
- PUSH D ;RESTORE STACK
- XRA A
- INX D ;ADDRESS COUNT FIELD
- STAX D ;INITIALIZE WITH A ZERO IN COUNT BYTE
- INX D
- XCHG ;ADDRESS FIRST BUFFER BYTE WITH HL
- INBUFA: CALL CONIN
- CPI 0DH ;IS IT A RETURN?
- JZ INBUFR ;IF SO, THEN RETURN
- CPI 7FH ;IS IT A DELETE?
- JZ DELETE
- CPI 8 ;CTRL-H WILL BACKSPACE..
- JZ DELETE ;..OVER DELETED CHAR.
- CPI 'U'-40H ;IS IT A CTRL-U
- JZ INBUFO ;OUTPUT # CR LF AND START OVER
- CPI 'R'-40H ;CTRL-R RETYPES LINE
- JZ RETYPE
- CPI 'E'-40H
- JZ PCRLF
- CPI 20H ;NO CONTROL CHARACTERS OTHER..
- JC INBUFA ;..THAN ABOVE ALLOWED.
- MOV B,A ;SAVE INPUTTED CHARACTER
- XCHG ;SAVE HL IN DE
- POP H ;GET ADDRESS OF BUFFER IN HL
- PUSH H ;RESTORE STACK
- INX H ;ADDRESS COUNT BYTE
- INR M ;INCREASE COUNT BYTE
- DCX H ;ADDRESS MAXIMUM
- MOV A,M ;PUT MAXIMUM IN A
- INX H ;ADDRESS COUNT
- CMP M ;COMPARE COUNT TO MAXIMUM
- JC ALERT ;IF MAXIMUM, RING BELL AND WAIT FOR CR
- XCHG ;RESTORE BUFFER POINTER TO HL
- MOV M,B ;PUT INPUTTED CHARACTER IN BUFFER
- MOV A,B ;OUTPUT IT
- CALL TYPE
- INX H ;BUMP POINTER
- JMP INBUFA ;GET NEXT CHARACTER
-
- DELETE: XCHG ;SAVE BUFFER POINTER IN DE
- POP H ;ADDRESS BEGINNING OF BUFFER
- PUSH H ;RESTORE STACK
- INX H ;ADDRESS COUNT FIELD
- MOV B,A ;SAVE DELETE CHAR - 7FH OR 08H
- MOV A,M
- SUI 1 ;DECREASE COUNT
- MOV M,A
- JC NODEL ;DON'T DELETE PAST BEGINING OF BUFFER.
- XCHG ;RESTORE BUFFER POINTER TO HL
- DCX H ;POINT TO LAST BYTE INPUTTED
- MOV A,B ;GET BACK EITHER 7FH OR 08H
- MOV B,M ;GET CHARACTER BEING DELETED
- MVI M,20H ;RESTORE BLANK
- CPI 8
- JZ BKSPC
- CPI 7FH
- JZ BKSPC0
- JMP INBUFA ;GET NEXT CHARACTER
- NODEL: INR M ;DON'T LEAVE COUNT NEGATIVE
- XCHG ;RESTORE POINTER TO HL
- JMP INBUFA
- BKSPC0: MVI A,08H
- BKSPC: CALL TYPE ;TRUE ERASE IF 08H
- MVI A,20H
- CALL TYPE
- MVI A,8
- CALL TYPE
- JMP INBUFA
-
- INBUFO: MVI A,'#'
- CALL TYPE
- CALL CRLF
- JMP ISTART
-
- RETYPE: POP D
- PUSH D
- INX D ;POINT TO CURRENT NUMBER..
- LDAX D ;..OF CHARACTERS.
- MOV B,A
- MVI A,'#'
- CALL TYPE
- CALL CRLF
- MOV A,B ;TEST IF ZERO INPUT
- ORA A
- JZ INBUFA
- CTLRLP: INX D
- LDAX D
- CALL TYPE
- DCR B
- JNZ CTLRLP
- JMP INBUFA
-
- ALERT: MVI A,7
- CALL TYPE
- DCR M
- XCHG
- JMP INBUFA
-
- PCRLF: CALL CRLF
- JMP INBUFA
-
- INBUFR: CALL CRLF
- POP D
- POP B
- POP H
- POP PSW
- RET
-
- ICLEAR: POP D ;ACCOUNTS FOR CALL
- POP H ;ADDRESS BUFFER IN HL
- PUSH H ;RESTORE..
- PUSH D ;..STACK
- MOV B,M ;SAVE MAXIMUM IN B
- INX H ;POINT TO FIRST..
- INX H ;..BUFFER BYTE.
- MVI A,20H
- CLEARL: MOV M,A
- INX H
- DCR B
- JNZ CLEARL
- RET
-
- CONIN: PUSH H
- PUSH D
- PUSH B
- CONINLP:CALL STAT
- JZ CONINLP
- CALL KEYIN
- CALL UCASE
- POP B
- POP D
- POP H
- RET
- ;==========================================
- ;LOADS A COMMAND LINE ADDRESSED BY DE REGISTERS (MAX # CHARACTERS IN LINE
- ;IN DE, NUMBER OF CHARS IN LINE IN DE+1, LINE STARTS IN DE+2) INTO FCB
- ;ADDRESSED BY HL REGISTERS. THE FCB SHOULD BE AT LEAST 33 BYTES IN LENGTH.
- ;THE COMMAND LINE BUFFER MUST HAVE A MAXIMUM LENGTH OF AT LEAST ONE MORE
- ;THAN THE GREATEST NUMBER OF CHARACTERS THAT WILL BE NEEDED.
-
- CPMLINE:PUSH PSW
- PUSH B
- PUSH D
- PUSH H
- CALL INIT ;FILLS FCBS WITH BLANKS AND NULLS
- XCHG ;GET START OF COMMAND LINE IN HL.
- INX H ;ADDRESS # BYTES IN CMD LINE.
- MOV E,M ;LOAD DE PAIR WITH # BYTES.
- MVI D,0
- INX H
- DAD D ;POINT TO BYTE AFTER LAST CHAR..
- MVI M,0DH ;..IN CMD LINE AND STORE DELIMITER.
- POP H ;RESTORE HL AND DE.
- POP D
- PUSH D
- PUSH H
- INX D ;ADDRESS START OF COMMAND.
- INX D
- CALL CDRIVE
- MVI C,8 ;TRANSFER FIRST FILENAME TO FCB.
- CALL TRANS
- CPI 0DH
- JZ CDONE
- CPI 20H ;IF SPACE, THEN START OF..
- JZ NAME2 ;..SECOND FILENAME.
- POP H ;FILETYPE MUST BE AFTER..
- PUSH H ;..EIGHTH BYTE OF NAME.
- LXI B,9
- DAD B
- MVI C,3 ;TRANSFER TYPE OF FIRST FILE
- CALL TRANS
- CPI 0DH
- JZ CDONE
- NAME2: LDAX D ;EAT MULTIPLE SPACES..
- CPI 20H ;..BETWEEN NAMES.
- JNZ NAME2C
- INX D
- JMP NAME2
- LDAX D
- CPI 0DH ;TEST IF FIRST NAME..
- JZ CDONE ;..ONLY AND THEN SPACE.
- NAME2C: POP H ;SECOND NAME STARTS IN 16TH BYTE.
- PUSH H ;POINT HL TO THIS BYTE.
- LXI B,16
- DAD B
- CALL CDRIVE
- MVI C,8
- CALL TRANS
- CPI 0DH
- JZ CDONE
- POP H ;SECOND TYPE STARTS IN 25TH BYTE.
- PUSH H
- LXI B,25
- DAD B
- MVI C,3
- CALL TRANS
- CDONE: POP H
- PUSH H
- INX H ;POINT TO FIRST CHAR OF FIRST NAME IN FCB.
- CALL CSCAN ;CHECK FOR * (AMBIGUOUS NAMES).
- POP H
- PUSH H
- LXI B,17 ;POINT TO FIRST CHAR OF SECOND NAME IN FCB.
- DAD B
- CALL CSCAN
- POP H
- POP D
- POP B
- POP PSW
- RET
-
- INIT: PUSH H ;INITIALIZES FCB WITH 1 NULL (FOR FIRST DRIVE),..
- PUSH B ;..11 BLANKS, 4 NULLS, 1 NULL (FOR 2ND DRIVE),..
- MVI M,0 ;..11 BLANKS, AND 4 NULLS.
- INX H
- MVI B,11
- MVI A,20H
- CALL INITFILL
- MVI B,5
- MVI A,0
- CALL INITFILL
- MVI B,11
- MVI A,20H
- CALL INITFILL
- MVI B,4
- MVI A,0
- CALL INITFILL
- POP B
- POP H
- RET
-
- INITFILL:
- MOV M,A
- INX H
- DCR B
- JNZ INITFILL
- RET
-
- CDRIVE: INX D ;CHECK 2ND BYTE OF FILENAME. IF IT..
- LDAX D ;..IS A ":", THEN DRIVE WAS SPECIFIED.
- DCX D
- CPI ':'
- JNZ DEFDR ;ELSE ZERO FOR DEFAULT DRIVE ('INIT' PUT ZERO)
- LDAX D
- ANI 5FH
- SUI 40H ;CALCULATE DRIVE (A=1, B=2,...)..
- MOV M,A ;..AND PLACE IT IN FCB.
- INX D ;ADDRESS FIRST BYTE OF..
- INX D ;..IN CMD LINE,..
- DEFDR: INX H ;..AND NAME FIELD IN FCB.
- RET
-
- TRANS: LDAX D ;TRANSFER FROM CMD LINE TO FCB..
- INX D ;..UP TO NUMBER OF CHARS SPECIFIED..
- CPI 0DH ;..BY C-REG. KEEP SCANNING FIELD..
- RZ ;..WITHOUT TRANSFER UNTIL A DELIMITING..
- CPI '.' ;..FIELD CHAR SUCH AS '.', BLANK, OR..
- RZ ;..C/R (FOR END OF CMD LINE).
- CPI 20H
- RZ
- DCR C
- JM TRANS ;ONCE C-REG IS LESS THAN ZERO, KEEP READING..
- MOV M,A ;..CMD LINE BUT DO NOT TRANSFER TO FCB.
- INX H
- JMP TRANS
-
- CSCAN: MVI B,8 ;SCAN FILE NAME ADDRESSED BY HL.
- TSTNAM: MOV A,M
- CPI '*' ;IF '*' FOUND, FILL IN REST OF FIELD..
- JZ FILL1 ;..WITH '?' FOR AMBIGUOUS NAME.
- INX H
- DCR B
- JNZ TSTNAM
- JMP TSTTYP
- FILL1: CALL FILL
-
- TSTTYP: MVI B,3 ;SCAN AND FILL TYPE FIELD FOR NAME..
- TSTLTYP:MOV A,M ;..SPECIFIED ABOVE.
- CPI '*'
- JZ FILL2
- INX H
- DCR B
- RZ
- JMP TSTLTYP
- FILL2: CALL FILL
- RET
-
- FILL: MVI M,'?' ;ROUTINE TRANSFERS '?'.
- INX H
- DCR B
- JNZ FILL
- RET
- ;======================================
- ;IN-LINE COMPARE. COMPARES STRING ADDRESSED BY DE-REG TO STRING
- ;AFTER CALL (ENDS WITH ZERO). RETURN WITH CARRY SET MEANS STRINGS
- ;NOT THE SAME. ALL REGISTERS EXCEPT A-REG ARE UNAFFECTED.
- ILCOMP: XTHL ;POINT HL TO 1ST CHAR.
- PUSH D
- ILCMPL: MOV A,M ;HL POINTS TO IN-LINE STRING.
- ORA A ;END OF STRING IF ZERO.
- JZ SAME
- LDAX D
- CMP M
- JNZ NOTSAME
- INX H
- INX D
- JMP ILCMPL
- NOTSAME:MVI A,0 ;IF NOT SAME, FINISH THRU..
- NSLP: INX H ;..STRING SO RETURN WILL..
- CMP M ;..GO TO INSTRUCTION AFTER..
- JNZ NSLP ;..STRING AND NOT REMAINDER OF STRING.
- STC
- SAME: POP D
- INX H ;AVOIDS A NOP INSTRUCTION..
- XTHL ;..WHEN RETURNING.
- RET
- ;==================================
- ;MULTI-FILE ACCESS SUBROUTINE. ALLOWS PROCESSING
- ;OF MULTIPLE FILES (E.G. *.ASM) FROM DISK. THIS
- ;ROUTINE BUILDS THE PROPER NAME IN THE FCB EACH
- ;TIME IT IS CALLED.
- ;THE FCB WILL BE SET UP WITH THE NEXT NAME, READY TO
- ;DO NORMAL PROCESSING (OPEN, READ, ETC.) WHEN ROUTINE IS CALLED.
- ;CARRY IS SET IF NO MORE NAMES CAN BE FOUND
- MFNAME: PUSH B
- PUSH D
- PUSH H
- MVI C,STDMA
- LXI D,80H
- CALL BDOS
- POP H
- POP D
- POP B
- XRA A
- STA FCBEXT
- LDA MFFLG1
- ORA A
- JNZ MFN01
- MVI A,1
- STA MFFLG1
- LXI H,FCB
- LXI D,MFREQ
- LXI B,12
- CALL MOVER
- LDA FCB
- STA MFCUR ;SAVE DISK IN CURR FCB
- LXI H,MFREQ
- LXI D,FCB
- LXI B,12
- CALL MOVER
- PUSH B
- PUSH D
- PUSH H
- MVI C,SRCHF
- LXI D,FCB
- CALL BDOS
- POP H
- POP D
- POP B
- JMP MFN02
- MFN01: LXI H,MFCUR
- LXI D,FCB
- LXI B,12
- CALL MOVER
- PUSH B
- PUSH D
- PUSH H
- MVI C,SRCHF
- LXI D,FCB
- CALL BDOS
- POP H
- POP D
- POP B
- LXI H,MFREQ
- LXI D,FCB
- LXI B,12
- CALL MOVER
- PUSH B
- PUSH D
- PUSH H
- MVI C,SRCHN
- LXI D,FCB
- CALL BDOS
- POP H
- POP D
- POP B
- MFN02: INR A
- STC
- JNZ MFFIX1
- STA MFFLG1
- RET
- MFFIX1: DCR A
- ANI 3
- ADD A
- ADD A
- ADD A
- ADD A
- ADD A
- ADI 81H
- MOV L,A
- MVI H,0
- PUSH H ;SAVE NAME POINTER
- LXI D,MFCUR+1
- LXI B,11
- CALL MOVER
- POP H
- LXI D,FCB+1
- LXI B,11
- CALL MOVER
- XRA A
- STA FCBEXT
- STA FCBRNO
- RET
- ;
- ;MULTI-FILE ACCESS WORK AREA
- ;
- MFFLG1: DB 0 ;1ST TIME SW
- MFREQ: DS 12 ;REQ NAME
- MFCUR: DS 12 ;CURR NAME
- ;=====================================
- ;MOVE SUBROUTINE
- MOVER: MOV A,M
- STAX D
- INX H
- INX D
- DCX B
- MOV A,B
- ORA C
- JNZ MOVER
- RET
- ;================================
- DIRLST: LXI D,CMDBUF ;PUT COMMAND LINE IN FCB
- LXI H,5CH
- CALL CPMLINE
- LXI H,SRCHFCB
- CALL INITFCBS
- LDA 6CH ;GET DRIVE #
- STA SRCHFCB
- LDA 6DH
- CPI 20H ;IF BLANK GET ALL NAMES
- PUSH PSW
- CZ QSTMARK
- POP PSW
- CNZ MOVENAME ;ELSE MOVE NAME INTO FCB
- CALL DRIVE
- LXI D,80H
- MVI C,STDMA
- CALL BDOS
- XRA A
- STA DNAMECT ;CR AFTER 4 NAMES
- LXI D,SRCHFCB
- MVI C,SRCHF ;DO FIRST SEARCH
- CALL BDOS
- CPI 0FFH
- JZ NOFILE
- DIRLP: CALL GETADD
- LXI D,15 ;OFFSET FOR RECORD COUNT
- DAD D
- MOV A,M
- ORA A
- JZ NEXTSR ;NO LIST IF FILE IS ZERO LENGTH
- LXI D,-5
- DAD D ;POINT TO $SYS ATTRIB BYTE
- MOV A,M
- ANI 80H
- JNZ NEXTSR ;NO LIST IF $SYS FILE
- LXI D,-10
- DAD D ;POINT TO BEGINNING OF NAME
- INX H ;POINT TO FIRST LETTER
- LXI D,PRNTNAME
- MVI B,8
- CALL MOVE
- INX D
- MVI B,3
- CALL MOVE
- CALL ILPRT
- PRNTNAME:
- DB ' ',' : ',0 ;12 SPACES
- LDA DNAMECT
- INR A
- STA DNAMECT
- ANI 03H
- ORA A
- CZ CRLF
- NEXTSR: LXI D,SRCHFCB
- MVI C,SRCHN ;DO NEXT SEARCH
- CALL BDOS
- CPI 0FFH
- JZ DIRDONE
- JMP DIRLP
- NOFILE: CALL ILPRT
- DB 'NOT FOUND',0
- DIRDONE:CALL CRLF
- RET
-
- QSTMARK:MVI A,'?' ;IF BLANK IN FCB, PUT IN 11 ?'s
- MVI B,11
- LXI H,SRCHFCB+1
- QSTLP: MOV M,A
- INX H
- DCR B
- JNZ QSTLP
- RET
-
- MOVENAME:
- LXI H,6DH
- LXI D,SRCHFCB+1
- MVI B,11
- CALL MOVE ;MOVE IN CP/M PROGRAM
- RET
-
- GETADD: ANI 03H ;GET MOD4 FOR CP/M 1.4
- ADD A
- ADD A
- ADD A ;ADD 32
- ADD A
- ADD A
- MOV E,A
- MVI D,0
- LXI H,80H ;ADD DMA OFFSET
- DAD D
- RET
-
- DRIVE: LDA SRCHFCB ;IF NO DRIVE, CAL
- ORA A ;LOGGED IN DRIVE
- JZ CALCDR
- ADI 40H
- JMP PRNTHD
- CALCDR: MVI C,25
- CALL BDOS
- ADI 41H
- PRNTHD: STA DRNAME
- CALL ILPRT
- DB CR,LF,'DRIVE '
- DRNAME: DB ' ',CR,LF,0
- RET
-
- SRCHFCB:DS 33
- DNAMECT:DS 1
- ;================================
- NFILFLG:DB FALSE ;Terminal file open flag
-
- OPTION: DB 0 ;primary option
- OPTBL EQU $
- QFLG: DB 'Q' ;secondary option flags
- RSEEFLG:DB 'R'
- SSEEFLG:DB 'S'
- VSEEFLG:DB 'V'
- TERMFLG:DB 'T'
- BATCHFLG:DB 'N' ;0=Non-batch
- OPTBE EQU $
-
- RESTROPT: ;MUST BE IN SAME ORDER AS TABLE ABOVE
- DB 'Q','R','S','V','T','N'
- CRCFLG: DB 'C' ;use CRC instead of cksum
-
- RESTSN: DB 0,0,0,0,0
- DW DBUF
- DB 0,0,0,0,0,0,0
-
- SECNOB EQU $
- RCVSNO: DB 0
- SECNO: DW 0 ;sector no.
- ERRCT: DB 0
- EOFLG: DB 0 ;end of file flag
- SECPTR: DW DBUF
- SECINBF: DB 0
- MAXEXT: DB 0
- RCNT: DW 0 ;no. of records to send
- DATAFLG: DB 0
- EXACFL: DB 0 ;literalise next char flag
- COLCNT: DB 0 ;column counter
- SECNOE EQU $
-
- FSTFLG: DB TRUE ;multiple file transmit flag
- FIRSTME:DB 0FFH ;first SOH received switch(it is zero after 1st SOH)
- LSTFLG: DB FALSE ;true=print echo on
- LSTRET: DB FALSE ;print toggle save
- BUFBEG: DW PRTBUF ;start of prtbuf
- BUFRIN: DW PRTBUF ;i/p pointer
- BUFROUT:DW PRTBUF ;o/p pointer
- BUFEND: DW PRTBUF+(RING*1024) ;end of prtbuf
- CMDBUF: DB 80H,0
- DS 80H
- HLSAVE: DS 2 ;memory pointer, terminal mode
- DISKNO: DS 1
- SENDFLG:DS 1
- NBSAVE: DS 2
- BGNMS: DS 2
- FILECT: DS 1
- NAMECT: DS 1
-
- DS 64
- STAK: DS 2
- FCB3: DS 33 ;terminal file fcb
- FCB4: DS 33 ;file transfer fcb
- FCBBUF: DS 15
- DBUF: DS DBUFSIZ*1024 ;FILE BUFFER FOR SEND & RECIEVE MODES
- NAMEBUF:DS 64*12 ;BUFFER FOR FILE NAMES IN BATCH MODE.
- ORG $ + 100H AND 0FF00H ;must be on page boundary
- CRCTBL: DS 512 ;crc lookup table
- PRTBUF: DS RING*1024 ;print buffer
- BOTTRAM:DS 1 ;MEMORY BUFFER FOR TERMINAL FILE
- END 100H