; Title 'MEX Overlay for the Vector 4 Computer Version 1.0' ; - Dick LeBleu ; - Winnipeg, Canada ; - 5 Oct 1986 ; Misc equates ; REV EQU 10 ;OVERLAY REVISION LEVEL ; NO EQU 0 YES EQU 0FFH ; TPA EQU 100H ; CR EQU 13 LF EQU 10 TAB EQU 9 ; ANCHOR EQU NO ;YES, ONLY if using Anchor Modem ANDAB EQU 65 ;Anchor dial abort character ('A') ; ; ; ; MEX Overlay for Vector 4 Computers with external modems. ; A full-featured SET command processor ; is implemented to select between modems as well as set ; specific characteristics of each one. The following table ; outlines the SET command options: ; ; SET Command ; ; PORT ; DELAY (seconds) ; BAUD ; ORIG (originate mode) ; ANSWER (mode) ; TONE (dialing) ; PULSE (dialing) ; MONITOR (speaker on) ; QUIET (speaker off) ; PARITY (Odd, Even, None) ; STOPBITS (1, 1.5, 2) ; LENGTH (5, 6, 7, or 8) ; MANUALO (turn off carrier tone ; for Originate mode) ; MANUALA (turn on carrier tone ; for Answer mode) ; ;............ ; ; ; This overlay includes the smartmodem dialing routine from ; MXO-SM13.ASM by Ron Fowler which has been slightly modified ; to allow programmable delay for answer. (Note that this is ; different from the "ATS7=nn".). ; ; This overlay is intended to be fully compatible with the ; MEX structure and should be readily upward compatible with ; the predicted MEX 2.0. ; ; Calling conventions for the various overlay entry points ; are detailed more fully in the PMMI overlay (MXO-PMxx.ASM, ; where xx=revision number). ; ; History: ; ; 08/08/86 1.0 Modified for Vector 4 by Dick Le Bleu. 8251 instead of sio ; ; 30/12/85 1.0 Modified for Ibex by Dick Le Bleu. Added set port ; command for switching between port A(Blue) and ; B(Black). ; ; 9/19/84 4.1 Fixed DISCON1 routine for non-Anchors, was leaving ; DTR and RTS off, now lowers them for one sec and ; raises it.. Also added code to dial routine to allow ; any character (other than ^C) typed during a dial ; command to abort THAT dial attempt, but will ; proceed with repetition or next command. ^C will ; abort call in progress and any other CALL cmds ; lined up. (This is for "dumb" Smartmodems that ; don't detect busy, if you hear busy, just hit ; the space bar and it will give it up and try the ; next one or try calling again.) -- Kim Levitt ; ; 9/9/84 4.0 Upgraded internal modem support to include ; SET PARITY, STOPBITS, and LENGTH. ; Corrected error when setting STOPBITS to 1.5, which ; was resetting parity off at the same time. With the ; the improvements to the internal modem support, all ; features of SUPRTERM are now supported by this overlay. ; Enhanced SET MANUAL processing for internal modem ; to support manual Originate or Answer carrier tones. ; Version level changed to eliminate confusion between ; 2.X and 3.X overlays currently in circulation. ; Updated comments and documentation in all sections. ; Terry Carroll ; ; 8/26/84 2.8 Added equate to support Anchor Signalman Mark XII modem. ; This overlay now supports DSC, dial abort (^C), ; and accurate SET DELAY processing for Anchor modems. ; Also incorporated the PARITY, STOPBITS and LENGTH ; commands from the Norm Saunders overlay (MXO-KP3X) in ; an attempt to unify the MEX overlay identity crisis. ; ; 8/03/84 2.7 Added call to DISCON: (disconnect routine) in the ; Smartmodem dialing routine at SMDMOFF:. It appeared that ; when either the delay timer timed out or a CTRL -C ; abort coincided with a connect, the modem did ; connect, even though the overlay responded with ; NO ANSWER. Added these calls to make sure there ; is no unannounced connect. John C. Smith ; ; 6/10/84 2.6 Undid revision 2.5. MEX is intended NOT to disconnect ; from the phone line on re-entering CPM; DCD detection ; supports this function as well as preventing the ; modem initialization string from being sent to the ; remote computer. For Smartmodem, set switch 6 up; ; for other modems, enable DCD detection. Also, ; the internal modem initialization had been commented ; out without documentation. This defeats one-half ; of the value of this overlay. Restored this ; initialization. ; ; 6/03/84 2.5 Commented out three lines Dennis Quinn ; at NITMOD2 which prevented Royal Oak, MI ; "off the shelf" Smartmodem ; from being initialized. Reason for this is that ; the Smartmodem asserts DCD even when no carrier ; is being detected unless the case is opened and ; an option switch is set. Side effect of commenting ; out these lines is re-entering MEX will transmit ; the initialization sequence to the remote if you ; are on-line. If you set the appropriate option ; switch (I can't remember which switch it is and ; my Smartmodem book is at the office), uncomment ; the code and all will be well. ; ; 6/02/84 2.4 Code was turning off RTS Dennis Quinn ; after disconnect sequence. Royal Oak, MI ; This was causing problems ; with certain modems which are more intelligent than ; the Smartmodem and require RTS before they will ; assert CTS. Enabled 110 baud operation for those ; who are masochists. ; ; ; 5/29/84 2.2 Corrected SET ? to display Steve Sanders ; proper SET ORIG command instead ; of SET ORIGINATE ; ; 5/18/84 1.0 Original version John Smith - Manlius, NY ; ; Credits: ; ; M7KP-1 overlay structure by Irv Hoff ; Smartmodem dialing routine by Ron Fowler ; ; Bug Reports: ; ; Would appreciate a note of any problems be left on the ; Computers Etc. RBBS at 315-446-7793. ; ; ;------------------------------------------------------------ ; ; Vector 4 default port definitions ; DCD EQU YES ;if supported by port CMBAUD EQU 11h ; modem baud rate port PTBAUD EQU 12h ; printer baud rate port COMCTL EQU 05h ; modem status port COMDAT EQU 04h ; modem data port PRTCTL EQU 07H ; printer status port PRTDAT EQU 06h ; printer data port ; ; Vector 4 bit definitions ; MDRCVB EQU 02H ;modem receive bit (DAV) MDRCVR EQU 02H ;modem receive ready MDSNDB EQU 01H ;modem send bit MDSNDR EQU 01H ;modem send ready bit MDSDCD EQU 80H ;modem DCD ready bit ; ; MEX Service Processor ; MEX EQU 0D00H ;address of the service processor INMDM EQU 255 ;get char from port to A, CY=no more in 100 ms TIMER EQU 254 ;delay 100ms * reg B TMDINP EQU 253 ;B=# secs to wait for char, cy=no char CHEKCC EQU 252 ;check for ^C from KBD, Z=present SNDRDY EQU 251 ;test for modem-send ready RCVRDY EQU 250 ;test for modem-receive ready SNDCHR EQU 249 ;send a character to the modem (after sndrdy) RCVCHR EQU 248 ;recv a char from modem (after rcvrdy) LOOKUP EQU 247 ;table search: see CMDTBL comments for info PARSFN EQU 246 ;parse filename from input stream BDPARS EQU 245 ;parse baud-rate from input stream SBLANK EQU 244 ;scan input stream to next non-blank EVALA EQU 243 ;evaluate numeric from input stream LKAHED EQU 242 ;get nxt char w/o removing from input GNC EQU 241 ;get char from input, cy=1 if none ILP EQU 240 ;inline print DECOUT EQU 239 ;decimal output PRBAUD EQU 238 ;print baud rate ; CONOUT EQU 2 ;simulated BDOS function 2: console char out PRINT EQU 9 ;simulated BDOS function 9: print string INBUF EQU 10 ;input buffer, same structure as BDOS 10 ; DCONIO EQU 6 ;BDOS Direct Console I/O function # DCONIN EQU 0FFH ;BDOS DCONIO flag for input BDOS EQU 5 ;address of BDOS function caller ; ; ; MACLIB Z80 ; ORG TPA ;we begin ; DB 0C3H ;JMP instruction - requd for MEX+ DS 2 ;MEX has a JMP START here ; DS 2 ;not used by MEX TPULSE: DB 'T' ;T=touch, P=pulse (Used by this overlay) CLOCK: DB 50 ;clock speed x .1, up to 25.5 mhz. MSPEED: DB 5 ;sets display time for sending a file ;0=110 1=300 2=450 3=600 4=710 ;5=1200 6=2400 7=4800 8=9600 9=19200 BYTDLY: DB 5 ;default time to send character in ;terminal mode file transfer (0-9) ;0=0 delay, 1=10 ms, 5=50 ms, 9=90 ms CRDLY: DB 5 ;end-of-line delay after CRLF in terminal ;mode file transfer for slow BBS systems ;0=0 delay, 1=100 ms, 5=500 ms, 9=900 ms COLUMS: DB 5 ;number of directory columns SETFL: DB YES ;yes=user-defined SET command SCRTST: DB YES ;yes=if home cursor and clear screen ;routine at CLRSCRN DB 0 ;was once ACKNAK, now spare BAKFLG: DB YES ;yes=make .BAK file CRCDFL: DB YES ;yes=default to CRC checking ;no=default to Checksum checking TOGCRC: DB YES ;yes=allow toggling of Checksum to CRC CVTBS: DB NO ;yes=convert backspace to rub TOGLBK: DB YES ;yes=allow toggling of bksp to rub ADDLF: DB NO ;no=no LF after CR to send file in ;terminal mode (added by remote echo) TOGLF: DB YES ;yes=allow toggling of LF after CR TRNLOG: DB NO ;yes=allow transmission of logon ;write logon sequence at location LOGON SAVCCP: DB YES ;yes=do not overwrite CCP LOCNXT: DB NO ;yes=local cmd if EXTCHR precedes ;no=not local cmd if EXTCHR precedes TOGLOC: DB YES ;yes=allow toggling of LOCNXTCHR LSTTST: DB YES ;yes=allow toggling of printer on/off ;in terminal mode. Set to no if using ;the printer port for the modem XOFTST: DB NO ;yes=allow testing of XOFF from remote ;while sending a file in terminal mode XONWT: DB NO ;yes=wait for XON after sending CR while ;transmitting a file in terminal mode TOGXOF: DB YES ;yes=allow toggling of XOFF testing IGNCTL: DB NO ;yes=do not send control characters ;above CTL-M to CRT in terminal mode ;no=send any incoming CTL-char to CRT EXTRA1: DB 0 ;for future expansion EXTRA2: DB 0 ;for future expansion BRKCHR: DB '@'-40H ;^B = Send a 300 ms. break tone NOCONN: DB 'N'-40H ;^N = Disconnect from phone line LOGCHR: DB 'L'-40H ;^L = Send logon LSTCHR: DB 'P'-40H ;^P = Toggle printer UNSVCH: DB 'R'-40H ;^R = Close input text buffer TRNCHR: DB 'T'-40H ;^T = Transmit file to remote SAVCHR: DB 'Y'-40H ;^Y = Open input text buffer EXTCHR: DB '^'-40H ;^^ = Send next character ; DS 2 ;not used ; ; Low-level modem I/O routines. ; INCTL1: JMP INCTL ;in modem control port DB 0,0,0,0,0,0,0 ;spares if needed for non-PMMI ; OTDATA: JMP OUTDAT ;out modem data port DB 0,0,0,0,0,0,0 ;spares if needed for non=PMMI ; INDATA: JMP INDAT ;in modem data port DB 0,0,0,0,0,0,0 ;spares if needed for non-PMMI ; ; Bit-test routines. ; MASKR: ANI MDRCVB ! RET ;bit to test for receive ready TESTR: CPI MDRCVR ! RET ;value of receive bit when ready MASKS: ANI MDSNDB ! RET ;bit to test for send ready TESTS: CPI MDSNDR ! RET ;value of send bit when ready ; DS 3 DCDV: JMP CHKDCD RNGV: JMP CHKRNG DS 3 ; LOGON: DS 2 ;needed for MDM compat, not ref'd by MEX DIALV: JMP DIAL DISCV: JMP DISCON GOODBV: JMP GOODBYE ;called before exit to CP/M INMODV: JMP NITMOD ;initialization. Called at cold-start NEWBDV: JMP PBAUD ;set baud rate NOPARV: RET!NOP!NOP ;set modem for no-parity PARITV: RET!NOP!NOP ;set modem parity SETUPV: JMP SETCMD ;SET cmd: jump to a RET if you don't write SET SPMENV: RET!NOP!NOP ;not used with MEX VERSNV: JMP SYSVER ;Overlay's voice in the sign-on message BREAKV: JMP SBREAK ;send a break ; ; MDM calls supported in MEX 1.0 but not recommended for use. ; ILPRTV: DS 3 ;replace with MEX function 9 INBUFV: DS 3 ;replace with MEX function 10 ILCMPV: DS 3 ;replace with table lookup funct. 247 INMDMV: DS 3 ;replace with MEX function 255 NXSCRV: DS 3 ;not supported by MEX (returns w/no action) TIMERV: DS 3 ;replace with MEX function 254 ; CLREOS: LXI D,EOSMSG MVI C,PRINT CALL MEX RET ; CLS: LXI D,CLSMSG MVI C,PRINT CALL MEX RET ;------------------------------------------------------------ ; ; end of fixed area ; ;------------------------------------------------------------ ; ORG 0200H ; ; read data reg ; INDAT: IN COMDAT RET ; ; write data reg ; OUTDAT: OUT COMDAT RET ; ; read control reg ; INCTL: IN COMCTL RET ; ; write control reg ; OUTCTL: OUT COMCTL RET ; ; write baud rate counter ; OUTBD: OUT CMBAUD RET ; ; MEX+ enhancements - Check for DCD A=0FFh if present, else 0 ; CHKDCD: PUSH H PUSH D PUSH B CALL INCTL ANI MDSDCD JZ DCDRET MVI A,0FFH DCDRET: POP B POP D POP H RET ; ; MEX+ enhancements - CHeck for Ring detect - (not used) ; CHKRNG: XRA A ;a=0 RET ; Print out the overlay version ; SYSVER: CALL MILP DB CR,LF DB 'Vector 4 Overlay - Version ' DB REV/10+'0' DB '.' DB REV MOD 10+'0' ; IF ANCHOR DB 'A' ;APPEND 'A' SUFFIX TO IDENTIFY OVERLAY ;VERSION AS CONFIGURED FOR ANCHOR MODEM ENDIF ; DB CR,LF DB 0 RET ; ; Break, disconnect and goodbye routines ; SBREAK: LDA CMD PUSH PSW ORI 008H ;SET BREAK CALL OUTCTL MVI B,3 ;DELAY 300 MS. CALL MTIME POP PSW CALL OUTCTL RET ; ; Disconnect Routine ; DISCON: IF ANCHOR ;Anchor does not respond to DTR ;so the only way to disconnect is through ;standard Smartmodem disconnect commands MVI B,20 MVI C,TIMER ;wait 2 seconds CALL MEX LXI H,SMATN ;send '+++' CALL SMSEND MVI B,40 ;wait 4 more seconds (Anchor is slow) MVI C,TIMER CALL MEX LXI H,SMDISC ;send 'ATH' CALL SMSEND MVI B,10 ;wait 1 second MVI C,TIMER CALL MEX RET ENDIF ; IF NOT ANCHOR LDA CMD PUSH PSW ANI 0DDH CALL OUTCTL ;SEND TO THE STATUS PORT MVI B,10 ;WAIT ONE SECOND MVI C,TIMER CALL MEX POP PSW CALL OUTCTL RET ENDIF ; ; GOODBYE routines are called by MEX prior to exit to CP/M ; GOODBYE: MVI B,3 ;DELAY 300 MS. CALL MTIME RET ; ; Initialize RS-232 port and default modes. ; NITMOD: CALL CHKDCD ;SEE IF MODEM IS CONNECTED, I.E., RETURNING CPI 0 ;TO ACTIVE MODEM FROM CPM RNZ ;SKIP IF CONNECTED ; ; Initialize Internal RS-232 and PIO port ; NITMOD2: CALL NITSIO LDA MONFLG ;GET MONITOR DEFAULT ORA A MVI A,'0' ;SPEAKER OFF JZ NITMOD4 MVI A,'1' ;SPEAKER ON NITMOD4: STA SMINIT+3 ;PUT IT IN SMINIT STRING LDA ANSFLG ;GET MODE DEFAULT ORA A MVI A,'0' ;ORIGINATE JZ NITMOD5 MVI A,'1' ;ANSWER NITMOD5: STA SMINIT+8 ;PUT IT IN SMINIT STRING LXI H,SMINIT SINIT: CALL SMSEND ;SEND THE INIT STRING SMTLP1: MVI C,INMDM ;WAIT FOR MODEM RESPONSE CALL MEX JNC SMTLP1 ;EAT EVERYTHING UNTIL SILENCE FOR RET ; 100 MSEC ; ; Initialize the 8251 chip ; NITSIO: LXI H,INITSQ ;POINT TO SEQUENCE MVI B,INITSE ;NUMBER OF BYTES IN SEQUENCE INIT1: MOV A,M ;GET A BYTE CALL OUTCTL ;SEND CHAR TO STATUS PORT XTHL ;DELAY IN CASE OF 6 MHZ. XTHL INX H ;POINT TO NEXT DCR B JNZ INIT1 ;SEND ENTIRE SEQUENCE INIT2: MVI C,0FFH ; = 0FFH IF INTERRUPTS ENABLED LXI H,0 ;PUSH KNOWN VALUE ONTO STACK PUSH H POP H ; LDAI ;CHECK Z-80 INTERRUPT STATUS DB 0EDH,057H JP INIT3 ;JUMP IF INTERRUPTS ARE ENABLED DCX SP ;NOW VERIFY THAT INTERRUPTS ARE DCX SP ;REALLY DISABLED BY CHECKING POP H ;KNOWN VALUE ON STACK TO SEE MOV A,H ;IF INTERRUPT SERVICE ROUTINE ORA A ;WAS CALLED. JNZ INIT3 ;JUMP IF INTERRUPTS ARE REALLY ENABLED MVI C,0 ; = 000H IF INTERRUPTS ARE DISABLED INIT3: DI ;PROTECT BAUDRATE SET SEQUENCE LXI H,BAUDRATE ;SET SELECTED BAUDRATE MOV A,M CALL OUTBD INX H MOV A,M CALL OUTBD MOV A,C ;CHECK INTERRUPT STATUS ORA A JZ INITEXIT ;LEAVE INTERRUPTS DISABLED EI ;ELSE RE-ENABLE INTERRUPTS INITEXIT: RET * INITSQ: DB 000H,000H,000H RESET: DB 040H ;SET FOR CONTROL SEQUENCE CNTL: DB 04EH ;DEFAULT CNTL 1 STP, NO PAR, 8 BIT, 16X CMD: DB 027H ;RTS, RCV EN, TX EN, DTR * INITSE EQU $-INITSQ * ; ; Set command processor ; SETCMD: MVI C,SBLANK ;ANY ARGUMENTS? CALL MEX JC SETSHO ;IF NOT, DISPLAY DEFAULT(S) LXI D,CMDTBL MVI C,LOOKUP CALL MEX ;PARSE THE ARGUMENT PUSH H ;SAVE ANY PARSED ARGUMENTS ON STACK RNC ;IF WE HAVE ONE, RETURN TO IT POP H ;OOPS, INPUT NOT FOUND IN TABLE SETERR: LXI D,SETEMS MVI C,PRINT CALL MEX CALL CRLF RET SETEMS: DB CR,LF,'SET command error',CR,LF,'$' ; SETBAD: LXI D,SETBMS MVI C,PRINT CALL MEX RET SETBMS: DB CR,LF,'SET command not valid for modem',CR,LF,'$' ; ; Argument table ; CMDTBL: DB '?'+80H ; HELP DW SETHELP DB 'ORI','G'+80H ; ORIGINATE MODE DW ORIG DB 'POR','T'+80H ; ORIGINATE MODE DW STPORT DB 'ANSWE','R'+80H ; ANSWER MODE DW ANS DB 'TON','E'+80H ; TONE DIALING DW STTONE DB 'PULS','E'+80H ; PULSE DIALING DW STPULSE DB 'MONITO','R'+80H ; MONITOR ON DW MONIT DB 'QUIE','T'+80H ; MONITOR OFF DW QUIET DB 'BAU','D'+80H ; SET BAUD DW STBAUD DB 'DELA','Y'+80H ; SET DELAY DW DELAY DB 'PARIT','Y'+80H ; SET PARITY DW STPRTY DB 'STOPBIT','S'+80H ; SET STOPBITS DW STSTOP DB 'LENGT','H'+80H ; SET LENGTH DW STBITS DB 'MANUAL','O'+80H ; SET MANUAL ORIGINATE DW MANUALO DB 'MANUAL','A'+80H ; SET MANUAL ANSWER DW MANUALA DB 0 ;TABLE TERMINATOR ; ; ; "SET (no args): PRINT CURRENT STATISTICS ; SETSHO: CALL MILP DB CR,LF DB 'SET values:',CR,LF,0 CALL CRLF CALL MDSHOW CALL CRLF CALL TPSHOW CALL CRLF CALL PTSHOW CALL CRLF CALL BDSHOW CALL CRLF CALL DLSHOW CALL CRLF CALL MONSHO CALL CRLF CALL CRLF CALL SHPRTY CALL CRLF CALL SHSTOP CALL CRLF CALL SHBITS CALL CRLF CALL CRLF RET ; ; "SET ?" processor ; SETHELP: CALL MILP DB CR,LF,'SET PORT - C or P' DB CR,LF,'SET ORIG' DB CR,LF,'SET ANSWER' DB CR,LF,'SET TONE' DB CR,LF,'SET PULSE' DB CR,LF,'SET DELAY - seconds' DB CR,LF,'SET PARITY - OFF, EVEN or ODD' DB CR,LF,'SET STOPBITS - 1, 1.5 or 2' DB CR,LF,'SET LENGTH - 5, 6, 7 or 8' DB CR,LF,'SET QUIET - Speaker OFF' DB CR,LF,'SET MONITOR - Speaker ON' DB CR,LF,'SET BAUD - 110, 300, 600, 1200' DB CR,LF,' 2400, 4800, 9600' DB CR,LF,'SET MANUALO - Manual Originate mode' DB CR,LF,'SET MANUALA - Manual Answer mode' DB CR,LF,CR,LF,0 RET ; ; "SET BAUD" processor ; STBAUD: MVI C,BDPARS ;FUNCTION CODE: PARSE A BAUDRATE CALL MEX ;LET MEX LOOK UP CODE JC SETERR ;JUMP IF INVALID CODE CALL PBAUD ;NO, TRY TO SET IT JC SETERR ;IF NOT ONE OF OURS, BOMB OUT BDSHOW: LDA MSPEED ;GET CURRENT BAUD RATE MVI C,PRBAUD ;LET MEX PRINT IT CALL MEX RET ; ; This routine sets baud rate passed as MSPEED code in A. ; Returns CY=1 if baud rate not supported. ; PBAUD: PUSH H ;DON'T ALTER ANYBODY PUSH D PUSH B PUSH A ;SAVE MSPEED ADD A ;DOUBLE INDEX INTO BAUD RATE TBL MOV E,A ;MSPEED CODE TO DE MVI D,0 LXI H,BAUDTB ;OFFSET INTO TABLE DAD D MOV A,M ;FETCH CODE ORA A ;0 MEANS UNSUPPORTED CODE STC ;PREP CARRY IN CASE UNSUPPORTED JZ PBEXIT ;EXIT IF BAD STA BAUDRATE ;SAVE IN BAUDRATE LO INX H MOV A,M ;NOW UPPER BYTE STA BAUDRATE+1 CALL INIT2 POP A ;GET MSPEED CODE BACK STA MSPEED ;SET IT ORA A ;RETURN NO ERRORS PBEXIT: POP B POP D POP H RET ; * DELAY CONSTANTS FOR BAUD RATE GENERATION * BAUDTB: DW 0470H ;110 DW 001A1H ;300 DW 0 ;450 (not supported) DW 00D0H ;600 DW 0 ;710 (not supported) DW 0068H ;1200 DW 0034H ;2400 DW 001AH ;4800 DW 000DH ;9600 DW 0 ;19200(not supported) BAUDRATE: DW 0068H ;DEFAULT ; ; SET MODE PROCESSOR ---- SET MODEM SELECTION TO INTERNAL OR EXTERNAL ; ORIG: XRA A STA ANSFLG ;SET ORIG FLAG LXI H,SMO ;SEND OUT ATS0=0 CALL SINIT JMP MDSHOW ; SMO: DB 'ATS0=0',CR,0 SMA: DB 'ATS0=1',CR,0 ; ANS: MVI A,0FFH STA ANSFLG ;SET ANS FLAG LXI H,SMA ;SEND OUT ATS0=1 CALL SINIT CALL MDSHOW RET ; MDSHOW: LDA ANSFLG ORA A JZ MDORIG CALL MILP DB 'Auto-answer mode',0 RET MDORIG: CALL MILP DB 'Originate mode: auto-answer disabled',0 RET ; ; Port control processor ; STPORT: MVI C,SBLANK ;check for stop bits CALL MEX ; JC SETERR ;if none, print error LXI D,PRTTBL ;check for proper syntax MVI C,LOOKUP CALL MEX ; PUSH H ;match found, go do it! RNC ; POP H ;no match: fix stack and JMP SETERR ; print error ; PRTC: MVI A,COMDAT STA INDAT+1 STA OUTDAT+1 MVI A,COMCTL STA INCTL+1 STA OUTCTL+1 MVI A,CMBAUD STA OUTBD+1 XRA A STA PTFLG CALL PTSHOW JMP NITSIO ; PRTP: MVI A,PRTDAT STA INDAT+1 STA OUTDAT+1 MVI A,PRTCTL STA INCTL+1 STA OUTCTL+1 MVI A,PTBAUD STA OUTBD+1 MVI A,0FFH STA PTFLG CALL PTSHOW JMP NITSIO ; PTSHOW: LDA PTFLG ORA A JZ PTSHOW1 CALL MILP DB 'Printer port selected',0 RET PTSHOW1: CALL MILP DB 'Communications port selected',0 RET PTFLG: DB 0 ; ; SET PORT command table ; PRTTBL: DB 'C'+80H ;"set stop 1" DW PRTC DB 'P'+80H ;"set stop 2" DW PRTP DB 0 ;<<== End of stop-bits table ; ; Monitor control processor ; QUIET: XRA A STA MONFLG LXI H,SMQT CALL SINIT JMP MONSHO MONIT: MVI A,0FFH STA MONFLG LXI H,SMMON CALL SINIT MONSHO: LDA MONFLG ORA A JZ MONOFF CALL MILP DB 'Speaker On',0 RET MONOFF: CALL MILP DB 'Speaker Off',0 RET SMQT: DB 'ATM0',CR,0 SMMON: DB 'ATM1',CR,0 ; ; Set dial processor ; STTONE: MVI B,'T' JMP SDIAL1 STPULSE: MVI B,'P' SDIAL1: LDA TPULSE CPI B JZ TPSHOW MOV A,B STA TPULSE CPI 'P' MVI A,01010000B ;PULSE DIAL JZ SDIAL2 MVI A,01000000B ;TONE DIAL SDIAL2: STA DIALWD TPSHOW: LDA DIALWD ANI 00010000B JZ TPTONE CALL MILP DB 'Pulse Dial',0 RET TPTONE: CALL MILP DB 'Tone Dial',0 RET ; ; Set manual processor ; MANUALO: MVI A,00H STA ANSFLG LXI H,SMMANO CALL SMSEND JMP OFF MANUALA: MVI A,0FFH STA ANSFLG LXI H,SMMANA CALL SMSEND OFF: MVI B,10 ;WAIT 1 SEC CALL MTIME RET ; ; Set delay processor ; DELAY: MVI C,EVALA CALL MEX MOV A,H ORA A JNZ SETERR MOV A,L STA NDELAY DLSHOW: CALL MILP DB 'Answer Delay is ',0 LDA NDELAY MOV L,A MVI H,0 MVI C,DECOUT CALL MEX CALL MILP DB ' seconds',0 RET ; ; SET PARITY command: reset transmit/receive parity ; ; Parity is controlled by bits 4 and 5 of ; the byte sent to the 8251 CNTL register ; as follows: ; ; Parity Bit 5 Bit 4 ; Off - 0 ; Odd 0 1 ; Even 1 1 ; STPRTY: MVI C,SBLANK ;check for parity code CALL MEX ; JC SETERR ;if none, print error LXI D,PARTBL ;check for proper syntax MVI C,LOOKUP CALL MEX PUSH H ;match found, go do it! RNC ; POP H ;no match: fix stack and JMP SETERR ; print error ; PROFF: LDA CNTL ;get register 4 byte ANI 0CFH ;reset bit 4,5 JMP PARTB1 ; PREVEN: LDA CNTL ; ORI 030H ;set bits 4 & 5 JMP PARTB1 ; PRODD: LDA CNTL ; ORI 010H ;set bit 4 ANI 0DFH ;reset bit 5 PARTB1: STA CNTL ; CALL NITSIO ;re-initialize the USART CALL SHPRTY ;print the result RET ; SHPRTY: CALL MILP ;display parity DB 'Parity: ',TAB,' ',0 LDA CNTL ; ANI 010H ;test bit 4 CPI 0 ;if bit4=0 then parity off JNZ SHPRT1 ; CALL MILP ; DB 'Off',0 ; RET SHPRT1: LDA CNTL ; ANI 020H ;test bit 5 CPI 0 ;if bit5=0 then parity odd JNZ SHPRT2 ; CALL MILP ; DB 'Odd',0 ; RET ; SHPRT2: CALL MILP ; DB 'Even',0 ; RET ; ; SET PARITY command table ; PARTBL: DB 'OF','F'+80H ;"set parity off" DW PROFF DB 'EVE','N'+80H ;"set parity even" DW PREVEN DB 'OD','D'+80H ;"set parity odd" DW PRODD DB 0 ;<<== end of parity table ; ; SET STOPBITS command: reset number of stop bits ; ; The number of stop bits is controlled by bits ; 6 and 7 of the byte sent to the 8251 CONTROL ; register, as follows: ; ; Stop bits Bit 7 Bit 6 ; 1 0 1 ; 1.5 1 0 ; 2 1 1 ; ; STSTOP: MVI C,SBLANK ;check for stop bits CALL MEX ; JC SETERR ;if none, print error LXI D,STPTBL ;check for proper syntax MVI C,LOOKUP CALL MEX ; PUSH H ;match found, go do it! RNC ; POP H ;no match: fix stack and JMP SETERR ; print error ; STOP01: LDA CNTL ;get CNTL byte ANI 07FH ;reset bit 7 ORI 040H ;set bit 6 JMP STSTP1 ; STOP02: LDA CNTL ; ORI 0C0H ;set bits 6 and 7 JMP STSTP1 ; STOP15: LDA CNTL ; ORI 080H ;set bit 7 ANI 0BFH ;reset bit 6 STSTP1: STA CNTL ; CALL NITSIO ; CALL SHSTOP ;print the result RET SHSTOP: CALL MILP ;display stop-bits DB 'Stop bits:',TAB,' ',0 LDA CNTL ; ANI 040H ;test bit 6 CPI 0 ;if bit6=0 then 1.5 JNZ SHSTP1 ; CALL MILP ; DB '1.5',0 ; RET SHSTP1: LDA CNTL ; ANI 080H ;test bit 7 CPI 0 ;if bit7=0 then 1 JNZ SHSTP2 ; CALL MILP ; DB '1',0 ; RET SHSTP2: CALL MILP ; DB '2',0 ; RET ; ; SET STOPBITS command table ; STPTBL: DB '1'+80H ;"set stop 1" DW STOP01 DB '2'+80H ;"set stop 2" DW STOP02 DB '1.','5'+80H ;"set stop 1.5" DW STOP15 DB 0 ;<<== End of stop-bits table ; ; SET LENGTH command: set bits per character ; ; The number of bits per character is controlled ; by bits 2 and 3 of the control byte ; ; BPC Bit 3 Bit 2 ; 5 0 0 ; 6 0 1 ; 7 1 0 ; 8 1 1 ; STBITS: MVI C,SBLANK ;check for bits/char CALL MEX ; JC SETERR ;if none, print error LXI D,BITTBL ;check for proper syntax MVI C,LOOKUP CALL MEX PUSH H ;match found, go do it! RNC ; POP H ;no match: fix stack and JMP SETERR ; print error ; BIT5: LDA CNTL ; ANI 0F3H ;reset bit 2,3 JMP STBTS1 ; BIT6: LDA CNTL ; ANI 0F7H ;reset bit 3 ORI 004H ;set bit 2 JMP STBTS1 ; BIT7: LDA CNTL ; ORI 008H ;set bit 3 ANI 0FBH ;reset bit 2 JMP STBTS1 ; BIT8: LDA CNTL ; ORI 00CH ;set bit 2,3 STBTS1: STA CNTL ; CALL NITSIO ; CALL SHBITS ;print the result RET SHBITS: CALL MILP ;display bits/char DB 'Bits/char:',TAB,' ',0 LDA CNTL ; ANI 008H ;test bit 3 CPI 0 ;if bit3=0 then 6 or 5 bpc JNZ SHBTS2 ; LDA CNTL ; ANI 004H ;test bit 2 CPI 0 ;if bit2=0 then 5 bpc JNZ SHBTS1 ; CALL MILP ; DB '5',0 ; RET ; SHBTS1: CALL MILP ; DB '6',0 ; RET ; SHBTS2: LDA CNTL ; ANI 004H ;test bit 2 CPI 0 ;if bit2=0 then 7 bpc JNZ SHBTS3 ; CALL MILP ; DB '7',0 ; RET ; SHBTS3: CALL MILP ; DB '8',0 ; RET ; ; SET LENGTH command table ; BITTBL: DB '5'+80H ;"set bits 5" DW BIT5 DB '6'+80H ;"set bits 6" DW BIT6 DB '7'+80H ;"set bits 7" DW BIT7 DB '8'+80H ;"set bits 8" DW BIT8 DB 0 ;<<== end of bpc table ; ; ; Dialing routine ; Smartmodem dialing routine from Ron Fowler's MXO-SM13.ASM ; DIAL: LHLD DIALPT ;FETCH POINTER CPI 254 ;START DIAL? JZ STDIAL1 ;JUMP IF SO CPI 255 ;END DIAL? JZ ENDIAL1 ;JUMP IF SO ; ; Not start or end sequence, must be a digit to be sent to the modem ; MOV M,A ;PUT CHAR IN BUFFER INX H ;ADVANCE POINTER SHLD DIALPT ;STUFF PNTR RET ;ALL DONE ; ; Here on a start-dial sequence ; STDIAL1: LXI H,DIALBF ;SET UP BUFFER POINTER SHLD DIALPT RET ; ; Here on an end-dial sequence ; ENDIAL1: MVI M,CR ;STUFF END-OF-LINE INTO BUFFER INX H ;FOLLOWED BY TERMINATOR MVI M,0 LDA TPULSE ;GET OVERLAY'S TOUCH-TONE FLAG STA SMDIAL+3 ;PUT INTO STRING LXI H,SMDIAL ;POINT TO DIALING STRING CALL SMSEND ;SEND IT WAITSM: MVI C,INMDM CALL MEX ;CATCH ANY OUTPUT FROM THE MODEM JNC WAITSM ;LOOP UNTIL NO MORE CHARACTERS ; ; THE FOLLOWING LOOP WAITS FOR A RESULT FROM THE MODEM. ; RESULT: LDA NDELAY ;GET DELAY COUNT MOV C,A SMWLP: PUSH B MVI B,1 ;CHECK FOR A CHAR, UP TO 1 SEC WAIT MVI C,TMDINP ;DO TIMED INPUT CALL MEX POP B JNC SMTEST ;JUMP IF MODEM HAD A CHAR ; IF DCD ;if DCD is available, take a look at it CALL CHKDCD ; get the status byte INR A ; and test the DCD flag RZ ; return with A=0 if found, ;but otherwise ... ENDIF ;DCD ; CKKCC: PUSH B ;NO, TEST FOR CONTROL-C FROM CONSOLE MVI C,DCONIO ;USE DIRECT CONSOLE I/O MVI E,DCONIN ;ASK FOR INPUT CALL BDOS ;FROM BDOS POP B CPI 'C'-40H ;^C JNZ SMNEXT ;IF NOT, JUMP CALL SMDMOFF ;YES, SHUT DOWN THE MODEM MVI A,3 ;RETURN ABORT CODE RET SMNEXT: CPI 0 ;ANY OTHER KEY? JNZ SMTIMO ;YES, TREAT LIKE NO ANSWER DCR C ;NO JNZ SMWLP ;CONTINUE ; ; NO MODEM RESPONSE WITHIN THE TIME SPECIFIED IN SET DELAY COMMAND ; SMTIMO: CALL SMDMOFF MVI A,2 ;RETURN TIMEOUT CODE RET ; ; MODEM GAVE US A RESULT, CHECK IT ; SMTEST: ANI 7FH ;IGNORE ANY PARITY CALL SMANAL ;TEST THE RESULT JC RESULT ;GO TRY AGAIN IF UNKNOWN RESPONSE MOV A,B ;A=RESULT PUSH PSW ;SAVE IT SMTLP: MVI C,INMDM ;EAT ANY ADDITIONAL CHARS FROM SMARTMODEM CALL MEX JNC SMTLP ;UNTIL 100MS OF QUIET TIME POP PSW ;RETURN THE CODE RET ; ; Analyze character returned from External Modem ; SMANAL: IF ANCHOR ;Anchor echoes the digits as they are ;being dialed. The returned digits are ;interpreted as call return codes, shutting ;down the modem prematurely ; MVI B,0 ;PREP CONNECT CODE CPI 'C' ;"CONNECT"? RZ INR B ;PREP BUSY CODE B=1 CPI 'B' RZ INR B ;PREP NO CONNECT MSG B=2 CPI 'N' ;N=NO CONNECT RZ MVI B,4 ;PREP MODEM ERROR CPI 'E' ;E=ERROR RZ ENDIF ; IF NOT ANCHOR MVI B,0 ;PREP CONNECT CODE CPI 'C' ;"CONNECT"? RZ CPI '1' ;NUMERIC VERSION OF "CONNECT" RZ CPI '5' ;NUMERIC VERSION OF "CONNECT 1200" RZ INR B ;PREP BUSY CODE B=1 CPI 'B' RZ INR B ;PREP NO CONNECT MSG B=2 CPI 'N' ;N=NO CONNECT RZ CPI '3' ;NUMERIC VERSION OF "NO CONNECT" RZ MVI B,4 ;PREP MODEM ERROR CPI 'E' ;E=ERROR RZ CPI '4' ;NUMERIC VERSION OF "ERROR" RZ ENDIF ; ; UNKNOWN RESPONSE, RETURN CARRY TO CALLER. BUT FIRST, ; FLUSH THE UNKNOWN RESPONSE LINE FROM THE MODEM. ; WTLF: CPI LF ;LINEFEED? STC RZ ;END IF SO MVI C,INMDM ;NO. GET NEXT CHAR CALL MEX JNC WTLF ;UNLESS BUSY, LOOP RET ; ; Send string to the External Modem ; SMSEND: MVI C,SNDRDY ;WAIT FOR MODEM READY CALL MEX JNZ SMSEND MOV A,M ;FETCH NEXT CHARACTER INX H ORA A ;END? RZ ;DONE IF SO MOV B,A ;NO, POSITION FOR SENDING MVI C,SNDCHR ;NOPE, SEND THE CHARACTER CALL MEX JMP SMSEND ; ; Shut down (disconnect) External Modem ; SMDMOFF: ; IF ANCHOR MVI B,ANDAB ENDIF ; IF NOT ANCHOR MVI B,CR ENDIF ; MVI C,SNDCHR CALL MEX ; IF ANCHOR MVI B,20 ;TWO SECOND WAIT FOR ANCHOR CALL MTIME RET ENDIF ; IF NOT ANCHOR MVI B,10 ;ONE SECOND WAIT FOR HAYES, ETC CALL MTIME JMP DISCON ;MAKE SURE IT IS OFF ENDIF ; ; General utility routines ; MILP: MVI C,ILP ;IN-LINE PRINT JMP MEX RET ; MTIME: MVI C,TIMER ;MEX TIMER JMP MEX RET ; CRLF: CALL MILP ;PRINT CARRIAGE RETURN, LINE FEED DB CR,LF,0 RET ; ;========================================================================== ; Data Area ;========================================================================== ; ; Default UART parameters (Initalized for External RS-232) ; ; Miscellaneous Default Data ; SMDIAL: DB 'ATDP ' ;Smartmodem dial prefix DIALBF: DS 52 ;2* 24 CHAR MAX, + CR + NULL + SLOP DIALPT: DS 2 ;DIAL POSITION POINTER DIALWD: DB 01000000B ;PULSE/TONE DIAL WORD DIGIT DB 0 ;SAVE DIALED DIGIT MSPDSV: DB 0 ;SAVE MODEM MSPEED MONFLG: DB 0FFH ;0: MONITOR OFF - 0FFH: MONITOR ON ANSFLG: DB 0 ;0: ORIGINATE - 0FFH: ANS NDELAY: DB 30 ;NO. SECONDS FOR ANSWER ; SMATN: DB '+++',0 ;Smartmodem online 'attention' SMDISC: DB 'ATH',CR,0 ;Smartmodem disconnect (used by Anchor) SMINIT: DB 'ATM1 S0=0 S7=60 X1',CR,0 ;MODEM INIT STRING SMMANO: DB 'ATC0',CR,0 SMMANA: DB 'ATC1',CR,0 ; EOSMSG: DB 010H,'$' ;CLEAR TO END-OF-SCREEN CLSMSG: DB 04H,'$' ;CLEAR WHOLE SCREEN END