home *** CD-ROM | disk | FTP | other *** search
- 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
-