home *** CD-ROM | disk | FTP | other *** search
- ;MODEM.ASM V2.21, ORIGINALLY BY WARD CHRISTENSEN
- ; This version will assemble directly for an Intel MDS Series II
- ;
- ; (REVISED 04/19/82)
- ;
- ;CP/M - CP/M FILE TRANSFER PROGRAM, AND TERMINAL PROGRAM.
- ;
- ;
- ;--PRESENT CONFIGURATION--
- ;THIS FILE WILL ASSEMBLE WITHOUT EDITING FOR THE FOLLOWING:
- ;
- ; A 2 MHz clock
- ; External modem
- ; Ported I/O
- ; Standart CP/M
- ; Retry 10 times on block transfer error
- ; 5 drives (A-E) <-- see MAXDRV equate
- ; 16K disk buffer size
- ; Send stop 4 characters early for ascii capture
- ; Don't go to terminal mode before a file transfer.
- ;
- ;--> IF YOU CHANGE ANY CONDITIONALS
- ; PLEASE CHANGE THESE COMMENTS, TOO.
- ;
- ;--> SEE EQUATES FOR OTHER MODEMS & ADDITIONAL OPTIONS.
- ;
- ;* * * * * * * * * * * * * * * * * * * * * * * * *
- ;* *
- ;* THIS PROGRAM DOCUMENTED IN "MODEM.DOC" *
- ;* *
- ;* * * * * * * * * * * * * * * * * * * * * * * * *
- ;* THIS PROGRAM WAS "MODEM.ASM" BUT IS *
- ;* TEMPORARILY NAMED "MODEM2XX.ASM" SO PEOPLE *
- ;* WILL REALIZE IT IS AN ENHANCEMENT OF THE *
- ;* ORIGINAL PROGRAM "MODEM.ASM" ON CP/M USER'S *
- ;* GROUP DISK 25. *
- ;* * * * * * * * * * * * * * * * * * * * * * * * *
- ;
- ;MODIFICATIONS/FIXES:
- ;(IN REVERSE ORDER TO MINIMIZE READING TIME)
- ; (4/19/82)
- ; Added a section of code to reset the receiving
- ; device (usart, etc) on detection of an error
- ; (framing, parity, or overrun). The routine used
- ; is called RESRCVR ("reset receiver") and has
- ; conditional assemblies for the different types
- ; of devices. I have an i8251 usart and have
- ; implemented the particular code for that device,
- ; but since I no very little about the other
- ; commonly used devices, you will have to insert
- ; code for your device.
- ; This code was necessary for me since when toggling
- ; between terminal mode and send/receive mode it
- ; is very likely that the usart will detect an
- ; overrun error and since until now there was no
- ; reset to the usart, the one overrun would be
- ; detected as many times as the program "retried"
- ; the transfer and would always terminate.
- ; Again, remember to add your code if you don't
- ; have an i8251 usart. Put it in a conditional in
- ; the routine RESRCVR and put the reset code in
- ; the symbol RSTCODE.
- ; Dave Mabry
- ;
- ; 04/14/82
- ;SET DMA TO DEFAULT BUFFER IN CNREC TO CALC PROG
- ;SIZE CORRECTLY AFTER ASCII CAPTURE AND BEFORE
- ;FILE XFER. LEAVE ROOM FOR CCP BEYOND ASCBUF BY
- ;FIXING MEMEND. SEPARATE EQUATES FOR X6850 AND X8251
- ;FOR BASE I/O ADDRESS TO ALLOW BOTH IN FILE AT
- ;ONCE FOR MULTIPLE LOCAL MACHINES. MAKE FILE XFERS
- ;BUFFER SIZE ALTERABLE WITH DBUFSIZ EQUATE. CHECK
- ;FOR FILE ALREADY EXISTS ON ASCII CAPTURE THEN
- ;VERIFY BEFORE DELETING IT. PRINT OUT SECTOR #'S
- ;IN DECIMAL AND HEX ON SEND OR RECEIVE. ADJUST
- ;SEND AND RECEIVE MSG ALGORITHMS TO LEAVE CURSOR
- ;AT END OF MSG, NOT FRONT. ALL THE ABOVE CHANGES
- ;MADE BY ADAPTING THE SAME CODE FROM MODEM7X WHEN
- ;POSSIBLE TO FACILITATE FUTURE MAINTENANCE.
- ;
- ; THERE IS A TIMEOUT PROBLEM WITH CRC RECEIVE
- ;WHEN THE SENDING PROGRAM HAS A LARGE BUFFER,
- ;LIKE 16K. THE PROBLEM IS THAT THE RECEIVING
- ;PROGRAM SENDS THE INITIAL "C" INSTEAD OF NAK,
- ;THEN THE SENDING PROGRAM GOES INTO CRC MODE
- ;AND GOES OFF TO LOAD UP THE 1ST BUFFER OF FILE.
- ;IF THE SENDING PROGRAM TAKES MORE THAN THE
- ;COMMON TIMEOUT OF 3 SECONDS TO LOAD UP BEFORE
- ;SENDING THE 1ST SECTOR, THEN THE RECEIVING
- ;PROGRAM MAY DECIDE TO SWITCH TO CHECKSUM MODE,
- ;AND EXPECT A CHECKSUM AFTER THE 1ST SECTOR.
- ;THE SENDING PROGRAM SENDS A CRC INSTEAD, WHICH
- ;LOOKS LIKE A BAD CHECKSUM, SO THE RECEIVING
- ;PROGRAM NAK'S IT. THIS GOES ON UNTIL BOTH
- ;REACH THEIR ERROR LIMITS, THEN GIVE UP. WHY
- ;HASN'T THIS PROBLEM SHOWN UP BEFORE? THE COMMON
- ;XMODEM PROGRAM V4.7 AND UP HAS A 10 SEC TIMEOUT
- ;ON THE RESPONSE TO THE 1ST "C", NOT 3 SEC,
- ;WHICH SHOULD BE LONG ENUFF FOR 16K TO LOAD.
- ;FURTHUR, XMODEM AND MODEM2XX PROGRAMS TRADITIONALLY
- ;ONLY LOADED 2K BUFFERS, WHICH LOAD UP IN UNDER
- ;3 SECS. THE ONLY COMMON CASE WOULD BE TRANSFERRING
- ;A FILE OF 16K OR MORE BETWEEN TWO MODEM7X PROGRAMS,
- ;WITH CRC, WHERE THE RECEIVER HAD 3 SEC TIMEOUT.
- ;NOTE THAT IF CRC IS NOT SPECIFIED, THERE IS NO
- ;PROBLEM. MY VOTE IS TO LENGTHEN THE TIMEOUT
- ;EVERYWHERE TO 7 SEC OR SO, TO GIVE THE SENDER
- ;PLENTY OF TIME, BECAUSE THE 16K IS MUCH EASIER
- ;ON THE DISK, AND A SHADE FASTER TOO. SO THAT HAS
- ;BEEN DONE HERE. IF YOU GET BIT BY THIS, CHANGE
- ;DBUFSIZ TO 2K, AND THE 3 SEC LIMITATION SHOULD
- ;THEN SUFFICE. IF YOU CONTROL BOTH POINTS, WHICH
- ;SHOULD BE THE ONLY TIME TWO MODEMXX PROGRAMS
- ;TALK TO EACH OTHER, FIX BOTH ENDS. I REPEAT,
- ;THERE IS NO PROBLEM TALKING TO XMODEM.
- ;
- ; SINCE ASCII CAPTURE IS NOT IN EFFECT WHEN XFER
- ;IS GOING ON, EQUATE DBUF AND ASCBUF AT END OF
- ;PROGRAM. DID NOT CHANGE ASCBUF IN CASE FUTURE
- ;ENTERPRISING INDIVIDUALS CARE TO PRESERVE ASCII
- ;CAPTURE STATE OVER AN XFER. -- Steve Bogolub
- ;
- ; 3/31/82
- ;Added code to convert lower case to upper case and
- ;trap any illegal characters in filename given for
- ;ASCII capture. Added MAXDRV equate so that a non-
- ;valid drive will be trapped here, rather that bomb
- ;out of modem program with a BDOS error. Added code
- ;to force ASCII capture file closed if it is open
- ;when terminal mode is exited, or disconnect command
- ;is given. Added several new messages.
- ; James Underwood (N6CFI)
- ;
- ; 3/28/82
- ;Removed a call to PRINTER in the terminal mode that
- ;caused double printing of locally typed characters because
- ;they were printed when sent, and when echoed by the
- ;remote system. Also changed all occurances of 'H89' in IF
- ;statements to 'X8250' so that external 8250 chips are
- ;properly supported. Added a place for modem base port
- ;equate when X8250 and NOT H89 to eliminate an undefined
- ;symbol error. Fixed TRS and PMMI equates to eliminate
- ;doubly defined symbol errors. Cleaned up file and
- ;greatly simplified TRS and H89 sections.
- ; James Underwood (N6CFI)
- ;
- ; 2/21/82
- ;Cleaned up file, corrected HELP menu, changed
- ;settings for more "standard" machine, set error
- ;retries back to 10, made all lines 80 chars or less,
- ;added check for null filename in capture routines, and
- ;since the program already suffers from the most advanced
- ;case of RAMPANT FEATUREITIS known, added VIDEO mode for
- ;for use on VIDEO terminals. (Error msgs will be printed
- ;on separate lines, but successful "awaiting" or "sending"
- ;messages will overprint.) The spooling function still doesn't
- ;work the way I think it should, but it does work the way the
- ;original author intended it to (I think).
- ; (Dave Hardy)
- ;
- ; 1/31/82
- ;Implemented ascii capture feature and hardcopy
- ;option similar to that found in CCP. Added code
- ;for Heath H89/Zenith Z89 and for the 8250 ACE.
- ; (Mark McGee)
- ;
- ; 10/22/81
- ;Changed PMMI port equates to be relative to the
- ;first port equ, thus to change PMMI port values
- ;one only has to change one address. Removed the
- ;PMMI from the IF for INITREQ since PMMI does not
- ;require port initialization and in fact if it is
- ;initialized with INITREQ, the line will be lost.
- ;Changed receive sector routine so that on the
- ;first time thru when CRC is being used, it only
- ;waits for 3 seconds to receive the SOH after
- ;sending the initial 'C'. If a character is not
- ;received in 3 seconds, then a NAK is sent and this
- ;program switches to checksum mode. This allows
- ;the CRC MODEM to be used with versions of XMODEM
- ;that do not support CRC, even when MODEM has
- ;specified a CRC transmission. The transmission
- ;will then take place using checksum instead of
- ;CRC.
- ; Changed the default baud rate for the PMMI
- ;to an equate. By changing the 'DEFBAUD EQU', the
- ;default baud rate for the PMMI can set to any rate.
- ;Grouped all of the EQU's for the PMMI under one 'IF'
- ;statement for ease of maintenance and documentation
- ;purposes.
- ; Added equate(TERMNL EQU) to give one the option
- ;of whether or not to go to terminal mode before a
- ;file transfer.
- ; (John Mahr)
- ;
- ; 10/19/81
- ;FIXED 'SEND #' AND 'AWAITING #' STATEMENTS TO
- ;PROPERLY DISPLAY THE CURRENT SECTOR # BEING SENT OR
- ;RECEIVED. FIXED SEND MSG TO DISPLAY PROPER NUMBER
- ;OF RECORDS IN THE FILE TO BE SENT (FILES LARGER THAN
- ;1 EXTENT) USING THE SAME ROUTINES FOUND IN XMODEM43.
- ;IF NO OPTIONS SELECTED ON INITIAL ENTRY, JUMP TO
- ;'BADOPT' WITHOUT INITIALIZING MODEM. FIXED THE EQUATES
- ;FOR THE DCH ERROR MASKS FOR PARITY, OVERRUN & FRAMING.
- ;MADE A SEPARATE CONDITIONAL ASSEMBLY FOR DCH & X6850
- ;UART EQUATES (JUST IN CASE THE X6850 INFO WAS CORRECT)
- ;AND ELIMINATED THE DCH "INITC1" THRU "INITC4" EQUATES
- ;SINCE THEY ARE NOT USED BY DCH DURING THE "INITMD"
- ;CONDITIONAL ASSEMBLY. (BILL ATEN)
- ;
- ; 10/12/81
- ;ADDED CYCLIC REDUNDANCY CHECK OPTION ON THE FILE
- ;RECEIVE OPTION. THIS IN ANOTHER SECONDARY OPTION
- ;THAT IS SPECIFIED BY SPECIFYING A 'C'.
- ; MODEM RC.600 fn.ft
- ; MODEM ROC.300 fn.ft, etc.
- ; NOTE: CANNOT HAVE MORE THAN 6 SEC OPTIONS.
- ;WHEN THE FILE RECEIVE SPECIFIES CRC, THE LETTER 'C' IS
- ;SENT IN PLACE OF THE INITIAL NAK. THIS SIGNALS THE SENDER
- ;(XMODEM45+ or MODEM213+) THAT CRC IS IN EFFECT. THE SENDING
- ;PROGRAM WILL AUTOMATICALLY SWITCH TO CRC MODE. THE CRC
- ;WILL REPLACE THE CHECKSUM METHOD OF CHECKING FOR DATA
- ;INTEGRITY ON FILE TRANSMISSIONS. CRC WILL GIVE BETTER
- ;THAN A 99.99% PROBABILITY THAT THERE ARE NO DATA INTEGRITY
- ;ERRORS. ACKNOWLEDGEMENT AND THANKS TO PAUL HANSKNECHT
- ;WHO DESIGNED AND WROTE CRC120. IT IS THE CRC120 MACRO
- ;THAT WAS USED TO IMPLEMENT CRC IN THIS PROGRAM.
- ; (JOHN MAHR)
- ;
- ; 10/08/81
- ;ADDED TRS80 MODEL I SUPPORT INCLUDING BAUD RATE
- ;SELECT FROM COMMAND LINE. (MARK C WEHMHOEFER)
- ;
- ; 10/02/81
- ;FIXED RCVFILE BUG IN 10/1 VERSION. REVISED MOST
- ;MESSAGES TO UPPER & LOWER CASE. CHANGED RCVFILE SO
- ;IT SENDS THE INITIAL NAK AS SOON AS THE FILE IS OPEN,
- ;WITHOUT WAITING FOR A TIMEOUT FIRST. (DHH)
- ; *NOTE: A FILE TRANSFER WILL FAIL IF THE SEND
- ; END IS NOT STARTED BEFORE THE RECEIVE
- ; END WHEN THERE IS NO WAIT BEFORE
- ; SENDING THE INITIAL NAK OR CRC
- ; REQUEST. (10/12/81, JRM)
- ;
- ; 10/02/81
- ;FIXED DUPLICATE EQUATE FOR BASE ADDRESS, REMOVED UNUSED
- ;EQUATE FOR H8CPM. (KBP)
- ;
- ; 10/01/81
- ;ADDED ERROR MASKS FOR HAYES MICROMODEM & 6850 ACIA.
- ;ADDED "X6850" CONDITIONAL. ADDED "PORTED" CONDITIONAL
- ;TO ALLOW USE ON MEMORY-MAPPED SYSTEMS SUCH AS THE
- ;APPLE II. COLLECTED MODEM PRIMITIVE OPERATIONS TO
- ;FRONT OF PROGRAM. MADE RCV ERROR CHECKING ACTIVE FOR
- ;ALL MODEMS. (DAV HOLLE)
- ;
- ; 9/11/81
- ;FIXED BUG IN 6/2 MOD. ADDED BELL TO CERTAIN ERROR MSGS.
- ;ADDED R & S OPTIONS MSGS. CHANGED MULTI TO X8251
- ;CONDITIONAL & MOVED WITH MODEM TYPES. CHANGED SIGNON
- ;VERSION MESSAGE. (TED SHAPIN)
- ;
- ; 06/02/81
- ;ADDED BELL WHEN TRANSFER IS FINISHED. SHORTENED LABELS
- ;TO 6 CHARS SO OTHER ASSEMBLERS WILL WORK.
- ;ADDED CALL TO 'TERM' FROM BOTH SEND AND RECEIVE. THIS
- ;LETS YOU CONTROL THE REMOTE SYSTEM BEFORE TRANSMISSION.
- ;AFTER YOU LOG ON, ETC., AND TYPE "XMODEM R FOO.ASM"
- ;OR WHATEVER. YOU CAN THEN TYPE CONTROL-E TO PUT THIS PROGRAM
- ;INTO SEND OR RECEIVE MODE. (TED SHAPIN, ORANGE, CA.)
- ;
- ; 05/07/81
- ;ADDED TRAPS FOR AMBIGUOUS FILE NAME OR NONE AT ALL.
- ;REARRANGED EQUATES FOR GREATER CLARITY. CLEANED UP
- ;FILE. (KBP)
- ;
- ; 05/02/81
- ;ADDED THE ABILITY TO DISPLAY MODEM STATUS ON A
- ;FRONT PANEL, IF ONE HAS ONE (SUCH AS AN ITHACA
- ;INTERSYSTEMS DPS-1).
- ; 1. FRNTPNL EQU TRUE TURNS IT ON
- ; 2. PANEL EQU 0FFH (SETS UP PORT ADDRESS
- ; OF FRONT PANEL) (JOHN MAHR)
- ;
- ; 05/01/81
- ;RESTORED HELP DISPLAY. LOWER CASG CHARS AND TABS
- ;HAD BEEN TAKEN OUT. ADDED TYPICAL EXTERNAL PORT
- ;EQUATES AND INIT VALUES. REARRANGED ORDER OF
- ;MODIFICATION/FIXES INFO. (KBP)
- ;
- ; 04/18/81
- ;ADDED DETECTION OF FRAMING ERRORS, OVERRUN ERRORS,
- ;PARITY ERRORS (IF PARITY IS USED) FOR THE RECEIVE
- ;FILE ROUTINE. THIS FEATURE IS ONLY ACTIVE FOR
- ;THE PMMI MODEM, SINCE I DO NOT KNOW WHAT THE MODEM
- ;STATUS BITS ARE FOR IDS AND D.C. HAYES MODEMS.
- ;IF THERE IS ONE OF THE MENTIONED ERRORS, THE LINE
- ;WILL BE PURGED FOR THAT BLOCK AND A NAK WILL BE
- ;SENT TO THE SENDER FOR THAT BLOCK. A MESSAGE TO
- ;OPERATOR WILL ALSO BE DISPLAYED. (BY JOHN MAHR)
- ;
- ; 05/27/80
- ;ELIMINATED CONTROL-X CANCEL OF SEND FEATURE, AT
- ;SUGGESTION OF WARD CHRISTENSEN. A LINE GLITCH COULD
- ;CAUSE PREMATURE ABORT WHEN THIS FEATURE WAS ACTIVE.
- ;ADDED EQUATES FOR FALSE AND TRUE TO MAKE ASSEMBLY
- ;OPTIONS CLEARER. REMOVED H8 PORT EQUATES (THEY CAN
- ;BE PUT IN EXTERNAL MODEM EQUATES). (KBP)
- ;
- ; 12/06/79
- ;CORRECTED ERROR IN HELP FILE. SAID T.110, NOW SAYS
- ;TO.110. BY WARD CHRISTENSEN. CORRECTED RECEIVE FILE
- ;ROUTINE SO TERMINAL OR ECHO MODE WORKS AFTER FILE
- ;TRANSFER IN QUIET MODE. MOVED CHECKS FOR "H" AND
- ;"X" OPTIONS SO MODEM IS NOT REINITIALIZED. (KBP)
- ;
- ; 08/06/79
- ;ADDED EQUATES FOR EXTERNAL MODEM (NOT S-100 PLUG-IN)
- ;(KBP)
- ;
- ; 08/05/79
- ;ADDED D.C. HAYES MODEM SUPPORT BY JIM BELL (KBP)
- ;
- ; 07/24/79
- ;MOVE INITIALIZE LOCAL STACK TO BEGINNING OF PROGRAM
- ;SO DEFAULT STACK IS NOT USED. ADD CONDITIONAL ASSEMBLY
- ;OPTION TO TERMINAL ROUTINE FOR TIMESHARE SYSTEMS.
- ;CORRECT ERROR IN LOCAL ABORT ROUTINE (WAS LOOKING FOR
- ;CONTROL-E - NOW CORRECTLY LOOKS FOR CONTROL-X). ADD
- ;REGISTER SAVES TO CONOUT, KEYIN AND KEYBOARD STATUS
- ;ROUTINES, AS SOME CBIOS ROUTINES CLOBBER THEM. (KBP)
- ;
- ; 07/01/79
- ;MODIFIED PROGRAM TO ALLOW FOR NON-STANDARD VERSIONS OF
- ;CP/M. ALL REFERENCES TO ENTRIES INTO CP/M SHOULD BE MADE
- ;RELATIVE TO THE VARIABLE SYMBOL CALLED "BASE". FOR EXAMPLE,
- ;THE EQUATE TO BDOS SHOULD BE BASE+5 INSTEAD OF 5. BASE
- ;WILL BE SET TO 0 WHEN THE VARIABLE STDCPM IS SET TO TRUE.
- ;(BOB MATHIAS).
- ;
- ; 05/24/79
- ;FIXED MISSING RETURN INSTRUCTION AT END OF
- ;INITIALIZATION ROUTINE. (KBP)
- ;
- ; 05/22/79
- ;ADDED FEATURE TO MAKE RECEIVE FILE ROUTINE SAY
- ;FILE SUCCESSFULLY OPENED, WHEN IN QUIET MODE.
- ;MOVED INITIAL 'GOBBLE GARBAGE INPUTS' TO BEFORE
- ;COMMAND CPI'S SO ALL MODES ARE CLEARED. CHANGED
- ;INITIAL SEND WAIT TO 80 SECS TO ALLOW MORE TIME
- ;FOR RECEIVING END TO COME UP. ADDED 'H' AFTER MSG
- ;THAT SHOWS NUMBER OF SECTORS IN EXTENT ABOUT TO
- ;BE SENT. (KBP)
- ;
- ; 05/09/79
- ;ALLOW 'T' AND 'E' SUB-OPTIONS TO GO TO TERMINAL
- ;OR ECHO MODE AFTER TRANSFERRING A FILE. (WLC)
- ;
- ; 04/26/79
- ;REWRITTEN BY WARD CHRISTENSEN TO COMBINE
- ;IMPROVEMENTS TO THE ORIGINAL MADE BY WARD
- ;AND BY KEITH PETERSEN, W8SDZ, AND SUGGESTIONS
- ;BY JIM BELL WHICH KEITH IMPLEMENTED. SEE
- ;MODEM.DOC FOR ADDITIONAL HISTORICAL
- ;INFORMATION AND DOCUMENTATION.
- ;
- ; 09/23/77
- ;ORIGINALLY WRITTEN BY WARD CHRISTENSEN
- ;
- ; --------------
- ;
- ;NOTE: IF YOU ADD IMPROVEMENTS OR OTHERWISE UPDATE
- ;THIS PROGRAM, PLEASE MODEM A COPY OF THE NEW FILE
- ;TO "TECHNICAL CBBS" IN DEARBORN, MICHIGAN - PHONE
- ;313-846-6127 (110, 300, 450 OR 600 BAUD). USE THE
- ;FILENAME MODEM.NEW. (KBP)
- ;
- ; --------------
- ; DEFINE EQUATES
- ;
- FALSE EQU 0
- TRUE EQU NOT FALSE
- ;
- STDCPM EQU TRUE ;TRUE, IS STANDARD CP/M
- ALTCPM EQU FALSE ;TRUE, IS ALTERNATE CP/M FOR H8 OR TRS80
- DBUFSIZ EQU 16 ;BUFFER SIZE IN KBYTES
- ;
- ; DEFINE TYPE OF CP/M IN USE
- ;
- IF STDCPM
- BASE EQU 0 ;CP/M BASE ADDRESS
- ENDIF
- ;
- IF ALTCPM
- BASE EQU 4200H ;CP/M BASE ADDRESS FOR ALTERNATE CP/M
- ENDIF
- ;
- ; DEFINE MODEM INTERFACE
- ;
- DCH EQU FALSE ;TRUE, IS D.C. HAYES MODEM
- PMMI EQU FALSE ;TRUE, IS PMMI MODEM
- H89 EQU FALSE ;TRUE, IS HEATH H89
- ;BE SURE X8250 IS ALSO TRUE
- TRS EQU FALSE ;TRUE FOR TRS80 MODEL I
- ;BE SURE X8251 IS ALSO TRUE
- ;
- X8250 EQU FALSE ;TRUE, IS EXTERNAL 8250 ACE
- X8251 EQU TRUE ;TRUE, IS EXTERNAL 8251 USART
- X6850 EQU FALSE ;TRUE, IS EXTERNAL 6850 ACIA
- ;
- PORTED EQU TRUE ;TRUE FOR IN/OUT PORTS, FALSE FOR LDA/STA
- INITREQ EQU TRUE ;TRUE IF PORT MODEM CONNECTED TO...
- ; ...REQUIRES INITIALIZATION.
- MAXDRV EQU 'E' ;MAX DRIVE ON SYSTEM
- ;
- ; DEFINE OTHER SYSTEM PARAMETERS
- ;
- FASTCLK EQU FALSE ;TRUE FOR 4 MHZ CLOCK, FALSE FOR 2 MHZ
- FRNTPNL EQU FALSE ;TRUE FOR FRONT PANEL DISPLAY
- VIDEO EQU FALSE ;TRUE FOR USE WITH VIDEO TERMINAL
- TERMNL EQU FALSE ;TRUE, GO TO TERMINAL MODE BEFORE..
- ; ...FILE TRANSFER.
- ;
- IF FRNTPNL
- PANEL EQU 0FFH ;PORT ADDRESS FOR FRONT PANEL
- ENDIF
- ;
- ; SOME TIME-SHARE COMPUTERS REQUIRE TERMINALS TO
- ; HAVE BIT 7 HIGH (MARKING), SO IN THE TERMINAL
- ; MODE WE FORCE IT TO HIGH IF THE FOLLOWING OPTION
- ; IS SELECTED:
- ;
- TIMESHR EQU FALSE ;TRUE TO MAKE BIT 7 HIGH
- ;*****************************************************************************
- IF PMMI
- ; SET DCH=FALSE,H89=FALSE,PMMI=TRUE,X8250=FALSE,X8251=FALSE,
- ; X6850=FALSE,PORTED=TRUE,INITREQ=FALSE
- ;
- ; THESE EQUATES SET ALL OF THE VALUES NECESSARY TO USE A PMMI.
- ; THE ONLY ONE THAT SHOULD EVER HAVE TO BE CHANGED IS MDCTLP
- ; WHICH IS THE ADDRESS OF THE FIRST PORT ON THE PMMI. THIS
- ; ADDRESS IS SET BY SWITCHES ON THE PMMI CARD.
- ;
- MDCTLP EQU 0E0H ;PMMI VALUES (BASE ADDR OF I/O PORTS)
- MDDATP EQU MDCTLP+1 ;DATA PORT
- BAUDRP EQU MDCTLP+2 ;BAUD RATE OUTPUT
- MDCTL2 EQU MDCTLP+3 ;SECOND CTL PORT
- ORIGMD EQU 1DH ;8 DATA, NO PARITY, ORIG
- ANSWMD EQU 1EH ;8 DATA, NO PARITY, ANSW
- ;
- FRMER EQU 20H ;FRAMING ERROR MASK
- ORUNER EQU 10H ;OVERRUN ERROR MASK
- PARER EQU 08H ;PARITY ERROR MASK
- ;
- MDSNDB EQU 1 ;BIT TO TEST FOR SEND
- MDSNDR EQU 1 ;VALUE WHEN READY
- MDRCVB EQU 2 ;BIT TO TEST FOR RECEIVE
- MDRCVR EQU 2 ;VALUE WHEN READY
- ;
- DEFBAUD EQU 52 ;DEFAULT TO 300 BAUD
- ;USE 52 FOR 300 BAUD
- ;USE 26 FOR 600 BAUD
- ;USE 104 FOR 150 BAUD
- ;USE 142 FOR 110 BAUD
- ENDIF ;PMMI
- ;*****************************************************************************
- IF DCH
- MDCTLP EQU 82H ;D. C. HAYES VALUES
- MDDATP EQU 80H ;DATA PORT
- MDCTL2 EQU 81H ;SECOND CTL PORT
- ;
- ; NOTE: BAUD RATE DEFAULTS TO 300 - 1 STOP BIT.
- ; DO NOT CHANGE NEXT EQUATES:
- ;
- ORIGMD EQU 86H ;OFF HOOK, 110 BAUD, CAR. ON, ORIG.
- ANSWMD EQU 82H ;OFF HOOK, 110 BAUD, CAR. ON, ANSW.
- ENDIF ;DCH
- ;*****************************************************************************
- ;
- ; FOR APPLE CARDS: PORTED=FALSE AND X6850=TRUE, AND
- ; MDDATP IS 1 MORE THAN MDCTLP. FOR SSM AIO, APPLE COM
- ; CARD, OR CCS 7710 USE MDCTLP=0E0ACH (FOR SLOT 2), OR
- ; USE 0E0AEH FOR MICROMODEM II. FOR DIFFERENT SLOTS,
- ; ADD (SLOT-2)*10H TO THE ABOVE ADDRESSES.
- ;
- ;-->IF USING EXTERNAL MODEM WITH 8250, 8251 OR 6850
- ;-->CHIP, CHANGE THESE EQUATES TO YOUR SYSTEM REQUIREMENTS
- ;
- IF X6850
- MDCTLP EQU 0E0AEH ;MODEM CONTROL PORT
- MDDATP EQU MDCTLP+1 ;MODEM DATA PORT
- ENDIF ;X6850
- ;
- IF X8251
- MDCTLP EQU 0F7H ;MODEM CONTROL PORT
- MDDATP EQU MDCTLP-1 ;MODEM DATA PORT
- ENDIF ;X8251
- ;
- IF X8250 AND NOT H89
- MDDATP EQU 60H ;YOUR MODEM DATA PORT
- ENDIF ;X8250 AND NOT H89
- ;
- ;-->END OF EXTERNAL MODEM BASE EQUATES
- ;
- ;*****************************************************************************
- IF H89
- ;FOR H89 SET THESE TRUE, ALL OTHERS FALSE:
- ; H89,X8250,PORTED,STDCPM
- ;
- MDDATP EQU 0D8H ;HEATH MODEM PORT BASE ADDRESS
- ENDIF ;H89
- ;*****************************************************************************
- IF TRS
- ;FOR TRS SET THESE TRUE, ALL OTHERS FALSE:
- ; TRS,X8251,PORTED,ALTCPM
- ;
- MDCTLP EQU 0EAH ;TRS-80 WITH RS232 VALUES
- MDDATP EQU 0EBH ;DATA PORT
- ENDIF ;H89
- ;*****************************************************************************
- IF X8250
- MDCTL1 EQU MDDATP+1 ;INTERRUPT CONTROL
- MDCTL3 EQU MDDATP+3 ;WORD CHARACTERISTICS
- MDCTL4 EQU MDDATP+4 ;LINE CONTROL
- MDCTL5 EQU MDDATP+5 ;LINE STATUS
- ENDIF ;X8250
- ;*****************************************************************************
- ;
- ; THESE EQUATES SPECIFY THE INITIALIZATION SEQUENCE
- ; AND STATUS FLAGS USED BY YOUR TYPE OF MODEM.
- ;
- ;
- IF X8251
- INITC1 EQU 00H ;1ST INIT CHAR TO 8251 CTL PORT
- INITC2 EQU 00H ;2ND
- INITC3 EQU 00H ;3RD
- INITC4 EQU 37H ;4TH
- ;
- RSTCODE EQU 37H ; Reset error, set DTR,
- ; enable receiver and
- ; transmitter
- ;
- FRMER EQU 20H ;FRAMING ERR MASK
- ORUNER EQU 10H ;OVERRUN ERR MASK
- PARER EQU 08H ;PARITY ERR MASK
- ;
- MDSNDB EQU 1 ;BIT TO TEST FOR SEND
- MDSNDR EQU 1 ;VALUE WHEN READY
- MDRCVB EQU 2 ;BIT TO TEST FOR RECEIVE
- MDRCVR EQU 2 ;VALUE WHEN READY
- ENDIF ;X8251
- ;*****************************************************************************
- IF X8250
- INITC1 EQU 83H ;ACCESS DIVISOR LATCHES
- INITC2 EQU 03H ;SET DTR AND RTS
- INITC3 EQU 80H ;LOW BAUD DIVISOR (300 BAUD)
- INITC4 EQU 01H ;HIGH BAUD DIVISOR (300 BAUD)
- INITC5 EQU 03H ;8 BITS,1 STOP, NO PARITY
- INITC6 EQU 00H ;DISABLE ALL INTERRUPTS
- ;
- FRMER EQU 08H ;FRAMING ERR MASK
- ORUNER EQU 02H ;OVERRUN ERR MASK
- PARER EQU 04H ;PARITY ERR MASK
- ;
- MDSNDB EQU 20H ;BIT TO TEST FOR SEND
- MDSNDR EQU 20H ;VALUE WHEN READY
- MDRCVB EQU 01H ;BIT TO TEST FOR RECEIVE
- MDRCVR EQU 01H ;VALUE WHEN READY
- ENDIF ;X8250
- ******************************************************************************
- IF DCH
- PARER EQU 04H ;PARITY ERR MASK
- FRMER EQU 08H ;FRAMING ERR MASK
- ORUNER EQU 10H ;OVERRUN ERR MASK
- ;
- MDSNDB EQU 2 ;BIT TO TEST FOR SEND
- MDSNDR EQU 2 ;VALUE WHEN READY
- MDRCVB EQU 1 ;BIT TO TEST FOR RECEIVE
- MDRCVR EQU 1 ;VALUE WHEN READY
- ENDIF ;DCH
- ;*****************************************************************************
- IF X6850
- INITC1 EQU 3 ;1ST INIT CHAR TO 6850 CTL PORT
- INITC2 EQU 15H ;2ND, 8 DATA + 1 STOP + NO PARITY,
- ; 16X CLOCK. USE 16H FOR SAME WITH 64X
- ; CLOCK TO SWITCH FROM 1200 TO 300 BAUD,
- ; FOR EXAMPLE.
- INITC3 EQU INITC1 ;3RD (ONLY 2 NEEDED, REUSE 1 & 2)
- INITC4 EQU INITC2 ;4TH
- ;
- FRMER EQU 10H ;FRAMING ERR MASK
- ORUNER EQU 20H ;OVERRUN ERR MASK
- PARER EQU 40H ;PARITY ERR MASK
- ;
- MDSNDB EQU 2 ;BIT TO TEST FOR SEND
- MDSNDR EQU 2 ;VALUE WHEN READY
- MDRCVB EQU 1 ;BIT TO TEST FOR RECEIVE
- MDRCVR EQU 1 ;VALUE WHEN READY
- ENDIF ;X6850
- ;*****************************************************************************
- ;
- ; DEFINE SOME OTHER THINGS (NORMALLY NOT CHANGED)
- ;
- ERRLIM EQU 10 ;MAX ALLOWABLE ERRORS (10 STANDARD)
- STPTIME EQU 4 ;SEND STOP THIS MANY CHARS EARLY
- CPTRKEY EQU 'Y'-40H ;CTL-Y TOGGLES ASCII CAPTURE MODE
- DISCCHR EQU 'D'-40H ;CTL-D DISCONNECTS MODEM T/E
- EXITCHR EQU 'E'-40H ;CTL-E EXIT FROM T OR E
- PRTCHAR EQU 'P'-40H ;CTL-P TOGGLES PRINTER OPTION
- STRTCHR EQU 'Q'-40H ;CTL-Q TO MAKE OTHER END RESUME (MOST SYSTEMS
- ;WILL ACCEPT ANY CHAR,SO CTL-Q IS TO INCLUDE
- ;THE XON/XOFF PROTOCALL)
- STOPCHR EQU 'S'-40H ;CTL-S TO MAKE OTHER END PAUSE
- ;
- ; DEFINE ASCII CHARACTERS USED
- ;
- SOH EQU 1 ;START OF HEADER
- EOT EQU 4 ;END OF TRANSMISSION
- ACK EQU 6 ;ACKNOWLEDGE
- NAK EQU 15H ;NEG ACKNOWLEDGE
- CRC EQU 'C' ;USED TO REQUEST CRC INSTEAD OF CHECKSUM
- CAN EQU 18H ;CANCEL
- LF EQU 10 ;LINEFEED
- CR EQU 13 ;CARRIAGE RETURN
- BELL EQU 'G'-40H ;BELLS
- ;*****************************************************************************
- ORG BASE+100H
- ;
- ;INIT PRIVATE STACK
- LXI H,0 ;HL=0
- DAD SP ;HL=STACK FROM CP/M
- SHLD STACK ;..SAVE IT
- LXI SP,STACK ;SP=MY STACK
- LDA BASE+0007H ;BDOS PAGE ADDRESS
- SUI 8+1 ;ACCOUNT FOR CCP (2K) + 1 PG SLOP
- STA MEMEND ; AND SAVE THE RESULT
- CALL START ;GO PRINT ID
- DB 'MODEM ver 2.21A of 04/19/82'
- DB CR,LF,'$'
- ;
- ; MODEM I/O PRIMITIVES
- ;
- ; COLLECTED HERE FOR EASIER PATCHING & MAINTENANCE.
- ; PORTED I/O ROUTINES HAVE NOP'S TO LEAVE ROOM
- ; FOR LATER PATCHING TO LDA'S & STA'S IF NECESSARY.
- ;
- IF PORTED AND (NOT X8250)
- OUTDATA OUT MDDATP
- RET
- NOP
- INDATA IN MDDATP
- RET
- NOP
- OUTCTL OUT MDCTLP
- RET
- NOP
- INCTL IN MDCTLP
- RET
- NOP
- ENDIF ;PORTED AND (NOT X8250)
- ;
- IF PORTED AND X8250
- OUTDATA OUT MDDATP
- RET
- NOP
- INDATA IN MDDATP
- RET
- NOP
- OUTCTL1 OUT MDCTL1
- RET
- NOP
- OUTCTL3 OUT MDCTL3
- RET
- NOP
- OUTCTL4 OUT MDCTL4
- RET
- NOP
- INCTL5 IN MDCTL5
- RET
- NOP
- ENDIF ;PORTED AND X8250
- ;
- IF PORTED AND (DCH OR PMMI)
- OUTCT2 OUT MDCTL2
- RET
- NOP
- INCT2 IN MDCTL2
- RET
- NOP
- ENDIF ;PORTED AND (DCH OR PMMI)
- ;
- IF PORTED AND PMMI
- OUTBRP OUT BAUDRP
- RET
- NOP
- ENDIF ;PORTED AND PMMI
- ;
- IF PORTED AND FRNTPNL
- OUTPAN OUT PANEL
- RET
- NOP
- ENDIF ;PORTED AND FRNTPNL
- ;
- IF NOT PORTED
- OUTDATA STA MDDATP
- RET
- INDATA LDA MDDATP
- RET
- OUTCTL STA MDCTLP
- RET
- INCTL LDA MDCTLP
- RET
- ENDIF ;NOT PORTED
- ;
- IF (NOT PORTED) AND (DCH OR PMMI)
- OUTCT2 STA MDCTL2
- RET
- INCT2 LDA MDCTL2
- RET
- ENDIF ;(NOT PORTED) AND (DCH OR PMMI)
- ;
- IF PMMI AND NOT PORTED
- OUTBRP STA BAUDRP
- RET
- ENDIF ;PMMI AND NOT PORTED
- ;
- IF FRNTPNL AND NOT PORTED
- OUTPAN STA PANEL
- RET
- ENDIF ;FRNTPNL AND NOT PORTED
- ;
- START POP D ;GET ID MESSAGE
- MVI C,PRINT
- CALL BDOS ;PRINT ID MESSAGE
- ;
- ; INITIALIZE THE JMPS TO CP/M BIOS
- ;
- CALL INITADR
- ;
- LDA FCB+1 ;GET PRIMARY OPTION
- CPI 'H' ;MODEM H(ELP)?
- JZ HELP ;..YES, GIVE HELP
- CPI ' ' ;NO OPTIONS?
- JZ BADOPT ;..EXPLAIN & GIVE HELP
- CPI 'X' ;MODEM X(AMPLES)?
- JZ EXAM ;GIVE EXAMPLES
- ;
- ; SAVE PRIMARY OPTION, VALIDATE SECONDARY OPT.
- ;
- CALL PROCOPT
- ;
- ; INIT THE MODEM OR SERIAL PORT
- ;
- CALL INITMD
- ;
- ; MOVE THE FILENAME FROM FCB 2 TO FCB 1
- ;
- CALL MOVEFCB
- ;
- ; GOBBLE UP GARBAGE CHARS FROM THE LINE
- ; PRIOR TO RECEIVE OR SEND
- ;
- CALL INDATA
- CALL INDATA
- ;
- ; JMP TO APPROPRIATE FUNCTION
- ;
- LDA OPTION ;GET PRIMARY OPTION
- ;
- CPI 'C' ;(COMPAT W/EARLIER
- JZ TRMECHO ;OPTION "COMPUTER")
- ;
- CPI 'E' ;TERMINAL IN ECHO
- JZ TRMECHO ;..MODE?
- ;
- CPI 'T' ;TERMINAL..
- JZ TERM ;..MODE?
- ;
- CPI 'D' ;DISCONNECT?
- JZ DISCONN
- ;
- CPI 'S' ;SEND..
-
- IF TERMNL ;GO TO TERMINAL MODE FIRST.
- JZ TSND ;..A FILE?
- ENDIF
- ;
- IF NOT TERMNL ;GO STRAIGHT TO FILE SEND
- JZ TERMX ;GO SEND A FILE
- ENDIF
- ;
- CPI 'R' ;RECEIVE..
- ;
- IF TERMNL ;GO TO TERMINAL MODE FIRST
- JZ TRCV ;..A FILE?
- ENDIF
- ;
- IF NOT TERMNL ;GO STRAIGHT TO FILE RECEIVE
- JZ TERMX ;RECEIVE A FILE
- ENDIF
- ;
- ;INVALID OPTION
- ;
- JMP BADOPT
- ;
- TSND: CALL ILPRT
- DB 'In terminal mode, Ctl-E to start SEND',CR,LF,0
- JMP TERM
- TRCV: CALL ILPRT
- DB 'In terminal mode, Ctl-E to start RECEIVE',CR,LF,0
- ;FALL THRU TO TERM
- ;
- ;* * * * * * * * * * * * * * * * * * * * *
- ;* *
- ;* TERM: TERMINAL MODE *
- ;* *
- ;* * * * * * * * * * * * * * * * * * * * *
- ;
- ; THIS PROGRAM SIMPLY SENDS KEYED CHARACTERS
- ; DOWN THE LINE, AND DISPLAYS CHARACTERS
- ; RECEIVED FROM THE LINE. THIS MAKES IT
- ; SUITABLE FOR COMMUNICATION WITH TIME SHARING
- ; COMPUTERS, CBBS'S, OR ANOTHER PROGRAM
- ; RUNNING "MODEM E" (ECHO MODE)
- ;
- ; TYPE THE "EXITCHR" (ORIGINALLY CTL-E) TO LEAVE TERM MODE,
- ; OR THE "DISCCHR" (ORIGINALLY CTL-D) TO DISCONNECT.
- ;
- ; ASCII CAPTURE IS TOGGLED BY ENTERING CTL-Y, AT WHICH TIME
- ; THE PROGRAM WILL PROMPT FOR THE DESIRED FILE NAME. THE FILE
- ; IS CLOSED BY AGAIN ENTERING CTL-Y.
- ;
- ; THE PRINTER OPTION WORKS JUST AS IN CCP - ENTER CTL-P TO
- ; TURN THE PRINTER ON, AND AGAIN TO TURN IT OFF.
- ;
- TERM CALL STAT ;LOCAL CHAR KEYED?
- JZ TERML ;..NO, CHECK LINE
- CALL KEYIN ;GET CHAR
- CPI EXITCHR ;TIME TO END?
- JZ TERMX ;YES, LEAVE TERMINAL MODE
- CPI DISCCHR ;DISCONNECT REQUEST?
- JZ DISCONN ;YES, DO IT
- ;
- CPI CPTRKEY ;TOGGLE CAPTURE MODE?
- CZ CPTRTOG ;YES, DO IT
- JZ TERM01 ;IF CAPTURE MODE COMMAND, DON'T SEND IT
- CPI PRTCHAR ;TOGGLE PRINTER MODE?
- CZ PRTRTOG ;YES, DO IT
- JZ TERM01 ;IF PRINTER TOGGLE, DON'T SEND IT
- ;
- IF TIMESHR
- ORI 80H ;FORCE BIT 7 TO HIGH
- ENDIF ;TIMESHR
- ;
- CALL OUTDATA ;SEND THE CHAR
- TERM01 EQU $
- ;
- ; SEE IF CHAR FROM LINE
- ;
- IF (NOT DCH) AND (NOT X8250)
- TERML CALL INCTL ;READ STATUS
- ENDIF
- ;
- IF X8250
- TERML CALL INCTL5 ;READ STATUS
- ENDIF
- ;
- IF DCH
- TERML CALL INCT2 ;READ STATUS
- ENDIF
- ;
- IF FRNTPNL AND PMMI
- CALL OUTPAN ;DISPLAY STATUS
- ENDIF
- ;
- ANI MDRCVB ;ISOLATE BIT
- CPI MDRCVR ;READY?
- JNZ TERM ;..NO, LOOP
- CALL INDATA ;READ DATA
- ANI 7FH ;STRIP PARITY BIT
- CALL TYPE ;TYPE IT
- CALL PRINTER ;SEND TO PRINTER IF ENABLED
- CALL ASCPTR ;SAVE TO DISK IF ENABLED
- JMP TERM ;LOOP
- ;
- TERMX: LDA CPTRFLG
- ORA A
- CNZ CPTRTOG ;IF CAPTURE WAS ON, TURN OFF
- LDA FIRST ;DON'T JUMP
- INR A ;TO SEND OR RECEIVE
- STA FIRST ;MORE THAN ONCE
- JNZ CKDIS ;CHECK DISCONNECT
- LDA OPTION ;PRIMARY OPTION
- CPI 'S' ;SEND?
- JZ SENDFIL ;..A FILE
- CPI 'R' ;RECEIVE
- JZ RCVFIL ;A FILE
- JMP CKDIS ;REALLY EXIT
- ;
- ;* * * * * * * * * * * * * * * * * * * * *
- ;* *
- ;* TRMECHO: TERMINAL WITH ECHO *
- ;* *
- ;* * * * * * * * * * * * * * * * * * * * *
- ;
- ; TERMINAL PROGRAM WITH ECHO - SEE NOTES
- ; UNDER "TERM" ABOVE
- ;
- ; C A U T I O N DON'T RUN WITH BOTH COMPUTERS
- ; IN "ECHO" MODE - LINE ERRORS (OR ANY CHAR)
- ; WILL BE ECHOED BACK AND FORTH AD INFINITUM.
- ;
- ; ASCII CAPTURE IS TOGGLED BY ENTERING CTL-Y, AT WHICH TIME
- ; THE PROGRAM WILL PROMPT FOR THE DESIRED FILE NAME. THE FILE
- ; IS CLOSED BY AGAIN ENTERING CTL-Y.
- ;
- ; THE PRINTER OPTION WORKS JUST AS IN CCP - ENTER CTL-P TO
- ; TURN THE PRINTER ON, AND AGAIN TO TURN IT OFF.
- ;
- IF (NOT DCH) AND (NOT X8250)
- TRMECHO CALL INCTL ;GET STATUS
- ENDIF
- ;
- IF X8250
- TRMECHO CALL INCTL5 ;GET STATUS
- ENDIF
- ;
- IF DCH
- TRMECHO CALL INCT2 ;GET STATUS
- ENDIF
- ;
- IF FRNTPNL AND PMMI
- OUT PANEL ;DISPLAY STATUS
- ENDIF
- ;
- ANI MDRCVB ;ISOLATE READY BIT
- CPI MDRCVR ;ARE WE READY?
- JZ LINECHR ;YES, READ THE CHR
- CALL STAT ;CHECK LOCAL KB
- JZ TRMECHO ;..NO CHAR
- CALL KEYIN ;GET LOCAL CHAR
- CPI EXITCHR ;END?
- JZ CKDIS ;YES, CK DISCONN, EXIT
- CPI DISCCHR ;DISCONN?
- JZ DISCONN ;..YES, DO IT.
- CPI CPTRKEY ;TOGGLE CAPTURE MODE?
- CZ CPTRTOG ;..YES, DO IT
- JZ TERM02 ;IF CAPTURE MODE COMMAND, DON'T SEND IT
- CPI PRTCHAR ;TOGGLE PRINTER MODE?
- CZ PRTRTOG ;..YES, DO IT
- JZ TERM02 ;IF PRINTER TOGGLE, DON'T SEND IT
- CALL OUTDATA ;SEND CHAR
- CALL TYPE ;ECHO IT LOCALLY
- CALL PRINTER ;SEND TO PRINTER IF ENABLED
- CALL ASCPTR ;SAVE IT TO DISK IF ENABLED
- TERM02 JMP TRMECHO ;..AND LOOP
- ;
- ; GOT CHAR FROM LINE
- ;
- LINECHR CALL INDATA ;GET CHAR
- ANI 7FH ;STRIP PARITY BIT
- CALL OUTDATA ;ECHO IT
- CALL TYPE ;TYPE IT
- CALL PRINTER ;SEND TO PRINTER IF ENABLED
- JMP TRMECHO ;LOOP
- ;
- ;* * * * * * * * * * * * * * * * * * * * *
- ;* *
- ;* SENDFIL: SENDS A CP/M FILE *
- ;* *
- ;* * * * * * * * * * * * * * * * * * * * *
- ;
- ; THE CP/M FILE SPECIFIED IN THE MODEM COMMAND
- ; IS TRANSFERRED OVER THE PHONE TO ANOTHER
- ; COMPUTER RUNNING MODEM WITH THE "R" (RECEIVE)
- ; OPTION. THE DATA IS SENT ONE SECTOR AT A
- ; TIME WITH HEADERS AND CHECKSUMS OR CYCLIC
- ; REDUNDANCY CHECKS. CYCLIC REDUNDANCY CHECK
- ; IS USED IF THE LETTER 'C' IS RECEIVED IN
- ; PLACE OF THE INITIAL NAK. IT IS INCORRECT
- ; TO SPECIFY CRC ON THE SEND (MODEM SC fn.ft),
- ; SINCE IT IS THE RECEIVER WHO DETERMINES
- ; WHETHER CRC IS TO BE USED. IF THERE IS AN
- ; ERROR, THE SECTOR IS RETRANSMITTED.
- ;
- SENDFIL CALL TRAP ;CHECK FOR NO NAME OR AMBIG. NAME
- CALL CNREC ;COMPUTE RECORD COUNT
- CALL OPENFIL ;OPEN THE FILE
- MVI E,80 ;WAIT 80 SEC..
- CALL WAITNAK ;..FOR INITIAL NAK
- ;
- SENDLP CALL RDSECT ;READ A SECTOR
- JC SENDEOF ;SEND EOF IF DONE
- CALL INCRSNO ;BUMP SECTOR #
- XRA A ;ZERO ERROR..
- STA ERRCT ;..COUNT
- ;
- SENDRPT CALL SENDHDR ;SEND A HEADER
- CALL SENDSEC ;SEND DATA SECTOR
- LDA CRCFLG ;GET CRC FLAG
- ORA A ;CRC IN EFFECT?
- CZ SENDCRC ;YES, GO SEND CRC
- CNZ SENDCKS ;NO, SEND CKSUM NOT CRC
- CALL GETACK ;GET THE ACK
- JC SENDRPT ;REPEAT IF NO ACK
- JMP SENDLP ;LOOP UNTIL EOF
- ;
- ; FILE SENT, SEND EOT'S
- ;
- SENDEOF MVI A,EOT ;SEND..
- CALL SEND ;..AN EOT
- CALL GETACK ;GET THE ACK
- JC SENDEOF ;LOOP IF NO ACK
- JMP DONE ;ALL DONE
- ;
- ;----> CNREC: Computes record count, and saves it
- ; until successful file OPEN.
- ;
- ; LOOK UP THE FCB IN THE DIRECTORY
- CNREC: MVI C,STDMA ;SET DMA ADDR TO
- LXI D,BASE+80H ; DEF BUFFER
- CALL BDOS ; SO DIR INFO WHERE SHOULD BE
- 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++',CR,LF,'$'
- ;
- ; 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,BASE+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
- ;
- ;
- ;* * * * * * * * * * * * * * * * * * * * *
- ;* *
- ;* RCVFIL: RECEIVE A FILE *
- ;* *
- ;* * * * * * * * * * * * * * * * * * * * *
- ;
- ; RECEIVES A FILE IN BLOCK FORMAT AS SENT
- ; BY ANOTHER PERSON DOING "MODEM S FN.FT".
- ; IF THE CRC SECONDARY OPTION (MODEM RC fn.ft)
- ; WAS CHOSEN, THE LETTER 'C' WILL BE SENT IN
- ; PLACE OF THE INITIAL NAK. IF A SECTOR IS
- ; RECEIVED IN ERROR, THEN A NAK IS SENT WHICH
- ; REQUESTS THAT THE SECTOR BE RESENT.
- ;
- RCVFIL CALL TRAP ;CHECK FOR NO NAME OR AMBIG. NAME
- CALL ERASFIL ;ERASE THE FILE
- CALL MAKEFIL ;..THEN MAKE NEW
- CALL ILPRT ;PRINT:
- DB 'File open, ready to receive',CR,LF,0
- LDA CRCFLG ;GET CRC FLAG
- ORA A ;CRC BEING USED?
- MVI A,NAK ;PREPARE FOR CHECKSUM BEING IN EFFECT
- JNZ RCVFIL2 ;BRANCH IF CHECKSUM BEING USED
- MVI A,CRC ;REQUEST CYCLIC REDUNDANCY CHECK
- ;
- RCVFIL2 CALL SEND ;SEND INITIAL NAK (CHECKSUM) OR CRC REQUEST
- ;
- RCVLP CALL RCVSECT ;GET A SECTOR
- JC RCVEOT ;GOT EOT
- CALL WRSECT ;WRITE THE SECTOR
- CALL INCRSNO ;BUMP SECTOR #
- CALL SENDACK ;ACK THE SECTOR
- JMP RCVLP ;LOOP UNTIL EOF
- ;
- ; GOT EOT ON SECTOR - FLUSH BUFFERS, END
- ;
- RCVEOT CALL WRBLOCK ;WRITE THE LAST BLOCK
- CALL SENDACK ;ACK THE SECTOR
- CALL CLOSFIL ;CLOSE THE FILE
- JMP DONE ;ALL DONE
- ;
- ;* * * * * * * * * * * * * * * * * * * * *
- ;* *
- ;* SUBROUTINES *
- ;* *
- ;* * * * * * * * * * * * * * * * * * * * *
- ;
- ;----> TRAP: CHECK FOR NO FILE NAME OR AMBIGUOUS NAME
- ;
- TRAP LXI H,FCB+1 ;POINT TO FILE NAME
- MOV A,M ;GET FIRST CHAR OF FILE NAME
- CPI ' ' ;ANY THERE?
- JNZ ATRAP ;YES, CHECK FOR AMBIGOUS FILE NAME
- CALL ERXIT ;PRINT MSG, EXIT
- DB '++No file name specified++',CR,LF,'$'
- ;
- ATRAP MVI B,11 ;11 CHARS TO CHECK
- ;
- TRLOOP MOV A,M ;GET CHAR FROM FCB
- CPI '?' ;AMBIGUOUS?
- JZ TRERR ;YES, EXIT WITH ERROR MSG
- INX H ;POINT TO NEXT CHAR
- DCR B ;ONE LESS TO GO
- JNZ TRLOOP ;NOT DONE, CHECK SOME MORE
- RET ;NO AMBIGUOUS NAME, RETURN
- ;
- TRERR CALL ERXIT ;PRINT MSG, EXIT
- DB '++Can''t use wild card options++',CR,LF,'$'
- ;
- ;----> RCVSECT: RECEIVE A SECTOR
- ;
- ; RETURNS WITH CARRY SET IF EOT RECEIVED.
- ;
- RCVSECT XRA A ;GET 0
- STA ERRCT ;INIT ERROR COUNT
- ;
- RCVRPT XRA A ;GET 0
- STA ERRCDE ;CLEAR RECEIVE ERROR CODE
- LDA QFLG ;QUIET?
- ORA A
- JZ RCVSQ ;YES, NO STAT MSG.
- ;
- IF NOT VIDEO ;Then send CRLF
- CALL CRLF
- ENDIF
- ;
- IF VIDEO ;Then send only a CR
- MVI A,CR
- CALL TYPE
- ENDIF
- ;
- CALL ILPRT ;PRINT:
- DB 'Awaiting # ',0
- PUSH H ;SAVE HL
- LHLD SECTNO ;GET SECTOR #
- INX H ;BUMP IT
- CALL DECOUT ;PRINT SECTOR # IN DECIMAL
- CALL ILPRT
- DB ' (',0
- CALL DHXOUT ;16 BIT HEX CONV & OUTPUT
- CALL ILPRT
- DB 'H) ',0
- MOV A,L ;ONLY LOW BYTE USED BY PROG
- POP H ;RESTORE HL
- ;
- RCVSQ LDA FIRSTME ;GET FIRST TIME SWITCH
- ORA A ;FIRST TIME THRU?
- JZ RCVSQ2 ;NO, SKIP TO RECEIVE SOH
- XRA A ;TURN OFF..
- STA FIRSTME ;..FIRST TIME SWITCH
- LDA CRCFLG ;CRC IN..
- ORA A ;..EFFECT?
- JNZ RCVSQ2 ;NO, DO LONG WAIT FOR SOH
- MVI B,7 ;WAIT FOR UP TO 7 SECONDS
- CALL RECV ;GET A CHARACTER
- JNC RCVSQ3 ;GOT A CHAR, GO SEE IF SOH
- CALL ILPRT
- DB '++Switching to CHECKSUM MODE++',CR,LF,0
- MVI A,'C' ;TURN OFF...
- STA CRCFLG ;...CRC MODE
- MVI A,NAK ;SEND A NAK TO TELL SENDER CHECKSUM..
- CALL SEND ;..IN EFFECT & START SENDING DATA.
- JMP RCVSECT ;GO START RECEIVING SECTOR
- ;
- RCVSQ2 MVI B,10 ;10 SEC TIMEOUT
- CALL RECV ;GET SOH/EOT
- JC RCVSTOT ;TIMEOUT
-
- rcvsq3 CALL RCVR ;TRANS ERROR?
- JC RCERR ;CARRY ON IF ERROR
- CPI SOH ;GET SOH?
- JZ RCVSOH ;..YES
- ;
- ; EARLIER VERSIONS OF MODEM PROG SENT SOME NULLS -
- ; IGNORE THEM
- ;
- ORA A ;00 FROM SPEED CHECK?
- JZ RCVSQ ;YES, IGNORE IT
- CPI EOT ;END OF TRANSFER?
- STC ;RETURN WITH CARRY..
- RZ ;..SET IF EOT
- ;
- ; DIDN'T GET SOH OR EOT
- ;
- MOV B,A ;SAVE CHAR
- LDA VSEEFLG ;VIEWING..
- ORA A ;..MODE?
- JZ RCVSEH ;YES, PRT.MSG
- LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ RCVSERR ;YES, SKIP MSG
- ;
- RCVSEH MOV A,B ;GET CHAR
- CALL HEXO ;SHOW IN HEX
- CALL ILPRT ;PRINT:
- DB 'H rcvd, not SOH',CR,LF,0
- ;
- ; DIDN'T GET VALID HEADER - PURGE THE LINE,
- ; THEN SEND NAK.
- ;
- RCVSERR MVI B,1 ;WAIT FOR 1 SEC..
- CALL RECV ;..WITH NO CHARS
- JNC RCVSERR ;LOOP UNTIL SENDER DONE
- LDA ERRCT ;ABORT IF..
- INR A ;..WE HAVE REACHED..
- STA ERRCT ;..THE ERROR..
- CPI ERRLIM ;..LIMIT?
- JC RCVCQ2 ;..NO, TRY AGAIN (FIRST, SEND NAK)
- ;
- ; 10 ERRORS IN A ROW -
- ;
- LDA VSEEFLG ;VIEWING..
- ORA A ;..FILE?
- JZ RCVCKQ ;YES, ASK RETRY/QUIT
- LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ RCVSABT ;ABORT
- ;
- RCVCKQ CALL CKQUIT ;RETRY/QUIT?
- JNZ RCVSABT ;QUIT, THEN ABORT
- ;
- ; LINE MUST BE PURGED BECAUSE SENDER PROBABLY STARTED
- ; RESENDING WHILE OPERATOR ANSWERED RETRY/QUIT PROMPT.
- ;
- RCVCQ2 MVI A,NAK ;SEND NAK TO CANCEL SECTOR
- CALL SEND
- JMP RCVRPT ;GO RE-RECEIVE SECTOR
- ;
- RCVSABT CALL CLOSFIL ;KEEP WHATEVER WE GOT
- CALL ERXIT
- DB '++Unable to receive block -- Aborting++',BELL,CR,LF,'$'
- ;
- ; TIMED OUT ON RECEIVE
- ;
- RCVSTOT LDA VSEEFLG ;VIEWING..
- ORA A ;..MODE?
- JZ RCVSPT ;YES, PRT MSG
- LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ RCVSERR ;YES, NO MSG
- ;
- RCVSPT CALL ILPRT
- DB '++Timeout++ ',0
- ;
- RCVPRN LDA ERRCT ;PRINT ERROR..
- CALL HEXO ;..COUNT
- CALL CRLF
- JMP RCVSERR ;BUMP ERR CT, ETC.
- ;
- ;----> RCVR: CHECKS FOR FRAMING ERROR, OVERRUN ERROR,
- ; AND PARITY ERROR.
- ; 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, THE CARRY BIT IS SET ON.
- ;
- RCVR PUSH PSW ;SAVE CHAR TRANSMITTED
- LDA ERRCDE ;GET RECEIVE ERROR CODE
- ANA A ;IS IT ZERO?
- JZ RCVR2 ;YES, NO RECEIVE ERROR
- POP PSW ;RESTORE CHAR TRANSMITTED
- STC ;SET CARRY ON TO INDICATE AN ERROR
- RET
- ;
- RCVR2 POP PSW ;RESTORE CHAR TRANSMITTED
- ORA A ;CLEAR CARRY BIT
- RET
- ;
- ;----> RCERR: CHECKS FOR A RECEIVE ERROR AND DISPLAYS
- ; APROPRIATE ERROR MESSAGE. THEN GOES TO RCVSERR
- ; TO PURGE THE LINE AND SEND A NAK.
- ;
- RCERR LDA VSEEFLG ;VIEWING
- ORA A ;..MODE?
- JZ RCERRP ;YES,. PRT MSG
- LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ RCVSERR ;YES, NO MSG
- ;
- RCERRP:
- LDA ERRCDE ;GET RECEIVE ERR CODE
- ANI FRMER ;WAS THERE A FRAMING ERROR?
- CPI FRMER
- JNZ RCERR2 ;NO, GO CHECK FOR OVERRUN
- CALL ILPRT
- DB '++Framing error++ ',0
- CALL RCERR5 ;PRINT # OF ERR
- ;
- RCERR2:
- LDA ERRCDE ;GET RECEIVE ERR CODE
- ANI ORUNER ;WAS THERE AN OVERRUN?
- CPI ORUNER
- JNZ RCERR3 ;NO, CHECK FOR PARITY ERR
- CALL ILPRT
- DB '++Overrun error++ ',0
- CALL RCERR5
- ;
- RCERR3:
- LDA ERRCDE ;GET RECEIVE ERR CODE
- ANI PARER ;WAS THERE A PARITY ERR?
- CPI PARER
- JNZ RCERR4 ;NO, GO PURGE LINE
- CALL ILPRT
- DB '++Parity error++ ',0
- CALL RCERR5
- ;
- RCERR4:
- JMP RCVSERR ;GO PURGE LINE, SEND NAK
- ;
- ; DISPLAY THE NUMBER OF THE ERROR, DO A CARRIAGE
- ; RETURN AND LINE FEED.
- ;
- RCERR5:
- LDA ERRCT ;GET ERROR NUMBER
- CALL HEXO ;DISPLAY IT
- CALL CRLF ;DO CR, LF
- RET
- ;
- ;
- ; GOT SOH - GET BLOCK #, BLOCK # COMPLEMENTED
- ;
- RCVSOH MVI B,1 ;TIMEOUT = 1 SEC
- CALL RECV ;GET SECTOR #
- JC RCVSTOT ;GOT TIMEOUT
- CALL RCVR ;TRANSMISSION ERROR?
- JC RCERR ;YES, GO DISP MSG, PURGE LINE
- MOV D,A ;D=BLK #
- MVI B,1 ;TIMEOUT = 1 SEC
- CALL RECV ;GET COMPLEMENTED SECTOR #
- JC RCVSTOT ;TIMEOUT
- CALL RCVR ;TRANSMISSION ERROR?
- JC RCERR ;YES IF CARRY ON
- CMA ;CALC COMPLEMENT
- CMP D ;GOOD SECTOR #?
- JZ RCVDATA ;YES, GET DATA
- ;
- ; GOT BAD SECTOR #
- ;
- LDA VSEEFLG ;VIEWING..
- ORA A ;..MODE?
- JZ RCVBSE ;..YES, PRT MSG
- LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ RCVSERR ;..YES, NO MSG
- ;
- RCVBSE CALL ILPRT ;PRINT:
- DB '++Bad sector # in hdr',CR,LF,0
- JMP RCVSERR ;BUMP ERROR CT.
- ;
- RCVDATA MOV A,D ;GET SECTOR #
- STA RCVSNO ;SAVE IT
- MVI A,1 ;SHOW..
- STA DATAFLG ;GETTING DATA
- MVI C,0 ;INIT CKSUM
- CALL CLRCRC ;CLEAR CRC COUNTER
- LXI H,BASE+80H ;POINT TO BUFFER
- ;
- RCVCHR MVI B,1 ;1 SEC TIMEOUT
- CALL RECV ;GET CHAR
- JC RCVSTOT ;TIMEOUT
- CALL RCVR ;TRANSMISSION ERROR?
- JC RCERR ;YES IF CARRY ON
- MOV M,A ;STORE CHAR
- INR L ;DONE?
- JNZ RCVCHR ;NO, LOOP
- LDA CRCFLG ;GET CRC FLAG
- ORA A ;CRC IN EFFECT?
- JZ RCVCRC ;YES, GO GET CRC
- ;
- ; VERIFY CHECKSUM
- ;
- MOV D,C ;SAVE CHECKSUM
- XRA A ;SHOW..
- STA DATAFLG ;..END OF DATA
- MVI B,1 ;TIMEOUT LEN.
- CALL RECV ;GET CHECKSUM
- JC RCVSTOT ;TIMEOUT
- CALL RCVR ;TRANSMISSION ERROR?
- JC RCERR ;YES IF CARRY ON
- CMP D ;CHECKSUM OK?
- JNZ RCVCERR ;NO, ERROR
- ;
- ; GOT A SECTOR, IT'S A DUP IF = PREV,
- ; OR OK IF = 1 + PREV SECTOR
- ;
- CHKSNUM LDA RCVSNO ;GET RECEIVED
- MOV B,A ;SAVE IT
- LDA SECTNO ;GET PREV
- CMP B ;PREV REPEATED?
- JZ RECVACK ;ACK TO CATCH UP
- INR A ;CALC NEXT SECTOR #
- CMP B ;MATCH?
- JNZ ABORT ;NO MATCH - STOP SENDER, EXIT
- RET ;CARRY OFF - NO ERRORS
- ;
- ; RECEIVE THE CYCLIC REDUNDANCY CHECK CHARACTERS (2 BYTES),
- ; AND CHECK TO SEE IF THE SENT CRC MATCHES THE CALCULATED
- ; CRC. IF THEY MATCH GET NEXT SECTOR, ELSE PRINT ERROR
- ; MESSAGE IF NOT IN QUIET MODE AND SEND A NAK REQUESTING
- ; THAT THE SECTOR BE RESENT.
- ;
- RCVCRC MVI E,2 ;NUMBER OF CRC BYTES TO RECEIVE
- ;
- RCVCRC2 MVI B,1 ;1 SEC TIMEOUT
- CALL RECV ;GET CRC BYTE
- JC RCVSTOT ;CARRY SET IF TIMEOUT
- CALL RCVR ;TRANSMISSION ERR?
- JC RCERR ;CARRY SET IF TRANS ERR
- DCR E ;GOT BOTH CRC BYTES?
- JNZ RCVCRC2 ;NO, GO GET 2ND BYTE
- CALL CHKCRC ;CHECK RECVD CRC AGAINST CALCD CRC
- ORA A ;IS CRC OKAY?
- JZ CHKSNUM ;YES, GO CHECK SECTOR NUMBERS
- ;
- ;PRINT CRC ERROR MESSAGE
- ;
- LDA VSEEFLG ;VIEWING..
- ORA A ;..MODE?
- JZ RCVCRER ;..YES, PRINT MESSAGE
- LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ RCVSERR ;YES, NO MESSAGE
- ;
- RCVCRER CALL ILPRT
- DB '++CRC error++ ',0
- JMP RCVPRN
- ;
- ; GOT CKSUM
- ;
- RCVCERR LDA VSEEFLG ;VIEWING..
- ORA A ;..MODE?
- JZ RCVCPR ;..YES, PRT MSG
- LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ RCVSERR ;YES, NO MSG
- ;
- RCVCPR CALL ILPRT
- DB '++CKSUM error++ ',0
- JMP RCVPRN ;PRINT ERROR #
- ;
- ; PREVIOUS SECTOR REPEATED, DUE TO THE LAST ACK
- ; BEING GARBAGED. ACK IT SO SENDER WILL CATCH UP
- ;
- RECVACK CALL SENDACK ;SEND THE ACK,
- JMP RCVSECT ;GET NEXT BLOCK
- ;
- ; SEND AN ACK FOR THE SECTOR
- ;
- SENDACK MVI A,ACK ;GET ACK
- CALL SEND ;..AND SEND IT
- RET
- ;
- ;----> SENDHDR: SEND THE SECTOR HEADER
- ;
- ; SEND: (SOH) (BLOCK #) (COMPLEMENTED BLOCK #)
- ;
- SENDHDR LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ SENDHNM ;YES, SKIP STATUS MSG.
- ;
- IF NOT VIDEO ;Then send CRLF
- CALL CRLF
- ENDIF
- ;
- IF VIDEO ;Then send only a CR
- MVI A,CR
- CALL TYPE
- ENDIF
- ;
- CALL ILPRT ;PRINT:
- DB 'Send # ',0
- PUSH H ;SAVE HL
- LHLD SECTNO ;GET SECTOR #
- CALL DECOUT ;PRINT SECTOR # IN DECIMAL
- CALL ILPRT
- DB ' (',0
- CALL DHXOUT ;16 BIT HEX CONV & OUTPUT
- CALL ILPRT
- DB 'H) ',0
- POP H ;RESTORE HL
- ;
- SENDHNM MVI A,SOH ;SEND..
- CALL SEND ;..SOH,
- LDA SECTNO ;THEN SEND..
- CALL SEND ;..SECTOR #
- LDA SECTNO ;THEN SECTOR #
- CMA ;..COMPLEMENTED..
- CALL SEND ;..SECTOR #
- RET ;FROM SENDHDR
- ;
- ;----> SENDSEC: SEND THE DATA SECTOR
- ;
- ; WHILE SENDING THE SECTOR, THE "DATAFLG" IS SET
- ; SUCH THAT IF "V" (VIEW THE FILE) WAS REQUESTED,
- ; THE "SHOW" ROUTINE WILL PRINT THE DATA, BUT NOT
- ; THE HDR OR CKSUM, OR ANY NON-FATAL MSGS.
- ;
- SENDSEC MVI A,1 ;SHOW NOW AT DATA..
- STA DATAFLG ;..FOR VIEW COMMAND
- MVI C,0 ;INIT CKSUM
- CALL CLRCRC ;CLEAR CRC COUNTER
- LXI H,BASE+80H ;POINT TO BUFFER
- ;
- SENDC MOV A,M ;GET A CHAR
- CALL SEND ;SEND IT
- INR L ;POINT TO NEXT CHAR
- JNZ SENDC ;LOOP IF <100H
- XRA A ;SHOW NOT INTO DATA..
- STA DATAFLG ;..FOR VIEW COMMAND
- RET ;FROM SENDSEC
- ;
- ;----> SENDCKS: SEND THE CHECKSUM
- ;
- SENDCKS MOV A,C ;SEND THE..
- CALL SEND ;..CHECKSUM
- RET ;FROM SENDCKS
- ;
- ;----> SENDCRC: CALCULATE THE CYCLIC REDUNDANCY CHECK
- ; AND THEN SEND IT. FINCRC CALCS THE
- ; FINAL CRC AND PLACES IT IN D,E REGS.
- ;
- SENDCRC CALL FINCRC ;CALC CRC FOR THE SECTOR
- MOV A,D ;PUT FIRST CHAR OF CRC IN ACCUM
- CALL SEND ;SEND IT
- MOV A,E ;PUT SECOND CHAR OF CRC IN ACCUM
- CALL SEND
- XRA A ;MAKE SURE ZERO FLAG IS OFF
- RET
- ;
- ;----> GETACK: GET THE ACK ON THE SECTOR
- ;
- ; RETURNS WITH CARRY CLEAR IF ACK RECEIVED.
- ; IF AN ACK IS NOT RECEIVED, THE ERROR COUNT
- ; IS INCREMENTED, AND IF LESS THAN "ERRLIM",
- ; CARRY IS SET AOD CONTROL RETURNS. IF THE
- ; ERROR COUNT IS AT "ERRLIM", THE PROGRAM
- ; ABORTS IF IN "QUIET" MODE, OR ASKS THE
- ; USER FOR QUIT/RETRY IF NOT.
- ;
- GETACK MVI B,10 ;WAIT 10 SECONDS MAX
- CALL RECVDG ;RECV W/GARBAGE COLLECT
- JC GETATOT ;TIMED OUT
- CPI ACK ;OK? (CARRY OFF IF =)
- RZ ;YES, RET FROM GETACK
- MOV B,A ;SAVE CHAR
- LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ ACKERR ;..YES, NO MSG
- MOV A,B ;GET CHAR
- CALL HEXO ;PRINT IN HEX
- CALL ILPRT ;PRINT:
- DB 'H rcvd, not ACK',CR,LF,0
- ;
- ; TIMEOUT OR ERROR ON ACK - BUMP ERROR COUNT
- ;
- ACKERR LDA ERRCT ;GET COUNT
- INR A ;BUMP IT
- STA ERRCT ;SAVE BACK
- CPI ERRLIM ;AT LIMIT?
- RC ;NOT AT LIMIT
- ;
- ; REACHED ERROR LIMIT
- ;
- LDA VSEEFLG ;VIEWING..
- ORA A ;..FILE?
- JZ GACKV ;YES, ASK QUIT/RETRY
- LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ CSABORT ;..YES, NO MSG
- ;
- GACKV CALL CKQUIT ;SEE IF WANT TO QUIT
- STC ;TO SHOW NO ACK
- RZ ;KEEP ON TRYIN'
- ;
- CSABORT CALL ERXIT
- DB '++Can''t send sector -- Aborting++',BELL,CR,LF,'$'
- ;
- ; TIMEOUT GETTING ACK
- ;
- GETATOT LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ ACKERR ;YES, NO MSG
- CALL ILPRT ;PRINT:
- DB '++Timeout on ACK',CR,LF,0
- JMP ACKERR
- ;
- ABORT LXI SP,STACK
- ;
- ABORTL MVI B,1 ;1 SEC. W/O CHARS.
- CALL RECV
- JNC ABORTL ;LOOP UNTIL SENDER DONE
- MVI A,NAK ;NEGATIVE ACK
- CALL SEND ;TELL SENDING END
- CALL ILPRT ;EXIT WITH ABORT MSG
- DB 'MODEM program cancelled',CR,LF,0
- JMP CKDIS ;CHECK FOR DISCONN.
- ;
- ;----> INCRSNO: INCREMENT SECTOR #
- ;
- INCRSNO: PUSH H
- LHLD SECTNO ;GET SECTOR #
- INX H ;BOP IT
- SHLD SECTNO ;STORE UPDATED BACK
- MOV A,L ;COPY LOW TO ACC FOR CALLERS
- POP H
- RET
- ;
- ;----> ERASFIL: ERASE THE INCOMING FILE.
- ;
- ; IF IT EXISTS, ASK IF IT MAY BE ERASED.
- ;
- ERASFIL LXI D,FCB ;POINT TO CTL BLOCK
- MVI C,SRCHF ;SEE IF IT..
- CALL BDOS ;..EXISTS
- INR A ;FOUND?
- RZ ;..NO, RETURN
- CALL ILPRT ;PRINT:
- DB '++File exists, type ''Y'' to erase: ',BELL,0
- CALL KEYIN ;GET CHAR
- PUSH PSW
- CALL TYPE ;ECHO
- CALL CRLF ;BACK TO START OF LINE
- POP PSW
- ANI 5FH ;MAKE UPPER CASE
- CPI 'Y' ;WANT ERASED?
- JNZ CKDIS ;QUIT IF NOT ERASE
- ;
- ;ERASE OLD FILE
- ;
- LXI D,FCB ;POINT TO FCB
- MVI C,ERASE ;GET BDOS FNC
- CALL BDOS ;DO THE ERASE
- RET ;FROM "ERASFIL"
- ;
- ;----> MAKEFIL: MAKES THE FILE TO BE RECEIVED
- ;
- MAKEFIL LXI D,FCB ;POINT TO FCB
- MVI C,MAKE ;GET BDOS FNC
- CALL BDOS ;TO THE MAKE
- INR A ;FF=BAD?
- RNZ ;OPEN OK
- ;
- ; DIRECTORY FULL - CAN'T MAKE FILE
- ;
- CALL ERXIT
- DB '++ERROR -- Can''t make file',CR,LF
- DB '++Directory must be full',CR,LF,'$'
- ;
- ;----> OPENFIL: OPENS THE FILE TO BE SENT
- ;
- OPENFIL XRA A ;SET EXT & REC # TO 0 FOR PROPER OPEN
- STA FCBEXT
- STA FCBSNO
- LXI D,FCB ;POINT TO FILE
- MVI C,OPEN ;GET FUNCTION
- CALL BDOS ;OPEN IT
- INR A ;OPEN OK?
- JNZ OPENOK ;..YES
- CALL ERXIT ;..NO, ABORT
- DB '++Can''t open file',CR,LF,'$'
- ;
- OPENOK CALL ILPRT ;PRINT:
- DB 'File open - Size: ',0
- LHLD RCNT ; Get record count.
- CALL DECOUT ;PRINT DECIMAL NUMBER OF SECTORS
- CALL ILPRT ;Print:
- DB ' (',0
- CALL DHXOUT ;Now print size in hex.
- CALL ILPRT ;PRINT:
- DB 'H) sectors',CR,LF,0
- RET
- ;
- ;----> DECOUT: Decimal output routine
- ;
- DECOUT: 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
- RET
- ;
- ;----> DHXOUT: - double precision hex output routine.
- ; Call with hex value in HL.
- ;
- DHXOUT PUSH H ;Save H,L
- PUSH PSW ;Save A
- MOV A,H ;Get MS byte.
- CALL HEXO ;Output hi order byte.
- MOV A,L ;Get LS byte.
- CALL HEXO ;Output lo order byte.
- POP PSW ;Restore A
- POP H ;Restore H,L
- RET ;Return to caller.
- ;
- ;
- ;
- ;----> CLOSFIL: CLOSES THE RECEIVED FILE
- ;
- CLOSFIL LXI D,FCB ;POINT TO FILE
- MVI C,CLOSE ;GET FUNCTION
- CALL BDOS ;CLOSE IT
- INR A ;CLOSE OK?
- RNZ ;..YES, RETURN
- CALL ERXIT ;..NO, ABORT
- DB BELL,'++Can''t close file',CR,LF,'$'
- ;
- ;---> ASCPTR - CHECK TO SEE IF ASCII CAPTURE IS ENABLED-IF
- ; IT IS, SAVE THE INCOMING CHARACTER IN THE
- ; MEMORY BUFFER, WRITING IT WHEN FULL
- ;
- ASCPTR: PUSH PSW ;SAVE CHARACTER
- LDA CPTRFLG ;LOOK AT CAPTURE FLAG
- ORA A ;CAPTURE ENABLED?
- JZ ASCQEND ; NO, TAKE QUICK EXIT
- POP PSW ;GET THE CHARACTER
- PUSH PSW ; AND SAVE ALL THE REGISTERS
- PUSH B
- PUSH D
- PUSH H
- LHLD CAPPTR ;GET THE BUFFER POINTER
- MOV M,A ; PUT CHARACTER IN BUFFER
- INX H ; INCREMENT POINTER
- SHLD CAPPTR ; AND SAVE IT
- LDA MEMEND ;GET LAST PAGE ADDRESS
- CMP H ;ARE WE THERE YET?
- JZ ASCPTR1 ; YES, TIME TO WRITE THE BUFFER
- DCR A ;NEXT TO LAST PAGE ADDRESS
- CMP H ;NEARING THE END?
- JNZ ASCEND ; NO, EXIT ROUTINE
- MOV A,L ;CHECK LOWER BYTE OF ADDRESS
- CPI -STPTIME AND 0FFH
- JNZ ASCEND ;NOT TIME FOR STOP CHAR, SO EXIT
- MVI A,STOPCHR ;TELL OTHER END TO STOP
- CALL OUTDATA ; IN ADVANCE
- JMP ASCEND
- ASCPTR1 LXI D,ASCBUF
- LDA MEMEND
- SUB D
- MOV B,A ;NUMBER OF PAGES TO SAVE
- ASCPTR2 MOV C,2 ;NUMBER OF SECTORS/PAGE
- ASCPTR3 CALL AWRITE
- LXI H,128
- DAD D
- XCHG ;MOVE TO NEXT SECTOR TO WRITE
- DCR C
- JNZ ASCPTR3 ;UNTIL PAGE IS WRITTEN
- DCR B
- JNZ ASCPTR2 ;UNTIL ALL PAGES ARE WRITTEN
- LXI H,ASCBUF ;RESET BUFFER POINTER
- SHLD CAPPTR
- MVI A,STRTCHR ;TELL OTHER END TO START
- CALL OUTDATA
- ASCEND POP H
- POP D
- POP B
- ASCQEND POP PSW
- RET
- AWRITE PUSH D
- MVI C,STDMA ;SET BUFFER ADDRESS
- CALL BDOS
- LXI D,ASCFCB
- MVI C,21 ;WRITE SEQUENTIAL
- CALL BDOS
- INR A
- JNZ AWRITE1
- CALL ILPRT
- DB BELL,'++Out of disk space',CR,LF,0
- AWRITE1 POP D
- RET
- ;
- ;----> RDSECT: READS A SECTOR
- ;
- ; FOR SPEED, THIS ROUTINE BUFFERS UP DBUFSIZ*8
- ; SECTORS AT A TIME.
- ;
- RDSECT LDA SECINBF ;GET # SECT IN BUFF.
- DCR A ;DECREMENT..
- STA SECINBF ;..IT
- JM RDBLOCK ;EXHAUSTED? NEED MORE.
- LHLD SECPTR ;GET POINTER
- LXI D,BASE+80H ;TO DATA
- CALL MOVE128 ;MOVE TO BUFFER
- SHLD SECPTR ;SAVE BUFFER POINTER
- RET ;FROM "READSEC"
- ;
- ; BUFFER IS EMPTY - READ IN ANOTHER BLOCK OF DBUFSIZ*8
- ;
- RDBLOCK LDA EOFLG ;GET EOF FLAG
- CPI 1 ;IS IT SET/
- STC ;TO SHOW EOF
- RZ ;GOT EOF
- MVI C,0 ;SECTORS IN BLOCK
- LXI D,DBUF ;TO DISK BUFFER
- ;
- RDSECLP PUSH B
- PUSH D
- MVI C,STDMA ;SET DMA..
- CALL BDOS ;..ADDR
- LXI D,FCB
- MVI C,READ
- CALL BDOS
- POP D
- POP B
- ORA A ;READ OK?
- JZ RDSECOK ;YES
- DCR A ;EOF?
- JZ REOF ;GOT EOF
- ;
- ; READ ERROR
- ;
- CALL ERXIT
- DB BELL,'++File read error',CR,LF,'$'
- ;
- RDSECOK LXI H,80H ;ADD LENGTH OF ONE SECTOR...
- DAD D ;...TO NEXT BUFF
- XCHG ;BUFF TO DE
- INR C ;MORE SECTORS?
- MOV A,C ;GET COUNT
- CPI DBUFSIZ*8 ;DONE?
- JZ RDBFULL ;..YES, BUFF IS FULL
- JMP RDSECLP ;READ MORE
- ;
- REOF MVI A,1
- STA EOFLG ;SET EOF FLAG
- MOV A,C
- ;
- ; BUFFER IS FULL, OR GOT EOF
- ;
- RDBFULL STA SECINBF ;STORE SECTOR COUNT
- LXI H,DBUF ;INIT BUFFER..
- SHLD SECPTR ;..POINTER
- LXI D,BASE+80H ;RESET..
- MVI C,STDMA ;..DMA..
- CALL BDOS ;..ADDR
- JMP RDSECT ;PASS SECT TO CALLER
- ;
- ;----> WRSECT: WRITE A SECTOR
- ;
- ; WRITES THE SECTOR INTO A BUFFER. WHEN DBUFSIZ*8
- ; HAVE BEEN WRITTEN, WRITES THE BLOCK TO DISK.
- ;
- ; ENTRY POINT "WRBLOCK" FLUSHES THE BUFFER AT EOF.
- ;
- WRSECT LHLD SECPTR ;GET BUFF ADDR
- XCHG ;TO DE FOR MOVE
- LXI H,BASE+80H ;FROM HERE
- CALL MOVE128 ;MOVE TO BUFFER
- XCHG ;SAVE NEXT..
- SHLD SECPTR ;..BLOCK POINTER
- LDA SECINBF ;BUMP THE..
- INR A ;..SECTOR #..
- STA SECINBF ;..IN THE BUFF
- CPI DBUFSIZ*8 ;HAVE WE DBUFSIZ*8?
- RNZ ;NO, RETURN
- ;
- ;----> WRBLOCK: WRITES A BLOCK TO DISK
- ;
- WRBLOCK LDA SECINBF ;# SECT IN BUFFER
- ORA A ;0 MEANS END OF FILE
- RZ ;NONE TO WRITE
- MOV C,A ;SAVE COUNT
- LXI D,DBUF ;POINT TO DISK BUFF
- ;
- DKWRLP PUSH H
- PUSH D
- PUSH B
- MVI C,STDMA ;SET DMA
- CALL BDOS ;TO BUFFER
- LXI D,FCB ;THEN WRITE
- MVI C,WRITE ;..THE..
- CALL BDOS ;..BLOCK
- POP B
- POP D
- POP H
- ORA A
- JNZ WRERR ;OOPS, ERROR
- LXI H,80H ;LENGTH OF 1 SECT
- DAD D ;HL= NEXT BUFF
- XCHG ;TO DE FOR SETDMA
- DCR C ;MORE SECTORS?
- JNZ DKWRLP ;..YES, LOOP
- XRA A ;GET A ZERO
- STA SECINBF ;RESET # OF SECTORS
- LXI H,DBUF ;RESET BUFFER..
- SHLD SECPTR ;..POINTER
- ;
- RSDMA LXI D,BASE+80H ;RESET..
- MVI C,STDMA ;..DMA..
- CALL BDOS ;..ADDR
- RET
- ;
- WRERR CALL RSDMA ;RESET DMA TO NORM.
- CALL ILPRT ;PRINT:
- DB BELL,'++Error writing file',CR,LF,0
- JMP ABORT ;EXIT
- ;
- ;----> 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 $ ;RECEIVE W/GARBAGE DELETE
- CALL INDATA ;GET A CHAR
- CALL INDATA ;..TOTALLY PURGE UART
- ;
- RECV PUSH D ;SAVE
- ;
- IF FASTCLK ;4MHZ?
- MOV A,B ;GET TIME REQUEST
- ADD A ;DOUBLE IT
- MOV B,A ;NEW TIME IN B
- ENDIF
- ;
- MSEC LXI D,50000 ;1 SEC DCR COUNT
- ;
- IF (NOT DCH) AND (NOT X8250)
- MWTI CALL INCTL ;CHECK STATUS
- ENDIF
- ;
- IF X8250
- MWTI CALL INCTL5 ;CHECK STATUS
- ENDIF
- ;
- IF DCH
- MWTI CALL INCT2 ;CHECK STATUS
- ENDIF
- ;
- IF FRNTPNL AND PMMI
- CALL OUTPAN ;DISPLAY STATUS
- ENDIF
- ;
- ANI MDRCVB ;ISOLATE BIT
- CPI MDRCVR ;READY?
- JZ MCHAR ;GOT CHAR
- DCR E ;COUNT..
- JNZ MWTI ;..DOWN..
- DCR D ;..FOR..
- JNZ MWTI ;..TIMEOUT
- DCR B ;MORE SECONDS?
- JNZ MSEC ;YES, WAIT
- ;
- ; MODEM TIMED OUT RECEIVING
- ;
- POP D ;RESTORE D,E
- STC ;CARRY SHOWS TIMEOUT
- RET
- ;
- ; GOT CHAR FROM MODEM
- ;
- ; CHECK TO SEE IF THERE WAS A FRAMING, OVERRUN,
- ; AND/OR PARITY ERROR.
- ;
- MCHAR: IF (NOT DCH) AND (NOT X8250)
- CALL INCTL ;GET STATUS
- ENDIF
- ;
- IF X8250
- CALL INCTL5 ;GET STATUS
- ENDIF
- ;
- IF DCH
- CALL INCT2 ;GET STATUS
- ENDIF
- ;
- MOV D,A ;SAVE STATUS
- ANI FRMER ;FRAMING ERR?
- JZ MCHAR2 ;NO, CHECK FOR OVERRUN
- LDA ERRCDE ;GET RECV ERR CODE
- ORI FRMER ;TURN ON RECV ERR CODE
- STA ERRCDE
- ;
- MCHAR2: MOV A,D ;RESTORE STATUS
- ANI ORUNER ;OVERRUN ERR?
- JZ MCHAR3 ;NO, CHECK FOR PARITY
- LDA ERRCDE ;GET RECV ERR CODE
- ORI ORUNER ;TURN ON RECV ERR CODE
- STA ERRCDE
- ;
- MCHAR3: MOV A,D ;RESTORE STATUS
- ANI PARER ;PARITY ERR?
- JZ MCHAR4 ;NO, GET DATA CHAR
- LDA ERRCDE ;GET RECV ERR CODE
- ORI PARER ;TURN ON RECV ERR CODE
- STA ERRCDE
- ;
- ; Check for error and call reset code if yes
- ;
- MCHAR4:
- LDA ERRCDE ; Retrieve error code
- ORA A ; Set flags
- CNZ RESRCVR ; Reset if necessary
- ;
- ; GET THE DATA CHAR
- ;
- CALL INDATA ;GET MODEM DATA CHAR
- POP D ;RESTORE DE
- ;
- ; CALC CHECKSUM AND CYCLIC REDUNDANCY CHECK
- ;
- PUSH PSW ;SAVE THE CHAR
- CALL UPDCRC ;CALC CYCLIC REDUNDANCY CHECK
- ADD C ;ADD TO CHECKSUM
- MOV C,A ;SAVE CHECKSUM
- ;
- ; CHECK IF MONITORING REC'D DATA
- ;
- LDA RSEEFLG ;SEE RECEIVED..
- ORA A ;..DATA?
- JZ MONIN ;..YES
- ;
- ; CHECK IF "VIEWING" AND THIS IS A DATA CHAR
- ;
- LDA VSEEFLG ;VIEWING..
- ORA A ;..DATA?
- JNZ NOMONIN ;..NO
- ;
- ; "VIEW" REQUESTED. SHOW THE CHAR IF IT IS DATA
- ;
- LDA DATAFLG ;GET DATA FLAG
- ORA A ;TEST IT
- JZ NOMONIN ;..OFF, NOT DATA
- ;
- MONIN POP PSW ;..IS DATA,
- PUSH PSW ;GET IT,
- CALL SHOW ;..AND SHOW IT
- ;
- NOMONIN POP PSW ;RESTORE CHAR
- ORA A ;CARRY OFF: NO ERROR
- RET ;FROM "RECV"
- ;
- ; This is the section of code that resets the error
- ; bit in the receiving device. (from parity, framing,
- ; and overrun)
- ; NOTE: I have implemented the code for an Intel 8251
- ; usart, but since I know nothing about other
- ; commonly used devices, you must add your own
- ; reset code here in a conditional.
- ;
- RESRCVR:
- IF X8251
- MVI A,RSTCODE ; Load reset code
- CALL OUTCTL ; Send to control port
- ENDIF ; X8251
-
- ; Add code here for other than 8251 !!!!
-
- RET ; <=== This "RET" must be here
- ; outside the conditional !
-
- ;
- ;----> SEND: SEND A CHARACTER TO THE MODEM
- ;
- ; THE CHARACTER TO BE SENT IS SAVED
- ; IN REG D. IF VIEWING IS IN EFFECT,
- ; THE CHARACTER IS DISPLAYED. THEN
- ; BOTH THE CHECKSUM AND CRC ARE CALCU-
- ; LATED.
- ;
- SEND PUSH D ;SAVE D,E REGS
- MOV D,A ;SAVE THE CHAR
- ;
- ; CHECK IF MONITORING SENT DATA
- ;
- LDA SSEEFLG ;CHECK IF MONITORING..
- ORA A ;..SENT DATA
- JZ MONOUT ;..YES
- ;
- ; CHECK IF "VIEWING" THE FILE
- ;
- LDA VSEEFLG ;GET VIEW FLAG
- ORA A ;TEST IT
- JNZ NOMONOT ;NO
- LDA DATAFLG ;IS THIS
- ORA A ;..DATA?
- JZ NOMONOT ;..NO.
- ;
- MONOUT MOV A,D ;GET THE CHAR
- CALL SHOW ;SHOW IT
- ;
- NOMONOT MOV A,D ;RESTORE THE CHAR
- CALL UPDCRC ;CALC CRC
- ADD C ;CALC CKSUM
- MOV C,A ;SAVE CKSUM
- ;
- IF (NOT DCH) AND (NOT X8250)
- SENDW CALL INCTL ;GET STATUS
- ENDIF
- ;
- IF X8250
- SENDW CALL INCTL5 ;GET STATUS
- ENDIF
- ;
- IF DCH
- SENDW CALL INCT2 ;GET STATUS
- ENDIF
- ;
- IF FRNTPNL
- CALL OUTPAN ;DISPLAY STATUS
- ENDIF
- ;
- ANI MDSNDB ;ISOLATE READY BIT
- CPI MDSNDR ;READY?
- JNZ SENDW ;..NO, WAIT
- MOV A,D ;GET CHAR
- POP D ;RESTORE D,E
- CALL OUTDATA ;OUTPUT IT
- RET ;FROM "SEND"
- ;
- ;----> WAITNAK: WAITS FOR INITIAL NAK
- ;
- ; TO ENSURE NO DATA IS SENT UNTIL THE RECEIVING
- ; PROGRAM IS READY, THIS ROUTINE WAITS FOR
- ; THE FIRST TIMEOUT-NAK FROM THE RECEIVER/
- ; (E) CONTAINS THE # OF SECONDS TO WAIT.
- ;
- WAITNAK LDA VSEEFLG ;VIEWING?
- ORA A
- JZ WAITNPR ;PRINT MSG
- LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ WAITNLP ;YES, SKIP MSG
- ;
- WAITNPR CALL ILPRT ;PRINT:
- DB 'Awaiting initial NAK or CRC request',CR,LF,0
- ;
- WAITNLP MVI B,1 ;TIMEOUT DELAY
- CALL RECV ;DID WE GET..
- CPI NAK ;..A NAK?
- RZ ;YES, SEND BLOCK
- CPI CRC ;CRC REQUEST?
- JZ WAITCRC ;YES, GO SET CRC FLAG
- DCR E ;80 TRIES?
- JZ ABORT ;YES, ABORT
- JMP WAITNLP ;NO, LOOP
- ;
- WAITCRC CALL ILPRT
- DB 'CRC request received',CR,LF,0
- XRA A ;ZERO ACCUM
- STA CRCFLG ;INDICATE CRC IN EFFECT
- RET
- ;
- ;----> INITADR: INIT'S CP/M BIOS ADDRESSES
- ;
- ; THIS ROUTINE FILLS IN THE ADDRESSES OF VARIOUS
- ; JMP AND CALL INSTRUCTIONS, SO THAT CP/M BDOS
- ; IS BYPASSED WHILE ACCESSING THE CONSOLE. THIS
- ; IS DONE TO ALLOW CHARACTERS SUCH AS CONTROL-C
- ; AND CONTROL-S TO BE KEYED WHILE IN TERMINAL
- ; MODE, WITHOUT CP/M INTERPRETING THEM.
- ;
- INITADR LHLD BASE+1 ;GET WARM BOOT ADDR
- LXI D,3 ;LENGTH OF A 'JMP'
- DAD D ;TO CONSOLE STAT
- SHLD VSTAT+1 ;MODIFY CALL
- DAD D ;TO CONSOLE IN
- SHLD VKEYIN+1 ;MODIFY CALL
- DAD D ;TO CONSOLE OUT
- SHLD VTYPE+1 ;MODIFY CALL
- RET
- ;
- ;----> CPTRTOG - toggles ASCII capture mode on and off
- ;
- CPTRTOG PUSH H ;SAVE ALL REGISTERS
- PUSH D
- PUSH B
- PUSH PSW
- MVI A,STOPCHR
- CALL OUTDATA
- LDA CPTRFLG ;GET CAPTURE FLAG
- CMA ; INVERT IT
- STA CPTRFLG ; AND SAVE IT
- ORA A ;DO WE OPEN OR CLOSE A FILE?
- JZ CPTRCLS ; CAPTURE DISABLED, SO CLOSE
- LXI H,ASCBUF ;INITIALIZE BUFFER STARTING ADDRESS
- SHLD CAPPTR
- GETNAM CALL ILPRT
- DB CR,LF,'Enter ASCII capture file name --> ',BELL,0
- LXI H,ASCFCB
- MVI M,0 ;DEFAULT DRIVE IF NOT SPECIFIED
- ;
- INX H ;POINT TO FILE NAME
- MVI B,11 ;FILL NAME AND TYPE WITH BLANKS
- MVI A,' '
- CPTRT01 MOV M,A
- INX H
- DCR B
- JNZ CPTRT01
- ;
- LXI H,ASCBUF ;GET FILE NAME FROM USER
- MVI M,15 ;MAX NUMBER OF CHARACTERS TO ACCEPT
- XCHG
- MVI C,10 ;USE READ CONSOLE BUFFER FUNCTION
- CALL BDOS ;TO GET INPUT
- ;
- MVI E,LF ;PUT USER BACK ON CLEAN LINE
- MVI C,2
- CALL BDOS
- ;
- LXI H,ASCBUF
- INX H
- MOV B,M ;NUMBER OF CHARACTERS INPUT
- MOV A,B ;MAKE SURE SOMETHING WAS INPUT
- CPI 0 ;IF NOTHING INPUT, THEN
- JZ NULNAM ; ASK FOR FILENAME AGAIN...
- MVI C,0 ;NUMBER OF FCB CHARS FILLED
- INX H
- INX H ;LOOK AT 2ND CHARACTER INPUT
- MOV A,M
- CPI ':' ;DRIVE CODE SPECIFIED?
- DCX H ;POINT BACK TO 1ST CHAR INPUT
- JNZ CPTRSET ;SKIP IF NO DRIVE SPECIFIED
- MOV A,M ;GET DRIVE CODE
- CALL VFYCHR ;LEGAL CHARACTER ????
- CPI 'A'
- JM BADDRV ;JUMP IF < A:
- CPI MAXDRV+1
- JP BADDRV ;JUMP IF > MAXDRV
- ANI 0FH ;CONVERT FROM ASCII
- STA ASCFCB ;PUT IT IN THE FCB
- INX H
- INX H ;POINT TO FIRST CHAR OF FILE NAME
- DCR B
- DCR B ;ADJUST CHAR COUNT
- JZ NONAME
- CPTRSET LXI D,ASCFCB+1 ;START OF FILE NAME IN FCB
- CPTRSE1 MOV A,M ;GET CHAR
- CPI '.' ;END OF FILE NAME?
- JZ CPTRTYP
- CALL VFYCHR ;LEGAL CHARACTER ????
- STAX D ;NO, STORE IT
- INX H
- INX D
- INR C
- DCR B
- JNZ CPTRSE1 ;LOOP IF MORE CHARS WERE INPUT
- JMP CPTROPN ;NO FILE TYPE GIVEN, SO USE BLANK DEFAULT
- ;
- CPTRTYP INX H ;MOVE PAST PERIOD IN SPECIFIED NAME
- LXI D,ASCFCB+9 ;POINT TO FILE TYPE IN FCB
- DCR B ;ACCOUNT FOR THE SKIPPED PERIOD
- JZ CPTROPN ;IF NO MORE, SKIP IT
- MOV A,M ;GET THE CHAR
- CALL VFYCHR ;LEGAL CHARACTER ????
- STAX D ; AND SAVE IT
- INX H
- INX D
- DCR B
- JZ CPTROPN ;SKIP IF NO MORE
- MOV A,M ;GET NEXT CHAR
- CALL VFYCHR ;LEGAL CHARACTER ????
- STAX D ; AND SAVE IT
- INX H
- INX D
- DCR B
- JZ CPTROPN ;SKIP IF NO MORE
- MOV A,M ;GET LAST CHAR
- CALL VFYCHR ;LEGAL CHARACTER ????
- STAX D ; AND SAVE IT
- CPTROPN PUSH H
- LXI H,ASCFCB+1 ;POINT TO 1ST CHAR. IN NAME
- MOV A,M
- POP H
- CPI ' '
- JZ NONAME ;IF = ' ' THEN NO NAME GIVEN
- MVI A,0
- STA ASCFCB+12 ;CLEAR EXTENT
- STA ASCFCB+32 ; AND CURRENT RECORD
- LXI D,ASCFCB ;SEE IF THERE ALREADY
- MVI C,SRCHF
- CALL BDOS
- INR A
- JZ CPTRNF ;PASS IF NOT
- CALL ILPRT
- DB '++File exists, type ''Y'' to erase: ',BELL,0
- CALL KEYIN ;GET RESPONSE
- PUSH PSW ;SAVE IT
- CALL TYPE ;ECHO IT
- CALL CRLF ; THEN EJECT LINE
- POP PSW
- ANI 5FH ;FOLD TO UPPER CASE
- CPI 'Y' ;GOT A YES?
- JNZ GETNAM ;ASK AGAIN IF NOT
- LXI D,ASCFCB ;PRE-DELETE FILE
- MVI C,ERASE
- CALL BDOS
- ;
- CPTRNF: LXI D,ASCFCB
- MVI C,22 ; MAKE FILE
- CALL BDOS
- INR A ;0FFH ERROR CODE BECOMES 00H
- JNZ CPTROP2 ;SKIP IF NO ERROR
- CALL ILPRT
- DB CR,LF,'++Directory full',CR,LF,0
- XRA A
- STA CPTRFLG
- JMP CPTRRET
- CPTROP2 CALL ILPRT
- DB CR,LF,'ASCII capture now activated',CR,LF,0
- JMP CPTRRET
- CPTRCLS LHLD CAPPTR ;GET CURRENT BUFFER POINTER
- CPTRCL1 MVI M,1AH ;FILL OUT THE RECORD WITH CTL-Z
- MOV A,L
- ANI 7FH ;ARE WE ON A MULTIPLE OF 128?
- JZ CPTRCL2 ; YES, EXIT LOOP
- INX H ;ELSE INCREMENT POINTER
- JMP CPTRCL1 ; AND CONTINUE
- CPTRCL2 LXI D,ASCBUF ;START OF BUFFER
- MOV A,D ;IF THE BUFFER IS EMPTY
- CMP H ; THEN DON'T WRITE ANYTHING
- JNZ CPTRCL3 ; AND CLOSE THE FILE
- MOV A,E
- CMP L
- JZ CPTRCL4
- CPTRCL3 CALL AWRITE ;WRITE A RECORD
- LXI H,128 ;INCREMENT WRITE POINTER BY 1 SECTOR
- DAD D
- XCHG
- LDAX D ;GET THE FIRST CHAR OF NEXT SECTOR
- CPI 1AH ;END OF FILE?
- JNZ CPTRCL3 ; IF NOT, WRITE SOME MORE
- CPTRCL4 LXI D,ASCFCB
- MVI C,16 ; CLOSE FILE
- CALL BDOS
- INR A ;0FFH ERROR CODE BECOMES 00H
- JZ CPTRCL5 ;SKIP IF ERROR
- CALL ILPRT
- DB CR,LF,'ASCII capture now off, '
- DB 'file closed',CR,LF,0
- JMP CPTRRET
- CPTRCL5 CALL ILPRT
- DB CR,LF,'++Error in closing file',CR,LF,0
- CPTRRET MVI A,STRTCHR
- CALL OUTDATA
- POP PSW
- POP B
- POP D
- POP H
- RET
- ;
- ;----> VFYCHR - CONVERT LOWER CASE TO UPPER, AND TRAP
- ;----> ALL ILLEGAL CHARACTERS IN FILE NAME
- VFYCHR ANI 7FH ;FORCE PARITY OFF
- CPI 061H
- JM VFYCH1 ;BEGIN LOWER->UPPER
- CPI 7BH
- JP VFYCH1
- SUI 20H ;WAS LOWER, FIX IT
- VFYCH1 CPI ' '
- JM BADNAM ;NO CTRL CHARS IN FILE NAME
- CPI '9'+1
- JM VFYCH2
- CPI '@'
- JM BADNAM
- VFYCH2 CPI 5FH
- JP BADNAM
- CPI '.'
- JZ BADNAM
- CPI ','
- JZ BADNAM
- CPI '*'
- JZ BADNAM
- CPI '['
- JZ BADNAM
- CPI ']'
- JZ BADNAM
- RET ;GOOD CHARACTER !!!!
- ;
- BADNAM CALL ILPRT
- DB '++Invalid character in '
- DB 'file name++',BELL,CR,LF,LF,0
- POP H ;REMOVE LAST CALL
- JMP GETNAM
- ;
- NULNAM CALL ILPRT
- DB '++Null file name specified,'
- DB ' ASCII capture not activated'
- DB '++',CR,LF,LF,0
- XRA A
- STA CPTRFLG ;FORCE CPATURE OFF
- JMP CPTRRET ;EXIT
- ;
- BADDRV CALL ILPRT
- DB '++Invalid drive specified, '
- DB 'try again++',BELL,CR,LF,0
- JMP GETNAM
- ;
- NONAME CALL ILPRT
- DB '++Can''t specify filetype '
- DB 'without a filename++',BELL,CR,LF,0
- JMP GETNAM
- ;
- ;
- ;----> PRINTER - SEND A CHARACTER TO THE PRINTER
- ;
- PRINTER PUSH H ;SAVE REGISTERS
- PUSH D
- PUSH B
- PUSH PSW
- LDA PRTRFLG ;GET PRINTER FLAG
- ORA A ;ENABLED?
- JZ PRTREND ;NO, SKIP IT
- POP PSW ;GET THE CHAR
- PUSH PSW ; AND SAVE IT AGAIN
- MOV E,A
- MVI C,5
- CALL BDOS ;PRINT IT
- PRTREND POP PSW ;RESTORE REGISTERS
- POP B
- POP D
- POP H
- RET
- ;
- ;----> PRTRTOG - ENABLE/DISABLE THE PRINTER
- ;
- PRTRTOG PUSH PSW
- LDA PRTRFLG
- CMA
- STA PRTRFLG
- POP PSW
- RET
- ;
- ;----> PROCOPT: PROCESS COMMAND OPTIONS
- ;
- ; 1) SAVED THE PRIMARY OPTION IN 'OPTION';
- ; 2) SCANS THE SUB-OPTION CHARACTERS, AND FOR
- ; EACH FOUND, ZEROS THE APPROPRIATE ENTRY IN
- ; THE OPTION TABLE. FOR EXAMPLE, IF 'Q' IS
- ; CODED (QUIT/DISCONNECT) THEN THE 'D' STORED AT
- ; 'DISCFLG' IS SET TO 0 SO IT CAN BE TESTED
- ; LATER.
- ;
- PROCOPT LXI D,FCB+1 ;TO PRIMARY OPT.
- LDAX D ;GET PRIMARY
- STA OPTION ;SAVE IT
- ;
- OPTLP INX D ;TO SECONDARY OPTION
- LDAX D ;GET CHAR
- ;
- ; IF YOU MOD THIS PROGRAM FOR >7 OPTIONS,
- ; YOU MUST CHANGE THE FOLLOWING, SINCE
- ; THERE WON'T BE A ' ' AFTER THE OPTION
- ; IF A BAUD RATE WAS SPECIFIED.
- ;
- CPI ' ' ;NO MORE OPT'NS?
- JZ ENDOPT ;..YES
- ;
- ; SET THE APPROP. OPTION: STORE 0 IN IT
- ;
- LXI H,OPTBL ;HL = ADDR OF 'OAQDSRV'
- MVI B,OPTBE-OPTBL ;OPT TABLE LEN
- ;
- OPTCK CMP M ;FOUND THE OPTION?
- JNZ OPTNO ;NO, DON'T SET IT
- MVI M,0 ;SET THE OPTION
- JMP OPTLP ;GET NEXT OPTION
- ;
- OPTNO INX H ;TO NEXT
- DCR B ;MORE?
- JNZ OPTCK
- ;
- ; OPTION NOT IN TABLE
- ;
- JMP BADOPT ;SHOW BAD SUB OPTION
- ;
- ENDOPT LDA CRCFLG ;GET CRC FLAG
- ORA A ;CRC IN EFFECT?
- JNZ ENDOPT2 ;NO, EVERYTHING OKAY
- LDA OPTION ;GET PRIMARY OPTION
- CPI 'R' ;WAS IT 'FILE RECEIVE'
- JNZ BADOPT ;NO, CRC ONLY ALLOWED FOR RECV
- ;
- ; IF "VIEW" WAS ASKED FOR, SET QUIET FLAG
- ;
- ENDOPT2 LDA VSEEFLG ;VIEW..
- ORA A ;..ASKED FOR?
- RNZ ;..NO, RET FROM 'PROCOPT'
- STA QFLG ;YES, NO HDR/CKSUM PRT
- RET ;FROM 'PROCOPT'
- ;
- ; DONE - CLOSE UP SHOP
- ;
- DONE LDA VSEEFLG ;VIEWING?
- ORA A
- JZ DONETC ;SHOW MSG
- LDA QFLG ;QUIET
- ORA A ;..MODE?
- JZ DONECTE ;YES, CK TERM/ECHO
- ;
- DONETC CALL ILPRT
- DB BELL,CR,LF,'Transfer complete'
- DB CR,LF,BELL,0
- ;
- ; CHECK IF TERMINAL OR ECHO SUB COMMAND
- ; WAS SPECIFIED
- ;
- DONECTE LDA TERMFLG ;TERM?
- ORA A
- JZ TERM ;..YES
- LDA ECHOFLG ;ECHO?
- ORA A
- JZ TRMECHO ;..YES
- ;
- ; FALL INTO 'CKDIS'
- ;
- ;----> CKDIS: CHECK IF DISCONNECT REQUESTED
- ;
- ; THIS ROUTINE IS JUMPED TO AT THE END OW
- ; PROCESSING, AND DISCONNECTS THE PHONE IF
- ; 'D' WAS SPECIFIED AS A SUB-OPTION.
- ;
- CKDIS LDA DISCFLG ;CHECK 'D' FLAG
- ORA A ;REQUESTED?
- ;
- IF PMMI OR DCH
- JNZ NDIS ;..NO, JUST EXIT
- ENDIF
- ;
- IF NOT PMMI AND NOT DCH
- JNZ EXIT
- ENDIF
- ;
- ; AWAIT C/R TO DISC. SO WE DON'T LOSE THE PHONE
- ;
- CALL ILPRT
- DB CR,LF,'Press RETURN to disconnect:',0
- CALL KEYIN
- PUSH PSW
- CALL CRLF
- POP PSW
- CPI CR
- JNZ CKDIS ;ASK AGAIN
- ;
- ;----> DISCONN: DISCONNECT THE PHONE
- ;
- DISCONN:LDA CPTRFLG
- ORA A
- CNZ CPTRTOG ;IF CAPTURE WAS ON, TURN OFF
- ;
- IF PMMI
- XRA A ;GET DISCONN VALUE
- CALL OUTCTL ;RESET ORIG/ANSW
- CALL OUTCT2 ;TURN OFF DTR, DO BREAK
- ENDIF
- ;
- IF DCH
- XRA A ;GET DISCONNECT VALUE
- CALL OUTCTL ;DISCONNECT
- ENDIF
- ;
- CALL ILPRT ;PRINT:
- DB '++Disconnected++',0
- JMP EXIT
- ;
- ; NO DISCONNECT, TYPE MSG AS REMINDER THAT PHONE'S
- ; OFF HOOK
- ;
- IF PMMI OR DCH
- NDIS LDA QFLG ;QUIET..
- ORA A ;..MODE?
- JZ EXIT ;..YES, NO MSG
- CALL ILPRT
- DB CR,LF,'++The MODEM is still connected++',CR,LF
- DB 'Use "MODEM D" to disconnect',CR,LF,0
- JMP EXIT
- ENDIF ;PMMI OR DCH
- ;
- ;----> INITMOD: INITIALIZES THE MODEM
- ;
- ; THIS ROUTINE IS USED TO INITIALIZE SERIAL
- ; BOARDS, OR SETUP S-100 MODEM BOARDS.
- ; JUST RETURNS IF NO INITIALIZATION REQUIRED.
- ;
- INITMD:
- IF INITREQ AND (NOT DCH) AND (NOT X8250)
- MVI A,INITC1 ;GET 1ST INIT CHAR
- CALL OUTCTL ;OUTPUT IT
- NOP
- NOP ;DELAY FOR USART
- NOP
- NOP
- MVI A,INITC2 ;GET 2ND INIT CHAR
- CALL OUTCTL ;OUTPUT IT
- NOP
- NOP ;DELAY FOR USART
- NOP
- NOP
- MVI A,INITC3 ;GET 3RD INIT CHAR
- CALL OUTCTL ;OUTPUT IT
- NOP
- NOP ;DELAY FOR USART
- NOP
- NOP
- MVI A,INITC4 ;GET 4TH INIT CHAR
- CALL OUTCTL ;OUTPUT IT
- ENDIF ;INITREQ AND (NOT DCH) AND (NOT X8250)
- ;
- IF DCH
- CALL GETBAUD ;GET BAUD RATE
- ENDIF
- ;
- IF PMMI
- CALL GETBAUD ;GET BAUD RATE
- CALL OUTBRP ;OUT BAUD RATE PORT
- ;
- ; SET MODEM CHIP BIT FOR >300 BAUD IF REQ'D
- ;
- CPI 52 ;>300?
- MVI A,5FH ;VALUE FOR >300
- JC GT300
- MVI A,7FH ;VALUE FOR <=300
- GT300 CALL OUTCT2 ;SET IT
- ;
- ; SET ORIG/ANSW IF REQUESTED
- ;
- LDA ORIGFLG
- ORA A ;ORIG MODE?
- MVI A,ORIGMD
- JZ OFFHOOK ;YES
- LDA ANSWFLG
- ORA A ;ANSW MODE?
- MVI A,ANSWMD
- RNZ ;NO
- ENDIF ;PMMI
- ;
- IF DCH
- LDA ANSWFLG
- ORA A ;ANSW MODE?
- MVI B,ANSWMD
- JZ INITM1 ;YES
- LDA ORIGFLG
- ORA A ;ORIG MODE?
- MVI B,ORIGMD
- JZ INITM1 ;YES
- LDA HOLDD ;NEITHER - GET LAST VALUE
- MOV B,A ;STORE IN B
- ;
- INITM1: MOV A,B ;GET MODE
- STA HOLDD ;SAVE VALUE
- MOV A,C ;GET BAUD RATE INDICATOR
- ORA A ;ZERO IF 110 BAUD
- MOV A,B ;GET MODE
- JZ OFFHOOK ;DO OFFHOOK
- ORI 1 ;SET 300 BAUD
- ENDIF ;DCH
- ;
- IF PMMI OR DCH
- ;
- ; GO OFFHOOK IN REQUESTED (ORIG/ANSW) MODE
- ;
- OFFHOOK LXI H,4000 ;DELAY AMT
- ;
- OFFDLY DCR L
- JNZ OFFDLY
- DCR H
- JNZ OFFDLY
- CALL OUTCTL ;GO OFF HOOK
- RET
- ENDIF ;PMMI OR DCH
- ;
- IF X8250
- MVI A,INITC1 ;ACCESS DIVISOR LATCHES
- CALL OUTCTL3
- MVI A,INITC2 ;SET DTR AND RTS
- CALL OUTCTL4
- MVI A,INITC3 ;BAUD DIVISOR LOW BYTE
- CALL OUTDATA
- MVI A,INITC4 ;BAUD DIVISOR HIGH BYTE
- CALL OUTCTL1
- MVI A,INITC5 ;DISABLE DIVISOR LATCHES,
- CALL OUTCTL3 ; SET 8 BIT WORD, 1 STOP, NO PAR
- MVI A,INITC6 ;DISABLE INTERRUPTS FROM 8250
- CALL OUTCTL1
- ENDIF ;X8250
- ;
- ;----> GETBAUD: GETS BAUD RATE FROM COMMAND
- ;
- ; THIS ROUTINE CHECKS IF A BAUD RATE HAS
- ; BEEN ASKED FOR, (SUCH AS MODEM T.450),
- ; AND IF SO, CALCULATES THE PMMI BAUD RATE
- ; VALUE TO BE OUTPUT. DEFAULTS TO 300.
- ;
- IF PMMI
- GETBAUD LDA FCB+9 ;GET 'FILETYPE'
- CPI ' ' ;DEFAULT?
- MVI A,DEFBAUD ;DEFAULT BAUD RATE
- RZ ;NO BAUD RATE, USE 300
- ;
- ; GOT BAUD RATE - CONVERT TO PROPER TIMER VALUE
- ;
- CALL CVBIN ;CONVERT NUMBER TO BINARY
- ;
- ; CALCULATE THE VALUE TO OUTPUT:
- ; RATE = 250000/16/BAUD RATE
- ; DIVIDE BY USING REPETITIVE SUBTRACTION
- ;
- ; COMPLEMENT THE BAUD RATE
- ;
- MOV A,H ;GET HI
- CMA ;COMPLEMENT
- MOV D,A ;SAVE
- MOV A,L ;GET LO
- CMA ;COMPLEMENT
- MOV E,A ;SAVE
- INX D ;DE=2'S COMPLEMENT
- ; DIVIDE
- LXI H,15625 ;250000/16
- LXI B,-1 ;INIT QUOTIENT
- ;
- DIVLP INX B ;BUMP QUOTIENT
- DAD D ;'SUBTRACT'
- JC DIVLP ;LOOP TIL DOOE
- ; VALIDATE THE RESULT
- MOV A,B ;CAN'T HAVE >255
- ORA A
- MOV A,C ;GET ACTUAL
- RZ ;RET IF <256
- JMP BADRATE ;INVALID
- ENDIF ;PMMI
- ;
- IF DCH
- GETBAUD LDA FCB+9 ;GET 'FILETYPE'
- CPI ' ' ;DEFAULT?
- JNZ GETBAU1 ;NO - DO BAUD RATE STUFF
- MVI C,1 ;SET 300 BAUD
- MVI B,17H ;SET 1 STOP BIT
- JMP GETBAU2
- ;
- GETBAU1 CALL CVBIN ;CONVERT TO BINARY
- PUSH H ;SAVE BAUD RATE
- MVI C,0 ;ANTICIPATE 110 BAUD
- MVI B,1FH ;SET 2 STOP BITS
- LXI D,-110 ;GET CONSTANT
- DAD D ;SUBTRACT
- MOV A,H
- ORA L
- POP H
- JZ GETBAU2 ;110 BAUD
- MVI B,17H ;SET 1 STOP BIT
- INR C
- LXI D,-300 ;GET CONSTANT
- DAD D
- MOV A,H
- ORA L
- JNZ BADRATE ;INVALID
- ;
- GETBAU2 MOV A,B ;GET SET UP
- CALL OUTCT2 ;INIT STOP & DATA BITS, ETC
- RET
- ENDIF ;DCH
- ;
- ; ROUTINE TO CONVERT BAUD RATE TO BINARY
- ;
- IF PMMI OR DCH
- CVBIN: LXI D,FCB+9 ;TO ASCII VALUE
- LXI H,0 ;INIT BINARY RESULT
- ;
- DECLP LDAX D ;GET ASCII DIGIT
- INX D ;TO NEXT DIGIT
- CPI ' ' ;BLANK ONE?
- JZ DECLP ;..YES, SKIP IT
- CPI '0' ;VAMIDATE IT
- JC BADRATE ;ERROR
- CPI '9'+1 ;VALIDATE
- JNC BADRATE ;ERROR
- SUI '0' ;MAKE DIGIT BINARY
- ;
- ; MULTIPLY PREV VALUE BY 10
- ;
- MOV B,H ;SET UP FOR
- MOV C,L ;MULTIPLY BY 10
- DAD H ;MULTIPLY BY 2
- DAD H ;X 2 = 4
- DAD B ;+ 1 = 5
- DAD H ;X 2 = 10
- ADD L ;ADD IN DIGIT
- MOV L,A ;SAVE BACK
- JNZ DIGNC ;NO CARRY?
- INR H ;ADD IN CARRY
- ;
- ; CHECK IF DONE
- ;
- DIGNC MOV A,E ;SEE IF PAST
- CPI FCB+12 ;..LAST DIGIT
- JNZ DECLP ;NO, LOOP
- RET
- ;
- ; INVALID BAUD RATE
- ;
- BADRATE CALL ERXIT
- DB '++Invalid baud rate++',CR,LF,'$'
- ENDIF ;PMMI OR DCH
- ;
- ; THE FOLLOWING PROVIDES A RETURN FROM INITMOD
- ;
- IF (NOT PMMI) AND (NOT DCH)
- RET ;**THIS MUST BE HERE**
- ENDIF ;(NOT PMMI) AND (NOT DCH)
- ;
- ;----> MOVEFCB: MOVES FCB(2) TO FCB
- ;
- ; I ATTEMPTED TO MAKE THE MODEM COMMAND 'NATURAL',
- ; I.E. MODEM SEND FILENAME (MODEM S FN.FT) RATHER
- ; THAN MODEM FILENAME SEND (MODEM FN.FT S) SO THIS
- ; ROUTINE MOVES THE FILENAME FROM THE SECOND FCB
- ; TO THE FIRST
- ;
- MOVEFCB LXI H,FCB+16 ;FROM
- LXI D,FCB ;TO
- MVI B,16 ;LEN
- CALL MOVE ;DO THE MOVE
- XRA A ;GET 0
- STA FCBSNO ;ZERO SECTOR #
- STA FCBEXT ;..AND EXTENT
- RET
- ;
- ;----> SHOW: SHOWS CHAR SENT/RECEIVED
- ;
- ; CR, LF, AND TAB ARE SHOWN. ALL OTHER
- ; NON-PRINTABLE CHARACTERS ARE SHOWN IN
- ; HEX AS (XX)
- ;
- SHOW CPI LF ;LF?
- JZ CTYPE ;..YES, TYPE IT
- CPI CR ;CR?
- JZ CTYPE ;..YES, TYPE IT
- CPI 09 ;TAB
- JZ CTYPE ;..YES, TYPE IT
- CPI ' ' ;CTL-CHR?
- JC SHOWHEX ;YES, SHOW IN HEX
- CPI 7FH ;DEL?
- JC CTYPE ;NO, TYPE THE CHAR
- ;
- SHOWHEX PUSH PSW ;SAVE THE CHAR
- MVI A,'(' ;TYPE..
- CALL CTYPE ;..'('
- POP PSW ;THEN..
- CALL HEXO ;..THE CHAR
- MVI A,')' ;THEN..
- JMP CTYPE ;..')' AND RETURN.
- ;
- ;----> CTYPE: TYPES VIA CP/M SO TABS ARE EXPANDED
- ;
- CTYPE PUSH B ;SAVE..
- PUSH D ;..ALL..
- PUSH H ;..REGS
- MOV E,A ;CHAR TO E
- MVI C,WRCON ;GET BDOS FNC
- CALL BDOS ;PRIN THE CHR
- POP H ;RESTORE..
- POP D ;..ALL..
- POP B ;..REGS
- RET ;FROM "CTYPE"
- ;
- CRLF MVI A,CR
- CALL TYPE
- MVI A,LF
- ;
- ;----> TYPE: TYPE VIA DIRECT CBIOS ACCESS.
- ; WE ASSUME CBIOS MAY DESTROY SOME REGISTERS,
- ; SO SAVE THEM ALL.
- ;
- ; THIS ROUTINE BYPASSES CP/M'S CTL-S, CTL-C
- ; TESTS.
- ;
- TYPE PUSH PSW ;SAVE CHAR
- PUSH B ;AND OTHER REGISTERS
- PUSH D
- PUSH H
- MOV C,A ;FOR BIOS
- VTYPE CALL $-$ ;MODIFIED AT INIT
- POP H ;RESTORE REGISTERS
- POP D
- POP B
- POP PSW ;..AND CHAR
- RET ;FROM "TYPE"
- ;
- ;----> STAT: KEYBOARD STATUS
- ;
- ; SAVE ALL REGISTERS, EXCEPT A, IN CASE
- ; CBIOS CLOBBERS THEM.
- ;
- STAT PUSH B
- PUSH D
- PUSH H
- VSTAT CALL $-$ ;ADDR SET AT INIT
- POP H
- POP D
- POP B
- ORA A ;0 => NOT READY
- RET
- ;
- ;----> KEYIN: KEYBOARD INPUT
- ;
- ; SAVE ALL REGISTERS, EXCEPT A, IN CASE
- ; CBIOS CLOBBERS THEM.
- ;
- KEYIN PUSH B
- PUSH D
- PUSH H
- VKEYIN CALL $-$ ;ADDR SET AT INIT
- POP H
- POP D
- POP B
- ANI 7FH ;STRIP PARITY IF THERE
- RET ;FROM KEYIN
- ;
- ;----> HEXO: HEX OUTPUT
- ;
- HEXO PUSH PSW ;SAVE FOR RIGHT DIGIT
- RAR ;RIGHT..
- RAR ;..JUSTIFY..
- RAR ;..LEFT..
- RAR ;..DIGIT..
- CALL NIBBL ;PRINT LEFT DIGIT
- POP PSW ;RESTORE RIGHT
- ;
- NIBBL ANI 0FH ;ISOLATE DIGIT
- CPI 10 ;IS IS <10?
- JC ISNUM ;YES, NOT ALPHA
- ADI 7 ;ADD ALPHA BIAS
- ;
- ISNUM ADI '0' ;MAKE PRINTABLE
- JMP TYPE ;..THEN TYPE IT
- ;
- ;----> CKQUIT: QUIT/RETRY AFTER X8251 MULTIPLE ERRORS
- ;
- ; RETURNS W/ZERO SET IF "RETRY" ASKED FOR
- ;
- CKQUIT XRA A ;ZERO..
- STA ERRCT ;..ERROR COUNT
- CALL ILPRT ;PRINT:
- DB BELL,'Multiple errors encountered. '
- DB 'Type ''Q'' to quit, ''R'' to retry: ',0
- CALL KEYIN ;QUIT/RETRY
- PUSH PSW
- CALL TYPE
- CALL CRLF
- POP PSW
- ANI 5FH ;MAKE UPPER CASE
- CPI 'R' ;RETRY?
- RZ ;'KEEP ON TRUCKIN'
- CPI 'Q' ;QUIT?
- JNZ CKQUIT ;NO, ASK AGAIN
- ORA A ;SET NON-ZERO
- RET
- ;
- ;----> ILPRT: INLINE PRINT OF MSG
- ;
- ; THE CALL TO ILPRT IS FOLLOWED BY A MESSAGE,
- ; BINARY 0 AS THE END. BINARY 1 MAY BE USED TO
- ; PAUSE (MESSAGE 'PRESS RETURN TO CONTINUE')
- ;
- ILPRT XTHL ;SAVE HL, GET HL=MSG
- ;
- ILPLP MOV A,M ;GET CHAR
- ORA A ;END OF MSG?
- JZ ILPRET ;..YES, RETURN
- CPI 1 ;PAUSE WITH MSG?
- JZ ILPAUSE ;..YES
- CPI 2 ;PAUSE, NO MSG?
- JZ ILPAUSE1 ;..YES
- CALL CTYPE ;TYPE THE MSG
- ;
- ILPNEXT INX H ;TO NEXT CHAR
- JMP ILPLP ;LOOP
- ;
- ; PAUSE WHILE TYPING HELP SO INFO DOESN'T
- ; SCROLL OFF OF VIDEO SCREENS
- ;
- ILPAUSE CALL ILPRT ;PRINT:
- DB CR,LF,'Press RETURN to continue: ',0
- ILPAUSE1 CALL KEYIN ;GET ANY CHAR
- CPI 'C'-40H ;REBOOT?
- JZ EXIT ;YES.
- CALL ILPRT ;PRINT
- DB CR,LF,0
- JMP ILPNEXT ;LOOP
- ;
- ILPRET XTHL ;RESTORE HL
- RET ;PAST MSG
- ;
- ;----> PRTMSG: PRINTS MSG POINTED TO BY (DE)
- ;
- ; A '$' IS THE ENDING DELIMITER FOR THE PRINT.
- ; NO REGISTERS SAVED.
- ;
- PRTMSG MVI C,PRINT ;GET BDOS FNC
- JMP BDOS ;PRINT MESSAGE, RETURN
- ;
- ;----> ERXIT: EXIT PRINTING MSG FOLLOWING CALL
- ;
- ERXIT POP D ;GET MESSAGE
- CALL PRTMSG ;PRINT IT
- CALL CKDIS ;DISCONNECT?
- ;
- EXIT CALL ILPRT ;PRINT:
- DB CR,LF,0
- LHLD STACK ;GET ORIGINAL STACK
- SPHL ;RESTORE IT
- RET ;--EXIT-- TO CP/M
- ;
- ; MOVE 128 CHARACTERS
- ;
- MOVE128 MVI B,128 ;SET MOVE COUNT
- ;
- ; MOVE FROM (HL) TO (DE) LENGTH IN (B)
- ;
- MOVE MOV A,M ;GET A CHAR
- STAX D ;STORE IT
- INX H ;TO NEXT "FROM"
- INX D ;TO NEXT "TO"
- DCR B ;MORE?
- JNZ MOVE ;..YES, LOOP
- RET ;..NO, RETURN
- ;************************************************************************
- ;* 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) *
- ;* *
- ;* *
- ;* There are four entry points, which are used as follows: *
- ;* *
- ;* CLRCRC - A call to this entry resets the CRC accumulator. *
- ;* It must be called at the start of each message. *
- ;* *
- ;* Entry Parameters: None. *
- ;* *
- ;* Exit Conditions: CRC accumulator cleared. *
- ;* All registers preserved. *
- ;* *
- ;* *
- ;* UPDCRC - A call to this entry updates the CRC accumulator. *
- ;* It must be called once for each byte in the *
- ;* message for which the CRC is being calculated. *
- ;* *
- ;* Entry Parameters: (A) = a byte to be included *
- ;* in the CRC calculation. *
- ;* *
- ;* Exit Conditions: CRC accumulator updated. *
- ;* All registers preserved. *
- ;* *
- ;* *
- ;* FINCRC - A call to this entry finishes the CRC calculation *
- ;* for a message which is to be TRANSMITTED. It must *
- ;* be called after the last byte of the message has *
- ;* been passed thru UPDCRC. It returns the calculated *
- ;* CRC bytes, which must be transmitted as the final *
- ;* two bytes of the message (first D, then E). *
- ;* *
- ;* Entry Parameters: None. *
- ;* *
- ;* Exit Conditions: (DE) = calculated CRC bytes. *
- ;* All other registers preserved. *
- ;* *
- ;* *
- ;* CHKCRC - A call to this routine checks the CRC bytes of *
- ;* a RECEIVED message and returns a code to indicate *
- ;* whether the message was received correctly. It must *
- ;* be called after the message AND the two CRC bytes *
- ;* have been received AND passed thru UPDCRC. *
- ;* *
- ;* Entry Parameters: None. *
- ;* *
- ;* Exit Conditions: (A) = 0 if message ok. *
- ;* (A) = -1 if message garbled. *
- ;* All other registers preserved. *
- ;* *
- ;************************************************************************
- ;* *
- ;* Designed & coded by Paul Hansknecht, June 13, 1981 *
- ;* *
- ;* *
- ;* Copyright (c) 1981, Carpenter Associates *
- ;* Box 451 *
- ;* Bloomfield Hills, MI 48013 *
- ;* 313/855-3074 *
- ;* *
- ;* This program may be freely reproduced for non-profit use. *
- ;* *
- ;************************************************************************
- ;
- CLRCRC: 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 ;CRC VALUE STORAGE
- ;
- OPTION DB 0 ;PRIMARY OPTION
- ;
- ; DATAFLG IS USED BY THE "V" SUBCOMMAND -
- ; IT IS 0 WHEN A HEADER OR CKSUM IS BEING
- ; SENT/RCD, AND 1 IF "VIEWABLE" DATA (THE
- ; SECTOR ITSELF)
- ;
- DATAFLG DB 0 ;AT HEADER, FIRST
- ;
- ; SUB-OPTION TABLE. IF AN OPTION IS IN EFFECT,
- ; THE CHARACTER IS SET TO BINARY 0
- ;
- OPTBL EQU $
- ANSWFLG DB 'A' ;ANSWER MODE
- DISCFLG DB 'D' ;DISCONNECT WHEN DONE
- ECHOFLG DB 'E' ;TO ECHO AFTER XFER
- ORIGFLG DB 'O' ;ORIGINATE MODE
- QFLG DB 'Q' ;QUIET TRANSFER (NO MSGS)
- RSEEFLG DB 'R' ;SEE WHAT'S RECEIVED
- SSEEFLG DB 'S' ;SEE WHAT'S SENT
- TERMFLG DB 'T' ;TO TERM AFTER XFER
- VSEEFLG DB 'V' ;VIEW MESSAGES (NO HDR, ETC)
- CRCFLG DB 'C' ;USE CRC INSTEAD OF CHECKSUM
- OPTBE EQU $ ;END OF OPTIONS
- ;
- FIRST DB 0FFH ;FLAG FOR FIRST TIME THRU SND OR RCV
- FIRSTME DB 0FFH ;FLAG FOR FIRST SOH RCVD IN CRC MODE
- ;
- MAXEXT DB 0 ;EXT COUNT USED BY 'CNREC'
- RCNT DW 0 ;EXTENT RECORD COUNT USED BY 'CNREC'
- RCVSNO DB 0 ;SECT # RECEIVED
- SECTNO: DW 0 ;CURRENT SECTOR NUMBER (LO, THEN HI)
- ERRCT DB 0 ;ERROR COUNT
- ERRCDE DB 0 ;RECEIVE ERROR CODE
- HOLDD DB 86H ;DC HAYES MODEM DEFAULT HOLDING AREA
- ;
- ; FOLLOWING USED BY ASCII CAPTURE AND PRINTER FUNCTIONS
- ;
- CPTRFLG DB 0 ;CAPTURE ENABLED FLAG
- PRTRFLG DB 0 ;PRINTER ENABLED FLAG
- ASCFCB DS 33 ;CAPTURE FCB
- MEMEND DS 1 ;LAST PAGE OF TPA
- CAPPTR DS 2 ;BUFFER POINTER
- ;
- ; FOLLOWING 3 USED BY DISK BUFFERING ROUTINES
- ;
- EOFLG DB 0 ;EOF FLAG (1=TRUE)
- SECPTR DW DBUF
- SECINBF DB 0 ;# OF SECTORS IN BUFFER
- ;
- DB 055H,0AAH ;GUARD BYTES TO HELP
- ; IDENTIFY STACK OVERFLOWS,
- ; NOT USED BY PROGRAM, ONLY
- ; FOR DUMP ANALYSIS
- DS 128 ;STACK AREA
- STACK DS 2 ;STACK POINTER
- ;
- ; DISK BUFFER (OVERLAYS HELP MSGS), SIZE=128*DBUFSIZ*8.
- ; NO PROGRAM CHECK IS DONE TO VERIFY THAT THE BUFFER
- ; WILL NOT OVERLAY THE CCP AND/OR BDOS ON A GIVEN SYSTEM,
- ; SO THE BURDEN IS ON THE USER TO MAKE SURE OF THIS.
- ; A REASONABLE BUFFER SIZE IS 16K. TRADITIONALLY, BUFFER
- ; SIZE HAS BEEN 2K.
- ;
- DBUF EQU $
- ;
- ; ASCII CAPTURE BUFFER, MUST START ON PAGE BOUNDARY
- ;
- ASCBUF: EQU DBUF+0FFH AND 0FF00H ;USE SAME DISK BUFFER FOR ASCII
- ;CAPTURE, SINCE CAPTURE NOT DONE
- ;WHILE XFER IN PROGRESS. TO HAVE SEPARATE BUFFERS LIKE IN
- ;MODEM220: ASCBUF EQU (DBUF+(DBUFSIZ*1024)+0FFH) AND 0FF00H
- ;
- ; INVALID COMMAND
- ;
- BADOPT PUSH PSW ;SAVE BAD OPTION
- CALL CRLF
- CALL ILPRT
- DB '++''',0
- POP PSW ;RETRIEVE BAD OPTION
- CALL TYPE ;PRINT BAD OPTION
- CALL ILPRT ;EXIT W/ERROR
- DB ''' is an invalid MODEM command option++',CR,LF,CR,LF
- DB 'Press RETURN for help, Ctl-C to exit: ',2,0
- ;
- HELP CALL ILPRT
- DB '(T)erminal and (E)cho mode commands:',CR,LF
- DB ' Ctl-Y = Ascii capture enable/disable toggle',CR,LF
- DB ' Ctl-E = Exit to CP/M',CR,LF
- DB ' Ctl-D = Disconnect phone',CR,LF
- DB ' Ctl-P = Printer enable/disable toggle',CR,LF,CR,LF
- DB 'Format for command is:',CR,LF,CR,LF
- DB 'MODEM # Filename',CR,LF,CR,LF
- DB 'Where # is a 1 character primary option,',CR,LF
- DB ' which may be followed by sub-options,',CR,LF
- DB ' and by ".xxx" to set baud rate to xxx',CR,LF,CR,LF,1
- DB 'Primary Options:',CR,LF,CR,LF
- DB ' S to send a file',CR,LF
- DB ' R to receive a file',CR,LF
- DB ' T to act as a terminal',CR,LF
- DB ' E to act as a computer (echo data)',CR,LF
- DB ' D to disconnect the phone',CR,LF
- DB ' H to print this help file',CR,LF,CR,LF,1
- DB 'Secondary options:',CR,LF
- DB ' A answer mode',CR,LF
- DB ' O originate mode',CR,LF
- DB ' D disconnect after execution',CR,LF
- DB ' T go to terminal mode after file xfer',CR,LF
- DB ' E go to echo mode after file xfer',CR,LF
- DB ' Q quiet mode - no status msgs',CR,LF
- DB ' R show chars received',CR,LF
- DB ' S show chars sent',CR,LF
- DB ' V view file sent/received (no status)',CR,LF
- DB ' C use cyclic redundancy check for file xfers',CR,LF
- DB CR,LF,'For examples, type: MODEM X',CR,LF,0
- JMP EXIT
- ;
- EXAM CALL ILPRT
- DB 'Send file, originate mode, 300 baud:',CR,LF
- DB ' MODEM SO fn.ft',CR,LF
- DB 'Send another file:',CR,LF
- DB ' MODEM S fn/ft',CR,LF
- DB 'Then send a third file at 450 baud and disconnect:'
- DB CR,LF,' MODEM SD.450 fn.ft',CR,LF
- DB 'Act as a terminal, originate mode, at 110 baud:',CR,LF
- DB ' MODEM TO.110',CR,LF
- DB ' (Use ctl-D to disconnect)',CR,LF
- DB 'Receive file, answer mode, view it, 600 baud:',CR,LF
- DB ' MODEM RAV.600 fn.ft',CR,LF
- DB 'Receive file, use cyclic redundancy check, 600 baud:',CR,LF
- DB ' MODEM RC.600 fn,ft',CR,LF
- DB 'Turn printer mode on/off in terminal or echo mode:',CR,LF
- DB ' ^P (printer now toggled)',CR,LF
- DB 'Turn on ascii capture mode:',CR,LF
- DB ' ^Y ',CR,LF
- DB ' FILE NAME --> b:test.doc [CR] (file now open)',CR,LF
- DB 'Turn off ascii capture mode:',CR,LF
- DB ' ^Y (ascii capture disabled, file closed)',CR,LF,0
-
- JMP EXIT
- ;
- ; BDOS EQUATES (VERSION 2)
- ;
- RDCON EQU 1
- WRCON EQU 2
- PRINT EQU 9
- CONST EQU 11 ;CONSOLE STAT
- OPEN EQU 15 ;0FFH=NOT FOUND
- CLOSE EQU 16 ; " "
- SRCHF EQU 17 ; " "
- SRCHN EQU 18 ; " "
- ERASE EQU 19 ;NO RET CODE
- READ EQU 20 ;0=OK- 1=EOF
- WRITE EQU 21 ;0=OK, 1=ERR, 2=?, 0FFH=NO DIR SPC
- MAKE EQU 22 ;0FFH=BAD
- REN EQU 23 ;0FFH=BAD
- STDMA EQU 26 ;SET DMA
- BDOS EQU BASE+5
- REIPL EQU BASE
- FCB EQU BASE+5CH ;SYSTEM FCB
- FCBEXT EQU FCB+12 ;FILE EXTENT
- FCBSNO EQU FCB+32 ;SECTOR #
- FCB2 EQU FCB+6CH ;2ND FCB
- END