home *** CD-ROM | disk | FTP | other *** search
- TITLE 'CP/M MODEM PROGRAM Version 7.65'
- ;
- ;THE FOLLOWING IS AN EXTENSIVE REVISION OF THE CP/M MODEM PROGRAM
- ;CREATED BY WARD CHRISTENSEN FOR THE CP/M USERS LIBRARY.
- ;IT ALSO INCORPORATES ROUTINES FOUND IN THE POTOMAC MICRO-MAGIC MODEM
- ;MANUAL WHICH MAY BE USED IF YOU HAVE A PMMI MODEM BOARD.
-
- ; ******* N O T I C E *********
- ;When using this modem program, you can avoid its shakey
- ;features (which show up primarily in batch mode) by always
- ;using the O or A option even if either modem is already in the
- ;originate or answer mode; and, by always declaring the speed
- ;option such as .300, .600, etc.
- *****************************
-
- ;05/29/82 Moved fix log to history file. MODEM7xx.HIS
- RLP
-
-
- MACLIB MODEM76 ;CONTAINS CMDLINE, INBUF, INLNCOMP, @7.61
- ;DIR, AND MFACCESS ROUTINES
- ;changed to MODEM.LIB BY Jim Mills
- ;to differentiate from other 'MACROS.LIB'
-
-
- TRUE EQU 0FFH
- FALSE EQU 0
-
- CPM2X EQU TRUE ;true if CP/M 2.X
- ;false if CP/M 1.4 OR CDOS
- DBUFSIZ EQU 16 ;BUFFER SIZE IN KBYTES
-
- ; PMMI EQUATES
-
- PORT EQU 07 ;PMMI BASE ADDRESS
-
- MODCTLP EQU 07 ;MODEM CONTROL PORT
- MODSNDB EQU 04 ;MODEM SEND BIT (XMIT BUFF EMPTY)
- MODSNDR EQU 04 ;MODEM SEND READY
- MODRCVB EQU 01 ;MODEM RECEIVE BIT (DAV)
- MODRCVR EQU 01 ;MODEM RECEIVE READY
- MODDATP EQU 05 ;MODEM DATA PORT
- BAUDRP EQU PORT+2 ;BAUD RATE PORT
- MODCTL2 EQU PORT+3 ;2ND MODEM CONTROL PORT
- ORIGMOD EQU 1DH ;ORIGINATE MODE
- ANSWMOD EQU 1EH ;ANSWER MODE
- BRKMSK EQU 0FBH ;MASK TO SET BREAK
- FRMER EQU 20H ;FRAMING ERROR MASK
- ORUNER EQU 10H ;OVERRUN ERROR MASK
- PARER EQU 08H ;PARITY ERROR MASK
- ODPARMSK EQU 0CFH ;MASK TO SET ODD PARITY
- EVPARMSK EQU 20H ;MASK TO SET EVEN PARITY
- NOPARMSK EQU 10H ;MASK TO RESET TO NO PARITY
- ERRCDMSK EQU 38H ;MASK FOR ALL BITS EXCEPT ERROR CODES
-
- WAITCTS EQU 255 ;number of seconds X 10 to wait for computer
- ;tone after pmmi auto-dial function, 255 MAX.
-
- CHGBAUD EQU 'P'-40H ;USED IN TERMINAL MODE TO CHANGE
- ;BAUD RATE 'ON THE FLY'
- ERRLIM EQU 10 ;NUMBER OF TIMES TO RETRY
- ;SEND/RECEIVE ERRORS BEFORE QUIT
- BRKCHR EQU '@'-40H ; ^@ = TRANSMIT "BREAK" WITH PMMI
- EXITCHR EQU 'E'-40H ; ^E = EXIT WITHOUT DISCONNECT
- DISCCHR EQU 'D'-40H ; ^D = DISCONNECT
- TRANCHR EQU 'T'-40H ; ^T = TRANSFER CHARACTER
- CAN EQU 'X'-40H ; ^X = CANCEL SEND/RECEIVE
- EOFCHAR EQU 'Z'-40H ; ^Z = END OF FILE
- SAVECHR EQU 'Y'-40H ; ^Y = SAVE CHARACTER
- XOFF EQU 'S'-40H ; ^S = XOFF CHARACTER
- XON EQU 'Q'-40H ; ^Q = XON CHARACTER
- EXTCHR EQU '^'-40H ; ^^ = SEND NXT CHR
- SOH EQU 1 ; START OF HEADER
- EOT EQU 4 ; END OF TEXT
- ACK EQU 6 ; ACKNOWLEDGE
- NAK EQU 15H ; NOT ACKNOWLEDGE
- CRC EQU 'C' ;USED TO RQST CRC INSTEAD OF CHCKSUM
- BDNMCH EQU 75H ; BAD NAME MATCH
- OKNMCH EQU ACK ; OKAY NAME MATCH
- LF EQU 10 ; LINEFEED
- CR EQU 13 ; CARRIAGE RETURN
- BELL EQU 7 ; BELL CHARACTER
- FRONTPAN EQU 0FFH ; IMSAI FRONT PANEL
-
- BOTTRAM SET LAST+100H AND 0FF00H
-
- ORG 100H
-
- JMP START
-
- ;THESE ROUTINES ARE AT THE BEGINNING OF THE PROGRAM SO
- ;THEY CAN BE PATCHED BY A MONITER WITHOUT RE-ASSEMBLING
- ;THE PROGRAM.
-
- PMMIBYTE: DB FALSE ;true=pmmi modem
- IMSAIBYTE: DB FALSE ;true=imsai front panel
- FASTCLK: DB FALSE ;4 MHz or greater
- BAKUPBYTE: DB TRUE ;true=make .BAK file
- XPRFLG: DB FALSE ;true=no menu, false=print menu
- PULSERATE: DB 125 ;125 FOR 20PPS, 250 FOR 10PPS dialing
- SAVCCP: DB false ;true=do not overwrite CCP
- CLDBOOT: DW 0F000H ;put your coldboot entry here. ;@7.63
- IN$MODCTLP: IN MODCTLP ! RET ;in modem control port
- OUT$MODDATP: OUT MODDATP ! RET ;out modem data port
- ANI$MODSNDB: ANI MODSNDB ! RET ;bit to test for send ready
- CPI$MODSNDR: CPI MODSNDR ! RET ;value of send bit when ready
- IN$MODDATP: IN MODDATP ! RET ;in modem data port
- ANI$MODRCVB: ANI MODRCVB ! RET ;bit to test for receive ready
- CPI$MODRCVR: CPI MODRCVR ! RET ;value of receive bit when ready
- JMP$INITMOD: JMP INITMOD ;to initialize port, if necessary
- IN$BAUDRP: IN BAUDRP ! RET ;in baudrate port
- OUT$BAUDRP: OUT BAUDRP ! RET ;out baudrate port
- OUT$MODCTL2: OUT MODCTL2 ! RET ;out modem control port #2
- OUT$MODCTLP: OUT MODCTLP ! STA UARTCTLB ! RET ;out modem control port
- ;and store control byte
-
- CRFLAG: DB 0 ;CONTINUOUS REDIAL FLAG
-
- ; PHONE NUMBER LIBRARY TABLE FOR DIALING FROM LIBRARY
- ; OF NUMBERS STORED IN THESE DB'S AT ASSEMBLY-TIME.
- ; EACH DB MUST BE 30 CHARACTERS LONG FOR PROPER OPERATION.
- ; A 'DB 0' INDICATES NO DIALING, PROGRAM WILL DISCONNECT
- ; AND RETURN TO COMMAND MODE. LAST DB MUST BE DB 0. UP TO
- ; 26 NUMBERS ARE ALLOWED.
-
- NUMBLIB:
- ; '----5---10---15---20---25---30'
- DB 'A=Amrad 703-734-1387' ;'A'
- DB 'B=Ben Bronson 312-955-4493' ;'B'
- DB 'C= ' ;'C'
- DB 'D=C.Cliff C.C. 312-234-9257' ;'D'
- DB 'E=Ron Fowler 313-729-1905R' ;'E'
- DB 'F= ' ;'F'
- DB 'G=Gasnet NASA 301-344-9156' ;'G'
- DB 'H=Dave Hardy 313-846-6127' ;'H'
- DB 'I=Wayne Hammerly 301-953-3753' ;'I'
- DB 'J=RBBS Pasadena 213-356-1034' ;'J'
- DB 'K=David Kozinn 216-334-4604' ;'K'
- DB 'L=Program Store 202-337-4694' ;'L'
- DB 'M=Kelly Smith 805-527-9321' ;'M'
- DB 'N= ' ;'N'
- DB 'O=SYSOP Sys 313-885-0506' ;'O'
- DB 'P=CBBS Pasadena 213-799-1632' ;'P'
- DB 'Q=R.Plouffe 703-524-2549' ;'Q'
- DB 'R=Bruce Ratoff 201-272-1874' ;'R'
- DB 'S=K.Peterson 313-759-6569R' ;'S'
- DB 'T=Tech. CBBS 313-846-6127' ;'T'
- DB 'U=PMMI 703-379-0303' ;'U'
- DB 'V= ' ;'V'
- DB 'W= ' ;'W'
- DB 'X= ' ;'X'
- DB 'Y= ' ;'Y'
- DB 'Z= ' ;'Z'
- DB 0 ; end
-
- START: LXI H,0
- DAD SP ;GET CP/M'S STACK
- SHLD STACK ;SAVE IT
- LXI SP,STACK ;START LOCAL STACK
-
- CALL START1
-
- DB CR,LF,'MODEM 7.65 as of 05/29/82',cr,lf
- DB 'Originally Written by Ward Christensen',cr,lf,'$'
-
-
- START1: POP D ;GET ADDRESS OF ABOVE MESSAGE
- MVI C,PRINT ; 9
- CALL BDOS
-
- CALL INITADR ;INITIALIZE ADDRESSES
- MVI A,TRUE ; 0FFH
- STA NFILFLG
- CMA ; 0
- STA SAVEFLG
- OUT FRONTPAN ; IMSAI
-
- CALL PROCOPT ;PROCESS CONTROL OPTIONS
- LDA UARTFLG ; @7.61
- ORA A ; @7.5
- MVI A,ANSWMOD ; @7.5
- STA UARTCTLB ; @7.5
- JNZ START2 ; @7.5
- MVI A,ORIGMOD ; @7.5
- STA UARTCTLB ; @7.5
- START2: LDA OPTION ;GET MAIN OPTION
- CPI 'X' ;EXPERT FLAG?
- JNZ RESTART ;NO
- MVI A,TRUE ;YES
- STA XPRFLG ;MAKE EXPERT
- JMP MENU
-
- RESTART:
- LDA OPTION ;GET MAIN OPTION
- MOV B,A ;SAVE IT
- LDA PMMIBYTE ;PMMI?
- ORA A ;SET FLAGS
- MOV A,B ;GET OPTION BACK
- JZ S1 ;NOT PMMI
- CPI 'C' ;CALL (DIAL) FUNCTION?
- JZ DIALPL ;YES, GO TO IT
-
- S1: CPI ' ' ;NO OPTION SPEC'D?
- JZ MENU ;TRUE, GO MENU
- CPI 'M' ;MENU ASKED FOR?
- JZ MENU2 ;YES, GO MENU
- CALL JMP$INITMOD
- CALL MOVEFCB
- MVI A,FALSE
- STA NFILFLG
-
- CALL IN$MODDATP ;GOBBLE UP GARBAGE..
- CALL IN$MODDATP ;..CHARACTERS ON LINE
-
- LDA OPTION ;PROCESS MAIN OPTION
- CPI 'E' ;ECHO MODE?
- JZ TRMECHO ;YES
- CPI 'T' ;TERMINAL MODE?
- JZ DSKSAVE ;YES
- CPI 'S' ;SEND A FILE?
- JZ SENDFIL ;YES
- CPI 'R' ;RECEIVE A FILE?
- JZ RCVFIL ;YES
- CPI 'D' ;DISCONNECT?
- JZ DISCON1 ;YES, DISCONNECT & GO MENU
- JMP MENU ;NO OPTION SPEC'D, GO MENU
-
- ;REVISED TERMINAL ROUTINE ALLOWING MEMORY SAVE
-
- DSKSAVE:
- LDA NFILFLG ;NEW FILE FLAG
- CPI TRUE ;OFFH? (TRUE=NORMAL TERMINAL MODE)
- JZ TERM ;YES
- LDA FCB+1 ;FIRST CHAR OF FILENAME
- CPI ' ' ;FILE SPEC'D
- JNZ GOODNM ;YES, GOOD NAME
- MVI A,TRUE ;0FFH
- STA NFILFLG ;
- OUT FRONTPAN ;0FFH PORT FOR IMSAI FRONT PANEL
- CMA ; 0
- STA SAVEFLG ;
- JMP TERM ;
-
- GOODNM: CALL ERASFIL
- CALL MOVE2
- LXI D,FCB3
- MVI C,MAKE
- CALL BDOS
- LXI D,FCB3
- MVI C,OPEN
- CALL BDOS
- LXI H,BOTTRAM
- SHLD HLSAVE
- MVI A,FALSE
- STA NFILFLG
-
- TERM:
- LDA UARTFLG ; @7.61
- sta origsav ; @MODEM75.FIX
- ORA A ; @7.5
- MVI A,ANSWMOD ; @7.5
- STA UARTCTLB ; @7.5
- JNZ TERM2 ; @7.5
- MVI A,ORIGMOD ; @7.5
- STA UARTCTLB ; @7.5
- TERM2: CALL STAT ;KEYPRESS?
- JZ TERML ;NO, CHECK LINE
- CALL KEYIN ;GET CHAR FROM KBD
- MOV B,A ;SAVE
- LDA EXACFL
- ORA A ;EXACT?
- MVI A,0
- STA EXACFL ;CLR FOR NEXT TIME
- MOV A,B ;RESTORE
- JNZ NOTOG
- CPI EXITCHR ;^E?
- JZ MENU ;YES, RETURN TO MENU
- CPI DISCCHR ;^D?
- JZ DISCON1 ;YES, DISCONNECT & RETURN TO MENU
- CPI EXTCHR ;^^?
- JZ EXTFLG ;YES, SET FLAG FOR NXT CHAR
-
- CPI TRANCHR ;TEST FOR TRANSFER REQUEST (^T)
- CZ TRANSFER ;SEND-A-FILE (BLIND SEND)
- JZ TERM ;LOOP
-
- MOV B,A
- LDA PMMIBYTE
- ORA A
- MOV A,B
- JZ S2
- CPI BRKCHR ;BREAK?
- JZ BREAK
- CPI CHGBAUD
- PUSH PSW
- PUSH H
- CZ NEWBAUD
- POP H
- POP PSW
- JZ TERML
-
- S2: CPI SAVECHR
- JNZ NOTOG
- LDA NFILFLG ;DO NOT ALLOW SAVE IF..
- CPI TRUE ;..THIS FLAG IS SET.
- JZ TERML
- LDA SAVEFLG
- CMA
- STA SAVEFLG
- JMP TERML
-
- EXTFLG: MVI A,TRUE
- STA EXACFL
- JMP TERML
-
- NOTOG: CALL OUT$MODDATP
-
- TERML: CALL IN$MODCTLP
- CALL ANI$MODRCVB
- CALL CPI$MODRCVR
- JNZ TERM
- CALL IN$MODDATP
- ANI 7FH ;STRIP PARITY
- JZ TERM
- CALL TYPE
- PUSH PSW
- LDA SAVEFLG
- CPI FALSE
- JZ NOSAVE
- POP PSW
- MOV M,A
- INX H
- SHLD HLSAVE ;MENU COMMAND DESTROYS HL-REG..
- ;..GET HL WHEN ENTERING VIA 'RET' CMD.
- MOV B,A
- LDA IMSAIBYTE
- ORA A
- MOV A,B
- JZ COLON
- CMA ;FRONT PANEL SHOWS CHARS WHEN..
- OUT FRONTPAN ;..MEMORY SAVE IS ACTIVE.
- JMP NOCOLON
- COLON: CPI LF ;IF NO FRONT PANEL, THEN..
- JNZ NOCOLON ;..TYPE ":" AFTER EACH LINE FEED..
- MVI A,':' ;..WHEN MEMORY SAVE ACTIVE.
- CALL TYPE
- NOCOLON:
- LDA SAVCCP
- ORA A
- JZ SUB1
- LDA 7
- SBI 8 ;..PAGE BELOW CCP ..
- JMP SUB1A
- SUB1: LDA 7
- SUB1A: DCR A ;..OR BDOS HAS BEEN..
- CMP H ;..REACHED AND DISKSAVE IS NEEDED.
- CZ INTDSKSV
-
- JMP TERM
- NOSAVE: POP PSW
- JMP TERM
-
- SAVEFLG: DB FALSE
- LASTBYT1: DB 0
- LASTBYT2: DB 0
-
- INTDSKSV:
- MVI A,XOFF ;SEND A CTRL-S TO STOP..
- CALL OUT$MODDATP ;..REMOTE COMPUTER OUTPUT.
-
- MVI D,0 ;D IS THE BUFFER COUNT
- CALL INMODEM ;GET LAST BYTES SENT..
- STA LASTBYT1 ;..AFTER CTRL-S.
- CALL INMODEM ;ADD MORE CALLS TO INMODEM..
- STA LASTBYT2 ;..AND STA LASTBYT# IF YOU ARE..
- ;..LOSING BYTES WHEN MEMORY IS FULL.
- PUSH D
- CALL NUMREC1
- CALL WRTDSK ;WRITE THE RECORDS
- POP D
-
- LXI H,BOTTRAM
- INR D
- DCR D ;TEST BUFFER COUNT FOR ZERO
- JZ CTRLQ
- LDA LASTBYT1 ;GET THE LAST BYTES THAT WERE..
- MOV M,A ;..SAVED AND PUT THEM IN..
- INX H ;..BOTTRAM.
- CALL TYPE
- DCR D
- JZ CTRLQ
- LDA LASTBYT2
- MOV M,A
- INX H
- CALL TYPE
-
- CTRLQ: MVI A,XON ;SEND START CHARACTER..
- CALL OUT$MODDATP ;..TO REMOTE COMPUTER.
-
- RET
-
- BREAK: PUSH D ;SAVE IT
- LXI D,0 ;ZERO IT
- LDA MODCTLB ;GET THE LAST MODEM CONTROL BYTE
- ANI 0FBH ;SET THE TRANSMIT BREAK BIT LOW - ACTIVE LOW
- CALL OUT$MODCTL2 ;SEND IT TO THE MODEM
- LDA FASTCLK ;GET FAST CLOCK FLAG
- ORA A ;SET FLAGS
- LXI B,450 ;BREAK DELAY COUNTER FOR SLOW CLOCK
- JZ BRK1 ;JUMP IF NOT FAST CLOCK
- LXI B,900 ;BREAK DELAY COUNTER FOR FAST CLOCK
- BRK1: CALL TIMERL
- JZ BRK2 ;IF TIME IS UP RESET BREAK
- CPI 0 ;CHECK FOR NULLS
- JZ BRK1 ;DON'T PROCESS THEM
- ANI 7FH ;STRIP PARITY
- CALL TYPE
- PUSH PSW
- LDA SAVEFLG
- CPI FALSE
- JZ NOSAVEB
- POP PSW
- MOV M,A
- INX H
- SHLD HLSAVE ;MENU COMMAND DESTROYS HL-REG..
- ;..GET HL WHEN ENTERING VIA 'RET' CMD.
- PUSH D
- MOV D,A
- LDA IMSAIBYTE
- ORA A
- MOV A,D
- POP D
- JZ COLONB
- CMA ;FRONT PANEL SHOWS CHARS WHEN..
- OUT FRONTPAN ;..MEMORY SAVE IS ACTIVE.
- JMP BRK1
- COLONB: CPI LF ;IF NO FRONT PANEL, THEN..
- JNZ BRK1 ;..TYPE ":" AFTER EACH LINE FEED..
- MVI A,':' ;..WHEN MEMORY SAVE ACTIVE.
- CALL TYPE
- JMP BRK1 ;@
- NOSAVEB: POP PSW ;RESTORE IT
- JMP BRK1
-
- BRK2: LDA MODCTLB ;GET MODEM CONTROL BYTE
- CALL OUT$MODCTL2
- POP D
- LHLD HLSAVE ;LAST ADDRESS WRITTEN IF DATA BEING SAVED
- LDA SAVCCP
- ORA A
- JZ SUB2
- LDA 7 ;CHECK TO SEE IF..
- SBI 8 ;..PAGE BELOW CCP ..
- JMP SUB2A
- SUB2: LDA 7
- SUB2A: DCR A ;..OR BDOS HAS BEEN ..
- CMP H ;..REACHED AND DISKSAVE IS NEEDED.
- JNZ TERM ;NO PROBLEM - GO BACK TO NORMAL ROUTINE
- CALL ILPRT
- DB CR,LF,'Memory save buffer full',CR,LF,BELL,0
- JMP TERM
-
-
- ;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:
- LDA FASTCLK
- ORA A
- LXI B,1250
- JZ TIMERL
- LXI B,2500
- TIMERL: CALL IN$MODCTLP
- CALL ANI$MODRCVB
- CALL CPI$MODRCVR
- JZ GETBYTE
- DCX B
- MOV A,B
- ORA C
- JNZ TIMERL
- RET
- GETBYTE:
- CALL IN$MODDATP
- INR D
- RET
-
- NUMRECS:
- MVI M,EOFCHAR
- INX H
- LXI D,127
- DAD D
- NUMREC1:
- LXI D,-(BOTTRAM)
- DAD D
-
- MOV A,L ;DIVIDE HL BY 128..
- ORA A
- RAL ;..TO GET THE..
- MOV L,H ;..NUMBER OF SECTORS
- MVI H,0
- PUSH PSW
- DAD H
- POP PSW
- MVI A,0
- ADC L
- MOV L,A ;RETURNS WITH NUMBER OF..
- RET ;..128 BYTE RECORDS IN HL.
-
- WRTDSK: LXI D,BOTTRAM
- NEXTWRT:
- MVI C,STDMA
- CALL BDOSRT
- PUSH D
- LXI D,FCB3
- MVI C,WRITE
- CALL BDOSRT
- POP D
- XCHG
- PUSH D
- LXI D,128
- DAD D
- POP D
- XCHG
- DCX H
- MOV A,H
- ORA L
- JNZ NEXTWRT
- RET
-
- CLOSE3: LXI D,FCB3
- MVI C,CLOSE
- CALL BDOS
- RET
-
- BDOSRT: PUSH B ! PUSH D ! PUSH H ! PUSH PSW
- CALL BDOS
- POP PSW ! POP H ! POP D ! POP B
- RET
-
- MOVE2: LXI H,FCB3
- CALL INITFCBS
- LXI H,FCB
- LXI D,FCB3
- MVI B,12
- CALL MOVE
- RET
-
- ;FILE TRANSFER ROUTINE - CALLED WITH
- ;CONTROL-T FROM TERMINAL ROUTINE.
- ;TRANSFER MAY BE CANCELLED WHILE SENDING BY USING CONTROL-X.
-
- TRANSFER:
- PUSH H ! PUSH D ! PUSH B ! PUSH PSW
- LXI H,FCB4
- CALL INITFCBS ;INITIALIZES FCBS POINTED..
- LXI H,FCB+16 ;..TO BY HL REG.
- CALL INITFCBS
- GET: CALL GETNAME
- LDA CMDBUF+2 ;WAS FILE ENTERED
- CPI 20H
- JZ TRANSL2
- CALL MOVE4
- CALL OPEN4
- CPI 0FFH ;RETURN WITH 0FFH MEANS
- JNZ CONTIN ;FILE DOES NOT EXIST
- TRANSL1: CALL ILPRT
- DB CR,LF,'++File does not exist++',CR,LF,0
- TRANSL2: CALL ILPRT
- DB 'Type "R" to return to modem',CR,LF
- DB 'Type "A" to re-enter name: ',BELL,0
- CALL KEYIN
- CALL UCASE
- CALL TYPE ;ECHO RESPONSE
- CALL CRLF
- CPI 'A'
- JZ GET
- CPI 'R'
- JZ RETURN
- JMP TRANSL2
-
- CONTIN: LXI D,80H
- MVI C,STDMA
- CALL BDOS
- READMR: CALL READ80
- CPI 1 ;END OF FILE
- JZ RETURNS
- CPI 2 ;BAD READ
- JZ RETURNU
- CALL SEND80C
- CPI EOFCHAR ;END OF FILE - OMIT IF OBJECT..
- JZ RETURNS ;..CODE IS TO BE SENT.
- CPI CAN ;CANCELLATION?
- JZ TRANCAN
- JMP READMR
- RETURNS:
- CALL ILPRT
- DB CR,LF,'++File transfer completed++',CR,LF,BELL,0
- JMP RETURN
- RETURNU:
- CALL ILPRT
- DB CR,LF,'++File transfer unsuccessful++',CR,LF,BELL,0
- JMP RETURN
- TRANCAN:
- CALL ILPRT
- DB CR,LF,CR,LF,'++ Transfer cancelled ++',CR,LF,BELL,0
- RETURN: POP PSW ! POP B ! POP D ! POP H
- RET
-
- INITFCBS: ;ENTRY AT +2 WILL LEAVE..
- MVI M,0 ;..DRIVE NO. INTACT.
- INX H ;WILL INITIALIZE AN FCB..
- MVI B,11 ;..POINTED TO BY HL-REG. FILLS 1ST POS
- LOOP10: MVI M,' ' ;..WITH 0, NEXT 11 WITH..
- INX H ;..WITH BLANKS, AND LAST..
- DCR B ;..21 WITH NULLS.
- JNZ LOOP10
- MVI B,21
- LOOP11: MVI M,0
- INX H
- DCR B
- JNZ LOOP11
- RET
-
- GETNAME: CALL ILPRT
- DB CR,LF,'Enter file name to be transferred - C/R TO QUIT: ',0
- LXI D,CMDBUF
- CALL INBUFF
- CALL CRLF
- RET
-
- MOVE4: LXI D,CMDBUF
- LXI H,FCB4
- CALL CPMLINE
- RET
-
- OPEN4: LXI D,FCB4
- MVI C,OPEN
- CALL BDOS
- RET
-
- READ80: LXI D,FCB4
- MVI C,READ
- CALL BDOS
- RET
-
- SEND80C:
- MVI B,80H
- LXI H,80H
- SENDCH1:
- MOV A,M
- CALL MODOUT
- CPI EOFCHAR
- RZ
- CALL STAT ;TEST TO SEE IF
- ORA A ;CANCELLATION REQUESTED
- JZ SKIP12
- CALL KEYIN
- CPI CAN
- RZ
- SKIP12: INX H
- DCR B
- JNZ SENDCH1
- RET
-
- MODOUT: PUSH PSW
- MODOUTL:
- CALL IN$MODCTLP
- CALL ANI$MODSNDB
- CALL CPI$MODSNDR
- JNZ MODOUTL
- POP PSW
- CALL OUT$MODDATP
- CALL TYPE
- RET
-
- FCB4: DS 33
-
- ;TERMINAL ECHO MODE
-
- TRMECHO:
- CALL IN$MODCTLP
- CALL ANI$MODRCVB
- CALL CPI$MODRCVR
- JZ LINECHR
- CALL STAT
- JZ TRMECHO
- CALL KEYIN
- CPI EXITCHR
- JZ MENU
-
- MOV B,A
- LDA PMMIBYTE
- ORA A
- MOV A,B
- JZ S3
- CPI CHGBAUD ;SAME ROUTINE AS IN TERMINAL MODE
- PUSH PSW
- CZ NEWBAUD
- POP PSW
- CPI CHGBAUD
-
- JZ TRMECHO
- S3: CALL OUT$MODDATP
- CALL TYPE
- JMP TRMECHO
-
- LINECHR:
- CALL IN$MODDATP
- CALL OUT$MODDATP
- CALL TYPE
- JMP TRMECHO
-
-
- ; SEND A CP/M FILE
-
- SENDFIL:
- CALL PARITY ;SET PARITY IF REQUESTED
- LDA BATCHFLG ;CHECK IF MULTIPLE FILE..
- ORA A ;..MODE IS SET.
- JNZ SENDC1
- MVI A,TRUE ;INDICATE BATCH SEND
- STA SENDFLG
- LDA FSTFLG ;IF FIRST TIME THRU..
- ORA A ;..SCAN THE COMMAND LINE..
- CNZ TNMBUF ;..FOR MULTIPLE NAMES.
- CALL SENDFN ;SENDS FILE NAME TO RECEIVER
- JNC SENDC2 ;CARRY SET MEANS NO MORE FILES.
- MVI A,'B' ;STOP BATCH..
- STA BATCHFLG ;..MODE OPTION.
- MVI A,EOT ;FINAL XFER END
- CALL SEND
- JMP DONE
- SENDC1: LDA FCB+1
- CPI ' '
- JZ BLKFILE
- SENDC2: CALL CNREC ;GET NUMBER OF RECORDS
- CALL OPENFIL
- MVI E,80
- CALL WAITNAK
- SENDLP: CALL RDSECT
- JC SENDEOF
- CALL INCRSNO
- XRA A
- STA ERRCT
- SENDRPT:
- CALL SENDHDR
- CALL SENDSEC
- LDA CRCFLG
- ORA A
- CZ SENDCRC
- CNZ SENDCKS
- CALL GETACK
- JC SENDRPT
- JMP SENDLP
-
- SENDEOF:
- MVI A,EOT
- CALL SEND
- CALL GETACK
- JC SENDEOF
- JMP DONE
-
- ; RECEIVE A FILE
-
- RCVFIL: xra a ;@7.41 - default to CRC mode
- sta CRCFLG ;@7.41
- RCVFIL1: ;@FIX7.61
- CALL PARITY ;SET PARITY IF REQUESTED
- LDA BATCHFLG ;CHECK IF MULT..
- ORA A ;..FILE MODE.
- JNZ RCVC1
- MVI A,FALSE ;FLAG WHERE TO RETURN..
- STA SENDFLG ;..FOR NEXT FILE TRANS.
- CALL GETFN ;GET THE FILE NAME.
- JNC RCVC2 ;CARRY SET MEANS NO MORE FILES.
- MVI A,'B' ;STOP BATCH..
- STA BATCHFLG ;..MODE OPTION.
- JMP DONE
- RCVC1: LDA FCB+1 ;MAKE SURE FILE IS NAMED
- CPI ' '
- JZ BLKFILE
- JMP RCVC3
- RCVC2: CALL CKCPM2
- CALL CKBAKUP
- RCVC3: CALL ERASFIL
- CALL MAKEFIL
- lda batchflg;@75.FIX.................
- ora a ;DON'T PRINT MSSG IF..
- jnz rcvc4 ;..IN MULTI AND QUIET.
- lda qflg
- ora a
- jz rcvfst
- rcvc4: CALL ILPRT ;@75.FIX.................
- DB 'File open, ready to receive',CR,LF,0
- RCVFST: LDA CRCFLG
- ORA A
- MVI A,NAK
- JNZ RCVFIL2
- MVI A,CRC
- ;
- RCVFIL2:
- CALL SEND
- lda CRCFLG ;@7.41...............................
- ora a
- jnz RCVNAKM ;if in CRC mode
- call ILPRT ;then say so
- DB 'CRC in effect',cr,lf,0
- jmp RCVLP
- RCVNAKM:
- call ILPRT ;else say checksum mode
- DB 'Checksum in effect',cr,lf,0
- ;@7.41...............................
- RCVLP: CALL RCVSECT
- JC RCVEOT
- CALL WRSECT
- CALL INCRSNO
- CALL SENDACK
- JMP RCVLP
-
- RCVEOT: CALL WRBLOCK
- CALL SENDACK
- CALL CLOSFIL
- JMP DONE
-
- ;SUBROUTINES
-
- SENDFN: LDA QFLG
- ORA A
- JZ SWNAK
- CALL ILPRT
- DB 'Awaiting name NAK',CR,LF,0
- SWNAK: MVI E,80
- CALL WAITNLP
- MVI A,ACK ;GOT NAK, SEND ACK
- CALL SEND
- LXI H,FILECT
- DCR M
- JM NOMRNM
- LHLD NBSAVE ;GET FILE NAME..
- LXI D,FCB ;..IN FCB
- MVI B,12
- CALL MOVE
- SHLD NBSAVE
- CALL SENDNM ;SEND IT
- ORA A ;CLEAR CARRY
- RET
- NOMRNM: MVI A,EOT
- CALL SEND
- STC
- RET
-
- SENDNM: PUSH H
- SENDNM1:
- MVI D,11 ;COUNT CHARS IN NAME
- MVI C,0 ;INIT CHECKSUM
- LXI H,FCB+1 ;ADDRESS NAME
- NAMLPS: MOV A,M ;SEND NAME
- ANI 7FH ;STRIP HIGH ORDER BIT SO CP/M 2..
- CALL SEND ;..WON'T SEND R/O FILE DESIGNATION.
- LDA QFLG ;SHOW NAME IF..
- ORA A ;..QFLG NOT SET.
- MOV A,M
- CNZ TYPE
- ACKLP: PUSH B ;SAVE CKSUM
- MVI B,1 ;WAIT FOR RECEIVER..
- CALL RECV ;..TO ACKNOWLEDGE..
- POP B ;..GETTING LETTER.
- JC SCKSER
- CPI ACK
- JNZ ACKLP
- INX H ;NEXT CHAR
- DCR D
- JNZ NAMLPS
- MVI A,EOFCHAR ;TELL RECEIVER END OF NAME
- CALL SEND
- LDA QFLG
- ORA A
- CNZ CRLF
- MOV D,C ;SAVE CHECKSUM
- MVI B,1
- CALL RECV ;GET CHECKSUM..
- CMP D ;..FROM RECEIVER.
- JZ NAMEOK
- SCKSER: MVI A,BDNMCH ;BAD NAME-TELL RECEIVER
- CALL SEND
- LDA QFLG
- ORA A
- JZ SKCSER1
- CALL ILPRT
- DB 'Checksum error',CR,LF,0
- SKCSER1:
- MVI E,80 ;DO HANDSHAKING OVER
- CALL WAITNLP ;DON'T PRINT "AWAITING NAK" MSG
- MVI A,ACK
- CALL SEND
- JMP SENDNM1
- NAMEOK: MVI A,OKNMCH ;GOOD NAME-TELL RECEIVER
- CALL SEND
- POP H
- RET
-
- GETFN: LXI H,FCB
- CALL INITFCBS+2 ;DOES NOT INITIALIZE DRIVE
- LDA QFLG
- ORA A
- JZ GNAMELP
- CALL ILPRT
- DB 'Awaiting file name',CR,LF,0
- GNAMELP:
- CALL HSNAK
- JC GNAMELP
- CALL GETNM ;GET THE NAME
- CPI EOT ;IF EOT, THEN NO MORE FILES
- JZ NOMRNMG
- ORA A ;CLEAR CARRY
- RET
- NOMRNMG:
- STC
- RET
-
- GETNM: PUSH H
- GETNM1: MVI C,0 ;INIT CHECKSUM
- LXI H,FCB+1
- NAMELPG:
- MVI B,5
- CALL RECV ;GET CHAR
- JNC GETNM3
- LDA QFLG
- ORA A
- JZ GETNM2
- CALL ILPRT
- DB 'Time out receiving filename',CR,LF,0
- GETNM2: JMP GCKSER
- GETNM3: CPI EOT ;IF EOT, THEN NO MORE FILES
- JZ GNRET
- CPI EOFCHAR ;GOT END OF NAME
- JZ ENDNAME
- MOV M,A ;PUT NAME IN FCB
- LDA QFLG ;TYPE IT IF NO QFLG
- ORA A
- MOV A,M
- CNZ TYPE
- PUSH B ;SAVE CKSUM
- MVI A,ACK ;ACK GETTING LETTER
- CALL SEND
- POP B
- INX H ;GET NEXT CHAR
- MOV A,L ;DON'T LET NOISE...
- CPI 7FH ;..CAUSE OVERFLOW..
- JZ GCKSER ;..INTO PROGRAM AREA.
- JMP NAMELPG
- ENDNAME:
- LDA QFLG
- ORA A
- CNZ CRLF
- MOV A,C ;SEND CHECKSUM
- CALL SEND
- MVI B,1
- CALL RECV ;CHECKSUM GOOD?
- CPI OKNMCH ;YES IF OKNMCH SENT..
- JZ GNRET ;..ELSE DO OVER.
- GCKSER: LXI H,FCB ;CLEAR FCB (EXCEPT DRIVE)..
- CALL INITFCBS+2 ;..SINCE IT MIGHT BE DAMAGED..
- LDA QFLG ;..BY TOO MANY CHARS.
- ORA A
- JZ GCKSER1
- CALL ILPRT
- DB 'Checksum error',CR,LF,0
- GCKSER1:
- CALL HSNAK ;DO HANDSHAKING OVER
- JC GCKSER1
- JMP GETNM1
- GNRET: POP H
- RET
-
- HSNAK: MVI A,NAK ;SEND NAK UNTIL..
- CALL SEND ;..RECEIVING ACK.
- CALL CKABORT ;DON'T GET HUNG UP HERE
- MVI B,2 ;WAIT 2 SECONDS..
- CALL RECV ;..IN RECEIVE.
- CPI ACK ;IF ACK,RETURN WITH..
- RZ ;..CARRY CLEAR.
- STC
- RET
-
- TNMBUF: MVI A,FALSE ;CALL FROM SENDFIL ONLY ONCE.
- STA FSTFLG
- STA FILECT
- CALL SCAN
- LXI H,NAMEBUF
- SHLD NBSAVE ;SAVE ADDR OF 1ST NAME
- TNLP1: CALL TRTOBUF
- LXI H,FCB
- LXI D,FCBBUF
- CALL CPMLINE ;PARSE NAME TO CP/M FORMAT
- TNLP2: CALL MFNAME ;SEARCH FOR NAMES (* FORMAT)
- JC NEXTNM
- LDA FCB+10 ;IF CP/M 2 $SYS FILE..
- ANI 80H ;..DON'T SEND
- JNZ TNLP2
- LHLD NBSAVE ;GET NAME
- LXI D,FCB ;MOVE IT TO FCB
- XCHG
- MVI B,12
- CALL MOVE
- XCHG
- SHLD NBSAVE ;ADDR OF NEXT NAME
- LXI H,FILECT ;COUNT FILES FOUND
- INR M
- JMP TNLP2
- ;
- NEXTNM: LXI H,NAMECT ;COUNT NAMES FOUND
- DCR M
- JNZ TNLP1
- LXI H,NAMEBUF ;SAVE START OF BUFFER
- SHLD NBSAVE
- LDA FILECT
- CPI 65 ;NO MORE THAN 64 TRANSFERS
- RC
- MVI A,64 ;ONLY X'FER FIRST 64
- STA FILECT
- RET
-
- ;SCANS CMDBUF COUNTING NAMES AND PUTTING DELIMITER (SPACE)
- ;AFTER LAST NAME
-
- SCAN: PUSH H
- LXI H,NAMECT
- MVI M,0
- LXI H,CMDBUF+1 ;FIND END OF CMD LINE..
- MOV C,M ;..AND PUT SPACE THERE.
- MVI B,0
- LXI H,CMDBUF+2
- DAD B
- MVI M,20H
- LXI H,CMDBUF+1
- MOV B,M
- INR B
- INR B
- SCANLP1:
- INX H
- DCR B
- JZ DNSCAN
- MOV A,M
- CPI 20H
- JNZ SCANLP1
- SCANLP2:
- INX H ;EAT EXTRA SPACES
- DCR B
- JZ DNSCAN
- MOV A,M
- CPI 20H
- JZ SCANLP2
- SHLD BGNMS ;SAVE START OF NAMES IN CMDBUF
- INR B
- DCX H
- SCANLP3:
- INX H
- DCR B
- JZ DNSCAN
- MOV A,M
- CPI 20H
- JNZ SCANLP3
- LDA NAMECT ;COUNTS NAMES
- INR A
- STA NAMECT
- SCANLP4:
- INX H ;EAT SPACES
- DCR B
- JZ DNSCAN
- MOV A,M
- CPI 20H
- JZ SCANLP4
- JMP SCANLP3
- ;
- DNSCAN: MVI M,20H ;SPACE AFTER LAST CHAR
- POP H
- RET
-
- ;PLACES NEXT NAME IN BUFFER SO CPMLINE MAY PARSE IT
- TRTOBUF:
- LHLD BGNMS
- MVI B,0
- LXI D,FCBBUF+2
- TBLP: MOV A,M
- CPI 20H
- JZ TRBFEND
- STAX D
- INX H
- INX D
- INR B ;COUNT CHARS IN NAME
- JMP TBLP
- ;
- TRBFEND:
- INX H
- MOV A,M ;EAT EXTRA SPACES
- CPI 20H
- JZ TRBFEND
- SHLD BGNMS
- LXI H,FCBBUF+1 ;PUT # CHARS BEFORE NAME
- MOV M,B
- RET
-
- ;IN CP/M V.2, IF FILE IS R/O OR SYS, IT IS CHANGED TO 'BAK'.
- CKCPM2: MVI C,12
- CALL BDOS
- ORA A ;RETURN 0 MEANS CP/M 1
- RZ
- MVI C,STDMA
- LXI D,80H
- CALL BDOS
- MVI C,SRCHF ;SEARCH FOR FILE
- LXI D,FCB
- CALL BDOS
- CPI 0FFH
- RZ
- ADD A ! ADD A ;MULT A-REG BY..
- ADD A ! ADD A ;..32 TO FIND..
- ADD A ;..NAME IN DMA.
- LXI H,80H
- ADD L
- MOV L,A ;HL POINTS TO DIR NAME
- LXI D,9
- DAD D ;POINT TO R/O ATTRIB BYTE
- MOV A,M
- ANI 80H ;TEST MSB
- JNZ MKCHG ;IF SET, MAKE CHANGE
- INX H ;CHECK SYSTEM ATTRIB BYTE
- MOV A,M
- ANI 80H
- RZ ;NOT $SYS OR $R/O
- DCX H
- MKCHG: LXI D,-8
- DAD D ;POINT HL TO FILENAME + 1
- LXI D,FCB+1 ;MOVE DIR NAME TO FCB..
- MVI B,11 ;..WITHOUT CHANGING DRIVE.
- CALL MOVE
- LXI H,FCB+9 ;R/O ATTRIB
- MOV A,M
- ANI 7FH ;STRIP R/O ATTRIB
- MOV M,A
- INX H ;SYS ATTRIB
- MOV A,M
- ANI 7FH
- MOV M,A
- LXI D,FCB
- MVI C,30 ;SET NEW ATTRIBS IN DIR
- CALL BDOS
-
- ;MAY BE CALLED BY CKBAKUP BELOW. ITS RETURN DONE HERE
- PLANCHG:
- LXI H,FCB ;CHANGE NAME TO TYPE "BAK"
- LXI D,6CH
- MVI B,9 ;MOVE DRIVE AND NAME (NOT TYPE)
- CALL MOVE
- LXI H,75H ;START OF TYPE IN FCB2
- MVI M,'B'
- INX H
- MVI M,'A'
- INX H
- MVI M,'K'
- LXI D,6CH
- MVI C,ERASE ;ERASE ANY PREV BACKUPS
- CALL BDOS
- LXI H,6CH ;FCB2 DR FIELD SHOULD..
- MVI M,0 ;..0 FOR RENAME.
- LXI D,FCB
- MVI C,23 ;RENAME
- CALL BDOS
- RET
-
- CKBAKUP:
- LDA BAKUPBYTE
- ORA A
- RZ
- MVI C,SRCHF
- LXI D,FCB
- CALL BDOS
- INR A
- RZ ;FILE NOT FOUND
- JMP PLANCHG ;IN "CKCPM2" - RET DONE THERE
-
- ;MULTI-FILE ACCESS SUBROUTINE FROM CP/M USER'S GROUP
- ;FIXED BY MARK ZEIGER 8/17/80
- ;CARRY IS SET IF NO MORE NAMES CAN BE FOUND
-
- MFNAME: MFACCESS ;A MACRO IN MODEM.LIB
-
- RCVSECT:
- XRA A
- STA ERRCT
- RCVRPT: XRA A ;ZERO ACCUM
- STA ERRCDE ;CLEAR RECEIVE ERROR CODE
- LDA QFLG
- ORA A
- JZ RCVSQ
- CALL ILPRT
- DB CR,'Awaiting # ',0
- PUSH H ;SAVE IT
- LHLD SECTNO ;GET SECTOR NUMBER
- INX H ;BUMP IT
- CALL DECOUT ;PRINT SECTOR NUMBER IN DECIMAL
- CALL ILPRT
- DB ' (', 0
- CALL DHXOUT ;16 BIT HEX CONVERSION & OUTPUT
- CALL ILPRT
- DB 'H)',0
- MOV A,L ;ONLY LOW BYTE USED BY PROGRAM
- POP H ;RESTORE IT
- ;
- ;----> RCVSQ:
- ; If CRC is in effect, there is only a 3 second wait
- ; for the first SOH. If the SOH is not received within
- ; 3 seconds, then a NAK is sent which tells the sender
- ; to use checksum checking instead of CRC. This allows
- ; automatic compatability with versions of XMODEM that
- ; do not implement Cyclic Redundancy Checking(CRC).
- ;
- RCVSQ: LDA FIRSTME ;first SOH...
- ORA A ;...been received?
- JZ RCVSQ2 ;yes, go get next SOH
- XRA A ;turn off...
- STA FIRSTME ;...first soh recvd switch
- LDA CRCFLG ;CRC in...
- ORA A ;...effect?
- JNZ RCVSQ2 ;no, do long wait for first SOH
- MVI B,7 ;wait for upto 7 seconds <---- JKM MOD 7/16/82
- CALL RECV ;get a character from modem
- JNC RCVSQ3 ;got a char, go see if SOH
- CALL ILPRT
- DB CR,LF,'++Switching to CHECKSUM MODE++',CR,LF,0
- MVI A,'C' ;turn off...
- STA CRCFLG ;...CRC mode.
- MVI A,NAK ;send NAK to tell sender checksum
- CALL SEND ;...is in effect & to start sending.
- JMP RCVSECT ;go start receiving sector
- ;
- RCVSQ2: MVI B,7 ;10 IN ORIG PROG
- CALL RECV
- JC RCVSTOT
- ;
- RCVSQ3: CALL RCVERR ;CHECK FOR ERRORS
- JC RCVDERR ;JUMP IF THERE WAS AN ERROR
- CPI SOH
- JZ RCVSOH
- ORA A
- JZ RCVSQ
- CPI EOT
- STC
- RZ
- MOV B,A
- LDA VSEEFLG
- ORA A
- JZ RCVSEH
- LDA QFLG
- ORA A
- JZ RCVSERR
-
- RCVSEH: MOV A,B
- CALL CRLF
- CALL HEXO
- CALL ILPRT
- DB 'H recv''d, not SOH',CR,LF,0
-
- RCVSERR: MVI B,1
- CALL RECV
- JNC RCVSERR
- MVI A,NAK
- CALL SEND
- LDA ERRCT
- INR A
- STA ERRCT
- CPI ERRLIM
- JC RCVRPT
- LDA VSEEFLG
- ORA A
- JZ RCVCKQ
- LDA QFLG
- ORA A
- JZ RCVSABT
- RCVCKQ: CALL CKQUIT
- JZ RCVSECT
- RCVSABT:
- CALL CLOSFIL
- CALL ERXIT
- DB CR,LF,'++Unable to receive block - Aborting++',CR,LF,'$'
-
- RCVSTOT:
- LDA VSEEFLG
- ORA A
- JZ RCVSPT
- LDA QFLG
- ORA A
- JZ RCVSERR
- RCVSPT: CALL ILPRT
- DB CR,LF,'++ Timeout ++ ',0
- RCVPRN: LDA ERRCT
- CALL HEXO
- CALL CRLF
- JMP RCVSERR
-
- ;----> RCVERR:
- ; Checks for framing, overrun, and parity errors. Parity errors
- ; cannot be detected unless the parity option has been selected.
- ; 1.Error code (ERRCDE) was set in RECV routine.
- ; 2.ERRCDE=0 for no errors, ERRCDE<>0 for errors.
- ; 3.If there is an error, routine returns with carry flag set.
-
- RCVERR: PUSH PSW ;SAVE CHAR TRANSMITTED
- LDA ERRCDE ;GET RECEIVE ERROR CODE
- ANA A ;IS IT ZERO?
- JZ RCVERR2 ;YES, NO RECEIVE ERROR
- POP PSW ;RESTORE CHAR TRANSMITTED
- STC ;SET CARRY ON TO INDICATE AN ERROR
- RET
-
- RCVERR2:
- POP PSW ;RESTORE CHAR TRANSMITTED
- RET
-
- ;----> RCVDERR: Checks for a receive error and displays appropriate error
- ; message. Then goes to RCVSERR to purge the line and send a NAK.
-
- RCVDERR:
- LDA VSEEFLG ;VIEWING
- ORA A ;...MODE?
- JZ RCVDERRP ;YES,..PRT MSG
- LDA QFLG ;QUIET...
- ORA A ;...MODE?
- JZ RCVSERR ;YES, NO MSG
-
- RCVDERRP: CALL ILPRT
- DB CR,LF,0
- LDA ERRCDE ;GET RECEIVE ERR CODE
- ANI FRMER ;WAS THERE A FRAMING ERROR?
- JZ RCVDERR2 ;NO, GO CHECK FOR OVERRUN
- CALL ILPRT
- DB '++Framing error++ ',0
- CALL RCVDERR5 ;PRINT # OF ERROR
-
- RCVDERR2:
- LDA ERRCDE ;GET RECEIVE ERR CODE
- ANI ORUNER ;WAS THERE AN OVERRUN
- JZ RCVDERR3 ;NO, GO CHECK FOR PARITY ERROR
- CALL ILPRT
- DB '++Overrun error++ ',0
- CALL RCVDERR5
-
- RCVDERR3:
- LDA ERRCDE ;GET RECEIVE ERR CODE
- ANI PARER ;WAS THERE A PARITY ERROR?
- JZ RCVDERR4 ;NO, GO PURGE LINE
- CALL ILPRT
- DB '++Parity error++ ',0
- CALL RCVDERR5
-
- RCVDERR4: JMP RCVSERR ;GO PURGE LINE, SEND NAK
-
- ;Display the number of the error, do a carriage return and line feed.
- RCVDERR5:
- LDA ERRCT ;GET ERROR NUMBER
- CALL HEXO ;DISPLAY IT
- CALL CRLF ;DO CR, LF
- RET
-
- RCVSOH: MVI B,1
- CALL RECV
- JC RCVSTOT
- CALL RCVERR ;CHECK FOR RECEIVE ERROR
- JC RCVDERR
- MOV D,A
- MVI B,1
- CALL RECV
- JC RCVSTOT
- CALL RCVERR ;CHECK FOR RECEIVE ERROR
- JC RCVDERR
- CMA
- CMP D
- JZ RCVDATA
- LDA VSEEFLG
- ORA A
- JZ RCVBSE
- LDA QFLG
- ORA A
- JZ RCVSERR
- RCVBSE: CALL ILPRT
- DB CR,LF,'++ Bad sector # in Hdr',CR,LF,0
- JMP RCVSERR
-
- RCVDATA:
- MOV A,D
- STA RCVSNO
- MVI A,1
- STA DATAFLG
- MVI C,0
- CALL CLRCRC ;clear crc counter
- LXI H,80H
- RCVCHR: MVI B,1
- CALL RECV
- JC RCVSTOT
- CALL RCVERR ;CHECK FOR RECEIVE ERROR
- JC RCVDERR
- MOV M,A
- INR L
- JNZ RCVCHR
- LDA CRCFLG
- ORA A
- JZ RCVCRC
- MOV D,C
- XRA A
- STA DATAFLG
- MVI B,1
- CALL RECV
- JC RCVSTOT
- CALL RCVERR ;CHECK FOR RECEIVE ERROR
- JC RCVDERR
- CMP D
- JNZ RCVCERR
- CHKSNUM:
- LDA RCVSNO
- MOV B,A
- LDA SECTNO
- CMP B
- JZ RECVACK
- INR A
- CMP B
- JNZ ABORT
- RET
- ;
- RCVCRC: MVI E,2 ;nr of crc bytes
- ;
- RCVCRC2:
- MVI B,1
- CALL RECV
- JC RCVSTOT
- CALL RCVERR
- JC RCVDERR
- DCR E
- JNZ RCVCRC2
- CALL CHKCRC
- ORA A
- JZ CHKSNUM
- LDA VSEEFLG
- ORA A
- JZ RCVCRER
- LDA QFLG
- ORA A
- JZ RCVSERR
- ;
- RCVCRER:
- CALL ILPRT
- DB CR,LF,'++CRC error++',0
- JMP RCVPRN
-
- RCVCERR:
- LDA VSEEFLG
- ORA A
- JZ RCVCPR
- LDA QFLG
- ORA A
- JZ RCVSERR
- RCVCPR: CALL ILPRT
- DB '++Cksum error++ ',0
- JMP RCVPRN
-
- RECVACK:
- CALL SENDACK
- JMP RCVSECT
-
- SENDACK:
- MVI A,ACK
- CALL SEND
- RET
-
- SENDHDR:
- LDA QFLG
- ORA A
- JZ SENDHNM
- CALL ILPRT
- DB CR,'Send # ',0
- PUSH H
- LHLD SECTNO ;GET SECTOR NUMBER
- CALL DECOUT ;PRINT IT IN DECIMAL
- CALL ILPRT
- DB ' (',0
- CALL DHXOUT ;16 BIT HEX CONVERSION & OUTPUT
- CALL ILPRT
- DB 'H)',0
- POP H
- SENDHNM:
- MVI A,SOH
- CALL SEND
- LDA SECTNO
- CALL SEND
- LDA SECTNO
- CMA
- CALL SEND
- RET
-
- SENDSEC:
- MVI A,1
- STA DATAFLG
- MVI C,0
- CALL CLRCRC
- LXI H,80H
- SENDC: MOV A,M
- CALL SEND
- INR L
- JNZ SENDC
- XRA A
- STA DATAFLG
- RET
-
- SENDCKS:
- MOV A,C
- CALL SEND
- RET
-
- SENDCRC:
- CALL FINCRC
- MOV A,D
- CALL SEND
- MOV A,E
- CALL SEND
- XRA A
- RET
-
- GETACK: MVI B,7 ;10 IN ORIG PROG
- CALL RECVDG
- JC GETATOT
- CPI ACK
- RZ
- MOV B,A
- LDA QFLG
- ORA A
- JZ ACKERR
- MOV A,B
- CALL CRLF
- CALL HEXO
- CALL ILPRT
- DB 'H Recv''d, not ACK',CR,LF,0
- ACKERR: LDA ERRCT
- INR A
- STA ERRCT
- CPI ERRLIM
- RC
- LDA VSEEFLG
- ORA A
- JZ GACKV
- LDA QFLG
- ORA A
- JZ CSABORT
- GACKV: CALL CKQUIT
- STC
- RZ
- CSABORT:
- CALL ERXIT
- DB CR,LF,'Can''t send sector -- Aborting',CR,LF,'$'
- ;
- GETATOT:
- LDA QFLG
- ORA A
- JZ ACKERR
- CALL ILPRT
- DB CR,LF,'Timeout on ACK',CR,LF,0
- JMP ACKERR
-
- CKABORT:
- LDA VSEEFLG
- ORA A
- JZ CKABGO
- LDA QFLG
- ORA A
- RZ
- CKABGO: CALL STAT
- RZ
- CALL KEYIN
- CPI CAN
- RNZ
- ABORT: LXI SP,STACK
- ABORTL: MVI B,1
- CALL RECV
- JNC ABORTL
- MVI A,CAN
- CALL SEND
- ABORTW: MVI B,1
- CALL RECV
- JNC ABORTW
- MVI A,' '
- CALL SEND
- CALL ILPRT
- DB CR,LF,'Routine cancelled',CR,LF,BELL,0
- MVI A,'B' ;TURN MULTI-FILE MODE..
- STA BATCHFLG ;..OFF SO ROUTINE ENDS.
- JMP DONETCE
-
- INCRSNO:
- PUSH H
- LHLD SECTNO ;GET SECTOR NUMBER
- INX H ;BUMP IT
- SHLD SECTNO ;STORE IT
- MOV A,L
- POP H
- RET
-
- ERASFIL:
- LDA BATCHFLG ;DON'T ASK FOR ERASE..
- ORA A ;..IN MULTI-FILE MODE,..
- JZ NOASK ;..JUST DO IT.
- LXI D,FCB
- MVI C,SRCHF
- CALL BDOS
- INR A
- RZ
- CALL ILPRT
- DB 'File exists -- Type ''Y'' to erase: ',BELL,0
- CALL KEYIN
- PUSH PSW
- CALL TYPE
- POP PSW
- CALL UCASE
- CPI 'Y'
- JNZ MENU
- CALL CRLF
- ;
- NOASK: LXI D,FCB
- MVI C,ERASE
- CALL BDOS
- RET
-
- BLKFILE:
- CALL ILPRT ;ROUTINE IF NO FILE IS NAMED FOR "SEND" OR "RECEIVE"
- DB CR,LF,'No file specified',CR,LF,BELL,0
- JMP MENU
-
- MAKEFIL:
- LXI D,FCB
- MVI C,MAKE
- CALL BDOS
- INR A
- RNZ
- CALL ERXIT
- DB 'Error - Can''t make file',CR,LF
- DB 'Directory must be full',CR,LF,'$'
-
- IF CPM2X
- CNREC: MVI C,FILSIZ ;COMPUTE FILE SIZE FUNCTION IN CP/M 2.x
- LXI D,FCB ;POINT TO FILE CONTROL BLOCK
- CALL BDOS
- LHLD FCB+33 ;GET RECORD COUNT
- SHLD RCNT ;STORE IT
- LXI H,0 ;ZERO HL
- SHLD FCB+33 ;RESET RANDOM RECORD IN FCB
- RET
- ENDIF
-
- IF NOT CPM2X
- CNREC: MVI A,'?' ;MATCH ALL EXTENTS
- STA FCBEXT
- MVI A,0FFH
- STA MAXEXT ;INIT MAX EXT NO.
- MVI C,SRCHF ;GET 'SEARCH FIRST' FNC
- LXI D,FCB
- CALL BDOS ;READ FIRST
- INR A ;WERE THERE ANY?
- JNZ SOME ;GOT SOME
- CALL ERXIT
- DB '++File not found++$'
-
- ;READ MORE DIRECTORY ENTRIES
- MOREDIR:
- MVI C,SRCHN ;SEARCH NEXT
- LXI D,FCB
- CALL BDOS ;READ DIR ENTRY
- INR A ;CHECK FOR END (0FFH)
- JNZ SOME ;NOT END OF DIR...PROCESS EXTENT
- LDA MAXEXT ;HIT END...GET HIGHEST EXTENT NO. SEEN
- MOV L,A ;WHICH GIVES EXTENT COUNT -1
- MVI H,0
- MOV D,H
- LDA RCNT ;GET RECORD COUNT OF MAX EXTENT SEEN
- MOV E,A ;SAVE IT IN DE
- DAD H
- DAD H ;MULTIPLY # OF EXTENTS -1
- DAD H ; TIMES 128
- DAD H
- DAD H
- DAD H
- DAD H
- DAD D ;ADD IN SIZE OF LAST EXTENT
- SHLD RCNT ;SAVE TOTAL RECORD COUNT
- RET ;AND EXIT
-
- ;POINT TO DIRECTORY ENTRY
- SOME: DCR A ;UNDO PREV 'INR A'
- ANI 3 ;MAKE MODULUS 4
- ADD A ;MULTIPLY...
- ADD A ;..BY 32 BECAUSE
- ADD A ;..EACH DIRECTORY
- ADD A ;..ENTRY IS 32
- ADD A ;..BYTES LONG
- LXI H,80H ;POINT TO BUFFER
- ADD L ;POINT TO ENTRY
- ADI 15 ;OFFSET TO RECORD COUNT
- MOV L,A ;HL NOW POINTS TO REC COUNT
- MOV B,M ;GET RECORD COUNT
- DCX H
- DCX H ;BACK DOWN TO EXTENT NUMBER
- DCX H
- LDA MAXEXT ;COMPARE WITH CURRENT MAX.
- ORA A ;IF NO MAX YET
- JM BIGGER ;THEN SAVE RECORD COUNT ANYWAY
- CMP M
- JNC MOREDIR
- BIGGER: MOV A,B ;SAVE NEW RECORD COUNT
- STA RCNT
- MOV A,M ;SAVE NEW MAX. EXTENT NO.
- STA MAXEXT
- JMP MOREDIR ;GO FIND MORE EXTENTS
- ENDIF
-
- OPENFIL:
- XRA A
- STA FCBEXT
- LXI D,FCB
- MVI C,OPEN
- CALL BDOS
- INR A
- JNZ OPENOK
- CALL ERXIT
- DB 'Can''t open file$'
-
- OPENOK: LDA BATCHFLG
- ORA A
- JNZ OPENOK1
- LDA QFLG
- ORA A
- RZ
- OPENOK1:
- CALL ILPRT
- DB 'File open, size: ',0
- LHLD RCNT ;GET RECORD COUNT
- CALL DECOUT ;PRINT NUMBER OF SECTORS IN DECIMAL
- CALL ILPRT ;PRINT
- DB ' (',0
- CALL DHXOUT
- CALL ILPRT
- DB 'H) sectors',CR,LF,0
- RET
-
- CLOSFIL:
- LXI D,FCB
- MVI C,CLOSE
- CALL BDOS
- INR A
- RNZ
- CALL ERXIT
- DB 'Can''t close file$'
-
- RDSECT:
- LDA SECINBF
- DCR A
- STA SECINBF
- JM RDBLOCK
- LHLD SECPTR
- LXI D,80H
- CALL MOVE128
- SHLD SECPTR
- RET
-
- RDBLOCK:
- LDA EOFLG
- CPI 1
- STC
- RZ
- MVI C,0
- LXI D,DBUF
- RDSECLP:
- PUSH B
- PUSH D
- MVI C,STDMA
- CALL BDOS
- LXI D,FCB
- MVI C,READ
- CALL BDOS
- POP D
- POP B
- ORA A
- JZ RDSECOK
- DCR A
- JZ REOF
- CALL ERXIT
- DB '++ File read error ++$'
- RDSECOK:
- LXI H,80H
- DAD D
- XCHG
- INR C
- MOV A,C
- CPI DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS
- JZ RDBFULL
- JMP RDSECLP
- REOF: MVI A,1
- STA EOFLG
- MOV A,C
- RDBFULL:
- STA SECINBF
- LXI H,DBUF
- SHLD SECPTR
- LXI D,80H
- MVI C,STDMA
- CALL BDOS
- JMP RDSECT
- ;
- WRSECT: LHLD SECPTR
- XCHG
- LXI H,80H
- CALL MOVE128
- XCHG
- SHLD SECPTR
- LDA SECINBF
- INR A
- STA SECINBF
- CPI DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS
- RNZ
- ;
- WRBLOCK:
- LDA SECINBF
- ORA A
- RZ
- MOV C,A
- LXI D,DBUF
- DKWRLP: PUSH H
- PUSH D
- PUSH B
- MVI C,STDMA
- CALL BDOS
- LXI D,FCB
- MVI C,WRITE
- CALL BDOS
- POP B
- POP D
- POP H
- ORA A
- JNZ WRERR
- LXI H,80H
- DAD D
- XCHG
- DCR C
- JNZ DKWRLP
- XRA A
- STA SECINBF
- LXI H,DBUF
- SHLD SECPTR
- RET
-
- WRERR: MVI C,CAN
- CALL SEND
- CALL ERXIT
- DB 'Error writing file',CR,LF,'$'
-
- ;----> RECV: Receive a character
-
- ;Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage
- ;characters on the line. For example, having just sent a sector, calling
- ;RECVDG will delete any line noise induced characters LONG before the
- ;ACK/NAK would be received.
-
- RECVDG: EQU $
- CALL IN$MODDATP
- CALL IN$MODDATP
- RECV: PUSH D
- LDA FASTCLK
- ORA A
- JZ MSEC
- MOV A,B
- ADD A
- MOV B,A
- MSEC: LXI D,15000 ;60% OF ORIG 50000
- CALL CKABORT
- MWTI: CALL IN$MODCTLP
- CALL ANI$MODRCVB
- CALL CPI$MODRCVR
- JZ MCHAR
- DCR E
- JNZ MWTI
- DCR D
- JNZ MWTI
- DCR B
- JNZ MSEC
- POP D
- STC
- RET
-
- MCHAR: LDA PMMIBYTE ;IS THE MODEM A PMMI?
- ORA A ;SET FLAGS
- JZ MCHAR1 ;YES, JUMP
- CALL IN$MODCTLP ;GET ERROR-STATUS BYTE
- ANI ERRCDMSK ;MASK OUT ALL EXCEPT ERROR BITS (3-5)
- STA ERRCDE ;SAVE THE ERROR CODE
- MCHAR1: CALL IN$MODDATP
- POP D
- PUSH PSW
- CALL UPDCRC ;calc crc
- ADD C
- MOV C,A
- LDA RSEEFLG
- ORA A
- JZ MONIN
- LDA VSEEFLG
- ORA A
- JNZ NOMONIN
- LDA DATAFLG
- ORA A
- JZ NOMONIN
- MONIN: POP PSW
- PUSH PSW
- CALL SHOW
- NOMONIN:
- POP PSW
- ORA A
- RET
-
- SEND: PUSH PSW
- LDA SSEEFLG
- ORA A
- JZ MONOUT
- LDA VSEEFLG
- ORA A
- JNZ NOMONOT
- LDA DATAFLG
- ORA A
- JZ NOMONOT
- MONOUT: POP PSW
- PUSH PSW
- CALL SHOW
- NOMONOT:
- POP PSW
- PUSH PSW
- CALl UPDCRC ;calc crc
- ADD C
- MOV C,A
- SENDW: CALL IN$MODCTLP
- CALL ANI$MODSNDB
- CALL CPI$MODSNDR
- JNZ SENDW
- POP PSW
- CALL OUT$MODDATP
- RET
-
- WAITNAK:
- LDA VSEEFLG
- ORA A
- JZ WAITNPR
- LDA QFLG
- ORA A
- JZ WAITNLP
- WAITNPR:
- CALL ILPRT
- DB 'Awaiting initial NAK',CR,LF,0
- WAITNLP:
- CALL CKABORT
- MVI B,1
- CALL RECV
- CPI NAK
- RZ
- CPI CRC ;crc request?
- JZ WAITCRC ;yes, go set crc flag
- DCR E
- JZ ABORT
- JMP WAITNLP
- ;
- WAITCRC:
- CALL ILPRT
- DB 'CRC request received',CR,LF,0
- XRA A
- STA CRCFLG
- RET
- ;
- ;--->PARITY: Routine to setup PMMI for odd/even parity.
-
- PARITY: LDA PMMIBYTE ;IS MODEM A PMMI?
- ORA A ;SET FLAGS
- RZ ;NO, RETURN
- LDA OPARITY ;GET ODD PARITY REQUEST BYTE
- ORA A ;SET FLAGS
- JNZ EVENPAR ;IF NOT ODD SEE IF IT IS EVEN
- LDA UARTCTLB ;GET UART/MODEM CONTROL BYTE
- ANI ODPARMSK
- JMP PARITY1
-
- EVENPAR:
- LDA EPARITY ;GET EVEN PARITY REQUEST BYTE
- ORA A ;SET FLAGS
- RNZ ;IF EVEN PARITY NOT SPECIFIED RETURN
- LDA UARTCTLB ;GET UART/MODEM CONTROL BYTE
- ANI ODPARMSK ;SET FOR PARITY
- ORI EVPARMSK ;NOW SET FOR EVEN PARITY
-
- PARITY1:
- JMP OUT$MODCTLP ;SEND TO PMMI -
- ;WHEN OUT$MODCTLP DOES RET IT
- ;WILL GO BACK TO CALLING ROUTINE
-
- NOPARIT:
- LDA PMMIBYTE
- ORA A
- RZ
- LDA UARTCTLB ;GET UART/MODEM CONTROL BYTE
- ORI NOPARMSK ;RESET PARITY BIT ON PMMI
- JMP OUT$MODCTLP
-
-
- INITADR:
- LHLD 1
- LXI D,3
- DAD D
- SHLD VSTAT+1
- DAD D
- SHLD VKEYIN+1
- DAD D
- SHLD VTYPE+1
- LDA PMMIBYTE
- ORA A
- JZ JMP$INITMOD ;RETURN DONE FROM THIS ROUTINE..
- LDA IN$MODCTLP+1 ;..IF NOT PMMI
- STA OUT$MODCTLP+1
- INR A
- STA OUT$MODDATP+1
- STA IN$MODDATP+1
- INR A
- STA IN$BAUDRP+1
- STA OUT$BAUDRP+1
- INR A
- STA OUT$MODCTL2+1
- RET
-
- PROCOPT:
- LXI D,FCB+1
- LDAX D
- STA OPTION
- OPTLP: INX D
- LDAX D
- CPI ' '
- JZ ENDOPT
- LXI H,OPTBL
- MVI B,OPTBE-OPTBL
- OPTCK: CMP M
- JNZ OPTNO
- CPI 'O' ; @7.61
- JNZ OPTCK1 ; @7.61
- XRA A ; @7.61
- STA UARTFLG ; @7.61
- JMP OPTCK2 ; @7.61
- OPTCK1: CPI 'A' ; @7.61
- JNZ OPTCK2 ; @7.61
- MVI A,0FFH ; @7.61
- STA UARTFLG ; @7.61
- OPTCK2: MVI M,0 ; @7.61
- JMP OPTLP
- OPTNO: INX H
- DCR B
- JNZ OPTCK
- JMP BADOPT
-
- ENDOPT: LDA CRCFLG
- ORA A
- JNZ ENDOPT2
- LDA OPTION
- CPI 'R'
- JNZ BADOPT ;crc only allowed for recv
- ;
- ENDOPT2:
- LDA VSEEFLG
- ORA A
- RNZ
- STA QFLG
- RET
-
- DONE: LDA BATCHFLG
- ORA A
- JNZ DONETCC
- LDA QFLG
- ORA A
- JZ NMSTRNS
- LXI H,FCB+1 ;PUT FILE NAME IN..
- LXI D,FTRNMSG ;..SPACES IN MESSAGE..
- MVI B,8 ;..BELOW.
- CALL MOVE
- INX D ;PUT FILE TYPE AFTER..
- MVI B,3 ;..SKIPPING ONE SPACE..
- CALL MOVE ;..BELOW.
- CALL ILPRT
- FTRNMSG:
- DB ' transferred',CR,LF,CR,LF,0 ;13 SPACES
-
- NMSTRNS:
- LDA FCB ;SAVE DRIVE NO.
- STA DISKNO
- LXI H,FCB ;BLANK OUT FILE CONTROL BLOCKS
- CALL INITFCBS
- LDA DISKNO ;PUT DRIVE NUMBER BACK
- STA FCB
- LXI H,RESTSN ;RESTORE SECTORE NUMBERS..
- LXI D,SECTNOB ;..FOR NEW FILE TRANSFER.
- MVI B,SECTNOE-SECTNOB ;ROUTINE ALSO DONE IN MENU.
- CALL MOVE
- LDA SENDFLG ;GOES TO EITHER SEND OR..
- ORA A ;..RECEIVE FILE, DEPENDING..
- JNZ SENDFIL ;..UPON WHICH ROUTINE SET..
- JMP RCVFIL1 ;..THE FLAG IN MULTI-FILE MODE. @FIX7.61
-
- DONETCC:
- MVI A,TRUE ;INDICATE NO FILES BEING..
- STA FSTFLG ;RESET MULTIFILE TRANS
- STA NFILFLG ;..USED IN TERMINAL ROUTINE.
- CMA
- OUT FRONTPAN
- STA SAVEFLG ;STOP MEMORY SAVE IN TERM ROUTINE.
- LDA VSEEFLG
- ORA A
- JZ DONETC
- LDA QFLG
- ORA A
- JZ DONETCA
- DONETC: CALL ILPRT
- DB CR,LF,'All transfers completed'
- DB CR,LF,BELL,0
- DONETCA:
- LDA DISCFLG ;see if disconnect when thru
- ORA A
- JNZ DONETCE ;no, don't disconnect
- DONETCB:
- CALL ILPRT
- DB CR,LF,'++Press RETURN to disconnect++',BELL,CR,LF,0
- MVI C,RDCON
- CALL BDOS ;wait for response
- CPI 0DH ;carriage return
- JNZ DONETCB ;nope
- CALL ILPRT
- DB CR,LF,'++Disconnected++',CR,LF,0
- CALL DISCONNT ;hang-up the pmmi
- JMP EXIT ;go to CP/M
-
- DONETCE:
- CALL NOPARIT ;RESET TO NO PARITY
- mvi a,crc ;@7.41....................
- sta CRCFLG ;turn off CRC option
- mvi a,0FFH
- sta FIRSTME ;set first-time flag
- ;@7.41....................
- LDA TERMFLG ;SEE IF RETURN TO..
- ORA A ;..TERMINAL MODE..
- JNZ MENU ;..AFTER X'FER.
- CALL CRLF
- JMP TERM
-
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; THIS BIT INSTALLED FOR BIGBOARD1...
- SIODATA:DB 00,18H,10H,02,00,04,44H,03,0C1H,01,00,05,0EAH,00
- ; INIT STRING FOR SIO
- ;
- INITMOD:
- LXI H,SIODATA ;POINTS HL TO SIO INIT STRING
- LXI B,0E07H ;SETS UP BC FOR Z80 INST OTIR
- ; B IS NO. OF BYTES TO TRANSFER
- ; C IS OUTPUT PORT NO.
- DB 0EDH,0B3H ;Z80 OTIR INST.
- ;
- ; INIT OF BIGBOARD1 BAUD RATE GEN....
- MVI A,05H ;05 FOR 300 BAUD
- OUT 0CH ; BAUD RATE PORT.
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SETBAUD:
- LDA PMMIBYTE
- ORA A
- RZ
- LDA ANSWFLG ;IF ANSWER OR ORIGINATE MODE..
- ORA A ;..IS NOT REQUESTED OR NO..
- JNZ SKIPB1 ;..BAUDRATE SPECIFIED, THEN..
- CALL GETBAUD ;..ROUTINE RETURNS WITH CHANGE..
- JMP FIXBAUD ;..OF BAUD. IF OPT REQUESTED,..
- SKIPB1: LDA ORIGFLG ;..A BLANK FORCES 300 BAUD..
- ORA A ;..ELSE A 0 FROM NEWBAUD..
- RNZ ;..FORCES 300 BAUD.
- CALL GETBAUD
- FIXBAUD:
- CALL OUT$BAUDRP
- CPI 52
- MVI A,5FH
- JC GT300
- MVI A,7FH
- GT300: CALL OUT$MODCTL2
- STA MODCTLB ;SAVE MODEM CONTROL BYTE
- LDA ORIGFLG
- ORA A
- MVI A,ORIGMOD
- JZ OFFHOOK
- LDA ANSWFLG
- ORA A
- MVI A,ANSWMOD
- RNZ
-
- OFFHOOK:
- LXI H,4000
- OFFDLY: DCR L
- JNZ OFFDLY
- DCR H
- JNZ OFFDLY
- CALL OUT$MODCTLP
- RET
-
- GETBAUD:
- LDA FCB+9
- CPI ' '
- MVI A,52
- RZ
- LDA FCB+9
- CPI 0
- MVI A,52
- RZ
-
- LXI D,FCB+9
- LXI H,0
- DECLP: LDAX D
- INX D
- CPI ' '
- JZ DECLP
- CPI '0'
- JC BADRATE
- CPI '9'+1
- JNC BADRATE
- SUI '0'
- MOV B,H
- MOV C,L
- DAD H
- DAD H
- DAD B
- DAD H
- ADD L
- MOV L,A
- JNZ DIGNC
- INR H
- DIGNC: MOV A,E
- CPI FCB+12
- JNZ DECLP
- MOV A,H
- CMA
- MOV D,A
- MOV A,L
- CMA
- MOV E,A
- INX D
- LXI H,15625
- LXI B,-1
- DIVLP: INX B
- DAD D
- JC DIVLP
- MOV A,B
- ORA A
- MOV A,C
- RZ
-
- BADRATE:
- CALL ERXIT
- DB '++ Invalid baud rate ++$'
-
- MOVEFCB:
- LXI H,FCB+16
- LXI D,FCB
- MVI B,16
- CALL MOVE
- XRA A
- STA FCBSNO
- STA FCBEXT
- RET
-
- SHOW: CPI LF
- JZ CTYPE
- CPI CR
- JZ CTYPE
- CPI 9
- JZ CTYPE
- CPI ' '
- JC SHOWHEX
- CPI 7FH
- JC CTYPE
- SHOWHEX:
- PUSH PSW
- MVI A,'('
- CALL CTYPE
- POP PSW
- CALL HEXO
- MVI A,')'
- JMP CTYPE
-
- CTYPE: PUSH B
- PUSH D
- PUSH H
- MOV E,A
- MVI C,WRCON
- CALL BDOS
- POP H
- POP D
- POP B
- RET
-
- CRLF: PUSH PSW
- MVI A,CR
- CALL TYPE
- MVI A,LF
- CALL TYPE
- POP PSW
- RET
-
- TYPE: PUSH PSW
- PUSH B
- PUSH D
- PUSH H
- MOV C,A
- VTYPE: CALL $-$
- POP H
- POP D
- POP B
- POP PSW
- RET
-
- STAT: PUSH B
- PUSH D
- PUSH H
- VSTAT: CALL $-$
- POP H
- POP D
- POP B
- ORA A
- RET
-
- KEYIN: PUSH B
- PUSH D
- PUSH H
- VKEYIN: CALL $-$
- POP H
- POP D
- POP B
- RET
-
- UCASE: CPI 61H ;CHANGES LOWER CASE CHARACTER..
- RC ;..IN A-REG TO UPPER CASE.
- CPI 7BH
- RNC
- ANI 5FH
- RET
-
- DECOUT: PUSH PSW
- PUSH B
- PUSH D
- PUSH H
- LXI B,-10
- LXI D,-1
-
- DECOU2: DAD B
- INX D
- JC DECOU2
- LXI B,10
- DAD B
- XCHG
- MOV A,H
- ORA L
- CNZ DECOUT
- MOV A,E
- ADI '0'
- CALL CTYPE
- POP H
- POP D
- POP B
- POP PSW
- RET
-
- ;----> DHXOUT: - double precision hex output routine.
-
- DHXOUT: PUSH H
- PUSH PSW
- MOV A,H ;GET MS BYTE
- CALL HEXO ;OUTPUT HIGH ORDER BYTE
- MOV A,L ;GET LS BYTE
- CALL HEXO ;OUTPUT LOW ORDER BYTE
- POP PSW
- POP H
- RET
-
- HEXO: PUSH PSW
- RAR
- RAR
- RAR
- RAR
- CALL NIBBL
- POP PSW
- NIBBL: ANI 0FH
- CPI 10
- JC ISNUM
- ADI 7
- ISNUM: ADI '0'
- JMP TYPE
-
- ;RETURNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN
- ;NO QUESTIONS ASKED, JUST QUIT
-
- CKQUIT: LDA BATCHFLG
- ORA A
- JNZ CKQTASK ;ASK FOR RETRY
- INR A ;RESET ZERO FLG
- RET
- CKQTASK:
- XRA A
- STA ERRCT
- CALL ILPRT
- DB 'Multiple errors encountered.',CR,LF
- DB 'Type Q to quit, R to retry: ',BELL,0
- CALL KEYIN
- PUSH PSW
- CALL CRLF
- POP PSW
- CALL UCASE ;INSTEAD OF "ANI 5FH"
- CPI 'R'
- RZ
- CPI 'Q'
- JNZ CKQUIT
- ORA A
- RET
-
- ILPRT: XTHL
- ILPLP: MOV A,M
- ORA A
- JZ ILPRET
- CALL CTYPE
- INX H
- JMP ILPLP
- ILPRET: XTHL
- RET
-
- PRTMSG: MVI C,PRINT
- JMP BDOS
-
- ERXIT: POP D
- CALL PRTMSG
- CALL ILPRT
- DB BELL,0
- LDA BATCHFLG
- ORA A
- JNZ DONETCE
- MVI A,'Q' ;RESET QFLG
- STA QFLG
- JMP ABORT ;ABORT OTHER COMPUTER
-
- EXIT: LXI D,80H
- MVI C,STDMA
- CALL BDOS
- LHLD STACK
- SPHL
- LDA SAVCCP
- ORA A
- JZ 0 ;WARM BOOT
- RET
-
- MOVE128:
- MVI B,128
- MOVE: MOV A,M
- STAX D
- INX H
- INX D
- DCR B
- JNZ MOVE
- RET
-
- ;DIALING ROUTINES TAKEN (AND GREATLY MODIFIED) FROM PMMI MANUAL.
-
- ;MODEM CONTROL COMMAND WORDS
-
- CLEAR EQU 3FH ;IDLE MODE
- MAKEM EQU 1 ;TELE LINE MAKE (OFF HOOK)
- BRKM EQU 0 ;TELE LINE ON HOOK (BREAK DURING DIALING)
- DTMSK EQU 1 ;DIAL TONE MASK
- RBLMT EQU 70 ;# OF SEC*10 TO WAIT BEFORE GIVING NO RING HEARG MSG
- RBWAIT EQU 50 ;# OF SEC*10 DELAY BEFORE REDIALING NUMBER
- TMPUL EQU 80H ;TIMER PULSES MASK BIT
- TRATE EQU 250 ;VALUE FOR 0.1 SECOND
-
-
- DIALPL: LDA PMMIBYTE ;FLAG FOR PMMI OPERATION
- ORA A ;SET FLAGS
- RZ ;PMMI FALSE, RETURN
- XRA A ; 0
- STA CRFLAG ;CONTINUOUS REDIAL FLAG
- CALL DIALPL0 ; DISCONNECT, RECONNECT, WAIT DIAL TONE
- JC DILAGN ;ASK IF TRY AGAIN
- LXI H,CMDBUF+1 ;POINT # OF CHARS IN BUFF
- MOV A,M ;GET # OF CHARS
- CPI 4 ;4 OR MORE CHARS TYPED BEFORE <CR>?
- JC ENTNUM ;NO, ASK FOR NUMBER
- LXI H,CMDBUF+6 ;POINT TO NUMBER TO DIAL
- JMP DIAL10 ;CHECK IF LIB #, & DIAL
-
- DIALPL0:
- CALL DISCONNT
- CALL ILPRT
- DB CR,LF,'Waiting for dial tone',CR,LF,0
-
- MVI A,MAKEM ;MAKE MAKE (OFF-HOOK)
- CALL OUT$MODCTLP ;DO IT
- MVI D,DTMSK ;DIAL TONE MASK
- MVI C,100 ;10 SECOND WAIT
- CALL WAIT ;WAIT FOR DIAL TONE
- NOP ;DELAY
-
- ; WAIT SUBROUTINE WILL RETURN WITH CARRY SET IF UNABLE TO
- ; GET DIALTONE, ELSE CARRY NOT SET MEANS DIALTONE RECEIVED
-
- RNC ;IF DIAL TONE WITHIN 10 SECONDS
- CALL ILPRT ;ELSE, MESSAGE AND RETURN WITH CARRY SET
- DB CR,LF
- DB '++No dial tone after 10 seconds++',CR,LF,0
- STC
- RET
-
- ENTNUM: ;this is all the set-up for the print at entnum2.
- MVI C,13 ;number of lines to move
- LXI H,NUMBLIB ;address of source memory
- LXI D,DBUF ;address of target memory
- CALL NEWLINE ;start with CRLF
- STAX D ;+LF
- INX D ;and bump it
-
- ENTNUM1:
- MVI B,30 ;number of bytes to move
- CALL MOVE ;move to buffer
- CALL SPACES ;2 entries + 3 spaces = 63 characters
- MVI B,30
- CALL MOVE
- CALL NEWLINE
- DCR C ;number of lines to print
- JZ ENTNUM2
- JMP ENTNUM1
-
- NEWLINE: ;puts CR-LF at memory pointed by DE
- MVI A,CR ;CR
- STAX D ;store it
- MVI A,LF ;LF
- INX D ;bump pointer
- STAX D ;store LF
- INX D ;bump pointer
- RET
-
- SPACES:
- MVI A,20H ;space
- STAX D ! INX D ; 1
- STAX D ! INX D ; 2
- STAX D ! INX D ; 3
- RET
-
- ENTNUM2:
- MVI A,'$'
- STAX D
- MVI C,PRINT
- LXI D,DBUF ;point to table of numbers to print
- CALL BDOS
- CALL CRLF
-
- CALL ILPRT
- DB 'Enter number or library letter - Type C/R when finished,',CR,LF
- DB 'CTRL-X cancels while dialing: ',0
-
- LXI D,CMDBUF
- CALL INBUFF
-
- DIALLP1:
- LDA CMDBUF+1
- ORA A ;NULL MEANS <CR> WAS TYPED
- JZ BORTIT ;ABORT DIALING, RETURN TO MENU
-
- LXI H,CMDBUF+2 ;FIRST TYPED CHAR OF NUMBER TO DIAL
- ;
- ; ENTER THIS ROUTINE WITH HL POINTING TO NUMBER TO DIAL
- ;
- DIAL10:
- MVI B,'A' ;FIRST LETTER OF ALPHABET
- MVI E,0 ;COUNTS NUMBER OF LETTERS TO MATCH
- MVI C,26 ;NUMBER OF LETTERS IN ALPHABET
- MOV A,M ;GET CHAR BUFFER
- DIAL11:
- CMP B ;NUMBER FROM TABLE?
- JZ LIBSET
- INR B ;MAKE NEXT LETTER (A-Z)
- INR E ;COUNT UP
- DCR C ;COUNT DOWN
- JZ DIALLPX ;NOT A LETTER
- JMP DIAL11 ;LOOP
-
- LIBSET:
- LXI H,NUMBLIB ;PHONE NUMBER LIBRARY
- LXI B,30 ;LENGTH OF LIBRARY ENTRY
- MOV A,E ;NUMBER OF TIMES TO ADD 30 TO HL
- ORA A ;SET FLAGS
- JZ DIAL13
-
- DIAL12:
- MOV A,M ;GET FIRST CHAR OF SELECTED LIB ENTRY
- ORA A ;SET FLAGS
- JZ DIALLP2 ;SEND BADLIB MSG
- DAD B ;INCREMENT HL BY 30
- DCR E ;COUNTDOWN
- JNZ DIAL12 ;NOT THERE YET, LOOP
-
- DIAL13:
- MVI B,30 ;NUMBER OF CHARACTERS TO GET FROM TABLE
- LXI D,CMDBUF+1 ;POINT TO BUFFER
- XCHG ;HL POINTS TO CMDBUF+1
- MOV M,B ;STORE # OF BYTES IN A TABLE ENTRY
- XCHG ;RESTORE REG.
- INX D ;POINT TO FIRST CHAR POSITION IN BUFFER
- CALL MOVE ;MOVE TABLE ENTRY TO BUFFER
-
- DIALLPX:
- LDA CMDBUF+1
- MOV E,A ;NUMBER OF CHARS IN BUFF
- LXI H,CMDBUF+2 ;POINT FIRST CHAR
-
- DIALLP2:
- MOV A,M ;GET FIRST # FROM BUFFER
- ;
- ; ROUTINE TO PRINT 'BADLIB' MESSAGE AND ABORT IF NULL ENCOUNTERED
- ;
- ORA A ;SET FLAGS
- PUSH D ;SAVE DE REGISTERS
- LXI D,BADLIB ;BAD LIBRARY NUMBER IF NULL
- MVI C,PRINT ; 9
- PUSH PSW ;SAVE A AND FLAGS
- CZ BDOS
- POP PSW ;RESTORE A AND FLAGS
- POP D ;RESTORE DE REGISTERS
- JZ BORTIT ;ABORT
- ;
- ; DIAL A DIGIT, CHECK KBD FOR ABORT
- ;
- CALL DIAL ;DIAL IT
- CALL STAT ; KEYPRESS?
- ORA A ;SET FLAGS
- CNZ KEYIN ;YES, GO GET IT
- CPI CAN ; ^X?
- JZ BORTIT ;YES, ABORT
- INX H ;BUMP POINTER
- PUSH D ;SAVE DE
- PUSH H ;SAVE HL
- MVI B,1 ;WAIT 1 TIME INTERVAL
- CALL TIMER
- POP H ;RESTORE HL
- POP D ;RESTORE DE
- DCR E ;COUNT DOWN CHARS IN BUFF
- JNZ DIALLP2 ;NOT DONE, LOOP
- JZ DIALDN ;DIALING DONE
-
- DISCONNT:
- XRA A ;0
- CALL OUT$MODCTL2 ;CLEAR DAV, ESD, ETC
- CALL OUT$MODCTLP ;HANG-UP
- PUSH B
- MVI B,8 ;wait for PMMI to disconnect
- CALL TIMER
- POP B
- RET
-
- TIMER: MVI A,TRATE ;TRATE 250, VALUE FOR .1 SEC INTERVAL
- CALL OUT$BAUDRP ;B-REG CONTAINS NUMBER OF .1 SEC INTERVALS
- TIMES: CALL IN$BAUDRP ;TO COUNT
- ANI TMPUL
- JZ TIMES ;WAIT FOR TIMER TO GO HIGH
- TIMEE: CALL IN$BAUDRP
- ANI TMPUL
- JNZ TIMEE ;WAIT FOR TIMER TO GO LOW
- DCR B
- JNZ TIMES
- RET
-
- BORTIT: CALL DISCONNT
- JMP MENU
-
- ;AUTO DIALER
-
- DIAL: CALL TYPE ;PRINT WHATEVER CHARACTER, DASHES, ETC.
- CPI 30H
- RC ;DIGIT MUST BE AT LEAST 0..
- CPI 'R' ;COULD IT BE A RINGBACK CHARACTER
- JNZ DIAL1 ;NO? - JUMP
- PUSH PSW ;SAVE ACCUMULATOR & FLAGS
- MOV A,E ;GET # OF CHAR LEFT INTO ACC.
- CPI 01H ;IS THIS THE LAST CHARACTER?
- JZ RINGBK ;IF SO, IT MUST BE RINGBACK CHAR - DO RINGBACK
- POP PSW ;EVERYTHING BACK AS IT WAS
- DIAL1: CPI 3AH
- RNC ;..AND NOT MORE THAN 9
- ANI 0FH ;STRIP ASCII -- COULD ALSO DO SUI 30H ('0')
- JNZ DIALS
- MVI A,10 ;CONVERT ZERO TO 10 PULSES
- DIALS: MOV C,A
- LDA PULSERATE ;CONTAINS VALUE FOR DIAL SPEED
- CALL OUT$BAUDRP
- DIALC: CALL IN$BAUDRP
- ANI TMPUL
- JNZ DIALC
- DIALB: CALL IN$BAUDRP
- ANI TMPUL
- JZ DIALB
- MAKEP: MVI A,MAKEM
- CALL OUT$MODCTLP
- TIMEM: CALL IN$BAUDRP
- ANI TMPUL
- JNZ TIMEM
- MVI A,BRKM
- CALL OUT$MODCTLP
- TIMEB: CALL IN$BAUDRP
- ANI TMPUL
- JZ TIMEB
- DCR C
- JNZ MAKEP
- MVI A,MAKEM
- CALL OUT$MODCTLP
- MVI B,2
- CALL TIMER
- RET
-
- RINGBK: POP PSW ;TO GET IT OFF THE STACK
- LDA CMDBUF+1 ;GET # OF CHAR IN BUFFER
- SUI 01 ;SUBTRACT 1 TO AVOID THE RINGBACK CHAR
- STA CMDBUF+1 ;STORE THE NEW VALUE
- MVI D,DTMSK ;LOAD TONE DETECT MASK
- MVI C,RBLMT ;SET TIMER FOR RBLMT NUMBER OF SECONDS
- CALL WAIT
- JC RBTIME ;JUMP IF NO RING DETECTED
- MVI B,25 ;WAIT 2.5 SEC
- CALL TIMER
- CALL IN$BAUDRP ;IS TONE STILL PRESENT?
- ANA D
- JNZ RNGBK1
- JMP DILAGN ;YES, MUST BE BUSY
-
- RNGBK1: CALL HANGP ;HANG UP THE PHONE
- MVI B,RBWAIT ;WAIT X SEC
- CALL TIMER
- CALL DIALPL0 ;GO OFF HOOK & LISTEN FOR DIAL TONE
- JNC DIALLPX ;GO REDIAL NUMBER
- JMP DILAGN ;NO DIAL TONE HEARD
-
- RBTIME: CALL CRLF
- JMP RNGBK1 ;HANGUP, REDIAL, & LISTEN FOR CARRIER
-
-
- ;TIME OUT ROUTINE. MUST BE CALLED WITH MASK IN D REG FOR INPUT
- ;AT RELATIVE PORT 2 AND NUMBER OF SECONDS * 10 IN C REG.
-
- WAIT: MVI B,1
- CALL TIMER ;WAIT FOR TIMER TO GO HIGH THEN LOW
- CALL IN$BAUDRP ;PMMIADDR+2 (MODEM STATUS PORT)
- ANA D ;(CTS or DIALTONE MASK)
- RZ ;ACTIVE LOW, SO RETURN ON 0
- PUSH B ;SAVE..
- PUSH D ;..ACTIVE REG'S
- CALL STAT ;KEYPRESS?
- ORA A ;SET FLAGS
- CNZ KEYIN ;YES, GET CHAR
- CPI CAN ;^X?
- JZ WAIT1 ;YES, DISCONNECT, JMP TO MENU
- POP D ;RESTORE..
- POP B ;..REGS
- DCR C ;COUNT-DOWN
- JNZ WAIT
- STC ;SET CARRY TO INDICATE MASK NOT SET
- RET
-
- WAIT1:
- POP D ;RESET..
- POP B ;..STACK
- JMP DISCON1 ;DISCONNECT
-
- HANGP: MVI A,CLEAR
- CALL OUT$MODCTL2
- MVI A,0
- CALL OUT$MODCTLP
- RET
-
- DIALDN: CALL CRLF
- MVI A,07FH ;TURN ON DTR
- CALL OUT$MODCTL2 ;TIMER RATE?
-
- MVI B,1
- CALL TIMER ;WAIT FOR MODEM TO TURN ON DTR
-
- MVI A,5DH ;2 STOP BITS, NO PARITY, 8 DATA BITS
- ;+ NO DISCONNECT AFTER 17 SECS
- CALL OUT$MODCTLP
-
- MVI D,4 ;CLEAR TO SEND MASK
- MVI C,WAITCTS ;wait time for cts (25.5 SEC MAX)
- CALL WAIT
-
- JNC CONMADE ;CONNECTION MADE
-
- CALL DISCONNT
- DILAGN:
- LDA CRFLAG ;CONTINUOUS REDIAL FLAG
- ORA A
- JNZ DILAGN0
- CALL ILPRT
- DB CR,LF,'No answer after time-out. Redial? (Y/N/C): ',BELL,0
- CALL KEYIN ;GET RESPONSE
- CALL TYPE ;ECHO IT
- CALL UCASE ;ANI 5FH
- CALL CRLF ;NEW LINE
- CPI 'N' ;REDIAL?
- JZ MENU ;NO, GO MENU
- CPI 'Y' ;REDIAL?
- JZ DILAGN0 ;YES, REDIAL
- CPI 'C' ;CONTINUOUS REDIAL?
- JNZ DILAGN ;INVALID RESPONSE, ASK AGAIN
- XRA A ! CMA ;0FFH
- STA CRFLAG ;CONTINUOUS REDIAL FLAG
- DILAGN0:
- MVI B,50 ;5 seconds wait for pmmi reset
- CALL TIMER ;else busy tone may be sensed as dialtone
- CALL DIALPL0 ;WAIT FOR DIAL TONE
- JNC DIALLP1 ;DIAL NUMBER
- JMP DILAGN ;NO DIAL TONE AFTER 10 SECS
-
- CONMADE:
- CALL ILPRT
- DB CR,LF,'Connection established - Select options: ',BELL,0
- DILAGN1:
- CALL STAT ;KEYPRESS?
- ORA A ;SET FLAGS
- JNZ GETCMD ;KEY PRESSED, GO GET OPTIONS
- MVI A,BELL
- CALL TYPE ;RING BELL
- LXI B,2000H
- DILAGN2: ;@7.32.........
- DCR C
- JNZ DILAGN2 ;KILL SOME TIME FOR TERMINAL TO PROCESS BELL
- DCR B
- JNZ DILAGN2 ;@7.32.........
- JMP DILAGN1 ;LOOP
-
-
- ;INITIALIZES CP/M FILE CONTROL BLOCKS AT 5CH AND 6CH
- SETFCB: LXI D,CMDBUF
- LXI H,FCB
- CALL CPMLINE
- CALL PROCOPT
-
- CHECKNM:
- LDA FCB+1 ;CHECK ON THE PRIMARY OPTION
- CPI 'E' ;RETURN IF ECHO OPTION
- RZ
- CPI 'M' ;RETURN TO MENU
- RZ
- MOV B,A
- LDA PMMIBYTE
- ORA A
- MOV A,B
- JZ S4
- CPI 'C'
- RZ
- S4: CPI 'T'
- JZ TERMSEL
- CPI 'S'
- JZ CKFILE
- CPI 'R'
- JNZ BDOPT
- LDA BATCHFLG ;IF MULT FILE MODE, THEN..
- ORA A ;..RECV OPT DOES NOT NEED..
- RZ ;..NAME.
- JMP CKFILE
- BDOPT: CALL ILPRT
- DB CR,LF,'++Bad Option++',CR,LF,0
- JMP REENT
- CKFILE: LDA FCB+17 ;IF OPTION THAT NEEDS FILE NAME,..
- CPI ' ' ;..THEN CHECK TO SEE IF NAME..
- RNZ ;..EXISTS. IF NOT..
- REENT: CALL ILPRT ;..DO EVERYTHING OVER.
- DB CR,LF,'Re-enter PRIMARY option and file name only: ',BELL,0
- LXI D,CMDBUF
- CALL INBUFF
- JMP SETFCB
-
- TERMSEL:
- LDA FCB+17
- CPI ' '
- JNZ SAVAGN
- MVI A,FALSE
- STA SAVEFLG
- MVI A,TRUE
- STA NFILFLG
- CMA
- OUT FRONTPAN
- RET
- SAVAGN:
- MVI A,FALSE
- STA NFILFLG
- RET
-
- NEWBAUD:
- LDA PMMIBYTE
- ORA A
- RZ
- CALL ILPRT
- DB CR,LF,'Enter New Baudrate: ',0 ; @7.61
- LXI H,FCB+9
- MVI M,0 ;PUTS A ZERO IN FIRST POSITION SO AS TO
- LOOP5: CALL KEYIN ;FORCE THE DEFAULT OPTION OF 300 BAUD.
- CPI CR ;CARRIAGE RET ENTERS BAUD RATE
- JNZ CONNEWB ;GOES TO THE ESTABLISHED ROUTINE - RETURN TO MAIN
- CALL CRLF ;PROGRAM IS DONE THERE.
- JMP SETBAUD
- CONNEWB:
- CPI 30H ;MAKE SURE IT'S..
- JC LOOP5 ;..A DIGIT, ELSE..
- CPI 3AH ;..DON'T ACCEPT IT.
- JNC LOOP5
- MOV M,A
- MOV C,A
- CALL TYPE ;ECHO THE CHARACTER ENTERED
- INX H
- JMP LOOP5
- ;
- ;****************************************************************
- ;* CRCSUBS (Cyclic Redundancy Code Subroutines) version 1.20 *
- ;* 8080 Mnemonics *
- ;* *
- ;* These subroutines will compute and check a true 16-bit *
- ;* Cyclic Redundancy Code for a message of arbitrary length. *
- ;* *
- ;* The use of this scheme will guarantee detection of all *
- ;* single and double bit errors, all errors with an odd *
- ;* number of error bits, all burst errors of length 16 or *
- ;* less, 99.9969% of all 17-bit error bursts, and 99.9984% *
- ;* of all possible longer error bursts. (Ref: Computer *
- ;* Networks, Andrew S. Tanenbaum, Prentiss-Hall, 1981) *
- ;* *
- ;* Designed & coded by Paul Hansknecht, June 13, 1981 *
- ;* *
- ;* Copyright (c) 1981, Carpenter Associates *
- ;* Box 451 *
- ;* Bloomfield Hills, MI 48013 *
- ;* 313/855-3074 *
- ;* *
- ;* This program may be freely reproduced for non-profit use. *
- ;* *
- ;****************************************************************
- ;
- ; ENTRY CLRCRC,UPDCRC,FINCRC,CHKCRC
- ;
- CLRCRC: EQU $ ;Reset CRC Accumulator for a new message.
- PUSH H
- LXI H,0
- SHLD CRCVAL
- POP H
- RET
- ;
- UPDCRC: EQU $ ;Update CRC Accumulator using byte in (A).
- PUSH PSW
- PUSH B
- PUSH H
- MVI B,8
- MOV C,A
- LHLD CRCVAL
- ;
- UPDLOOP: MOV A,C
- RLC
- MOV C,A
- MOV A,L
- RAL
- MOV L,A
- MOV A,H
- RAL
- MOV H,A
- JNC SKIPIT
- MOV A,H ;The generator is X^16 + X^12 + X^5 + 1
- XRI 10H ;as recommended by CCITT.
- MOV H,A ;An alternate generator which is often
- MOV A,L ;used in synchronous transmission protocols
- XRI 21H ;is X^16 + X^15 + X^2 + 1. This may be
- MOV L,A ;used by substituting XOR 80H for XOR 10H
- SKIPIT: DCR B ;and XOR 05H for XOR 21H in the adjacent code.
- JNZ UPDLOOP
- SHLD CRCVAL
- POP H
- POP B
- POP PSW
- RET
- ;
- FINCRC: EQU $ ; Finish CRC calc for outbound message.
- PUSH PSW
- XRA A
- CALL UPDCRC
- CALL UPDCRC
- PUSH H
- LHLD CRCVAL
- MOV D,H
- MOV E,L
- POP H
- POP PSW
- RET
- ;
- CHKCRC: EQU $ ; Check CRC bytes of received message.
- PUSH H
- LHLD CRCVAL
- MOV A,H
- ORA L
- POP H
- RZ
- MVI A,0FFH
- RET
- ;
- CRCVAL: DW 0
- ;
- MENU: LXI H,RESTSN ;RESTORE SECTORE NUMBERS..
- LXI D,SECTNOB ;..FOR NEW FILE TRANSFER.
- MVI B,SECTNOE-SECTNOB
- CALL MOVE
- LXI H,RESTROPT ;RESTORE OPTION TABLE
- LXI D,OPTBL
- MVI B,OPTBE-OPTBL
- CALL MOVE
- MVI A,0
- STA MFFLG1 ;RESET MFACCESS ROUTINE..
- CMA ;..AND MULTI TRANS IN CASE..
- STA FSTFLG ;..OF ABORT.
-
- MENU1: LDA XPRFLG ;TEST IF MENU SHOULD BE SHOWN
- ORA A
- JNZ XPRT
- MENU2: CALL ILPRT
- DB CR,LF,CR,LF
- DB 'WRT - Write file to disk (from terminal mode)',CR,LF
- DB 'DEL - Erase present file (from terminal mode)',CR,LF
- DB 'RET - Return to terminal mode with no loss of data',CR,LF,0
- LDA PMMIBYTE
- ORA A
- JZ S5
- CALL ILPRT
- DB 'DSC - Disconnect',CR,LF
- DB 'BYE - Disconnect and reboot',CR,LF
- DB 'CAL - Dial number',CR,LF,0
- S5: CALL ILPRT
- DB 'XPR - Toggle expert mode (Menu on/off)',CR,LF
- DB 'DIR - List directory (may specify drive)',CR,LF
- DB 'CPM - Exit to CP/M',CR,LF
- DB 'S - Send CP/M file',CR,LF
- DB 'R - Receive CP/M file',CR,LF
- DB 'T - Terminal mode (optional file name)',CR,LF
- DB 'E - Terminal mode with echo',CR,LF,0
- XPRT: CALL ILPRT
- DB CR,LF,CR,LF,'DEFAULT DRIVE: ',0
- MVI C,25 ;CURRENT DISK FUNCTION
- CALL BDOS
- ADI 41H ;MAKE ASCII
- CALL TYPE
- CALL ILPRT
- DB CR,LF,CR,LF,'Command: '
- DB 0
-
- GETCMD: LXI D,CMDBUF ;ENTER COMMAND
- CALL INBUFF
- CALL CRLF
- LXI D,CMDBUF+2 ;POINT TO COMMAND
- CALL ILCOMP
- DB 'CPM',0
- JNC EXIT
- CALL ILCOMP
- DB 'DIR',0
- JNC DIR
- CALL ILCOMP
- DB 'RET',0
- JC NXTOPT1 ;CARRY SET = NO MATCH
- lda origsav ;@MODEM75.FIX
- sta origflg ;@MODEM75.FIX
- LHLD HLSAVE ;RETURN TO TERMINAL..
- JMP TERM ;..MODE WITH SAVE OPTION..
- ;..IF PREVIOUSLY ENABLED.
- NXTOPT1:
- LDA PMMIBYTE
- ORA A
- JZ S6
- CALL ILCOMP ;DE SET FROM 1ST ILCOMP CALL
- DB 'DSC',0
- JNC DISCON1
- CALL ILCOMP
- DB 'BYE',0 ;@7.63
- JNC BYEBYE
- S6: CALL ILCOMP
- DB 'WRT',0
- JNC WRTFIL
- CALL ILCOMP
- DB 'XPR',0
- JNC XPRMODE
- CALL ILCOMP
- DB 'DEL',0
- JNC NEWFILE
- LDA PMMIBYTE
- ORA A
- JZ NXTOPT2
- CALL ILCOMP
- DB 'CAL',0
- JC NXTOPT2
- MVI A,20H ;FOOL THE SYSTEM'''
- STA CMDBUF+4 ;..CMDBUF SO THAT IT..
- JMP DOOPT ;..LOOKS AT OPTION FOR DIAL
-
- NXTOPT2:
- PUSH H
- LDA CMDBUF+2
- LXI H,COMPLIST
- CALL COMPARE ;COMPARES LIST POINTED TO BY HL..
- POP H ;..TO CHAR IN A-REG.
- JC MENU1 ;CARRY SET = NO MATCH
-
- DOOPT: PUSH H ;LOAD ORIGINAL FCB WITH TRANSFER..
- CALL SETFCB ;..CMDS AND GO TO BEGINNING OF..
- POP H ;..PROGRAM. WILL FOLLOW SAME LOGIC..
- JMP RESTART ;..AS IF PROGRAM WERE CALLED WITH..
- ;..CP/M COMMAND LINE.
-
- DISCON1:
- LDA PMMIBYTE
- ORA A
- JZ MENU
- CALL DISCONNT
- CALL ILPRT
- DB CR,LF,'++Disconnected++',CR,LF,BELL,0
- JMP MENU
-
- BYEBYE: LDA PMMIBYTE ;@7.63
- ORA A
- JZ MENU
- CALL ILPRT
- DB CR,LF,'Goodbye, happy up/down loading',CR,LF,0
- XRA A
- OUT MODCTLP
- OUT MODCTL2
- LHLD CLDBOOT ;GET COLD BOOT PROM ADDRESS ;@7.63
- PCHL ;JUMP TO IT
-
- DIR: CALL DIRLST
- JMP XPRT
-
- NEWFILE:
- LDA FCB3+1
- CPI ' '
- JZ MENU1 ;IF NO FILE, DON'T ERASE
- LXI D,FCB3
- MVI C,ERASE
- CALL BDOSRT
- MVI A,TRUE ;DO NOT ALLOW TERMINAL..
- STA NFILFLG ;..SAVE SINCE NO FILE..
- CMA ;..SPECIFIED.
- STA SAVEFLG
- OUT FRONTPAN
- LXI H,FCB3
- CALL INITFCBS
- JMP MENU1
-
- WRTFIL:
- LDA NFILFLG
- CPI TRUE
- JZ MENU1
- LDA FCB3+1 ;CHECK THAT FILE WAS REQUESTED
- CPI ' '
- JZ MENU1
- LHLD HLSAVE
- CALL NUMRECS ;DISK WRITE ROUTINE AS USED IN..
- CALL WRTDSK ;..IN THE INTDSKSV ROUTINE.
- CALL CLOSE3
- MVI A,TRUE
- STA NFILFLG
- CMA
- STA SAVEFLG
- OUT FRONTPAN
- LXI H,FCB3
- CALL INITFCBS ;BLANK OUT FCB SO WRITTEN FILE..
- JMP MENU1 ;..CAN'T BE ERASED.
-
- XPRMODE:
- LDA XPRFLG
- CMA
- STA XPRFLG
- JMP MENU1
-
-
- COMPARE:
- MOV B,M ;COMPARES A-REG WITH LIST..
- COMPLP: INX H ;..ADDRESSED BY HL. FIRST ELEMENT..
- CMP M ;..OF LIST MUST BE NUMBER OF ELEMENTS..
- JZ VALID ;..BEING COMPARED. RETURNS WITH..
- DCR B ;..CARRY SET IF A-REG DOES NOT..
- JNZ COMPLP ;.. CONTAIN AN ELEMENT IN LIST.
- STC
- VALID: RET
-
- COMPLIST: DB 5, 'S', 'R', 'T', 'E', 'M'
-
- ILCOMP: INLNCOMP ;A MACRO IN MODEM.LIB
-
-
- INBUFF: INBUF ;A MACRO IN "MODEM.LIB"
-
- ;IF ABOVE ROUTINE DOES NOT LET YOU EDIT IN A PROPER MANNER,
- ;THEN THE MACRO MAY BE SUBSTITUTED FOR THE FOLLOWING ROUTINE:
-
- ;INBUFF:
- ; MVI C,RDBUF
- ; CALL BDOSRT
- ; RET ;BUT BE CAREFUL OF CONTROL-C
-
-
- CPMLINE:
- CMDLINE ;A MACRO IN "MODEM.LIB"
-
- DIRLST: DIRLIST ;A MACRO IN "MODEM.LIB"
-
- NFILFLG:
- DB FALSE ;NORMALLY SET TO FALSE. ALLOWS WRITE TO..
- ;..MEMORY IN TERMINAL MODE.
-
- OPTION: DB 0
-
- OPTBL: EQU $
- ANSWFLG:
- DB 'A'
- DISCFLG:
- DB 'D'
- ORIGFLG:
- DB 'O'
- QFLG: DB 'Q'
- RSEEFLG:
- DB 'R'
- SSEEFLG:
- DB 'S'
- VSEEFLG:
- DB 'V'
- TERMFLG:
- DB 'T'
- EPARITY:
- DB '0' ;EVEN PARITY SUB-OPTION - ONLY AVAILABLE IN 'S' AND 'R' MODES
- OPARITY:
- DB '1' ;ODD PARITY SUB-OPTION - ONLY AVAILABLE IN 'S' AND 'R' MODES
- BATCHFLG:
- DS 1 ;SET TO 'B' BY MENU. DOES NOT ALLOW MULTI-..
- OPTBE: EQU $ ;..FILE XFER WHEN PROGRAM INITIALLY CALLED.
-
- RESTROPT: ;MUST BE IN SAME ORDER AS TABLE ABOVE
-
- DB 'A','D','O','Q','R','S','V','T'
- DB '0','1','B'
-
- CRCFLG:
- DB 'C' ;use CRC instead of cksum ;@7.62 (moved)
-
- RESTSN: DB 0,0,0,0,0,0
- DW DBUF
- DB 0,0,0,0,0
-
- SECTNOB: EQU $
- RCVSNO: DB 0
- SECTNO: DW 0
- ERRCT: DB 0
- ERRCDE: DB 0
- EOFLG: DB 0
- SECPTR: DW DBUF
- SECINBF: DB 0
- MAXEXT: DB 0
- RCNT: DW 0
- DATAFLG: DB 0
- EXACFL: DB 0
- SECTNOE: EQU $
-
- BADOPT: CALL ILPRT
- DB 'Invalid option',CR,LF,BELL,0
- JMP MENU
-
- FSTFLG: DB TRUE
- FIRSTME:
- DB 0FFH
- ;first SOH received switch(it is zero after 1rst SOH)
-
- CMDBUF: DB 80H,0
- DS 80H
- BADLIB: DB CR,LF,'++Bad library number called++',CR,LF,'$'
- HLSAVE: DS 2
- DISKNO: DS 1
- SENDFLG:
- DS 1
- NBSAVE: DS 2
- BGNMS: DS 2
- FILECT: DS 1
- NAMECT: DS 1
- origsav: ds 1 ;@MODEM75.FIX
- MODCTLB:
- DB 07FH
- UARTFLG:DB 0FFH ; @7.61
- UARTCTLB:
- DB ANSWMOD ; @7.5 (was previously ORIGMOD)
-
- DS 100
- STACK: DS 2
- FCB3: DS 33
- FCBBUF: DS 15
- DBUF: EQU $
- NAMEBUF: EQU DBUF+(DBUFSIZ*1024)
- ;BUFFER FOR NAMES IN BATCH MODE. OVERFLOWS..
- ;..ABOVE PROGRAM CODE.
-
- ; BDOS EQUATES
- RDCON EQU 1
- WRCON EQU 2
- PRINT EQU 9
- RDBUF EQU 10
- CONST EQU 11
- OPEN EQU 15
- CLOSE EQU 16
- SRCHF EQU 17
- SRCHN EQU 18
- ERASE EQU 19
- READ EQU 20
- WRITE EQU 21
- MAKE EQU 22
- REN EQU 23
- STDMA EQU 26
- FILSIZ EQU 35
- BDOS EQU 5
- REIPL EQU 0
- FCB EQU 5CH
- FCBEXT EQU FCB+12
- FCBSNO EQU FCB+32
- FCBRNO EQU FCB+32
- FCB2 EQU 6CH
-
- LAST END 100H
-
-