; TITLE 'MEX DATEC 212 OVERLAY V1.0' ; ; Datec 212 overlay for MEX: revision 1.0 ; Modified from MXO-SM10.ASM by Ted H. Emigh 25 May 1984 (emigh@ecsvax) ; ; Last revision: 25 May 1984, THE ; ; This modules adapts MEX for the Datec 212. The main function ; of this module is to provide dialing capability; the disconnect ; vector is ancillary. ; ; The only conditional you might want to change in this ; module is the DISC equate below -- if left on, MEX will ; use the Datec 212's disconnect code. If you prefer to ; provide your own in your overlay's DISCV vector (e.g., ; by dropping DTR), then set DISC to FALSE and re-assemble. ; (If you don't understand this, then play it safe, and ; leave the equate set as it is). ; ; This overlay will work with any modem overlay that terminates ; prior to 0B00H ; FALSE EQU 0 TRUE EQU NOT FALSE ; ; DISC EQU TRUE ;<<== CHANGE TO FALSE IF YOU DISC. WITH DTR ECHOSW EQU TRUE ;<<== TRUE IF COMMANDS TO MODEM ARE ECHOED ; BY THE MODEM VERBOS EQU TRUE ;<<== TRUE IF MODEM MESSAGES ARE ECHOED ON ; THE CONSOLE LFSW EQU TRUE ;<<== TRUE IF CR/LF AFTER DATEC MESSAGES ; ; SYSTEM CONSTANTS ; TPULSE EQU 0105H ;TONE/PULSE FLAG IN MODEM OVERLAY DIALV EQU 0162H ;LOCATION OF DIAL VECTOR IN OVERLAY DISCV EQU 0165H ;LOCATION OF DISCONNECT VECTOR IN OVERLAY DIALOC EQU 0B00H ;DIALING CODE GOES HERE MEX EQU 0D00H ;"CALL MEX" ; ; FOLLOWING ARE FUNCTION CODES FOR THE MEX SERVICE CALL PROCESSOR ; INMDM EQU 255 ;RETURN CHAR FROM MDM IN A, CY=NO CHR IN 100MS TIMER EQU 254 ;DELAY 100 MS*REGISTER 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) CONOUT EQU 2 ;SIMULATED BDOS FUNCTION 2: CONSOLE OUTPUT ; CR EQU 13 LF EQU 10 ; ; ; ORG TPULSE DB 'T' ;T=touch, P=pulse ; ORG DIALV ;OVERLAY THE DIALING VECTOR JMP DIAL ; IF DISC ;IF PROVIDING DISCONNECT CODE ORG DISCV ;OVERLAY THE VECTOR JMP DISCON ENDIF ; ; This is the DIAL routine called by MEX to dial a digit. The digit ; to be dialed is passed in the A register. Note that two special ; codes must be intercepted as non-digits: 254 (start dial sequence) ; and 255 (end-dial sequence). Mex will always call DIAL with 254 ; in the accumulator prior to dialing a number. Mex will also call ; dial with 255 in A as an indication that dialing is complete. ; ; After the 254-start-dial sequence, MEX will call the overlay with ; digits, one-at-a-time. MEX will make no assumptions about the dig- ; its, and will send each to the DIAL routine un-inspected (some modems, ; like the Datec 212, allow special non-numeric characters in the ; phone number, and MEX may make no assumptions about these). ; ; After receiving the end-dial sequence (255) the overlay must take ; whatever end-of-dial actions are necessary *including* waiting for ; carrier at the distant end. The overlay should monitor the keyboard ; during this wait (using the MEX keystat service call), and return ; an exit code to MEX in the A register, as follows: ; ; 0 - Carrier detected, connection established ; 1 - Far end busy (only for modems that can detect this condition) ; 2 - No answer (or timed out waiting for modem response) ; 3 - Keyboard abort (^C only: all others should be ignored) ; 4 - Error reported by modem ; ; <No other codes should be returned after an end-dial sequence> ; ; The overlay should not loop forever in the carrier-wait routine, but ; instead use either the overlay timer vector, or the INMDMV (timed 100 ; ms character wait) service call routine. ; ; The DIAL routine is free to use any of the registers, but must return ; the above code after an end-dial sequence ; ORG DIALOC ; DIAL: LHLD DIALPT ;FETCH POINTER CPI 254 ;START DIAL? JZ STDIAL ;JUMP IF SO CPI 255 ;END DIAL? JZ ENDIAL ;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 ; STDIAL: LXI H,DIALBF+1 ;SET UP BUFFER POINTER SHLD DIALPT RET ; ; Here on an end-dial sequence ; ENDIAL: XRA A ;RESET DISCONNECT FLAG STA DSCFLG 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 DIALBF ;PUT INTO STRING LXI H,ATTN ;GET MODEM'S ATTENTION CALL MSEND MVI A,3 ;WAIT 3 SECONDS FOR RESPONSE STA TIME CALL RESPON CPI 6 ;SEE IF MODEM IS READY MVI A,4 ;SET FOR MODEM ERROR RNZ LXI H,DIALBF ;POINT TO DIALING STRING CALL MSEND ;SEND IT CALL RESPON ;WAIT 3 SECONDS FOR RESPONSE CPI 7 ;SEE IF MESSAGE "NUMBER STORED" MVI A,4 ;SET FOR MODEM ERROR RNZ LXI H,DIALCM ;FINALLY, DIAL THE NUMBER CALL MSEND ;SEND IT CALL RESPON ;WAIT 3 SECONDS FOR A RESPONSE CPI 5 ;SEE IF MODEM IS DIALING MVI A,4 ;SET FOR MODEM ERROR RNZ MVI A,60 ;WAIT 60 SECONDS FOR RESPONSE STA TIME CALL RESPON CPI 5 ;ADJUST RESPONSE TO 0-4 RC MVI A,4 ;RESPONSE ABOVE 4 ARE ERRORS RET ; ; THE FOLLOWING LOOP WAITS FOR A RESPONSE FROM THE MODEM (UP TO ; 60 SECONDS: YOU MAY CHANGE THIS VALUE IN THE FOLLOWING LINE) ; RESPON: XRA A ;ZERO THE MESSAGE FLAG STA MSGFLG LDA TIME ;GET MAXIMUM TIME TO WAIT FOR RESPONSE MOV C,A MWLP: 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 MTEST ;JUMP IF MODEM HAD A CHAR PUSH B ;NO, TEST FOR CONTROL-C FROM CONSOLE MVI C,CHEKCC CALL MEX POP B JNZ MNEXT ;IF NOT, JUMP LDA DSCFLG ;SEE IF ^C ALREADY HIT ORA A JNZ MWLP ;ALREADY HIT, IGNORE THIS ONE DCR A ;SET DSCFLG STA DSCFLG LXI H,DISCD ;MAKE THIS ROUTINE EXIT THROUGH DISCD PUSH H JMP MWLP ;WAIT FOR ANOTHER MODEM CHARACTER MNEXT: DCR C ;NO JNZ MWLP ;CONTINUE ; ; ONE MINUTE WITH NO MODEM RESPONSE (OR NO CONNECTION) ; MTIMO: MVI A,2 ;RETURN TIMEOUT CODE RET ; ; DATA USED DURING WAIT FOR RESPONSE FROM MODEM ; TIME: DB 0 ;TIME (IN SECONDS) TO WAIT ; ; MODEM GAVE US A RESPONSE, CHECK IT ; MTEST: ; IF VERBOS CALL CDISP ;DISPLAY THE CHARACTER ENDIF ; ANI 7FH ;IGNORE ANY PARITY CALL MANAL ;TEST THE RESPONSE JC MWLP ;GO TRY AGAIN IF UNKNOWN RESPONSE MOV A,B ;A=RESPONSE PUSH PSW ;SAVE IT MTLP: MVI C,INMDM ;EAT ANY ADDITIONAL CHARS FROM DATEC CALL MEX ; IF VERBOS CNC CDISP ;DISPLAY THE CHARACTER (DOES NOT EFFECT CARRY) ENDIF ; JNC MTLP ;UNTIL 100MS OF QUIET TIME POP PSW ;RETURN THE CODE RET ; MANAL: MOV B,A ;SAVE CHARACTER LDA MSGFLG ;SEE IF CONTINUATION OF MESSAGE ORA A JNZ CMSG ;CONTINUATIN OF MESSAGE MOV A,B ;RESTORE CHARACTER CPI 'O' ;"ON LINE" OR "OFF LINE"? JZ OMSG CPI 'N' ;"NO CARRIER", "NUMBER STORED", OR ;"NO NUMBER STORED" JZ NMSG ; ; RETURN CODE 0 ; MVI B,0 ;PREP CONNECT CODE CPI '1' ;NUMERIC VERSION OF "ON LINE" RZ ; ; RETURN CODE 2 ; MVI B,2 CPI '3' ;NUMERIC VERSION OF "NO CARRIER" RZ ; ; RETURN CODE 4 ; MVI B,4 ;PREP MODEM ERROR CPI 'E' ;"ERROR"? RZ CPI '4' ;NUMERIC VERSION OF "ERROR" RZ ; ; RETURN CODE 5 ; INR B CPI 'D' ;"DIALING'? RZ CPI '5' ;NUMERIC VERSION OF "DIALING" RZ CPI '6' ;NUMERIC VERSION OF "DIALING 1ST NUMBER" RZ CPI '7' ;NUMERIC VERSION OF "DIALING 2ND NUMBER" RZ ; ; RETURN CODE 6 ; INR B CPI 'R' ;USED FOR THIS ROUTINE FOR RZ ;"READY"? CPI '0' ;NUMERIC VERSION OF "READY" RZ ; ; RETURN CODE 7 ; INR B CPI '8' ;NUMERIC VERSION OF "NUMBER STORED" RZ ; ; RETURN CODE 8 ; INR B CPI '9' ;NUMERIC VERSION OF "OFF LINE" RZ ; ; RETURN CODE 9 ; INR B CPI 'A' ;NUMERIC VERSION OF "NO NUMBER STORED" RZ ; ; FINISHED WITH RECOGNIZABLE CODES ; CPI CR ;IGNORE CARRIAGE RETURNS STC RZ ; ; 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 WTLF1: MVI C,INMDM ;NO. GET NEXT CHAR CALL MEX ; IF VERBOS CNC CDISP ;DISPLAY THE CHARACTER (DOES NOT EFFECT PSW) ENDIF ; JNC WTLF ;UNLESS BUSY, LOOP RET ; ; CONTINUATION OF MESSAGE -- NOT ABLE TO DISTINGUISH ; WITH THE FIRST LETTER. USE THE FOURTH LETTER FOR "N" ; MESSAGES AND THE SECOND LETTER WITH "O" MESSAGES ; CMSG: RAL ;SEE IF "O" OR "N" MESSAGE JNC CNMSG ;"N" MESSAGE ; ; RETURN CODE 0 ; STA MSGFLG ;RESET MESSAGE FLAG MOV A,B ;GET CHARACTER MVI B,0 CPI 'N' ;"ON LINE" RZ ; ; RETURN CODE 8 ; MVI B,8 CPI 'F' ;"OFF LINE" RZ JMP WTLF ;UNKNOWN RESPONSE ; ; CHECK FOURTH LETTER FOR "N" MESSAGES ; CNMSG: RAR INR A ;A = LETTER # CPI 4 JC GETNXT ;IGNORE THIS LETTER, GET ANOTHER MOV A,B ; ; RETURN CODE 2 ; MVI B,2 CPI 'C' ;"NO CARRIER" RZ ; ; RETURN CODE 7 ; MVI B,7 CPI 'B' ;"NUMBER STORED" RZ ; ; RETURN CODE 9 ; MVI B,9 CPI 'N' ;"NO NUMBER STORED" RZ JMP WTLF ;UNRECOGNIZED RESPONSE ; ; GET THE NEXT CHARACTER IN THE MESSAGE ; GETNXT: STA MSGFLG ;UPDATE MESSAGE FLAG RET ;CARRY FLAG IS SET ; ; INITIALIZE THE "O" MESSAGE SEARCH ; OMSG: MVI A,80H ;SET THE MESSAGE FLAG FOR "O" MESSAGE STA MSGFLG STC ;GET ANOTHER CHARACTER RET ; ; INITIALIZE THE "N" MESSAGE SEARCH ; NMSG: MVI A,1 ;SET THE MESSAGE FLAG FOR "N" MESSAGE STA MSGFLG STC ;GET ANOTHER CHARACTER RET ; ; MESSAGE FLAG ; SIGNALS WHETHER OR NOT A RESOLUTION OF AN "O" OR "N" MESSAGE ; IS IN PROGRESS MSGFLG: DS 1 ; ; SEND A TO THE CONSOLE FOR VERBOS OPTION ; IF VERBOS CDISP: PUSH PSW PUSH H PUSH D PUSH B ANI 7FH ;STRIP HIGH BIT MOV E,A MVI C,CONOUT CALL MEX ;SEND TO THE CONSOLE POP B POP D POP H POP PSW RET ENDIF ; ; FOLLOWING ROUTINE DISCONNECTS THE MODEM USING DATEC ; CODES. ALL REGISTERS ARE AVAILABLE FOR THIS FUNCTION ; NOTHING RETURNED TO CALLER ; DISCD: CALL DISCV ;DISCONNECT THE MODEM ;GO TO DISCV IN CASE DISC=FALSE MVI A,3 ;^C CODE FOR DIAL ROUTINE RET ; DSCFLG: DB 0 ;DISCONNECT FLAG ; IF DISC ; DISCON: LXI H,MATN ;SEND '^D^D^D' CALL MSEND MVI A,60 ;MAXIMUM OF 60 SECONDS TO WAIT STA TIME ;__FOR MODEM TO DISCONNECT CALL RESPON RET ; MATN: DB 'D'-40H,'D'-40H,'D'-40H,0 ; ENDIF ; ; DATEC UTILITY ROUTINE: SEND STRING TO MODEM ; MSEND: MOV A,M ;FETCH NEXT CHARACTER INX H ORA A ;END? RZ ;DONE PUSH H PUSH PSW ;SAVE CHARACTER MSEND1: MVI C,SNDRDY ;WAIT FOR MODEM READY CALL MEX JNZ MSEND1 POP B ;GET CHARACTER MVI C,SNDCHR ;SEND THE CHARACTER CALL MEX ; IF ECHOSW MVI C,INMDM ;DELAY TIL ECHO, OR 100MS CALL MEX ENDIF ; POP H JMP MSEND ; ; DATA AREA ; ATTN: DB 'AT',0 ;GET THE MODEM'S ATTENTION DIALCM: DB 'A/',0 ;DIAL THE NUMBER DIALPT: DS 2 ;DIAL POSITION POINTER DIALBF: DS 50 ;NUMBER BUFFER (48 CHAR MAX+CR+NULL+SLOP) ; END