home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol049
/
modem.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
11KB
|
500 lines
TITLE 'MODEM - PL/1 DC HAYES MODEM SUBROUTINES'
; . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; MODEM I/O AND CONTROL SUBROUTINES FOR DC HAYES MODEM
; (ADAPTED FROM MICROMODEM 100 PROGRAM)
; (ADAPTED AGAIN TO RUN WITH PL/1 ON AUGUST 30, 1980)
; . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
; ASSEMBLER STUFF
NAME 'MODEM'
MODEM: CSEG
FALSE: EQU 0 ;TRUE/FALSE SUBSTITUTIONS
TRUE: EQU NOT FALSE
; PORT ASSIGNMENTS
DATA EQU 80H ;DATA I/O PORT
STAT EQU DATA+1 ;STATUS PORT
MODE EQU DATA+2 ;MODE CONTROL PORT
CR1 EQU DATA+1 ;CONTROL REG 1
CR2 EQU DATA+2 ;CONTROL REG 2
CR3 EQU DATA+3 ;CONTROL REG 3
; BIT FUNCTIONS
;STATUS REGISTER
RRF EQU 001H ;RECEIVE REGISTER FULL
TRE EQU 002H ;TRANSMITTER HOLDING REGISTER EMPTY
PE EQU 004H ;PARITY ERROR
FE EQU 008H ;FRAMING ERROR
OE EQU 010H ;DATA OVERRUN ERROR
TMR EQU 020H ;TIMER STATUS
CD EQU 040H ;CARRIER PRESENT
RI EQU 080H ;NOT RING INDICATOR (LOW TRUE)
;CONTROL REGISTER 1 (CR1)
EPE EQU 001H ;EVEN PARITY ENABLE
LS1 EQU 002H ;WORD LENGTH SELECT BIT 1
LS2 EQU 004H ;WORD LENGTH SELECT BIT 2
SBS EQU 008H ;STOP BITS
PI EQU 010H ;PARITY INHIBIT
TMIE EQU 020H ;TIMER INTERRUPTS ENABLE
;CONTROL REGISTER 2 (CR2)
BRS EQU 001H ;BAUD RATE CONTROL
TXE EQU 002H ;TRANSMIT CARRIER ENABLE
MS EQU 004H ;MODE (0=ANSWER 1=ORIGINATE)
BRK EQU 008H ;SEND BREAK
ST EQU 010H ;SELF TEST
TIE EQU 020H ;TRANSMITTER INTERRUPT ENABLE
RIE EQU 040H ;RECEIVER INTERRUPT ENABLE
OH EQU 080H ;OFF-HOOK
; * * * RESET MODEM * * *
MDMRST:
PUBLIC MDMRST
XRA A ;ZERO CONTROL REGS.
OUT CR1
OUT CR2
STA MICR1 ; AND MEMORY IMAGES OF REGISTERS.
STA MICR2
RET
; * * * TRANSMIT CHAR * * *
; THIS ROUTINE SENDS A BYTE IN REGISTER C TO THE MODEM
; TRANSMITTER. ONLY REGISTER A IS DISTURBED.
MDMTXC:
PUBLIC MDMTXC
CALL PLICHR ;GET THE CHAR TO OUTPUT.
MDMTXC$DIR:
IN STAT ;GET MODEM STATUS.
ANI TXE ;XMIT BUFFER EMPTY?
JZ MDMTXC$DIR ;...YES, LOOP.
MOV A,C ;...NO, SEND THE BYTE.
OUT DATA
RET
; * * * RECEIVE CHAR * * *
; THIS ROUTINE RECEIVES A BYTE FROM THE MODEM RECEIVER
; IN REGISTER A.
MDMRXC:
PUBLIC MDMRXC
IN STAT ;GET MODEM STATUS.
ANI RRF ;RECV BUFFER EMPTY?
JZ MDMRXC ;...YES, LOOP.
IN DATA ;...NO, GET DATA.
ANI 07FH ;STRIP PARITY.
RET
; * * * GET RECV STATUS * * *
; THIS ROUTINE RETURNS A=TRUE IF A RECEIVED CHARACTER
; IS WAITING OR A=FALSE IF NOT.
MDMRXS:
PUBLIC MDMRXS
IN STAT ;GET MODEM STATUS.
ANI RRF ;RECV BUFFER EMPTY?
MVI A,FALSE
RZ ;...YES, RETURN A=FALSE.
MVI A,TRUE ;...NO, RETURN A=TRUE
RET
; * * * CHECK CARRIER STATUS * * *
; THIS ROUTINE RETURNS TRUE IF CARRIER IS PRESENT.
MDMCDS:
PUBLIC MDMCDS
IN STAT ;GET MODEM STATUS.
ANI CD ;CARRIER DETECTED?
MVI A,FALSE
RZ ;...NO.
MVI A,TRUE ;...YES.
RET
; * * * CHECK RING STATUS * * *
; THIS ROUTINE CHECKS FOR PHONE RINGING RETURNING
; TRUE IF SO.
MDMRIS:
PUBLIC MDMRIS
IN STAT ;GET MODEM STATUS.
ANI RI ;PHONE RINGING?
MVI A,TRUE
RZ ;...YES.
MVI A,FALSE
RET
; * * * CHECK FOR MODEM ERROR * * *
; THIS ROUTINE RETURNS THE MODEM ERROR FLAGS IN
; REGISTER A. A=0 IF NO ERRORS. OTHERWISE,
; BIT 0 = PARITY ERROR BIT 1 = FRAMING ERROR
; BIT 2 = OVERRUN ERROR
MDMERR:
PUBLIC MDMERR
IN STAT ;GET MODEM STATUS.
RAR ;SHIFT BITS RIGHT 2 PLACES.
RAR
ANI 7 ;KILL UNWANTED BITS.
RET
; * * * CARRIER CONTROL * * *
; THIS ROUTINE TURNS THE CARRIER ON/OFF ACCORDING
; TO REGISTER C. C=FALSE FOR OFF; C=TRUE FOR ON.
MDMCRC:
PUBLIC MDMCRC
CALL PLICHR ;GET THE COMMAND.
MDMCRC$DIR:
MOV A,C
ORA A
MVI A,TXE ;CARRIER CONTROL BIT.
JZ MDMCC2 ;CLEAR IT IF A=FALSE.
JMP MDMSC2 ;SET IT IF A=TRUE.
; * * * BAUD RATE CONTROL * * *
; THIS ROUTINE SETS THE BAUD RATE GIVEN BY REGISTER
; C. C=FALSE FOR 110; C=TRUE FOR 300.
MDMBDC:
PUBLIC MDMBDC
CALL PLICHR ;GET THE COMMAND.
MDMBDC$DIR:
MOV A,C
ORA A
MVI A,BRS ;BAUD RATE SELECT BIT.
JZ MDMCC2 ;CLEAR IT IF A=FALSE.
JMP MDMSC2 ;SET IT IF A=TRUE.
; * * * HOOK CONTROL * * *
; THIS ROUTINE SETS THE HOOK ON OR OFF ACCORDING
; TO REGISTER C. C=FALSE FOR ON (IDLE); C=TRUE
; FOR OFF (ACTIVE).
MDMSWH:
PUBLIC MDMSWH
CALL PLICHR ;GET THE COMMAND.
MDMSWH$DIR:
MOV A,C
ORA A
MVI A,OH ;HOOK CONTROL BIT.
JZ MDMCC2 ;CLEAR IT IF A=FALSE.
JMP MDMSC2 ;SET IT IF A=TRUE.
; * * * GET HOOK STATUS * * *
; THIS ROUTINE RETURNS THE HOOK STATUS IN REGISTER
; A. A=TRUE FOR OFF-HOOK; A=FALSE FOR ON-HOOK.
MDMSHS:
PUBLIC MDMSHS
LDA MICR2 ;GET CR2.
ANI OH ;MASK FOR OFF-HOOK.
MVI A,TRUE
RNZ ;...OFF-HOOK.
MVI A,FALSE ;...ON-HOOK.
RET
; * * * MODE CONTROL * * *
; THIS ROUTINE SETS THE MODE (ANSWER OR ORIGINATE)
; ACCORDING TO REGISTER C. C=FALSE FOR ANSWER;
; C=TRUE FOR ORIGINATE.
MDMMOD:
PUBLIC MDMMOD
CALL PLICHR ;GET THE COMMAND.
MDMMOD$DIR:
MOV A,C
ORA A
MVI A,MS ;MODE SELECT BIT.
JZ MDMCC2 ;CLEAR IT IF A=FALSE.
JMP MDMSC2 ;SET IT IF A=TRUE.
; * * * SELF-TEST CONTROL * * *
; THIS ROUTINE SETS THE SELF-TEST MODE
; ACCORDING TO REGISTER C. C=FALSE FOR NORMAL;
; C=TRUE FOR SELF-TEST.
MDMSLT:
PUBLIC MDMSLT
CALL PLICHR ;GET THE COMMAND.
MDMSLT$DIR:
MOV A,C
ORA A
MVI A,ST ;SELF TEST BIT.
JZ MDMCC2 ;CLEAR IT IF A=FALSE.
JMP MDMSC2 ;SET IT IF A=TRUE.
; * * * SEND BREAK * * *
; THIS ROUTINE SENDS A BREAK CONSISTING OF A
; SPACE (LOW TONE) FOR A NUMBER OF 50 MS IN-
; TERVALS SPECIFIED BY REGISTER C.
MDMBRK:
PUBLIC MDMBRK
CALL PLICHR ;GET # OF INTERVALS.
MDMBRK$DIR:
PUSH B
MVI C,2 ;WAIT 100 MS.
CALL MDMDLY$DIR
POP B
PUSH H ;SET THE BREAK BIT.
LXI H,MICR2
MVI A,BRK
ORA M
OUT CR2
CALL MDMDLY$DIR ;DELAY (C)*50 MS.
MVI A,BRK ;RESET BREAK BIT.
CMA
ANA M
OUT CR2
POP H
RET
; * * * SET PARITY * * *
; THIS ROUTINE SETS THE PARITY ACCORDING TO REG C.
; C=0 FOR NO PARITY, C=1 FOR ODD PARITY AND C=2
; FOR EVEN PARITY.
MDMPAR:
PUBLIC MDMPAR
CALL PLICHR ;GET THE COMMAND.
MDMPAR$DIR:
MOV A,C ;TEST FOR NO PARITY.
ORA A
JZ MDMPAF ;TURN OFF PARITY.
MVI A,PI ;CLEAR PARITY INHIBIT BIT.
CALL MDMCC1
MOV A,C ;SET LSB FOR EVEN/ODD PARITY.
RAR
ANI 1
MVI A,EPE ;CLEAR EPE IF ODD.
JZ MDMCC1
JMP MDMSC1 ;SET EPE IF EVEN.
MDMPAF:
MVI A,PI ;INHIBIT PARITY.
JMP MDMSC1
; * * * SELECT WORD LENGTH * * *
; THIS ROUTINE SETS THE WORD LENGTH ACCORDING TO REG C.
; C = NUMBER OF BITS (5,6,7,8)
MDMWLN:
PUBLIC MDMWLN
CALL PLICHR ;GET THE COMMAND.
MDMWLN$DIR:
MOV A,C ;REMOVE BIAS.
SUI 5
RC
CPI 3+1
CMC
RC
ADD A ;SHIFT LEFT 1 PLACE.
MOV C,A ;SAVE RESULT.
LDA MICR1 ;GET MEMORY IMAGE.
ANI NOT LS1+LS2 ;CLEAR WORD LENGTH BITS.
ORA C ;PUT IN NEW ONES.
STA MICR1 ;UPDATE MEMORY IMAGE.
OUT CR1 ;WRITE IT TO MODEM.
RET
; * * * SET NUMBER OF STOP BITS * * *
; THIS ROUTINE SETS THE NUMBER OF STOP BITS ACCORDING
; TO REGISTER C. C = STOP BITS (1 OR 2)
MDMNST:
PUBLIC MDMNST
CALL PLICHR ;GET THE COMMAND.
MDMNST$DIR:
MOV A,C ;REMOVE BIAS.
SUI 1
RC
CPI 1+1
CMC
RC
ORA A
MVI A,SBS ;STOP BIT SELECT BIT.
JZ MDMCC1 ;CLEAR IT.
JMP MDMSC1
; * * * DELAY ROUTINE * * *
; THIS ROUTINE WAITS 50MS TIMES THE VALUE OF THE
; REGISTER C.
MDMDLY:
PUBLIC MDMDLY
CALL PLICHR ;GET THE TIME AMOUNT.
MDMDLY$DIR:
MOV A,C
ORA A ;IF ZERO, DON'T WAIT.
RZ
PUSH B
MDMDL1:
OUT CR3 ;START TIMER.
MDMDL2:
IN STAT ;WAIT TILL TIMER BIT
ANI TMR ;TIMES OUT.
JZ MDMDL2
DCR C ;LOOP (C) TIMES.
JNZ MDMDL1
POP B
RET
; * * * START 50MS TIMER * * *
MDMSTM:
PUBLIC MDMSTM
OUT CR3
RET
; * * * CHECK TIMER STATUS * * *
MDMCTM:
IN STAT ;GET MODEM STATUS.
ANI TMR ;TIME OUT?
MVI A,TRUE
RNZ ;...YES.
MVI A,FALSE
RET
; * * * GO OFF HOOK * * *
; THIS ROUTINE GOES OFF HOOK AND WAITS FOR A DIAL TONE.
; MICROMODEM HAS NO DIAL TONE DETECTOR. WE JUST GO OFF
; HOOK, WAIT 2 SEC, ASSUME A DIAL TONE IS PRESENT AND
; RETURN.
MDMDLT:
PUBLIC MDMDLT
PUSH B
MVI C,TRUE ;GO OFF-HOOK.
CALL MDMSWH$DIR
MVI C,40 ;WAIT 2 SECONDS.
CALL MDMDLY$DIR
POP B
RET
; * * * DIAL PULSE GENERATION * * *
; THIS ROUTINE GENERATES A DIALING PULSE FOR THE DIGIT
; IN REGISTER C. IF C=0 THEN 10 PULSES WILL BE
; PRODUCED. THE DIGIT IN THE C REGISTER MAY BE
; BINARY OR ASCII. AFTER THE DIGIT IS OUT-PULSED,
; THIS ROUTINE WILL PAUSE FOR 600 MS FOR INTER-DIGIT
; SPACING.
MDMPLS:
PUBLIC MDMPLS
CALL PLICHR ;GET THE DIGIT.
MDMPLS$DIR:
PUSH B
MOV A,C ;GET DIGIT.
MVI B,10 ;PRE-LOAD PULSE COUNTER
ANI 00FH ;KILL POSSIBLE ASCII BIAS.
CPI 0 ;SEE IF WE'RE DOING 10 PULSES.
JZ MDMPL1
MOV B,A ;PULSE COUNT TO B
MDMPL1:
MVI C,FALSE ;GO ON-HOOK.
CALL MDMSWH$DIR
MVI C,1 ;WAIT 50 MS.
CALL MDMDLY$DIR
MVI C,TRUE ;GO OFF-HOOK AGAIN.
CALL MDMSWH$DIR
MVI C,1 ;DELAY 50 MS.
CALL MDMDLY$DIR
DCR B ;LOOP FOR ALL PULSES.
JNZ MDMPL1
MVI C,11 ;WAIT 550 MS.
CALL MDMDLY$DIR
POP B
RET
; * * * DIAL A NUMBER * * *
; THIS ROUTINE GENERATES ALL THE DIALING PULSES
; FOR A NUMBER GIVEN AS A VARYING CHARACTER STRING.
; THEREFORE, IT DIALS THE NUMBER.
MDMDLN:
PUBLIC MDMDLN
CALL MDMDLT ;GET DIAL TONE.
CALL PLICHR ;GET THE STRING LENGTH IN C.
ORA A ;LENGTH=ZERO?
RZ ;...YES, RETURN.
INX H ;BUMP TO BEGINNING OF STRING.
MDMDLN$LP:
MOV A,M ;GET THE NEXT NUMBER.
CPI '*' ;DELAY?
JNZ MDMDLN$NUM ;...YES.
PUSH B
MVI C,40 ;WAIT 2 SEC.
CALL MDMDLY$DIR
POP B
JMP MDMDLN$NXT ; GET NEXT CHAR.
MDMDLN$NUM:
CPI '9'+1 ;ASCII 0-9?
JNC MDMDLN$NXT ;...NO, SKIP IT.
CPI '0'
JC MDMDLN$NXT ;...NO, SKIP IT.
PUSH B ;SAVE CURRENT COUNT.
MOV C,A ;PULSE OUT THE NUMBER.
CALL MDMPLS$DIR
POP B
MDMDLN$NXT:
INX H ;BUMP PTR.
DCR C ;DECREMENT COUNT.
RZ ;RETURN IF NO MORE DIGITS.
JMP MDMDLN$LP ;GO PULSE ANOTHER DIGIT.
; * * * SET CR1 * * *
; THIS ROUTINE SETS BITS IN CONTROL REGISTER
; 1. REGISTER A HAS 1'S WHERE BITS ARE TO
; BE SET.
MDMSC1:
PUSH H
LXI H,MICR1 ;OR IN BITS TO SET.
ORA M
MOV M,A ;SAVE RESULT.
OUT CR1 ;SET THE MODEM.
POP H
RET
; * * * CLEAR CR1 * * *
; THIS ROUTINE CLEARS THE BITS IN CONTROL REGISTER
; 1. REGISTER A HAS 1'S FOR THE BITS TO BE CLEARED.
MDMCC1:
PUSH H
LXI H,MICR1 ;MEMORY IMAGE OF CR1.
CMA
ANA M ;TURN OFF THE BIT.
MOV M,A ;UPDATE MEMORY.
OUT CR1 ;UPDATE MODEM.
POP H
RET
; * * * SET CR2 * * *
; THIS ROUTINE SETS BITS IN CONTROL REGISTER
; 2. REGISTER A HAS 1'S WHERE BITS ARE TO
; BE SET.
MDMSC2:
PUSH H
LXI H,MICR2 ;OR IN BITS TO SET.
ORA M
MOV M,A ;SAVE RESULT.
OUT CR2 ;SET THE MODEM.
POP H
RET
; * * * CLEAR CR2 * * *
; THIS ROUTINE CLEARS THE BITS IN CONTROL REGISTER
; 2. REGISTER A HAS 1'S FOR THE BITS TO BE CLEARED.
MDMCC2:
PUSH H
LXI H,MICR2 ;MEMORY IMAGE OF CR2.
CMA
ANA M ;TURN OFF THE BIT.
MOV M,A ;UPDATE MEMORY.
OUT CR2 ;UPDATE MODEM.
POP H
RET
; * * * GET PL/I PARAMETER * * *
; THIS ROUTINE GETS A PL/I PARAMETER ACCORDING TO
; ITS STANDARD CALLING CONVENTIONS.
PLICHR:
PUSH D ;SAVE DE.
MOV E,M ;GET PARM PTR FROM 0(HL).
INX H
MOV D,M
LDAX D ;GET THE ONE BYTE PARM.
MOV C,A ;PUT IT IN (C).
XCHG ;PUT PARM PTR IN HL.
POP D
RET
; * * * DATA AREA FOR MODEM I/O * * *
DSEG
MICR1: DB 0 ;MEMORY IMAGE OF CONTROL REGISTER 1
MICR2: DB 0 ;MEMORY IMAGE OF CONTROL REGISTER 2
END