; M7VIO-2.ASM -- Ithaca VIO w/ 2651 overlay. 06/30/85. ; ; Replaces M7VIO-1.ASM and supports the SET command at 2400 Baud. ; It starts out at 1200 baud when the program is first called up. ; Tested with the Hayes Smartmodem 1200 and US Robotics Courier 2400. ; ; One small problem surfaced. When calling with the Courier at 2400, ; if the other end answers at 1200, the Courier resets to 1200 and ; expects you to do the same with the UART. That code was not added ; here and if it happens to you, the simplest recovery is to get out ; of MODEM and start over. ; ; TO USE: First edit this file filling in answers for your own ; equipment. Then assemble with ASM.COM or equivalent ; assembler. Then use DDT to overlay the the results ; of this program to the original .COM file: ; ; A>DDT MDM729.COM ; DDT VERS 2.2 ; NEXT PC ; 4A00 0100 ; -IM7VIO-1.HEX (note the "I" command) ; -R ("R" loads in the .HEX file) ; NEXT PC ; 4A00 0000 (MDM729 is 73 sectors) ; -G0 (return to CP/M) ; A>SAVE 73 MODEM.COM (now have a modified .COM file) ; ; = = = = = = = = = = = = = = = = = = ; ; 06/30/85 - Added 2400 Baud support - Dave Crane ; 03/24/84 - Added SMODEM commands - Dave Crane ; 09/18/83 - MDM711HZ modified for Ithaca VIO+2651 - Dave Crane ; 07/01/83 - Revised to work with MDM711 - Irv Hoff ; 06/22/83 - Revised to work with MDM710 - Irv Hoff ; 05/27/83 - Revised to work with MDM709 - Irv Hoff ; 05/15/83 - Revised to work with MDM708 - Irv Hoff ; 04/11/83 - Updated to work with MDM707 - Irv Hoff ; 04/04/83 - Updated to work with MDM706 - Irv Hoff ; 02/27/83 - Updated to work with MDM705 - Irv Hoff ; 02/17/83 - Modified MDM703CF to work with ; Heath/Zenith -100 series com- ; puters with 2661B I/O - Irv Hoff ; ; = = = = = = = = = = = = = = = = = ; BELL: EQU 07H ;bell CR: EQU 0DH ;carriage return ESC: EQU 1BH ;escape LF: EQU 0AH ;linefeed ; YES: EQU 0FFH NO: EQU 0 ; ; Modem cable assumed set up as follows: ; ; Modem Ithaca VIO board Function ; 2 3 TXD -> RXD ; 3 2 RXD <- TXD ; 4-\ RTS -\ (jumpered) ; 5-/ CTS -/ (together) ; 8 20 Carrier=DCD -> DSR ; 7 7 Ground -- Ground ; 22 22 RI -> not used ; 20 8 DTR <- DTR ; ; Be certain the 2651 pin 16 (DCD) is tied to ground. If it floats, the ; chip will never indicate data available. This was a flaw in several ; Rev/B boards tested, even though the documentation indicates Rev/B fixed ; the problem. ; ; This diagram and logic also applies to BYEII and XMODEM but note that data- ; set ready, not the ring indicator, is the signal that a call is coming in. ; SmartModem switches are assumed to be UUDU DUUD for BYE. XMODEM doesn't care. ; USR Courier 2400 switches are assumed UUDD DUDD DU; it will work with the ; same switch settings as the Hayes 1200. ; ; DCC 3/26/84 ; ;======================================================================= ; MODDATP: EQU 20H ;BASE PORT = Data Port MODSTAT: EQU MODDATP+1 ;STATUS PORT MODMODE: EQU MODDATP+2 ;MODE PORT MODCTLP: EQU MODDATP+3 ;CONTROL PORT BASEP EQU MODDATP ;Base port for Intersystems VIO DPORT EQU BASEP ;Modem data port SPORT EQU BASEP+1 ;Modem status port MPORT EQU BASEP+2 ;Modem mode select port CPORT EQU BASEP+3 ;Modem control port ; ; Modem status port equates ; TBMT EQU 00000001b ;Transmit buffer empty DAV EQU 00000010b ;Data available PE EQU 00001000b ;Parity error OE EQU 00010000b ;Overrun error FE EQU 00100000b ;Framing error DCD EQU 01000000b ;Carrier detect RDET EQU 10000000b ;Ring detect ; (In this configuration RDET is actually data set ready) ; ; Mode port equates ; E8NO1 EQU 01001110b ;8 data bits, no p, 1 stop, 16x rate EBASE EQU 00110000b ;Mode register 2 base B110 EQU EBASE+2 ;110 baud (not implemented) B300 EQU EBASE+5 ;300 baud B600 EQU EBASE+6 ;600 baud (not implemented) B1200 EQU EBASE+7 ;1200 baud B2400 EQU EBASE+10 ;2400 baud B4800 EQU EBASE+12 ;4800 baud (not implemented) B9600 EQU EBASE+14 ;9600 Baud ; ; Command port equates ; CBASE EQU 00000101b ;Command base RISET EQU 00010000b ;Reset errors DTR EQU 00000010b ;Turn on DTR RTS EQU 00100000b ;Turn on RTS ; ORG 100H ; DS 3 ;(for "JMP START" instruction) ; PMMIMODEM: DB NO ;yes=PMMI S-100 Modem 103H SMARTMODEM: DB YES ;yes=HAYES Smartmodem, no=non-Hayes 104H TOUCHPULSE: DB 'T' ;T=touch, P=pulse (Smartmodem-only) 105H ; CLOCK: DB 57 ;clock speed in MHz x10, 25.5 MHz max. 106H ;20=2 MHh, 37=3.68 MHz, 40=4 MHz, etc. MSPEED: DB 5 ;0=110 1=300 2=450 3=600 4=710 5=1200 107H ;6=2400 7=4800 8=9600 9=19200 default BYTDLY: DB 5 ;0=0 delay 1=10ms 5=50 ms - 9=90 ms 108H ;default time to send character in ter- ;minal mode file transfer for slow BBS. CRDLY: DB 5 ;0=0 delay 1=100 ms 5=500 ms - 9=900 ms 109H ;default time for extra wait after CRLF ;in terminal mode file transfer NOOFCOL: DB 5 ;number of DIR columns shown 10AH SETUPTST: DB YES ;yes=user-added Setup routine 10BH SCRNTEST: DB NO ;Cursor control routine 10CH NORETRY: DB YES ;yes=resend a record after any non-ACK 10DH ;no=resend a record after a valid NAK BAKUPBYTE: DB YES ;yes=change any file same name to .BAK 10EH CRCDFLT: DB YES ;yes=default to CRC checking 10FH TOGGLECRC: DB YES ;yes=allow toggling of CRC to Checksum 110H CONVBKSP: DB NO ;yes=convert backspace to rub 111H TOGGLEBK: DB NO ;yes=allow toggling of bksp to rub 112H ADDLF: DB NO ;no=no LF after CR to send file in 113H ;terminal mode (added by remote echo) TOGGLELF: DB YES ;yes=allow toggling of LF after CR 114H TRANLOGON: DB YES ;yes=allow transmission of logon 115H ;write logon sequence at location LOGON SAVCCP: DB YES ;yes=do not overwrite CCP 116H LOCONEXTCHR: DB NO ;yes=local command if EXTCHR precedes 117H ;no=external command if EXTCHR precedes TOGGLELOC: DB YES ;yes=allow toggling of LOCONEXTCHR 118H LSTTST: DB NO ;yes=printer available on printer port 119H XOFFTST: DB YES ;yes=checks for XOFF from remote while 11AH ;sending a file in terminal mode XONWAIT: DB NO ;yes=wait for XON after CR while 11BH ;sending a file in terminal mode TOGXOFF: DB YES ;yes=allow toggling of XOFF checking 11CH IGNORCTL: DB YES ;yes=CTL-chars above ^M not displayed 11DH EXTRA1: DB 0 ;for future expansion 11EH EXTRA2: DB 0 ;for future expansion 11FH BRKCHR: DB '@'-40H ;^@ = Send a 300 ms. break tone 120H NOCONNCT: DB 'N'-40H ;^N = Disconnect from the phone line 121H LOGCHR: DB 'O'-40H ;^O = Send logon 122H LSTCHR: DB 'P'-40H ;^P = Toggle printer 123H UNSAVE: DB 'R'-40H ;^R = Close input text buffer 124H TRANCHR: DB 'T'-40H ;^T = Transmit file to remote 125H SAVECHR: DB 'Y'-40H ;^Y = Open input text buffer 125H EXTCHR: DB '^'-40H ;^^ = Send next character 126H ; DS 2 ; 128H ; IN$MODSTAT: IN MODSTAT ! RET ;in modem status port 12AH DS 7 OUT$MODDATP: OUT MODDATP ! RET ;out modem data port 134H DS 7 IN$MODDATP: IN MODDATP ! RET ;in modem data port 13EH ;---> DS 31 DS 7 ;---> ; ANI$MODRCVB: ANI DAV ! RET ;bit to test for receive ready 148H CPI$MODRCVR: CPI DAV ! RET ;value of rcv. bit when ready 14BH ANI$MODSNDB: ANI TBMT ! RET ;bit to test for send ready 14EH CPI$MODSNDR: CPI TBMT ! RET ;value of send bit when ready 151H DS 6 ; 156H OUT$MODCTL1: OUT MODCTLP ! RET ;out modem control port #2 15AH OUT$MODCTL2: OUT MODCTLP ! RET ;out modem control port #1 15DH ; ;---> ; LOGONPTR: DW LOGON ;for user message. 160H DS 6 ; 162H JMP$GOODBYE: JMP GOODBYE ; 168H JMP$INITMOD: JMP INITMOD ;go to user written routine 16BH RET ! NOP ! NOP ;(by-passes PMMI routine) 16EH RET ! NOP ! NOP ;(by-passes PMMI routine) 171H RET ! NOP ! NOP ;(by-passes PMMI routine) 174H JMP$SETUPR: JMP SETUPR ; 177H JMP$SPCLMENU: JMP SPCLMENU ; 17AH JMP$SYSVER: JMP SYSVER ; 17DH JMP$BREAK: JMP SENDBRK ; 180H ; ; Do not change the following six lines. ; JMP$ILPRT: DS 3 ; 183H JMP$INBUF DS 3 ; 186H JMP$INLNCOMP: DS 3 ; 189H JMP$INMODEM DS 3 ; 18CH JMP$NXTSCRN: DS 3 ; 18FH JMP$TIMER: DS 3 ; 192H ; ; TVI, Lear Siegler, etc. ; CLREOS: CALL JMP$ILPRT ; 195H DB ESC,79H,0,0,0 ; 198H RET ; 19DH ; CLRSCRN: CALL JMP$ILPRT ; 19EH DB ESC,3AH,0,0,0 ;CLEAR ENTIRE SCREEN 1A1H RET ; 1A6H ; ; SYSVER: CALL JMP$ILPRT ; 1A7H DB 'Version for Ithaca VIO/2651 at port 20H' DB CR,LF,0 DB RET ;..... ;----------------------------------------------------------------------- ; ; NOTE: You can change the SYSVER message to be longer or shorter. The ; end of your last routine should terminate by 0400H (601 bytes ; available after start of SYSVER) if using the Hayes Smartmodem ; or by address 0C00H (2659 bytes available) otherwise. ; ;----------------------------------------------------------------------- ; ; You can put in a message at this location which can be called up with ; CTL-O if TRANLOGON has been set YES. You can put in several lines if ; desired. End with a 0. ; LOGON: DB 'DAVE;CRANE',CR,LF,0 ;..... ; ; This routine allows a 300 ms. break tone to be sent to reset some ; time-share computers. ; SENDBRK: MVI A,3DH ;SEND A BREAK TONE FOR 300 MS. MVI B,3 ;DELAY FOR 300 MS. CALL JMP$TIMER MVI A,CBASE+RISET+DTR+RTS OUT MODCTLP ;Xmit, Recv, DTR, RTS on, reset. IN MODDATP ;CLEAR ANY INCOMING CHARS. IN MODDATP ;TRY ONCE MORE RET ; ; This routine sends a 300 ms. break tone and sets DTR low for the same ; length of time to disconnect some modems such as the Bell 212A, etc. ; GOODBYE: CALL SENDBRK ;SEND 300MS BREAK TONE MVI A,CBASE ;SET BREAK, DTR & RTS LOW OUT MODCTLP ;PUT COMMAND REGISTER OUT OF MODE MVI B,3 ;DELAY FOR 300 MS. CALL JMP$TIMER MVI A,CBASE+RISET+DTR+RTS OUT MODCTLP ;SEND TO COMMAND REGISTER IN MODDATP ;CLEAR ANY INCOMING CHARS. IN MODDATP ;TRY ONCE MORE XRA A ;CLEAR THE 'A' REG. RET ; ; The following are used in setting up the 2651 I/O port. ; INITMOD: MVI A,5 ;START WITH 1200 BAUD STA MSPEED ;DEFAULT TRANSFER TIME IN MODCTLP ;Clear/Reset Mode toggle on port MVI A,E8NO1 ;1 STOP, NO PARITY, 8 BITS, ASYNC 16X OUT MODMODE ;SEND TO MODE REGISTER 1 INITMOD1: MVI A,B1200 ;START WITH 1200 BAUD OUT MODMODE ;SEND TO MODE REGISTER 2 MVI A,CBASE+RISET+DTR+RTS ;RESET RTS, FLAGS, DTR LOW, ENABLE R/T OUT MODCTLP ;SEND TO COMMAND REGISTER CALL SMINIT ;Reinitialize the SmartModem to this rate. RET ;..... ; ; The following changes the baud rate with the SET command. ; SETUPR: LXI D,BAUDBUF CALL JMP$ILPRT DB 'Input Baud Rate (300, 1200, 2400, 9600): ',0 CALL JMP$INBUF LXI D,BAUDBUF+2 CALL JMP$INLNCOMP ;COMPARE BAUDBUF+2 WITH CHARACTERS BELOW DB '300',0 JNC OK300 ;GO IF GOT MATCH CALL JMP$INLNCOMP DB '1200',0 JNC OK1200 CALL JMP$INLNCOMP DB '2400',0 JNC OK2400 CALL JMP$INLNCOMP DB '4800',0 JNC OK4800 CALL JMP$INLNCOMP DB '9600',0 JNC OK9600 CALL JMP$ILPRT ;ALL MATCHES FAILED, ASK AGAIN DB '++ Incorrect entry ++',CR,LF,BELL,0 JMP SETUPR ;TRY AGAIN ; OK300: MVI A,1 LHLD BD300 JMP LOADBD ; OK1200: MVI A,5 LHLD BD1200 JMP LOADBD ; OK2400: MVI A,6 LHLD BD2400 JMP LOADBD ; OK4800: MVI A,6 ;See comments after next Baud rate: LHLD BD4800 JMP LOADBD ; OK9600: MVI A,6 ;Obviously this won't work with a slower LHLD BD9600 ; modem. It's intended for null modems. JMP LOADBD ; LOADBD: STA INITMOD+1 ;Store in INITMOD instruction MOV A,L ;get least significant baud rate byte STA INITMOD1+1 ;store in INITMOD1 JMP INITMOD ;reset 2651 ;..... ; ; TABLE OF BAUDRATE PARAMETERS FOR 2651 I/O ; BD110 DB EBASE+2 ; 110 BAUD BD300 DB EBASE+5 ; 300 BAUD BD1200 DB EBASE+7 ;1200 BAUD BD2400 DB EBASE+10 ;2400 BAUD BD4800 DB EBASE+14 ;4800 BAUD BD9600 DB EBASE+14 ;9600 BAUD ; BAUDBUF: DB 10,0 DS 10 ; ; SPCLMENU: RET ; Not used ; NOTE: MUST TERMINATE PRIOR TO 0400H (with Smartmodem) ; 0C00H (without Smartmodem) ; ; D.C. Hayes Smartmodem 300/1200 'Modem Control' ; From: BY2+SMDM.ASM by Don Brown ; Version 1.1 04/24/83 ; Mods: Dave Crane, Dallas RCP/M ; ; These routines may be used along with the more specific modem/ ; serial port/baud rate routines commonly found in BY2-MOD.LBR. ; ; The following Smartmodem Default switches are assumed: ; A. Switches 'Not' configurable by Software Control: ; 1=Up, DTR supported, do Not force to always logic true. ; 6=Up, DCD supported, do Not force to always logic true. ; 7=Up, Single Line RJ11 Telephone connection to Smartmodem. ; 8=Down, Enables modem command recognition, when in Command State. ; B. Switches 'configurable' by Software Control: ; 2=Up, Send English result codes when in Command State. ; 3=Down, Result Codes are sent to the Terminal. ; 4=Down, Do not echo characters when in Command State. ; 5=Down, Do not answer the telephone. ; ; The USR Courier 2400 switches are almost identical to the Hayes 1200. ; We run the RCP/M with 1,2,6, and 10 UP and the rest DOWN (except "11"). ; ; Notes: ; USR Courier will automatically set itself to the speed of the ; calling modem, provided the speed is 300 -> 2400 baud. This ; relieves us of the need to set the modem (still have to check and ; set the USART/baud), via software instructions. 110 baud is not ; supported because Smartmodem cannot differentiate between 110-300 ; baud and will not set itself automatically. ; ; Code causes DTR to go false in order to Hang-Up the phone. When ; DTR goes false, smartmodem will automatically drop the line and go ; to Local Command State. However, DTR must be true for Smartmodem ; to receive and execute commands. Further, when you turn DTR on, for ; this purpose, Smartmodem is still set at the Baud rate of the last ; call and is still in auto answer mode. If the telephone is ringing ; when DTR goes true and the number of rings stored in smartmodem ; register S0 is 1 (and possibly even 2), there may not be enough time ; to send the first command string before smartmodem goes off the hook ; into a carrier wait state. If you send any characters to smartmodem ; during this carrier wait state (before it has recognizes an incoming ; carrier and goes On Line), the smartmodem will hang-up the line and ; return to local command state. Also, all characters received by it, ; after this first key character (ie. the 'A' of the required 'AT..'), ; after in local command state, will be received as random data and ; may confuse smartmodem's baud rate detector and command decoder, ; leaving smartmodem in an unpredictable state (which may keep your ; system down till you manually reset it). If the command string is ; sent after smartmodem has recognized carrier and gone on line, it ; goes out the modem port to the calling modem as data (garbage). ; Consequently, it is extremely important that smartmodem register S0 ; be set to at least 3 if not 4 rings and the smartmodem command string ; 'ATZ' be executed immediately after DTR is set true!! ; ; The first command string sent to smartmodem ie. 'ATZ', will set the ; smartmodem baud rate to the speed at which it was sent (the speed or ; baud of your USART which was just set in the initialization routines). ; This command will also cause the Smartmodem to do its own software ; reset (return to default switch settings). Note that switch 5 is ; down so that modem does Not default to auto Answer. We set auto ; when we're ready, with the second command string we send. ; ; The Smartmodem needs at least 250msecs. delay between commands, in ; order to execute the command and be ready to receive the next command ; or between data and a command (sometimes longer). ; ; Initialize the Smartmodem. ; DTR must be logic true for Smartmodem to receive and process a command. ; The S0 modem register setting should not be less than 2 and should be the ; last command in the command string. ; PSPEED: EQU 6 ;Processor speed - MHz ; SMINIT: CALL MDMRST ;Reset with 'ATZ' CALL SMDELAY ;One second delay needed by Smartmodem CALL SMSEND ;Initialize Smartmodem DB 'ATQ1E0M1S2=128S7=11S9=6S10=60S0=255',CR,0 CALL SMDELAY ;One second delay needed by Smartmodem RET ;Return ; ; Initialize the SmartModem to virgin state ; MDMRST: CALL SMSEND DB 'ATZ',CR,0 ; set SmardModem to no auto answer RET ; ; Let the Smartmodem have one second before receiving a command. ; ie. one second to process a Command or before any other data ; is sent to it. DTR must be On for Smartmodem to receive and process ; a command when it is local command state. ; SMDELAY: PUSH B ;Preserve in case it's in use elsewhere MVI B,10 ;Wait one second DLP1: CALL DELAY DCR B JNZ DLP1 ;Keep looping till done POP B ;Done, restore BC RET ;Return ; ; Send the Command String to the Smartmodem ; Similiar to how ILPRT sends to console ; SMSEND: XTHL ;Save HL, get address of message PUSH B ;Save BC ; SMPLP: IN SPORT ;Get modem output status ANI TBMT ;mask junk JZ SMPLP ;Not ready to send yet... MOV A,M ;Ready, get the character.. OUT DPORT ;Send the character INX H ;Point to next character MOV A,M ;Get next character ORA A ;Delimiter ? All sent ? JNZ SMPLP ;..No, go send another POP B ;..Yes, restore BC XTHL ;...restore HL, get return Address RET ;Return ; ;.1 sec delay routine ; DELAY: PUSH B LXI B,417*PSPEED ;timing constant * speed in MHz ; DELAY1: DCX B MOV A,B ORA C JNZ DELAY1 POP B RET ; END  LXI B,417*PSPEED ;timing constant * speed in MHz ; DELAY1: DCX B MOV A,B ORA C JNZ