home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
mex
/
mxo-ax11.azm
/
MXO-AX11.ASM
Wrap
Assembly Source File
|
1987-02-08
|
35KB
|
1,402 lines
;==========================================================================
;
; MXO-AX10.ASM
;
; This file is an extended and upgraded version of the MEX overlay
; MXO-KP30.ASM designed for use with MEX10.COM, the Modem EXecutive
; communications program and the Actrix computer.
;
; To use: Check carefully through the following equates and defines
; to make sure the various options are set to your particular in-
; stallation requirements and personal tastes. This file may be
; modified with any word processor such as ED or WordStar. Once all
; desired modifications have been entered, the .ASM file must be
; assembled to a .HEX file using ASM, LINKASM, or the MAC assembler.
; Use the MLOAD program distributed with MEX10 to generate a working
; copy of MEX as follows:
;
; MLOAD MEXNEW.COM=MEX10.COM,MXO-KP30.HEX
;
;
REV EQU 11 ;overlay revision level
;
;==========================================================================
;
; Ver AX1.1 Added capability to use NEW 300+ internal modem
; board that will operate at 300/1200 baud.
;
; Ver AX1.0 Converted from the KayPro II overlay to Axtrix
; computer. Designed to use either port J5 or J6
; for external modem. Has either Hayes SmartModem
; or Ven-Tel modem protocols for dialling.
; Modified 03/09/84 by Bill Rink
;
; Ver KP3.0 Combined the primarily modem-oriented commands
; from the Smith-Quinn MXO-KP25 with the SIO-
; oriented commands from the Saunders MXO-KP14
; overlay -- 7/23/84 (Norm Saunders)
;
; Ver KP1.4 Tightened the code a bit more and added the
; code to automatically print the revision number
; from the variable REV -- 6/26/84 (Norm Saunders)
;
; Ver KP1.3 Fixed a bug in the SHDLY subroutine and added
; code for automatic initialization of the
; modem if it's a Hayes. Also added Mark Pulver's
; fix to the Hayes SMANAL subroutine -- 6/2/84
; (Norm Saunders)
;
; Ver KP1.2 Fixed a minor bug in the 'set bits' command,
; tightened up the code in the 'set baud' command,
; and incorporated Ver 1.1 of the Hayes Smart-
; modem overlay -- 5/24/84 (Norm Saunders)
;
; Ver KP1.1 Implemented the PBAUD; vector, added an expanded
; SET command, and incorporated the Hayes Smart-
; modem overlay with conditional assembly commands
; -- 5/19/84 (Norm Saunders)
;
; Ver KP1.0 Translated M7KP-1.ASM to conform to the mnemonics
; and service processor calls of MEX10 -- 5/7/84
; (Norm Saunders)
;
;==========================================================================
;
; Miscellaneous equates
;
BELL EQU 07H ;bell
CR EQU 0DH ;carriage return
ESC EQU 1BH ;escape
LF EQU 0AH ;linefeed
TAB EQU 09H ;tab
NO EQU 0 ;
YES EQU 0FFH ;
FALSE EQU 0 ;
TRUE EQU NOT FALSE ;
TPA EQU 0100H ;
MEXLOC EQU 0D00H ;start of MEX service processor
BDOS EQU 05H ;BDOS call
;
; Actrix port definitions
;
PORT1 EQU 040H ;Base serial input/output port J5
MODCTL1 EQU PORT1+2 ;Modem control port
MODDAT1 EQU PORT1 ;Modem data port
BAUD1 EQU 5 ;SET BUAD RATE FOR PORT J5
;
PORT2 EQU 041H ;Base serial input/output port J6
MODCTL2 EQU PORT2+2 ;Modem control port
MODDAT2 EQU PORT2 ;Modem data port
BAUD2 EQU 6 ;SET BUAD RATE FOR PORT J6
;
; Actrix bit definitions
;
MDRCVB EQU 01H ;Your bit to test for receive
MDRCVR EQU 01H ;Your value when receive ready
MDSNDB EQU 04H ;Your bit to test for send
MDSNDR EQU 04H ;Your value when send ready
;
; MEX service processor functions
;
MEX EQU MEXLOC ;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
;
; Smart Modem Definition Flags
;
HAYES EQU FALSE ;set if a Hayes smartmodem is used
VENTEL EQU TRUE ;set if Ven-Tel smartmodem is used
;
ORG TPA
;
DS 3 ;(for "JMP START" instruction)
;
; The following variables are located at the beginning of the program
; to facilitate modification without the need of re-assembly. They will
; be moved in MEX 2.0.
;
SMODEM: DW TRUE ;true= smartmodem, false=non-dialing 103H
TPULSE: DB 'T' ;T=touch, P=pulse (Smartmodem-only) 105H
CLOCK: DB 40 ;clock speed in MHz x10, 25.5 MHz max. 106H
;20=2 MHh, 37=3.68 MHz, 40=4 MHz, etc.
MSPEED: DB 5 ;0=110 1=300 2=450 3=600 4=710 5=1200 107H
;6=2400 7=4800 8=19200 default display
;time for sending a file
BYTDLY: DB 1 ;0=0 delay 1=10ms 5=50 ms - 9=90 ms 108H
;default time to send character in ter-
;minal mode file transfer for slow BBS.
CRDLY: DB 9 ;0=0 delay 1=100 ms 5=500 ms - 9=900 ms 109H
;default time for extra wait after CRLF
;in terminal mode file transfer
COLUMS: DB 5 ;number of DIR columns shown 10AH
SETFL: DB YES ;yes=user-added SET command 10BH
SCRTST: DB YES ;yes=user-added cursor control routine 10CH
DB 0 ;spare (replaces ACKNAK) 10DH
BAKFLG: DB NO ;yes=change any file same name to .BAK 10EH
CRCDFL: DB YES ;yes=default to CRC checking 10FH
TOGCRC: DB YES ;yes=allow toggling of CRC to Checksum 110H
CVTBS: DB NO ;yes=convert backspace to rub 111H
TOGLBK: DB YES ;yes=allow toggling of bksp to rub 112H
ADDLF: DB NO ;no=no LF after CR to send file in 113H
;terminal mode (added by remote echo)
TOGLF: DB YES ;yes=allow toggling of LF after CR 114H
TRNLOG: DB NO ;yes=allow transmission of logon 115H
;write logon sequence at location LOGON
SAVCCP: DB YES ;yes=do not overwrite CCP 116H
LOCNXT: DB NO ;yes=local command if EXTCHR precedes 117H
;no=external command if EXTCHR precedes
TOGLOC: DB YES ;yes=allow toggling of LOCNXT 118H
LSTTST: DB YES ;yes=printer available on printer port 119H
XOFTST: DB NO ;yes=chcks for XOFF from remote while 11AH
;sending a file in terminal mode
XONWT: DB NO ;yes=wait for XON after CR while 11BH
;sending a file in terminal mode
TOGXOF: DB YES ;yes=allow toggling of XOFF checking 11CH
IGNCTL: DB YES ;yes=CTL-chars above ^M not displayed 11DH
EXTRA1: DB 0 ;for future expansion 11EH
EXTRA2: DB 0 ;for future expansion 11FH
;
CTLPORT DB MODCTL2 ; init for J6 port 120H
DATPORT DB MODDAT2 ; 121H
BAUDPT DB BAUD2 ; 122H
INTERN DB NO ; set modem to external use 123
DS 6
;
; Low-level modem I/O routines
;
INCTRL: JMP INSTAT ;read USART status 12AH
DS 7 ;
OTDATA: JMP OUTDAT ;out modem data port 134H
DS 7 ;
INPORT: JMP INDAT ;in modem data port 13EH
DS 7 ;
;
; Bit-test routines
;
MASKR: ANI MDRCVB ! RET ;bit to test for receive ready 148H
TESTR: CPI MDRCVR ! RET ;value of receive bit when rdy 14BH
MASKS: ANI MDSNDB ! RET ;bit to test for send ready 14EH
TESTS: CPI MDSNDR ! RET ;value of send bit when ready 151H
DS 12 ;
;
; MEX10 vector to overlay-provided functions
;
LOGON: DS 2 ;not implemented in MEX 160H
;
IF NOT SMODEM
DIALV: DS 3 ;dummied out for non-dialing 162H
DISCV: DS 3 ;modems 165H
GOODBV: JMP GDBY ;disconnect 212-type modems 168H
ENDIF
;
IF SMODEM
DIALV: JMP DIAL ;Hayes dialing routine 162H
DISCV: JMP DISCON ;Hayes disconnect routine 165H
GOODBV: JMP GDBY ; 168H
ENDIF
;
INMODV: JMP NITMOD ;UART initialization 16BH
NEWBDV: JMP PBAUD ;Reset baud rate from library 16EH
NOPARV: RET ! NOP ! NOP ;(by-passes PMMI routine) 171H
PARITV: RET ! NOP ! NOP ;(by-passes PMMI routine) 174H
SETUPV: JMP SETCMD ;Actrix SET command 177H
SPMENV: DS 3 ;not implemented in MEX 17AH
VERSNV: JMP SYSVER ;print signon message 17DH
BREAKV: JMP BREAK ;send a break tone 180H
;
; The following jump vector provides the overlay with access to special
; routines in MEX10 provided to maintain compatibility with MDM7 over-
; lays. It is recommended that these routines be avoided as they will
; disappear in future versions of MEX.
;
ILPRTV: DS 3 ;replaced with MEX function 9 183H
INBUFV: DS 3 ;replaced with MEX function 10 186H
ILCMPV: DS 3 ;replaced with table lookup fnc 247 189H
INMDMV: DS 3 ;replaced with MEX function 255 18CH
NXSCRV: DS 3 ;not supported by MEX 18FH
TIMERV: DS 3 ;replaced with MEX function 254 192H
;
; Clear-screen and clear-to-end-of-screen functions
;
SCRN1: JMP CLREOS ;clear to end of screen 195H
DS 6 ; 198H
;
SCRN2: JMP CLS ;clear screen, home cursor 19EH
DS 6 ; 1A1H
;
;---------------------------------------------------------------------------
;
; *** End of fixed format area ***
;
;---------------------------------------------------------------------------
;
; Modem I/O routines
;
INSTAT: PUSH B
LDA CTLPORT
MOV C,A
MVI A,10H ;channel 0, reset interrupts.
DB 0EDH,79H ;OUT MODCTL
DB 0EDH,78H ;IN MODCTL, get the status bits
POP B
RET ;
OUTDAT: PUSH B
MOV B,A ;SAVE OUTPUT CHAR
LDA DATPORT
MOV C,A
MOV A,B ;RETURN
DB 0EDH,79H ;OUT MODDAT, out modem data port
POP B
RET ;
INDAT: PUSH B
LDA DATPORT
MOV C,A
DB 0EDH,78H ;IN MODDAT, in modem data port
POP B
RET ;
;
; Screen-handling routines
;
CLREOS: LXI D,EOSMSG ;
MVI C,PRINT ;
CALL MEX ;
RET ;
;
CLS: LXI D,CLSMSG ;
MVI C,PRINT ;
CALL MEX ;
RET ;
;
; Print system version message
;
SYSVER: CALL ILPRT ;
DB CR,LF,'Custom Actrix Overlay -- Ver. '
DB REV/10+'0'
DB '.'
DB REV MOD 10 + '0'
DB CR,LF
DB '(type SET for Set Command syntax)',CR,LF,LF,0
RET
;
; Put Internal Modem OFFHOOK
OFFHK: LDA MSPEED
CPI 1
JZ OFF300
MVI A,0B0H
JMP OFFMDM
OFF300: MVI A,0BAH
OFFMDM: CALL CTLOUT
LDA CTLPORT
MOV C,A
MVI A,5 ;select SIO write-register 5
DB 0EDH,79H ;OUT MODCTL ;
LDA REG5 ;get the register 5 control byte
ORI 80H ;set bit 7 (pulls DTR high)
JMP GDBY1
;
; Send BREAK function
;
BREAK: LDA CTLPORT
MOV C,A
MVI A,5 ;select SIO register 5
DB 0EDH,79H ;OUT MODCTL
LDA REG5 ;get the register 5 control byte
ORI 010H ;set bit 4 (sends a break signal)
;
JMP GDBY1
;
; Set DTR low for 300ms (disconnects some modems)
;
GDBY: LDA INTERN
ORA A
JZ GDBY1
LDA CTLPORT
MOV C,A
MVI A,5 ;select SIO write-register 5
DB 0EDH,79H ;OUT MODCTL ;
LDA REG5 ;get the register 5 control byte
ANI 07FH ;reset bit 7 (pulls DTR low)
;
GDBY1: DB 0EDH,79H ;OUT MODCTL
MVI B,3 ;Delay 300 ms.
MVI C,TIMER
CALL MEX
LDA INTERN
ORA A
JNZ GDBY2
LDA CTLPORT
MOV C,A
MVI A,5
DB 0EDH,79H ;OUT MODCTL
LDA REG5 ;Restore to normal
DB 0EDH,79H ;OUT MODCTL
GDBY2: RET
;
; Actrix initialization routines
;
NITMOD: CALL NTBAUD ;initialize the baud rate
;
IF SMODEM
CALL NITMDM ;initialize the smartmodem
ENDIF
;
RET ;
;
; Initialize the Zilog SIO chip
;
NITSIO: LDA CTLPORT
MOV C,A
MVI A,00H ;Select reg. 0
DB 0EDH,79H ;OUT MODCTL
LDA REG0 ;Command byte
DB 0EDH,79H ;OUT MODCTL
MVI A,04H ;Select reg. 4
DB 0EDH,79H ;OUT MODCTL
LDA REG4 ;Receive/transmit control byte
ANI 3FH ;reset bit 7 and 6
ORI 40H ;set bit 6
MOV B,A ;save reg. 4
LDA MSPEED ;get modem speed
CPI 1 ;300 BAUD
MOV A,B ;restore A
JNZ NITCTL
ORI 0C0H ;set bit 7 and 6
NITCTL: STA REG4
DB 0EDH,79H ;OUT MODCTL
MVI A,03H ;Select reg. 3
DB 0EDH,79H ;OUT MODCTL
LDA REG3 ;Receiver logic byte
DB 0EDH,79H ;OUT MODCTL
MVI A,05H ;Select reg. 5
DB 0EDH,79H ;OUT MODCTL
LDA INTERN
ORA A
LDA REG5 ;Transmitter logic byte
JNZ NITEXT
ORI 80H
NITEXT: DB 0EDH,79H ;OUT MODCTL
RET
;
; Wait for Dial Tone (Internal Modem)
;
WAITON: MVI B,10 ;WAIT 1 SEC FOR TONE
MVI C,TIMER
CALL MEX
LDA 10H
OUT 43H
IN 43H
ANI 20H ;GOT A DIAL TONE?
RET
;
; Control Bits out to Internal Modem
;
CTLOUT: OUT 30H
IN 21H
ORI 20H ;STROBE DATE OUT
OUT 21H
ANI 0DFH
OUT 21H
RET
;
; Initialize the baudrate generator
;
NTBAUD: LDA MSPEED ;get the speed code
CALL PBAUD ;go set it
RET
;
; Initialize the modem
;
IF SMODEM
NITMDM: CALL SHPORT
IF HAYES
CALL STSPK1 ;
CALL CRLF ;
CALL STDL15 ;
CALL CRLF ;
CALL STMOD1 ;
CALL CRLF ;
CALL SHDIAL ;
CALL CRLF ;
ENDIF
CALL SHBAUD ;
CALL CRLF ;
RET ;
;
; Send a string to the modem
;
MDMSET: CALL SMSEND ;send a string to the modem
NITMD1: MVI C,INMDM ;eat all feedback from the modem
CALL MEX ;
JNC NITMD1 ;
RET ;
ENDIF
;
; Actrix SET command processor
;
SETCMD: MVI C,SBLANK ;check for SET arguments
CALL MEX ;
JC SETHLP ;if none, print help message
LXI D,CMDTBL ;parse the command
CALL TSRCH ;
PUSH H ;put returned address on stack
RNC ;go there if table match found
POP H ;if no match, fix the stack and
SETERR: LXI D,SETEMS ;print an error message
MVI C,PRINT ;
CALL MEX ;
RET ;
;
; SET <no arguments>: print help message
;
SETHLP: LXI D,HLPMSG ;
MVI C,PRINT ;
CALL MEX ;
RET ;
;
HLPMSG: DB CR,LF,'SET command - Actrix version:',CR,LF,LF
DB CR,LF,'SET BAUD <300> <600> <1200> <2400>'
DB ' <4800> <9600>'
DB CR,LF,'SET PARITY <OFF> <EVEN> <ODD>'
DB CR,LF,'SET STOPBITS <1> <1.5> <2>'
DB CR,LF,'SET LENGTH <5> <6> <7> <8>'
DB CR,LF,'SET PORT <J5> <J6>'
DB CR,LF,'SET MODEM <EXT> <INT>'
;
IF HAYES
DB CR,LF,'SET MONITOR ON <or> OFF'
DB CR,LF,'SET DELAY 15 <or> 30 <or> 45 <or> 60'
DB CR,LF,'SET MODE ORIG <or> ANSWER'
DB CR,LF,'SET DIAL PULSE <or> TONE'
ENDIF
;
DB CR,LF,LF,'SET ? (show current settings)'
DB CR,LF,'$'
;
; SET BAUD command: reset the baudrate generator
;
STBAUD: MVI C,SBLANK ;check for baudrate
CALL MEX ;
JC SETERR ;if none, print error message
LXI D,BDTBL ;check for acceptable rate
CALL TSRCH ;
JC SETERR ;if no match, print error
MOV A,L ;get file speed parameter
CALL PBAUD ;set the baudrate
CALL SHBAUD ;show the baud rate
JMP CRLF
SHBAUD: CALL ILPRT ;display current baudrate
DB 'Baud rate:',TAB,' ',0
LDA MSPEED
MVI C,PRBAUD
JMP MEX
;
; Set the baud rate from the MSPEED code in reg. A
; CY set if the specified rate is unsupported
;
PBAUD: PUSH H ;save all the registers
PUSH D ;
PUSH B ;
PUSH PSW ;
MVI E,1BH ;send ESCAPE code to monitor
MVI C,6 ;do a direct conout
CALL BDOS ;
MVI E,0F0H ;send SET BAUD RATE code to monitor
MVI C,6 ;do a direct conout
CALL BDOS ;
LDA BAUDPT ;GET CURRENT BUAD PORT
MOV E,A ;OUTPUT TO PROPER PORT
MVI C,6 ;do a direct conout
CALL BDOS ;
POP PSW ;restore Areg
MOV E,A ;put MSPEED in DE
MVI D,0 ;
LXI H,BDTBL2 ;offset into the table
DAD D ;
MOV A,M ;get the baud-generator code
ORA A ; test for zero value
JZ PBAUD2 ; EXIT if so
PUSH D ; SAVE E
MOV E,A ;output the baud rate
MVI C,6 ;do a direct conout
CALL BDOS ;
POP D ;
MOV A,E ;get MSPEED code back
STA MSPEED ;save it
ORA A ;return, no errors
PBAUD1:
POP B ;
POP D ;
POP H ;
CALL NITSIO ;reset SIO
RET ;
PBAUD2: MVI A,28H ;put out a standard baud rate
MOV E,A ;output the baud rate
MVI C,6 ;do a direct conout
CALL BDOS ;
CTC ; If Error
JP PBAUD1
;
; SET ? command: show all current settings
;
STSHOW: CALL CRLF ;
LXI H,SHOTBL ;get table of SHOW routines
STSHW1: MOV E,M ;get address of a routine
INX H ;
MOV D,M ;
INX H ;
MOV A,D ;
ORA E ;end of table?
RZ ;if yes, we're done
PUSH H ;save the table pointer
XCHG ;put address in HL
CALL GOHL ;go do it!
CALL CRLF ;print newline
MVI C,CHEKCC ;console abort?
CALL MEX ;
POP H ;
JNZ STSHW1 ;if no abort then continue
RET ;
;
GOHL: PCHL ;
;
; 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: MVI C,SBLANK ;check for parity code
CALL MEX ;
JC SETERR ;if none, print error
LXI D,PARTBL ;check for proper syntax
CALL TSRCH ;
PUSH H ;match found, go do it!
RNC ;
POP H ;no match: fix stack and
JMP SETERR ; print error
;
PROFF: LDA REG4 ;get register 4 byte
ANI 0FEH ;reset bit 0
JMP PARTB1 ;
PREVEN: LDA REG4 ;
ORI 003H ;set bits 0 & 1
JMP PARTB1 ;
PRODD: LDA REG4 ;
ORI 001H ;set bit 0
ANI 0FDH ;reset bit 1
PARTB1: STA REG4 ;
CALL NITSIO ;re-initialize the USART
CALL SHPRTY ;print the result
JMP CRLF ;
SHPRTY: CALL ILPRT ;display parity
DB 'Parity: ',TAB,' ',0
LDA REG4 ;
ANI 001H ;test bit 0
CPI 0 ;if bit0=0 then parity off
JNZ SHPRT1 ;
CALL ILPRT ;
DB 'Off',0 ;
RET
SHPRT1: LDA REG4 ;
ANI 002H ;test bit 1
CPI 0 ;if bit1=0 then parity odd
JNZ SHPRT2 ;
CALL ILPRT ;
DB 'Odd',0 ;
RET ;
SHPRT2: CALL ILPRT ;
DB 'Even',0 ;
RET
;
; 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: MVI C,SBLANK ;check for stop bits
CALL MEX ;
JC SETERR ;if none, print error
LXI D,STPTBL ;check for proper syntax
CALL TSRCH ;
PUSH H ;match found, go do it!
RNC ;
POP H ;no match: fix stack and
JMP SETERR ; print error
;
STOP01: LDA REG4 ;get register 4 byte
ANI 0F7H ;reset bit 3
ORI 004H ;set bit 2
JMP STSTP1 ;
STOP02: LDA REG4 ;
ORI 00CH ;set bits 2 and 3
JMP STSTP1 ;
STOP15: LDA REG4 ;
ORI 008H ;set bit 3
ANI 0F8H ;reset bit 2
STSTP1: STA REG4 ;
CALL NITSIO ;
CALL SHSTOP ;print the result
JMP CRLF ;
SHSTOP: CALL ILPRT ;display stop-bits
DB 'Stop bits:',TAB,' ',0
LDA REG4 ;
ANI 004H ;test bit 2
CPI 0 ;if bit2=0 then 1.5
JNZ SHSTP1 ;
CALL ILPRT ;
DB '1.5',0 ;
RET
SHSTP1: LDA REG4 ;
ANI 008H ;test bit 3
CPI 0 ;if bit3=0 then 1
JNZ SHSTP2 ;
CALL ILPRT ;
DB '1',0 ;
RET
SHSTP2: CALL ILPRT ;
DB '2',0 ;
RET
;
; 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: MVI C,SBLANK ;check for bits/char
CALL MEX ;
JC SETERR ;if none, print error
LXI D,BITTBL ;check for proper syntax
CALL TSRCH ;
PUSH H ;match found, go do it!
RNC ;
POP H ;no match: fix stack and
JMP SETERR ; print error
;
BIT5: LDA REG3 ;
ANI 0BFH ;reset bit 6
ANI 07FH ;reset bit 7
STA REG3 ;
LDA REG5 ;
ANI 0DFH ;reset bit 5
ANI 0BFH ;reset bit 6
JMP STBTS1 ;
BIT6: LDA REG3 ;
ANI 0BFH ;reset bit 6
ORI 080H ;set bit 7
STA REG3 ;
LDA REG5 ;
ANI 0DFH ;reset bit 5
ORI 040H ;set bit 6
JMP STBTS1 ;
BIT7: LDA REG3 ;
ORI 040H ;set bit 6
ANI 07FH ;reset bit 7
STA REG3 ;
LDA REG5 ;
ORI 020H ;set bit 5
ANI 0BFH ;reset bit 6
JMP STBTS1 ;
BIT8: LDA REG3 ;
ORI 040H ;set bit 6
ORI 080H ;set bit 7
STA REG3 ;
LDA REG5 ;
ORI 020H ;set bit 5
ORI 040H ;set bit 6
STBTS1: STA REG5 ;
CALL NITSIO ;
CALL SHBITS ;print the result
JMP CRLF
SHBITS: CALL ILPRT ;display bits/char
DB 'Bits/char:',TAB,' ',0
LDA REG5 ;
ANI 040H ;test bit 6
CPI 0 ;if bit6=0 then 6 bpc
JNZ SHBTS2 ;
LDA REG5 ;
ANI 020H ;test bit 5
CPI 0 ;if bit5=0 then 5 bpc
JNZ SHBTS1 ;
CALL ILPRT ;
DB '5',0 ;
RET ;
SHBTS1: CALL ILPRT ;
DB '7',0 ;
RET ;
SHBTS2: LDA REG5 ;
ANI 020H ;test bit 5
CPI 0 ;if bit5=0 then 6 bpc
JNZ SHBTS3 ;
CALL ILPRT ;
DB '6',0 ;
RET ;
SHBTS3: CALL ILPRT ;
DB '8',0 ;
RET
;
; Set Port Address for Modem
;
STPORT: MVI C,SBLANK ;check for parity code
CALL MEX ;
JC SETERR ;if none, print error
LXI D,PORTBL ;check for proper syntax
CALL TSRCH ;
PUSH H ;match found, go do it!
RNC ;
POP H ;no match: fix stack and
JMP SETERR ; print error
;
PORTJ5: MVI A,MODCTL1
STA CTLPORT ;DEFINE CONTROL PORT
MVI A,MODDAT1 ;
STA DATPORT ;DEFINE DATA PORT
MVI A,BAUD1 ;
STA BAUDPT ;DEFINE BAUD PORT
JMP SPORT ;
PORTJ6: MVI A,MODCTL2
STA CTLPORT ;DEFINE CONTROL PORT
MVI A,MODDAT2 ;
STA DATPORT ;DEFINE DATA PORT
MVI A,BAUD2 ;
STA BAUDPT ;DEFINE BAUD PORT
SPORT: CALL NTBAUD
CALL NITSIO
SHPORT: CALL CRLF ;
CALL ILPRT ;
DB 'Initializing modem for port J',0
LDA BAUDPT ;get the port number
CPI 5
JNZ SHPJ6
MVI A,'5'
JMP SHPOUT
SHPJ6: CPI 6
JNZ SHPU
MVI A,'6'
JMP SHPOUT
SHPU: MVI A,'?'
SHPOUT: CALL TYPE
LDA INTERN
ORA A
JZ SHEXT
CALL ILPRT
DB CR,LF,'USING Internal 300/1200 Modem',0
JMP SHEXIT
SHEXT: CALL ILPRT
DB CR,LF,'USING External Modem',0
SHEXIT: CALL ILPRT
DB CR,LF,LF,0
RET
;
STMDM: MVI C,SBLANK ;check for parity code
CALL MEX ;
JC SETERR ;if none, print error
LXI D,MDMTBL ;check for proper syntax
CALL TSRCH ;
PUSH H ;match found, go do it!
RNC ;
POP H ;no match: fix stack and
JMP SETERR ; print error
;
EXTMDM: XRA A
JMP SETINT
INTMDM: MVI A,0FFH
SETINT: STA INTERN
JMP SHPORT
;
IF HAYES
;
; SET MONITOR command: turn Hayes speaker on and off
; to monitor dialing
;
STSPKR: MVI C,SBLANK ;
CALL MEX ;
JC SETERR ;
LXI D,MONTBL ;
CALL TSRCH ;
JC SETERR ;
MOV A,L ;
ADI '0' ;
STA MONMSG+3 ;
STSPK1: LXI H,MONMSG ;
CALL MDMSET ;
SHSPKR: CALL ILPRT ;
DB 'Modem monitor:',TAB,' ',0
LDA MONMSG+3 ;
CPI 0+'0' ;if monflg=0 then speaker is off
JNZ SHSPK1 ;
CALL ILPRT ;
DB 'Off',0 ;
RET ;
SHSPK1: CALL ILPRT ;
DB 'On',0 ;
RET ;
;
; SET DELAY command: set wait-time for 'no answer'
;
STDLY: MVI C,SBLANK ;check for delay parameter
CALL MEX ;
JC SETERR ;
LXI D,DLYTBL ;
CALL TSRCH ;
PUSH H ;
RNC ;
POP H ;
JMP SETERR ;
STDL15: LXI H,DL15MS ;delay 15 seconds
CALL MDMSET ;
MVI A,15 ;
STA NDELAY ;
JMP SHDLY ;
STDL30: LXI H,DL30MS ;
CALL MDMSET ;
MVI A,30 ;
STA NDELAY ;
JMP SHDLY ;
STDL45: LXI H,DL45MS ;
CALL MDMSET ;
MVI A,45 ;
STA NDELAY ;
JMP SHDLY ;
STDL60: LXI H,DL60MS ;
CALL MDMSET ;
MVI A,60 ;
STA NDELAY ;
SHDLY: CALL ILPRT ;
DB 'Modem delay:',TAB,' ',0
LDA NDELAY ;
CPI 15 ;
JNZ SHDLY1 ;
CALL ILPRT ;
DB '15 seconds',0
RET
SHDLY1: CPI 30 ;
JNZ SHDLY2 ;
CALL ILPRT ;
DB '30 seconds',0
RET
SHDLY2: CPI 45 ;
JNZ SHDLY3 ;
CALL ILPRT ;
DB '45 seconds',0
RET
SHDLY3: CALL ILPRT ;
DB '60 seconds',0
RET ;
;
; SET MODE command (answer or originate)
;
STMODE: MVI C,SBLANK ;
CALL MEX ;
JC SETERR ;
LXI D,MODTBL ;
CALL TSRCH ;
JC SETERR ;
MOV A,L ;
ADI '0' ;
STA MODMSG+5 ;
STMOD1: LXI H,MODMSG ;
CALL MDMSET ;
SHMODE: CALL ILPRT ;
DB 'Mode: ',TAB,' ',0
LDA MODMSG+5 ;
CPI 0+'0' ;if zero, then originate mode
JNZ SHMOD1 ;
CALL ILPRT ;
DB 'Originate',0 ;
RET ;
SHMOD1: CALL ILPRT ;
DB 'Answer',0 ;
RET ;
;
; SET DIAL command (touch or pulse)
;
SETDIA: MVI C,SBLANK ;
CALL MEX ;
JC SETERR ;
LXI D,DIALTB ;
CALL TSRCH ;
JC SETERR ;
MOV A,L ;
STA TPULSE ;
SHDIAL: CALL ILPRT ;
DB 'Phone type:',TAB,' ',0
LDA TPULSE ;
CPI 'T' ;
JNZ SHDIL1 ;
CALL ILPRT ;
DB 'Touchtone',0
RET ;
SHDIL1: CALL ILPRT ;
DB 'Pulse-dial',0 ;
RET ;
ENDIF
;
; Newline on console
;
CRLF: MVI A,CR
CALL TYPE
MVI A,LF ;fall into TYPE
;
; type char in A on console
;
TYPE: PUSH H ;save 'em
PUSH D
PUSH B
MOV E,A ;align output character
MVI C,CONOUT ;print via MEX
CALL MEX
POP B
POP D
POP H
RET
;
; Compare next input-stream item in table @DE; CY=1
; if not found, else HL=matched data item
;
TSRCH: MVI C,LOOKUP ;get function code
JMP MEX ;pass to MEX processor
;
; Print in-line message ... blows away C register
;
ILPRT: MVI C,ILP ;get function code
JMP MEX ;go do it
;
IF SMODEM
;
; Hayes Smartmodem 1200 dialling routines
;
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 ;set up buffer pointer
SHLD DIALPT
LDA INTERN ; USING INTERNAL MODEM?
JZ STDRET ; NOPE
CALL OFFHK
STDRET: RET
;
; Here on an end-dial sequence
;
ENDIAL: MVI M,CR ;stuff end-of-line into buffer
INX H ;followed by terminator
IF VENTEL
LDA INTERN
ORA A
JNZ ENDL ;DON'T NEED THIS FOR INTERNAL
MVI M,'>' ;end bufffered command string
INX H ;
ENDIF
ENDL: MVI M,0
IF HAYES
LDA TPULSE ;get overlay's touch-tone flag
STA SMDIAL+3 ;put into string
ENDIF
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 (up to
; 60 seconds: you may change this value in the following line)
;
RESULT: MVI C,60 ;<<== maximum time to wait for result
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
PUSH B ;no, test for control-c from console
MVI C,CHEKCC
CALL MEX
POP B
JNZ SMNEXT ;if not, jump
MVI B,CR ;yes, shut down the modem
MVI C,SNDCHR
CALL MEX
MVI A,3 ;return abort code
RET
SMNEXT: DCR C ;no
JNZ SMWLP ;continue
;
; One minute with no modem response (or no connection)
;
SMTIMO: 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
;
SMANAL:
IF HAYES
MVI B,0 ;prep connect code
CPI 'C' ;"connect"?
RZ
CPI '1' ;numeric version of "connect"
RZ
CPI '5' ;or "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
IF VENTEL
MVI B,0 ;prep connect code
CPI 'O' ;"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 'D' ;e=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
;
; Following routine disconnects the modem using smartmodem
; codes. All registers are available for this function.
; Nothing returned to caller.
;
;
DISCON:
IF HAYES
MVI B,20
MVI C,TIMER ;wait 2 seconds
CALL MEX
LXI H,SMATN ;send '+++'
CALL SMSEND
MVI B,20 ;wait 2 more seconds
MVI C,TIMER
CALL MEX
LXI H,SMDISC ;send 'ATH'
CALL SMSEND
MVI B,1 ;wait 1 second
MVI C,TIMER
CALL MEX
ENDIF
RET
;
; Smartmodem utility routine: send string to 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
;
ENDIF
;
; Data area
;
EOSMSG: DB 1BH,'Y$' ;clear-to-end-of-screen
CLSMSG: DB 1BH,'*$' ;clear-screen-home-cursor
;
; Default UART parameters in the following table
;
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 01101010B ;Enable transmit at 8 bits/char
;
SETEMS: DB CR,LF,'SET command error',CR,LF,'$'
;
IF HAYES
MONMSG: DB 'ATM0',CR,0
NDELAY: DB 15 ;delay-time in seconds
DL15MS: DB 'ATS7=15',CR,0
DL30MS: DB 'ATS7=30',CR,0
DL45MS: DB 'ATS7=45',CR,0
DL60MS: DB 'ATS7=60',CR,0
MODMSG: DB 'ATS0=0',CR,0
SMATN: DB '+++',0
SMDISC: DB 'ATH',CR,0
SMDIAL: DB 'ATDT '
ENDIF
IF VENTEL
SMDIAL: DB '<K'
ENDIF
DIALBF: DS 52 ;2* 24 char max, + CR + NULL + slop
DIALPT: DS 2 ;dial position pointer
;
;
;
; SET command -- master command table
;
CMDTBL: DB '?'+80H ;"set ?"
DW STSHOW ;
DB 'BAU','D'+80H ;"set baud"
DW STBAUD ;
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 'POR','T'+80H ;"set port for modem"
DW STPORT
DB 'MODE','M'+80H ;set modem as internal or external
DW STMDM
;
IF HAYES
DB 'MONITO','R'+80H;"set monitor"
DW STSPKR
DB 'DELA','Y'+80H ;"set delay"
DW STDLY
DB 'MOD','E'+80H ;"set mode"
DW STMODE
DB 'DIA','L'+80H ;"set dial"
DW SETDIA
ENDIF
;
DB 0 ;<<== end of CMDTBL
;
; SET BAUD command table
;
BDTBL: DB '30','0'+80H ;"set baud 300"
DW 0001H ;
DB '60','0'+80H ;"set baud 600"
DW 0003H ;
DB '120','0'+80H ;"set baud 1200"
DW 0005H ;
DB '240','0'+80H ;"set baud 2400"
DW 0006H ;
DB '480','0'+80H ;"set baud 4800"
DW 0007H ;
DB '960','0'+80H ;"set baud 9600"
DW 0008H ;
DB 0 ;<<== end of baudrate table
;
; PBAUD baudrate generator lookup table
;
BDTBL2: DB 0H ;110 baud (not supported)
DB 28H ;300 baud
DB 0 ;450 baud (not supported)
DB 4FH ;600 baud
DB 0 ;710 baud (not supported)
DB 28H ;1200 baud
DB 14H ;2400 baud
DB 0AH ;4800 baud
DB 5H ;9600 baud
DB 0H ;19200 baud (not supported)
;
; Table of SHOW subroutine addresses
;
SHOTBL: DW SHBAUD ;show baud rate
DW SHPRTY ;show parity setting
DW SHSTOP ;show no. of stop bits
DW SHBITS ;show bits/character
DW SHPORT ;show port address
;
IF HAYES
DW SHSPKR ;show modem speaker status
DW SHDLY ;show hangup delay
DW SHMODE ;show answer or originate
DW SHDIAL ;show pulse or tone
ENDIF
;
DW 0 ;<<== end of show address list
;
; 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 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 table
;
; SET PORT command table
;
PORTBL: DB 'J','5'+80H ;"set J5"
DW PORTJ5
DB 'J','6'+80H ;"set J6"
DW PORTJ6
DB 0 ;<<== End of stop-bits table
;
MDMTBL: DB 'EX','T'+80H ;"EXTERANL MODEM"
DW EXTMDM
DB 'IN','T'+80H ;"INTERNAL MODEM"
DW INTMDM
DB 0 ;<<== End of table
;
; 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
;
IF HAYES
;
; SET MONITOR command table
;
MONTBL: DB 'O','N'+80H ;"set monitor on"
DW 0001H
DB 'OF','F'+80H ;"set monitor off"
DW 0000H
DB 0 ;<<== end of monitor table
;
; SET DELAY command table
;
DLYTBL: DB '1','5'+80H ;"set delay 15"
DW STDL15
DB '3','0'+80H ;"set delay 30"
DW STDL30
DB '4','5'+80H ;"set delay 45"
DW STDL45
DB '6','0'+80H ;"set delay 60"
DW STDL60
DB 0 ;<<== end of delay table
;
; SET MODE command table
;
MODTBL: DB 'ORI','G'+80H ;"set mode orig"
DW 0000H
DB 'ANSWE','R'+80H ;"set mode answer"
DW 0001H
DB 0 ;<<== end of mode table
;
; SET DIAL command table
;
DIALTB: DB 'TON','E'+80H ;"set dial tone"
DW 0054H
DB 'PULS','E'+80H ;"set dial pulse"
DW 0050H
DB 0 ;<<== end of dial table
ENDIF
;
END
;
BITTBL: DB '5'+80H ;"set bits 5"
DW BIT5
DB '6'+80H ;"set bits 6"
DW BIT6
DB '7'+80H ;"set bits 7"
DW B