home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
BEEHIVE
/
COMMS
/
HAMMODEM.ARC
/
HAMMODEM.ASM
next >
Wrap
Assembly Source File
|
1988-08-07
|
51KB
|
2,589 lines
TITLE 'HAM MODEM PROGRAM Version 1.0, 20 Feb 82'
;
;A CP/M file transfer program for simplex operation on Amateur Radio bands.
;Adapted from MODEM74.ASM by Phil Cary, W5TYF and Ken Shutt, K5GUU.
;
;CP/M MACRO (MAC) assembler required along with MODEM7.LIB
;
;Will asemble as is to run on a North Star with the modem on the right
;serial port. Conditional equates to use features of the Heath/Zenith H-19
;terminal if h19term is set to true.
;
;May be patched under DDT or SID for other port assignments. Value of "timer"
;may be changed to accomodate different transmitter and receiver recovery
;characteristics, and call sign for CWID may be entered. See HAMMODEM.SET and
;HAMMODEM.DOC.
;
;HAMMODEM is adapted from MODEM74 for use in a simplex mode on
;the Amateur radio bands. It has been used by the authors on 2 meter
;FM, both direct and through repeaters, at 1200 baud for several months.
;No testing has been done on SSB on the low bands, but it should work
;at the appropriate baud rates as long as there is little or no QRM.
;
;A simple modem must be interfaced to the ham rig. A schematic and
;parts list for a modem using the EXAR 2211 and 2206 chips is available
;upon receipt of a s.a.s.e. to either of the following:
;
; Phil Cary, W5TYF Ken Shutt, K5GUU
; 748 Kenilworth Parkway 12433 Archery Drive
; Baton Rouge, LA 70808 Baton Rouge, LA 70815
; (504) 766-5255 (504) 275-0330
;
;No audio filtering has been needed in 2 meter operation, but probably
;would be required for SSB use.
;
;MODEM.ASM was originally created by Ward Christensen, with numerous
;revisions by Mark Zeigler, Jim Mills and others. MODEM74.ASM was the
;basis for this version of HAMMODEM. The CWID routines were borrowed
;from PACKET by Dale Heatherington, WA4DSY, Decatur, GA.
;
;We believe that all of the routines in MODEM74 and PACKET have at one time
;or the other been copyrighted and/or placed in the public domain for non-
;commercial use only. The routines may be used but not sold by others.
;All new and changed code in HAMMODEM .ASM is in lower case.
;
;All of the features of MODEM74 such as batch mode, blind send, etc. have
;been retained. All routines associated with the PMMI modem have been
;removed to conserve space. All IMSAI and FRONTPANEL code has been
;removed. The CRC method of error checking is used during file transfer
;and the CHECKSUM code has been removed. CHECKSUM is still used for file
;names in the batch mode. The E(cho) mode has been removed, and echo has
;been added to the T(erminal) mode. Added other functions to T(erminal)
;mode to send a CWID and to send a line that has previously been entered
;with the transmitter off. Conditional equates to use features of the
;Heath/Zenith H-19 terminal added. See HAMMODEM.DOC for further details.
MACLIB MODEM7 ;CONTAINS CMDLINE, INBUF, INLNCOMP,
;DIR, AND MFACCESS ROUTINES
;changed to MODEM.LIB by Jim Mills
;to differentiate from other 'MACROS.LIB'
TRUE EQU 0FFH
FALSE EQU 0
DBUFSIZ EQU 16 ;BUFFER SIZE IN KBYTES
;Modem Equates
MODCTLP EQU 05h ;MODEM CONTROL PORT
modsftp equ 05h ;Modem control port for shift/unshift
MODDATP EQU 04h ;MODEM DATA PORT
MODSNDB EQU 1 ;MODEM SEND BIT (XMIT BUFF EMPTY)
MODSNDR EQU 1 ;MODEM SEND READY
MODRCVB EQU 2 ;MODEM RECEIVE BIT (DAV)
MODRCVR EQU 2 ;MODEM RECEIVE READY
ERRLIM EQU 20 ;NUMBER OF TIMES TO RETRY
;SEND/RECEIVE ERRORS BEFORE QUIT
EXITCHR EQU 'E'-40H ; ^E = EXIT terminal mode
TRANCHR EQU 'T'-40H ; ^T = TRANSFER CHARACTER
CAN EQU 'X'-40H ; ^X = CANCEL SEND/RECEIVE
EOFCHAR EQU 'Z'-40H ; ^Z = END OF FILE
SAVECHR EQU 'Y'-40H ; ^Y = SAVE CHARACTER
ESC equ '['-40h ; ^[ = Escape
EXTCHR EQU '^'-40H ; ^^ = SEND NXT CHR
SOH EQU 1 ; START OF HEADER
EOT EQU 4 ; END OF TEXT
ACK EQU 6 ; ACKNOWLEDGE
NAK EQU 15H ; NOT ACKNOWLEDGE
BDNMCH EQU 75H ; BAD NAME MATCH
OKNMCH EQU ACK ; OKAY NAME MATCH
LF EQU 10 ; LINEFEED
CR EQU 13 ; CARRIAGE RETURN
BELL EQU 7 ; BELL CHARACTER
BOTTRAM SET LAST+100H AND 0FF00H
ORG 100H
JMP START
;THESE ROUTINES ARE AT THE BEGINNING OF THE PROGRAM SO
;THEY CAN BE PATCHED BY A MONITER WITHOUT RE-ASSEMBLING
;THE PROGRAM.
mycall db ' ' ;ID call. Pad with spaces to 8 char.
timer dw 00dfh ;Value for transmitter delay routine
ptton db 035h ;DTR=0
pttoff db 037h ;DTR=1
mark db 035h ;Char to reset modem to mark state
space db 03ch ;Char for modem to send steady space
IN$MODCTLP IN MODCTLP ! RET ;in modem control port
OUT$MODCTLP OUT MODCTLP ! RET ;out modem control port
out$modsftp out modsftp ! ret ;out modem cntrl port for shift/unshift
IN$MODDATP IN MODDATP ! RET ;in modem data port
OUT$MODDATP OUT MODDATP ! RET ;out modem data port
ANI$MODSNDB ANI MODSNDB ! RET ;bit to test for send ready
CPI$MODSNDR CPI MODSNDR ! RET ;value of send bit when ready
ANI$MODRCVB ANI MODRCVB ! RET ;bit to test for receive ready
CPI$MODRCVR CPI MODRCVR ! RET ;value of receive bit when ready
FASTCLK DB TRUE ;4 MHz or greater
BAKUPBYTE DB false ;true=make .BAK file
XPRFLG DB false ;true=no menu, false=print menu
h19term equ false ;True=Heath/Zenith H-19 terminal
START: LXI H,0
DAD SP ;GET CP/M'S STACK
SHLD STACK ;SAVE IT
LXI SP,STACK ;START LOCAL STACK
CALL START1
DB CR,LF,'HAMMODEM Ver 1.0, 20 Feb 82.',cr,lf,lf
db 'Adapted from MODEM74 by Phil Cary, W5TYF and Ken Shutt, K5GUU.'
db cr,lf,lf,'MODEM.ASM originally written by Ward Christensen.'
db cr,lf,'Revisions through MODEM74 by Mark Zeiger, Jim Mills, '
db 'and others.',cr,lf,'$'
START1: POP D ;GET ADDRESS OF ABOVE MESSAGE
MVI C,PRINT ;Call CPM print string
CALL BDOS ;..function
CALL INITADR ;INITIALIZE ADDRESSES
MVI A,TRUE ; 0FFH
STA NFILFLG ;No file specified in Terminal mode
CMA ; 0
STA SAVEFLG
CALL PROCOPT ;PROCESS CONTROL OPTIONS
LDA OPTION ;GET MAIN OPTION
CPI 'X' ;EXPERT FLAG?
JNZ RESTART ;NO
MVI A,TRUE ;YES
STA XPRFLG ;MAKE EXPERT
JMP MENU
RESTART
LDA OPTION ;GET MAIN OPTION
CPI ' ' ;NO OPTION SPEC'D?
JZ MENU ;TRUE, GO MENU
CPI 'M' ;MENU ASKED FOR?
JZ MENU2 ;YES, GO MENU
CALL MOVEFCB
MVI A,FALSE
STA NFILFLG
CALL IN$MODDATP ;GOBBLE UP GARBAGE..
CALL IN$MODDATP ;..CHARACTERS ON LINE
LDA OPTION ;PROCESS MAIN OPTION
CPI 'T' ;TERMINAL MODE?
JZ DSKSAVE ;YES
CPI 'S' ;SEND A FILE?
JZ SENDFIL ;YES
CPI 'R' ;RECEIVE A FILE?
JZ RCVFIL ;YES
JMP MENU ;NO OPTION SPEC'D, GO MENU
;REVISED TERMINAL ROUTINE ALLOWING MEMORY SAVE
DSKSAVE LDA NFILFLG ;NEW FILE FLAG
CPI TRUE ;OFFH? (TRUE=NORMAL TERMINAL MODE)
JZ termint ;YES
LDA FCB+1 ;FIRST CHAR OF FILENAME
CPI ' ' ;FILE SPEC'D
JNZ GOODNM ;YES, GOOD NAME
MVI A,TRUE ;0FFH
STA NFILFLG
CMA
STA SAVEFLG
JMP termint
GOODNM CALL ERASFIL
CALL MOVE2
LXI D,FCB3
MVI C,MAKE
CALL BDOS
LXI D,FCB3
MVI C,OPEN
CALL BDOS
LXI H,BOTTRAM
SHLD HLSAVE
MVI A,FALSE
STA NFILFLG
termint:
if h19term
call ilprt
db esc,'E',esc,'j' ;Clear screen, save cursor position
db esc,'x','1' ;Enable 25th line
db esc,'Y',56,33 ;Position cursor to L25,C2
db esc,'p' ;Reverse video on
db ' f1=CWID | f2=TX Line | f3=TX File Blind '
db '| f4=Toggle Save | f5=Exit To Menu '
db esc,'q',esc,'k',0 ;Reverse video off, restore cursor
endif
;
TERM: CALL STAT ;KEYPRESS?
JZ TERML ;NO, CHECK LINE
CALL KEYIN ;GET CHAR FROM KBD
MOV B,A ;SAVE
LDA EXACFL
ORA A ;EXACT?
MVI A,0
STA EXACFL ;CLR FOR NEXT TIME
MOV A,B ;RESTORE
JNZ NOTOG
cpi esc ;^[?
jz txcmd ;Process second character
CPI EXITCHR ;^E?
JZ trmexit ;YES, RETURN TO MENU after reseting terminal
CPI EXTCHR ;^^?
JZ EXTFLG ;YES, SET FLAG FOR NXT CHAR
CPI TRANCHR ;TEST FOR TRANSFER REQUEST (^T)
CZ TRANSFER ;SEND-A-FILE (BLIND SEND)
JZ TERM ;LOOP
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 TERML
txcmd: call stat ;Character at keyboard?
jz txcmd ;Loop till there is
call keyin ;Get it
cpi 'S' ;Is it S?(ESC S or f1 function key on H-19)
cz cwidrou ;If so, go id in cw
cpi 'T' ;Is it T?(ESC T or f2 function key on H-19)
cz linesend ;Set up to send a line of charaters
CPI 'W' ;Is it W?(ESC W or f5 function key on H-19)
JZ trmexit ;Yes, reset terminal and return to menu
CPI 'U' ;ESC U or f3?
CZ TRANSFER ;SEND-A-FILE (BLIND SEND)
JZ TERM ;LOOP
CPI 'V' ;ESC V or f4?
JNZ txcmd2
LDA NFILFLG ;DO NOT ALLOW SAVE IF..
CPI TRUE ;..THIS FLAG IS SET.
JZ TERM
LDA SAVEFLG
CMA
STA SAVEFLG
jmp term
txcmd2: cpi 'Q' ;Is it Q?(ESC Q or Red function key on H-19)
cz txon ;If so, turn on transmitter
cpi 'P' ;Is it P?(ESC P or Blue function key on H-19)
cz txoff ;If so, turn off transmitter
cpi 'R' ;R?(ESC R or White function key on H-19)
jnz term ;If not, go get another character
call txon ;If so, turn on transmitter
mvi a,true ;..and set AUTO TX OFF on CR
sta autotx ;..flag
jmp term ;Get another character
linesend:
lxi h,linebuf ;Point to line buffer
lineret:
call stat ;Character at keyboard
jz lineret ;Loop if not
call keyin ;Get character
cpi cr ;Is it a CR
push psw ;Save character and flags
mov m,a ;Put character in linebuf
call type ;Display the character
inx h ;Increment linebuf
PUSH PSW
LDA SAVEFLG
CPI FALSE
JZ lineret1
xchg ;Hold linebuf pointer in DE
lhld hlsave ;Point to main save buffer
POP PSW
MOV M,A
INX H
SHLD HLSAVE
xchg ;Linebuf pointer back in HL
lineret1:
pop psw ;Get flag back
jz lineout ;Send line if CR
jmp lineret ;Get another character if not CR
lineout:
lda saveflg ;First see if saving
jnz lineout1
lhld hlsave ;If so, point to main save buffer
mvi m,lf ;..and put a LF in the file
inx h
shld hlsave
lineout1:
call crlf
call txon
lxi h,linebuf ;Point to line buffer
lineout2:
call in$modctlp
call ani$modsndb
call cpi$modsndr
jnz lineout2
mov a,m ;Get character
push psw ;Save character
call out$moddatp ;Send character
call type ;Echo it
inx h ;Increment line buffer
pop psw ;Get character
cpi cr ;Was it a CR
jnz lineout2 ;Loop for next character if not
lineout3:
call in$modctlp ;Get status
call ani$modsndb ;Mask ready bit
call cpi$modsndr ;Ready?
jnz lineout3
mvi a,lf ;Else get LF
call out$moddatp ;..and send it
call type ;..and echo it
lda saveflg ;If saving
cpi true ;..then
jnz lineout4
mvi a,':' ;..type a ":"
call type ;..at beginning of line
lineout4:
call txoff ;Finished with line if CR
lhld hlsave ;Restore save buffer pointer to HL before ret
jmp term ;Return to terminal mode with xmitter off
trmexit:
if h19term ;Routine to reset H-19. Erases entire screen,
call ilprt ;..disables 25th line and homes cursor
db esc,'z',0
endif
call txoff ;Be sure transmitter is off and
jmp menu ;..exit terminal mode to menu
EXTFLG: MVI A,TRUE
STA EXACFL
JMP TERML
NOTOG: push psw
notog1: call in$modctlp ;Get status
call ani$modsndb ;Mask ready bit
call cpi$modsndr ;Ready?
jnz notog1
pop psw
CALL OUT$MODDATP
call type
PUSH PSW
LDA SAVEFLG
CPI FALSE
JZ notog2
POP PSW
MOV M,A
INX H
SHLD HLSAVE ;MENU COMMAND DESTROYS HL-REG..
push psw
notog2: pop psw
cpi cr ;Is it CR?
jnz terml ;Continue if not
notog3: call in$modctlp ;Get status
call ani$modsndb ;Mask ready bit
call cpi$modsndr ;Ready?
jnz notog3
mvi a,lf
call out$moddatp
call type
MOV M,A
INX H
SHLD HLSAVE ;MENU COMMAND DESTROYS HL-REG..
lda autotx ;Otherwise, get auto TXOFF on CR flag
cpi true ;See if it is set
cz txoff ;Turn off TX if set
mvi a,false ;..and reset
sta autotx ;..flag
lda saveflg
cpi true
jnz terml
mvi a,':'
call type
TERML: CALL IN$MODCTLP
CALL ANI$MODRCVB
CALL CPI$MODRCVR
JNZ TERM
CALL IN$MODDATP
CPI 0 ;CHECK FOR NULLS
JZ TERM ;DON'T PROCESS THEM
ANI 7FH ;STRIP PARITY
CALL TYPE
PUSH PSW
LDA SAVEFLG
CPI FALSE
JZ NOSAVE
POP PSW
MOV M,A
INX H
SHLD HLSAVE ;MENU COMMAND DESTROYS HL-REG..
COLON: CPI LF ;If linefeed
JNZ NOCOLON ;..TYPE ":" AFTER EACH LINE FEED..
MVI A,':' ;..WHEN MEMORY SAVE ACTIVE.
CALL TYPE
NOCOLON:
LDA 7 ;CHECK TO SEE IF..
DCR A ;..PAGE BELOW BDOS HAS BEEN..
CMP H ;..REACHED AND DISKSAVE IS NEEDED.
CZ INTDSKSV
JMP TERM
NOSAVE: POP PSW
JMP TERM
autotx: db false
SAVEFLG: DB FALSE
INTDSKSV:
call ilprt
db cr,lf,lf,'WARNING!!! BUFFER AREA IS FULL.',cr,lf,bell
db 'Data is being lost while buffer contents is being'
db 'written to disk.',bell,cr,lf
db 'Save will continue after disk write.',bell
db cr,lf,lf,0
CALL NUMREC1
CALL WRTDSK ;WRITE THE RECORDS
lxi h,bottram
shld hlsave
RET
NUMRECS MVI M,EOFCHAR
INX H
LXI D,127
DAD D
NUMREC1 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 ;RETURNS 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
XCHG
PUSH D
LXI D,128
DAD D
POP D
XCHG
DCX H
MOV A,H
ORA L
JNZ NEXTWRT
RET
CLOSE3 LXI D,FCB3
MVI C,CLOSE
CALL BDOS
RET
BDOSRT PUSH B ! PUSH D ! PUSH H ! PUSH PSW
CALL BDOS
POP PSW ! 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:
PUSH H ! 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 GETNAME
LDA CMDBUF+2 ;WAS FILE ENTERED
CPI 20H
JZ TRANSL2
CALL MOVE4
CALL OPEN4
CPI 0FFH ;RETURN WITH 0FFH MEANS
JNZ CONTIN ;FILE DOES NOT EXIST
TRANSL1:
CALL ILPRT
DB CR,LF,'++FILE DOES NOT EXIST++',CR,LF,0
TRANSL2:
CALL ILPRT
DB 'TYPE "R" TO RETURN TO MODEM',CR,LF
DB 'TYPE "A" TO RE-ENTER NAME: ',BELL,0
CALL KEYIN
CALL UCASE
CALL TYPE ;ECHO RESPONSE
CALL CRLF
CPI 'A'
JZ GET
CPI 'R'
JZ RETURN
JMP TRANSL2
CONTIN: call txon
LXI D,80H
MVI C,STDMA
CALL BDOS
READMR: CALL READ80
CPI 1 ;END OF FILE
JZ RETURNS
CPI 2 ;BAD READ
JZ RETURNU
CALL SEND80C
CPI EOFCHAR ;END OF FILE - OMIT IF OBJECT..
JZ RETURNS ;..CODE IS TO BE SENT.
CPI CAN ;CANCELLATION?
JZ TRANCAN
JMP READMR
RETURNS:
CALL ILPRT
DB CR,LF,'++FILE TRANSFER COMPLETED++',CR,LF,BELL,BELL,0
JMP RETURN
RETURNU:
CALL ILPRT
DB CR,LF,'++FILE TRANSFER UNSUCCESSFUL++',CR,LF,BELL,BELL,0
JMP RETURN
TRANCAN:
CALL ILPRT
DB CR,LF,CR,LF,'++ TRANSFER CANCELLED ++',CR,LF,BELL,BELL,0
RETURN: POP PSW ! POP B ! POP D ! POP H
call txoff
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
GETNAME CALL ILPRT
DB CR,LF,'ENTER FILE NAME TO BE TRANSFERRED - C/R TO QUIT: ',0
LXI D,CMDBUF
CALL INBUFF
CALL CRLF
RET
MOVE4 LXI D,CMDBUF
LXI H,FCB4
CALL CPMLINE
RET
OPEN4 LXI D,FCB4
MVI C,OPEN
CALL BDOS
RET
READ80 LXI D,FCB4
MVI C,READ
CALL BDOS
RET
SEND80C MVI B,80H
LXI H,80H
SENDCH1 MOV A,M
CALL MODOUT
CPI EOFCHAR
RZ
CALL STAT ;TEST TO SEE IF
ORA A ;CANCELLATION REQUESTED
JZ SKIP12
CALL KEYIN
CPI CAN
RZ
SKIP12 INX H
DCR B
JNZ SENDCH1
RET
MODOUT PUSH PSW
MODOUTL CALL IN$MODCTLP
CALL ANI$MODSNDB
CALL CPI$MODSNDR
JNZ MODOUTL
POP PSW
CALL OUT$MODDATP
CALL TYPE
RET
FCB4 DS 33
;UNCOMMENTED LINES ARE THOSE OF ORIGINAL MODEM PROGRAM.
; SEND A CP/M FILE
SENDFIL:
LDA BATCHFLG ;CHECK IF MULTIPLE FILE..
ORA A ;..MODE IS SET.
JNZ 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,'B' ;STOP BATCH..
STA BATCHFLG ;..MODE OPTION.
call txon
MVI A,EOT ;FINAL XFER END
CALL SEND
call txoff
JMP DONE
SENDC1 LDA FCB+1
CPI ' '
JZ BLKFILE
SENDC2 CALL CNREC ;GET NUMBER OF RECORDS
CALL OPENFIL
CALL WAITNAK
SENDLP CALL RDSECT
JC SENDEOF
CALL INCRSNO
XRA A
STA ERRCT
SENDRPT:
call txon
CALL SENDHDR
CALL SENDSEC
call sendcrc
call txoff
CALL GETACK
JC SENDRPT
JMP SENDLP
SENDEOF:
call txon
MVI A,EOT
CALL SEND
call txoff
CALL GETACK
JC SENDEOF
JMP DONE
; RECEIVE A FILE
RCVFIL: LDA BATCHFLG ;CHECK IF MULT..
ORA A ;..FILE MODE.
JNZ 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,'B' ;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
JNZ rcvlp
LDA BATCHFLG
ORA A ;DON'T PRINT MSSG IF..
JZ rcvlp ;..IN MULTI AND QUIET.
CALL ILPRT
DB 'FILE OPEN, READY TO RECEIVE',CR,LF,0
;
RCVLP CALL RCVSECT
JC RCVEOT
CALL WRSECT
CALL INCRSNO
CALL SENDACK
JMP RCVLP
RCVEOT: CALL WRBLOCK
CALL SENDACK
CALL CLOSFIL
JMP DONE
;SUBROUTINES
;
;FSK CWID routine.
;ASCII to CW translate table
ASCII$CW:
DB 5+10010000B ; / -..-.
DB 5+11111000B ;ZERO
DB 5+01111000B ;1
DB 5+00111000B ;2
DB 5+00011000B ;3
DB 5+00001000B ;4
DB 5+00000000B ;5
DB 5+10000000B ;6
DB 5+11000000B ;7
DB 5+11100000B ;8
DB 5+11110000B ;9
DB 0 ;: NOT USED
DB 0 ; ; NOT USED
DB 0 ; < NOT USED
DB 0 ; = NOT USED
DB 0 ; > NOT USED
DB 0 ; ? NOT USED
DB 0 ; @ NOT USED
DB 2+01000000B ; A .-
DB 4+10000000B ;B -...
DB 4+10100000B ; C -.-.
DB 3+10000000B ; D -..
DB 1+00000000B ; E .
DB 4+00100000B ; F ..-.
DB 3+11000000B ;G --.
DB 4+00000000B ;H
DB 2+00000000B ; I ..
DB 4+01110000B ; J .---
DB 3+10100000B ; K -.-
DB 4+01000000B ; L .-..
DB 2+11000000B ; M --
DB 2+10000000B ; N -.
DB 3+11100000B ; O ---
DB 4+01100000B ; P .--.
DB 4+11010000B ; Q --.-
DB 3+01000000B ; R .-.
DB 3+00000000B ; S ...
DB 1+10000000B ; T -
DB 3+00100000B ; U ..-
DB 4+00010000B ; V ...-
DB 3+01100000B ; W .--
DB 4+10010000B ; X -..-
DB 4+10110000B ; Y -.--
DB 4+11000000B ; Z --..
;End of translate table
;
ID$STRING: DS 14 ;RESERVE 14 BYTES FOR ID STRING
DE$STR: DB 'DE '
cwidrou: push psw ! push h ! push d ! push b
call cwid
pop b ! pop d ! pop h ! pop psw
ret
CWID: LXI D,ID$STRING
LXI H,DE$STR ;POINT TO "DE" STRING
MVI B,3
CALL MOVE
LXI H,MYCALL ;PUT OUR CALL IN
MVI B,8
CALL MOVE
XCHG
MVI M,' ' ;TRAILING SPACE
INX H
MVI M,0 ;NULL TERMINATES STRING
CALL txon ;KEY TRANSMITTER
CALL shift ;Send space tone
LXI H,ID$STRING
CWID1: MOV A,M ;GET A ASCII CHAR.
ORA A ;NULL?
JZ txoff ;QUIT IF NULL
CPI '0'
JC CWID2 ;IGNORE INVALID CHAR
PUSH H
MOV C,A
CALL SEND$CW$CHAR ;CONVERT TO CW AND SEND
POP H
CWID2: INX H
JMP CWID1 ;LOOP TILL DONE
SEND$CW$CHAR:
PUSH B
CALL shift ;Send space tone
MVI C,2
CALL DELAYX ;WAIT 2 DOT TIMES
POP B ;GET ASCII CHARACTER BACK
LXI H,ASCII$CW-2FH ;POINT TO CONVERSION TABLE
MOV A,C
CPI 20H ;TEST FOR SPACE
JNZ CW1
MVI C,7 ;7 DOT TIMES FOR SPACE
JMP DELAYX
CW1: MVI B,0
DAD B ;INDEX INTO TABLE
MOV A,M ;GET CW CODE
ANI 7 ;KEEP COUNT
RZ ;RETURN IF ZERO COUNT
MOV B,A ;PUT COUNT IN REG. B
MOV A,M ;GET CODE AGAIN
CW2: ADD A ;SHIFT MSB INTO CARRY
MVI E,1 ;ASSUME A DOT
JNC CW3 ;JUMP IF DOT
MVI E,3 ;ELSE SET FOR DASH
CW3: PUSH B ;SAVE COUNT
PUSH PSW ;SAVE CODE
CALL unshift ;Send mark tone
MOV C,E ;GET TIME
CALL DELAYX
CALL shift ;Send space tone
MVI C,1
CALL DELAYX ;WAIT 1 DOT TIME
POP PSW ;RESTORE CODE
POP B ;RESTORE COUNT
DCR B ;COUNT DOWN
JNZ CW2 ;LOOP TILL FINISHED
RET
;THIS TIMES 1 DIT.
DELAYX: MOV A,C
ORA A
RZ
PUSH B
PUSH D
DLY1: LXI D,50 ;50 MS DELAY
CALL delayd
DCR C
JNZ DLY1
POP D
POP B
RET
;
;Frequency shift keying routines
;
unshift:
PUSH PSW
lda mark
call out$modsftp
POP PSW
RET
;
shift:
PUSH PSW
lda space
call out$modsftp
POP PSW
RET
;
;txon/txoff. Key the transmitter by setting
; DTR on and off with appropriate
; delays.
;
txon: push psw ;SAVE A
lda ptton ;DTR=0
call out$modctlp ;Turn on transmitter
pop psw ;Get A
push h ;Save HL
lhld timer ;Get value of timer
call delayh ;Wait for full power
lhld timer ;Do it again
call delayh ;..yet
pop h ;Restore HL
ret
txoff: push psw ;Save A
push h ;Save HL
lhld timer ;Get value of timer
call delayh ;Delay a little while other end is coming up
pop h ;Restore HL
busy: call in$modctlp ;Get status
call ani$modsndb ;Mask ready bit
call cpi$modsndr ;Ready?
jnz busy ;..No, wait
lda pttoff ;DTR=1
call out$modctlp ;Turn off transmitter
pop psw ;get A
call in$moddatp ;Clear garbage
call in$moddatp ;..again
ret
;
;
;This is a delay routine
;Enter at delayh with delay in ms. in HL or
; enter at delayd with delay in ms. in DE
delayh: xchg
call delayd
xchg
ret
delayd: call wait
dcx d
mov a,e
ora d
jnz delayd
ret
wait: push psw
lda fastclk ;FF=4 Mhz, 00=2 Mhz
ora a
jz wait1
mvi a,216 ;Multiples of 108 for North Star(Z80)
jmp wait2 ;..to give 1 millisecond delay
wait1: mvi a,108 ;..in this routine.
wait2: dcr a
nop
jnz wait2
pop psw
ret
;
SENDFN LDA QFLG
ORA A
JZ SWNAK
CALL ILPRT
DB 'AWAITING NAME NAK',CR,LF,0
SWNAK CALL WAITNLP
call txon
MVI A,ACK ;GOT NAK, SEND ACK
CALL SEND
call txoff
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: call txon
MVI A,EOT
CALL SEND
call txoff
STC
RET
SENDNM: PUSH H
SENDNM1:
MVI D,11 ;COUNT CHARS IN NAME
MVI C,0 ;INIT CHECKSUM
LXI H,FCB+1 ;ADDRESS NAME
NAMLPS: call txon
MOV A,M ;SEND NAME
ANI 7FH ;STRIP HIGH ORDER BIT SO CP/M 2..
CALL SEND ;..WON'T SEND R/O FILE DESIGNATION.
call txoff
LDA QFLG ;SHOW NAME IF..
ORA A ;..QFLG NOT SET.
MOV A,M
CNZ TYPE
ACKLP: PUSH B ;SAVE CKSUM
MVI B,2 ;WAIT FOR RECEIVER
CALL recvdg ;..TO ACKNOWLEDGE
POP B ;..GETTING LETTER
JC SCKSER
CPI ACK
JNZ ACKLP
INX H ;NEXT CHAR
DCR D
JNZ NAMLPS
call txon
MVI A,EOFCHAR ;TELL RECEIVER END OF NAME
CALL SEND
call txoff
LDA QFLG
ORA A
CNZ CRLF
MOV D,C ;SAVE CHECKSUM
MVI B,2
CALL recvdg ;GET CHECKSUM
CMP D ;..FROM RECEIVER.
JZ NAMEOK
SCKSER: call txon
MVI A,BDNMCH ;BAD NAME-TELL RECEIVER
CALL SEND
call txoff
LDA QFLG
ORA A
JZ SKCSER1
CALL ILPRT
DB 'CHECKSUM ERROR',CR,LF,0
SKCSER1: ;Do handshaking over
CALL WAITNLP
call txon
MVI A,ACK
CALL SEND
call txoff
JMP SENDNM1
NAMEOK: call txon
MVI A,OKNMCH ;GOOD NAME-TELL RECEIVER
CALL SEND
call txoff
POP H
RET
GETFN: LXI H,FCB
CALL INITFCBS+2 ;DOES NOT INITIALIZE DRIVE
LDA QFLG
ORA A
JZ GNAMELP
CALL ILPRT
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 NOMRNMG
ORA A ;CLEAR CARRY
RET
NOMRNMG:
STC
RET
GETNM: PUSH H
GETNM1: MVI C,0 ;INIT CHECKSUM
LXI H,FCB+1
NAMELPG:
MVI B,5
CALL recvdg ;GET CHAR
JNC GETNM3
LDA QFLG
ORA A
JZ GETNM2
CALL ILPRT
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 QFLG ;TYPE IT IF NO QFLG
ORA A
MOV A,M
CNZ TYPE
PUSH B ;SAVE CKSUM
call txon
MVI A,ACK ;ACK GETTING LETTER
CALL SEND
call txoff
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
call txon
MOV A,C ;SEND CHECKSUM
CALL SEND
call txoff
MVI B,2
CALL recvdg ;CHECKSUM GOOD?
CPI OKNMCH ;YES IF OKNMCH 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 GCKSER1
CALL ILPRT
DB 'CHECKSUM ERROR',CR,LF,0
GCKSER1 CALL HSNAK ;DO HANDSHAKING OVER
JC GCKSER1
JMP GETNM1
GNRET POP H
RET
HSNAK: call txon
MVI A,NAK ;SEND NAK UNTIL..
CALL SEND ;..RECEIVING ACK.
call txoff
CALL CKABORT ;DON'T GET HUNG UP HERE
MVI B,5 ;WAIT 2 SECONDS
CALL recvdg ;..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
CPI 65 ;NO MORE THAN 64 TRANSFERS
RC
MVI A,64 ;ONLY X'FER FIRST 64
STA FILECT
RET
;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
SCANLP1 INX H
DCR B
JZ DNSCAN
MOV A,M
CPI 20H
JNZ SCANLP1
SCANLP2 INX H ;EAT EXTRA SPACES
DCR B
JZ DNSCAN
MOV A,M
CPI 20H
JZ SCANLP2
SHLD BGNMS ;SAVE START OF NAMES IN CMDBUF
INR B
DCX H
SCANLP3 INX H
DCR B
JZ DNSCAN
MOV A,M
CPI 20H
JNZ SCANLP3
LDA NAMECT ;COUNTS NAMES
INR A
STA NAMECT
SCANLP4 INX H ;EAT SPACES
DCR B
JZ DNSCAN
MOV A,M
CPI 20H
JZ SCANLP4
JMP SCANLP3
DNSCAN MVI M,20H ;SPACE AFTER LAST CHAR
POP H
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,23 ;RENAME
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
;MULTI-FILE ACCESS SUBROUTINE FROM CP/M USER'S GROUP
;FIXED BY MARK ZEIGER 8/17/80
;CARRY IS SET IF NO MORE NAMES CAN BE FOUND
MFNAME MFACCESS ;A MACRO IN MACROS.LIB
RCVSECT XRA A
STA ERRCT
RCVRPT: LDA QFLG
ORA A
JZ RCVSQ
CALL ILPRT
DB CR,'AWAITING # ',0
PUSH H ;SAVE IT
LHLD SECTNO ;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
MOV A,L ;ONLY THE LOW BYTE IS USED BY THE PROGRAM
POP H ;RESTORE IT
;
RCVSQ: MVI B,2
CALL RECV
JC RCVSTOT
CPI SOH
JZ RCVSOH
ORA A
JZ RCVSQ
CPI EOT
STC
RZ
MOV B,A
LDA VSEEFLG
ORA A
JZ RCVSEH
LDA QFLG
ORA A
JZ RCVSERR
RCVSEH call ilprt
db cr,lf,0
MOV A,B
CALL HEXO
CALL ILPRT
DB 'H RCD, NOT SOH',CR,LF,0
RCVSERR MVI B,1
CALL RECV
JNC RCVSERR
call txon
MVI A,NAK
CALL SEND
call txoff
LDA ERRCT
INR A
STA ERRCT
CPI ERRLIM
JC RCVRPT
LDA VSEEFLG
ORA A
JZ RCVCKQ
LDA QFLG
ORA A
JZ RCVSABT
RCVCKQ CALL CKQUIT
JZ RCVSECT
RCVSABT CALL CLOSFIL
CALL ERXIT
DB CR,LF,'++ UNABLE TO RECEIVE BLOCK -- ABORTING ++',CR,LF,'$'
RCVSTOT LDA VSEEFLG
ORA A
JZ RCVSPT
LDA QFLG
ORA A
JZ RCVSERR
RCVSPT CALL ILPRT
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 VSEEFLG
ORA A
JZ RCVBSE
LDA QFLG
ORA A
JZ RCVSERR
RCVBSE CALL ILPRT
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
call clrcrc ;clear crc counter
LXI H,80H
RCVCHR MVI B,1
CALL RECV
JC RCVSTOT
MOV M,A
INR L
JNZ RCVCHR
mvi e,2 ;nr of crc bytes
rcvcrc mvi b,1
call recv
jc rcvstot
dcr e
jnz rcvcrc
call chkcrc
ora a
jz chksnum
lda vseeflg
ora a
jz rcvcrer
lda qflg
ora a
jz rcvserr
;
rcvcrer call ilprt
db cr,lf,'++CRC err++ ',0
jmp rcvprn
chksnum LDA RCVSNO
MOV B,A
LDA SECTNO
CMP B
JZ RECVACK
INR A
CMP B
JNZ ABORT
RET
RECVACK CALL SENDACK
JMP RCVSECT
SENDACK:
call txon
MVI A,ACK
CALL SEND
call txoff
RET
;Transmitter is on when arrive here from SENDRPT
SENDHDR LDA QFLG
ORA A
JZ SENDHNM
CALL ILPRT
DB CR,'SEND # ',0
PUSH H
LHLD SECTNO ;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 SECTNO
CALL SEND
LDA SECTNO
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
;
sendcrc call fincrc
mov a,d
call send
mov a,e
call send
xra a
ret
;
;Transmitter turned of after return to SENDRPT
;
GETACK MVI B,7
CALL RECVDG
JC GETATOT
CPI ACK
RZ
MOV B,A
LDA QFLG
ORA A
JZ ACKERR
CALL ILPRT
DB CR,LF,0
MOV A,B
CALL HEXO
CALL ILPRT
DB 'H RCD, NOT ACK',CR,LF,0
ACKERR LDA ERRCT
INR A
STA ERRCT
CPI ERRLIM
RC
LDA VSEEFLG
ORA A
JZ GACKV
LDA QFLG
ORA A
JZ CSABORT
GACKV CALL CKQUIT
STC
RZ
CSABORT CALL ERXIT
DB CR,LF,'CAN''T SEND SECTOR -- ABORTING',CR,LF,'$'
GETATOT LDA QFLG
ORA A
JZ ACKERR
CALL ILPRT
DB CR,LF,'TIMEOUT ON ACK',CR,LF,0
JMP ACKERR
CKABORT:
CALL STAT
RZ
CALL KEYIN
CPI CAN
RNZ
ABORT LXI SP,STACK
ABORTL MVI B,1
CALL RECV
JNC ABORTL
call txon
MVI A,CAN
CALL SEND
call txoff
ABORTW MVI B,1
CALL RECV
JNC ABORTW
call txon
MVI A,' '
CALL SEND
call txoff
CALL ILPRT
DB CR,LF,'ROUTINE CANCELLED',CR,LF,BELL,0
MVI A,'B' ;TURN MULTI-FILE MODE..
STA BATCHFLG ;..OFF SO ROUTINE ENDS.
JMP DONETCE
INCRSNO PUSH H
LHLD SECTNO ;GET SECTOR NUMBER
INX H ;BUMP IT
SHLD SECTNO ;STORE IT
MOV A,L
POP H
RET
ERASFIL LDA BATCHFLG ;DON'T ASK FOR ERASE..
ORA A ;..IN MULTI-FILE MODE,..
JZ NOASK ;..JUST DO IT.
LXI D,FCB
MVI C,SRCHF
CALL BDOS
INR A
RZ
CALL ILPRT
DB 'FILES EXISTS -- TYPE ''Y'' TO ERASE: ',BELL,0
CALL KEYIN
PUSH PSW
CALL TYPE
POP PSW
CALL UCASE
CPI 'Y'
JNZ MENU
CALL CRLF
NOASK LXI D,FCB
MVI C,ERASE
CALL BDOS
RET
BLKFILE CALL ILPRT ;ROUTINE IF NO FILE IS NAMED FOR "SEND" OR "RECEIVE"
DB CR,LF,'No file specified',CR,LF,BELL,0
JMP MENU
MAKEFIL LXI D,FCB
MVI C,MAKE
CALL BDOS
INR A
RNZ
CALL ERXIT
DB 'ERROR - CAN''T MAKE FILE',CR,LF
DB 'DIRECTORY MUST BE FULL',CR,LF,'$'
CNREC: 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
OPENFIL LXI D,FCB
MVI C,OPEN
CALL BDOS
INR A
JNZ OPENOK
CALL ERXIT
DB 'CAN''T OPEN FILE$'
OPENOK LDA BATCHFLG
ORA A
JNZ OPENOK1
LDA QFLG
ORA A
RZ
OPENOK1 CALL ILPRT
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
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
JZ RDSECOK
DCR A
JZ REOF
CALL ERXIT
DB '++ FILE READ ERROR ++$'
RDSECOK 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
RET
WRERR: call txon
MVI C,CAN
CALL SEND
call txoff
CALL ERXIT
DB 'ERROR WRITING FILE',CR,LF,'$'
;----> 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 EQU $
CALL IN$MODDATP
CALL IN$MODDATP
RECV PUSH D
LDA FASTCLK
ORA A
JZ MSEC
MOV A,B
ADD A
MOV B,A
MSEC LXI D,15000
CALL CKABORT
MWTI CALL IN$MODCTLP
CALL ANI$MODRCVB
CALL CPI$MODRCVR
JZ MCHAR
DCR E
JNZ MWTI
DCR D
JNZ MWTI
DCR B
JNZ MSEC
POP D
STC
RET
MCHAR: CALL IN$MODDATP
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
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
SENDW CALL IN$MODCTLP
CALL ANI$MODSNDB
CALL CPI$MODSNDR
JNZ SENDW
POP PSW
CALL OUT$MODDATP
RET
WAITNAK LDA VSEEFLG
ORA A
JZ WAITNPR
LDA QFLG
ORA A
JZ WAITNLP
WAITNPR CALL ILPRT
DB 'AWAITING INITIAL NAK',CR,LF,0
WAITNLP CALL CKABORT ;Now waits indefinetly here. ^X to cancel.
MVI B,2
CALL RECV
CPI NAK
RZ
JMP WAITNLP
;
INITADR
LHLD 1
LXI D,3
DAD D
SHLD VSTAT+1
DAD D
SHLD VKEYIN+1
DAD D
SHLD VTYPE+1
RET
PROCOPT
LXI D,FCB+1
LDAX D
STA OPTION
OPTLP INX D
LDAX D
CPI ' '
JZ ENDOPT
LXI H,OPTBL
MVI B,OPTBE-OPTBL
OPTCK CMP M
JNZ OPTNO
MVI M,0
JMP OPTLP
OPTNO INX H
DCR B
JNZ OPTCK
JMP BADOPT
ENDOPT: LDA VSEEFLG
ORA A
RNZ
STA QFLG
RET
DONE: LDA BATCHFLG
ORA A
JNZ DONETCC
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
db ' ' ;Leave a couple of spaces
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 SECTORE NUMBERS..
LXI D,SECTNOB ;..FOR NEW FILE TRANSFER.
MVI B,SECTNOE-SECTNOB ;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 RCVFIL ;..THE FLAG IN MULTI-FILE MODE.
DONETCC MVI A,TRUE ;INDICATE NO FILES BEING..
STA FSTFLG ;RESET MULTIFILE TRANS
STA NFILFLG ;..USED IN TERMINAL ROUTINE.
CMA
STA SAVEFLG ;STOP MEMORY SAVE IN TERM ROUTINE.
LDA VSEEFLG
ORA A
JZ DONETC
LDA QFLG
ORA A
JZ donetce
DONETC CALL ILPRT
DB CR,LF,'ALL TRANSFERS COMPLETED'
DB CR,LF,BELL,0
DONETCE:
LDA TERMFLG ;SEE IF RETURN TO..
ORA A ;..TERMINAL MODE..
JNZ MENU ;..AFTER X'FER.
CALL CRLF
JMP termint
MOVEFCB LXI H,FCB+16
LXI D,FCB
MVI B,16
CALL MOVE
XRA A
STA FCBSNO
STA FCBEXT
RET
SHOW CPI LF
JZ CTYPE
CPI CR
JZ CTYPE
CPI 9
JZ CTYPE
CPI ' '
JC SHOWHEX
CPI 7FH
JC CTYPE
SHOWHEX PUSH PSW
MVI A,'('
CALL CTYPE
POP PSW
CALL HEXO
MVI A,')'
JMP CTYPE
CTYPE PUSH B
PUSH D
PUSH H
MOV E,A
MVI C,WRCON
CALL BDOS
POP H
POP D
POP B
RET
CRLF PUSH PSW
MVI A,CR
CALL TYPE
MVI A,LF
CALL TYPE
POP PSW
RET
TYPE PUSH PSW
PUSH B
PUSH D
PUSH H
MOV C,A
VTYPE CALL $-$
POP H
POP D
POP B
POP PSW
RET
STAT PUSH B
PUSH D
PUSH H
VSTAT CALL $-$
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
;----> DHXOUT: - double precision hex output routine.
DHXOUT: PUSH H
PUSH PSW
MOV A,H ;GET MS BYTE
CALL HEXO ;OUTPUT HIGH ORDER BYTE
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 TYPE
;RETURNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN
;NO QUESTIONS ASKED, JUST QUIT
CKQUIT LDA BATCHFLG
ORA A
JNZ 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 CRLF
POP PSW
CALL UCASE ;INSTEAD OF "ANI 5FH"
CPI 'R'
RZ
CPI 'Q'
JNZ CKQUIT
ORA A
RET
ILPRT XTHL
ILPLP MOV A,M
ORA A
JZ ILPRET
CALL CTYPE
INX H
JMP ILPLP
ILPRET XTHL
RET
PRTMSG MVI C,PRINT
JMP BDOS
ERXIT POP D
CALL PRTMSG
CALL ILPRT
DB BELL,0
LDA BATCHFLG
ORA A
JNZ DONETCE
MVI A,'Q' ;RESET QFLG
STA QFLG
JMP ABORT ;ABORT OTHER COMPUTER
EXIT LXI D,80H
MVI C,STDMA
CALL BDOS
JMP 0
MOVE128 MVI B,128
MOVE MOV A,M
STAX D
INX H
INX D
DCR B
JNZ MOVE
RET
;INITIALIZES CP/M FILE CONTROL BLOCKS AT 5CH AND 6CH
SETFCB LXI D,CMDBUF
LXI H,FCB
CALL CPMLINE
CALL PROCOPT
CHECKNM LDA FCB+1 ;CHECK ON THE PRIMARY OPTION
CPI 'M' ;RETURN TO MENU
RZ
CPI 'T'
JZ TERMSEL
CPI 'S'
JZ CKFILE
CPI 'R'
JNZ BDOPT
LDA BATCHFLG ;IF MULT FILE MODE, THEN..
ORA A ;..RECV OPT DOES NOT NEED..
RZ ;..NAME.
JMP CKFILE
BDOPT CALL ILPRT
DB CR,LF,'++Bad Option++',CR,LF,0
JMP REENT
CKFILE LDA FCB+17 ;IF OPTION THAT NEEDS FILE NAME,..
CPI ' ' ;..THEN CHECK TO SEE IF NAME..
RNZ ;..EXISTS. IF NOT..
REENT CALL ILPRT ;..DO EVERYTHING OVER.
DB CR,LF,'Re-enter PRIMARY option and file name only: ',BELL,0
LXI D,CMDBUF
CALL INBUFF
JMP SETFCB
TERMSEL LDA FCB+17
CPI ' '
JNZ SAVAGN
MVI A,FALSE
STA SAVEFLG
MVI A,TRUE
STA NFILFLG
CMA
RET
SAVAGN MVI A,FALSE
STA NFILFLG
RET
;
;************************************************************************
;* CRCSUBS (Cyclic Redundancy Code Subroutines) version 1.20 *
;* 8080 Mnemonics *
;* *
;* These subroutines will compute and check a true 16-bit *
;* Cyclic Redundancy Code for a message of arbitrary length. *
;* *
;* The use of this scheme will guarantee detection of all *
;* single and double bit errors, all errors with an odd *
;* number of error bits, all burst errors of length 16 or *
;* less, 99.9969% of all 17-bit error bursts, and 99.9984% *
;* of all possible longer error bursts. (Ref: Computer *
;* Networks, Andrew S. Tanenbaum, Prentiss-Hall, 1981) *
;* *
;* Designed & coded by Paul Hansknecht, June 13, 1981 *
;* *
;* Copyright (c) 1981, Carpenter Associates *
;* Box 451 *
;* Bloomfield Hills, MI 48013 *
;* 313/855-3074 *
;* *
;* This program may be freely reproduced for non-profit use. *
;* *
;************************************************************************
;
; ENTRY CLRCRC,UPDCRC,FINCRC,CHKCRC
;
CLRCRC: EQU $ ; Reset CRC Accumulator for a new message.
PUSH H
LXI H,0
SHLD CRCVAL
POP H
RET
;
UPDCRC: EQU $ ; Update CRC Accumulator using byte in (A).
PUSH PSW
PUSH B
PUSH H
MVI B,8
MOV C,A
LHLD CRCVAL
;
UPDLOOP:MOV A,C
RLC
MOV C,A
MOV A,L
RAL
MOV L,A
MOV A,H
RAL
MOV H,A
JNC SKIPIT
MOV A,H ; The generator is X^16 + X^12 + X^5 + 1
XRI 10H ; as recommended by CCITT.
MOV H,A ; An alternate generator which is often
MOV A,L ; used in synchronous transmission protocols
XRI 21H ; is X^16 + X^15 + X^2 + 1. This may be
MOV L,A ; used by substituting XOR 80H for XOR 10H
SKIPIT: DCR B ; and XOR 05H for XOR 21H in the adjacent code.
JNZ UPDLOOP
SHLD CRCVAL
POP H
POP B
POP PSW
RET
;
FINCRC: EQU $ ; Finish CRC calc for outbound message.
PUSH PSW
XRA A
CALL UPDCRC
CALL UPDCRC
PUSH H
LHLD CRCVAL
MOV D,H
MOV E,L
POP H
POP PSW
RET
;
CHKCRC: EQU $ ; Check CRC bytes of received message.
PUSH H
LHLD CRCVAL
MOV A,H
ORA L
POP H
RZ
MVI A,0FFh
RET
;
CRCVAL: DW 0
;
MENU: LXI H,RESTSN ;RESTORE SECTORE NUMBERS..
LXI D,SECTNOB ;..FOR NEW FILE TRANSFER.
MVI B,SECTNOE-SECTNOB
CALL MOVE
LXI H,RESTROPT ;RESTORE OPTION TABLE
LXI D,OPTBL
MVI B,OPTBE-OPTBL
CALL MOVE
MVI A,0
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,CR,LF,0
if h19term
call ilprt
db esc,'E',0 ;Clear screen
endif
call ilprt
db '*PRIMARY OPTIONS* *SECONDARY OPTIONS*'
db cr,lf,lf
DB 'WRT- Write file to disk(terminal mode) '
db 'B- Multi file transfer(send or recv)',cr,lf
DB 'DEL- Erase present file(terminal mode) '
db 'T- Return to Terminal after transfer',cr,lf
DB 'RET- Return to terminal mode(save data) '
db 'Q- Quiet transfer(fatal messages only)',cr,lf
DB 'XPR- Toggle expert mode (Menu on/off) '
db 'V- View what is sent and received',cr,lf
DB 'DIR- List directory(may specify drive) '
db 'S- View what is sent during transfer',cr,lf
DB 'CPM- Exit to CP/M '
db 'R- View what is rcvd during transfer',cr,lf
DB 'S - Send CP/M file',CR,LF
DB 'R - Receive CP/M file',CR,LF
DB 'T - Terminal mode (optional file name)',CR,LF,lf
db '*TERMINAL MODE FUNCTIONS*',cr,lf,lf
if h19term
db 'f1 Key - Transmit CWID',cr,lf
db 'f2 Key - Send a line (Press f2 first, enter up to 80'
db ' characters then press CR)',cr,lf
db 'f3 Key - Initiate blind file transfer',cr,LF
db 'f4 Key - Toggle file save mode(File previously named'
db ' at "T")',cr,lf
db 'f5 Key - Exit terminal mode',cr,lf
db 'Blue Key - Transmitter OFF',cr,lf
db 'Red Key - Transmitter ON',cr,lf
db 'White Key- Transmitter ON, automatic OFF on CR',cr,0
endif
if not h19term
db '^E - Exit terminal mode',cr,lf
db '^Y - Toggle file save mode(File previously named'
db ' at "T")',cr,lf
db '^T - Initiate blind file transfer',cr,LF
db 'ESC S- Transmit CWID',cr,lf
db 'ESC T- Send a line (Enter ESC T first, enter up to 80'
db ' characters then press CR)',cr,lf
db 'ESC P- Transmitter OFF',cr,lf
db 'ESC Q- Transmitter ON',cr,lf
db 'ESC R- Transmitter ON, automatic OFF on CR',cr,0
endif
XPRT CALL ILPRT
DB CR,LF,CR,LF,'DEFAULT DRIVE: ',0
MVI C,25 ;CURRENT DISK FUNCTION
CALL BDOS
ADI 41H ;MAKE ASCII
CALL TYPE
call ilprt
db ' ',0
if h19term
call ilprt
db esc,'p',0
endif
CALL ILPRT
DB ' Command? '
DB 0
if h19term
call ilprt
db esc,'q',0
endif
GETCMD 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 'RET',0
JC NXTOPT1 ;CARRY SET = NO MATCH
LHLD HLSAVE ;RETURN TO TERMINAL..
JMP termint ;..MODE WITH SAVE OPTION..
;..IF PREVIOUSLY ENABLED.
NXTOPT1:
CALL ILCOMP
DB 'WRT',0
JNC WRTFIL
CALL ILCOMP
DB 'XPR',0
JNC XPRMODE
CALL ILCOMP
DB 'DEL',0
JNC NEWFILE
NXTOPT2 PUSH H
LDA CMDBUF+2
LXI H,COMPLIST
CALL COMPARE ;COMPARES LIST POINTED TO BY HL..
POP H ;..TO CHAR IN A-REG.
JC MENU1 ;CARRY SET = NO MATCH
DOOPT PUSH H ;LOAD ORIGINAL FCB WITH TRANSFER..
CALL SETFCB ;..CMDS AND GO TO BEGINNING OF..
POP H ;..PROGRAM. WILL FOLLOW SAME LOGIC..
JMP RESTART ;..AS IF PROGRAM WERE CALLED WITH..
;..CP/M COMMAND LINE.
DIR CALL DIRLST
JMP XPRT
NEWFILE LDA FCB3+1
CPI ' '
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..
CMA ;..SPECIFIED.
STA SAVEFLG
LXI H,FCB3
CALL INITFCBS
JMP MENU1
WRTFIL LDA NFILFLG
CPI TRUE
JZ MENU1
LDA FCB3+1 ;CHECK THAT FILE WAS REQUESTED
CPI ' '
JZ MENU1
LHLD HLSAVE
CALL NUMRECS ;DISK WRITE ROUTINE AS USED IN..
CALL WRTDSK ;..IN THE INTDSKSV ROUTINE.
CALL CLOSE3
MVI A,TRUE
STA NFILFLG
CMA
STA SAVEFLG
LXI H,FCB3
CALL INITFCBS ;BLANK OUT FCB SO WRITTEN FILE..
JMP MENU1 ;..CAN'T BE ERASED.
XPRMODE LDA XPRFLG
CMA
STA XPRFLG
JMP MENU1
COMPARE MOV B,M ;COMPARES A-REG WITH LIST..
COMPLP INX H ;..ADDRESSED BY HL. FIRST ELEMENT..
CMP M ;..OF LIST MUST BE NUMBER OF ELEMENTS..
JZ VALID ;..BEING COMPARED. RETURNS WITH..
DCR B ;..CARRY SET IF A-REG DOES NOT..
JNZ COMPLP ;.. CONTAIN AN ELEMENT IN LIST.
STC
VALID RET
;
;
COMPLIST DB 4, 'S', 'R', 'T', 'M'
ILCOMP INLNCOMP ;A MACRO IN MACROS.LIB
INBUFF INBUF ;A MACRO IN "MACROS.LIB"
CPMLINE CMDLINE ;A MACRO IN "MACROS.LIB"
DIRLST DIRLIST ;A MACRO IN "MACROS.LIB"
NFILFLG DB FALSE ;NORMALLY SET TO FALSE. ALLOWS WRITE TO..
;..MEMORY IN TERMINAL MODE.
OPTION DB 0
OPTBL EQU $
QFLG DB 'Q'
RSEEFLG DB 'R'
SSEEFLG DB 'S'
VSEEFLG DB 'V'
TERMFLG DB 'T'
BATCHFLG DS 1 ;SET TO 'B' BY MENU. DOES NOT ALLOW MULTI-..
OPTBE EQU $ ;..FILE XFER WHEN PROGRAM INITIALLY CALLED.
RESTROPT ;MUST BE IN SAME ORDER AS TABLE ABOVE
DB 'Q','R','S','V','T','B'
RESTSN DB 0,0,0,0,0
DW DBUF
DB 0,0,0,0,0,0
SECTNOB EQU $
RCVSNO DB 0
SECTNO DW 0
ERRCT DB 0
EOFLG DB 0
SECPTR DW DBUF
SECINBF DB 0
MAXEXT DB 0
RCNT DW 0
DATAFLG DB 0
EXACFL DB 0
SECTNOE EQU $
BADOPT CALL ILPRT
DB 'INVALID OPTION',CR,LF,BELL,0
JMP MENU
FSTFLG DB TRUE
CMDBUF DB 80H,0
DS 80H
HLSAVE DS 2
DISKNO DS 1
SENDFLG DS 1
NBSAVE DS 2
BGNMS DS 2
FILECT DS 1
NAMECT DS 1
DS 60
STACK DS 2
FCB3 DS 33
FCBBUF DS 15
linebuf ds 82
DBUF EQU $
NAMEBUF EQU DBUF+(DBUFSIZ*1024) ;BUFFER FOR NAMES IN BATCH MODE. OVERFLOWS..
;..ABOVE PROGRAM CODE.
; BDOS EQUATES
RDCON EQU 1
WRCON EQU 2
PRINT EQU 9
RDBUF EQU 10
CONST EQU 11
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
REIPL EQU 0
FCB EQU 5CH
FCBEXT EQU FCB+12
FCBSNO EQU FCB+32
FCBRNO EQU FCB+32
FCB2 EQU 6CH
LAST END 100H