home *** CD-ROM | disk | FTP | other *** search
- TITLE 'CP/M MODEM PROGRAM Version 7.98 12/31/82'
- ;
- ;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 S *********
- ;
- ; Revisers releasing new versions should only
- ; change the version number by 1 digit in the
- ; last place.
- ;
- ; Except for PMMI routines, revisers should
- ; only make nonspecialized changes for
- ; distribution. Please make configuration files,
- ; such as MCNFG7xx.ASM and MCOSB7xx.ASM, for
- ; particular computers, uarts or modems.
- ;
- ; **********************************
- ;
- ;##### This file requires MODEM797.LIB and MAC.COM to assemble. #####
- ;
- ;##### The file MCNFG797.ASM can be used to overlay the HEX #####
- ;##### or COM file versions with your own modem routines and #####
- ;##### configuration options. The file MODEM797.SET can be used #####
- ;##### as a reference for directly setting the modem equates #####
- ;##### and configuration options with the S command in DDT. #####
- ;
- ;Fix log in MODEM797.HIS
- ;
- ;
- MACLIB MODEM797 ;Contains the CMDLINE, INBUF, INLNCOMP,
- ;DIRLIST, SENDTIME, PRTBAUD, and MFACCESS
- ;routines.
- ;
- ;Note that the library has not been changed since version 7.97.
- ;
- ;
- 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
- ;
- 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
- ;
- ; PMMI EQUATES
- PORT EQU 0C0H ;PMMI BASE ADDRESS
- ;
- MODCTLP EQU PORT ;MODEM CONTROL PORT
- MODDATP EQU PORT+1 ;MODEM DATA PORT
- BAUDRP EQU PORT+2 ;BAUD RATE PORT
- MODCTL2 EQU PORT+3 ;2ND MODEM CONTROL PORT
- MODRCVB EQU 02H ;MODEM RECEIVE BIT (DAV)
- MODRCVR EQU 02H ;MODEM RECEIVE READY
- MODSNDB EQU 01H ;MODEM SEND BIT (XMIT BUFF EMPTY)
- MODSNDR EQU 01H ;MODEM SEND READY
- NOPARMSK EQU 10H ;MASK TO RESET TO NO PARITY
- EVPARMSK EQU 20H ;MASK TO SET EVEN PARITY
- ODPARMSK EQU 0CFH ;MASK TO SET ODD PARITY
- BRKMSK EQU 0FBH ;MASK TO SET BREAK
- ERRCDMSK EQU 38H ;MASK TO BLOCK ALL BITS EXCEPT ERROR CODES
- FRMER EQU 20H ;FRAMING ERROR MASK
- ORUNER EQU 10H ;OVERRUN ERROR MASK
- PARER EQU 08H ;PARITY ERROR MASK
- ANSWMOD EQU 1EH ;ANSWER MODE
- ORIGMOD EQU 1DH ;ORIGINATE MODE
- WAITCTS EQU 255 ;NUMBER OF SECONDS X 10 TO WAIT FOR COMPUTER
- ;TONE AFTER PMMI AUTO-DIAL FUNCTION 255 MAX.
- ;
- 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
- 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
- BDNMCH EQU 75H ; BAD NAME MATCH
- RUB EQU 7FH ; RUB
- ;
- BOTTRAM SET LAST+100H AND 0FF00H
- ;
- ORG 0100H
- ;
- JMP START
- ;
- ;THESE ROUTINES AND EQUATES ARE AT THE BEGINNING OF THE PROGRAM SO
- ;THEY CAN BE PATCHED BY A MONITOR OR OVERLAY FILE WITHOUT RE-ASSEMBLING
- ;THE PROGRAM.
- ;
- PMMIBYTE: DB TRUE ;true=PMMI modem
- SETUPTST: DB FALSE ;true=non-PMMI setup routine
- SCRNTEST: DB FALSE ;true=if home cursor and clear screen
- ;routine at CLRSCRN
- CLOCK: DB 4 ;clock speed in MHz, 8 MHz maximum
- BAKUPBYTE: DB FALSE ;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 FALSE ;true=add LF after CR
- TOGGLELF: DB TRUE ;true=allow toggling of LF after CR
- TRANLOGON: DB FALSE ;true=allow transmission of logon
- ;write logon sequence at location LOGON
- SAVCCP: DB TRUE ;true=do not overwrite CCP
- 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
- MSPEED: DB 1 ;sets the display time to send a file
- ;0=110 1=300 2=450 3=600 4=710 5=1200
- ;6=2400 7=4800 8=9600
- 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 30 ;bell repeat time = value*0.03 sec
- 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
- ;
- ;Equates used only by PMMI routines grouped together here.
- PULSERATE: DB 125 ;125 for 20pps, 250 for 10pps on PMMI
- ;not used if PMMI FALSE
- CLDBOOT: DW 00000H ;currently set to warm boot with
- ;BYE routine for PMMI, put your cold
- ;boot entry here if you have one and
- ;desire to do on BYE
- BRKCHR: DB '@'-40H ; ^@ = Transmit "BREAK" with PMMI
- CHGBAUD: DB 'B'-40H ; ^B = Used with PMMI in terminal
- ; mode to change baud rate on fly
- DISCCHR: DB 'D'-40H ; ^D = PMMI Disconnect
- ;
- ;
- IN$MODCTLP: IN MODCTLP ! RET ;in modem control port
- OUT$MODDATP: OUT MODDATP ! RET ;out modem data port
- IN$MODDATP: IN MODDATP ! RET ;in modem data port
- ANI$MODSNDB: ANI MODSNDB ! RET ;bit to test for send ready
- CPI$MODSNDR: CPI MODSNDR ! RET ;value of send bit when ready
- ANI$MODRCVB: ANI MODRCVB ! RET ;bit to test for receive ready
- CPI$MODRCVR: CPI MODRCVR ! RET ;value of receive bit when ready
- ;
- ;THE FOLLOWING ARE TYPICALLY USED ONLY BY PMMI
- 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 ;out modem control port
- STA UARTCTLB ! RET ;and store control byte
- ;
- LOGONPTR: DW LOGON
- JMP$INITMOD: JMP INITMOD
- JMP$SETUPR: JMP SETUPR
- ;Clear sequences are for H19. Change to yours.
- CLREOS: CALL JMP$ILPRT
- DB ESC,'J',0,0,0
- RET
- CLRSCRN: CALL JMP$ILPRT
- DB ESC,'E',0,0,0
- RET
- ;
- ;NEXT THREE LINES SHOULD NOT BE CHANGED BY USER OVERLAY
- JMP$ILPRT: JMP ILPRT
- JMP$ILCOMP: JMP ILCOMP
- JMP$INBUFF: JMP INBUFF
- JMP$SYSVER: JMP SYSVER
- JMP$DIALPL: JMP DIALPL
- JMP$DISCONNT: JMP DISCONNT
- ;
- SYSVER:
- LDA PMMIBYTE ;USING THE PMMI S-100 MODEM?
- ORA A
- JZ SYSVER1 ;GO IF NOT
- CALL ILPRT
- DB 'Version for: PMMI S-100 MODEM Starting at Port ',0
- LDA IN$MODCTLP+1
- CALL HEXO
- CALL ILPRT
- DB 'H',CR,LF,0
- RET
- ;
- SYSVER1:
- CALL ILPRT ;IF NOT USING THE PMMI S-100 BOARD
- DB 'Version for: Non-PMMI MODEM',CR,LF,0
- RET
- ;
- ;INSERT YOUR LOGON HERE, MUST END IN 0.
- LOGON: DB 0
- ;
- ;INSERT YOUR INITIALIZATION ROUTINE HERE IF NEEDED.
- ;CAN REPLACE THE FOLLOWING SECTION WHICH IS PRESENTLY
- ;USED FOR THE PMMI BOARD.
- ;
- INITMOD:
- 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
- CALL CHGMSPD
- MOV A,C
- STA MSPEED
- MOV A,B
- 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 ++$'
- ;
- CHGMSPD: ;CHANGES MSPEED FOR 110-710 BAUD
- MVI C,0 ;CONTAINS MSPEED
- MOV B,A ;SAVE BAUD RATE DIVISOR
- CPI 100 ; < 300 BAUD
- RNC
- INR C
- CPI 40 ; < 450 BAUD
- RNC
- INR C
- CPI 30 ; < 600 BAUD
- RNC
- INR C
- CPI 24 ; < 710 BAUD
- RNC
- INR C ;MUST BE 710 BAUD
- 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 HEARD 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
- DPL1: 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,'<< No dial tone >>',CR,LF,0
- CALL DISCONNT
- STC
- RET
- ;
- ;THIS IS ALL THE SET-UP FOR THE PRINT AT 'ENTNUM2'.
- ;
- ENTNUM:
- 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,32 ;NUMBER OF BYTES TO MOVE
- CALL MOVE ;MOVE TO BUFFER
- CALL SPACES ;2 ENTRIES + 3 SPACES = 67 CHARACTERS
- MVI B,32
- CALL MOVE
- CALL NEWLINE
- DCR C ;NUMBER OF LINES TO PRINT
- JZ ENTNUM2
- JMP ENTNUM1
- ;
- ENTNUM2:
- MVI A,'$'
- STAX D
- CALL CLRTST
- MVI C,PRINT
- LXI D,DBUF ;POINT TO TABLE OF NUMBERS TO PRINT
- CALL BDOS
- CALL ILPRT
- DB CR,LF,'Enter number or library letter - <CR> when finished,'
- DB CR,LF,'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:
- PUSH H ;SAVE HL
- CALL DIALPL0 ;DISCONNECT, RECONNECT, WAIT FOR DIAL TONE
- POP H ;GET HL
- JC DILAGN ;NO DIALTONE?, ASK RETRY
- 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,32 ;LENGTH OF LIBRARY ENTRY
- MOV A,E ;NUMBER OF TIMES TO ADD 32 TO HL
- ORA A ;SET FLAGS
- JZ DIAL13
- DIAL12:
- MOV A,M ;GET FIRST CHAR OF SELECTED LIB ENTRY
- ORA A ;SET FLAGS
- JZ DIALLPA ;SEND BAD LIBRARY MSG AND ABORT
- DAD B ;INCREMENT HL BY 32
- DCR E ;COUNTDOWN
- JNZ DIAL12 ;NOT THERE YET, LOOP
- DIAL13:
- MVI B,32 ;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
- ORA A ;SET FLAGS
- JNZ NOBLMSG
- ;
- ; PRINT BAD LIBRARY MESSAGE AND ABORT IF NULL ENCOUNTERED
- DIALLPA:
- CALL ILPRT
- DB CR,LF,'++ Bad library number called ++',CR,LF,0
- JMP BORTIT ;ABORT
- ;
- ; DIAL A DIGIT, CHECK KBD FOR ABORT
- ;
- NOBLMSG:
- 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
- CALL CRLF
- 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 01H ;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
- CALL OUT$MODCTLP
- MVI D,4 ;CLEAR TO SEND MASK
- MVI C,WAITCTS ;WQAIT 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,70 ;7 SECONDS WAIT FOR PMMI RESET
- CALL TIMER ;ELSE BUSY TONE MAY BE SENSED AS DIALTONE
- LXI H,CMDBUF+1 ;CHECK IF 'CAL LIBNUM'
- MOV A,M
- CPI 4 ;MORE THAN 4 CHARACTERS TYPED
- JC DIALLP1 ;NO, THEN GET MENU CHOICE
- JMP DPL1 ;YES, THEN USE CAL LETTER
- ;
- 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:
- DCR C
- JNZ DILAGN2 ;KILL SOME TIME FOR TERMINAL TO PROCESS BELL
- DCR B
- JNZ DILAGN2
- JMP DILAGN1 ;LOOP
- ;
- CRFLAG: DB 0 ;CONTINUOUS REDIAL FLAG
- ;
- ; END OF PMMI ROUTINES
- ;
- ;
- ;THE NON PMMI SETUP ROUTINES ARE INTENDED TO COME FROM
- ;THE USER OVERLAY. THE FOLLOWING IS A SAFETY NET
- ;
- SETUPR: RET
- ;
- ; PHONE NUMBER LIBRARY TABLE FOR DIALING FROM LIBRARY
- ; OF NUMBERS STORED IN THESE DB'S AT ASSEMBLY-TIME.
- ; EACH DB MUST BE 32 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-----32'
- DB 'A=Amrad 1-703-734-1387' ;'A'
- DB 'B=Ben Bronson 1-312-955-4493' ;'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= ' ;'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'
- ;
- START:
- LXI H,0
- DAD SP ;GET CP/M'S STACK
- SHLD STACK ;SAVE IT
- LXI SP,STACK ;START LOCAL STACK
- CALL ILPRT
- DB CR,LF,'MODEM 7.98 - 12/31/82',CR,LF,0
- CALL INITADR ;INITIALIZE ADDRESSES
- CALL JMP$SYSVER ;GIVE CONFIGURATION MESSAGE
- CALL GETUSR ;GET USER
- STA SAVUSR ;SAVE FOR EXIT
- MVI A,TRUE ;0FFH
- STA NFILFLG
- CMA ;0
- STA SAVEFLG
- LDA FCB+1 ;IS THERE A COMMAND TAIL?
- STA OPTION
- CPI ' '
- JNZ START0 ;IF YES, DIGEST IT
- SUB A
- STA EXITFLG ;ELSE SAY WE WANT MENU
- JMP START1
- START0:
- LXI H,80H ;SIMULATE COMMAND LINE INPUT FROM MENU
- MOV B,M ;SAVE CHAR CNT
- STARTA:
- INX H
- MOV A,M ;SKIP OVER LEADING SPACES IN COMMAND TAIL
- CPI ' '
- JNZ STARTB
- DCR B
- JMP STARTA
- STARTB:
- MOV A,B
- STA CMDBUF+1 ;STORE COMMAND CHAR COUNT LESS LEADING SPACES
- INR B ;MOVE 1 EXTRA BYTE (SHOULD BE A NULL)
- LXI D,CMDBUF+2
- CALL MOVE
- CALL SETFCB ;DIGEST COMMAND LINE AND OPTIONS
- START1:
- LDA UARTFLG
- ORA A
- MVI A,ANSWMOD
- STA UARTCTLB
- JNZ RESTART
- MVI A,ORIGMOD
- STA UARTCTLB
- ;
- RESTART:
- LXI SP,STACK;MAKE SURE WE HAVE A CLEAN STACK
- LXI D,CMDBUF+1 ;MAY BE USEFUL WHERE WE ARE GOING
- 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 JMP$DIALPL ;YES, GO TO IT
- CPI 'D' ;DISCONNECT?
- JZ DISCON1 ;YES, DISCONNECT & GO MENU
- S1: CPI ' ' ;NO OPTION SPEC'D?
- JZ MENU ;TRUE, GO MENU
- CPI 'H' ;MENU ASKED FOR?
- JZ MENU2 ;YES, GO MENU2
- CALL JMP$INITMOD
- CALL MOVEFCB
- CALL IN$MODDATP ;GOBBLE UP GARBAGE..
- CALL IN$MODDATP ;..CHARACTERS ON LINE
- XRA A
- STA ECHOFLG ;RESET ECHO FLAG
- STA LOCFLG ;RESET LOCAL FLAG
- LDA OPTION ;PROCESS MAIN OPTION
- CPI 'E' ;ECHO MODE?
- JNZ NOECH ;JUMP IF NOT
- MVI A,TRUE ;SET ECHO TO TRUE
- STA ECHOFLG
- JMP DSKSAVE
- NOECH: CPI 'L' ;LOCAL ECHO MODE
- JNZ NOLOC
- MVI A,TRUE
- STA LOCFLG
- JMP DSKSAVE
- NOLOC: CPI 'T' ;TERMINAL MODE?
- JZ DSKSAVE ;YES
- CPI 'S' ;SEND A FILE?
- JZ SENDFIL ;YES
- CPI 'R' ;RECEIVE A FILE?
- JZ RCVFIL ;YES
- CALL NOTVLDMSG ;SAY NOT A VALID OPTION
- JMP MENU ;NO VALID OPTION SPEC'D, GO MENU
- ;
- ;REVISED TERMINAL ROUTINE ALLOWING MEMORY SAVE
- ;
- DSKSAVE:
- LDA FCB+1 ;FIRST CHAR OF FILENAME
- CPI ' ' ;FILE SPEC'D
- JNZ GOODNM ;YES, GOOD NAME
- MVI A,TRUE ;0FFH
- STA NFILFLG
- 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
- XRA A
- STA NFILFLG
- STA LISTMOR ;STOP ANY BUFFERED PRINTER OUTPUT
- TERM: LDA UARTFLG
- STA ORIGSAV
- ORA A
- MVI A,ANSWMOD
- STA UARTCTLB
- JNZ TERM2
- MVI A,ORIGMOD
- STA UARTCTLB
- TERM2: LDA LISTMOR ;ANY BUFFERED PRINTER OUTPUT?
- ORA A
- CNZ GOLIST ;GO IF SO
- CALL STAT ;KEYPRESS?
- JZ TERML ;NO, CHECK LINE
- CALL KEYIN ;GET CHAR FROM KBD
- CPI ' '
- JNC NOTOG ;GO IF NOT CONTROL CHARACTER
- MOV B,A ;SAVE
- CPI BKSP ;TEST FOR BACKSPACE
- JNZ NOBKSP
- LDA CONVBKSP ;CONVERT BACKSPACE TO RUB?
- ORA A
- JZ NOBKSP ;GO IF NO CONVERSION
- MVI A,RUB
- JMP NOTOG
- NOBKSP: LDA EXACFLG
- ORA A ;EXACT?
- MVI A,0
- STA EXACFLG ;CLR FOR NEXT TIME
- JZ NOTEXAFLG ;GO OF EXAFLG FALSE
- LDA LOCONEXTCHR
- ORA A ;SHOULD WE SEND ON EXAFLG?
- MOV A,B
- JZ NOTOG ;YES, IF LOCONEXTCHR FALSE
- LDA EXTCHR ;WE WANT TO SEND EXTCHR IN ANY CASE
- CMP B
- MOV A,B
- JZ NOTOG ;SEND IF EXTCHR
- JMP LOCCHK ;OTHERWISE DO LOCAL STUFF
- NOTEXAFLG:
- LDA EXTCHR ;TREAT NEXT CHARACTER IN SPECIAL WAY?
- CMP B
- JZ EXTFLG ;YES, SET EXAFLG FOR NEXT CHAR
- LDA LOCONEXTCHR
- ORA A ;SHOULD WE SEND IF NOT EXAFLG
- MOV A,B
- JNZ NOTOG ;YES, IF LOCONEXTCHR TRUE
- LOCCHK: LDA EXITCHR ;RETURN TO MENU?
- CMP B
- JZ EXITMEN ;YES, RETURN TO MENU
- LDA TRANCHR ;OUTPUT TEXT FILE TO REMOTE?
- CMP B
- CZ TRANSFER ;SEND-A-FILE (BLIND SEND)
- JZ TERM2 ;LOOP
- LDA TRANLOGON
- ORA A
- JZ SKPLOGON
- LDA LOGCHR ;SEND LOGON?
- CMP B
- JZ SENDLOG
- SKPLOGON:
- LDA LSTTST
- ORA A
- JZ NOLST
- LDA LSTCHR
- CMP B
- JNZ NOLST
- LDA LISTFLG
- CMA
- STA LISTFLG
- CALL CRLF
- CALL CRLF
- CALL LSTMSG
- CALL CRLF
- JMP TERML
- NOLST: LDA PMMIBYTE
- ORA A
- JZ S2
- LDA DISCCHR ;PMMI DISCONNECT?
- CMP B
- JZ DISCON1 ;YES, DISCONNECT & RETURN TO MENU
- LDA BRKCHR ;PMMI BREAK?
- CMP B
- JZ BREAK
- LDA CHGBAUD ;PMMI CHANGE BAUD?
- CMP B
- PUSH PSW
- PUSH H
- CZ NEWBAUD
- POP H
- POP PSW
- JZ TERML
- S2: LDA UNSAVECHR ;CLOSE INPUT BUFFER?
- CMP B
- JZ S2A ;IF YES, DISABLE COPY
- LDA SAVECHR ;OPEN INPUT BUFFER?
- CMP B
- MOV A,B ;RESTORE CHARACTER TYPED
- JNZ NOTOG
- LDA NFILFLG ;DO NOT ALLOW SAVE IF..
- CPI TRUE ;..THIS FLAG IS SET.
- JZ TERML
- MVI A,TRUE ;0FFH -- ALLOW COPY INTO FILE
- JMP S2B
- S2A: MVI A,FALSE ;0 -- STOP COPY INTO FILE
- S2B: STA SAVEFLG
- CALL BUFMSG
- JMP TERML
- ;
- BUFMSG: CALL ILPRT
- DB CR,LF,LF,'** Memory buffer ',0
- LDA SAVEFLG
- ORA A
- 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 IN$MODCTLP
- CALL ANI$MODSNDB
- JMP CPI$MODSNDR
- ;
- SENDLF: CALL SENDREADY
- JNZ NOLFYET ;GO IF NOT READY FOR OUTPUT YET
- MVI A,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 H
- LHLD LOGONPTR ;HL POINTS TO START OF LOGON MESSAGE
- LOGLP: CALL SENDREADY
- JNZ NOSENDLOG ;GO IF NOT READY
- MOV A,M ;GET LOGON BYTE
- INX H
- CPI 0 ;IS IT THE END?
- JZ ENDLOG ;GO IF SO
- CALL OUT$MODDATP
- JMP LOGLP
- NOSENDLOG:
- CALL EXITTEST ;TEST SO DON'T GET HUNG UP
- JNC EXITLOG ;GO IF OPERATOR WANTS EXIT
- JMP LOGLP
- ;
- ENDLOG: POP H
- JMP TERML
- ;
- EXITLOG:
- POP H
- JMP EXITMEN
- ;
- EXITTEST:
- CALL STAT ;KEYPRESS?
- JZ NOKEY
- CALL KEYIN
- MOV B,A
- LDA EXITCHR ;SEE IF OPERATOR WANTS EXIT
- CMP B
- JNZ NOKEY ;GO IF WRONG KEY
- STC
- CMC ;RESET FOR EXIT
- RET
- NOKEY: STC ;SET FOR NO KEY OR WRONG KEY
- RET
- ;
- EXTFLG: MVI A,TRUE
- STA EXACFLG
- JMP TERML
- ;
- RCVREADY:
- CALL IN$MODCTLP
- CALL ANI$MODRCVB
- JMP CPI$MODRCVR
- ;
- LSTMSG: LDA LISTFLG
- ORA A
- JZ LSTMSG2
- CALL ILPRT
- DB 'Printer is on',CR,LF,0
- RET
- LSTMSG2:
- CALL ILPRT
- DB 'Printer is off',CR,LF,0
- RET
- ;
- NOTOG: CALL OUT$MODDATP
- MOV B,A
- LDA LOCFLG
- ORA A
- JNZ LTYPE
- LDA ECHOFLG
- ORA A
- JZ CHKCR
- LTYPE: MOV A,B
- CALL TYPE
- CALL CHKSAVE ;TO STORE LOCAL IF BUFFER OPEN
- CALL CHKPRNT
- CHKCR: MVI A,CR
- CMP B
- JNZ TERML
- LDA ADDLF
- ORA A
- JZ TERML
- JMP SENDLF
- ;
- TERML: CALL RCVREADY ;TEST FOR RECEIVED CHARACTER
- JNZ TERM2
- CALL IN$MODDATP
- ANI 7FH ;STRIP PARITY
- JZ TERM2
- GIVLF: CALL TYPE
- MOV B,A
- CALL CHKSAVE
- CALL CHKPRNT
- LDA ECHOFLG
- ORA A
- JZ NOECHO
- MOV A,B
- CALL OUT$MODDATP
- NOECHO: MVI A,CR
- CMP B
- JNZ TERM2
- LDA ADDLF
- JZ TERM2
- LDA ECHOFLG
- ORA A
- JNZ SENDLF
- MVI A,LF
- JMP GIVLF
- ;
- CHKSAVE:
- LDA SAVEFLG
- ORA A
- RZ
- MOV M,B
- INX H
- SHLD HLSAVE ;MENU COMMAND DESTROYS HL-REG..
- MVI A,LF
- CMP B
- JNZ NOCOLON ;..TYPE ":" AFTER EACH LINE FEED..
- MVI A,':' ;..WHEN MEMORY SAVE ACTIVE.
- CALL TYPE
- NOCOLON:
- CALL GETMAX
- CMP H
- PUSH B
- CZ INTDSKSV
- POP B
- RET
- ;
- GETMAX: LDA SAVCCP
- ORA A
- LDA 7
- JZ SUB1
- SBI 8 ;..PAGE BELOW CCP ..
- SUB1: DCR A ;..OR BDOS HAS BEEN..
- RET ;..REACHED AND DISKSAVE IS NEEDED.
- ;
- CHKPRNT:
- LDA LISTFLG ;OUT TO PRINTER?
- ORA A
- RZ ;RETURN IF NOT
- LDA NFILFLG ;IS BUFFER USED FOR FILE?
- ORA A
- 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
- LHLD HLSAVE1
- CMP H ;ARE WE THERE?
- JNZ NOTMAX ;GO IF NOT
- LXI H,BOTTRAM ;FLUSH BUFFER
- SHLD HLSAVE1
- SHLD HLSAVE2
- NOTMAX:
- MOV M,B ;SAVE CHARACTER IN BUFFER
- INX H ;INCREMENT END OF BUFFER
- SHLD HLSAVE1
- MVI A,TRUE ;SET FLAG FOR PRINTER OUTPUT
- STA LISTMOR
- RET
- ;
- NOBUFF:
- CALL LSTSTAT
- RZ ;RETURN IF PRINTER BUSY
- MOV C,B ;ELSE PRINT CHARACTER
- JMP LISTER
- ;
- GOLIST:
- CALL LSTSTAT
- RZ ;RETURN IF PRINTER BUSY
- LHLD HLSAVE2 ;GET LOCATION OF NEXT CHARACTER TO PRINT
- MOV C,M ;GET CHARACTER
- INX H ;INCREMENT POINTER
- SHLD HLSAVE2
- CALL CMPBUFF ;CHECK FOR END OF BUFFER
- JMP LISTER ;PRINT
- ;
- ;ROUTINE CHECKS FOR END OF BUFFER, RESETS BUFFER IF SO AND STOPS
- ;PRINTER OUTPUT
- ;
- CMPBUFF:
- LHLD HLSAVE2
- XCHG
- LHLD HLSAVE1
- MOV A,L
- SUB E
- MOV L,A
- MOV A,H
- SBB D
- ORA L
- RNZ
- LXI H,BOTTRAM
- SHLD HLSAVE1
- SHLD HLSAVE2
- XRA A
- STA LISTMOR
- RET
- ;
- 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..
- 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..
- JMP OUT$MODDATP ;..TO REMOTE COMPUTER.
- ;
- 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
- PUSH H
- LXI H,225
- CALL FIXCNT
- PUSH H
- POP B
- POP H
- 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 'NOL' CMD.
- COLONB:
- CPI LF
- 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 TERM2 ;NO PROBLEM - GO BACK TO NORMAL ROUTINE
- CALL ILPRT
- DB CR,LF,'Memory save buffer full',CR,LF,BELL,0
- JMP TERM2
- ;
- ;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 H
- LXI H,625
- CALL FIXCNT
- PUSH H
- POP B
- POP H
- TIMERL:
- CALL RCVREADY
- 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
- JMP BDOS
- ;
- 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
- JMP MOVE
- ;
- ;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,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
- JMP CRLF
- ;
- MOVE4:
- LXI D,CMDBUF
- LXI H,FCB4
- JMP CPMLINE
- ;
- OPEN4:
- LXI D,FCB4
- MVI C,OPEN
- JMP BDOS
- ;
- READ80:
- LXI D,FCB4
- MVI C,READ
- JMP BDOS
- ;
- SEND80C:
- MVI B,80H
- LXI H,80H
- SENDCH1:
- PUSH D
- CALL SPEED
- POP D
- 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:
- LDA XOFFTST
- ORA A
- CNZ TXOFF
- CALL SENDREADY
- JNZ MODOUTL
- POP PSW
- CALL OUT$MODDATP
- CALL TYPE
- CPI CR
- JZ DLYCR
- RET
- ;
- DLYCR: INX H ;ALWAYS DISPLAY LF AFTER CR
- MVI A,LF
- CMP M
- DCX H
- JZ LFSKIP
- CALL TYPE
- LFSKIP: LDA XONWAIT ;WAIT FOR XON AFTER CR?
- ORA A
- JNZ WAITXON
- LDA CRDLY ;EXTRA DELAY AFTER CR
- JMP DLYCR2
- ;
- SPEED: LDA BYTDLY ;GET SPEED VALUE (0-9)
- ;DELAY IS FROM 0.02 SEC FOR SPDVAL = 1
- ;TO 0.18 SEC FOR SPDVAL = 9
- DLYCR2: ORA A
- RZ ;RETURN IF 0
- MOV C,A
- SPDLP: CALL SPD1 ;OUTER LOOP
- DCR C
- RZ
- JMP SPDLP
- ;
- SPD1: PUSH H
- LXI H,357 ;ABOUT 0.02 SEC AT 2 MHZ
- LDA XOFFTST
- ORA A
- JZ SPD2
- LXI H,102 ;ADJUST FOR XOFF TESTING
- LDA ECHOFLG
- ORA A
- JZ SPD2
- LDA LOCFLG
- ORA A
- JZ SPD2
- LXI H,76 ;ADJUST AGAIN FOR REMOTE ECHO
- SPD2: CALL FIXCNT
- PUSH H
- POP D
- POP H
- SPDLP1: DCX D ;INNER LOOP
- LDA XOFFTST
- ORA A
- CNZ TXOFF
- MOV A,E
- ORA D
- RZ
- JMP SPDLP1
- ;
- TXOFF: CALL RCVREADY
- RNZ
- CALL IN$MODDATP
- ANI 7FH
- CPI XOFF
- CZ WAITXON
- RET
- ;
- WAITXON:
- CALL RCVREADY
- JNZ WTXON2
- CALL IN$MODDATP
- ANI 7FH
- CPI XON
- RZ
- WTXON2: CALL STAT ;TEST TO SEE IF
- ORA A ;CANCELLATION REQUESTED
- JZ WAITXON ;SO DON'T GET HUNG UP
- CALL KEYIN
- CPI CAN
- RZ
- JMP WAITXON
- ;
- ;SEND A CP/M FILE
- ;
- SENDFIL:
- MVI A,TRUE ;ALWAYS FORCE CHECKSUM MODE INITIALLY ON SEND
- STA CKSUMFLG
- SENDFIL1:
- CALL PARITY ;SET PARITY IF REQUESTED
- LDA BATCHFLG ;CHECK IF MULTIPLE FILE..
- ORA A ;..MODE IS SET.
- JNZ SENDC1
- MVI A,TRUE ;INDICATE SEND FOR BATCH MODE
- 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
- MVI A,1
- STA ERRCT
- SENDRPT:
- CALL SENDHDR
- CALL SENDSEC
- LDA CKSUMFLG
- 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:
- LDA CKSUMDFLT ;GET MODE REQUESTED BY OPERATOR
- STA CKSUMFLG ;STORE IT
- RCVFIL1:
- 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
- ;
- RCVC2:
- CALL CKCPM2
- CALL CKBAKUP
- RCVC3:
- CALL ERASFIL
- CALL MAKEFIL
- LDA BATCHFLG
- ORA A ;DON'T PRINT MSG IF..
- JZ RCVFST ;..IN BATCH
- CALL ILPRT
- DB 'File open, ready to receive',CR,LF,0
- RCVFST:
- LDA CKSUMFLG
- ORA A
- MVI A,NAK
- JNZ RCVFIL2
- MVI A,CRC
- RCVFIL2:
- CALL SEND
- LDA QFLG
- ORA A
- JZ RCVLP
- LDA CKSUMFLG
- ORA A
- JNZ RCVNAKM ;IF IN CRC MODE
- CALL ILPRT ;THEN SAY SO
- DB 'CRC in effect',CR,LF,0
- JMP RCVLP
- RCVNAKM:
- CALL ILPRT ;ELSE SAY CHECKSUM MODE
- DB 'Checksum in effect',CR,LF,0
- RCVLP:
- CALL RCVSECT
- JC RCVEOT
- CALL WRSECT
- 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
- MOV A,C
- STA FTYCNT ;INITIATE FILE TYPE COUNT
- 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
- JZ ACKLP
- CALL FTYTST ;TYPE CHARACTER ETC.
- 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
- MOV A,C
- STA FTYCNT ;INITIATE COUNT FOR FILE TYPE
- 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 ;CAN TYPE IT IF NO QFLG
- ORA A
- JZ SKPTYP
- CALL FTYTST
- SKPTYP: 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
- ;
- FTYTST:
- LDA FTYCNT
- INR A
- STA FTYCNT
- CPI 9 ;ARE WE AT THE FILE TYPE?
- JZ SPCTST ;GO IF SO
- ENDSPT: MOV A,M
- CPI ' ' ;TEST FOR SPACE
- CNZ TYPE ;TYPE IF NOT
- RET
- ;
- SPCTST: MOV A,M
- CPI ' ' ;TEST FOR SPACE IN FIRST FILE TYPE BYTE
- RZ ;DON'T OUTPUT PERIOD IF SPACE
- MVI A,'.'
- CALL TYPE
- JMP ENDSPT ;OUTPUT FIRST FILE TYPE BYTE
- ;
- 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
- JMP BDOS
- ;
- CKBAKUP:
- LDA BAKUPBYTE
- ORA A
- RZ
- MVI C,SRCHF
- LXI D,FCB
- CALL BDOS
- INR A
- RZ ;FILE NOT FOUND
- JMP PLANCHG ;IN "CKCPM2" - RET DONE THERE
- ;
- ;MULTI-FILE ACCESS SUBROUTINE FROM CP/M USER'S GROUP
- ;FIXED BY MARK ZEIGER 8/17/80
- ;CARRY IS SET IF NO MORE NAMES CAN BE FOUND
- ;
- MFNAME:
- MFACCESS ;A MACRO IN MACROS.LIB
- ;
- RCVSECT:
- MVI A,1
- 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: ;WAIT FOR SOH OR EOT
- MVI B,10 ;10 SECONDS
- CALL RECV
- JC RCVSTOT
- 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 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 ;WAIT FOR 1 SEC..
- CALL RECV ;..WITH NO CHARS
- JNC RCVSERR ;LOOP UNTIL SENDER DONE
- LDA CKSUMFLG ;GET CHECKSUM FLAG
- ORA A ;CRC IN EFFECT?
- MVI A,NAK ;PUT NAK IN ACCUM
- JNZ RCVSER2 ;NO, SEND THE NAK
- LDA FIRSTME ;GET FIRST TIME SWITCH
- ORA A ;HAS FIRST SOH BEEN RECEIVED?
- MVI A,NAK ;PUT NAK IN ACCUM
- JZ RCVSER2 ;YES, THEN SEND NAK
- MVI A,CRC ;TELL SENDER CRC IS IN EFFECT
- RCVSER2:
- CALL SEND ;..THE NAK or CRC request
- LDA ERRCT ;ABORT IF..
- INR A ;..WE HAVE REACHED..
- STA ERRCT ;..THE ERROR..
- CPI ERRLIM ;..LIMIT?
- JC RCVRPT ;..NO, TRY AGAIN
- 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 QFLG
- ORA A
- JZ RCVSCRC
- RCVSPT: CALL ILPRT
- DB CR,LF,'++ Timeout ++ ',0
- RCVPRN: LDA ERRCT
- PUSH H
- MVI H,0
- MOV L,A
- CALL DECOUT
- POP H
- CALL CRLF
- RCVSCRC:
- CALL RCVSCRC2
- JMP RCVSERR
- ;
- ;ROUTINE WILL SWITCH FROM CRC TO CHECKSUM IF ERCNT REACHES ERRCRC
- ;AND FIRSTME IS TRUE
- ;
- RCVSCRC2:
- LDA ERRCT
- CPI ERRCRC
- RNZ
- LDA FIRSTME
- ORA A
- RZ
- LDA CKSUMFLG
- ORA A
- RNZ
- CMA
- STA CKSUMFLG
- STA CKSUMDFLT
- LDA QFLG
- ORA A
- RZ
- CALL ILPRT
- DB '++ Switching to Checksum mode ++',CR,LF
- DB '++ Sender may not be CRC capable ++',CR,LF,BELL,0
- RET
- ;
- ;----> 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 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
- PUSH H
- MVI H,0
- MOV L,A
- CALL DECOUT ;DISPLAY IT
- POP H
- JMP CRLF ;DO CR, LF
- ;
- ;Got SOH - get block #, block # complemented
- ;
- RCVSOH: XRA A ;ZERO ACCUM
- STA FIRSTME ;INDICATE FIRST SOH RECV'D
- MVI B,1 ;TIMEOUT = 1 SEC
- CALL RECV ;GET SECTOR
- JC RCVSTOT ;GOT TIMEOUT
- 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 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 CKSUMFLG
- 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 ;NUMBER 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 QFLG
- ORA A
- JZ RCVSERR
- RCVCRER:
- CALL ILPRT
- DB CR,LF,'++ CRC error ++',0
- JMP RCVPRN
- ;
- RCVCERR:
- LDA QFLG
- ORA A
- JZ RCVSERR
- RCVCPR:
- CALL ILPRT
- DB CR,LF,'++ Checksum error ++ ',0
- JMP RCVPRN
- ;
- RECVACK:
- CALL SENDACK
- JMP RCVSECT
- ;
- SENDACK:
- MVI A,ACK
- JMP SEND
- ;
- SENDHDR:
- LDA QFLG
- ORA A
- JZ SENDHNM
- CALL ILPRT
- DB CR,'Sending # ',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
- JMP SEND
- ;
- 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
- JMP SEND
- ;
- SENDCRC:
- CALL FINCRC
- MOV A,D
- CALL SEND
- MOV A,E
- CALL SEND
- XRA A
- RET
- ;
- GETACK: MVI B,10 ;10 SECONDS
- 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
- DCR A
- CPI ERRLIM
- RC
- 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 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
- JMP BDOS
- ;
- 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 is likely 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 ;CPM2X
- ;
- 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 ;NOT CPM2X
- ;
- 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 ;ONLY IF SINGLE FILE...
- RZ
- JMP SENDTIM ;A LIB MACRO SHOWS TIME TO SEND
- ;
- 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 CR,LF,'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
- MSEC: PUSH H
- LXI H,7500
- CALL FIXCNT
- PUSH H
- POP D
- POP H
- CALL CKABORT
- MWTI:
- CALL RCVREADY
- 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 ;CALCULATE 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 ;CALCULATE CRC
- ADD C
- MOV C,A
- SENDW: CALL SENDREADY
- JNZ SENDW
- POP PSW
- JMP OUT$MODDATP
- ;
- WAITNAK:
- LDA QFLG
- ORA A
- JZ WAITNLP
- 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
- CPI CAN ;CANCEL?
- JZ ABORT
- DCR E
- JZ ABORT
- JMP WAITNLP
- ;
- WAITCRC:
- LDA QFLG
- ORA A
- JZ WAITCRC1
- CALL ILPRT
- DB 'CRC request received',CR,LF,0
- WAITCRC1:
- XRA A
- STA CKSUMFLG
- 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
- DAD D
- SHLD VLIST+1
- LXI D,30
- DAD D
- SHLD VLSTAT+1
- LDA PMMIBYTE
- ORA A
- RZ ;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
- ;
- ; CHECK OPTIONS, PUT 0 IN APPROPRIATE PLACES IN OPTION TABLE
- ; IF OPTION SELECTED
- ;
- 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'
- JNZ OPTCK1
- XRA A
- STA UARTFLG
- JMP OPTCK2
- ;
- OPTCK1: CPI 'A'
- JNZ OPTCK2
- MVI A,TRUE
- STA UARTFLG
- OPTCK2: MVI M,0
- JMP OPTLP
- ;
- OPTNO: INX H
- DCR B
- JNZ OPTCK
- CALL NOTVLDMSG
- POP PSW ;PRESERVE STACK
- JMP MENU
- ;
- ENDOPT: LDA VSEEFLG
- ORA A
- RNZ
- STA QFLG ;IF VIEWING SUPPRESS ALL ELSE
- RET
- ;
- DONE:
- LDA BATCHFLG
- ORA A
- JNZ DONETC
- LDA QFLG
- ORA A
- JZ NMSTRNS
- MVI B,12 ;ZERO OUT FTRNMSG
- LXI H,FTRNMSG
- MVI A,0
- ZEROLP: MOV M,A
- INX H
- DCR B
- JNZ ZEROLP
- MVI B,12 ;PUT FILE NAME IN FTRNMSG
- LXI H,FCB+1
- LXI D,FTRNMSG
- LOADMSG:
- MVI A,4 ;START OF FILE TYPE?
- CMP B
- JZ PERIOD ;PUT IN PERIOD IF SO
- MOV A,M
- CPI ' ' ;DON'T PUT IN SPACE
- JZ SKPSP
- STAX D ;STORE IN FTRNMSG
- INX D
- SKPSP: INX H
- DCR B
- MOV A,B
- ORA A ;END OF FILE NAME?
- JZ FTRNMSG0 ;DISPLAY FILE NAME
- JMP LOADMSG ;LOOP FOR ANOTHER CHARACTER
- ;
- PERIOD:
- MOV A,M
- CPI ' ' ;IS FILE TYPE EMPTY?
- JZ FTRNMSG0 ;GO IF SO
- MVI A,'.' ;ELSE PUT PERIOD IN MESSAGE
- STAX D
- INX D
- DCR B
- JMP LOADMSG
- ;
- FTRNMSG0:
- CALL ILPRT
- DB CR,LF
- FTRNMSG:
- DS 12
- DB 0
- CALL ILPRT
- DB ' Transferred',CR,LF,LF,0
- 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 SENDFIL1 ;..UPON WHICH ROUTINE SET..
- JMP RCVFIL1 ;..THE FLAG IN MULTI-FILE MODE.
- ;
- DONETC:
- CALL ILPRT
- DB CR,LF,'Transfer completed',CR,LF,BELL,0
- DONETCA:
- LDA DISCFLG ;SEE IF DISCONNECT WHEN THROUGH
- 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 JMP$DISCONNT ;HANG-UP THE PMMI
- JMP EXIT ;GO TO CP/M
- ;
- DONETCE:
- CALL NOPARIT ;RESET TO NO PARITY
- MVI A,TRUE
- STA FIRSTME ;SET FIRST-TIME FLAG
- STA FSTFLG ;RESET MULTIFILE TRANS
- STA NFILFLG ;..USED IN TERMINAL ROUTINE
- CMA
- STA SAVEFLG ;STOP MEMORY SAVE IN TERM ROUTINE
- STA LISTMOR ;STOP ANY BUFFERED OUTPUT TO PRINTER
- LXI H,BOTTRAM ;RESET PRINTER BUFFER POINTERS
- SHLD HLSAVE1
- SHLD HLSAVE2
- LDA TERMFLG ;SEE IF RETURN TO..
- ORA A ;..TERMINAL MODE..
- JNZ MENU ;..AFTER X'FER.
- CALL CRLF
- JMP TERM
- ;
- 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
- ;
- LISTER:
- PUSH B
- PUSH D
- PUSH H
- VLIST: CALL $-$
- POP H
- POP D
- POP B
- RET
- ;
- LSTSTAT:
- PUSH B
- PUSH D
- PUSH H
- VLSTAT: CALL $-$
- POP H
- POP D
- POP B
- ORA A
- 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:
- MVI A,1
- STA ERRCT
- CALL ILPRT
- DB CR,LF,'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
- ;
- SHFTYPE:
- PUSH PSW
- CALL ILPRT
- DB 'ctrl-',0
- POP PSW
- ADI 40H
- CALL TYPE
- ;
- ;WRITE A STRING OF CHARACTERS
- ;
- 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
- MVI A,BELL
- CALL TYPE
- LDA BATCHFLG
- ORA A
- JNZ DONETCE
- MVI A,'Q' ;RESET QFLG
- STA QFLG
- JMP ABORT ;ABORT OTHER COMPUTER
- ;
- EXIT:
- CALL ILPRT
- DB '%%% Exiting MODEM %%%',0
- LDA SAVUSR
- MOV E,A
- CALL SETUSR
- 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
- ;
- ;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 'H' ;RETURN IF HELP OPTION
- RZ
- CPI 'L' ;RETURN IF LOCAL ECHO OPTION
- 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
- RET
- ;
- SAVAGN:
- MVI A,FALSE
- STA NFILFLG
- RET
- ;
- NEWBAUD:
- LDA PMMIBYTE
- ORA A
- RZ
- CALL ILPRT
- DB CR,LF,'Enter New Baudrate: ',0
- 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 JMP$INITMOD
- ;
- 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 CALCULATION FOR OUTPUT 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
- ;
- MENU0:
- LDA NFILFLG
- ORA A
- JNZ MENU ;GO IF NO FILE ACTIVE
- 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
- MVI B,2 ;2 MORE BELLS
- BLOOP: LDA BELRPT ;GET TIME
- MOV C,A
- BCLOOP: LXI H,1000 ;ABOUT 0.03 SECONDS
- CALL FIXCNT
- BILOOP: MOV A,L
- ORA H
- DCX H
- JNZ BILOOP
- DCR C
- JNZ BCLOOP
- MVI A,BELL
- CALL TYPE
- DCR B
- JNZ BLOOP
- JMP MENU1
- ;
- MENU:
- LDA EXITFLG
- ORA A
- JNZ EXIT
- MENU1:
- LXI H,RESTSN ;RESTORE SECTOR 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.
- 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 file using Christensen Protocol',CR,LF
- DB ' S - Send 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
- ;
- LDA PMMIBYTE
- ORA A
- JZ THREELTR
- CALL ILPRT
- DB ' Additional Subcommands for PMMI Modem',CR,LF,LF
- DB ' Modem control:',CR,LF
- DB ' O - Send or receive on Originate tone',CR,LF
- DB ' A - Send or receive on Answer tone',CR,LF
- DB ' D - Disconnect option',CR,LF,LF
- DB ' Parity options:',CR,LF
- DB ' 1 - Set and check for odd parity',CR,LF
- DB ' 0 - Set and check for even parity',CR,LF
- DB ' Both ends must be capable of these options',CR,LF
- DB ' which are available only in S and R modes.',CR,LF
- DB ' The parity checking will be part of the',CR,LF
- DB ' file transfer protocol.',CR,LF,LF
- DB ' Speed Options:',CR,LF
- DB ' After entering your primary and secondary options,'
- DB CR,LF
- DB ' you can set the modem speed by placing a "." after'
- DB CR,LF
- DB ' the options followed by the speed e.g. 110, 300.',CR,LF
- DB ' For example: SBO1T.600 will set the modem to run',CR,LF
- DB ' at 600 baud.',CR,LF,LF,0
- ;
- CALL NXTSCRN
- ;
- THREELTR:
- CALL ILPRT
- DB ' Three Letter Commands',CR,LF,LF
- DB 'DIR - List directory and space free (may specify drive)'
- DB CR,LF
- DB 'END - Exit from this program',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 'SPD - Set speed of file output in terminal mode',CR,LF,0
- ;
- CALL SORPTST
- JNZ NOTIME
- CALL ILPRT
- DB 'TIM - Set S mode time-to-send message',CR,LF,0
- ;
- NOTIME:
- LDA TOGGLECRC
- ORA A
- JZ NOTOGCRC
- CALL ILPRT
- DB 'TCC - Toggle Checksum/CRC mode on receive',CR,LF,0
- ;
- NOTOGCRC:
- LDA TOGGLEBK
- ORA A
- JZ NOTOGBK
- CALL ILPRT
- DB 'TBR - Toggle backspace to rub conversion',CR,LF,0
- ;
- NOTOGBK:
- LDA TOGGLELOC
- ORA A
- JZ NOTOGLOC
- CALL ILPRT
- DB 'TLC - Toggle 1) local command immediate',CR,LF
- DB ' 2) local command after ',0
- LDA EXTCHR
- CALL SHFTYPE
- DB CR,LF,0
- ;
- NOTOGLOC:
- LDA TOGGLELF
- ORA A
- JZ NOTOGLF
- CALL ILPRT
- DB 'TLF - Toggle send linefeed after carriage return',CR,LF,0
- ;
- NOTOGLF:
- LDA TOGXOFF
- ORA A
- JZ NOTOGXOFF
- CALL ILPRT
- DB 'TXO - Toggle XOFF/XON testing in terminal mode file output'
- DB CR,LF,0
- ;
- NOTOGXOFF:
- LDA PMMIBYTE
- ORA A
- JNZ NONUM
- CALL ILPRT
- DB 'NUM - List remote systems',CR,LF,0
- LDA SETUPTST
- ORA A
- JZ NOSETUP
- CALL ILPRT
- DB 'SET - Set communication ports',CR,LF,0
- ;
- NOSETUP:
- MVI A,LF
- CALL TYPE
- JMP NOPMMI
- ;
- NONUM:
- CALL ILPRT
- DB 'CAL - Dial number',CR,LF
- DB 'DSC - Disconnect',CR,LF
- DB 'BYE - Disconnect and reboot',CR,LF,LF,0
- ;
- NOPMMI:
- CALL ILPRT
- DB ' The following are terminal text buffer commands:'
- DB CR,LF,0
- LDA PMMIBYTE
- ORA A
- JNZ SKIPLF
- MVI A,LF
- CALL TYPE
- SKIPLF:
- 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
- LDA EXITCHR
- CALL SHFTYPE
- DB ' - Exit to command mode',CR,LF,LF,0
- ;
- LDA PMMIBYTE
- ORA A
- JZ S5A
- ;
- LDA DISCCHR
- CALL SHFTYPE
- DB ' - Disconnect',CR,LF,0
- LDA BRKCHR
- CALL SHFTYPE
- DB ' - Send break',CR,LF,0
- LDA CHGBAUD
- CALL SHFTYPE
- DB ' - Change baud rate',CR,LF,0
- ;
- S5A:
- LDA TRANLOGON
- ORA A
- JZ NOTRANLOG
- LDA LOGCHR
- CALL SHFTYPE
- DB ' - Transmit logon',CR,LF,0
- ;
- NOTRANLOG:
- LDA LSTTST
- ORA A
- JZ NOLST2
- LDA LSTCHR
- CALL SHFTYPE
- DB ' - Toggle printer',CR,LF,0
- ;
- NOLST2:
- MVI A,LF
- CALL TYPE
- LDA SAVECHR
- CALL SHFTYPE
- DB ' - Start copy into buffer',CR,LF,0
- LDA 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
- LDA TRANCHR
- CALL SHFTYPE
- DB ' - Transfer ASCII file to remote',CR,LF,LF,0
- LDA LOCONEXTCHR
- ORA A
- LDA 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
- MVI C,CURDSK ;CURRENT DISK FUNCTION
- CALL BDOS
- ADI 'A' ;MAKE ASCII
- CALL TYPE
- ;
- IF CPM2X ;IF CPM VER 2.X
- ;
- CALL GETUSR ;GET CURRENT USER NUMBER
- CPI 0
- JZ SR3B ;SKIP IF USER 0
- PUSH PSW
- CALL ILPRT
- DB ', User ',0
- POP PSW
- MVI H,0
- MOV L,A
- CALL DECOUT ;REPORT USER
- ;
- ENDIF ;CPM2X
- ;
- SR3B: CALL CRLF
- LDA NFILFLG
- ORA A
- JNZ NOBUFMSG
- CALL GETSPC
- CALL ILPRT
- DB ' bytes of buffer free',CR,LF,0
- NOBUFMSG:
- CALL ILPRT
- DB 'COMMAND (H for Help): ',0
- GETCMD:
- LXI D,CMDBUF ;ENTER COMMAND
- CALL INBUFF
- CALL CRLF
- LXI D,CMDBUF+2 ;POINT TO COMMAND
- CALL ILCOMP
- DB 'END',0
- JNC EXIT
- CALL ILCOMP
- DB 'LOG',0
- JNC LOGNEW
- CALL ILCOMP
- DB 'DIR',0
- JNC DIR
- CALL ILCOMP
- DB 'ERA',0
- JNC ERASEF
- CALL ILCOMP
- DB '?',0
- JNC CURPAR
- CALL ILCOMP
- DB 'SPD',0
- JNC SETSPD
- CALL ILCOMP
- DB 'TIM',0
- JNC SETTIM
- CALL ILCOMP
- DB 'TCC',0
- JNC TOGCRC
- CALL ILCOMP
- DB 'TBR',0
- JNC TOGBKSP
- CALL ILCOMP
- DB 'TLC',0
- JNC TOGLOC
- CALL ILCOMP
- DB 'TLF',0
- JNC TOGLF
- CALL ILCOMP
- DB 'TXO',0
- JNC TOGTXOFF
- LDA PMMIBYTE
- ORA A
- JNZ NONUM2
- CALL ILCOMP
- DB 'NUM',0
- JNC NUMPRN
- NONUM2: LDA SETUPTST
- ORA A
- JZ NOSETUP2
- CALL ILCOMP
- DB 'SET',0
- JNC SETUPENT
- NOSETUP2:
- CALL ILCOMP
- DB 'NOL',0
- JC NXTOPT1 ;CARRY SET = NO MATCH
- LDA NFILFLG
- ORA A
- JNZ NOFILOPN ;GO TELL OPERATOR IF NO FILE OPEN
- LDA ORIGSAV
- STA ORIGFLG
- CALL BUFMSG
- LHLD HLSAVE ;RETURN TO TERMINAL..
- JMP TERM ;..MODE WITH SAVE OPTION..
- ;..IF PREVIOUSLY ENABLED.
- ;
- NXTOPT1:
- CALL ILCOMP
- DB 'WRT',0
- JNC WRTFIL
- CALL ILCOMP
- DB 'DEL',0
- JNC NEWFILE
- LDA PMMIBYTE
- ORA A
- JZ S6
- CALL ILCOMP ;DE SET FROM 1ST ILCOMP CALL
- DB 'DSC',0
- JNC DISCON1
- CALL ILCOMP
- DB 'BYE',0
- JNC BYEBYE
- CALL ILCOMP
- DB 'CAL',0
- JC S6
- MVI A,20H ;FOOL THE SYSTEM
- STA CMDBUF+4 ;..CMDBUF SO THAT IT..
- JMP DOOPT ;..LOOKS AT OPTION FOR DIAL
- S6: PUSH H
- LDA CMDBUF+2
- LXI H,COMPLIST
- CALL COMPARE ;COMPARES LIST POINTED TO BY HL..
- POP H ;..TO CHAR IN A-REG.
- JC NOTVLD ;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.
- ;
- NOTVLD:
- CALL NOTVLDMSG
- JMP XPRT
- ;
- NOTVLDMSG:
- CALL ILPRT
- DB '++ Invalid Command ++',CR,LF,BELL,0
- RET
- ;
- DISCON1:
- CALL JMP$DISCONNT
- CALL ILPRT
- DB CR,LF,'<< Disconnected >>',CR,LF,BELL,0
- JMP EXITMEN
- ;
- BYEBYE:
- CALL ILPRT
- DB CR,LF,'Goodbye...',CR,LF,0
- XRA A
- CALL OUT$MODCTLP
- CALL OUT$MODCTL2
- LDA SAVUSR
- MOV E,A
- CALL SETUSR
- LHLD CLDBOOT ;GET COLD BOOT PROM ADDRESS OR WARM BOOT
- PCHL ;JUMP TO IT
- ;
- DIR:
- MVI C,CURDSK
- CALL BDOS
- STA DISKSAV
- CALL DIRLST
- LDA DISKSAV
- MOV E,A
- MVI C,SELDSK
- CALL BDOS
- JMP XPRT
- ;
- LOGNEW: LDA NFILFLG
- ORA A
- JZ NORESET
- LDA CMDBUF+6
- CPI ' '
- JNZ SPECIFD
- MVI C,CURDSK
- CALL BDOS
- ADI 'A'
- SPECIFD:
- SUI 'A'
- STA DISKSAV
- CPI 16
- JNC NOTVLD
- ;
- IF CPM2X ;IF CPM VER. 2.X
- ;
- CALL GETUSR ;PICK UP CURRENT USER NUMBER
- MOV B,A ;SAVE IT
- LDA CMDBUF+7 ;GET NEW USER NUMBER
- CPI ' ' ;CHECK FOR SPACE
- JZ SR7B ;EXIT IF NO NEW USER NUMBER SPECIFIED
- CALL NUMCHK ;CHECK TO SEE IF IT IS A NUMBER
- MOV B,A ;SAVE
- LDA CMDBUF+8 ;GET SECOND DIGIT
- CPI ' '
- JZ SR7B ;GO IF SPACE
- CALL NUMCHK
- MOV C,A ;SAVE
- MOV A,B ;GET SAVED FIRST DIGIT
- ADD A ; X2
- ADD A ; X4
- ADD A ; X8
- ADD B ; X9
- ADD B ; X10
- ADD C
- MOV B,A ;SAVE
- LDA CMDBUF+9 ;GET THIRD DIGIT
- CPI ' '
- JZ SR7B ;GO IF SPACE
- CALL NUMCHK
- MOV C,A ;SAVE
- MOV A,B ;GET SAVED FIRST & SECOND DIGIT
- ADD A ; X2
- ADD A ; X4
- ADD A ; X8
- ADD B ; X9
- ADD B ; X10
- ADD C
- ; CPI 16 ;CHECK FOR < 16
- ; JNC NOTVLD ;GO IF NOT
- MOV B,A
- SR7B: MOV A,B
- STA SAVUSR
- ;
- ENDIF ;CPM2X
- ;
- CALL ILPRT
- DB 'Insert disk for drive ',0
- LDA DISKSAV
- ADI 'A'
- CALL TYPE
- NOTCR: CALL ILPRT
- DB CR,LF,'Hit return when ready',0
- CALL KEYIN
- CPI 3 ;CTL-C ABORTS LOGIN
- JZ XPRT
- CPI CR
- JNZ NOTCR
- CALL CRLF
- MVI C,RESET
- CALL BDOS
- LDA DISKSAV
- MOV E,A
- MVI C,SELDSK
- CALL BDOS
- ;
- IF CPM2X
- LDA SAVUSR
- MOV E,A
- CALL SETUSR
- ENDIF
- ;
- JMP XPRT
- ;
- IF CPM2X
- ;
- GETUSR: MVI E,0FFH ;GET CURRENT USER
- SETUSR: MVI C,USER ;SET-UP FUNCTION CALL
- JMP BDOS ;NUMBER IN RETURNED IN A
- ;
- ENDIF ;CPM2X
- ;
- 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
- XRA A
- JMP XPRT
- ;
- ERASEF: LXI D,CMDBUF ;PUT CMD LINE INTO FCB AT HL
- LXI H,FCB
- CALL CPMLINE
- CALL MOVEFCB ;MOVE FCB+16 TO FCB
- LDA FCB+1
- CPI ' '
- JZ NOTVLD ;GO IF NO FILE SPECIFIED
- LXI D,FCB
- MVI C,SRCHF
- CALL BDOS
- INR A ;0 IF FILE NOT FOUND
- JNZ ERAFILE ;OK, GO ERASE
- CALL ILPRT
- DB '++ File not found ++',CR,LF,BELL,0
- JMP XPRT
- ;
- ERAFILE:
- LXI D,FCB
- MVI C,ERASE
- CALL BDOS
- CALL ILPRT
- DB 'File erased',CR,LF,0
- JMP XPRT
- ;
- SETSPD:
- CALL ILPRT
- DB 'Enter character output delay [0(none) - 9(longest delay)]: ',0
- CALL NUMGET
- JNC NOCHG1
- STA BYTDLY
- NOCHG1: CALL SPDMSG
- CALL ILPRT
- DB CR,LF,'Enter additional delay after <CR> [0-9]: ',0
- CALL NUMGET
- JNC NOCHG2
- RLC ;X2
- RLC ;X4
- STA CRDLY
- NOCHG2: CALL CRDLYMSG
- JMP XPRT
- ;
- NUMGET: LXI D,CMDBUF
- CALL INBUFF
- LDA CMDBUF+2 ;GET NUMBER
- CPI ' '
- RZ
- NUMCHK: SUI '0'
- CPI 10
- RC
- POP PSW ;PRESERVE STACK
- JMP NOTVLD
- ;
- SPDMSG: CALL ILPRT
- DB 'Terminal mode file output delay is 0.',0
- LDA BYTDLY
- CALL GIVNUM
- CALL ILPRT
- DB ' seconds per character',CR,LF,0
- RET
- ;
- CRDLYMSG:
- CALL ILPRT
- DB 'Additional delay after <CR> is 0.',0
- LDA CRDLY
- CALL GIVNUM
- CALL ILPRT
- DB ' seconds',CR,LF,0
- RET
- ;
- GIVNUM: ADD A ;2X
- CPI 10
- MOV B,A
- JNC NOZERO
- MVI A,'0'
- CALL TYPE
- MOV A,B
- NOZERO: PUSH H
- MOV L,A
- MVI H,0
- CALL DECOUT
- POP H
- RET
- ;
- SETTIM:
- CALL SORPTST
- JNZ NOTVLD
- CALL ILPRT
- 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=710, 5=1200, 6=2400,'
- DB CR,LF
- DB ' 7=4800, and 8=9600 Baud.'
- DB CR,LF,LF,'Enter value: ',0
- CALL NUMGET
- CPI 9
- JNC NOTVLD
- STA MSPEED
- CALL SETTIM2
- JMP XPRT
- ;
- SETTIM2:
- CALL SORPTST
- 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:
- JMP BAUDPRT
- ;
- SORPTST:
- LDA SETUPTST
- MOV B,A
- LDA PMMIBYTE
- ORA B
- RET
- ;
- TOGCRC:
- LDA TOGGLECRC
- ORA A
- JZ NOTVLD
- LDA CKSUMDFLT
- CMA
- STA CKSUMDFLT
- CALL TOGCRC2
- JMP XPRT
- ;
- TOGCRC2:
- ORA A
- JNZ CHEKMSG
- CALL ILPRT
- DB 'CRC mode set',CR,LF,0
- RET
- ;
- CHEKMSG:
- CALL ILPRT
- DB 'Checksum mode set',CR,LF,0
- RET
- ;
- TOGBKSP:
- LDA TOGGLEBK
- ORA A
- JZ NOTVLD
- LDA CONVBKSP
- CMA
- STA CONVBKSP
- CALL TOGBKSP2
- JMP XPRT
- ;
- TOGBKSP2:
- LDA CONVBKSP
- ORA A
- JZ NORUBMSG
- CALL ILPRT
- DB 'Backspace is rub',CR,LF,0
- RET
- ;
- NORUBMSG:
- CALL ILPRT
- DB 'Backspace is backspace',CR,LF,0
- RET
- ;
- TOGLOC: LDA TOGGLELOC
- ORA A
- JZ NOTVLD
- LDA LOCONEXTCHR
- CMA
- STA LOCONEXTCHR
- CALL TOGLOC2
- JMP XPRT
- ;
- TOGLOC2:
- CALL ILPRT
- DB 'Use ',0
- LDA LOCONEXTCHR
- ORA A
- LDA 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: LDA TOGGLELF
- ORA A
- JZ NOTVLD
- LDA ADDLF
- CMA
- STA ADDLF
- CALL TOGLF2
- JMP XPRT
- ;
- TOGLF2:
- CALL ILPRT
- DB 'Linefeed ',0
- LDA ADDLF
- ORA A
- JNZ LFMSG
- CALL ILPRT
- DB 'NOT ',0
- LFMSG: CALL ILPRT
- DB 'sent after <CR>',CR,LF,0
- RET
- ;
- TOGTXOFF:
- LDA TOGXOFF
- ORA A
- JZ NOTVLD
- CALL ILPRT
- DB 'Use XOFF testing? (Y/N): ',0
- CALL GETANS
- JC NOCHG3
- STA XOFFTST
- NOCHG3: CALL XOFFMSG
- CALL ILPRT
- DB CR,LF,'Use XON waiting after <CR> (Y/N): ',0
- CALL GETANS
- JC NOCHG4
- STA XONWAIT
- NOCHG4: CALL XONMSG
- LDA XONWAIT
- ORA A
- JZ XPRT
- CMA
- STA XOFFTST ;DON'T ALLOW BOTH
- CALL ILPRT
- DB 'Therefore ',0
- CALL XOFFMSG
- JMP XPRT
- ;
- GETANS:
- LXI D,CMDBUF
- CALL INBUFF
- LDA CMDBUF+2 ;GET ANSWER
- CPI ' '
- CMC
- RZ
- MOV B,A
- CPI 'N'
- MVI A,FALSE
- RZ
- MOV A,B
- CPI 'Y'
- MVI A,TRUE
- RZ
- POP PSW ;PRESERVE STACK
- JMP NOTVLD
- ;
- XOFFMSG:
- CALL ILPRT
- DB 'XOFF testing ',0
- LDA XOFFTST
- ORA A
- 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
- LDA XONWAIT
- ORA A
- JNZ XONMSG2
- CALL ILPRT
- DB 'NOT ',0
- XONMSG2:
- CALL ILPRT
- DB 'automatically tested after <CR>',0
- JMP XONMSG3
- ;
- SETUPENT:
- LDA SETUPTST
- ORA A
- JZ NOTVLD
- LXI D,CMDBUF+1
- CALL JMP$SETUPR
- JMP XPRT
- ;
- NEWFILE:
- LDA NFILFLG
- ORA A
- JNZ NOFILOPN
- LDA FCB3+1 ;CHECK THAT FILE WAS REQUESTED
- CPI ' '
- JZ NOFILOPN ;IF NO FILE, DON'T ERASE
- LXI D,FCB3
- MVI C,ERASE
- CALL BDOSRT
- MVI A,TRUE ;DO NOT ALLOW TERMINAL..
- STA NFILFLG ;..SAVE SINCE NO FILE..
- CMA ;..SPECIFIED.
- STA SAVEFLG
- LXI H,FCB3
- CALL INITFCBS
- LXI H,BOTTRAM
- SHLD HLSAVE
- JMP XPRT
- ;
- WRTFIL:
- LDA NFILFLG
- CPI TRUE
- JZ NOFILOPN
- LDA FCB3+1 ;CHECK THAT FILE WAS REQUESTED
- CPI ' '
- JZ NOFILOPN
- LHLD HLSAVE
- CALL NUMRECS ;DISK WRITE ROUTINE AS USED IN..
- CALL WRTDSK ;..IN THE INTDSKSV ROUTINE.
- CALL CLOSE3
- MVI A,TRUE
- STA NFILFLG
- CMA
- STA SAVEFLG
- LXI H,FCB3
- CALL INITFCBS ;BLANK OUT FCB SO WRITTEN FILE CAN'T BE ERASED.
- LXI H,BOTTRAM
- SHLD HLSAVE
- JMP XPRT
- ;
- NOFILOPN:
- CALL ILPRT
- DB '++ No File Open ++',CR,LF,BELL,0
- JMP XPRT
- ;
- ;THIS ROUTINE DISPLAYS THE PHONE NUMBERS IN THE LIBRARY
- ;
- NUMPRN:
- PUSH H
- CALL CLRTST
- CALL ILPRT
- DB ' Library of Phone Numbers of Remote Systems',0
- 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
- NUMPRN1:
- INX H ;SKIP PMMI DIALING LETTER
- INX H ;AND EQUAL SIGN
- MVI B,30 ;NUMBER OF BYTES TO MOVE
- CALL MOVE ;MOVE TO BUFFER
- CALL SPACES ;2 ENTRIES + 3 SPACES = 63 CHARACTERS
- INX H
- INX H
- MVI B,30
- CALL MOVE
- CALL NEWLINE
- DCR C ;NUMBER OF LINES TO PRINT
- JZ NUMPRN2
- JMP NUMPRN1
- ;
- 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
- ;
- NUMPRN2:
- MVI A,'$'
- STAX D
- MVI C,PRINT
- LXI D,DBUF ;POINT TO TABLE OF NUMBERS TO PRINT
- CALL BDOS
- CALL CRLF
- CALL CRLF
- POP H
- JMP XPRT
- ;
- 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
- ;
- 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
- CPI 3 ;QUIT?
- JNZ CLRTST
- POP PSW ;CLEAN RETURN ADR OFF OF STACK
- JMP XPRT
- ;
- CLRTST: LDA SCRNTEST
- ORA A
- JNZ CLRSCRN
- ;
- LOTSALF:
- MVI A,CR
- CALL TYPE
- MVI B,12
- MVI A,LF
- LFLOOP: CALL TYPE
- DCR B
- JNZ LFLOOP
- RET
- ;
- CURPAR:
- CALL CLRTST
- CALL ILPRT
- DB ' Current Settings',CR,LF,LF,LF,0
- LDA CKSUMDFLT
- CALL TOGCRC2
- LDA LSTTST
- ORA A
- JZ NOLST3
- CALL LSTMSG
- NOLST3:
- CALL SETTIM2
- CALL TOGBKSP2
- CALL TOGLF2
- CALL TOGLOC2
- CALL ILPRT
- DB 'Terminal mode file buffer is ',0
- LDA NFILFLG
- ORA A
- 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
- CALL XOFFMSG
- CALL XONMSG
- CALL SPDMSG
- CALL CRDLYMSG
- CALL CRLF
- JMP XPRT
- ;
- GETSPC: CALL GETMAX
- MOV B,A
- LHLD HLSAVE
- STC
- CMC
- MVI A,0
- SBB L
- MOV L,A
- MOV A,B
- SBB H
- MOV H,A
- JMP DECOUT
- ;
- ;ADJUSTS LOOP COUNTERS FOR VARIOUS CLOCK SPEEDS
- ;
- FIXCNT: LDA CLOCK
- CPI 1
- RZ
- PUSH D
- PUSH H
- POP D
- CNTMUL: DAD D
- DCR A
- JNZ CNTMUL
- POP D
- RET
- ;
- COMPLIST:
- DB 6, 'S', 'R', 'T', 'E', 'H', 'L'
- ILCOMP:
- INLNCOMP ;A LIB MACRO
- INBUFF:
- INBUF ;A LIB MACRO
- ;
- ;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
- ; JMP BDOSRT ;BUT BE CAREFUL OF CONTROL-C
- ;
- CPMLINE:
- CMDLINE ;A LIB MACRO
- DIRLST:
- DIRLIST ;A LIB MACRO
- SENDTIM:
- SENDTIME ;A LIB MACRO
- BAUDPRT:
- PRTBAUD ;A LIB MACRO
- 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'
- LOCCHFLG:
- DB 'L'
- 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:
- DB 'B' ;BATCH FLAG (WHY WAS THIS DISABLED IN EARLIER VERS?)
- OPTBE EQU $
-
- RESTROPT: ;MUST BE IN SAME ORDER AS TABLE ABOVE
- DB 'A','D','O','Q','R','S','V','T','L'
- DB '0','1','B'
- ;
- ;THE NEXT 13 BYTES EQUAL THE NUMBER OF BYTES BETWEEN SECTNOB AND SECTNOE
- RESTSN:
- DB 0,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 ; \
- ERRCDE: DB 0 ; \
- EOFLG: DB 0 ; \ 13 BYTES BETWEEN TABLE MARKERS
- SECPTR: DW DBUF ; /
- SECINBF: DB 0 ; /
- MAXEXT: DB 0 ; /
- RCNT: DW 0 ; /
- DATAFLG: DB 0 ;/
- SECTNOE EQU $ ;END OF TABLE MARKER
- ;
- MODCTLB: DB 07FH
- UARTFLG: DB TRUE
- UARTCTLB: DB ANSWMOD ;(WAS PREVIOUSLY ORIGMOD)
- 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)
- EXITFLG: DB TRUE
- HLSAVE: DW BOTTRAM
- HLSAVE1: DW BOTTRAM
- HLSAVE2: DW BOTTRAM
- CMDBUF: DB 80H,0
- DS 80H
- DISKNO: DS 1
- DISKSAV: DS 1
- SAVUSR: DS 1
- SENDFLG: DS 1
- NBSAVE: DS 2
- BGNMS: DS 2
- FILECT: DS 1
- NAMECT: DS 1
- ORIGSAV: DS 1
- FTYCNT: DS 1
- DS 100
- STACK: DS 2
- FCB3: DS 33
- FCB4: 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
- LSTOUT EQU 5
- 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
- USER EQU 32
- 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
-