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
/
CPM
/
CPM86
/
MDM9IBM1.A86
< prev
next >
Wrap
Text File
|
2000-06-30
|
116KB
|
6,020 lines
; MODEM901, a 16-bit "MODEM" program for CP/M-86
;
; by: Michael J. Mellinger,
; Data Research Associates, Inc.,
; 9270 Olive Boulevard,
; St. Louis,
; Missouri, 63132,
; U.S.A.
;
; Many, many fixes to Mike's original translation and
; further translation by:
;
; Bill Bolton,
; Software Tools RCPM,
; P.O. Box 80,
; Newport Beach,
; NSW, 2106,
; Australia
;
;*****************************************************************************
; Converted for IBM PC-XT. Most changes and fixes marked
; with "@DH".
;
; by: Dick Hill
; (AMS) Advanced Micro Systems
; 2304 McCord Road
; Valparaiso, IN 46383
;
;*****************************************************************************
;
;VERSION LIST, most recent version first
;
;30/DEC/84 Added option to change baud rate from terminal mode.
; Word length, parity, stop bits not affected.
; MODEM 9.01.IBM-1.1 Dick Hill
;
;24/Dec/84 Converted for IBMPC. Changed version to MODEM 9.01.IBM-1.0.
; Many changes and fixes. Hopefully all marked with "@DH".
;
;***KNOWN PROBLEMS:*** When the IBM and a CP/M 80 system running a
; Z80 B at 6 mhz are hooked up back to back the IBM can not keep
; up at baud rates faster than 1200 baud when receiving a file.
; No problem at any baud rate when the IBM is sending and the Z80 B
; is receiving. Everything else seems to work.
;
; HOW TO: ASM86 MODM9IBM $PZ
; GENCMD MODM9IBM 8080
;
;25/Nov/83 Fixed batch bugs, changed to proper speed calculations,
; fixed printer support, fixed batch file name problems.
;
;24/Sep/83 Fixed many bugs, properly implemented command line
; processor, added new USART implementations for SYS
; module. Tidied up documentation and added version
; lists etc. Basically made it work right!
; Version 9.01.04. Bill Bolton
;
;08/Jul/83 Original quick translation from CP/M-80 code.
; Version 9.01.02. Michael Mellinger
;
; See the file MODEM-86.DOC for further details, otherwise
; the existing CP/M-80 MODEM901 documentation applies.
;
; Clearing house for comments, changes, suggestions:
; (No guarantee of response and no liability assumed)
;
;U.S.A. Thousand Oaks Technical RCP/M
; 805-492-5472
;
;AUSTRALIA Software Tools RCPM
; (02) 997-1836 (CCITT V21 standard,
; Bell 103 won't work!)
;
; MODEM9
;
;BASED ON THE CP/M-80 MODEM PROGRAM CREATED BY WARD CHRISTENSEN
;
; ********* N O T I C E S *********
;
; Revisers releasing new versions should only
; change the version number by the digits in
; the last 2 places, i.e. 9.01.??
;
; This program is in the public domain, please
; respect the massive effort of the CP/M-86
; "translators" by leaving their names intact
; in the signon message.
;
; At the same time we wish to give full credit to
; the many individuals who created the CP/M-80
; version of MODEM901, and wish to thank them for
; their efforts (and especially Ward for starting
; it all!).
;
; **********************************
;
;This is just a header file to give the HEX output the right name.
;
;
; INCLUDE DEFF.A86
; INCLUDE START.A86
; INCLUDE SYS.A86 ;Rename your XXXXSYS.A86 to this
; INCLUDE MAIN.A86
; INCLUDE CONSOLE.A86
; INCLUDE TERM.A86
; INCLUDE SENDRECV.A86
; INCLUDE FILES.A86
; INCLUDE FINISH.A86
;
; DEFF.A86
;
;Deffinitions for use in assembling MODEM9.xx.
;
TRUE EQU 0FFH
FALSE EQU 0
;
CPM2X EQU TRUE ;TRUE IF CP/M 2.X
DBUFSIZ EQU 16 ;BUFFER SIZE FOR FILE TRANSFER IN KBYTES
CAPTURE EQU 16 ;Buffer size for text capture
;
ERRCRC EQU 6 ;NUMBER OF TIMES TO TRY CRC MODE BEFORE
;SWITCHING TO CHECKSUM
ERRLIM EQU 10 ;NUMBER OF TIMES TO RETRY
;SEND/RECEIVE ERRORS BEFORE QUIT
;
CRC EQU 'C' ;USED TO REQUEST 'CRC' INSTEAD OF 'CKSUM'
ESC EQU '['-40H ; ^[ = ESCAPE
SOH EQU 'A'-40H ; ^A = START OF HEADER
EOT EQU 'D'-40H ; ^D = END OF TEXT
ACK EQU 'F'-40H ; ^F = ACKNOWLEDGE
OKNMCH EQU 'F'-40H ; ^F = OKAY NAME MATCH
BELL EQU 'G'-40H ; ^G = BELL CHARACTER
BKSP EQU 'H'-40H ; ^H = BACKSPACE
TAB EQU 'I'-40H ; ^I = TAB
LF EQU 'J'-40H ; ^J = LINEFEED
CR EQU 'M'-40H ; ^M = CARRIAGE RETURN
XON EQU 'Q'-40H ; ^Q = XON CHARACTER
XOFF EQU 'S'-40H ; ^S = XOFF CHARACTER
NAK EQU 'U'-40H ; ^U = NOT ACKNOWLEDGE
CAN EQU 'X'-40H ; ^X = CANCEL SEND/RECEIVE
EOFCHAR EQU 'Z'-40H ; ^Z = END OF FILE
SPACE EQU ' ' ; SPACE
BDNMCH EQU 75H ; BAD NAME MATCH
RUB EQU 7FH ; RUB
;
;BDOS EQUATES
;
RDCON EQU 1
WRCON EQU 2
LSTOUT EQU 5
DCONIO EQU 6
PRINT EQU 9
RDBUF EQU 10
CONST EQU 11
RESET EQU 13
SELDSK EQU 14
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
CURDSK EQU 25
STDMA EQU 26
GETALC EQU 27 ;CP/M ALLOCATION VECTOR ADDRESS
GETPARM EQU 31 ;CURRENT DISK PARAMETERS ADDRESS
USER EQU 32
FILSIZ EQU 35
REIPL EQU 0
FCB EQU 5CH
FCBEXT EQU FCB+12
FCBSNO EQU FCB+32
FCBRNO EQU FCB+32
FCB2 EQU 6CH
;
; START.A86
;
;This file is for making changes to MODEM9.xx which are not UART/MODEM
;specific. UART/MODEM suport is provided by the various SYS files.
;
;The user can make the following changes in this file:
;
; a) Set the TRUE/FALSE statements in the lookup table which
; begins with BAKUPBYTE and ends with EOFSEND
; b) Change the control characters that are used for local commands,
; this sequence starts with EXITCHR and ends with EXTCHR
; c) Set STRGOK to TRUE and enter up to ten strings at location
; STRINGS. These strings can be logon sequences or frequently
; used commands that are sent to a remote computer
;
;
STRGOK EQU FALSE ;change to TRUE if you want to define
;strings, such as logon sequences, for
;transmission. Up to 10 strings may be
;entered at location STRINGS in this file.
;
;*** Don't change the ORG locations in this file or in the files ***
;*** SETUP and MAIN. This ORG statements provide standard locations ***
;*** for modification by overaly files or DDT. ***
;
CSEG
ORG 0100H
;
JMP START
;
BAKUPBYTE DB TRUE ;true=make .BAK file
CKSUMDFLT DB FALSE ;true=default to Checksum checking
;false=default to CRC checking
TOGGLECRC DB TRUE ;true=allow toggling of Checksum to CRC
CONVBKSP DB FALSE ;true=convert backspace to rub
TOGGLEBK DB TRUE ;true=allow toggling of bksp to rub
ADDLF DB TRUE ;true=add LF after CR
TOGGLELF DB TRUE ;true=allow toggling of LF after CR
STRLF DB FALSE ;true=strip LF after CR in terminal file output
TOGSLF DB TRUE ;true=toggle strip LF after CR in file output
LOCONEXTCHR DB FALSE ;true=local command if EXTCHR precedes
;false=not local command if EXTCHR precedes
TOGGLELOC DB TRUE ;true=allow toggling of LOCONEXTCHR
LSTTST DB TRUE ;true=allow toggling of printer on/off
;in terminal mode. Set to false if your
;printer can't keep up with the modem
XOFFTST DB FALSE ;true=allow testing of XOFF from remote
;while transmitting a file in terminal mode
XONWAIT DB FALSE ;true=wait for XON after sending CR while
;transmitting a file in terminal mode
TOGXOFF DB TRUE ;true=allow toggling of XOFF/XON testing
ECHWAIT DB FALSE ;true=wait for echo before sending next
;character in terminal mode file output
EOFSEND DB FALSE ;true=send eof in terminal mode file output
NAKONLY DB FALSE ;true=resends a record only after a valid NAK
;false=resends a record after any non-ACK
;true is intended only for use with mainframes
;that send, for example, xoff when buffer is
;full
;
SETUPTST DB SETUP
SCRNTEST DB SCRNCLR
TRANLOGON DB STRGOK
DISCFLG DB DISCON
CARDETFLG DB CARDET
CLOCK DB CLKRATE
;
MSPEED DB 4 ;sets the display time to send a file
;0=110 1=300 2=450 3=600 4-1200 @DH
;5=2400 6=4800 7=9600 8=19200 @DH
; ;0=110 1=300 2=600 3=1200 @DH
; ;4=2400 5=4800 6=9600 7=19200 @DH
BYTDLY DB 0 ;default time to send character in
;terminal mode file transfer
;0=0 delay, 1=0.02 sec, -- ,9=0.18 sec
CRDLY DB 0 ;default time for extra wait after CR
;in terminal mode file transfer
;0=0 delay, 1=0.02 sec, -- ,9=0.18 sec
BELRPT DB 10 ;bell repeat time = value*0.03 sec
NOOFCOL DB 5 ;number of directory columns, currently
;set for 80 column screen
;
BAUDCHR DB 'B'-40H ; ^B = Change baud rate 30/DEC/84 @DH
; from terminal mode @DH
EXITCHR DB 'E'-40H ; ^E = Exit without disconnect
LOGCHR DB 'O'-40H ; ^O = Send logon
LSTCHR DB 'P'-40H ; ^P = Toggle printer
UNSAVECHR DB 'R'-40H ; ^R = Close input text buffer
TRANCHR DB 'T'-40H ; ^T = Transmit file to remote
SAVECHR DB 'Y'-40H ; ^Y = Open input text buffer
EXTCHR DB '^'-40H ; ^^ = Send next character
;
VERNUM: CALL ILPRT
DB CR,LF
DB 'MODEM 9.01.IBM-1.1 - 30/Dec/84'
DB CR,LF,LF
DB 'CP/M-86 version by Michael Mellinger and Bill Bolton'
DB CR,LF,LF
DB 'CP/M-86-IBM version by Dick Hill'
DB CR,LF,LF,0
JMP SYSVER
;
;ALL STRINGS MUST BE 31 CHARACTERS OR LESS AND MUST BE TERMINATED WITH 0
;
STRINGS:
DB 'STRING #0 at 240H',0
RB (OFFSET STRINGS)-(OFFSET $)+32*1
DB 'STRING #1 at 260H',0
RB (OFFSET STRINGS)-(OFFSET $)+32*2
DB 'STRING #2 at 280H',0
RB (OFFSET STRINGS)-(OFFSET $)+32*3
DB 'STRING #3 at 2A0H',0
RB (OFFSET STRINGS)-(OFFSET $)+32*4
DB 'STRING #4 at 2C0H',0
RB (OFFSET STRINGS)-(OFFSET $)+32*5
DB 'STRING #5 at 2E0H',0
RB (OFFSET STRINGS)-(OFFSET $)+32*6
DB 'STRING #6 at 300H',0
RB (OFFSET STRINGS)-(OFFSET $)+32*7
DB 'STRING #7 at 320H',0
RB (OFFSET STRINGS)-(OFFSET $)+32*8
DB 'STRING #8 at 340H',0
RB (OFFSET STRINGS)-(OFFSET $)+32*9
DB 'STRING #9 at 360H',0
;
;
;PHONE NUMBER LIBRARY TABLE.
;
;EACH DB MUST BE 32 CHARACTERS LONG FOR PROPER OPERATION.
;LAST DB MUST BE DB 0. UP TO 26 NUMBERS ARE ALLOWED.
;
NUMBLIB:
; '----5---10---15---20---25-----32'
DB 'A=Amrad 1-703-734-1387' ;'A'
DB 'B=Palatine RCPM 1-312-359-8080' ;'B'
DB 'C=CBBS Pasadena 1-213-799-1632' ;'C'
DB 'D=PMMI 1-703-379-0303' ;'D'
DB 'E=Tech. CBBS 1-313-846-6127' ;'E'
DB 'F=Ron Fowler 1-313-729-1905R' ;'F'
DB 'G=Gasnet NASA 1-301-344-9156' ;'G'
DB 'H=Dave Hardy 1-313-846-6127' ;'H'
DB 'I=Wayne Hammerly 1-301-953-3753' ;'I'
DB 'J=RBBS Pasadena 1-213-356-1034' ;'J'
DB 'K=David Kozinn 1-216-334-4604' ;'K'
DB 'L=Program Store 1-202-337-4694' ;'L'
DB 'M=Kelly Smith 1-805-527-9321' ;'M'
DB 'N=SuperBrain Sys 1-617-862-0781' ;'N'
DB 'O=R.L.Plouffe 1-703-524-2549' ;'O'
DB 'P=K.Petersen 1-313-759-6569R' ;'P'
DB 'Q=Bruce Ratoff 1-201-272-1874' ;'Q'
DB 'R=Mark Pulver 1-312-789-0499' ;'R'
DB 'S=Smokin Silicon 1-312-941-0049' ;'S'
DB 'T= ' ;'T'
DB 'U= ' ;'U'
DB 'V= ' ;'V'
DB 'W= ' ;'W'
DB 'X= ' ;'X'
DB 'Y= ' ;'Y'
DB 'Z= ' ;'Z'
DB 0 ; end
; '----5---10---15---20---25-----32'
;
; IBMSYS.A86
;
; For the IBM Personal Computer communications port.
;
;Used 8250SYS.ASM from CP/M 80 version of MODEM9 and 8251SYS.A86 from
;CP/M 86 version of MODEM9 to make this file. 12/24/84 - Dick Hill (AMS)
;
;Change the clock speed to suit your system.
CLKRATE EQU 4 ;clock speed in MHz, 8 MHz maximum
;
;Do not change the next three equates.
SETUP EQU TRUE
DISCON EQU TRUE
CARDET EQU TRUE
SCRNCLR EQU TRUE
;
;8250 equates.
;
MODRCVB EQU 01H ;bit to test for received data
MODRCVR EQU MODRCVB ;change to 0 if bit is 0 when
;data received
MODSNDB EQU 020H ;bit to test for ready to send
MODSNDR EQU MODSNDB ;change to 0 if bit is 0 when
;ready to send
;
MODDATP EQU 03F8H ;Serial Port 0 data
MODCTLP EQU MODDATP+5 ;Serial Port 0 status
;
;Control and status ports.
;
MODDLL EQU MODDATP ;divisor latch low
MODDLH EQU MODDATP+1 ;divisor latch high
MODIER EQU MODDATP+1 ;interrupt enable
;MODIIR EQU MODDATP+2 ;interrupt ident.
MODLCR EQU MODDATP+3 ;modem line control reg.
MODMCR EQU MODDATP+4 ;modem control reg.
;MODLSR EQU MODDATP+5 ;line status, same as MODCTLP
MODMSR EQU MODDATP+6 ;modem status reg.
;
;Control bytes
;
DISABL EQU 00H ;disable interrupts
LOOPNODTR EQU 10H ;set loop back, DTR off
ACCBAUD EQU 80H ;access baud rate divisor latches
DTR EQU 03H ;DTR and RTS on
WORDLEN EQU 3 ;8 bit word, 1 stop bit, no parity, no
;break, deaccess baud rate divisor
;latches
;
CLR1 EQU 1BH ;clear from cursor to
CLR2 EQU 'J' ;end of screen
CLR3 EQU 0
CLR4 EQU 0
;
SCLR1 EQU 1BH ;clear entire screen
SCLR2 EQU 'E' ;and home cursor
SCLR3 EQU 0
SCLR4 EQU 0
SCLR5 EQU 0
SCLR6 EQU 0
SCLR7 EQU 0
;
CLREOS: CALL ILPRT
;
DB CLR1,CLR2,CLR3,CLR4,0
RET
;
CLRSCRN: CALL ILPRT
;
DB SCLR1,SCLR2,SCLR3,SCLR4,SCLR5,SCLR6,SCLR7,0
RET
;
INMODCTLP: PUSH DX
MOV DX,MODCTLP
IN AL,DX
POP DX
RET
;
OUTMODDATP: PUSH DX
MOV DX,MODDATP
OUT DX,AL
POP DX
RET
;
INMODDATP: PUSH DX
MOV DX,MODDATP
IN AL,DX
POP DX
RET
;
ANIMODSNDB: AND AL,MODSNDB ;bit to test for send ready
RET
;
CPIMODSNDR: CMP AL,MODSNDR ;value of send bit when ready
RET
;
ANIMODRCVB: AND AL,MODRCVB ;bit to test for receive ready
RET
;
CPIMODRCVR: CMP AL,MODRCVR ;value of receive ready bit
RET
;
OUTMODMCR: PUSH DX
MOV DX,MODMCR
OUT DX,AL
POP DX
RET
;
OUTMODLCR: PUSH DX
MOV DX,MODLCR
OUT DX,AL
POP DX
RET
;
OUTMODIER: PUSH DX
MOV DX,MODIER
OUT DX,AL
POP DX
RET
;
OUTMODMSR: PUSH DX
MOV DX,MODMSR
OUT DX,AL
POP DX
RET
;
OUTMODDLL: PUSH DX
MOV DX,MODDLL
OUT DX,AL
POP DX
RET
;
OUTMODDLH: PUSH DX
MOV DX,MODDLH
OUT DX,AL
POP DX
RET
;
INMODMSR: PUSH DX
MOV DX,MODMSR
IN AL,DX
POP DX
RET
;
;This is where the message goes giving the system for
;which MODEM9 has been customized.
;
SYSVER:
CALL ILPRT
DB 'Set Up for: IBM Personal Computer',CR,LF,LF,0
RET
;
;The following is used to initialize the 8250 on execution
;of MODEM9.
;
INITMOD:
MOV AL,DISABL
CALL OUTMODIER
MOV AL,LOOPNODTR
CALL OUTMODMCR
MOV AL,ACCBAUD
CALL OUTMODLCR
MOV AL,MSPEED ;value for offset into baud table
MOV BX,OFFSET BDTABL ;point to baud table
MOV DX,0 ;initialize DX
ADD AL,AL ;X2 = offset into baud table for rate
MOV DL,AL ;put it in DX
ADD BX,DX ;point to baud rate
MOV AX,[BX] ;put baud divisor in AX..
;..AL=LSD, AH=MSD
PUSH AX ;put it on stack
MOV AL,AH ;get high order of divisor
CALL OUTMODDLH ;to high divisor latch
POP AX ;get low order of divisor
CALL OUTMODDLL ;to low divisor latch
MOV AL,WORDLEN
PARM1 EQU OFFSET $ - 1
CALL OUTMODLCR ;to line control reg.
MOV AL,DTR
CALL OUTMODMCR ;to modem control reg.
RET
;
;The following are parameters/masks used in setting word length
;stop bits and parity for the 8250.
;
MSKWD EQU 03H ;word length mask
SEVEN EQU 02H ;receive seven bit word
EIGHT EQU 03H ;receive eight bit word
MSKST EQU 04H ;stop bit mask
ONE EQU 00H ;one stop bit
TWO EQU 04H ;two stop bits
MSKPA EQU 18H ;mask for parity bits
NONE EQU 00H ;no parity
ODD EQU 08H ;odd parity
EVEN EQU 18H ;even parity
;
;The following routine changes the baud rate, stop bits and parity on
;the 8250 from the command level. Note the routine MUST modify the
;parameters used by the INITMOD routine.
;
SETUPR:
PUSH BX
CALL CLRTST
CALL ILPRT
DB ' IBM/UART/Modem Control',CR,LF,LF,LF
DB 'Current settings -',CR,LF,0
CALL SETTIM2
CALL GIVEPRM
CALL ILPRT
DB CR,LF
DB 'Enter choices below - <CR> for no change',CR,LF,0
AGAIN:
MOV DX,OFFSET BAUDBUF ;point to input buffer for ILCOMP
CALL ILPRT
DB 'Baud Rate (110, 300, 450, 600, 1200, 2400, 4800, 9600, 19200): ',0
CALL INBUFF
MOV DX,OFFSET BAUDBUF+2
CALL ILCOMP ;compare BAUDBUF+2 with characters below
DB '110',0
MOV AL,0
JNC OK ;go if got match
CALL ILCOMP
DB '300',0
MOV AL,1
JNC OK
CALL ILCOMP
DB '450',0
MOV AL,2
JNC OK
CALL ILCOMP
DB '600',0
MOV AL,3
JNC OK
CALL ILCOMP
DB '1200',0
MOV AL,4
JNC OK
CALL ILCOMP
DB '2400',0
MOV AL,5
JNC OK
CALL ILCOMP
DB '4800',0
MOV AL,6
JNC OK
CALL ILCOMP
DB '9600',0
MOV AL,7
JNC OK
CALL ILCOMP
DB '19200',0
MOV AL,8
JNC OK
CALL ILCOMP
DB ' ',0
JNC AGAIN2
CALL WRONG
JMP AGAIN ;try again
;
OK:
MOV MSPEED,AL
;
AGAIN2:
MOV DX,OFFSET BAUDBUF ;point to input buffer for ILCOMP
CALL ILPRT
DB CR,LF
DB 'Word Length (7, 8): ',0
CALL INBUFF
MOV DX,OFFSET BAUDBUF+2
CALL ILCOMP ;compare BAUDBUF+2 with characters below
DB '7',0
MOV AL,SEVEN
JNC OK2
CALL ILCOMP
DB '8',0
MOV AL,EIGHT
JNC OK2
CALL ILCOMP
DB ' ',0
JNC AGAIN3
CALL WRONG
JMP AGAIN2
;
OK2:
MOV WDLEN,AL
;
AGAIN3:
MOV DX,OFFSET BAUDBUF ;point to input buffer for ILCOMP
CALL ILPRT
DB CR,LF
DB 'Stop Bits (1, 2): ',0
CALL INBUFF
MOV DX,OFFSET BAUDBUF+2
CALL ILCOMP ;compare BAUDBUF+2 with characters below
DB '1',0
MOV AL,ONE
JNC OK3
CALL ILCOMP
DB '2',0
MOV AL,TWO
JNC OK3
CALL ILCOMP
DB ' ',0
JNC AGAIN4
CALL WRONG
JMP AGAIN3
;
OK3:
MOV STPLN,AL
;
AGAIN4:
MOV DX,OFFSET BAUDBUF ;point to input buffer for ILCOMP
CALL ILPRT
DB CR,LF
DB 'Parity (None, Even, Odd): ',0
CALL INBUFF
MOV DX,OFFSET BAUDBUF+2
CALL ILCOMP ;compare BAUDBUF+2 with characters below
DB 'NONE',0
MOV AL,NONE
JNC OK4 ;go if got match
CALL ILCOMP
DB 'EVEN',0
MOV AL,EVEN
JNC OK4
CALL ILCOMP
DB 'ODD',0
MOV AL,ODD
JNC OK4
CALL ILCOMP
DB ' ',0
JNC GOSET
CALL WRONG
JMP AGAIN4 ;try again
;
OK4:
MOV PARIT,AL
;
GOSET:
MOV AL,0
OR AL,WDLEN
OR AL,PARIT
OR AL,STPLN
MOV BYTE PTR .PARM1,AL
CALL ILPRT
DB CR,LF
DB 'New settings -',CR,LF,0
CALL SETTIM2
CALL GIVEPRM
POP BX
JMP INITMOD ;reset 8250
;
GIVEPRM:
CALL GETPRM
CALL ILPRT
DB 'Word length is ',0
MOV AL,WDLEN
CMP AL,SEVEN
JNZ NOTSEV
CALL ILPRT
DB 'seven',0
JMP GIVEST
NOTSEV:
CALL ILPRT
DB 'eight',0
GIVEST:
CALL ILPRT
DB ', number of stop bits is ',0
MOV AL,STPLN
CMP AL,ONE
JNZ NOTONE
CALL ILPRT
DB 'one',0
JMP GIVEPA
NOTONE:
CALL ILPRT
DB 'two',0
GIVEPA:
CALL ILPRT
DB ', parity is ',0
MOV AL,PARIT
CMP AL,NONE
JNZ NOTNON
CALL ILPRT
DB 'none',CR,LF,0
RET
NOTNON:
MOV AL,PARIT
CMP AL,ODD
JNZ NOTODD
CALL ILPRT
DB 'odd',CR,LF,0
RET
NOTODD:
CALL ILPRT
DB 'even',CR,LF,0
RET
;
GETPRM:
MOV AL,BYTE PTR .PARM1 ;get present word length
AND AL,MSKWD
MOV WDLEN,AL ;store it
MOV AL,BYTE PTR .PARM1 ;get present stop bits and parity
MOV CH,AL
AND AL,MSKST
MOV STPLN,AL ;store stop bits
MOV AL,CH
AND AL,MSKPA
MOV PARIT,AL ;store parity
RET
;
WRONG:
CALL ILPRT ;all matches failed - tell operator
DB '++ Incorrect entry ++',CR,LF,BELL,0
RET
;
;Table of baud rate parameters
;
BDTABL EQU WORD PTR $
DW 0417H ; 110 baud
DW 0180H ; 300 baud
DW 0100H ; 450 baud
DW 00C0H ; 600 baud
DW 0060H ; 1200 baud
DW 0030H ; 2400 baud
DW 0018H ; 4800 baud
DW 000CH ; 9600 baud
DW 0006H ; 19200 BAUD
;
WDLEN DB EIGHT
STPLN DB ONE
PARIT DB NONE
;
BAUDBUF:
DB 10,0
RB 10
;
;For MODEMs which disconnect from the telephone line when data terminal
;ready (DTR) drops, the following routine will disconnect.
;
HANGUP EQU 0 ;HANG UP THE TELEPHONE
;
DISCR:
MOV AL,HANGUP
CALL OUTMODMCR
RET
;
;The following routine will give the carrier detect status
;
RLSD EQU 80H ;RECEIVED LINE SIGNAL (CARRIER) DETECT
;
DETCAR:
MOV AL,CARDETFLG
OR AL,AL
JZ DETCARRET ;RETURN IF FALSE
CALL ILPRT
DB 'Carrier ',0
CALL INMODMSR ;in modem status reg.
AND AL,RLSD
JNZ DETCAR1
CALL ILPRT
DB 'not ',0
DETCAR1:
CALL ILPRT
DB 'present',CR,LF,0
DETCARRET:
RET
;
; MAIN.A86
;
;Main line routines for MODEM9.xx.
;
START:
MOV AX,SS
MOV SAVESS,AX
MOV AX,SP
MOV SAVESP,AX
PUSHF ;push flags in CCP stack
POP AX ;save flags in AX @DH
MOV DX,DS ;set SS register to base @DH
MOV SS,DX ;set SS, SP with interrupt @DH
MOV SP,OFFSET STACKTOP ; for 8088 @DH
PUSH AX ;restore the flags @DH
; POP BX ; @DH
; MOV AX,DS ; @DH
; MOV SS,AX ; @DH
; MOV SP,STACKTOP ; @DH
; PUSH BX ; @DH
POPF
CLD
CALL INITADR ;INITIALIZE ADDRESSES
CALL VERNUM ;GIVE CONFIGURATION MESSAGE
CALL GETUSR ;GET USER
MOV SAVUSR,AL ;SAVE FOR EXIT
MOV NFILFLG,TRUE
MOV SAVEFLG,FALSE
CALL PROCOPT ;PROCESS CONTROL OPTIONS
;
RESTART:
MOV AL,OPTION ;GET MAIN OPTION
CMP AL,' ' ;NO OPTION SPEC'D?
JZ MENUJMP ;TRUE, GO MENU
CMP AL,'H' ;MENU ASKED FOR?
JZ MENU2JMP ;YES, GO MENU2
CALL INITMOD
CALL MOVEFCB
CALL INMODDATP ;GOBBLE UP GARBAGE..
CALL INMODDATP ;..CHARACTERS ON LINE
MOV ECHOFLG,0 ; RESET ECHO FLAG
MOV LOCFLG,0 ; RESET LOCAL FLAG
MOV AL,OPTION ;PROCESS MAIN OPTION
CMP AL,'E' ;ECHO MODE?
JNZ NOECH ;JUMP IF NOT
MOV ECHOFLG,TRUE ;SET ECHO TO TRUE
JMP DSKSAVE
;
MENU2JMP:
JMP MENU2
;
NOECH: CMP AL,'L' ;LOCAL ECHO MODE
JNZ NOLOC
MOV AL,TRUE
MOV LOCFLG,AL
JMP DSKSAVE
NOLOC:
CMP AL,'T' ;TERMINAL MODE?
JNZ NOLOC1
JMP DSKSAVE ;YES
NOLOC1:
CMP AL,'S' ;SEND A FILE?
JNZ NOLOC2
JMP SENDFIL ;YES
NOLOC2:
CMP AL,'R' ;RECEIVE A FILE?
JNZ NOLOC3
JMP RCVFIL ;YES
NOLOC3:
CALL NOTVLDMSG ;SAY NOT A VALID OPTION
MENUJMP:
JMP MENU ;NO VALID OPTION SPEC'D, GO MENU
;
INITADR:
JMP INITMOD ;RETURN DONE FROM THIS ROUTINE..
;
; CHECK OPTIONS, PUT 0 IN APPROPRIATE PLACES IN OPTION TABLE
; IF OPTION SELECTED
;
PROCOPT:
MOV DX,OFFSET FCB+1
XCHG BX,DX
MOV AL,BYTE PTR [BX]
XCHG BX,DX
MOV OPTION,AL
OPTLP:
INC DX
XCHG BX,DX
MOV AL,BYTE PTR [BX]
XCHG BX,DX
CMP AL,' '
JZ ENDOPT
MOV BX,OFFSET OPTBL
MOV CH,OFFSET OPTBE- OFFSET OPTBL
OPTCK:
CMP AL,BYTE PTR [BX]
JNZ OPTNO
CMP AL,'B'
JNZ OPTCK1
MOV AL,OPTION
CMP AL,'S'
JZ OPTCK1
CMP AL,'R'
JNZ OPTNO1
OPTCK1:
MOV BYTE PTR [BX],0
JMP OPTLP
;
OPTNO:
INC BX
DEC CH
JNZ OPTCK
OPTNO1:
CALL NOTVLDMSG
POP AX ;PRESERVE STACK
JMP MENU
;
ENDOPT:
MOV AL,VSEEFLG
OR AL,AL
JNZ ENDOPTRT
MOV QFLG,AL ;IF VIEWING SUPPRESS ALL ELSE
ENDOPTRT:
RET
;
MOVEFCB:
MOV BX,OFFSET FCB+16
MOV DX,OFFSET FCB
MOV CH,16
CALL MOVE
MOV BYTE PTR .FCBSNO,0
MOV BYTE PTR .FCBEXT,0
RET
;
PRTMSG:
MOV CL,PRINT
INT 224
RET
;
EXIT:
MOV DL,SAVUSR
CALL SETUSR
MOV DX,OFFSET 80H
MOV CL,STDMA
INT 224
CALL CKMODM ;CATCH ANY GARBAGE CHARACTERS (is this safe?)
COLDBOOT:
PUSHF ;Must keep the flags in a register
POP BX ; as the current stack is about to blow
MOV AX,SAVESS ;Restore the original stack segment
MOV SS,AX
MOV AX,SAVESP ; and pointer
MOV SP,AX
PUSH BX
POPF ;Restore the flags
MOV CX,0 ;Exit is via BDOS call 0
MOV DX,0
INT 224 ;We're off to see the wizard....
;
;INITIALIZES CP/M FILE CONTROL BLOCKS AT 5CH AND 6CH
;
SETFCB:
MOV DX,OFFSET CMDBUF
MOV BX,OFFSET FCB
CALL CPMLINE
CALL PROCOPT
CHECKNM:
MOV AL,BYTE PTR .FCB+1 ;CHECK ON THE PRIMARY OPTION
CMP AL,'E' ;RETURN IF ECHO OPTION
JZ CHECKNMRT
CMP AL,'H' ;RETURN IF HELP OPTION
JZ CHECKNMRT
CMP AL,'L' ;RETURN IF LOCAL ECHO OPTION
JZ CHECKNMRT
CMP AL,'T'
JNZ L@103
JMP TERMSEL
L@103:
CMP AL,'S'
JNZ L@104
JMP CKFILE
L@104:
CMP AL,'R'
JNZ BDOPT
MOV AL,BATCHFLG ;IF MULT FILE MODE, THEN..
OR AL,AL ;..RECV OPT DOES NOT NEED..
JNZ CKFILE
CHECKNMRT:
RET
;
BDOPT:
CALL ILPRT
DB CR,LF,'++ Bad Option ++',CR,LF,0
JMP REENT
CKFILE:
MOV AL,BYTE PTR .FCB+17 ;IF OPTION THAT NEEDS FILE NAME,..
CMP AL,' ' ;..THEN CHECK TO SEE IF NAME..
JNZ CHECKNMRT ;...EXISTS. IF NOT..
REENT:
CALL ILPRT ;..DO EVERYTHING OVER.
DB CR,LF,'Re-enter PRIMARY option and file name only: ',BELL,0
MOV DX,OFFSET CMDBUF
CALL INBUFF
JMP SETFCB
;
TERMSEL:
CMP BYTE PTR .FCB+17,' '
JNZ SAVAGN
MOV SAVEFLG,FALSE
MOV NFILFLG,TRUE
RET
;
SAVAGN:
MOV NFILFLG,FALSE
RET
;
;
;ADJUSTS LOOP COUNTERS FOR VARIOUS CLOCK SPEEDS
;
FIXCNT:
MOV AL,CLOCK
CMP AL,1
JZ FIXCNTRT
PUSH DX
PUSH BX
POP DX
CNTMUL:
ADD BX,DX
DEC AL
JNZ CNTMUL
POP DX
FIXCNTRT:
RET
;
MOVE128:
MOV CH,128
;
MOVE:
MOV SI,BX
PUSH DS
POP ES
MOV DI,DX
MOVE001:
MOVS BYTE PTR [DI], BYTE PTR [SI]
DEC CH
JNZ MOVE001
MOV BX,SI
MOV DX,DI
RET
;
MENU0:
TEST NFILFLG,0FFH
JZ MENU1
JMP MENU ;GO IF NO FILE ACTIVE
MENU1:
CALL ILPRT ;ELSE PRINT MESSAGE
DB CR,LF,LF
DB '** There may be text in the memory buffer **',CR,LF
DB '** It will be lost unless NOL or WRT commands are used **'
DB CR,LF,BELL,0
MOV CH,2 ;2 MORE BELLS
BLOOP:
MOV AL,BELRPT ;GET TIME
MOV CL,AL
BCLOOP:
MOV BX, 1000 ;ABOUT 0.03 SECONDS
CALL FIXCNT
BILOOP:
MOV AL,BL
OR AL,BH
DEC BX
JNZ BILOOP
DEC CL
JNZ BCLOOP
MOV AL,BELL
CALL TIPE
DEC CH
JNZ BLOOP
;
MENU:
MOV BX,OFFSET RESTSN ;RESTORE SECTOR NUMBERS..
MOV DX,OFFSET SECTNOB ;..FOR NEW FILE TRANSFER.
MOV CH,OFFSET SECTNOE- OFFSET SECTNOB
CALL MOVE
MOV BX,OFFSET RESTROPT ;RESTORE OPTION TABLE
MOV DX,OFFSET OPTBL
MOV CH,OFFSET OPTBE- OFFSET OPTBL
CALL MOVE
MOV AL,0
MOV MFFLG1,AL ;RESET MFACCESS ROUTINE..
NOT AL ;..AND MULTI TRANS IN CASE..
MOV FSTFLG,AL ;..OF ABORT.
JMP XPRT
;
MENU2:
CALL CLRTST
CALL ILPRT
DB ' Single Letter Commands',CR,LF,LF
DB ' H - Display this information',CR,LF
DB ' ? - Display current settings',CR,LF,LF
DB ' T - Terminal mode',CR,LF
DB ' E - Terminal mode with echo',CR,LF
DB ' L - Terminal mode with local echo',CR,LF
DB ' For capturing text use T(or E or L) FILENAME.TYP and'
DB CR,LF
DB ' Start & Stop toggles described on subsequent screen.'
DB CR,LF,LF
DB ' R - Receive CP/M file using Christensen Protocol',CR,LF
DB ' S - Send CP/M file using Christensen Protocol',CR,LF
DB ' Command is: R(or S) FILENAME.TYP',CR,LF
DB ' R and S can use the following subcommands:',CR,LF
DB ' B - Bulk transfer using wildcards (e.g. *.*)',CR,LF
DB ' Q - Quiet mode (no messages to console)',CR,LF
DB ' T - Return to terminal mode after transfer',CR,LF
DB ' V - View bytes transferred on console',CR,LF,LF
DB 'The single letter commands may also be used on the',CR,LF
DB 'command line when the program is initially executed.'
DB CR,LF,LF,0
;
CALL NXTSCRN
;
CALL ILPRT
DB ' Three Letter Commands',CR,LF,LF
DB 'CPM - Exit from this program to CP/M',CR,LF
DB 'DIR - List directory and space free (may specify drive)'
DB CR,LF
DB 'ERA - Erase file (may specify drive)',CR,LF
DB 'LOG - Change default drive/user (specify drive/user)'
DB CR,LF
DB ' and reset disks. e.g. LOG A0, LOG B (user unchanged)'
DB CR,LF
DB 'FOP - Display commands for setting terminal mode file',CR,LF
DB ' output parameters',CR,LF,0
;
TEST DISCFLG,0FFH
JZ NODISC
CALL ILPRT
DB 'DSC - Disconnect the modem from the telephone line',CR,LF,0
;
NODISC:
TEST SETUPTST,0FFH
JNZ NOTIME
CALL ILPRT
DB 'TIM - Set S mode time-to-send message',CR,LF,0
;
NOTIME:
MOV AL,TOGGLECRC
OR AL,AL
JZ NOTOGCRC
CALL ILPRT
DB 'TCC - Toggle Checksum/CRC mode on receive',CR,LF,0
;
NOTOGCRC:
TEST TOGGLEBK,0FFH
JZ NOTOGBK
CALL ILPRT
DB 'TBR - Toggle backspace to rub conversion',CR,LF,0
;
NOTOGBK:
TEST TOGGLELOC,0FFH
JZ NOTOGLOC
CALL ILPRT
DB 'TLC - Toggle 1) local command immediate',CR,LF
DB ' 2) local command after ',0
MOV AL,EXTCHR
CALL SHFTYPE
DB CR,LF,0
;
NOTOGLOC:
MOV AL,TOGGLELF
OR AL,AL
JZ NOTOGLF
CALL ILPRT
DB 'TLF - Toggle send linefeed after carriage return',CR,LF,0
;
NOTOGLF:
CALL ILPRT
DB 'NUM - List remote systems',CR,LF,0
MOV AL,SETUPTST
OR AL,AL
JZ NOSETUP
CALL ILPRT
DB 'SET - Set communication ports',CR,LF,0
;
NOSETUP:
MOV AL,LF
CALL TIPE
CALL ILPRT
DB ' The following are terminal text buffer commands:'
DB CR,LF,0
CALL ILPRT
DB 'DEL - Delete memory buffer and file',CR,LF
DB 'NOL - Return to terminal mode - no loss of data in buffer'
DB CR,LF
DB 'WRT - Write memory buffer to disk file',CR,LF,LF,0
CALL NXTSCRN
;
CALL ILPRT
DB ' Local Commands while in Terminal Mode',CR,LF,LF,0
MOV AL,BAUDCHR ; @DH
CALL SHFTYPE ; @DH
DB ' - Change baud rate from terminal mode',CR,LF,LF,0 ; @DH
MOV AL,EXITCHR
CALL SHFTYPE
DB ' - Exit to command mode',CR,LF,LF,0
MOV AL,TRANLOGON
OR AL,AL
JZ NOTRANLOG
MOV AL,LOGCHR
CALL SHFTYPE
DB ' - Transmit string',CR,LF
DB ' Must be followed by number of string (0-9)',CR,LF
DB ' or L to display list of strings',CR,LF,LF,0
;
NOTRANLOG:
TEST LSTTST,0FFH
JZ NOLST2
MOV AL,LSTCHR
CALL SHFTYPE
DB ' - Toggle printer',CR,LF,0
;
NOLST2:
MOV AL,LF
CALL TIPE
MOV AL,SAVECHR
CALL SHFTYPE
DB ' - Start copy into buffer',CR,LF,0
MOV AL,UNSAVECHR
CALL SHFTYPE
DB ' - Stop copy into buffer',CR,LF
DB ' Start & Stop may be toggled as often as desired.',CR,LF
DB ' A ":" at start of line indicates buffer is open.',CR,LF
DB ' XOFF automatically used to stop input when writing',CR,LF
DB ' full buffer to disk, XON sent to resume.',CR,LF,LF,0
MOV AL,TRANCHR
CALL SHFTYPE
DB ' - Transfer ASCII file to remote',CR,LF,LF,0
MOV AL,LOCONEXTCHR
OR AL,AL
MOV AL,EXTCHR
JNZ REMDFLT
CALL SHFTYPE
DB ' - Send local control character to remote',CR,LF,0
JMP XPRT
REMDFLT:
CALL SHFTYPE
DB ' - Next character will be used for local control',CR,LF,0
;
XPRT:
CALL ILPRT
DB CR,LF,'Drive ',0
MOV CL,CURDSK ;CURRENT DISK FUNCTION
INT 224
ADD AL,'A' ;MAKE ASCII
CALL TIPE
CALL GETUSR ;GET CURRENT USER NUMBER
CMP AL,0
JZ SR3B ;SKIP IF USER 0
PUSH AX
CALL ILPRT
DB ', User ',0
POP AX
MOV BH,0
MOV BL,AL
CALL DECOUT ;REPORT USER
;
SR3B:
CALL CRLF
TEST NFILFLG,0FFH
JNZ NOBUFMSG
CALL GETSPC
CALL ILPRT
DB ' bytes of buffer free',CR,LF,0
NOBUFMSG:
CALL ILPRT
DB 'COMMAND (H for Help): ',0
GETCMD:
MOV DX,OFFSET CMDBUF ;ENTER COMMAND
CALL INBUFF
CALL CRLF
MOV DX,OFFSET CMDBUF+2 ;POINT TO COMMAND
CALL ILCOMP
DB 'CPM',0
JC GETCMD1
JMP EXIT
GETCMD1:
CALL ILCOMP
DB 'LOG',0
JC GETCMD2
JMP LOGNEW
GETCMD2:
CALL ILCOMP
DB 'DIR',0
JC GETCMD3
JMP DIR
GETCMD3:
CALL ILCOMP
DB 'ERA',0
JC GETCMD4
JMP ERASEF
GETCMD4:
CALL ILCOMP
DB 'DSC',0
JC GETCMD5
JMP DISC
GETCMD5:
CALL ILCOMP
DB '?',0
JC GETCMD6
JMP CURPAR
GETCMD6:
CALL ILCOMP
DB 'SPD',0
JC GETCMD7
JMP SETSPD
GETCMD7:
CALL ILCOMP
DB 'FOP',0
JC GETCMD8
JMP TFOMENU
GETCMD8:
CALL ILCOMP
DB 'TIM',0
JC GETCMD9
JMP SETTIM
GETCMD9:
CALL ILCOMP
DB 'TCC',0
JC GETCMD10
JMP TOGCRC
GETCMD10:
CALL ILCOMP
DB 'TBR',0
JC GETCMD11
JMP TOGBKSP
GETCMD11:
CALL ILCOMP
DB 'TLC',0
JC GETCMD12
JMP TOGLOC
GETCMD12:
CALL ILCOMP
DB 'TLF',0
JC GETCMD13
JMP TOGLF
GETCMD13:
CALL ILCOMP
DB 'TSL',0
JC GETCMD14
JMP TOGSTL
GETCMD14:
CALL ILCOMP
DB 'TXF',0
JC GETCMD15
JMP TOGTXOFF
GETCMD15:
CALL ILCOMP
DB 'TXN',0
JC GETCMD16
JMP TOGTXON
GETCMD16:
CALL ILCOMP
DB 'TWE',0
JC GETCMD17
JMP TOGWECH
GETCMD17:
CALL ILCOMP
DB 'TEF',0
JC GETCMD18
JMP TOGTEOF
GETCMD18:
CALL ILCOMP
DB 'NUM',0
JC GETCMD19
JMP NUMPRN
GETCMD19:
MOV AL,SETUPTST
OR AL,AL
JZ NOSETUP2
CALL ILCOMP
DB 'SET',0
JC NOSETUP2
JMP SETUPENT
NOSETUP2:
CALL ILCOMP
DB 'NOL',0
JC NXTOPT1 ;CARRY SET = NO MATCH
MOV AL,NFILFLG
OR AL,AL
JZ NOSETUP3
JMP NOFILOPN ;GO TELL OPERATOR IF NO FILE OPEN
NOSETUP3:
CALL BUFMSG
MOV BX,HLSAVE ;RETURN TO TERMINAL..
JMP TERM ;..MODE WITH SAVE OPTION..
;..IF PREVIOUSLY ENABLED.
;
NXTOPT1:
CALL ILCOMP
DB 'WRT',0
JC NXTOPT2
JMP WRTFIL
NXTOPT2:
CALL ILCOMP
DB 'DEL',0
JC NXTOPT3
JMP NEWFILE
NXTOPT3:
PUSH BX
MOV AL,CMDBUF+2
MOV BX,OFFSET COMPLIST
CALL COMPARE ;COMPARES LIST POINTED TO BY HL..
POP BX ;..TO CHAR IN A-REG.
JC NOTVLD ;CARRY SET = NO MATCH
DOOPT:
PUSH BX ;LOAD ORIGINAL FCB WITH TRANSFER..
CALL SETFCB ;..CMDS AND GO TO BEGINNING OF..
POP BX ;..PROGRAM. WILL FOLLOW SAME LOGIC..
JMP RESTART ;..AS IF PROGRAM WERE CALLED WITH..
;..CP/M COMMAND LINE.
;
NOTVLD:
CALL NOTVLDMSG
JMP XPRT
;
NOTVLDMSG:
CALL ILPRT
DB '++ Invalid Command ++',CR,LF,BELL,0
RET
;
DIR:
MOV CL,CURDSK
INT 224
MOV DISKSAV,AL
CALL DIRLST
MOV DL,DISKSAV
MOV CL,SELDSK
INT 224
JMP XPRT
;
LOGNEW:
TEST NFILFLG,0FFH
JNZ LOGNEW1
JMP NORESET
LOGNEW1:
MOV AL,CMDBUF+6
CMP AL,' '
JNZ SPECIFD
MOV CL,CURDSK
INT 224
ADD AL,'A'
SPECIFD:
SUB AL,'A'
MOV DISKSAV,AL
CMP AL,16
JC SPECIFD1
JMP NOTVLD
SPECIFD1:
MOV AL,CMDBUF+7 ;GET NEW USER NUMBER
CMP AL,' ' ;CHECK FOR SPACE
JZ SR7A ;EXIT IF NO NEW USER NUMBER SPECIFIED
CALL NUMCHK ;CHECK TO SEE IF IT IS A NUMBER
MOV CH,AL ;SAVE
MOV AL,CMDBUF+8 ;GET SECOND DIGIT
CMP AL,' '
JZ SR7B ;GO IF SPACE
CALL NUMCHK
MOV CL,AL ;SAVE
MOV AL,CH ;GET SAVED FIRST DIGIT
ADD AL,AL ; X2
ADD AL,AL ; X4
ADD AL,AL ; X8
ADD AL,CH ; X9
ADD AL,CH ; X10
ADD AL,CL
CMP AL,16 ;CHECK FOR < 16
JC SPECIFD2
JMP NOTVLD ;GO IF NOT
SPECIFD2:
MOV CH,AL
SR7B:
PUSH CX
CALL GETUSR
POP CX ;RESTORE SELECTED USER
CMP AL,CH ;AND COMPARE THEM
JZ SR7A ;EXIT IF UNCHANGED
MOV DL,CH ;ELSE SET NEW USER
CALL SETUSR
;
SR7A:
CALL ILPRT
DB 'Insert disk for drive ',0
MOV AL,DISKSAV
ADD AL,'A'
CALL TIPE
NOTCR:
CALL ILPRT
DB CR,LF,'Hit return when ready',0
CALL KEYIN
CMP AL,CR
JNZ NOTCR
CALL CRLF
MOV CL,RESET
INT 224
MOV DL,DISKSAV
MOV CL,SELDSK
INT 224
JMP XPRT
;
GETUSR:
MOV DL,0FFH ;GET CURRENT USER
SETUSR:
MOV CL,USER ;SET-UP FUNCTION CALL
INT 224 ;NUMBER IN RETURNED IN A
RET
;
NORESET:
CALL ILPRT
DB '++ Terminal mode file open ++',CR,LF
DB '++ Use WRT or DEL before LOG command ++',CR,LF
DB CR,LF,LF,BELL,0
XOR AL,AL
JMP XPRT
;
ERASEF:
MOV DX,OFFSET CMDBUF ;PUT CMD LINE INTO FCB AT HL
MOV BX,OFFSET FCB
CALL CPMLINE
CALL MOVEFCB ;MOVE FCB+16 TO FCB
CMP BYTE PTR .FCB+1,' '
JNZ ERASEF1
JMP NOTVLD ;GO IF NO FILE SPECIFIED
ERASEF1:
MOV DX,OFFSET FCB
MOV CL,SRCHF
INT 224
INC AL ;0 IF FILE NOT FOUND
JNZ ERAFILE ;OK, GO ERASE
CALL ILPRT
DB '++ File not found ++',CR,LF,BELL,0
JMP XPRT
;
ERAFILE:
MOV DX,OFFSET FCB
MOV CL,ERASE
INT 224
CALL ILPRT
DB 'File erased',CR,LF,0
JMP XPRT
;
DISC:
MOV AL,DISCFLG
OR AL,AL
JNZ DISC1
JMP NOTVLD
DISC1:
CALL DISCR
CALL ILPRT
DB '** Disconnected **',CR,LF,BELL,0
JMP XPRT
;
SETSPD:
CALL ILPRT
DB 'Enter character output delay [0(none) - 9(longest delay)]: ',0
CALL NUMGET
JNC NOCHG1
MOV BYTDLY,AL
NOCHG1:
CALL SPDMSG
CALL ILPRT
DB CR,LF,'Enter additional delay after <CR> [0-9]: ',0
CALL NUMGET
JNC NOCHG2
ROL AL,1 ;X2
ROL AL,1 ;X4
MOV CRDLY,AL
NOCHG2:
CALL CRDLYMSG
JMP XPRT
;
NUMGET:
MOV DX,OFFSET CMDBUF
CALL INBUFF
MOV AL,CMDBUF+2 ;GET NUMBER
CMP AL,' '
JZ NUMCHKRT
NUMCHK:
SUB AL,'0'
CMP AL,10
JC NUMCHKRT
POP AX ;PRESERVE STACK
JMP NOTVLD
NUMCHKRT:
RET
;
SPDMSG:
CALL ILPRT
DB 'Terminal mode file output delay is 0.',0
MOV AL,BYTDLY
CALL GIVNUM
CALL ILPRT
DB ' seconds per character',CR,LF,0
RET
;
CRDLYMSG:
CALL ILPRT
DB 'Additional delay after <CR> is 0.',0
MOV AL,CRDLY
CALL GIVNUM
CALL ILPRT
DB ' seconds',CR,LF,0
RET
;
GIVNUM:
ADD AL,AL ;2X
CMP AL,10
MOV CH,AL
JNC NOZERO
MOV AL,'0'
CALL TIPE
MOV AL,CH
NOZERO:
PUSH BX
MOV BL,AL
MOV BH,0
CALL DECOUT
POP BX
RET
;
;Routine to change baud rate from terminal mode 30/DEC/84 @DH
;
BAUDCHG: ; @DH
PUSH BX ; @DH
PUSH DX ; @DH
PUSH CX ; @DH
PUSH AX ; @DH
CALL CLRSCRN ; @DH
CALL ILPRT ; @DH
DB CR,LF,LF ; @DH
DB ' Select 0 - 8 for new baud rate' ; @DH
DB CR,LF,LF ; @DH
DB ' 0 = 110 bps 5 = 2400 bps',CR,LF,LF ; @DH
DB ' 1 = 300 bps 6 = 4800 bps',CR,LF,LF ; @DH
DB ' 2 = 450 bps 7 = 9600 bps',CR,LF,LF ; @DH
DB ' 3 = 600 bps 8 = 19200 bps',CR,LF,LF ; @DH
DB ' 4 = 1200 bps',CR,LF,LF ; @DH
DB ' Enter selection (0 - 8 or <CR> for no change): ',0; @DH
;
CALL NUMGET
CMP AL,' ' ; @DH
JNZ BAUD0 ; @DH
JMP RETURN ; @DH
;
BAUD0: CMP AL,9 ; @DH
; CMP AL,8 ; @DH
JC BAUD1 ; @DH
JMP BAUDCHG ; @DH
;
BAUD1: ; @DH
MOV MSPEED,AL ; @DH
CALL CLRSCRN ; @DH
CALL ILPRT ; @DH
DB CR,LF,LF ; @DH
DB 'New Modem speed is ',0 ; @DH
CALL BAUDPRT ; @DH
CALL INITMOD ; @DH
JMP RETURN ; @DH
;
SETTIM:
MOV AL,SETUPTST
OR AL,AL
JZ SETTIM1
JMP NOTVLD
SETTIM1:
CALL CLRSCRN ; @DH
CALL ILPRT
DB CR,LF,LF ; @DH
DB 'Use 0-8 to give baud rate for S mode time-to-send message,'
DB CR,LF
DB 'where 0=110, 1=300, 2=450, 3=600, 4=1200, 5=2400',CR,LF ;@DH
DB '6=4800, 7=9600 and 8=19200 baud',CR,LF,LF,'Enter value: ',0;@DH
; DB 'where 0=110, 1=300, 2=600, 3=1200, 4=2400',CR,LF ;@DH
; DB '5=4800, 6=9600 and 7=19200 baud',CR,LF,LF,'Enter value: ',0;@DH
CALL NUMGET
CMP AL,9 ; @DH
; CMP AL,8 ; @DH
JC SETTIM1A
JMP NOTVLD
;
SETTIM1A:
MOV MSPEED,AL
CALL SETTIM2
JMP XPRT
;
SETTIM2:
MOV AL,SETUPTST
OR AL,AL
JNZ SETTIM3
CALL ILPRT
DB 'Rate for the S mode time-to-send message is set to ',0
JMP SETTIM4
;
SETTIM3:
CALL ILPRT
DB 'Modem speed is ',0
SETTIM4:
CALL BAUDPRT
RET
;
;Shows baud rates set for 'time to send' file transfer.
;
BAUDPRT:
MOV BX,OFFSET BAUDSPD
MOV DH,0
MOV AL,MSPEED ;GET BAUD RATE CODE
ADD AL,AL ;X2
MOV DL,AL
ADD BX,DX ;POINT TO CORRECT RATE
MOV AL,BYTE PTR [BX] ; GET FIRST DIGIT
CALL TIPE
INC BX
MOV AL,BYTE PTR [BX] ; GET SECOND DIGIT
CALL TIPE
MOV AL,MSPEED
; CMP AL,7 ; @DH
CMP AL,8 ;FOR ADDITION OF 19200 BAUD RATE @DH
JC NOTFAST
INC BX
MOV AL,Byte Ptr [BX] ;Get third digit
CALL TIPE
NOTFAST:
MOV AL,MSPEED ;CHECK FOR GREATER THAN 1000
CMP AL,4 ;FOR ADDITION OF 450 BAUD RATE @DH
; CMP AL,3 ; @DH
JC NOTHOU ;GO IF LESS
MOV AL,'0' ;PRINT EXTRA 0
CALL TIPE
NOTHOU:
CALL ILPRT
DB '0 baud',CR,LF,0
RET
; ;added 450 and 19200 baud rates @DH
BAUDSPD DB '11','30','45','60','12','24','48','96','192'; @DH
;BAUDSPD DB '11','30','60','12','24','48','96','192'; @DH
;
TOGCRC:
MOV AL,TOGGLECRC
OR AL,AL
JNZ TOGCRC1
JMP NOTVLD
TOGCRC1:
MOV AL,CKSUMDFLT
NOT AL
MOV CKSUMDFLT,AL
CALL TOGCRC2
JMP XPRT
;
TOGCRC2:
OR AL,AL
JNZ CHEKMSG
CALL ILPRT
DB 'CRC mode set',CR,LF,0
RET
;
CHEKMSG:
CALL ILPRT
DB 'Checksum mode set',CR,LF,0
RET
;
TOGBKSP:
MOV AL,TOGGLEBK
OR AL,AL
JNZ TEMP8
JMP NOTVLD
TEMP8:
MOV AL,CONVBKSP
NOT AL
MOV CONVBKSP,AL
CALL TOGBKSP2
JMP XPRT
;
TOGBKSP2:
TEST CONVBKSP,0FFH
JZ NORUBMSG
CALL ILPRT
DB 'Backspace is rub',CR,LF,0
RET
;
NORUBMSG:
CALL ILPRT
DB 'Backspace is backspace',CR,LF,0
RET
;
TOGLOC:
MOV AL,TOGGLELOC
OR AL,AL
JNZ TOGLOC1
JMP NOTVLD
TOGLOC1:
NOT LOCONEXTCHR
CALL TOGLOC2
JMP XPRT
;
TOGLOC2:
CALL ILPRT
DB 'Use ',0
MOV AL,LOCONEXTCHR
OR AL,AL
MOV AL,EXTCHR
JZ LOCMSG
CALL SHFTYPE
DB ' before local command',CR,LF,0
RET
;
LOCMSG:
CALL SHFTYPE
DB ' to send local command to remote',CR,LF,0
RET
;
TOGLF:
MOV AL,TOGGLELF
OR AL,AL
JNZ TOGLF1
JMP NOTVLD
TOGLF1:
NOT ADDLF
CALL TOGLF2
JMP XPRT
;
TOGLF2:
CALL ILPRT
DB 'Linefeed ',0
MOV AL,ADDLF
OR AL,AL
JNZ LFMSG
CALL ILPRT
DB 'NOT ',0
LFMSG:
CALL ILPRT
DB 'sent after <CR>',CR,LF,0
RET
;
TOGSTL:
MOV AL,TOGSLF
OR AL,AL
JNZ TOGSTL1
JMP NOTVLD
TOGSTL1:
NOT STRLF
CALL TOGSTL2
JMP XPRT
;
TOGSTL2:
CALL ILPRT
DB 'Linefeed ',0
MOV AL,STRLF
OR AL,AL
JZ SLFMSG
CALL ILPRT
DB 'NOT ',0
SLFMSG:
CALL ILPRT
DB 'sent after <CR> in terminal mode file output',CR,LF,0
RET
;
TOGTXOFF:
MOV AL,TOGXOFF
OR AL,AL
JNZ TOGTXOFF1
JMP NOTVLD
TOGTXOFF1:
CALL ILPRT
DB 'Use XOFF testing? (Y/N): ',0
CALL GETANS
JC NOCHG3
MOV XOFFTST,AL
NOCHG3:
CALL XOFFMSG
MOV AL,XOFFTST
OR AL,AL
JNZ NOCHG3A
JMP XPRT
NOCHG3A:
NOT AL
MOV XONWAIT,AL
MOV ECHWAIT,AL
CALL THEREF
CALL XONMSG
CALL ECHMSG
JMP XPRT
;
TOGTXON:
CALL ILPRT
DB 'Use XON waiting after <CR> (Y/N): ',0
CALL GETANS
JC NOCHG4
MOV XONWAIT,AL
NOCHG4:
CALL XONMSG
MOV AL,XONWAIT
OR AL,AL
JNZ NOCHG4A
JMP XPRT
NOCHG4A:
NOT AL
MOV XOFFTST,AL ;DON'T ALLOW BOTH
MOV ECHWAIT,AL
CALL THEREF
CALL XOFFMSG
CALL ECHMSG
JMP XPRT
;
TOGWECH:
CALL ILPRT
DB 'Use echo waiting before transmitting next character (Y/N): ',0
CALL GETANS
JC NOCHG5
MOV ECHWAIT,AL
NOCHG5:
CALL ECHMSG
MOV AL,ECHWAIT
OR AL,AL
JNZ NOCHG5A
JMP XPRT
NOCHG5A:
NOT AL
MOV XOFFTST,AL
MOV XONWAIT,AL
CALL THEREF
CALL XOFFMSG
CALL XONMSG
JMP XPRT
;
ECHMSG: CALL ILPRT
DB 'Waiting for character echo ',0
MOV AL,ECHWAIT
OR AL,AL
JNZ ECHMSG2
CALL ILPRT
DB 'NOT ',0
ECHMSG2:
CALL ILPRT
DB 'used in terminal mode file output',CR,LF,0
RET
;
GETANS:
MOV DX,OFFSET CMDBUF
CALL INBUFF
MOV AL,CMDBUF+2 ;GET ANSWER
CMP AL,' '
CMC
JZ GETANSRT
MOV CH,AL
CMP AL,'N'
MOV AL,FALSE
JZ GETANSRT
MOV AL,CH
CMP AL,'Y'
MOV AL,TRUE
JZ GETANSRT
POP AX ;PRESERVE STACK
JMP NOTVLD
GETANSRT:
RET
;
THEREF:
CALL ILPRT
DB 'Therefore -',CR,LF,0
RET
;
XOFFMSG:
CALL ILPRT
DB 'XOFF testing ',0
MOV AL,XOFFTST
OR AL,AL
JNZ XOTSTON
CALL ILPRT
DB 'NOT ',0
XOTSTON:
CALL ILPRT
DB 'used',0
XONMSG3:
CALL ILPRT
DB ' in terminal mode file output',CR,LF,0
RET
;
XONMSG:
CALL ILPRT
DB 'XON ',0
MOV AL,XONWAIT
OR AL,AL
JNZ XONMSG2
CALL ILPRT
DB 'NOT ',0
XONMSG2:
CALL ILPRT
DB 'automatically tested after <CR>',0
JMP XONMSG3
;
SETUPENT:
MOV AL,SETUPTST
OR AL,AL
JNZ SETUPENT1
JMP NOTVLD
SETUPENT1:
CALL SETUPR
JMP XPRT
;
NEWFILE:
MOV AL,NFILFLG
OR AL,AL
JNZ NOFILOPN
MOV AL,FCB3+1 ;CHECK THAT FILE WAS REQUESTED
CMP AL,' '
JZ NOFILOPN ;IF NO FILE, DON'T ERASE
MOV DX,OFFSET FCB3
MOV CL,ERASE
CALL BDOSRT
MOV AL,TRUE ;DO NOT ALLOW TERMINAL..
MOV NFILFLG,AL ;..SAVE SINCE NO FILE..
NOT AL ;..SPECIFIED.
MOV SAVEFLG,AL
MOV BX,OFFSET FCB3
CALL INITFCBS
MOV BX,OFFSET BOTTRAM
MOV HLSAVE,BX
JMP XPRT
;
WRTFIL:
CMP NFILFLG,TRUE
JZ NOFILOPN
MOV AL,FCB3+1 ;CHECK THAT FILE WAS REQUESTED
CMP AL,' '
JZ NOFILOPN
MOV BX,HLSAVE
CALL NUMRECS ;DISK WRITE ROUTINE AS USED IN..
CALL WRTDSK ;..IN THE INTDSKSV ROUTINE.
CALL CLOSE3
MOV NFILFLG,TRUE
MOV SAVEFLG,FALSE
MOV BX,OFFSET FCB3
CALL INITFCBS ;BLANK OUT FCB SO WRITTEN..
;..FILE CAN'T BE ERASED
MOV BX,OFFSET BOTTRAM
MOV HLSAVE,BX
JMP XPRT
;
NOFILOPN:
CALL ILPRT
DB '++ No File Open ++',CR,LF,BELL,0
JMP XPRT
;
COMPARE:
MOV CH,BYTE PTR [BX] ;COMPARES A-REG WITH LIST..
COMPLP:
INC BX ;..ADDRESSED BY HL. FIRST ELEMENT..
CMP AL,BYTE PTR [BX] ;..OF LIST MUST BE NUMBER OF ELEMENTS..
JZ VALID ;..BEING COMPARED. RETURNS WITH..
DEC CH ;..CARRY SET IF A-REG DOES NOT..
JNZ COMPLP ;.. CONTAIN AN ELEMENT IN LIST.
STC
VALID:
RET
;
NXTSCRN:
CALL ILPRT
DB 'HIT any KEY to CONTINUE',0
NOKEY1:
CALL STAT ;GET KEYBOARD STATUS
JZ NOKEY1 ;KEEP LOOPING UNTIL KEYPRESS
CALL KEYIN ;GOBBLE UP KEYPRESS
CALL CLRTST
RET
;
CLRTST:
TEST SCRNTEST,0FFH
JZ LOTSALF
CALL CLRSCRN
RET
;
LOTSALF:
MOV AL,CR
CALL TIPE
MOV CH,12
MOV AL,LF
LFLOOP:
CALL TIPE
DEC CH
JNZ LFLOOP
RET
;
CURPAR:
CALL CLRTST
CALL ILPRT
DB ' Current Settings',CR,LF,LF,LF,0
MOV AL,CKSUMDFLT
CALL TOGCRC2
MOV AL,LSTTST
OR AL,AL
JZ NOLST3
CALL LSTMSG
NOLST3:
CALL DETCAR
CALL SETTIM2
CALL TOGBKSP2
CALL TOGLF2
CALL TOGLOC2
CALL ILPRT
DB 'Terminal mode file buffer is ',0
TEST NFILFLG,0FFH
JZ ACTIVE
CALL ILPRT
DB 'in',0
ACTIVE:
CALL ILPRT
DB 'active',CR,LF,'Unused portion of buffer is ',0
CALL GETSPC
CALL ILPRT
DB ' bytes',CR,LF,0
TEST SETUPTST,0FFH
JZ NOSETP
CALL GIVEPRM
NOSETP:
CALL TOGSTL2
CALL TOGTEOF2
CALL XOFFMSG
CALL XONMSG
CALL ECHMSG
CALL SPDMSG
CALL CRDLYMSG
CALL CRLF
JMP XPRT
;
GETSPC:
CALL GETMAX
MOV CH,AL
MOV BX,HLSAVE
STC
CMC
MOV AL,0
SBB AL,BL
MOV BL,AL
MOV AL,CH
SBB AL,BH
MOV BH,AL
CALL DECOUT
RET
;
TFOMENU:
CALL CLRTST
CALL ILPRT
DB ' Commands for Setting Terminal Mode File Output'
DB ' Parameters',CR,LF,LF,LF
DB 'SPD - Set speed of file output',CR,LF
DB 'TEF - Toggle transmission of end-of-file character',CR,LF,0
MOV AL,TOGSLF
OR AL,AL
JZ NOTOGSLF
CALL ILPRT
DB 'TSL - Toggle stripping linefeeds',CR,LF
DB 'TWE - Toggle wait for character echo',CR,LF,0
;
NOTOGSLF:
TEST TOGXOFF,0FFH
JZ NOTOGXOFF
CALL ILPRT
DB 'TXF - Toggle XOFF testing',CR,LF
DB 'TXN - Toggle XON waiting after <CR>',CR,LF,LF,LF,0
;
NOTOGXOFF:
JMP XPRT
;
TOGTEOF:
NOT EOFSEND
CALL TOGTEOF2
JMP XPRT
;
TOGTEOF2:
CALL ILPRT
DB 'End-of-file character ',0
TEST EOFSEND,0FFH
JNZ EOFMSG
CALL ILPRT
DB 'NOT ',0
EOFMSG:
CALL ILPRT
DB 'sent in terminal mode file output',CR,LF,0
RET
;
;
;THIS ROUTINE DISPLAYS THE PHONE NUMBERS IN THE LIBRARY
;
NUMPRN:
PUSH BX
CALL CLRTST
CALL ILPRT
DB ' Library of Phone Numbers of Remote Systems',0
MOV CL,13 ;NUMBER OF LINES TO MOVE
MOV BX,OFFSET NUMBLIB ;ADDRESS OF SOURCE MEMORY
MOV DX,OFFSET DBUF ;ADDRESS OF TARGET MEMORY
CALL NEWLINE ;START WITH CRLF
XCHG BX,DX
MOV BYTE PTR [BX],AL ;+LF
XCHG BX,DX
INC DX ;AND BUMP IT
NUMPRN1:
INC BX ;SKIP PMMI DIALING LETTER
INC BX ;AND EQUAL SIGN
MOV CH,30 ;NUMBER OF BYTES TO MOVE
CALL MOVE ;MOVE TO BUFFER
CALL SPACES ;2 ENTRIES + 3 SPACES = 63 CHARACTERS
INC BX
INC BX
MOV CH,30
CALL MOVE
CALL NEWLINE
DEC CL ;NUMBER OF LINES TO PRINT
JZ NUMPRN2
JMP NUMPRN1
;
NEWLINE: ;PUTS CR-LF AT MEMORY POINTED BY 'DE'
MOV AL,CR ;CR
XCHG BX,DX
MOV BYTE PTR [BX],AL
MOV AL,LF ;LF
INC BX ;BUMP POINTER
MOV BYTE PTR [BX],AL ;STORE LF
XCHG BX,DX
INC DX ;BUMP POINTER
RET
;
SPACES:
MOV AL,20H ;SPACE
XCHG BX,DX
MOV BYTE PTR [BX],AL ;1
INC BX
MOV BYTE PTR [BX],AL ;2
INC BX
MOV BYTE PTR [BX],AL ;3
INC BX
XCHG BX,DX
RET
;
NUMPRN2:
MOV AL,'$'
XCHG BX,DX
MOV BYTE PTR [BX],AL
XCHG BX,DX
MOV CL,PRINT
MOV DX,OFFSET DBUF ;POINT TO TABLE OF NUMBERS TO PRINT
INT 224
CALL CRLF
CALL CRLF
POP BX
JMP XPRT
;
;
; CONSOLE.A86
;
DBIOS EQU 50 ;Access BIOS through BDOS
DCONSTAT EQU 2 ;BIOS console status
DCONIN EQU 3 ;BIOS console input
DCONOUT EQU 4 ;BIOS console out
DLIST EQU 5 ;BIOS list out
DLISTST EQU 15 ;BIOS list status
;
;Console I/O routines for MODEM9.xx.
;
SHOW:
CMP AL,LF
JZ CTYPE
CMP AL,CR
JZ CTYPE
CMP AL,9
JZ CTYPE
CMP AL,' '
JC SHOWHEX
CMP AL,7FH
JC CTYPE
SHOWHEX:
PUSH AX
MOV AL,'('
CALL CTYPE
POP AX
CALL HEXO
MOV AL,')'
JMP CTYPE
;
CTYPE:
PUSH CX
PUSH DX
PUSH BX
MOV DL,AL
MOV CL,WRCON
INT 224
POP BX
POP DX
POP CX
RET
;
CRLF:
PUSH AX
MOV AL,CR
CALL TIPE
MOV AL,LF
CALL TIPE
POP AX
RET
;
TIPE:
PUSH SI
PUSH CX
PUSH DX
PUSH BX
MOV Byte Ptr TBLOCK1,AL
MOV CL,DBIOS
MOV DX,Offset TIPEBLOCK
INT 224
POP BX
POP DX
POP CX
POP SI
RET
;
TIPEBLOCK DB DCONOUT
TBLOCK1 DW 0
DW 0
;
STAT:
PUSH CX
PUSH DX
PUSH BX
MOV CL,DBIOS
MOV DX,Offset STATBLOCK
INT 224
POP BX
POP DX
POP CX
OR AL,AL
RET
;
STATBLOCK:
DB DCONSTAT
DW 0
DW 0
;
KEYIN:
PUSH CX
PUSH DX
PUSH BX
KEYIN1:
MOV CL,DBIOS
MOV DX,Offset KEYBLOCK
INT 224
POP BX
POP DX
POP CX
RET
;
KEYBLOCK:
DB DCONIN
DW 0
DW 0
;
LISTER:
PUSH CX
PUSH DX
PUSH BX
MOV CH,0 ; MJM 9.01.05
MOV LBLOCK1,CX ; MJM 9.01.05
MOV DX,Offset LSTBLOCK
MOV CL,DBIOS
INT 224
POP BX
POP DX
POP CX
RET
;
LSTBLOCK DB DLIST
LBLOCK1 DW 0
DW 0
;
LSTSTAT:
PUSH CX
PUSH DX
PUSH BX
MOV DX, OFFSET LSTSTATBLOCK
MOV CL,DBIOS
INT 224
POP BX
POP DX
POP CX
OR AL,AL
RET
LSTSTATBLOCK:
DB DLISTST
DW 0
DW 0
;
;
UCASE:
CMP AL,61H ;CHANGES LOWER CASE CHARACTER..
JC UCASERET ;..IN 'AL' REG TO UPPER CASE.
CMP AL,7BH
JNC UCASERET
AND AL,5FH
UCASERET:
RET
;
DECOUT:
PUSH AX
PUSH CX
PUSH DX
PUSH BX
MOV CX, -10
MOV DX, -1
DECOU2:
ADD BX,CX
INC DX
JC DECOU2
MOV CX,OFFSET 10
ADD BX,CX
XCHG BX,DX
MOV AL,BH
OR AL,BL
JZ DECOU3
CALL DECOUT
DECOU3:
MOV AL,DL
ADD AL,'0'
CALL CTYPE
POP BX
POP DX
POP CX
POP AX
RET
;
;----> DHXOUT: - DOUBLE PRECISION HEX OUTPUT ROUTINE.
;
DHXOUT:
PUSH BX
PUSH AX
MOV AL,BH ;GET MS BYTE
CALL HEXO ;OUTPUT HIGH ORDER BYTE
MOV AL,BL ;GET LS BYTE
CALL HEXO ;OUTPUT LOW ORDER BYTE
POP AX
POP BX
RET
;
HEXO:
PUSH AX
RCR AL,1
RCR AL,1
RCR AL,1
RCR AL,1
CALL NIBBL
POP AX
NIBBL:
AND AL,0FH
CMP AL,10
JC ISNUM
ADD AL,7
ISNUM:
ADD AL,'0'
JMP TIPE
;
SHFTYPE:
PUSH AX
CALL ILPRT
DB 'ctrl-',0
POP AX
ADD AL,40H
CALL TIPE
;
;WRITE A STRING OF CHARACTERS
;
ILPRT:
POP SI
ILPLP:
LODS BYTE PTR [SI]
OR AL,AL
JZ ILPRET
; CALL TIPE ; @DH
CALL CTYPE ;CTYPE expands tabs @DH
JMPS ILPLP
ILPRET:
PUSH SI
RET
;
;WRITE A STRING OF CHARACTERS EXCEPT IN QUIET MODE
;
ILPRTQ:
POP SI
ILPLPQ:
LODS BYTE PTR [SI]
OR AL,AL
JZ ILPRETQ
TEST QFLG,0FFH
JZ ILPLPQ1
; CALL TIPE ; @DH
CALL CTYPE ;CTYPE expands tabs @DH
ILPLPQ1:
JMPS ILPLPQ
ILPRETQ:
PUSH SI
RET
;
;
;Duplicates 'read buffer' routine same as CP/M function 10,
;but does not use CTL-C (reason for the routine). Does
;allow controls U, R, E and H (backspace). Outputs bell if
;the input is greater than the buffer.
;
INBUFF:
LAHF
XCHG AL,AH
PUSH AX
XCHG AL,AH
PUSH BX
PUSH CX
PUSH DX ;'DX' REGISTERS MUST BE PUSHED LAST
ISTART:
CALL CLEAR ;CLEAR THE BUFFER AREA
POP DX ;GET ADDRESS OF BUFFER ON RETRIES
PUSH DX ;RESTORE STACK
XOR AL,AL
LAHF ;ADDRESS COUNT FIELD
INC DX
SAHF
MOV SI,DX ;INITIALIZE WITH A ZERO IN COUNT BYTE
MOV [SI],AL
LAHF
INC DX
SAHF
XCHG BX,DX ;ADDRESS FIRST BUFFER BYTE WITH 'BX'
INBUFA:
CALL CONIN
CMP AL,CR ;IS IT A RETURN?
JNZ INBUFA_1
JMP INBUFR ;IF SO, THEN RETURN
INBUFA_1:
CMP AL,7FH ;IS IT A DELETE?
JZ DELETE
CMP AL,8 ;CTL-H WILL BACKSPACE..
JZ DELETE ;..OVER DELETED CHAR.
CMP AL,'U'-40H ;IS IT A CTL-U
JNZ INBUFA_2
JMP INBUFO ;OUTPUT # CR-LF AND START OVER
INBUFA_2:
CMP AL,'R'-40H ;CTL-R RETYPES LINE
JNZ INBUFA_3
JMP RETYPE
INBUFA_3:
CMP AL,'E'-40H
JNZ INBUFA_4
JMP CRLF
INBUFA_4:
CMP AL,' ' ;NO CONTROL CHARACTERS OTHER..
JB INBUFA ;..THAN ABOVE ALLOWED.
MOV CH,AL ;SAVE INPUTTED CHARACTER
XCHG BX,DX ;SAVE 'BX' IN 'DX'
POP BX ;GET ADDRESS OF BUFFER IN 'BX'
PUSH BX ;RESTORE STACK
INC BX ;ADDRESS COUNT BYTE
INC Byte Ptr [BX] ;INCREASE COUNT BYTE
DEC BX ;ADDRESS MAXIMUM
MOV AL,Byte Ptr [BX] ;PUT MAXIMUM IN 'AL'
INC BX ;ADDRESS COUNT
CMP AL,Byte Ptr [BX] ;COMPARE COUNT TO MAXIMUM
JNB INBUFA_5
JMP ALERT ;IF MAXIMUM, RING BELL AND WAIT FOR CR
INBUFA_5:
XCHG BX,DX ;RESTORE BUFFER POINTER TO 'BX'
MOV Byte Ptr [BX],CH ;PUT INPUTTED CHARACTER IN BUFFER
MOV AL,CH ;OUTPUT IT
CALL TIPE
LAHF ;BUMP POINTER
INC BX
SAHF
JMPS INBUFA ;GET NEXT CHARACTER
;
DELETE:
XCHG BX,DX ;SAVE BUFFER POINTER IN 'DX'
POP BX ;ADDRESS BEGINNING OF BUFFER
PUSH BX ;RESTORE STACK
INC BX ;ADDRESS COUNT FIELD
MOV CH,AL ;SAVE DELETE CHAR - 7FH OR 08H
MOV AL,Byte Ptr [BX]
SUB AL,1 ;DECREASE COUNT
MOV Byte Ptr [BX],AL
JB NODEL ;DON'T DELETE PAST BEGINING OF BUFFER.
XCHG BX,DX ;RESTORE BUFFER POINTER TO 'BX'
DEC BX ;POINT TO LAST BYTE INPUTTED
MOV AL,CH ;GET BACK EITHER 7FH OR 08H
MOV CH,Byte Ptr [BX] ;GET CHARACTER BEING DELETED
MOV Byte Ptr [BX],' ' ;RESTORE BLANK
CMP AL,8
JZ BKSPC
CMP AL,7FH
JZ BKSPC0
JMP INBUFA ;GET NEXT CHARACTER
;
NODEL:
INC Byte Ptr [BX] ;DON'T LEAVE COUNT NEGATIVE
XCHG BX,DX ;RESTORE POINTER TO 'BX'
JMP INBUFA
;
BKSPC0:
MOV AL,08H
BKSPC:
CALL TIPE ;TRUE ERASE IF 08H
MOV AL,' '
CALL TIPE
MOV AL,8
CALL TIPE
JMP INBUFA
;
INBUFO:
MOV AL,'#'
CALL TIPE
CALL CRLF
JMP ISTART
;
RETYPE:
POP DX
PUSH DX
LAHF ;POINT TO CURRENT NUMBER..
INC DX
SAHF
MOV SI,DX ;..OF CHARACTERS.
MOV AL,[SI]
MOV CH,AL
MOV AL,'#'
CALL TIPE
CALL CRLF
MOV AL,CH ;TEST IF ZERO INPUT
OR AL,AL
JNZ CTLRLP
JMP INBUFA
CTLRLP:
LAHF
INC DX
SAHF
MOV SI,DX
MOV AL,[SI]
CALL TIPE
DEC CH
JNZ CTLRLP
JMP INBUFA
;
ALERT:
MOV AL,7
CALL TIPE
DEC Byte Ptr [BX]
XCHG BX,DX
JMP INBUFA
;
PCRLF:
CALL CRLF
JMP INBUFA
;
INBUFR:
CALL CRLF
POP DX
POP CX
POP BX
POP AX
XCHG AL,AH
SAHF
RET
;
CLEAR:
POP DX ;ACCOUNTS FOR CALL
POP BX ;ADDRESS BUFFER IN 'BX'
PUSH BX ;RESTORE..
PUSH DX ;..STACK
MOV CH,Byte Ptr [BX] ;SAVE MAXIMUM IN 'CH'
LAHF ;POINT TO FIRST..
INC BX
SAHF
LAHF ;..BUFFER BYTE.
INC BX
SAHF
MOV AL,' '
CLEARL:
MOV Byte Ptr [BX],AL
LAHF
INC BX
SAHF
DEC CH
JNZ CLEARL
RET
;
CONIN:
CALL KEYIN
CMP AL,61H ;CHANGE TO UPPER..
JB NOUCASE ;..CASE SINCE CP/M..
CMP AL,7BH ;..DOES THE SAME.
JNB NOUCASE
AND AL,5FH
NOUCASE:
RET
;
;Parses a CP/M buffer into format same as CP/M command line.
;
;Loads a command line addressed by 'DX' registers (max # characters in
;line in 'DX', number of characters in the line in 'DX'+1, line starts
;in 'DX'+2) into FCB addressed by 'BX' registers. The FCB should be at
;least 33 bytes in length. The command line buffer must have a maximum
;length of at least one more than the greatest number of characters
;that will be needed.
;
CPMLINE:
PUSH AX
PUSH CX
PUSH DX
PUSH BX
CALL CINIT ;FILLS FCBS WITH BLANKS AND NULLS
XCHG BX,DX ;GET START OF COMMAND LINE IN 'BX'
INC BX ;ADDRESS # BYTES IN CMD LINE
MOV DL,BYTE PTR [BX] ;LOAD 'DX' PAIR WITH # BYTES
MOV DH,0
INC BX
ADD BX,DX ;POINT TO BYTE AFTER LAST CHAR..
MOV BYTE PTR [BX],CR ;..IN CMD LINE AND STORE DELIMITER
POP BX ;RESTORE 'BX' AND 'DX'
POP DX
PUSH DX
PUSH BX
INC DX ;ADDRESS START OF COMMAND
INC DX
CALL DRIVE
NAME1:
MOV CL,8 ;TRANSFER FIRST FILENAME TO FCB
CALL TRANS
CMP AL,CR
JZ CDONE
CMP AL,' ' ;IF SPACE, THEN START OF..
JZ NAME2 ;..SECOND FILENAME.
TYPE1:
POP BX ;FILETYPE MUST BE AFTER..
PUSH BX ;..EIGHTH BYTE OF NAME
MOV CX, 9
ADD BX,CX
MOV CL,3 ;TRANSFER TYPE OF FIRST FILE
CALL TRANS
CMP AL,CR
JZ CDONE
NAME2:
XCHG BX,DX
MOV AL,BYTE PTR [BX] ;EAT MULTIPLE SPACES..
XCHG BX,DX
CMP AL,' ' ;..BETWEEN NAMES
JNZ NAME2C
INC DX
JMP NAME2
NAME2C:
POP BX ;SECOND NAME STARTS IN 16TH BYTE
PUSH BX ;POINT 'BX' TO THIS BYTE
MOV CX, 16
ADD BX,CX
CALL DRIVE
MOV CL,8
CALL TRANS
CMP AL,CR
JZ CDONE
TYPE2:
POP BX ;SECOND TYPE STARTS IN 25TH BYTE.
PUSH BX
MOV CX,OFFSET 25
ADD BX,CX
MOV CL,3
CALL TRANS
CDONE:
POP BX
PUSH BX
INC BX ;POINT TO 1ST CHAR OF 1ST NAME IN FCB
CALL CSCAN ;CHECK FOR * (AMBIGUOUS NAMES).
POP BX
PUSH BX
MOV CX,OFFSET 17 ;POINT TO 1ST CHAR OF 2ND NAME IN FCB.
ADD BX,CX
CALL CSCAN
POP BX
POP DX
POP CX
POP AX
RET
;
CINIT:
PUSH BX ;INITIALIZES FCB WITH 1 NULL (FOR 1ST DRIVE),..
PUSH CX ;..11 BLANKS, 4 NULLS, 1 NULL (FOR 2ND DRIVE)..
MOV BYTE PTR [BX],0 ;..11 BLANKS, AND 4 NULLS
INC BX
MOV CH,11
MOV AL,' '
CALL INITFILL
MOV CH,5
MOV AL,0
CALL INITFILL
MOV CH,11
MOV AL,' '
CALL INITFILL
MOV CH,4
MOV AL,0
CALL INITFILL
POP CX
POP BX
RET
;
INITFILL:
MOV BYTE PTR [BX],AL
INC BX
DEC CH
JNZ INITFILL
RET
;
DRIVE:
INC DX ;CHECK 2ND BYTE OF FILENAME. IF IT..
XCHG BX,DX
MOV AL,BYTE PTR [BX] ;..IS A ":", THEN DRIVE WAS SPECIFIED
XCHG BX,DX
DEC DX
CMP AL,':'
JNZ DEFDR ;ELSE ZERO FOR DEFAULT DRIVE ('INIT' PUT ZERO)
XCHG BX,DX
MOV AL,BYTE PTR [BX]
XCHG BX,DX
AND AL,5FH
SUB AL,40H ;CALCULATE DRIVE (A=1, B=2,...)..
MOV BYTE PTR [BX],AL ;..AND PLACE IT IN FCB
INC DX ;ADDRESS FIRST BYTE OF..
INC DX ;..IN CMD LINE..
DEFDR:
INC BX ;..AND NAME FIELD IN FCB
DEFDRRET:
RET
;
TRANS:
XCHG BX,DX
MOV AL,BYTE PTR [BX]
XCHG BX,DX ;TRANSFER FROM CMD LINE TO FCB..
INC DX ;..UP TO NUMBER OF CHARS SPECIFIED..
CMP AL,CR ;..BY 'CL' REG. KEEP SCANNING FIELD..
JZ DEFDRRET ;..WITHOUT TRANSFER UNTIL A DELIMITING..
CMP AL,'.' ;..FIELD CHAR SUCH AS '.', BLANK, OR..
JZ DEFDRRET ;..C/R (FOR END OF CMD LINE)
CMP AL,' '
JZ DEFDRRET
DEC CL
JB TRANS ;ONCE 'CL' REG IS LESS THAN '0' KEEP READING
MOV BYTE PTR [BX],AL ;..CMD LINE BUT DO NOT TRANSFER TO FCB
INC BX
JMP TRANS
;
CSCAN:
MOV CH,8 ;SCAN FILE NAME ADDRESSED BY 'BX'
TSTNAM:
MOV AL,BYTE PTR [BX]
CMP AL,'*' ;IF '*' FOUND, FILL IN REST OF FIELD..
JZ FILL1 ;..WITH '?' FOR AMBIGUOUS NAME
INC BX
DEC CH
JNZ TSTNAM
JMP TSTTYP
;
FILL1:
CALL FILL
TSTTYP:
MOV CH,3 ;SCAN AND FILL TYPE FIELD FOR NAME..
TSTTYPL:
MOV AL,BYTE PTR [BX] ;..SPECIFIED ABOVE
CMP AL,'*'
JZ FILL2
INC BX
DEC CH
JZ FILL2RET
JMP TSTTYPL
;
FILL2:
CALL FILL
FILL2RET:
RET
;
FILL:
MOV BYTE PTR [BX],'?' ;ROUTINE TRANSFERS '?'
INC BX
DEC CH
JNZ FILL
RET
;
;
;In-line compare. Compares string addressed by 'DX' pair to string af-
;the call (ends with '0'). Return with carry set means strings not the
;same. All registers (except 'AL') are unaffected.
;
ILCOMP:
POP SI ; POINT 'SI' TO 1ST CHARACTER
PUSH BX
MOV BX,SI
PUSH DX
ILCOMPL:
MOV AL,BYTE PTR [BX] ;'BX' POINTS TO IN-LINE STRING
OR AL,AL ;END OF STRING IF ZERO
JZ SAME
XCHG BX,DX
MOV AL,BYTE PTR [BX]
XCHG BX,DX
CMP AL,BYTE PTR [BX]
JNZ NOTSAME
INC BX
INC DX
JMP ILCOMPL
;
NOTSAME:
MOV AL,0 ;IF NOT SAME, FINISH THRU..
NSLP:
INC BX ;..STRING SO RETURN WILL..
CMP AL,BYTE PTR [BX] ;..GO TO INSTRUCTION AFTER..
JNZ NSLP ;..STRING AND NOT REMAINDER OF STRING
STC
SAME:
POP DX
INC BX ;AVOIDS A NOP INSTRUCTION..
MOV SI,BX ;..WHEN RETURNING
POP BX
PUSH SI
RET
;
;
; TERM.A86
;
;Terminal routines with text file I/O for MODEM9.xx.
;
DSKSAVE:
CALL CKMODM
MOV AL,BYTE PTR .FCB+1 ;FIRST CHAR OF FILENAME
CMP AL,' ' ;FILE SPEC'D
JNZ GOODNM ;YES, GOOD NAME
MOV NFILFLG,TRUE
MOV SAVEFLG,FALSE
JMP TERM
;
GOODNM:
CALL ERASFIL
CALL MOVE2
MOV DX,OFFSET FCB3
MOV CL,MAKE
INT 224
MOV DX,OFFSET FCB3
MOV CL,OPEN
INT 224
MOV BX,OFFSET BOTTRAM
MOV HLSAVE,BX
MOV NFILFLG,0
MOV LISTMOR,0 ;STOP ANY BUFFERED PRINTER OUTPUT
TERM:
TEST LISTMOR,0FFH ;ANY BUFFERED PRINTER OUTPUT?
JZ TERM1
CALL GOLIST ;GO IF SO
TERM1:
CALL STAT ;KEYPRESS?
JNZ TERM2
JMP TERML ;NO, CHECK LINE
TERM2:
CALL KEYIN ;GET CHAR FROM KBD
CMP AL,' '
JC TERM3
JMP NOTOG ;GO IF NOT CONTROL CHARACTER
TERM3:
MOV CH,AL ;SAVE
CMP AL,BKSP ;TEST FOR BACKSPACE
JNZ NOBKSP
TEST CONVBKSP,0FFH ;CONVERT BACKSPACE TO RUB?
JZ NOBKSP ;GO IF NO CONVERSION
MOV AL,RUB
JMP NOTOG
NOBKSP:
TEST EXACFLG,0FFH ; EXACT ?
MOV EXACFLG,0 ;CLR FOR NEXT TIME
JZ NOTEXAFLG ;GO OF EXAFLG FALSE
TEST LOCONEXTCHR,0FFH ;SHOULD WE SEND ON EXAFLG?
MOV AL,CH
JNZ NOBKSP1
JMP NOTOG ;YES, IF LOCONEXTCHR FALSE
NOBKSP1:
MOV AL,EXTCHR ;WE WANT TO SEND EXTCHR IN ANY CASE
CMP AL,CH
MOV AL,CH
JNZ NOBKSP2
JMP NOTOG ;SEND IF EXTCHR
NOBKSP2:
JMP LOCCHK ;OTHERWISE DO LOCAL STUFF
NOTEXAFLG:
MOV AL,EXTCHR ;TREAT NEXT CHARACTER IN SPECIAL WAY?
CMP AL,CH
JNZ NOTEXA1
JMP EXTFLG ;YES, SET EXAFLG FOR NEXT CHAR
NOTEXA1:
MOV AL,LOCONEXTCHR
OR AL,AL ;SHOULD WE SEND IF NOT EXAFLG
MOV AL,CH
JZ LOCCHK
JMP NOTOG ;YES, IF LOCONEXTCHR TRUE
LOCCHK:
MOV AL,EXITCHR ;RETURN TO MENU?
CMP AL,CH
JNZ LOCCHK1
JMP EXITMEN ;YES, RETURN TO MENU
LOCCHK1:
MOV AL,TRANCHR ;OUTPUT TEXT FILE TO REMOTE?
CMP AL,CH
JNZ LOCCHK1A ; @DH
; JNZ LOCCHK2 ; @DH
CALL TRANSFER ;SEND-A-FILE (BLIND SEND)
LOCCHK1A: ; @DH
MOV AL,BAUDCHR ;change baud rate.. 30/DEC/84 @DH
CMP AL,CH ;..from terminal mode @DH
JNZ LOCCHK2 ; @DH
CALL BAUDCHG ; @DH
LOCCHK2:
JNZ LOCCHK3
JMP TERM ;LOOP
LOCCHK3:
MOV AL,TRANLOGON
OR AL,AL
JZ SKPLOGON
MOV AL,LOGCHR ;SEND LOGON?
CMP AL,CH
JNZ SKPLOGON
JMP SENDLOG
SKPLOGON:
MOV AL,LSTTST
OR AL,AL
JZ NOLST
MOV AL,LSTCHR
CMP AL,CH
JNZ NOLST
MOV AL,LISTFLG
NOT AL
MOV LISTFLG,AL
CALL CRLF
CALL CRLF
CALL LSTMSG
CALL CRLF
JMP TERML
NOLST:
MOV AL,UNSAVECHR ;CLOSE INPUT BUFFER?
CMP AL,CH
JZ S2A ;IF YES, DISABLE COPY
MOV AL,SAVECHR ;OPEN INPUT BUFFER?
CMP AL,CH
MOV AL,CH ;RESTORE CHARACTER TYPED
JZ NOLST1
JMP NOTOG
NOLST1:
MOV AL,NFILFLG ;DO NOT ALLOW SAVE IF..
CMP AL,TRUE ;..THIS FLAG IS SET.
JNZ NOLST1A
JMP TERML
NOLST1A:
MOV AL,TRUE ;0FFH -- ALLOW COPY INTO FILE
JMP S2B
S2A:
MOV AL,FALSE ;0 -- STOP COPY INTO FILE
S2B:
MOV SAVEFLG,AL
CALL BUFMSG
JMP TERML
;
BUFMSG:
CALL ILPRT
DB CR,LF,LF,'** Memory buffer ',0
TEST SAVEFLG,0FFH
JZ BUFMSG2
CALL ILPRT
DB 'open **',CR,LF,LF,':',BELL,0
RET
;
BUFMSG2:
CALL ILPRT
DB 'closed **',CR,LF,LF,BELL,0
RET
;
EXITMEN:
CALL CRLF
CALL CLREOS ;CLEAR TO END OF SCREEN TO CLEAN UP ANY MESS
JMP MENU0
;
SENDREADY:
CALL INMODCTLP
CALL ANIMODSNDB
CALL CPIMODSNDR
RET
;
SENDLF:
CALL SENDREADY
JNZ NOLFYET ;GO IF NOT READY FOR OUTPUT YET
MOV AL,LF
JMP NOTOG ;SEND LF
NOLFYET:
CALL EXITTEST
JNC EXITMEN ;GO IF SO, SO DON'T GET HUNG UP
JMP SENDLF ;ELSE KEEP TRYING TO SEND LF
;
SENDLOG:
PUSH BX
SNDLG2:
CALL STAT
JZ SNDLG2
CALL KEYIN
CALL UCASE
CMP AL,'L' ;TEST IF LIST OF STRINGS REQUESTED
JZ GIVESTRS
SUB AL,'0'
CMP AL,10
JNC ENDLOG
ADD AL,AL ;X2
ADD AL,AL ;X4
ADD AL,AL ;X8
ADD AL,AL ;X16
MOV DL,AL
MOV DH,0
PUSH DX
POP BX
ADD BX,DX ;X32 IN HL
MOV DX,OFFSET STRINGS ;DE POINTS TO START OF STRINGS
ADD BX,DX
LOGLP:
CALL SENDREADY
JNZ NOSENDLOG ;GO IF NOT READY
MOV AL,BYTE PTR [BX] ;GET LOGON BYTE
INC BX
CMP AL,0 ;IS IT THE END?
JZ ENDLOG ;GO IF SO
CALL OUTMODDATP
JMP LOGLP
NOSENDLOG:
CALL EXITTEST ;TEST SO DON'T GET HUNG UP
JNC EXITLOG ;GO IF OPERATOR WANTS EXIT
JMP LOGLP
;
ENDLOG:
POP BX
JMP TERML
;
EXITLOG:
POP BX
JMP EXITMEN
;
EXITTEST:
CALL STAT ;KEYPRESS?
JZ NOKEY
CALL KEYIN
MOV CH,AL
MOV AL,EXITCHR ;SEE IF OPERATOR WANTS EXIT
CMP AL,CH
JNZ NOKEY ;GO IF WRONG KEY
STC
CMC ;RESET FOR EXIT
RET
NOKEY:
STC ;SET FOR NO KEY OR WRONG KEY
RET
;
GIVESTRS:
CALL ILPRT
DB CR,LF,' List of Strings',CR,LF,LF,LF,0
MOV BX,OFFSET STRINGS
MOV STRSAVE,BX
MOV CH,'0'
GVSTRS1:
MOV AL,CH
CALL TIPE
CALL ILPRT
DB ' = ',0
MOV BX,STRSAVE
MOV AL,BYTE PTR [BX]
CMP AL,0
JNZ NONULL
CALL ILPRT
DB '* null string *',0
JMP GVSTRS2
NONULL:
MOV BX,STRSAVE
NONUL2:
MOV AL,BYTE PTR [BX]
CMP AL,0
JZ GVSTRS2
CMP AL,CR
JZ NONUL3
CALL TIPE
NONUL3:
JNZ NOTACR
PUSH BX
CALL ILPRT
DB '<CR>',0
POP BX
NOTACR:
INC BX
JMP NONUL2
;
GVSTRS2:
MOV AL,'9'
CMP AL,CH
JZ GVSTRS3
INC CH
MOV BX,STRSAVE
MOV DX,OFFSET 32
ADD BX,DX
MOV STRSAVE,BX
CALL CRLF
JMP GVSTRS1
;
GVSTRS3:
CALL ILPRT
DB CR,LF,LF,'Enter number to transmit string',CR,LF,0
POP BX
JMP SENDLOG
;
EXTFLG:
MOV AL,TRUE
MOV EXACFLG,AL
JMP TERML
;
RCVREADY:
CALL INMODCTLP
CALL ANIMODRCVB
CALL CPIMODRCVR
RET
;
LSTMSG:
MOV AL,LISTFLG
OR AL,AL
JZ LSTMSG2
CALL ILPRT
DB 'Printer is on',CR,LF,0
RET
LSTMSG2:
CALL ILPRT
DB 'Printer is off',CR,LF,0
RET
;
NOTOG:
PUSH AX
NOTOG1:
CALL SENDREADY
JNZ NOTOG1
POP AX
CALL OUTMODDATP
MOV CH,AL
MOV AL,LOCFLG
OR AL,AL
JNZ LTYPE
MOV AL,ECHOFLG
OR AL,AL
JZ CHKCR
LTYPE:
MOV AL,CH
CALL TIPE
CALL CHKSAVE ;TO STORE LOCAL IF BUFFER OPEN
CALL CHKPRNT
CHKCR:
MOV AL,CR
CMP AL,CH
JNZ TERML
MOV AL,ADDLF
OR AL,AL
JZ TERML
JMP SENDLF
;
TERML:
CALL RCVREADY ;TEST FOR RECEIVED CHARACTER
JZ TERML1
JMP TERM
TERML1:
CALL INMODDATP
AND AL,7FH ;STRIP PARITY
JNZ GIVLF
JMP TERM
GIVLF:
MOV CH,AL
; CALL TIPE ; @DH
CALL CTYPE ;CTYPE EXPANDS TABS @DH
CALL CHKSAVE
CALL CHKPRNT
MOV AL,ECHOFLG
OR AL,AL
JZ NOECHO
MOV AL,CH
CALL OUTMODDATP
NOECHO:
MOV AL,CR
CMP AL,CH
JZ NOECHO1
JMP TERM
NOECHO1:
MOV AL,ADDLF
JNZ NOECHO2
JMP TERM
NOECHO2:
MOV AL,ECHOFLG
OR AL,AL
JZ NOECHO3
JMP SENDLF
NOECHO3:
MOV AL,LF
JMP GIVLF
;
CHKSAVE:
MOV AL,SAVEFLG
OR AL,AL
JNZ CHKSAVE1
RET
CHKSAVE1:
MOV BYTE PTR [BX],CH
INC BX
MOV HLSAVE,BX ;MENU COMMAND DESTROYS HL-REG..
MOV AL,LF
CMP AL,CH
JNZ NOCOLON ;..TYPE ":" AFTER EACH LINE FEED..
MOV AL,':' ;..WHEN MEMORY SAVE ACTIVE.
CALL TIPE
NOCOLON:
CALL GETMAX
CMP AL,BH
PUSH CX
JNZ NOCOLON1
CALL INTDSKSV
NOCOLON1:
POP CX
RET
;
GETMAX:
MOV AL,XAST SHR 8 ;END OF RESERVED BUFFER HAS BEEN
RET ;..REACHED AND DISKSAVE IS NEEDED.
;
CHKPRNT:
TEST LISTFLG,0FFH ;OUT TO PRINTER?
JNZ CHKPRNT1
RET ;RETURN IF NOT
CHKPRNT1:
TEST NFILFLG,0FFH ;IS BUFFER USED FOR FILE?
JZ NOBUFF ;DON'T BUFFER PRINTER IF SO, HOWEVER CHARACTERS
;WILL BE LOST IF PRINTER IS SLOWER THAN MODEM
CALL GETMAX ;GET MAXIMUM FOR BUFFER
MOV BX,HLSAVE1
CMP AL,BH ;ARE WE THERE?
JNZ NOTMAX ;GO IF NOT
MOV BX,OFFSET BOTTRAM ;FLUSH BUFFER
MOV HLSAVE1,BX
MOV HLSAVE2,BX
NOTMAX:
MOV BYTE PTR [BX],CH ;SAVE CHARACTER IN BUFFER
INC BX ;INCREMENT END OF BUFFER
MOV HLSAVE1,BX
MOV AL,TRUE ;SET FLAG FOR PRINTER OUTPUT
MOV LISTMOR,AL
RET
;
NOBUFF:
CALL LSTSTAT
JNZ NOBUFF1
RET ;RETURN IF PRINTER BUSY
NOBUFF1:
MOV CL,CH ;ELSE PRINT CHARACTER
CALL LISTER
RET
;
GOLIST:
CALL LSTSTAT
JNZ GOLIST1
RET ;RETURN IF PRINTER BUSY
GOLIST1:
MOV BX,HLSAVE2 ;GET LOCATION OF NEXT CHARACTER TO PRINT
MOV CL,BYTE PTR [BX] ;GET CHARACTER
INC BX ;INCREMENT POINTER
MOV HLSAVE2,BX
CALL CMPBUFF ;CHECK FOR END OF BUFFER
CALL LISTER ;PRINT
RET
;
;ROUTINE CHECKS FOR END OF BUFFER, RESETS BUFFER IF SO AND STOPS
;PRINTER OUTPUT
;
CMPBUFF:
MOV BX,HLSAVE2
CMP BX,HLSAVE1
JZ CMPBUFF1
RET
CMPBUFF1:
MOV BX,OFFSET BOTTRAM
MOV HLSAVE1,BX
MOV HLSAVE2,BX
MOV LISTMOR,0
RET
;
INTDSKSV:
MOV AL,XOFF ;SEND A CTRL-S TO STOP..
CALL OUTMODDATP ;..REMOTE COMPUTER OUTPUT.
MOV DH,0 ;D IS THE BUFFER COUNT
CALL INMODEM ;GET LAST BYTES SENT..
MOV LASTBYT1,AL ;..AFTER CTRL-S.
CALL INMODEM ;ADD MORE CALLS TO INMODEM..
MOV LASTBYT2,AL ;..AND STA LASTBYT# IF YOU ARE..
PUSH DX
CALL NUMREC1
CALL WRTDSK ;WRITE THE RECORDS
POP DX
MOV BX,OFFSET BOTTRAM
INC DH
DEC DH ;TEST BUFFER COUNT FOR ZERO
JZ CTRLQ
MOV AL,LASTBYT1 ;GET THE LAST BYTES THAT WERE..
MOV BYTE PTR [BX],AL ;..SAVED AND PUT THEM IN..
INC BX ;..BOTTRAM.
CALL TIPE
DEC DH
JZ CTRLQ
MOV AL,LASTBYT2
MOV BYTE PTR [BX],AL
INC BX
CALL TIPE
CTRLQ:
MOV AL,XON ;SEND START CHARACTER..
CALL OUTMODDATP ;..TO REMOTE COMPUTER.
RET
;
;THIS SUBROUTINE WILL LOOP UNTIL THE MODEM RECEIVES A CHARACTER
;OR 100 MILLISECONDS. IF A CHARACTER IS RECEIVED, A FLAG IS SET
;TO STORE THE CHARACTER. A MAXIMUM OF TWO CHARACTERS ARE STORED,
;BUT MORE MAY BE STORED IF DESIRED (SEE COMMENT IN "INTDSKSV"
;ABOVE).
;
INMODEM:
PUSH BX
MOV BX,OFFSET 625
CALL FIXCNT
PUSH BX
POP CX
POP BX
TIMERL:
CALL RCVREADY
JZ GETBYTE
DEC CX
MOV AL,CH
OR AL,CL
JNZ TIMERL
RET
;
GETBYTE:
CALL INMODDATP
INC DH
RET
;
NUMRECS:
MOV BYTE PTR [BX],EOFCHAR
INC BX
MOV DX,OFFSET 127
ADD BX,DX
NUMREC1:
MOV DX,-(OFFSET BOTTRAM)
ADD BX,DX
MOV AL,BL ;DIVIDE HL BY 128..
RCL AL,1 ;High bit set if sector to save
MOV AL,0 ;Save in carry
RCL AL,1 ;Now see if needed
MOV BL,BH ;..NUMBER OF SECTORS
MOV BH,0
PUSH AX
ADD BX,BX
POP AX
ADC AL,BL
MOV BL,AL ;RETURNS WITH NUMBER OF..
RET ;..128 BYTE RECORDS IN HL.
;
WRTDSK:
MOV DX,OFFSET BOTTRAM
NEXTWRT:
MOV CL,STDMA
CALL BDOSRT
PUSH DX
MOV DX,OFFSET FCB3
MOV CL,WRITE
CALL BDOSRT
POP DX
ADD DX,128
DEC BX
JNZ NEXTWRT
RET
;
CLOSE3:
MOV DX,OFFSET FCB3
MOV CL,CLOSE
INT 224
RET
;
BDOSRT:
PUSH CX
PUSH DX
PUSH BX
PUSH AX
INT 224
POP AX
POP BX
POP DX
POP CX
RET
;
MOVE2:
MOV BX,OFFSET FCB3
CALL INITFCBS
MOV BX,OFFSET FCB
MOV DX,OFFSET FCB3
MOV CH,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 BX
PUSH DX
PUSH CX
PUSH AX
MOV BX,OFFSET FCB4
CALL INITFCBS ;INITIALIZES FCBS POINTED..
MOV BX,OFFSET FCB+16 ;..TO BY HL REG.
CALL INITFCBS
GET:
CALL GETNAME
MOV AL,CMDBUF+2 ;WAS FILE ENTERED
CMP AL,20H
JZ TRANSL2
CALL MOVE4
CALL OPEN4
CMP AL,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
PUSH AX
CALL TIPE ;ECHO RESPONSE
CALL CRLF
POP AX
CMP AL,'A'
JNZ TRANSL3
JMP GET
TRANSL3:
CMP AL,'R'
JNZ TRANSL2
JMP RETURN
;
CONTIN:
MOV DX,OFFSET 80H
MOV CL,STDMA
INT 224
READMR:
CALL READ80
CMP AL,1 ;END OF FILE
JZ RETURNS
CMP AL,2 ;BAD READ
JZ RETURNU
CALL SEND80C
CMP AL,EOFCHAR ;END OF FILE - OMIT IF OBJECT..
JZ RETURNS ;..CODE IS TO BE SENT.
CMP AL,CAN ;CANCELLATION?
JZ TRANCAN
JMP READMR
;
RETURNS:
CALL ILPRT
DB CR,LF,'File transfer completed',CR,LF,BELL,0
JMP RETURN
;
RETURNU:
CALL ILPRT
DB CR,LF,'++ File transfer unsuccessful ++',CR,LF,BELL,0
JMP RETURN
;
TRANCAN:
CALL ILPRT
DB CR,LF,LF,'++ Transfer cancelled ++',CR,LF,BELL,0
RETURN:
POP AX
POP CX
POP DX
POP BX
RET
;
INITFCBS: ;ENTRY AT +2 WILL LEAVE..
MOV BYTE PTR [BX],0 ;..DRIVE NO. INTACT.
;see comments at label GETFN: @DH
;..about drive @DH
INC BX ;WILL INITIALIZE AN FCB..
MOV CH,11 ;..POINTED TO BY HL-REG. FILLS 1ST POS
LOOP10:
MOV BYTE PTR [BX],' ' ;..WITH 0, NEXT 11 WITH..
INC BX ;..WITH BLANKS, AND LAST..
DEC CH ;..21 WITH NULLS.
JNZ LOOP10
MOV CH,21
LOOP11:
MOV BYTE PTR [BX],0
INC BX
DEC CH
JNZ LOOP11
RET
;
GETNAME:
CALL ILPRT
DB CR,LF,'Enter file name to be transferred - <CR> TO QUIT: ',0
MOV DX,OFFSET CMDBUF
CALL INBUFF
CALL CRLF
RET
;
MOVE4:
MOV DX,OFFSET CMDBUF
MOV BX,OFFSET FCB4
CALL CPMLINE
RET
;
OPEN4:
MOV DX,OFFSET FCB4
MOV CL,OPEN
INT 224
RET
;
READ80:
MOV DX,OFFSET FCB4
MOV CL,READ
INT 224
RET
;
SEND80C:
MOV CH,80H
MOV BX,OFFSET 80H
SENDCH1:
PUSH DX
CALL SPEED
POP DX
MOV AL,BYTE PTR [BX]
CMP AL,EOFCHAR
JNZ SENDCH3
MOV AL,EOFSEND
OR AL,AL
JNZ SENDCH2
RET
SENDCH2:
MOV AL,BYTE PTR [BX]
SENDCH3:
CALL MODOUT
CMP AL,EOFCHAR
JNZ SENDCH4
RET
SENDCH4:
CALL STAT ;TEST TO SEE IF
OR AL,AL ;CANCELLATION REQUESTED
JZ SKIP12
CALL KEYIN
CMP AL,CAN
JNZ SKIP12
RET
SKIP12:
INC BX
DEC CH
JNZ SENDCH1
RET
;
MODOUT:
PUSH AX
MODOUTL:
MOV AL,XOFFTST
OR AL,AL
JZ MODOUTL1
CALL TXOFF
MODOUTL1:
CALL SENDREADY
JNZ MODOUTL
MOV AL,STRLF
OR AL,AL
JZ NOLFTST
POP AX
PUSH AX
CMP AL,LF
JZ NOTMOUT
NOLFTST:
POP AX
PUSH AX
MOV SAVEOUT,AL ;SAVE OUTPUT FOR POSSIBLE ECHO TEST
CALL OUTMODDATP
MOV AL,ECHWAIT ;DO WE WANT TO TEST FOR ECHOED CHAR?
OR AL,AL
JZ NOTMOUT
CALL WAITECHO ;GO IF SO
NOTMOUT:
POP AX
; CALL TIPE ; @DH
CALL CTYPE ;CTYPE EXPANDS TABS @DH
CMP AL,CR
JZ DLYCR
RET
;
DLYCR:
MOV AL,XONWAIT ;WAIT FOR XON AFTER CR?
OR AL,AL
JNZ WAITXON
MOV AL,CRDLY ;EXTRA DELAY AFTER CR
JMP DLYCR2
;
SPEED:
MOV AL,BYTDLY ;GET SPEED VALUE (0-9)
;DELAY IS FROM 0.02 SEC FOR SPDVAL = 1
;TO 0.18 SEC FOR SPDVAL = 9
DLYCR2:
OR AL,AL
JNZ DLYCR3
RET ;RETURN IF 0
DLYCR3:
MOV CL,AL
SPDLP:
CALL SPD1 ;OUTER LOOP
DEC CL
JNZ SPDLP
RET
;
SPD1:
PUSH BX
MOV BX,OFFSET 357 ;ABOUT 0.02 SEC
MOV AL,XOFFTST
OR AL,AL
JZ SPD2
MOV BX,OFFSET 102 ;ADJUST FOR XOFF TESTING
MOV AL,ECHOFLG
OR AL,AL
JZ SPD2
MOV AL,LOCFLG
OR AL,AL
JZ SPD2
MOV BX,OFFSET 76 ;ADJUST AGAIN FOR REMOTE ECHO
SPD2:
CALL FIXCNT
PUSH BX
POP DX
POP BX
SPDLP1:
DEC DX ;INNER LOOP
MOV AL,XOFFTST
OR AL,AL
JZ SPDLP2
CALL TXOFF
SPDLP2:
MOV AL,DL
OR AL,DH
JNZ SPDLP1
RET
;
TXOFF:
CALL RCVREADY
JZ TXOFF1
RET
TXOFF1:
CALL INMODDATP
AND AL,7FH
CMP AL,XOFF
JNZ TXOFF2
CALL WAITXON
TXOFF2:
RET
;
WAITXON:
CALL RCVREADY
JNZ WTXON2
CALL INMODDATP
AND AL,7FH
CMP AL,XON
JNZ WTXON2
RET
WTXON2:
CALL STAT ;TEST TO SEE IF
OR AL,AL ;CANCELLATION REQUESTED
JZ WAITXON ;SO DON'T GET HUNG UP
CALL KEYIN
CMP AL,CAN
JNZ WAITXON
RET
;
WAITECHO:
MOV AL,50 ;1 SECOND MAXIMUM DELAY WAITING FOR ECHO
MOV MECHDLY,AL
WTECH1:
CALL RCVREADY ;IS THERE INPUT?
JNZ WTECH2 ;GO IF NOT
CALL INMODDATP ;GET INPUT
AND AL,7FH
MOV CL,AL ;SAVE INPUT
MOV AL,SAVEOUT ;GET OUTPUT
CMP AL,CL ;ARE THEY THE SAME?
JNZ WTECH1A
RET ;RETURN IF SO
WTECH1A:
MOV AL,SAVEOUT ;GET OUTPUT
CMP AL,TAB ;CHECK IF TAB
JNZ WTECH2 ;GO IF NOT
MOV AL,SPACE ;MAYBE REMOTE CONVERTS TABS TO SPACES
CMP AL,CL
JNZ WTECH2
RET ;RETURN IF SPACE ECHOED ON TAB OUTPUT
WTECH2:
MOV AL,MECHDLY ;LOOP FOR 1 SECOND
DEC AL
MOV MECHDLY,AL
JNZ WTECH3
RET
WTECH3:
MOV AL,1 ;0.02 SECOND
CALL DLYCR2
JMP WTECH1
;
; Check for any garbage characters on line.
;
CKMODM:
CALL RCVREADY ;ANY CHARACTERS READY TO RECEIVE?
JZ CKMODM1
RET ;IF NOT, RETURN
CKMODM1:
CALL INMODDATP ;OTHERWISE GET THE CHARACTER AND IGNORE
JMP CKMODM ;CHECK FOR ANY ADDITIONAL CHARACTERS
;
;
; SENDRECV.A86
;
;Christensen protocol routines for MODEM9.xx.
;
;SEND A CP/M FILE
;
SENDFIL:
MOV CKSUMFLG,TRUE ;ALWAYS FORCE CHECKSUM MODE INITIALLY ON SEND
CALL CKMODM ;REMOVE GARBAGE FROM LINE
SENDFIL1:
TEST BATCHFLG,0FFH ;CHECK IF MULTIPLE FILE..
JNZ SENDC1
CALL ILPRT
DB 'Ready to send in the batch mode',CR,LF,0
MOV SENDFLG,TRUE ;INDICATE SEND FOR BATCH MODE
MOV AL,FSTFLG ;IF FIRST TIME THRU..
OR AL,AL ;..SCAN THE COMMAND LINE..
JZ SENDFIL2
CALL TNMBUF ;..FOR MULTIPLE NAMES.
SENDFIL2:
CALL SENDFN ;SENDS FILE NAME TO RECEIVER
JNC SENDC2 ;CARRY SET MEANS NO MORE FILES.
MOV BATCHFLG,'B' ;STOP BATCH ....MODE OPTION.
MOV AL,EOT ;FINAL XFER END
CALL SEND
JMP DONE
;
SENDC1:
CMP BYTE PTR .FCB+1,' '
JNZ SENDC2
JMP BLKFILE
SENDC2:
CALL CNREC ;GET NUMBER OF RECORDS
CALL OPENFIL
MOV DL,80
CALL WAITNAK
SENDLP:
CALL CKABORT ;WANT TO TERMINATE WHLE SENDING FILE?
CALL RDSECT
JC SENDEOF
CALL INCRSNO
MOV ERRCT,1
SENDRPT:
CALL CKABORT ;WANT TO TERMINATE WHILE SENDING FILE?
CALL SENDHDR
CALL SENDSEC
MOV AL,CKSUMFLG
OR AL,AL
JNZ SENDRPT1
CALL SENDCRC
JMPS SENDRPT2
SENDRPT1:
CALL SENDCKS
SENDRPT2:
CALL GETACK
JC SENDRPT
JMP SENDLP
;
SENDEOF:
MOV AL,EOT
CALL SEND
CALL GETACK
JC SENDEOF
JMP DONE
;
;RECEIVE A FILE
;
RCVFIL:
MOV AL,CKSUMDFLT ;GET MODE REQUESTED BY OPERATOR
MOV CKSUMFLG,AL ;STORE IT
CALL CKMODM ;CATCH ANY GARBAGE CHARACTERS
RCVFIL1:
MOV AL,BATCHFLG ;CHECK IF MULT..
OR AL,AL ;..FILE MODE.
JNZ RCVC1
MOV AL,FALSE ;FLAG WHERE TO RETURN..
MOV SENDFLG,AL ;..FOR NEXT FILE TRANS.
CALL GETFN ;GET THE FILE NAME.
JNC RCVC2 ;CARRY SET MEANS NO MORE FILES.
MOV AL,'B' ;STOP BATCH..
MOV BATCHFLG,AL ;..MODE OPTION.
JMP DONE
;
RCVC1:
MOV AL,BYTE PTR .FCB+1 ;MAKE SURE FILE IS NAMED
CMP AL,' '
; JNZ RECV1A ; @DH
JNZ RCVC2 ; @DH
JMP BLKFILE
;RECV1A: ; @DH
; JMP RCVC3 ; @DH
;
RCVC2:
CALL CKCPM2
CALL CKBAKUP
RCVC3:
CALL ERASFIL
CALL MAKEFIL
MOV AL,BATCHFLG ;DON'T PRINT MSG IF IN BATCH
OR AL,AL
JZ RCVFST
CALL ILPRTQ
DB 'File open, ready to receive',CR,LF,0
RCVFST:
MOV AL,CKSUMFLG
OR AL,AL
MOV AL,NAK
JNZ RCVFIL2
MOV AL,CRC
RCVFIL2:
CALL SEND
MOV AL,CKSUMFLG
OR AL,AL
JNZ RCVNAKM ;IF IN CRC MODE
CALL ILPRTQ ;THEN SAY SO
DB 'CRC in effect',CR,LF,0
JMP RCVLP
RCVNAKM:
CALL ILPRTQ ;ELSE SAY CHECKSUM MODE
DB 'Checksum in effect',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
;
SENDFN:
CALL ILPRTQ
DB 'Awaiting name NAK',CR,LF,0
MOV DL,80
CALL WAITNLP
MOV AL,ACK ;GOT NAK, SEND ACK
CALL SEND
MOV BX,OFFSET FILECT
DEC BYTE PTR [BX]
JS NOMRNM
MOV BX,NBSAVE ;GET FILE NAME..
MOV DX,OFFSET FCB ;..IN FCB
MOV CH,12
CALL MOVE
MOV NBSAVE,BX
CALL SENDNM ;SEND IT
OR AL,AL ;CLEAR CARRY
RET
;
NOMRNM:
MOV AL,EOT
CALL SEND
STC
RET
;
SENDNM:
PUSH BX
SENDNM1:
MOV DH,11 ;COUNT CHARS IN NAME
MOV CL,0 ;INIT CHECKSUM
MOV AL,CL
MOV FTYCNT,AL ;INITIATE FILE TYPE COUNT
MOV BX,OFFSET FCB+1 ;ADDRESS NAME
NAMLPS:
MOV AL,BYTE PTR [BX] ;SEND NAME
AND AL,07FH ;STRIP HIGH ORDER BIT SO CP/M 2..
CALL SEND ;..WON'T SEND R/O FILE DESIGNATION.
MOV AL,QFLG ;SHOW NAME IF..
OR AL,AL ;..QFLG NOT SET.
MOV AL,BYTE PTR [BX]
JZ ACKLP
CALL FTYTST ;TYPE CHARACTER ETC.
ACKLP:
PUSH CX ;SAVE CKSUM
MOV CH,1 ;WAIT FOR RECEIVER..
CALL RECV ;..TO ACKNOWLEDGE..
POP CX ;..GETTING LETTER.
JC SCKSER
CMP AL,ACK
JNZ ACKLP
INC BX ;NEXT CHAR
DEC DH
JNZ NAMLPS
MOV AL,EOFCHAR ;TELL RECEIVER END OF NAME
CALL SEND
MOV AL,QFLG
OR AL,AL
JZ ACKLP1
CALL CRLF
ACKLP1:
MOV DH,CL ;SAVE CHECKSUM
MOV CH,1
CALL RECV ;GET CHECKSUM..
CMP AL,DH ;..FROM RECEIVER.
JZ NAMEOK
SCKSER: MOV AL,BDNMCH ;BAD NAME-TELL RECEIVER
CALL SEND
CALL ILPRTQ
DB 'Checksum error',CR,LF,0
MOV DL,80 ;DO HANDSHAKING OVER
CALL WAITNLP ;DON'T PRINT "AWAITING NAK" MSG
MOV AL,ACK
CALL SEND
JMP SENDNM1
;
NAMEOK:
MOV AL,OKNMCH ;GOOD NAME, TELL RECEIVER
CALL SEND
POP BX
RET
;
;fix for batch mode to save.. @DH
;drive and handle file name.. @DH
;properly. call to initfcb+2.. @DH
;left the byte ptr set wrong.. @DH
GETFN: MOV AL,BYTE PTR .FCB ;save drive number @DH
MOV DISKNO,AL ; @DH
MOV BX,OFFSET FCB ;blank out file control block @DH
CALL INITFCBS ; @DH
MOV AL,DISKNO ;put drive number back @DH
MOV BYTE PTR .FCB,AL ; @DH
;GETFN: MOV BX,OFFSET FCB ; @DH
; CALL INITFCBS+2 ;DOES NOT INITIALIZE DRIVE @DH
CALL ILPRTQ
DB 'Awaiting file name',CR,LF,0
GNAMELP:
CALL HSNAK
CALL GETNM ;GET THE NAME
CMP AL,EOT ;IF EOT, THEN NO MORE FILES
JZ NOMRNMG
OR AL,AL ;CLEAR CARRY
RET
;
NOMRNMG:
STC
RET
;
GETNM:
PUSH BX
GETNM1:
MOV CL,0 ;INIT CHECKSUM
MOV AL,CL
MOV FTYCNT,AL ;INITIATE COUNT FOR FILE TYPE
MOV BX,OFFSET FCB+1
NAMELPG:
MOV CH,5
CALL RECV ;GET CHAR
JNC GETNM3
CALL ILPRTQ
DB 'Time out receiving filename',CR,LF,0
JMP GCKSER
;
GETNM3:
CMP AL,EOT ;IF EOT, THEN NO MORE FILES
JNZ GETNM4
JMP GNRET
GETNM4:
CMP AL,EOFCHAR ;GOT END OF NAME
JZ ENDNAME
MOV BYTE PTR [BX],AL ;PUT NAME IN FCB
MOV AL,QFLG ;CAN TYPE IT IF NO QFLG
OR AL,AL
JZ SKPTYP
CALL FTYTST
SKPTYP:
PUSH CX ;SAVE CKSUM
MOV AL,ACK ;ACK GETTING LETTER
CALL SEND
POP CX
INC BX ;GET NEXT CHAR
MOV AL,BL ;DON'T LET NOISE...
CMP AL,7FH ;..CAUSE OVERFLOW..
JZ GCKSER ;..INTO PROGRAM AREA.
JMP NAMELPG
;
FTYTST:
INC FTYCNT
CMP FTYCNT,9 ; ARE WE AT THE FILE TYPE?
JZ SPCTST ;GO IF SO
ENDSPT:
MOV AL,BYTE PTR [BX]
CMP AL,' ' ;TEST FOR SPACE
JZ ENDSPT1
CALL TIPE ;TYPE IF NOT
ENDSPT1:
RET
;
SPCTST:
MOV AL,BYTE PTR [BX]
CMP AL,' ' ;TEST FOR SPACE IN FIRST FILE TYPE BYTE
JZ ENDSPT1 ;DON'T OUTPUT PERIOD IF SPACE
; MJM 9.01.05 WAS JMPS
MOV AL,'.'
CALL TIPE
JMP ENDSPT ;OUTPUT FIRST FILE TYPE BYTE
;
ENDNAME:
MOV AL,QFLG
OR AL,AL
JZ ENDNAME1
CALL CRLF
ENDNAME1:
MOV AL,CL ;SEND CHECKSUM
CALL SEND
MOV CH,1
CALL RECV ;CHECKSUM GOOD?
CMP AL,OKNMCH ;YES IF OKNMCH SENT..
JZ GNRET ;..ELSE DO OVER.
GCKSER:
MOV BX,OFFSET FCB ;CLEAR FCB (EXCEPT DRIVE)..
CALL INITFCBS+2 ;..SINCE IT MIGHT BE DAMAGED..
CALL ILPRTQ
DB CR,LF,'++ Checksum error ++',CR,LF,0
CALL HSNAK ;DO HANDSHAKING OVER
JMP GETNM1
;
GNRET:
POP BX
RET
;
HSNAK:
MOV DL,180 ;3-MINUTE MAXIMUM WAIT FOR A FILE NAME
HSNAK1:
CALL CKABORT ;WANT TO ABORT?
MOV AL,NAK ;SEND NAK UNTIL RECEIVING ACK
CALL SEND
MOV CH,1 ;WAIT UP TO 1 SECOND FOR A CHARACTER
CALL RECV
CMP AL,ACK ;'ACK' IS WHAT WE WERE WAITING FOR
JNZ HSNAK2
RET
HSNAK2:
DEC DL ;ONE LESS TO TRY
JNZ HSNAK1
JMP ABORT ;TIMED OUT, ABORT BACK TO COMMAND LINE
;
TNMBUF:
MOV AL,FALSE ;CALL FROM SENDFIL ONLY ONCE.
MOV FSTFLG,AL
MOV FILECT,AL
CALL SCAN
MOV BX,OFFSET NAMEBUF
MOV NBSAVE,BX ;SAVE ADDR OF 1ST NAME
TNLP1:
CALL TRTOBUF
MOV BX,OFFSET FCB
MOV DX,OFFSET FCBBUF
CALL CPMLINE ;PARSE NAME TO CP/M FORMAT
TNLP2:
CALL MFNAME ;SEARCH FOR NAMES (* FORMAT)
JC NEXTNM
MOV AL,BYTE PTR .FCB+10 ;IF CP/M 2 $SYS FILE..
AND AL,80H ;..DON'T SEND
JNZ TNLP2
MOV BX,NBSAVE ;GET NAME
MOV DX,OFFSET FCB ;MOVE IT TO FCB
XCHG BX,DX
MOV CH,12
CALL MOVE
XCHG BX,DX
MOV NBSAVE,BX ;ADDR OF NEXT NAME
MOV BX,OFFSET FILECT ;COUNT FILES FOUND
INC BYTE PTR [BX]
JMP TNLP2
;
NEXTNM:
MOV BX,OFFSET SNAMECT ;COUNT NAMES FOUND
DEC BYTE PTR [BX]
JNZ TNLP1
MOV BX,OFFSET NAMEBUF ;SAVE START OF BUFFER
MOV NBSAVE,BX
MOV AL,FILECT
CMP AL,65 ;NO MORE THAN 64 TRANSFERS
JNC NEXTNM1
RET
NEXTNM1:
MOV AL,64 ;ONLY X'FER FIRST 64
MOV FILECT,AL
RET
;
;SCANS CMDBUF COUNTING NAMES AND PUTTING DELIMITER (SPACE)
;AFTER LAST NAME
;
SCAN:
PUSH BX
MOV BX,OFFSET SNAMECT
MOV BYTE PTR [BX],0
MOV BX,OFFSET CMDBUF+1 ;FIND END OF CMD LINE..
MOV CL,BYTE PTR [BX] ;..AND PUT SPACE THERE.
MOV CH,0
MOV BX,OFFSET CMDBUF+2
ADD BX,CX
MOV BYTE PTR [BX],20H
MOV BX,OFFSET CMDBUF+1
MOV CH,BYTE PTR [BX]
INC CH
INC CH
SCANLP1:
INC BX
DEC CH
JZ DNSCAN
MOV AL,BYTE PTR [BX]
CMP AL,20H
JNZ SCANLP1
SCANLP2:
INC BX ;EAT EXTRA SPACES
DEC CH
JZ DNSCAN
MOV AL,BYTE PTR [BX]
CMP AL,20H
JZ SCANLP2
MOV BGNMS,BX ;SAVE START OF NAMES IN CMDBUF
INC CH
DEC BX
SCANLP3:
INC BX
DEC CH
JZ DNSCAN
MOV AL,BYTE PTR [BX]
CMP AL,20H
JNZ SCANLP3
MOV AL,SNAMECT ;COUNTS NAMES
INC AL
MOV SNAMECT,AL
SCANLP4:
INC BX ;EAT SPACES
DEC CH
JZ DNSCAN
MOV AL,BYTE PTR [BX]
CMP AL,20H
JZ SCANLP4
JMP SCANLP3
;
DNSCAN:
MOV BYTE PTR [BX],20H ;SPACE AFTER LAST CHAR
POP BX
RET
;
;PLACES NEXT NAME IN BUFFER SO 'CPMLINE' MAY PARSE IT
;
TRTOBUF:
MOV BX,BGNMS
MOV CH,0
MOV DX,OFFSET FCBBUF+2
TBLP:
MOV AL,BYTE PTR [BX]
CMP AL,20H
JZ TRBFEND
XCHG BX,DX
MOV BYTE PTR [BX],AL
XCHG BX,DX
INC BX
INC DX
INC CH ;COUNT CHARS IN NAME
JMP TBLP
;
TRBFEND:
INC BX
MOV AL,BYTE PTR [BX] ;EAT EXTRA SPACES
CMP AL,20H
JZ TRBFEND
MOV BGNMS,BX
MOV BX,OFFSET FCBBUF+1 ;PUT # CHARS BEFORE NAME
MOV BYTE PTR [BX],CH
RET
;
RCVSECT:
MOV AL,1
MOV ERRCT,AL
RCVRPT:
CALL CKABORT ;WANT TO STOP RECEIVING FILE?
MOV AL,QFLG
OR AL,AL
JZ RCVSQ
CALL ILPRT
DB CR,'Awaiting # ',0
PUSH BX ;SAVE IT
MOV BX,SECTNO ;GET SECTOR NUMBER
INC BX ;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 AL,BL ;ONLY LOW BYTE USED BY PROGRAM
POP BX ;RESTORE IT
RCVSQ: ;WAIT FOR SOH OR EOT
MOV CH,10 ;10 SECONDS
CALL RECV
JNC RCVSQ1
JMP RCVSTOT
RCVSQ1:
CMP AL,SOH
JNZ RCVSQ2
JMP RCVSOH
RCVSQ2:
OR AL,AL
JZ RCVSQ
CMP AL,EOT
STC
JNZ RCVSQ3
RET
RCVSQ3:
MOV CH,AL
MOV AL,QFLG
OR AL,AL
JZ RCVSERR
RCVSEH:
MOV AL,CH
CALL CRLF
CALL HEXO
CALL ILPRT
DB 'H received not SOH - ',0
RCVPRN:
CALL SHOWERR ;DISPLAY ERROR COUNT
RCVSERR:
MOV CH,1 ;WAIT FOR 1 SEC..
CALL RECV ;..WITH NO CHARS
JNC RCVSERR ;LOOP UNTIL SENDER DONE
CALL CKABORT ;WANT TO STOP RECEIVING NOW?
MOV AL,CKSUMFLG ;GET CHECKSUM FLAG
OR AL,AL ;CRC IN EFFECT?
MOV AL,NAK ;PUT NAK IN ACCUM
JNZ RCVSER2 ;NO, SEND THE NAK
MOV AL,FIRSTME ;GET FIRST TIME SWITCH
OR AL,AL ;HAS FIRST SOH BEEN RECEIVED?
MOV AL,NAK ;PUT NAK IN ACCUM
JZ RCVSER2 ;YES, THEN SEND NAK
MOV AL,CRC ;TELL SENDER CRC IS IN EFFECT
RCVSER2:
CALL SEND ;..THE NAK or CRC request
MOV AL,ERRCT ;ABORT IF..
INC AL ;..WE HAVE REACHED..
MOV ERRCT,AL ;..THE ERROR..
CMP AL,ERRLIM ;..LIMIT?
JNC RCVSER3
JMP RCVRPT ;..NO, TRY AGAIN
RCVSER3:
MOV AL,QFLG
OR AL,AL
JZ RCVSABT
RCVCKQ:
CALL CKQUIT
JNZ RCVSABT
JMP RCVSECT
RCVSABT:
CALL CLOSFIL ;CLOSE THE PARTIAL FILE
CALL NOASK ;DELETE PARTIAL FILE
CALL ILPRT
DB CR,LF,LF
DB '++ File receive cancelled and unfinished file deleted ++'
DB BELL,CR,LF,0
JMP DONETCA
;
RCVSTOT:
MOV AL,QFLG
OR AL,AL
RCVSPT: CALL ILPRT
DB CR,LF,'++ Timeout ',0
CALL SHOWERR
RCVSCRC:
CALL RCVSCRC2
JMP RCVSERR
;
;ROUTINE WILL SWITCH FROM CRC TO CHECKSUM IF ERCNT REACHES ERRCRC
;AND FIRSTME IS TRUE
;
RCVSCRC2:
MOV AL,ERRCT
CMP AL,ERRCRC
JNZ RCVSCRC3
MOV AL,FIRSTME
OR AL,AL
JZ RCVSCRC3
MOV AL,CKSUMFLG
OR AL,AL
JNZ RCVSCRC3
NOT AL
MOV CKSUMFLG,AL
MOV CKSUMDFLT,AL
CALL ILPRTQ
DB '++ Switching to Checksum mode ++',CR,LF
DB '++ Sender may not be CRC capable ++',CR,LF,BELL,0
RCVSCRC3:
RET
;
;Got SOH - get block #, block # complemented
;
RCVSOH:
XOR AL,AL ;ZERO ACCUM
MOV FIRSTME,AL ;INDICATE FIRST SOH RECV'D
MOV CH,1 ;TIMEOUT = 1 SEC
CALL RECV ;GET SECTOR
JNC RCVSOH1
JMP RCVSTOT ;GOT TIMEOUT
RCVSOH1:
MOV DH,AL
MOV CH,1
CALL RECV
JNC RCVSOH2
JMP RCVSTOT
RCVSOH2:
NOT AL
CMP AL,DH
JZ RCVDATA
MOV AL,QFLG
OR AL,AL
JNZ RCVBSE
JMP RCVSERR
RCVBSE:
CALL ILPRT
DB CR,LF,'++ Bad sector # in Header ',0
JMP RCVPRN
;
RCVDATA:
MOV AL,DH
MOV RCVSNO,AL
MOV AL,1
MOV DATAFLG,AL
MOV CL,0
CALL CLRCRC ;CLEAR CRC COUNTER
MOV BX,OFFSET 80H
RCVCHR:
MOV CH,1
CALL RECV
JNC RCVCHR1
JMP RCVSTOT
RCVCHR1:
MOV BYTE PTR [BX],AL
INC BL
JNZ RCVCHR
MOV AL,CKSUMFLG
OR AL,AL
JZ RCVCRC
MOV DH,CL ; 9.01.02 MJM 7/8/83
XOR AL,AL
MOV DATAFLG,AL
MOV CH,1
CALL RECV
JNC RCVCHR2
JMP RCVSTOT
RCVCHR2:
CMP AL,DH
JNZ RCVCERR
CHKSNUM:
MOV AL,RCVSNO
MOV CH,AL
MOV AX,SECTNO
CMP AL,CH
JZ RECVACK
INC AL
CMP AL,CH
JZ CHKSNUM1
JMP ABORT
CHKSNUM1:
RET
;
RCVCRC:
MOV DL,2 ;NUMBER OF CRC BYTES
RCVCRC2:
MOV CH,1
CALL RECV
JNC RCVCRC3
JMP RCVSTOT
RCVCRC3:
DEC DL
JNZ RCVCRC2
CALL CHKCRC
OR AL,AL
JZ CHKSNUM
MOV AL,QFLG
OR AL,AL
JNZ RCVCRER
JMP RCVSERR
RCVCRER:
CALL ILPRT
DB CR,LF,'++ CRC error ',0
JMP RCVPRN
;
RCVCERR:
MOV AL,QFLG
OR AL,AL
JNZ RCVCPR
JMP RCVSERR
RCVCPR:
CALL ILPRT
DB CR,LF,'++ Checksum error ',0
JMP RCVPRN
;
RECVACK:
CALL SENDACK
JMP RCVSECT
;
SENDACK:
MOV AL,ACK
CALL SEND
RET
;
SENDHDR:
MOV AL,QFLG
OR AL,AL
JZ SENDHNM
CALL ILPRT
DB CR,'Sending # ',0
PUSH BX
MOV BX,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 BX
SENDHNM:
MOV AL,SOH
CALL SEND
MOV AX,SECTNO
CALL SEND
MOV AX,SECTNO
NOT AL
CALL SEND
RET
;
SENDSEC:
MOV AL,1
MOV DATAFLG,AL
MOV CL,0
CALL CLRCRC
MOV BX,OFFSET 80H
SENDC:
MOV AL,BYTE PTR [BX]
CALL SEND
INC BL
JNZ SENDC
XOR AL,AL
MOV DATAFLG,AL
RET
;
SENDCKS:
MOV AL,CL
CALL SEND
RET
;
SENDCRC:
CALL FINCRC
MOV AL,DH
CALL SEND
MOV AL,DL
CALL SEND
XOR AL,AL
RET
;
;
;After a record is sent, a character is returned telling if it was re-
;ceived properly or not. An ACK allows the next record to be sent. A
;NAK sends an error message and the current record is again repeated.
;This occurs until the error limit has been reached. If the first NAK
;is missed, it waits up to 12 seconds before declaring a 2nd error.
;This insures there is no collision with the station attempting to send
;the NAK, since it waits only 10 seconds.
;
GETACK:
MOV CH,12 ;12 SECONDS
CALL RECVDG ;WAIT FOR ACK OR NAK
JNC GETACK1
JMP GETATOT ;NO CHARACTER, TIMED OUT
GETACK1:
CMP AL,ACK
JNZ NOTACK
RET ;IF ACK RETURN AND SEND NEXT RECORD
NOTACK:
;
;If the ACKNAK option is FALSE it will resend the sector when any char-
;acter other than ACK is received (including NAK).
;
MOV CH,AL
MOV AL,NAKONLY
OR AL,AL
JZ ALLOTH
CMP AL,NAK ;WAS IT AN AUTHENTIC 'NAK'?
JNZ GETACK ;IGNORE IF NEITHER 'ACK' NOR 'NAK'
;WILL EVENTUALLY TIME OUT
ALLOTH:
MOV AL,QFLG
OR AL,AL
JZ ACKERR
CALL ILPRT
DB CR,LF,'++ ',0
MOV AL,CH
CMP AL,NAK ;IS IT A 'NAK'?
JZ GETACK2 ;SHOW 'NAK' IN THAT CASE
CALL HEXO
MOV AL,'H'
CALL TIPE
JMP GETACK3
GETACK2:
CALL ILPRT
DB 'NAK',0
GETACK3:
CALL ILPRT ;PRINT THE ERROR MESSAGE
DB ' received not ACK - ',0
CALL SHOWERR ;SHOW THE ERROR NUMBER
ACKERR:
MOV AL,ERRCT
INC AL
MOV ERRCT,AL
DEC AL
CMP AL,ERRLIM
JNC ACKERR1
RET
ACKERR1:
MOV AL,QFLG
OR AL,AL
JZ CSABORT
GACKV:
CALL CKQUIT
STC
JNZ CSABORT
RET
CSABORT:
CALL ERXIT
DB CR,LF,'Can''t send sector -- Aborting',CR,LF,'$'
GETATOT:
MOV AL,QFLG
OR AL,AL
JZ ACKERR
CALL ILPRT
DB CR,LF,'++ Timeout on ACK - ',0
CALL SHOWERR ;DISPLAY ERROR COUNT
JMP ACKERR
;
CKABORT:
; MOV AL,QFLG ;SO CTRL X.. @DH
; OR AL,AL ;..WILL WORK.. @DH
; JNZ CKABGO ;..EVEN IF IN.. @DH
; RET ;..QUIET MODE. @DH
CKABGO:
CALL STAT
JNZ CKABGO1
RET
CKABGO1:
CALL KEYIN
CMP AL,CAN
JZ ABORT
RET
ABORT:
MOV CH,1
CALL RECV
JNC ABORT
MOV AL,CAN
CALL SEND
ABORTW:
MOV CH,1
CALL RECV
JNC ABORTW
MOV AL,' '
CALL SEND
MOV AL,'B' ;TURN MULTI-FILE MODE..
MOV BATCHFLG,AL ;..OFF SO ROUTINE ENDS.
MOV AL,OPTION ;RECEIVING A FILE NOW?
CMP AL,'R'
JNZ ABORTW1
JMP RCVSABT ;IF YES, CANCEL THE UNFINISHED FILE
ABORTW1:
CALL ILPRT
DB CR,LF,LF,'++ File send cancelled ++',CR,LF,BELL,0
JMP DONETCA
;
INCRSNO:
INC SECTNO ; INCREMENT SECTOR NUMBER
MOV AX,SECTNO ; NEED IT IN LOW BYTE, DON'T CARE ABOUT HIGH
RET
;
;----> RECV: Receive a character
;
;Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage
;characters on the line. For example, having just sent a sector, calling
;RECVDG will delete any line noise induced characters LONG before the
;ACK/NAK would be received.
;
RECVDG:
CALL CKMODM ;CATCH ANY GARBAGE CHARACTERS
RECV:
PUSH DX
MSEC:
PUSH BX
MOV BX,OFFSET 5000
CALL FIXCNT
PUSH BX
POP DX
POP BX
CALL CKABORT
MWTI:
CALL RCVREADY
JZ MCHAR
DEC DL
JNZ MWTI
DEC DH
JNZ MWTI
DEC CH
JNZ MSEC
POP DX
STC
RET
;
MCHAR:
CALL INMODDATP
POP DX
PUSH AX
CALL UPDCRC ;CALCULATE CRC
ADD CL,AL
MOV AL,RSEEFLG
OR AL,AL
JZ MONIN
MOV AL,VSEEFLG
OR AL,AL
JNZ NOMONIN
MOV AL,DATAFLG
OR AL,AL
JZ NOMONIN
MONIN:
POP AX
PUSH AX
CALL SHOW
NOMONIN:
POP AX
OR AL,AL
RET
;
SEND:
PUSH AX
MOV AL,SSEEFLG
OR AL,AL
JZ MONOUT
MOV AL,VSEEFLG
OR AL,AL
JNZ NOMONOT
MOV AL,DATAFLG
OR AL,AL
JZ NOMONOT
MONOUT:
POP AX
PUSH AX
CALL SHOW
NOMONOT:
POP AX
PUSH AX
CALL UPDCRC ;CALCULATE CRC
ADD CL,AL
SENDW:
CALL SENDREADY
JNZ SENDW
POP AX
CALL OUTMODDATP
RET
;
WAITNAK:
CALL ILPRTQ
DB 'Awaiting initial NAK',CR,LF,0
WAITNLP:
CALL CKABORT
MOV CH,1
CALL RECV
CMP AL,NAK
JNZ WAITNLP1
RET
WAITNLP1:
;CTRL X FIX @DH
CMP AL,CAN ;ABORT REQUEST? @DH
JNZ WAITNLP0 ;NO.. @DH
JMP ABORT ;YES ABORT @DH
WAITNLP0: ; @DH
CMP AL,CRC ;CRC REQUEST?
JZ WAITCRC ;YES, GO SET CRC FLAG
; CMP AL,CAN ; @DH
; JNZ WAITNLP2 ; @DH
; JMP ABORT ; @DH
WAITNLP2:
DEC DL
JNZ WAITNLP
JMP ABORT
;
WAITCRC:
CALL ILPRTQ
DB 'CRC request received',CR,LF,0
XOR AL,AL
MOV CKSUMFLG,AL
RET
;
;RETURNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN
;NO QUESTIONS ASKED, JUST QUIT
;
CKQUIT:
MOV AL,BATCHFLG
OR AL,AL
JNZ CKQTASK ;ASK FOR RETRY
INC AL ;RESET ZERO FLG
RET
;
CKQTASK:
MOV ERRCT,1
CALL ILPRT
DB CR,LF,'Multiple errors encountered.',CR,LF
DB 'Type Q to quit, R to retry: ',BELL,0
CALL KEYIN
CALL CRLF
CALL UCASE ;INSTEAD OF "ANI 5FH"
CMP AL,'R'
JZ CKQTASK1
CMP AL,'Q'
JNZ CKQUIT
OR AL,AL
CKQTASK1:
RET
;
;Get the error count and display on CRT
;
SHOWERR:
PUSH BX ;SAVE THE CURRENT ADDRESS
MOV BL,ERRCT ;GET THE CURRENT ERROR NUMBER
MOV BH,0 ;ONLY A 8-BIT NUMBER, NOW IN 'L' REG.
CALL DECOUT ;DISPLAY THE ERROR IN DECIMAL
POP BX ;RESTORE THE CURRENT ADDRESS
CALL ILPRT
DB ' ++',CR,LF,0 ;FINISH THE ERROR MESSAGE
RET
;
ERXIT:
POP DX
CALL PRTMSG
MOV AL,BELL
CALL TIPE
MOV AL,BATCHFLG
OR AL,AL
JZ ERXIT1
JMP DONETCA
ERXIT1:
MOV AL,'Q' ;RESET QFLG
MOV QFLG,AL
JMP ABORT ;ABORT OTHER COMPUTER
;
DONE:
MOV AL,BATCHFLG
OR AL,AL
JZ DONE1
JMP DONETC
DONE1:
MOV AL,QFLG
OR AL,AL
JZ NMSTRNS
MOV CH,12 ;ZERO OUT FTRNMSG
MOV BX,OFFSET FTRNMSG
ZEROLP:
MOV BYTE PTR [BX],' ' ; mjm 9.01.05 FIX BATCH NAME REPORT
INC BX
DEC CH
JNZ ZEROLP
MOV CH,12 ;PUT FILE NAME IN FTRNMSG
MOV BX,OFFSET FCB+1
MOV DX,OFFSET FTRNMSG
LOADMSG:
MOV AL,4 ;START OF FILE TYPE?
CMP AL,CH
JZ PERIOD ;PUT IN PERIOD IF SO
MOV AL,BYTE PTR [BX]
CMP AL,' ' ;DON'T PUT IN SPACE
JZ SKPSP
XCHG BX,DX
MOV BYTE PTR [BX],AL ;STORE IN FTRNMSG
XCHG BX,DX
INC DX
SKPSP:
INC BX
DEC CH
MOV AL,CH
OR AL,AL ;END OF FILE NAME?
JZ FTRNMSG0 ;DISPLAY FILE NAME
JMP LOADMSG ;LOOP FOR ANOTHER CHARACTER
;
PERIOD:
MOV AL,BYTE PTR [BX]
CMP AL,' ' ;IS FILE TYPE EMPTY?
JZ FTRNMSG0 ;GO IF SO
MOV AL,'.' ;ELSE PUT PERIOD IN MESSAGE
XCHG BX,DX
MOV BYTE PTR [BX],AL
XCHG BX,DX
INC DX
DEC CH
JMP LOADMSG
;
FTRNMSG0:
CALL ILPRT
DB CR,LF
FTRNMSG RB 12
DB 0
CALL ILPRT
DB ' Transferred',CR,LF,LF,0
NMSTRNS:
MOV AL,BYTE PTR .FCB ;SAVE DRIVE NO.
MOV DISKNO,AL
MOV BX,OFFSET FCB ;BLANK OUT FILE CONTROL BLOCKS
CALL INITFCBS
MOV AL,DISKNO ;PUT DRIVE NUMBER BACK
MOV BYTE PTR .FCB,AL
MOV BX,OFFSET RESTSN ;RESTORE SECTOR NUMBERS..
MOV DX,OFFSET SECTNOB ;..FOR NEW FILE TRANSFER.
MOV CH,OFFSET SECTNOE-OFFSET SECTNOB ;ROUTINE ALSO DONE IN MENU.
CALL MOVE
CALL CKMODM ;CATCH ANY GARBAGE CHARACTERS
MOV AL,SENDFLG ;GOES TO EITHER SEND OR..
OR AL,AL ;..RECEIVE FILE, DEPENDING..
JZ NMSTRNS1
JMP SENDFIL1 ;..UPON WHICH ROUTINE SET..
NMSTRNS1:
JMP RCVFIL1 ;..THE FLAG IN MULTI-FILE MODE.
;
DONETC:
CALL CKABORT ;SLIGHT DELAY FOR NEXT MESSAGE
CALL ILPRT
DB CR,LF,'All transfers completed',CR,LF,BELL,0
DONETCA:
MOV AL,TRUE
MOV FIRSTME,AL ;SET FIRST-TIME FLAG
MOV FSTFLG,AL ;RESET MULTIFILE TRANS
MOV NFILFLG,AL ;..USED IN TERMINAL ROUTINE
NOT AL
MOV SAVEFLG,AL ;STOP MEMORY SAVE IN TERM ROUTINE
MOV LISTMOR,AL ;STOP ANY BUFFERED OUTPUT TO PRINTER
MOV BX,OFFSET BOTTRAM ;RESET PRINTER BUFFER POINTERS
MOV HLSAVE1,BX
MOV HLSAVE2,BX
MOV AL,TERMFLG ;SEE IF RETURN TO..
OR AL,AL ;..TERMINAL MODE..
JNZ DONETCA1 ;..AFTER X'FER.
CALL ILPRT
DB CR,LF,'** Entering terminal mode **',CR,LF,LF,BELL,0
JMP TERM
DONETCA1:
JMP MENU
;
;Shows the time to transfer a file at various baud rates
;
SENDTIM:
CALL ILPRT ;PRINT
DB 'File open: ',0
MOV BX,RCNT ;GET RECORD COUNT.
CALL DECOUT ;PRINT DECIMAL NUMBER OF RECORDS
CALL ILPRT
DB ' (',0
CALL DHXOUT ;NOW PRINT SIZE IN HEX.
CALL ILPRT
DB ' Hex) Records',CR,LF
DB 'Send time: ',0
MOV AL,MSPEED ;GET THE SPEED INDICATOR
MOV DH,0
MOV DL,AL ;SET UP FOR TABLE ACCESS
MOV BX,OFFSET BTABLE ;POINT TO BAUD FACTOR TABLE
ADD BX,DX ;INDEX TO PROPER FACTOR
ADD BX,DX
MOV DL,BYTE PTR [BX];FACTOR IN DE
INC BX
MOV DH,BYTE PTR [BX]
MOV BX,RCNT ;GET # OF RECORDS
CALL DIVHLDE ;DIVIDE HL BY VALUE IN A (RECORDS/MIN)
PUSH BX
MOV BX,CX
CALL DECOUT ;PRINT THE MINUTES PORTION
CALL ILPRT
DB ' mins, ',0
MOV BX,OFFSET SECTBL ;POINT TO DIVISORS FOR SECONDS
MOV DX,0 ; CALCULATION
MOV AL,MSPEED ;GET INDEX FOR BAUD RATE
MOV DL,AL
ADD BX,DX ;INDEX INTO TABLE
MOV AL,BYTE PTR [BX] ;GET MULTIPLIER = (SEC/REC) x 16
POP BX ;GET REMAINDER
CALL MULHLA ;MULTIPLY THE 'HL' x 'A'
CALL SHFTHL ;DIVIDE BY 16
CALL SHFTHL
CALL SHFTHL
CALL SHFTHL
MOV BH,0
CALL DECOUT ;PRINT THE SECONDS PORTION
CALL ILPRT
DB ' secs at ',0
CALL BAUDPRT
CALL ILPRT
DB 'To cancel use ctrl-X',CR,LF,0
RET
;
; CORRECTED BY M.J. MELLINGER FOR 9.01.05 11/25/83
BTABLE DW 5,13,25,48,96,192,384,0 ;RECORDS/MIN FOR 110-9600 BAUD
SECTBL DB 192,74,38,20,11,5,3,0
;
;
;----> DIVHLDE: DIVIDES 'HL' BY VALUE IN 'DE',
; UPON EXIT: 'BC'=QUOTIENT,'L'=REMAINDER
;
DIVHLDE:
PUSH DX ;SAVE DIVISOR
; MOV AL,DL
; NOT AL ;NEGATE DIVISOR
; MOV DL,AL
; MOV AL,DH
; NOT AL
; MOV DH,AL
; INC DX ;DE IS NOW TWOS COMPLEMENTED
NEG DX
MOV CX,0 ;INITIATE QUOTIENT
DIVL1:
ADD BX,DX ;SUBTRACT DIVISOR FROM DIVIDEND
INC CX ;INCREASE QUOTIENT
JC DIVL1 ;LOOP UNTIL SIGN CHANGES
DEC CX ;ADJUST QUOTIENT
POP DX ;RETRIEVE DIVISOR
ADD BX,DX ;ADJUST REMAINDER
RET
;
;----> MULHLA: MULTIPLY THE VALUE IN 'HL' BY THE VALUE IN 'A'
; RETURN WITH ANSWER IN 'HL'
;
MULHLA:
XCHG BX,DX ;MULTIPLICAND TO DE
MOV BX,OFFSET 0 ;INITIALIZE PRODUCT
INC AL ;ADJUST MULTIPLIER
MULLP:
DEC AL
JNZ MULLP1
RET
MULLP1:
ADD BX,DX
JMPS MULLP
;
; SHIFT 'HL' REGISTER PAIR ONE BIT TO THE RIGHT
;
SHFTHL:
CLC ;CLEAR THE CARRY
RCR BX,1
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. *
;* *
;****************************************************************
;
;
CLRCRC: ;RESET CRC ACCUMULATOR FOR A NEW MESSAGE.
MOV CRCVAL,0
RET
;
UPDCRC: ;UPDATE CRC ACCUMULATOR USING BYTE IN (A).
PUSH AX
PUSH CX
PUSH BX
MOV CH,8
MOV CL,AL
MOV BX,CRCVAL
UPDLOOP:
ROL CL,1
; MOV AL,CL
; ROL AL,1
; MOV CL,AL
RCL BX,1
JNC SKIPIT
XOR BX,1021H
SKIPIT:
DEC CH ;AND XOR 05H FOR XOR 21H IN THE ADJACENT CODE
JNZ UPDLOOP
MOV CRCVAL,BX
POP BX
POP CX
POP AX
RET
;
FINCRC: ;FINISH CRC CALCULATION FOR OUTPUT MESSAGE
PUSH AX
XOR AL,AL
CALL UPDCRC
CALL UPDCRC
MOV DX,CRCVAL
POP AX
RET
;
CHKCRC: ;CHECK CRC BYTES OF RECEIVED MESSAGE
MOV AX,CRCVAL
OR AL,AH
JZ CHKCRCRT
MOV AL,0FFH
CHKCRCRT:
RET
;
CRCVAL DW 0
;
;
; FILES.A86
;
;Disk file routines for MODEM9.xx.
;
;
;Multi-file access subroutine. Allows processing of multiple files
;(i.e., *.ASM) from disk. This routine builds the proper name in the
;FCB each time it is called. This command would be used in such pro-
;grams such as modem transfer, tape save, etc. in which you want to
;process single or multiple files.
;
;The FCB will be set up with the next name, ready to do normal proces-
;sing (OPEN, READ, etc.) when routine is called.
;
;Carry is set if no more names can be found
;
MFNAME: ;INIT DMA ADDR, FCB
MOV CL,STDMA
MOV DX,OFFSET 80H
INT 224
MOV byte ptr .FCBEXT,0
TEST MFFLG1,0FFH
JNZ MFN01 ;IF FIRST TIME
MOV MFFLG1,1 ;TURN OFF 1ST TIME SW
MOV BX,OFFSET FCB ;SAVE THE REQUESTED NAME
MOV DX,OFFSET MFREQ
MOV CX,OFFSET 12
CALL MOVER
MOV AL,BYTE PTR .FCB
MOV MFCUR,AL ;SAVE DISK IN CURRENT FCB
MOV BX,OFFSET MFREQ ;SRCHF REQ NAME
MOV DX,OFFSET FCB
MOV CX,OFFSET 12
CALL MOVER
PUSH CX
PUSH DX
PUSH BX
MOV CL,SRCHF
MOV DX,OFFSET FCB
INT 224
POP BX
POP DX
POP CX
JMP MFN02
;
MFN01:
MOV BX,OFFSET MFCUR ;SRCHF CURR NAME
MOV DX,OFFSET FCB
MOV CX,OFFSET 12
CALL MOVER
MOV CL,SRCHF
MOV DX,OFFSET FCB
INT 224
MOV BX,OFFSET MFREQ ;SRCHN REQ NAME
MOV DX,OFFSET FCB
MOV CX,OFFSET 12
CALL MOVER
MOV CL,SRCHN
MOV DX,OFFSET FCB
INT 224
MFN02:
INC AL ;RETURN CARRY IF NOT FOUND
STC
JNZ MFFIX1
MOV MFFLG1,AL
RET
;
MFFIX1:
DEC AL ;MOVE NAME FOUND TO CURR
AND AL,3
ADD AL,AL
ADD AL,AL
ADD AL,AL
ADD AL,AL
ADD AL,AL
ADD AL,81H
MOV BL,AL
MOV BH,0
PUSH BX ;SAVE NAME POINTER
MOV DX,OFFSET MFCUR+1
MOV CX,OFFSET 11
CALL MOVER
POP BX ;MOVE NAME FOUND TO FCB
MOV DX,OFFSET FCB+1
MOV CX,OFFSET 11
CALL MOVER
XOR AL,AL ;SETUP FCB
MOV BYTE PTR .FCBEXT,AL
MOV BYTE PTR .FCBRNO,AL
RET
;
; Move subroutine
;
MOVER: MOV AL,BYTE PTR [BX]
XCHG BX,DX
MOV BYTE PTR [BX],AL
XCHG BX,DX
INC BX
INC DX
DEC CX
JNZ MOVER
RET
;
;Lists directory and gives free space remaining on the requested drive.
;
DIRLST:
MOV DX,OFFSET CMDBUF ;PUT COMMAND LINE IN FCB
MOV BX,OFFSET 5CH
CALL CPMLINE
MOV BX,OFFSET SRCHFCB
CALL INITFCBS
MOV AL,BYTE PTR .6CH ;GET DRIVE #
MOV SRCHFCB,AL
MOV AL,BYTE PTR .6DH
CMP AL,20H ;IF BLANK GET ALL NAMES
PUSH AX
JNZ DIRLST1
CALL QSTMARK
DIRLST1:
POP AX
JZ DIRLST2
CALL MOVENAME ;ELSE MOVE NAME INTO FCB
DIRLST2:
MOV DX,OFFSET 80H
MOV CL,STDMA
INT 224
MOV NAMEGD,0
MOV AL,NOOFCOL ;GET NUMBER OF COLUMNS
MOV NAMECT,AL ;STORE TO CALCULATE CRLF POSITION
MOV DX,OFFSET SRCHFCB
MOV CL,SRCHF ;DO FIRST SEARCH
INT 224
CMP AL,0FFH
JZ NOFILE
PUSH AX
DIRLP:
POP AX
CALL GETADD
ADD BX,15 ;OFFSET FOR RECORD COUNT
MOV AL,BYTE PTR [BX]
OR AL,AL
JZ NEXTSR ;NO LIST IF FILE IS ZERO LENGTH
ADD BX,-5 ;POINT TO $SYS ATTRIB BYTE
MOV AL,BYTE PTR [BX]
AND AL,80H
JNZ NEXTSR ;NO LIST IF $SYS FILE
ADD BX,-10 ;POINT TO BEGINNING OF NAME
INC BX ;POINT TO FIRST LETTER
MOV DX,OFFSET PRNTNAME
MOV CH,8
CALL MOVE
INC DX
MOV CH,3
CALL MOVE
CALL ILPRT
PRNTNAME:
DB ' ','.',' ',' ', 0 ;8 SPACES, PERIOD, 3 SPACES, 1 SPACE
MOV NAMEGD,0FFH
NEXTSR:
MOV DX,OFFSET SRCHFCB
MOV CL,SRCHN ;DO NEXT SEARCH
INT 224
CMP AL,0FFH
JZ DIRDONE
PUSH AX
TEST NAMEGD,0FFH
JZ DIRLP
DEC NAMECT
JNZ NEXTSR1
CALL NEWCT
JMPS NEXTSR2
NEXTSR1:
CALL FENCE
NEXTSR2:
MOV NAMEGD,0
JMP DIRLP
;
NOFILE:
CALL ILPRT
DB 'NO FILE',0
;
; Determines free space remaining
;
DIRDONE:
MOV AL,SRCHFCB
OR AL,AL
JZ DEFLT
DEC AL
MOV DL,AL
MOV CL,SELDSK
INT 224
DEFLT:
MOV CL,GETPARM ;CURRENT DISK PARAMETER BLOACK
INT 224
ADD BX,2
MOV AL,ES: BYTE PTR [BX] ;GET BLOCK SHIFT FACTOR
MOV BSHIFTF,AL
INC BX ;BUMP TO BLOCK MASK
MOV AL,ES: BYTE PTR [BX] ;GET IT
MOV BMASK,AL
ADD BX,2
MOV DX,ES: WORD PTR [BX] ;GET MAX BLOCK NUMBER
; MOV DL,ES: BYTE PTR [BX] ;GET MAX BLOCK NUMBER
; INC BX
; MOV DH,ES: BYTE PTR [BX]
; XCHG BX,DX
MOV BMAX,DX ;PUT IT AWAY
MOV CL,GETALC ;ADDRESS OF CP/M ALLOCATION VECTOR
INT 224
XCHG BX,DX ;GET ITS LENGTH
MOV BX,BMAX
INC BX
MOV CX,0 ;INITIALIZE BLOCK COUNT TO ZERO
GSPBYT:
PUSH DX ;SAVE ALLOCATION ADDRESS
XCHG BX,DX
MOV AL,ES: BYTE PTR [BX]
XCHG BX,DX
MOV DL,8 ;SET TO PROCESS 8 BLOCKS
GSPLUP:
RCL AL,1 ;TEST BIT
JC NOTFRE
INC CX
NOTFRE:
MOV DH,AL ;SAVE BITS
DEC BX
MOV AL,BL
OR AL,BH
JZ ENDALC ;QUIT IF OUT OF BLOCKS
MOV AL,DH ;RESTORE BITS
DEC DL ;COUNT DOWN 8 BITS
JNZ GSPLUP ;DO ANOTHER BIT
POP DX ;BUMP TO NEXT COUNT OF ALLOCATION VECTOR
INC DX
JMP GSPBYT ;PROCESS IT
;
ENDALC:
POP DX ;CLEAR ALLOCATION VECTOR FROM STACK
MOV BX,CX ; COPY TO BX
MOV AL,BSHIFTF ;GET BLOCK SHIFT FACTOR
SUB AL,3 ;CONVERT FROM RECORDS TO THOUSANDS
JZ PRTFREE ;SKIP SHIFTS IF 1K BLOCKS
FREKLP:
ADD BX,BX ;MULTIPLY BLOCKS BY 'K PER BLOCK'
DEC AL
JNZ FREKLP
PRTFREE:
PUSH BX
CALL ILPRT
DB CR,LF,'Drive ',0
MOV AL,SRCHFCB ;IF NO DRIVE, GET
OR AL,AL ;LOGGED IN DRIVE
JNZ PRNTHD
MOV CL,CURDSK
INT 224
INC AL
PRNTHD:
ADD AL,'A'-1
MOV DRNAME,AL
CALL ILPRT
DRNAME DB ' has ',0
POP BX ;GET NUMBER OF BYTES AVAILABLE
CALL DECOUT
CALL ILPRT
DB 'K bytes free',CR,LF,0
RET
;
; Subroutines
;
FENCE:
CALL ILPRT
DB '| ',0
RET
;
NEWCT:
CALL CRLF
MOV AL,NOOFCOL
MOV NAMECT,AL
RET
;
QSTMARK:
MOV AL,'?' ;IF BLANK IN FCB, PUT IN 11 ?'s
MOV CH,11
MOV BX,OFFSET SRCHFCB+1
QSTLP:
MOV BYTE PTR [BX],AL
INC BX
DEC CH
JNZ QSTLP
RET
;
MOVENAME:
MOV BX,OFFSET 6DH
MOV DX,OFFSET SRCHFCB+1
MOV CH,11
CALL MOVE ;MOVE IN MAIN PROGRAM
RET
;
GETADD:
AND AL,03H ;GET MOD4 FOR CP/M 1.4
ADD AL,AL ;ADD 32
ADD AL,AL
ADD AL,AL
ADD AL,AL
ADD AL,AL
MOV DL,AL
MOV DH,0
MOV BX,OFFSET 80H ;ADD DMA OFFSET
ADD BX,DX
RET
;
;IN CP/M V.2, IF FILE IS R/O OR SYS, IT IS CHANGED TO 'BAK'.
;
CKCPM2:
MOV CL,STDMA
MOV DX,OFFSET 80H
INT 224
MOV CL,SRCHF ;SEARCH FOR FILE
MOV DX,OFFSET FCB
INT 224
CMP AL,0FFH
JNZ CKCPM2A
RET
CKCPM2A:
ADD AL,AL
ADD AL,AL ;MULT A-REG BY..
ADD AL,AL
ADD AL,AL ;..32 TO FIND..
ADD AL,AL ;..NAME IN DMA.
MOV BX,OFFSET 80H
ADD AL,BL
MOV BL,AL ;HL POINTS TO DIR NAME
MOV DX,OFFSET 9
ADD BX,DX ;POINT TO R/O ATTRIB BYTE
MOV AL,BYTE PTR [BX]
AND AL,80H ;TEST MSB
JNZ MKCHG ;IF SET, MAKE CHANGE
INC BX ;CHECK SYSTEM ATTRIB BYTE
MOV AL,BYTE PTR [BX]
AND AL,80H
JNZ CKCPM2B ; IS $SYS OR $R/O
RET
CKCPM2B:
DEC BX
MKCHG:
MOV DX, -8
ADD BX,DX ;POINT HL TO FILENAME + 1
MOV DX,OFFSET FCB+1 ;MOVE DIR NAME TO FCB..
MOV CH,11 ;..WITHOUT CHANGING DRIVE.
CALL MOVE
MOV BX,OFFSET FCB+9 ;R/O ATTRIB
AND BYTE PTR [BX],07FH ; STRIP R/O ATTRIB
INC BX
AND BYTE PTR [BX],07FH ; STRIP SYS ATTRIB
MOV DX,OFFSET FCB
MOV CL,30 ;SET NEW ATTRIBS IN DIR
INT 224
;
;MAY BE CALLED BY CKBAKUP BELOW. ITS RETURN DONE HERE
;
PLANCHG:
MOV BX,OFFSET FCB ;CHANGE NAME TO TYPE "BAK"
MOV DX,OFFSET 6CH
MOV CH,9 ;MOVE DRIVE AND NAME (NOT TYPE)
CALL MOVE
MOV BX,OFFSET 75H ;START OF TYPE IN FCB2
MOV BYTE PTR [BX],'B'
INC BX
MOV BYTE PTR [BX],'A'
INC BX
MOV BYTE PTR [BX],'K'
MOV DX,OFFSET 6CH
MOV CL,ERASE ;ERASE ANY PREV BACKUPS
INT 224
MOV BX,OFFSET 6CH ;FCB2 DR FIELD SHOULD..
MOV BYTE PTR [BX],0 ;..0 FOR RENAME.
MOV DX,OFFSET FCB
MOV CL,23 ;RENAME
INT 224
RET
;
CKBAKUP:
MOV AL,BAKUPBYTE
OR AL,AL
JZ CKBAKUPR
MOV CL,SRCHF
MOV DX,OFFSET FCB
INT 224
INC AL
JZ CKBAKUPR
JMP PLANCHG ;IN "CKCPM2" - RET DONE THERE
CKBAKUPR:
RET
;
ERASFIL:
MOV BX,OFFSET FCB ;CHECK FOR WILD CARDS
MOV CH,11
ERASFIL1:
INC BX
MOV AL,BYTE PTR [BX]
CMP AL,'?' ;IS IT A WILD CARD?
JZ WILDERR ;GO IF SO
DEC CH
JNZ ERASFIL1
MOV AL,BATCHFLG ;DON'T ASK FOR ERASE..
OR AL,AL ;..IN MULTI-FILE MODE,..
JZ NOASK ;..JUST DO IT.
MOV DX,OFFSET FCB
MOV CL,SRCHF
INT 224
INC AL
JZ CKBAKUPR
CALL ILPRT
DB 'File exists -- Type ''Y'' to erase: ',BELL,0
CALL KEYIN
PUSH AX
CALL TIPE
POP AX
CALL UCASE
CMP AL,'Y'
JZ ERASEIT
JMP MENU
ERASEIT:
CALL CRLF
NOASK:
MOV DX,OFFSET FCB
MOV CL,ERASE
INT 224
RET
;
WILDERR:
POP BX ;RESTORE STACK
CALL ILPRT
DB '++ No ambiguous file names allowed ++',CR,LF,BELL,0
JMP MENU
;
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:
MOV DX,OFFSET FCB
MOV CL,MAKE
INT 224
INC AL
JZ MAKEFIL1
RET
MAKEFIL1:
CALL ERXIT
DB 'Error - Can''t make file',CR,LF
DB 'Directory is likely full',CR,LF,'$'
;
CNREC:
MOV CL,FILSIZ ;COMPUTE FILE SIZE FUNCTION IN CP/M 2.x
MOV DX,OFFSET FCB ;POINT TO FILE CONTROL BLOCK
INT 224
MOV BX,WORD PTR .FCB+33 ;GET RECORD COUNT
MOV RCNT,BX ;STORE IT
MOV BX, 0 ;ZERO HL
MOV WORD PTR .FCB+33,BX ;RESET RANDOM RECORD IN FCB
RET
;
OPENFIL:
XOR AL,AL
MOV BYTE PTR .FCBEXT,AL
MOV DX,OFFSET FCB
MOV CL,OPEN
INT 224
INC AL
JNZ OPENOK
CALL ERXIT
DB 'Can''t open file$'
OPENOK:
MOV AL,QFLG
OR AL,AL
JNZ OPENOK1
RET
OPENOK1:
CALL SENDTIM ;A LIB MACRO SHOWS TIME TO SEND
MOV BYTE PTR .FCBRNO,0 ; MJM - 9.01.05 FIX BATCH SEND
MOV BYTE PTR .FCBEXT,0 ; MJM - 9.01.05 FIX BATCH SEND
RET
;
CLOSFIL:
MOV DX,OFFSET FCB
MOV CL,CLOSE
INT 224
INC AL
JZ CLOSFIL1
RET
CLOSFIL1:
CALL ERXIT
DB 'Can''t close file$'
RDSECT:
DEC SECINBF
JS RDBLOCK
MOV BX,SECPTR
MOV DX,OFFSET 80H
CALL MOVE128
MOV SECPTR,BX
RET
;
RDBLOCK:
MOV AL,EOFLG
CMP AL,1
STC
JNZ RDBLOCK1
RET
RDBLOCK1:
MOV CL,0
MOV DX,OFFSET DBUF
RDSECLP:
PUSH CX
PUSH DX
MOV CL,STDMA
INT 224
MOV DX,OFFSET FCB
MOV CL,READ
INT 224
POP DX
POP CX
OR AL,AL
JZ RDSECOK
DEC AL
JZ REOF
CALL ERXIT
DB '++ File read error ++$'
RDSECOK:
MOV BX,OFFSET 80H
ADD BX,DX
XCHG BX,DX
INC CL
MOV AL,CL
CMP AL,DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS
JZ RDBFULL
JMP RDSECLP
;
REOF: MOV AL,1
MOV EOFLG,AL
MOV AL,CL
RDBFULL:
MOV SECINBF,AL
MOV BX,OFFSET DBUF
MOV SECPTR,BX
MOV DX,OFFSET 80H
MOV CL,STDMA
INT 224
JMP RDSECT
;
WRSECT:
MOV BX,SECPTR
XCHG BX,DX
MOV BX,OFFSET 80H
CALL MOVE128
XCHG BX,DX
MOV SECPTR,BX
MOV AL,SECINBF
INC AL
MOV SECINBF,AL
CMP AL,DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS
JZ WRBLOCK
RET
WRBLOCK:
MOV AL,SECINBF
OR AL,AL
JNZ WRBLOCK1
RET
WRBLOCK1:
MOV CL,AL
MOV DX,OFFSET DBUF
DKWRLP:
PUSH BX
PUSH DX
PUSH CX
MOV CL,STDMA
INT 224
MOV DX,OFFSET FCB
MOV CL,WRITE
INT 224
POP CX
POP DX
POP BX
OR AL,AL
JNZ WRERR
MOV BX,OFFSET 80H
ADD BX,DX
XCHG BX,DX
DEC CL
JNZ DKWRLP
XOR AL,AL
MOV SECINBF,AL
MOV BX,OFFSET DBUF
MOV SECPTR,BX
MOV DX,OFFSET 80H ;TO RESET.. @DH
MOV CL,STDMA ;..DMA ADDRESS.. @DH
INT 224 ;..BDOS ENTRY @DH
RET
;
WRERR: MOV CL,CAN
CALL SEND
CALL ERXIT
DB CR,LF,'Error writing file',CR,LF,'$'
;
;
; FINISH.A86
;
;Parameters and buffers for MODEM9.xx.
;
COMPLIST DB 6, 'S', 'R', 'T', 'E', 'H', 'L'
;
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'
LOCCHFLG DB 'L'
BATCHFLG DB 'B' ;SET TO 'B' BY MENU. DOES NOT ALLOW MULTIFILE
;XFER WHEN PROGRAM INITIALLY CALLED.
OPTBE EQU $
RESTROPT DB 'Q','R','S','V','T','L','B'
;MUST BE IN SAME ORDER AS TABLE ABOVE
;
;THE NEXT 12 BYTES EQUAL THE NUMBER OF BYTES BETWEEN SECTNOB AND SECTNOE
;
RESTSN:
DB 0,0,0,0,0
DW DBUF
DB 0,0,0,0,0
;
SECTNOB EQU $ ;START OF TABLE MARKER
RCVSNO DB 0 ;\
SECTNO DW 0 ; \
ERRCT DB 0 ; \
EOFLG DB 0 ; \
SECPTR DW DBUF ; 12 BYTES BETWEEN TABLE MARKERS
SECINBF DB 0 ; /
MAXEXT DB 0 ; /
RCNT DW 0 ; /
DATAFLG DB 0 ;/
SECTNOE EQU $ ;END OF TABLE MARKER
;
MODCTLB DB 07FH
SAVEFLG DB FALSE
LASTBYT1 DB 0
LASTBYT2 DB 0
EXACFLG DB 0
ECHOFLG DB FALSE
LOCFLG DB FALSE
CKSUMFLG DB TRUE
LISTFLG DB FALSE
LISTMOR DB FALSE
FSTFLG DB TRUE
FIRSTME DB TRUE ;FIRST SOH RECEIVED SWITCH (ZERO AFTER 1ST SOH)
MFFLG1 DB 0 ;1ST TIME SW FOR MFACESS
HLSAVE DW BOTTRAM
HLSAVE1 DW BOTTRAM
HLSAVE2 DW BOTTRAM
STRSAVE DW STRINGS
CMDBUF DB 80H,0
RB 80H
DISKNO RB 1
DISKSAV RB 1
SAVUSR RB 1
SAVEOUT RB 1
MECHDLY RB 1
SENDFLG RB 1
NBSAVE RW 1
BGNMS RW 1
FILECT RB 2
SNAMECT RB 1
FTYCNT RB 1
RB 100
FCB3 RB 33
FCB4 RB 33
FCBBUF RB 15
;Multi-file access work area
MFREQ RB 12 ;REQ NAME
MFCUR RB 12 ;CURR NAME
;Unitialized storage for DIRLST
SRCHFCB RB 33
NAMEGD RB 1
NAMECT RB 1
BMAX RW 1 ;HIGHEST BLOCK NUMBER ON DRIVE
BMASK RB 1 ;(RECORDS/BLOCK)-1
BSHIFTF RB 1 ;NUMBER OF SHIFTS TO MULTIPLY BY REC/BLOCK
;
STACK RW 200H
STACKTOP EQU Offset $
SAVESS DW 0
SAVESP DW 0
;
;DBUF RB DBUFSIZ*1024 ; @DH
;NAMEBUF RB 64*12 ; @DH
;
;BOTTRAMEQU (OFFSET $) + 0FFH AND 0FF00H ; @DH
; RB CAPTURE*1024 ; @DH
;XAST EQU (OFFSET $) + 0FFH AND 0FF00H ; @DH
;
DBUF EQU OFFSET $ ; @DH
RB DBUFSIZ*1024 ; @DH
NAMEBUF EQU OFFSET $ ; @DH
RB 64*12 ; @DH
;
BOTTRAM EQU OFFSET $ ; @DH
RB CAPTURE*1024 ; @DH
XAST EQU OFFSET $ ; @DH
DB 0 ;end byte for GENCMD @DH
;
END