home *** CD-ROM | disk | FTP | other *** search
- 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
-