; MXM-UD10.ASM - MEX1.10 Smart modem overlay for UDS 212 A/D modem ; ; TO USE: Edit the UDSNEW parameter for your particular modem. ; Assemble with ASM.COM or equivalent assembler. Then ; use MLOAD21.COM (or later) to combine this overlay ; with the original MEXxx.COM file, and your computer ; specific overlay file.( MXO-xxxx in the example below). ; ; A>MLOAD21 MEX.COM=MEXxx.COM,MXM-UD10,MXO-xxxx ; ; >>>> Report bugs to fortfone rcp/m 414-563-9932 <<<<<<<<<<<< ; ; = = = = = = = = = = = = = = = = = = ; YES EQU 0FFH NO EQU 000H ; ; UDSNEW - If yes, this is a revised UDS 212 A/D. The new ; models can be disconnected by sending the string 'XXXT' followed ; by carriage return. Older models can only be disconnected by ; dropping DTR low for at least 60 msec. Define UDSNEW to be yes ; if you want to use the 'XXXT' disconnect string, Define UDSNEW ; to be NO to use the DTR disconnect method. (The computer overlay ; must intercept the DISCV vector, drop DTR, then JMP to the original ; DISCV vector address.) ; UDSNEW EQU YES ; ; ; *NOTE* As an owner of a UDS 212-A/D modem you are probably aware ; of the consequences regarding training the modem at one baud rate ; and then changing baud rates without untraining the modem first. ; The poor thing will go crazy. Using this overlay *requires* the ; user to always disconnect a call before changing baud rates. ; The Ctl-J + N command will disconnect the modem and then untrain ; the ACU. Do *NOT* make a completed call, exit terminal mode ; with Ctl-J + E, and then try to change baud rates. (Incomplete or ; aborted calls don't count, the modem is automatically untrained ; if the call isn't completed.) If you're in doubt, enter terminal ; mode and give the disconnect command, Ctl-J + N, this will insure ; the modem is disconnected and 'untrained'. ; ;--------------- ; ; Misc equates ; BDOS EQU 005H CR: EQU 0DH ;carriage return LF: EQU 0AH ;linefeed ; ;--------------- ; ; MEX service processor equates ; MEX EQU 0D00H ; MEX SERVICE PROCESSOR ENTRY POINT 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 chara (B) 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 PRNTBL EQU 237 ;print command table in columnar format PRID EQU 236 ;print MEX ID on console ; CONOUT EQU 2 ; simulated BDOS functions, for MEX PRINT EQU 9 INBUF EQU 10 ; ;--------------- ; ; PDIAL completion codes to be returned to MEX ; PCARR EQU 0 ; CARRIER DETECT, CONNECTION MADE PBSY EQU 1 ; PHONE IS BUSY PNOANS EQU 2 ; NO ANSWER PABRT EQU 3 ; KEYBD ABORT PERR EQU 4 ; MODEM ERROR PNRING EQU 5 ; NO RING PNDIAL EQU 6 ; NO DIAL TONE ; ;---------------- ; ; MEX Baud rate codes ; BD110 EQU 0 BD300 EQU 1 BD450 EQU 2 BD600 EQU 3 BD710 EQU 4 BD1200 EQU 5 BD2400 EQU 6 BD4800 EQU 7 BD9600 EQU 8 BD1920 EQU 9 ; ;----------------- ; ; Entry points in the computer overlay area ; ORG 0162H ; MEX main overlay JMP PDIAL ;jump to modem dialing routine 162H JMP MDMDSC ;jump to modem disconnect routine 165H MSPEED: EQU 0107H ;MEX speed code byte SET8BT: EQU 0171H ;Set serial port for 8-bit data, no parity SETNRM: EQU 0174H ;Set serial port for normal operation. ; ;---------------- ; ; New MEX 1.10 Smartmodem overlay patch points. ; ORG 0D55H ; Fixed at address 0D55H DW DUMMY ; SMINIT - not used. DW SSET ; SSET command processor DW DUMMY ; SMEXIT - not used. ; ;--------------- ; ; Smartmodem code begins at 0900H ; ORG 0900H ; ;--------------- ; ; PDIAL - Actual dial service routine. ; ; Entry point to dialing routine. This routine saves all the digits in ; a buffer, dialing the number only after all digits/commands have been ; received. It then monitors the ACU call progress responses and returns ; the proper success/failure codes to MEX. ; ; This routine is called by MEX with a dialing digit (ASCII) in the ; A register. The routine can use all registers. The routine is called ; with the special value 254 (decimal) to indicate the beginning of a ; dialing sequence. The special value 255 indicates the end of the ; dialing sequence, and requires the PDIAL routine to return one of the ; MEX dialing completion codes in the A register. ; PDIAL: CPI 254 JZ STDIAL ; start of dialing sequence, reset pointers ; CPI 255 JNZ DDIGIT ; store digit, will dial the whole number later ; ; all digits recieved, time to dial the number. ; XRA A ; Null terminate the phone number CALL DDIGIT ; ; check for 300/1200 baud rate. Modem ACU will not work at other rates. ; LDA MSPEED CPI BD300 JZ PDIAL0 CPI BD1200 JZ PDIAL0 ; CALL ILPRT DB CR,LF,'Baud rate must be 300/1200 for Auto Dial - ',0 JMP DLERR ; return the modem error code ; ; Return error code if an invalid dialing character was received. ; PDIAL0: LDA ERRFLG ORA A JZ PDIAL1 ; CALL ILPRT DB CR,LF,'Invalid Digit/Chara in dial string - ',0 JMP DLERR ; return the modem error code ; PDIAL1: CALL FLUSH ; Flush the modem input CALL SET8BT ; Set the serial port for 8-bit operation. CALL FLUSH ; Flush input again. ; ; First step is to train the modem to the current baud rate. ; CALL MDMTRN ; Send the modem training command 'EN' JC DLERR ; Exit upon training error. ; LXI H,DOPTS ; Send the options commands CALL SNDSTR CALL FLUSH ; Ignore modem responses ; ; Now dial the number ; MVI A,'D' ; Dialing command = 'D' CALL SEND1 LXI H,DPREFX ; Send the dialing prefix CALL SNDSTR LXI H,DNUMBR ; Send the phone number CALL SNDSTR MVI A,CR ; Send a Return to start the dialing procedure CALL SEND1 ; ; Begin call progress monitoring ; CALL FLUSH ; Flush the "DIALING - " message ; *** Note: cannot abort with Control-C while waiting on first dial tone *** MVI B,30 ; get a chara, time out after 30 seconds MVI C,TMDINP CALL MEX JC DLERR ; Timeout = Modem error CPI 'D' JNZ PDLER ; No Dial tone error - exit CALL FLUSH ; Flush the "D.T. - " message ; ; Got past first Dial Tone, now look for the following completion msgs. ; If there is no response in 25.5 seconds, report a modem error to MEX. ; ; COMPLETE ; NO ABT - ABORT ; BUSY - ABORT ; NO D.T. - ABORT ; NO ANSWER - ABORT ; PDLP0: MVI B,0 ; no response timeout counter 0=25.5 sec PDLP1: DCR B JZ DLERR ; Exit upon timeout error PUSH B MVI C,CHEKCC ; Check for Ctl-C from Keyboard CALL MEX JZ PDABRT MVI C,INMDM CALL MEX POP B JC PDLP1 ; try again, if no chara ; PDLP2: CPI 'C' ; Check for the letter 'C' as in 'COMPLETE' JNZ PDLP3 ; PDL20: MVI C,INMDM ; Flush charas until LF or a timeout is rcv'd. CALL MEX JC PDL21 CPI LF JNZ PDL20 PDL21: MVI A,PCARR ; Return carrier detect (success) code to MEX CALL SETNRM ; reset serial port for normal operation. RET ; PDLP3: CPI 'B' ; Check for the letter 'B' as in 'BUSY' JNZ PDLP4 MVI A,PBSY ; Return the busy error code JMP MDMRST ; PDLP4: CPI '.' ; Check for '.' as in 'NO D.T.' JNZ PDPLP5 PDLER: MVI A,PNDIAL ; Return the No dial tone error code JMP MDMRST ; PDPLP5: CPI 'A' ; Check for 'A' as in 'NO ANSWER/NO ABT' JNZ PDLP0 ; Get/check another chara from modem MVI A,PNOANS ; Return the no answer error code JMP MDMRST ; DLERR: MVI A,PERR ; Return the modem error code JMP MDMRST ; PDABRT: POP B MVI A,PABRT ; Keyboard abort code JMP MDMRST ; ;--------------- ; ; Start the dialing process, reset the dial pointer, error flag ; STDIAL: LXI H,DNUMBR ; Reset the dial string pointer SHLD DPTR XRA A ; Clear the error flag STA ERRFLG RET ; ;--------------- ; ; Add another digit to the phone number string ; DDIGIT: CPI ',' ; map ',' into 'D' (delay) JNZ DDGT1 MVI A,'D' ; ; Check digit/chara for validity ; DDGT1: CALL CHKDGT JC DGTERR ; ; Load valid digit into phone num string ; Dashes and spaces are ignored... ; CPI '-' RZ CPI ' ' RZ LHLD DPTR MOV M,A INX H SHLD DPTR RET ; ; Invalid digit, set flag and exit. ; DGTERR: MVI A,PERR ; Must use the modem error code STA ERRFLG RET ; ;--------------- ; ; CHKDGT - Check for valid dialing digit/char ; Returns CY=1 if invalid chara ; CHKDGT: MOV B,A ; Save orig char in B LXI H,CHRSTR MOV A,M ; DGTLP: CMP B RZ ; Character is ok, return CY=0 INX H ; Chk for end of table MOV A,M ORA A JNZ DGTLP ; STC ; CY=1 indicates error RET ; CHRSTR: DB 0 ; 0 is a valid digit, must be first digit of table. DB '0123456789' ; Valid dialing digits DB 'PDWT' ; Special ACU commands, Pulse,Delay,Wait,Tone DB 'pdwt' ; Lower case versions okay. DB '- ' ; Allow dash and space for clarity DB 0 ; end of table ; TRNSTR: DB 'EN',0 ; CLRSTR: DB 'OG0 ',0 ; CCODE: DB 0 ; Completion code byte ; DNUMBR: DS 50 ; storage for phone number ; DPTR: DW DNUMBR ; Pointer into DNUMBR for next digit ; ERRFLG: DB 0 ; Digit error flag ; ;--------------- ; ; Support routines ; ; Send null terminated string to modem ; SNDSTR: MOV A,M ORA A RZ ; Null terminated string INX H PUSH H CALL SEND1 POP H JMP SNDSTR ; ; Send One chara to modem ; SEND1: PUSH PSW SND1LP: MVI C,SNDRDY CALL MEX JNZ SND1LP POP PSW MOV B,A MVI C,SNDCHR JMP MEX ; ; Table Search, - for SSET command parsing ; TSRCH: MVI C,LOOKUP JMP MEX ; ; In-Line Print, null-terminated string ; ILPRT: MVI C,ILP JMP MEX ; ; CRLF - Send CR,LF to console ; CRLF: CALL ILPRT DB CR,LF,0 RET ; ;--------------- ; ; 'Train' the modem ACU ; MDMTRN: LXI H,TRNSTR ; Send the training string CALL SNDSTR CALL GCOLON ; Check for a ':' from the modem RC ; CY=1 indicates training error XRA A ; CY=0 RET ; ;--------------- ; ; MDMRST - Reset the ACU to an untrained state. Aborts any ; dialing operation in progress. Preserves register A ; ; Send 'Q' to abort dial operation ; Send 'OG0' to untrain the ACU. (if ACU is active) ; MDMRST: EI PUSH PSW ; Save 'A', trashes all other reg's CALL SET8BT ; Set port for 8 bit data CALL FLUSH MVI A,'Q' ; Abort dialing in progress CALL SEND1 ; CALL GCOLON ; Check if ACU is alive JC MDMRS1 ; LXI H,CLRSTR ; Send the 'OG0' command string CALL SNDSTR ; MDMRS1: CALL FLUSH CALL SETNRM ;reset the serial port for normal oper. CALL FLUSH POP PSW ; restore 'A' RET ; ;--------------- ; ; Get a colon response from the modem, if there is a character ; timeout before receiving colon, return CY=1 to indicate error ; All other characters are accepted, up to a maximum of 30 ; GCOLON: MVI C,INMDM MVI B,30 GCOLP: PUSH B CALL MEX POP B RC ; return CY=1 upon modem timeout.. CPI ':' RZ ; return CY=0 upon receving ':' DCR B STC RZ ; return CY=1 upon too many characters JMP GCOLP ; ;--------------- ; ; Flush charas from modem, returns upon timeout. ; FLUSH: MVI C,INMDM ; Read until there are no more charas in 100msec CALL MEX JNC FLUSH RET ; ;--------------- ; ; Disconnect modem from phone line and untrain the ACU. ; ; Uses the Disconnect string if the modem has the new EPROM. ; Otherwise the computer overlay must drop DTR for at least ; 60 msec to disconnect the modem. ; MDMDSC: PUSH PSW ; IF UDSNEW CALL SET8BT CALL FLUSH LXI H,DSCSTR CALL SNDSTR ENDIF ; UDSNEW ; CALL MDMRST ; untrain the modem ACU CALL FLUSH ; extra delay for modem to reset itself. POP PSW RET ; IF UDSNEW DSCSTR: DB 'XXXT',CR,0 ENDIF ; UDSNEW ; ;-------------------------------- ; ; SSET command processing routine ; SSET: MVI C,SBLANK CALL MEX JC SETSHO LXI D,CMDTBL CALL TSRCH PUSH H RNC POP H SETERR: CALL ILPRT DB CR,LF,'SSet command error',CR,LF,0 RET ; ; CMDTBL: DB '?'+80H DW SETHLP DB 'PREFI','X'+80H ; dialing prefix string DW SETPRE DB 'OPTION','S'+80H ; Options command string DW SETOPT ; INSERT ADDITIONAL SSET COMMANDS HERE DB 0 ;End of table ; ;--------------- ; ; SSET display status of all 'sset' items ; SETSHO: CALL CRLF LXI H,SHOTBL SETSLP: MOV E,M INX H MOV D,M INX H MOV A,D ORA E JZ CRLF ;Exit thru CRLF PUSH H XCHG CALL GOHL CALL CRLF POP H JMP SETSLP ; GOHL: PCHL ; ; table of Show routine addresses ; SHOTBL: DW OPTSHO ; Option commands DW PRESHO ; show the dialing prefix string ; Add other status routines here DW 0 ; End of table ; ;----------------------- ; ; SSET ? print available SSET commands ; SETHLP: CALL ILPRT DB CR,LF,'Available SSET Commands: (UDS-212 A/D)',0 ; LXI H,CMDTBL MVI C,PRNTBL CALL MEX CALL CRLF JMP CRLF ; Exit thru CRLF ; ;-------------- ; ; SSET PREFIX {string} Change the dialing prefix string, default is 'P' ; other useful prefixes are T, P9W, etc. ; ; SSET PREFIX Print current string. ; SSET PREFIX "" Set prefix to null string ; SSET PREFIX string Set prefix to 'string' ; SSET PREFIX "string" (Quotes are optional, same as above) ; SETPRE: MVI C,SBLANK ; Isolate the space terminated string CALL MEX JC PRESHO ; Show current string ; MVI B,(ENDPRE-DPREFX)-2 ; B=Max length of string LXI H,DPREFX MVI C,GNC ; MEX service code for get next chara SETPLP: PUSH H PUSH B CALL MEX ; Fetch chara, CY=1 means end of string JC SETPEX ; Verify chara as a valid dialing digit. CPI '"' CNZ CHKDGT JNC SETP1 ; Invalid digit, report error, terminate PREFIX string. CALL ILPRT DB CR,LF,'Invalid character in PREFIX string' DB CR,LF,0 JMP SETPEX ; Store good digit, except quote marks SETP1: POP B POP H CPI '"' JZ SETPLP MOV M,A ; Store new chara INX H DCR B ; Check for string too long JNZ SETPLP ; get next chara JMP SETPX1 ; Exit, if no more room SETPEX: POP B POP H SETPX1: MVI M,0 ; Finished. Insert 0, insert 'RET' INX H MVI M,0C9H ; Insert RET instruction ; Fall thru to PRESHO ; ;--------------- ; ; PRESHO Show current dial prefix string. ; PRESHO: CALL ILPRT DB 'Dialing prefix: ',0 CALL ILPRT DPREFX: DB 'P' ; dialing prefix string, default = 'P' DB 0,0,0,0,0,0,0,0,0,0,0 ; Max of 12 charas DB 0 ; String must be null-terminated, *plus* a RET inst. RET ENDPRE: ; ;-------------- ; ; SSET OPTIONS {string} Change the dialing options string, default is 'OF1' ; other useful options are OBx ; ; SSET OPTIONS Print current string. ; SSET OPTIONS "" Set options to null string ; SSET OPTIONS string Set options to 'string' ; SSET OPTIONS "string" (Quotes are optional, same as above) ; SETOPT: MVI C,SBLANK ; Isolate the space terminated string CALL MEX JC OPTSHO ; Show current string ; MVI B,(ENDOPT-DOPTS)-2 ; B=Max length of string LXI H,DOPTS MVI C,GNC ; MEX service code for get next chara SETOLP: PUSH H PUSH B CALL MEX ; Fetch chara, CY=1 means end of string POP B POP H JC SETOP1 CPI '"' ; ignore quote charas JZ SETOLP MOV M,A ; Store new chara INX H DCR B ; Check for string too long JNZ SETOLP ; get next chara ; SETOP1: MVI M,0 ; Finished. Insert 0, insert 'RET' INX H MVI M,0C9H ; Insert RET instruction ; Fall thru to PRESHO ; ;-------------- ; ; OPTSHO ; OPTSHO: CALL ILPRT DB 'Modem Options : ',0 CALL ILPRT DOPTS: DB 'OB1',0,0,0,0,0,0 ; 18 charas max, default=OB1 DB 0,0,0,0,0,0,0,0,0 DB 0 RET ENDOPT: ; ;---------------- ; DUMMY: RET ; Do nothing routine. ; ; ; END