home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
mex
/
mxo-on2.lbr
/
MXO-ON2.ZZ0
/
MXO-ON2.Z80
Wrap
Text File
|
1987-11-25
|
33KB
|
1,323 lines
; Title 'MEX Overlay for ON! computer Version SM 2.0'
;
REV EQU 20 ; Overlay revision level
;
;
; MEX Overlay for ON! Computers, external smartmodems,
; either Anchor or Hayes-compatible.
;
; A full-featured SET command processor is implemented.
; The following table outlines the SET command options:
;
;
; SET Command
;
; ANCHOR Sets modem to respond to
; Anchor modem commands; although
; Anchor modems are considered Hayes
; compatible, there ARE a few
; differences which require special
; processing considerations.
;
; DELAY <N> Number of seconds to wait before
; aborting a call in progress
;
; BAUD <RATE> Set modem to Baud rate specified.
; Baud rates supported are 300,
; 1200, 2400, 4800, 9600, and 19200
;
; ORIG Set modem to Originate mode
; ANSWER Set modem to Auto-answer mode
; TONE Set modem to Tone dialing
; PULSE Set modem to Pulse dialing
; MONITOR Turn Hayes monitor ON
; QUIET Turn Hayes monitor OFF
; PARITY Set Parity to Odd, Even, or Off
; STOPBITS Set number of Stop Bits to 1, 1.5, 2
; LENGTH Set word length to 5, 6, 7, 8
;
; MANUAL ORIG <or> ANSWER Place modem in active state and
; generate Answer or Originate
; carrier tone
;
;
; 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:
; November 24, 1987 MXO-ON2.Z80 (release version)
;
; Fixed buglet in PBAUD - Bruce Morgen
;
; October 8, 1987 MXO-ON2.Z80 (not released)
;
; SET ANSWER now sets the NDELAY variable to 12 via the
; SET DELAY code and waits for a connect indication from
; the modem before proceeding. A control-C abort results
; in a DISCON call, the restoration of the original SET
; DELAY condition, and a SET ORIGINATE sequence.
;
; Bruce Morgen
;
; July 20, 1987
; Adapted for ON! computer as MXO-ON1.Z80 - Bruce Morgen
;
; 12/20/84 4.0 Fixed bugs in send break and initialization routines.
; -- Kim Levitt
;
; 11/25/84 3.0 Added SILENT option to quiet that damn beep-beep-
; beep while dialing out. Speaker will come on at
; end of dialing.
; -- Kim Levitt
;
; 9/19/84 2.0 Fixed bug in DISCON routine that left DTR/RTS off,
; added "soft" abort (any key except ^C) to abort a
; CALL in progress, but not repeats or next CALL cmds.
; -- Kim Levitt
;
; 9/9/84 1.0 The universal Kaypro overlay distributed previously
; combined support for both the internal modem on the 4'84
; and external smartmodems. This overlay supports external
; smartmodems only, and thus provides more flexibility for
; expansion and adaptability to new MEX releases. The only
; additional feature of this overlay is support for
; entering Terminal mode via generation of manual Originate
; or Answer carrier tones. Clarity of documentation for
; the SET command has also been improved.
; Terry Carroll
;
;
; Credits:
;
; M7KP-1 overlay structure by Irv Hoff
; Smartmodem dialing routine by Ron Fowler
; Parity, Length and Stopbits routines by Norm Saunders
; MXO-KP overlay structure by John Smith
; Art work by Terry Carroll
; Bug fix/feature added by Kim Levitt
; Based on an idea by an inspired hacker
; Music by John Williams
; Directed by Stanley Kubrick
;
;------------------------------------------------------------
;
; Miscellaneous equates
;
NO EQU 0
YES EQU 0FFH
;
TPA EQU 100H
;
CR EQU 13
LF EQU 10
TAB EQU 9
;
; Silent dial option:
;
SILENT EQU YES ; If yes, speaker is silenced during dial
;
; (NOTE: This may not work on all "smart" modems, it works on the
; Hayes.. Set it to NO if it doesn't dial out ok...)
;
; ON! port definitions
;
EXPORT EQU 92H ; Base external port
EXTCT1 EQU EXPORT+1 ; External modem status port
EXTDAT EQU EXPORT ; External modem data port
;
; ON! bit definitions
;
MDRCVB EQU 01H ; Modem receive bit (dav)
MDRCVR EQU 01H ; Modem receive ready
MDSNDB EQU 04H ; Modem send bit
MDSNDR EQU 04H ; Modem send ready bit
;
; ON! baud rates. Low order byte is baud rate generator divisor,
; High order byte is the Dart divisor (WR4, 1 stop bit).
;
BD300 EQU 0C400H ; /64, /32
BD1200 EQU 04400H ; /16, /32
BD2400 EQU 08410H ; /32, /8
BD4800 EQU 04410H ; /16, /8
BD9600 EQU 0C420H ; /64, /1
BD19200 EQU 08420H ; /32, /1
;
; 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 io function #
DCONIN EQU 0FFH ; BDOS dconio flag for input
BDOS EQU 5 ; BDOS function caller
;
;
ORG TPA ; We begin
;
DS 3 ; 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 46 ; 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 ; ^@ = 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: LD A,10H ; In modem control port
OUT (EXTCT1),A
IN A,(EXTCT1)
RET
INCEND: DS 10-[INCEND-INCTL1]
;
OTDATA: OUT (EXTDAT),A ; Out modem data port
RET
OTDEND: DS 10-[OTDEND-OTDATA]
;
INPORT: IN A,(EXTDAT) ; In modem data port
RET
INPEND: DS 10-[INPEND-INPORT]
;
; Bit-test routines.
;
MASKR: AND MDRCVB
RET ; Bit to test for receive ready
TESTR: CP MDRCVR
RET ; Value of receive bit when ready
MASKS: AND MDSNDB
RET ; Bit to test for send ready
TESTS: CP MDSNDR
RET ; Value of send bit when ready
;
DS 12
;
LOGON: DS 2 ; Needed for MDM compat, not ref'd by MEX
DIALV: JP DIAL
DISCV: JP DISCON
GOODBV: JP GOODBYE ; Called before exit to CP/M
INMODV: JP NITMOD ; Initialization. called at cold-start
NEWBDV: JP PBAUD ; Set baud rate
NOPARV: RET
NOP
NOP ; Set modem for no-parity
PARITV: RET
NOP
NOP ; Set modem parity
SETUPV: JP SETCMD ; Set cmd: jump to a ret if you don't write SET
SPMENV: RET
NOP
NOP ; Not used with MEX
VERSNV: JP SYSVER ; Overlay's voice in the sign-on message
BREAKV: JP 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: LD DE,EOSMSG
LD C,PRINT
CALL MEX
RET
;
CLS: LD DE,CLSMSG
LD C,PRINT
CALL MEX
RET
;------------------------------------------------------------
;
; end of fixed area
;
;------------------------------------------------------------
;
; Print out the overlay version
;
SYSVER: CALL MILP
DB 'ON! Overlay Version SM '
DB REV/10+'0'
DB '.'
DB REV MOD 10+'0'
DB CR,LF,LF
DB 0
RET
;
; Break, disconnect and goodbye routines
;
SBREAK: LD A,5
OUT (EXTCT1),A
LD A,(REG5)
OR 9AH ; Send a break
OUT (EXTCT1),A
LD B,3 ; Delay 300 ms.
CALL MTIME
LD A,5
OUT (EXTCT1),A
LD A,(REG5)
OUT (EXTCT1),A ; Stop break
RET
;
; Disconnect Routine
;
DISCON: LD A,(MODMTYP)
OR A
JR Z,DISCONH
;
; Disconnect Anchor Modem.
; Anchor does not respond to DTR so the only way to disconnect is through
; standard Smartmodem disconnect commands
;
DISCONA:LD B,20
CALL MTIME ; Wait 2 seconds
LD HL,SMATN ; Send '+++'
CALL SMSEND
LD B,40 ; Wait 4 more seconds (Anchor is slow)
CALL MTIME
LD HL,SMDISC ; Send 'ATH'
CALL SMSEND
LD B,10 ; Wait 1 second
CALL MTIME
RET
;
; Disconnect Hayes, etc.
;
DISCONH:LD A,5
OUT (EXTCT1),A ; Send to the status port
LD A,68H ; Turn off DTR/RTS
OUT (EXTCT1),A
LD B,10 ; Delay 1 sec.
CALL MTIME
LD A,5
OUT (EXTCT1),A
LD A,0EAH ; Turn 'em back on again
OUT (EXTCT1),A
GOODBYE:RET
;
; GOODBYE routines are called by MEX prior to exit to CP/M
; (re-use DISCONH's RET to save space)
;GOODBYE:RET ; NOTE: EXIT TO CP/M with no change to
; connect status or settings (parity, etc)
;
; Initialize RS-232 port, Smartmodem, and default modes.
;
NITMOD: CALL NITSIO ; Don't assume initialized dart chip!
CALL INCTL1 ; See if modem is connected, i.e., returning
AND 08H ; To active modem from CPM
RET NZ ; Skip if connected
LD A,(MSPEED) ; Get default baud rate
CALL PBAUD ; Set it
LD A,(MONFLG) ; Get monitor default
OR A
LD A,'0' ; Speaker off
JR Z,NITMOD4
INC A ; Speaker on (A='1')
NITMOD4:LD (SMINIT+3),A ; Put it in sminit string
LD A,(ANSFLG) ; Get mode default
OR A
LD A,'0' ; Originate
JR Z,NITMOD5
INC A ; Answer (A='1')
NITMOD5:LD (SMINIT+8),A ; Put it in sminit string
LD HL,SMINIT
SINIT: CALL SMSEND ; Send the init string
SMTLP1: LD C,INMDM ; Wait for modem response
CALL MEX
JR NC,SMTLP1 ; Eat everything until silence for
RET ; 100 msec
;
; Initialize the Zilog DART chip
;
NITSIO: XOR A ; Select reg. 0
OUT (EXTCT1),A
LD A,(REG0) ; Command byte
OUT (EXTCT1),A
LD A,04H ; Select reg. 4
OUT (EXTCT1),A
LD A,(REG4) ; Receive/transmit control byte
OUT (EXTCT1),A
LD A,03H ; Select reg. 3
OUT (EXTCT1),A
LD A,(REG3) ; Receiver logic byte
OUT (EXTCT1),A
LD A,05H ; Select reg. 5
OUT (EXTCT1),A
LD A,(REG5) ; Transmitter logic byte
OUT (EXTCT1),A
RET
;
; Set command processor
;
SETCMD: LD C,SBLANK ; Any arguments?
CALL MEX
JP C,SETSHO ; If not, display default(s)
LD DE,CMDTBL
LD C,LOOKUP
CALL MEX ; Parse the argument
PUSH HL ; Save any parsed arguments on stack
RET NC ; If we have one, return to it
POP HL ; Oops, input not found in table
SETERR: LD DE,SETEMS
LD C,PRINT
CALL MEX
JP CRLF ; Jp = call!ret
; RET
SETEMS: DB CR,LF,'SET command error',CR,LF,'$'
;
; Argument table
;
CMDTBL: DB '?'+80H ; Help
DW SETHELP
DB 'ORI','G'+80H ; Originate mode
DW ORIG
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 'ANCHO','R'+80H ; Set to Anchor modem
DW SETANCH
DB 'MANUA','L'+80H ; Set to manual mode
DW MANUAL
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 MDMSHOW
CALL CRLF
CALL MDSHOW
CALL CRLF
CALL TPSHOW
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
JP CRLF ; JP = CALL!RET
;
; "SET ?" processor
;
SETHELP:CALL MILP
DB CR,LF,'SET ANCHOR - Set modem to respond to Anchor commands'
DB CR,LF,'SET ORIG - Set modem to Originate mode'
DB CR,LF,' (Disable auto-answer mode)'
DB CR,LF,'SET ANSWER - Set modem to auto-answer mode'
DB CR,LF,'SET TONE - Set modem for Touchtone dialing'
DB CR,LF,'SET PULSE - Set modem for Pulse dialing'
DB CR,LF,'SET DELAY - <N> seconds to wait for answer'
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 - Turn Modem monitor OFF'
DB CR,LF,'SET MONITOR - Turn Modem monitor ON'
DB CR,LF,'SET BAUD - 300, 1200, 2400, 4800, 9600, 19200'
DB CR,LF,'SET MANUAL - ORIG or ANSWER'
DB CR,LF,' Manually generate Answer or Originate '
DB 'carrier tone'
DB CR,LF,LF,0
RET
;
; SET ANCHOR processor
;
SETANCH:LD A,0FFH
LD (MODMTYP),A
LD A,041H
LD (DIALAB),A
XOR A
LD (MONFLG),A
MDMSHOW:LD A,(MODMTYP)
OR A
JR Z,MDMSHOH
CALL MILP
DB 'Anchor Modem',0
RET
MDMSHOH:CALL MILP
DB 'Hayes-compatible Smartmodem',0
RET
;
; Set manual processor
; Note: manual mode does not change the auto-answer status of the modem
;
MANUAL: LD C,SBLANK ; Check for orig <or> answer
CALL MEX ;
JP C,SETERR ; If none, print error
LD DE,MANTBL ; Check for proper syntax
LD C,LOOKUP
CALL MEX
PUSH HL ; Match found, go do it!
RET NC ;
POP HL ; No match: fix stack and
JP SETERR ; Print error
;
MANORIG:LD B,30 ; Force 3 second delay on originate end
CALL MTIME
LD HL,SMATD ; Send out 'ATD'
CALL SINIT
CALL MILP
DB CR,LF,'Manual originate mode,',CR,LF
DB 'Awaiting answer tone.'
DB CR,LF,LF,0
JR GOMAN
MANANS: LD HL,SMATA ; Send out 'ATD'
CALL SINIT
CALL MILP
DB CR,LF,'Manual answer mode, carrier tone sent',CR,LF,LF,0
JR GOMAN
;
SMATD: DB 'ATD',CR,0
SMATA: DB 'ATA',CR,0
;
GOMAN: LD B,20
CALL MTIME
CALL MILP
DB 'Enter Terminal Mode at the next command prompt',CR,LF
DB 'to check status of the connection',CR,LF,LF
DB 'To return to voice mode,',CR,LF
DB 'disconnect from terminal mode <ESC N>,',CR,LF
DB 'or from the command line <DSC>',CR,LF,LF,0
RET
;
; Manual originate / answer command table
;
MANTBL: DB 'ORI','G'+80H ; Manual originate mode
DW MANORIG
DB 'ANSWE','R'+80H ; Manual answer mode
DW MANANS
DB 0
;
; "SET BAUD" processor
;
STBAUD: LD C,BDPARS ; Function code: parse a baudrate
CALL MEX ; Let MEX look up code
JP C,SETERR ; Jump if invalid code
CALL PBAUD ; No, try to set it
JP C,SETERR ; If not one of ours, bomb out
BDSHOW: LD A,(MSPEED) ; Get current baud rate
LD C,PRBAUD ; Let MEX print it
JP MEX
; RET
;
; This routine sets baud rate passed as MSPEED code in A.
; Returns CY=1 if baud rate not supported.
;
;
;
PBAUD: PUSH HL
PUSH DE
PUSH BC
OR A
JR Z,NO$BAUD ; No speed selected
CP 10
JR NC,NO$BAUD ; Out of range
LD B,A
;
; Speed value in range, set it up
;
LD DE,BD300
DEC A
JR Z,SETBAUD ; Set 300 bps
DEC A
JR Z,NO$BAUD ; Skip 450 bps
DEC A
JR Z,NO$BAUD ; Skip 600 bps
DEC A
JR Z,NO$BAUD ; Skip 710 bps
LD DE,BD1200
DEC A
JR Z,SETBAUD ; Set 1200 bps
LD DE,BD2400
DEC A
JR Z,SETBAUD ; Set 2400 bps
LD DE,BD4800
DEC A
JR Z,SETBAUD ; Set 4800 bps
LD DE,BD9600
DEC A
JR Z,SETBAUD ; Set 9600 bps
LD DE,BD19200
DEC A
JR Z,SETBAUD ; Set 19200 bps
NO$BAUD:
SCF
JR ERR$RET
;
; Set up the baud rate requested
;
SETBAUD:
CALL SELBNK ; A=0 returns system port data
AND 0CFH ; Mask rate generator xx00xxxxb
OR E ; Selected rate
PUSH BC
LD C,A ; Return it in c
CALL SELBNK ; A<=>0 sets new rate
POP BC
LD A,4
OUT (EXTCT1),A ; Select wr4
LD A,D ; Get dart divisor, 1 stop bit
OUT (EXTCT1),A
LD A,3
OUT (EXTCT1),A ; Wr3
LD A,0C1H ; 8 bits, rx enable
OUT (EXTCT1),A
LD A,5
OUT (EXTCT1),A ; Wr5
LD A,0EAH ; Dtr, 8 bits, tx enable, rts
OUT (EXTCT1),A
LD A,B
LD (MSPEED),A
OR A ; Clear carry
;
ERR$RET:
POP BC
POP DE
POP HL
RET
;
; SELBNK routine in the ON bios gets/sets the baud rate clock
; This routine also affects the bank port and the terminal speed.
; Please don't play around with it.
;
SELBNK:
LD HL,(1) ; Bios jump table
LD L,33H ; Offset to selbnk jump
JP (HL) ; Do it, return to caller
;
; SET MODEM STATUS TO ENABLE OR DISABLE AUTO-ANSWER
;
;
SMO: DB 'ATS0=0',CR,0
SMA: DB 'ATS0=1',CR,0
ADELAY: DS 1
;
ANS: LD A,(ANSFLG) ; Already in auto-answer?
OR A
JR NZ,NOTORI ; Then no set delay stuff
CPL ; A=FFh
LD (ANSFLG),A ; Set ans flag
LD A,(NDELAY) ; Save originate mode's delay
LD (ADELAY),A
LD A,12 ; 12 seconds seems about right
CALL IDELAY ; Set delay 12
NOTORI: LD HL,SMA ; Send out ATS0=1
CALL SINIT
CALL MDSHOW ; Display mode
ANSLOO: CALL RESULT ; Poll modem
OR A ; Connect?
RET Z ; Then just return to MEX
CP 3 ; Control-C abort?
JR NZ,ANSLOO ; If not, loop
CALL DISCON ; Otherwise, hang up
; fall through
ORIG: LD A,(ANSFLG) ; Already in originate mode?
OR A
JR Z,NOTANS ; Then no set delay stuff
LD A,(ADELAY)
CALL IDELAY
XOR A
LD (ANSFLG),A ; Set orig flag
NOTANS: LD HL,SMO ; Send out ATS0=0
CALL SINIT
CALL CRLF
; fall through
MDSHOW: LD A,(ANSFLG)
OR A
JR Z,MDORIG
CALL MILP
DB CR,LF,'Auto-answer mode, ^C aborts',CR,LF,0
RET
MDORIG: CALL MILP
DB 'Originate mode, auto-answer off',CR,LF,0
RET
;
;
; Monitor control processor
;
QUIET: XOR A
LD (MONFLG),A
LD HL,SMQT
CALL SINIT
JR MONSHO
;
MONIT: LD A,0FFH
LD (MONFLG),A
LD HL,SMMON
CALL SINIT
;
MONSHO: CALL MILP
DB 'Monitor Speaker O',0
LD A,(MONFLG)
OR A
JR Z,MONOFF
CALL MILP
DB 'N',0
RET
;
MONOFF: CALL MILP
DB 'FF',0
RET
;
SMQT: DB 'ATM0',CR,0
SMMON: DB 'ATM1',CR,0
;
; Set dial processor
;
STTONE: LD B,'T'
JR SDIAL1
;
STPULSE:LD B,'P'
;
SDIAL1: LD A,(TPULSE)
CP B
JR Z,TPSHOW
LD A,B
LD (TPULSE),A
CP 'P'
LD A,01010000B ; Pulse dial
JR Z,SDIAL2
LD A,01000000B ; Tone dial
;
SDIAL2: LD (DIALWD),A
;
TPSHOW: LD A,(DIALWD)
AND 00010000B
JR Z,TPTONE
CALL MILP
DB 'Pulse Dialing',0
RET
TPTONE: CALL MILP
DB 'Touchtone Dialing',0
RET
;
; Set delay processor
;
DELAY: LD C,EVALA
CALL MEX
LD A,H
OR A
JP NZ,SETERR
LD A,L
IDELAY: LD (NDELAY),A
DLSHOW: CALL MILP
DB 'Answer Delay is ',0
LD A,(NDELAY)
LD L,A
LD H,0
LD C,DECOUT
CALL MEX
CALL MILP
DB ' seconds',0
RET
;
; SET PARITY command: reset transmit/receive parity
;
; Parity is controlled by bits 0 and 1 of
; the byte sent to the SIO write-register
; 4 as follows:
;
; Parity Bit 1 Bit 0
; Off - 0
; Odd 0 1
; Even 1 1
;
STPRTY: LD C,SBLANK ; Check for parity code
CALL MEX ;
JP C,SETERR ; If none, print error
LD DE,PARTBL ; Check for proper syntax
LD C,LOOKUP
CALL MEX
PUSH HL ; Match found, go do it!
RET NC ;
POP HL ; No match: fix stack and
JP SETERR ; Print error
;
PROFF: LD A,(REG4) ; Get register 4 byte
AND 0FEH ; Reset bit 0
JR PARTB1 ;
PREVEN: LD A,(REG4) ;
OR 003H ; Set bits 0 & 1
JR PARTB1 ;
PRODD: LD A,(REG4) ;
OR 001H ; Set bit 0
AND 0FDH ; Reset bit 1
PARTB1: LD (REG4),A ;
CALL NITSIO ; Re-initialize the usart
; FALL THRU ; To SHPRTY
; CALL SHPRTY ; Print the result
; RET ;
SHPRTY: CALL MILP ; Display parity
DB 'Parity: ',TAB,' ',0
LD A,(REG4) ;
AND 001H ; Test bit 0
OR A ; If bit0=0 then parity off
JR NZ,SHPRT1 ;
CALL MILP ;
DB 'Off',0 ;
RET
SHPRT1: LD A,(REG4) ;
AND 002H ; Test bit 1
OR A ; If bit1=0 then parity odd
JR NZ,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
; 2 and 3 of the byte sent to the SIO write-
; register 4, as follows:
;
; Stop bits Bit 3 Bit 2
; 1 0 1
; 1.5 1 0
; 2 1 1
;
;
STSTOP: LD C,SBLANK ; Check for stop bits
CALL MEX ;
JP C,SETERR ; If none, print error
LD DE,STPTBL ; Check for proper syntax
LD C,LOOKUP
CALL MEX ;
PUSH HL ; Match found, go do it!
RET NC ;
POP HL ; No match: fix stack and
JP SETERR ; Print error
;
STOP01: LD A,(REG4) ; Get register 4 byte
AND 0F7H ; Reset bit 3
OR 004H ; Set bit 2
JR STSTP1 ;
STOP02: LD A,(REG4) ;
OR 00CH ; Set bits 2 and 3
JR STSTP1 ;
STOP15: LD A,(REG4) ;
OR 008H ; Set bit 3
AND 0FBH ; Reset bit 2
STSTP1: LD (REG4),A ;
CALL NITSIO ;
; FALL THRU ; To SHSTOP
; CALL SHSTOP ; Print the result
; RET ;
SHSTOP: CALL MILP ; Display stop-bits
DB 'Stop bits:',TAB,' ',0
LD A,(REG4) ;
AND 004H ; Test bit 2
OR A ; If bit2=0 then 1.5
JR NZ,SHSTP1 ;
CALL MILP ;
DB '1.5',0 ;
RET
SHSTP1: LD A,(REG4) ;
AND 008H ; Test bit 3
OR A ; If bit3=0 then 1
JR NZ,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 for
; the receiver circuit by bits 6 and 7 of the byte
; sent to the SIO write-register 3 and for the trans-
; mitter circuit by bits 5 and 6 of the byte sent to
; the SIO write-register 5. The assumption has been
; made here that both transmission and reception will
; be carried on at the same number of bits per charac-
; ter. The bit configurations are shown for register
; 3 only, but are the same for register 5:
;
; BPC Bit 7 Bit 6
; 5 0 0
; 6 1 0
; 7 0 1
; 8 1 1
;
STBITS: LD C,SBLANK ; Check for bits/char
CALL MEX ;
JP C,SETERR ; If none, print error
LD DE,BITTBL ; Check for proper syntax
LD C,LOOKUP
CALL MEX
PUSH HL ; Match found, go do it!
RET NC ;
POP HL ; No match: fix stack and
JP SETERR ; Print error
;
BIT5: LD A,(REG3) ;
AND 0BFH ; Reset bit 6
AND 07FH ; Reset bit 7
LD (REG3),A ;
LD A,(REG5) ;
AND 0DFH ; Reset bit 5
AND 0BFH ; Reset bit 6
JR STBTS1 ;
BIT6: LD A,(REG3) ;
AND 0BFH ; Reset bit 6
OR 080H ; Set bit 7
LD (REG3),A ;
LD A,(REG5) ;
AND 0DFH ; Reset bit 5
OR 040H ; Set bit 6
JR STBTS1 ;
BIT7: LD A,(REG3) ;
OR 040H ; Set bit 6
AND 07FH ; Reset bit 7
LD (REG3),A ;
LD A,(REG5) ;
OR 020H ; Set bit 5
AND 0BFH ; Reset bit 6
JR STBTS1 ;
BIT8: LD A,(REG3) ;
OR 040H ; Set bit 6
OR 080H ; Set bit 7
LD (REG3),A ;
LD A,(REG5) ;
OR 020H ; Set bit 5
OR 040H ; Set bit 6
STBTS1: LD (REG5),A ;
CALL NITSIO ;
; FALL THRU ; To SHBITS
SHBITS: CALL MILP ; Display bits/char
DB 'Bits/char:',TAB,' ',0
LD A,(REG5) ;
AND 040H ; Test bit 6
OR A ; If bit6=0 then 6 bpc
JR NZ,SHBTS2 ;
LD A,(REG5) ;
AND 020H ; Test bit 5
OR A ; If bit5=0 then 5 bpc
JR NZ,SHBTS1 ;
CALL MILP ;
DB '5',0 ;
RET ;
SHBTS1: CALL MILP ;
DB '7',0 ;
RET ;
SHBTS2: LD A,(REG5) ;
AND 020H ; Test bit 5
OR A ; If bit5=0 then 6 bpc
JR NZ,SHBTS3 ;
CALL MILP ;
DB '6',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
;
; Smartmodem dialing routine from Ron Fowler's MXO-SM10.ASM
;
DIAL: LD HL,(DIALPT) ; Fetch pointer
CP 254 ; Start dial?
JR Z,STDIAL ; Jump if so
CP 255 ; End dial?
JR Z,ENDIAL ; Jump if so
;
; Not start or end sequence, must be a digit to be sent to the modem
;
LD (HL),A ; Put char in buffer
INC HL ; Advance pointer
LD (DIALPT),HL ; Stuff pntr
RET ; All done
;
; Here on a start-dial sequence
;
STDIAL: LD HL,DIALBF ; Set up buffer pointer
LD (DIALPT),HL
RET
;
; Here on an end-dial sequence
;
ENDIAL:
;
IF SILENT
LD A,(MONFLG) ; Check monitor speaker flag
OR A ; To see if on or off
JR Z,LEAVOFF ; If off, leave it off
LD (HL),'M' ; If we silenced speaker to dial,
INC HL ; Turn it on again
LD (HL),'1'
INC HL
LEAVOFF:
ENDIF
;
LD (HL),CR ; Stuff end-of-line into buffer
INC HL ; Followed by terminator
LD (HL),0
LD A,(TPULSE) ; Get overlay's touch-tone flag
;
IF SILENT
LD (SMDIAL+5),A
ENDIF
;
IF NOT SILENT
LD (SMDIAL+3),A ; Put into string
ENDIF
;
LD HL,SMDIAL ; Point to dialing string
CALL SMSEND ; Send it
;
WAITSM: LD C,INMDM
CALL MEX ; Catch any output from the modem
JR NC,WAITSM ; Loop until no more characters
;
; THE FOLLOWING LOOP WAITS FOR A RESULT FROM THE MODEM.
;
RESULT: LD A,(NDELAY) ; Get delay count
LD C,A
SMWLP: PUSH BC
LD B,1 ; Check for a char, up to 1 sec wait
LD C,TMDINP ; Do timed input
CALL MEX
POP BC
JR NC,SMTEST ; Jump if modem had a char
PUSH BC ; No, test for control-c from console
LD C,DCONIO
LD E,DCONIN ; Use BDOS direct console input function
CALL BDOS
POP BC
CP 'C'-40H ; ^C?
JR NZ,SMNEXT ; If not, jump
LD A,(DIALAB) ; Quit dialing
LD B,A
LD C,SNDCHR
CALL MEX
CALL INCTL1 ; See if modem is connected, i.e., returning
AND 08H ; To active modem from CPM
CALL Z,SMDMOFF ; No carrier, so shut down modem
LD A,3 ; Return abort code
RET
SMNEXT: OR A ; Any other key
JR NZ,SMTIMO ; Yes, treat like timeout
DEC C ; No
JR NZ,SMWLP ; Continue
;
; NO MODEM RESPONSE WITHIN THE TIME SPECIFIED IN SET DELAY COMMAND
;
SMTIMO: LD A,(DIALAB)
LD B,A
LD C,SNDCHR
CALL MEX
CALL INCTL1 ; See if modem is connected, i.e., returning
AND 08H ; To active modem from CPM
CALL Z,SMDMOFF ; Shut down modem if we're not on pc pursuit
LD A,2 ; Return timeout code
RET
;
; MODEM GAVE US A RESULT, CHECK IT
;
SMTEST: AND 7FH ; Ignore any parity
CALL SMANAL ; Test the result
JR C,RESULT ; Go try again if unknown response
LD A,B ; A=result
PUSH AF ; Save it
SMTLP: LD C,INMDM ; Eat any additional chars from smartmodem
CALL MEX
JR NC,SMTLP ; Until 100ms of quiet time
POP AF ; Return the code
RET
;
; Analyze character returned from External Modem
;
SMANAL: PUSH AF
LD A,(MODMTYP)
OR A
JR Z,SMANALH
;
; Analyze Modem response codes for Anchor modems.
; Anchor echoes the digits as they are being dialed. The returned digits
; are interpreted as call return codes, shutting down the modem too early.
;
SMANALA:POP AF
LD B,0 ; Prep connect code
CP 'C' ; "connect"?
RET Z
INC B ; Prep busy code B=1
CP 'B'
RET Z
INC B ; Prep no connect msg B=2
CP 'N' ; N=no connect
RET Z
LD B,4 ; Prep modem error
CP 'E' ; E=error
RET Z
JR WTLF
;
; Analyze Modem response codes for Hayes, etc.
;
SMANALH:POP AF
LD B,0 ; Prep connect code
CP 'C' ; "connect"?
RET Z
CP '1' ; Numeric version of "CONNECT"
RET Z
CP '5' ; Numeric version of "CONNECT 1200"
RET Z
INC B ; Prep busy code B=1
CP 'B'
JR NZ,NOBUSY ; Not busy, check for no answer
PUSH BC ; Otherwise, save return code
LD B,5 ; Wait 1/2 second
CALL MTIME
LD A,(DIALAB) ; Abort possible firmware re-dial
LD B,A
LD C,SNDCHR
CALL MEX
POP BC ; Get back return code
XOR A ; Clear carry, return
RET
NOBUSY: INC B ; Prep no connect msg B=2
CP 'N' ; N=no connect
RET Z
CP '3' ; Numeric version of "NO CONNECT"
RET Z
LD B,4 ; Prep modem error
CP 'E' ; E=error
RET Z
CP '4' ; Numeric version of "ERROR"
RET Z
;
; UNKNOWN RESPONSE, RETURN CARRY TO CALLER. BUT FIRST,
; FLUSH THE UNKNOWN RESPONSE LINE FROM THE MODEM.
;
WTLF: CP LF ; Linefeed?
SCF
RET Z ; End if so
LD C,INMDM ; No. get next char
CALL MEX
JR NC,WTLF ; Unless busy, loop
RET
;
; Send string to the External Modem
;
SMSEND: LD C,SNDRDY ; Wait for modem ready
CALL MEX
JR NZ,SMSEND
LD A,(HL) ; Fetch next character
INC HL
OR A ; End?
RET Z ; Done if so
LD B,A ; No, position for sending
LD C,SNDCHR ; Nope, send the character
CALL MEX
JR SMSEND
;
; Shut down (disconnect) External Modem
;
SMDMOFF:LD B,20 ; Two second wait to settle down
CALL MTIME
LD A,(MODMTYP) ; Test modem type
OR A
CALL Z,DISCON ; If Hayes type, do DTR disconnect
RET ; If Anchor, just return
;
; General utility routines
;
CRLF: CALL MILP ; Print carriage return, line feed
DB CR,LF,0
RET
;
MILP: LD C,ILP ; In-line print
JP MEX
;
MTIME: LD C,TIMER ; MEX timer
JP MEX
;
;
;==========================================================================
; Data Area
;==========================================================================
;
; Default UART parameters (Initalized for External RS-232)
;
REG0: DB 00011000B ; Reset channel A
REG3: DB 11000001B ; Enable receive at 8 bits/char
REG4: DB 01000100B ; No parity, 1 stop bit, clock x16
REG5: DB 11101010B ; Enable transmit at 8 bits/char
;
; Miscellaneous Default Data
;
SMDIAL: DB 'AT'
;
IF SILENT
DB 'M0' ; Turn off speaker during dialing
ENDIF
;
DB 'DT' ; 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 external modem mspeed
MONFLG: DB 0FFH ; 0: monitor off - 0ffh: monitor on
ANSFLG: DB 0 ; 0: originate - 0ffh: answer
NDELAY: DB 30 ; No. seconds for answer
MODMTYP:DB 0 ; 0=Hayes, etc., - 0ffh=Anchor modem
DIALAB: DB CR ; Character to use to abort dial sequence
;
SMATN: DB '+++',0 ; Smartmodem online 'attention'
SMDISC: DB 'ATH',CR,0 ; Smartmodem disconnect (used by Anchor)
SMINIT: DB 'ATM1 S0=0 S7=60 Q0 X1',CR,0 ; Modem init string
;
EOSMSG: DB 1BH,'Y$' ; Clear to end-of-screen
CLSMSG: DB 1BH,'+$' ; Clear whole screen
END