home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
mex
/
mxm-sc13.asm
< prev
next >
Wrap
Assembly Source File
|
1994-07-13
|
13KB
|
335 lines
TITLE 'MEXPLUS overlay for SwitchCom Canadiana 212A modem V 1.3'
; (DELETE ABOVE TITLE LINE IF ASSEMBLING WITH ASM)
; SwitchCom Canadiana 212A overlay for MEXPLUS: revision 1.3 86/12/01
; This module adapts MEX or MEXPLUS for the SwitchCom Canadiana 212A
; modem. Made by: SwitchCom Manufacturing Inc
; 100-10 Amber St., Markham, Ontario, Canada
; L3R 3A2 Tel: 416-475-0296
; This overlay will work with any port overlay that terminates
; prior to 0B00H and will work with either MEX or MEXPLUS.
; 86/12/26 V1.3 - moved modem initialization code to front of
; dial code and added flag to make sure that
; modem is only initialized once
; - Ian Cottrell
; 86/06/01 V1.2 - added 'space bar return busy' code (thanks
; to Al Jewer). This code allows the user to
; push the space bar if he knows that the
; called number is busy. If he is dialing
; a series of numbers, MEX will advance to the
; next one.
; - Ian Cottrell
; 86/01/18 V1.1 - filter all but numerals from dial routine,
; tightened code, made compatible with MEXPLUS
; - Ian Cottrell
; 85/03/06 V1.0 - Written - based on MXO-SM11.ASM
; - Ian Cottrell
; Sysop
; Info Centre BBS
; Ottawa, Ont
; Canada
; 613-952-2289
FALSE EQU 0
TRUE EQU NOT FALSE
DISC EQU TRUE ; <<== change to FALSE if you disc. with DTR
; always true for MEX 1.2 or greater
; System constants
NDISCV EQU 015FH ; New smart modem disconnect here
DIALV EQU 0162H ; Location of dial vector in port overlay
DISCV EQU 0165H ; Location of disconnect vector in port overlay
DIALOC EQU 0B00H ; Dialing code goes here
MEX EQU 0D00H ; "CALL MEX"
SMTABL: EQU 0D55H ; Smart modem init, SSET, de-init
; The following are function codes for the MEX Service Processor
INMDM EQU 255 ; Return char from mdm in A, CY=no char in 100ms
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 character from the modem (after RCVRDY)
ILP EQU 240 ; Inline print
KSTAT EQU 11 ; Keyboard status
KBDIN EQU 01 ; Keyboard input
CR EQU 13
LF EQU 10
CTRLQ EQU 'Q'-40H
ORG 100H
DB 0C3H ; We're an 8080/Z-80 overlay
ORG DIALV ; Overlay the dialing vector
JMP DIAL
IF DISC ; If providing disconnect code,
ORG NDISCV ; overlay the vector
JMP DISCON
ENDIF ; DISC
; 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. Thus,
; the overlay may use these values to "block" the number, holding it
; in a buffer until it is completely assembled (that's the scheme
; employed here ).
; After the 254-start-dial sequence, MEX will call the overlay with
; digits, one-at-a-time. MEX will make no assumptions about the digits,
; and will send each to the DIAL routine un-inspected (some modems,
; like the Smartmodem, allow special non-numeric characters in the
; phone number, and MEX may make no assumptions about these.
; The Canadiana does not allow non-numberic characters, so they are
; filtered out by the overlay).
; 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
; First, check to see if modem has been initialized. If not,
; initialize Canadiana by setting for numeric responses and
; turning off the echo.
DIAL: PUSH PSW ; Save number
LDA INITFL ; Get initialization flag
ORA A ; Test
JNZ DIAL1 ; If done, skip init code
LXI H,ECHO ; Else,point to message to set echo
CALL SCSEND ; Send it to modem
ELOOP: MVI C,INMDM ; Wait for response from modem
CALL MEX
JNC ELOOP ; Get it all
LXI H,VERBOSE ; Point to message to set verbose
CALL SCSEND ; Send it to modem
VLOOP: MVI C,INMDM ; Wait for response
CALL MEX
JNC VLOOP
MVI A,0FFH ; Set initialization flag
STA INITFL
DIAL1: POP PSW ; Restore number
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
CPI '0' ; Only allow numbers
RC ; If not a number, just ignore it
CPI '9'+1
RNC
MOV M,A ; Must be a number, so put it in buffer
INX H ; Advance pointer
SHLD DIALPT ; Stuff pointer
RET ; All done
; Here on a start-dial sequence
STDIAL: LXI H,DIALBF ; Set up buffer pointer
SHLD DIALPT
RET
; Here on an end-dial sequence
ENDIAL: MVI M,CR ; Stuff end-of-line into buffer
INX H ; followed by terminator
MVI M,0
LXI H,SCDIAL ; Point to dialing string
CALL SCSEND ; Send it
WAITSC: MVI C,INMDM
CALL MEX ; Catch any output from the modem
JNC WAITSC ; Loop until no more characters
; The following loop waits for a result from the modem (up to
; 60 seconds; you may change this value in the following line).
; Note that the Canadiana has an internal 30 second timeout while
; waiting for a carrier on the other end.
RESULT: MVI C,60 ; <<== Maximum time to wait for result (in secs)
SCWLP: 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 SCTEST ; If modem had a character, jump
PUSH B ; Else, test for character from console
MVI C,KSTAT ; Check for keypress
CALL MEX
ORA A
POP B
JZ SCNEXT ; Jump if no keypress
PUSH B ; Else, get character from keyboard
MVI C,KBDIN
CALL MEX
POP B
CPI 'C'-40H ; CTL-C?
JNZ SPTST ; If not, go test for space
MVI A,3 ; Else, get abort code
SCOFF: PUSH PSW ; Save it
MVI B,CR ; Shut down the modem
MVI C,SNDCHR
CALL MEX
POP PSW ; Restore return code
RET
SPTST: CPI ' ' ; Space?
JNZ SCNEXT ; If not, round the loop again
MVI A,1 ; Else, get busy code
JP SCOFF ; Now go shut down modem
SCNEXT: DCR C ; Decrement counter
JNZ SCWLP ; Continue if not done
; One minute with no modem response (or no connection)
SCTIMO: MVI A,2 ; Timed out, so return timeout code
RET
; Modem gave us a result, check it
SCTEST: ANI 7FH ; Ignore any parity
CALL SCANAL ; Test the result
JC RESULT ; Go try again if unknown response
MOV A,B ; A=result
PUSH PSW ; Save it
SCTLP: MVI C,INMDM ; Eat any additional chars from Candaiana
CALL MEX
JNC SCTLP ; Until 100ms of quiet time
POP PSW ; Return the code
RET
SCANAL: MVI B,0 ; Prep connect code
CPI '2' ; 2=connect
RZ
INR B ; Prep busy cond; B=1
INR B ; Prep no connect msg; B=2
CPI '3' ; 3=no connect (from Canadiana)
RZ
; Unknown response, return carry to caller. But first,
; flush the unknown response line from the modem.
WTLF: CPI 1 ; 'Dialing'?
STC
RZ ; End if so
MVI C,INMDM ; No - get next char
CALL MEX
JNC WTLF ; Unless busy, loop
RET
; Following routine disconnects the modem using Canadiana
; codes. All registers are available for this function.
; Nothing is returned to caller.
IF DISC
DISCON: MVI B,20
MVI C,TIMER ; Wait 2 seconds
CALL MEX
LXI H,SCATN ; Send 3 Ctrl-Q's
CALL SCSEND
PUSH B
MVI B,5
DISCLP: MVI C,TMDINP ; Wait for response from modem
CALL MEX
JNC DISCLP ; Wait til all done
POP B
LXI H,ECHRES ; Reset echo
CALL SCSEND
ECHLP: MVI C,INMDM ; Wait for next response
CALL MEX
JNC ECHLP
LXI H,VERRES ; Reset verbose
CALL SCSEND
XRA A ; Clear the init flag in case
STA INITFL ; we want to dial again
RET
SCATN: DB CTRLQ,CTRLQ,CTRLQ,CR,LF,0 ; Disconnect
ECHRES: DB 'E=1',CR,LF,0 ; Turn echo back on
VERRES: DB 'V=2',CR,LF,0 ; Turn verbose back on
ENDIF
;Canadiana Utility routing: send string to modem
SCSEND: MVI C,SNDRDY ; Wait for modem ready
CALL MEX
JNZ SCSEND
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 ; Send the character
CALL MEX
JMP SCSEND
; Data area
SCDIAL: DB 'D'
DIALBF: DS 52 ; 2 * 24 char max, + CR + NULL + slop
DIALPT: DS 2 ; Dial position pointer
VERBOSE:DB 'V=1',CR,LF,0 ; Set for numeric responses from modem
ECHO: DB 'E=0',CR,LF,0 ; Turn echo off
INITFL: DB 0 ; Storage for init flag
; must be 0 to start
NOTIMP: MVI C,ILP
CALL MEX
DB CR,LF,'Not Implemented',CR,LF,0
JUSTRT: RET
ORG SMTABL ; Table of smart modem vectors here
DS 2
DW NOTIMP ; SSET command (not implemented)
DW JUSTRT ; Smart modem exit (do nothing)
END