SEARCH SYS SEARCH SYSSYM SEARCH TRM OBJNAM 0,0,[IDV] ;[101] 27 May 1992 12:14 Edited by InterLink Systems, Inc ; Fix problem when using flow control ;[102] 30 NOV 1993 MP WSOL, Alpha Microsystems ; Update for RoadRunner Support ; This driver is for non-intelligent boards, (ie. no-Z80). ; Have tested with 16-port Revision B artwork. VMAJOR = 2 VMINOR = 0 VWHO = 0 VSUB = 0 VEDIT = 102. RADIX 16. ;[102] Updated for 32 bit addressing INTADD = ^H0FFFFFF90 ; Interrupt address AVLPIN = RS%RTS DEFINE CCC LABEL BCS 10$$ CALL LABEL 10$$: ENDM START: PHDR -1,0,0 BR CHROUT ; Character output routine BR INIT ; Initialize port BR 10$ ; Get the PIN status BR 20$ ; Set the PIN status WORD ^H0A5A5 ; Magic word for new driver LWORD AVLPIN ; Available pin numbers ;--------- Start of Driver ------------ 10$: JMP GETPIN 20$: JMP SETPIN CHROUT: SAVE D2,A3 ; Save used registers MOV T.IHM(A5),D0 ; Get interface port number LEA A3,PORTS ; Index initialized flag MOVW @A3,D2 ; Get the flag BTST D0,D2 ; Test initilazed bit BEQ IGNXIT ; Branch if not MOV T.IHW(A5),A3 ; Get hardware address MOVB #5,2(A3) ; Enable Interupt on port IGNXIT: REST A3,D2 ; Restore used register RTN INIT: CMP D0,#18. ; Max baud rate (38400 baud) JHIS BAUDER ; Above max LEA A0,INTRPT ; Index interupt routine MOV A0,064 ; Save in vector LEA A0,PORTS ; Port inited indicator MOVW @A0,D2 ; Get previous inited port MOV T.IHM(A5),D1 ; Get port number XORB #1,D1 ; Get other channel BTST D1,D2 ; Has the other chanel been inited? JEQ NEWINI ; Nope LEA A0,BVAL ; Get baud value used on other port CLR D3 MOVB 0(A0)[D1],D3 BTST #7,D3 ; Acr=1? JEQ TRYB0 LEA A0,BAUD1 ; Index the baud rate table ACR=1 MOVB 0(A0)[D0],D4 ; Is it a valid baud rate? CMPB D4,#-1 BEQ CHGB0 ; no - invalid baud rate BCLR #7,D3 MOVB 0(A0)[D3],D4 ; Other channel also supported CMPB D4,#-1 BEQ CHGB0 BSET #7,D0 ; Use ACR=1 JMP SBAUD ; Try to change to ACR=0 CHGB0: LEA A0,BAUD0 MOVB 0(A0)[D0],D4 ; Both baud rates defined CMPB D4,#-1 JEQ BAUDER BCLR #7,D3 MOVB 0(A0)[D3],D4 CMPB D4,#-1 JEQ BAUDER SAVE D0,A5 ; Reset baud rate on other channel MOV D3,D0 ; Old baud rate LEA A0,TCB0 LSL D1,#2 ; Port NUM * $ for LWORD offset MOV 0(A0)[D1],A5 ; Pntr to other chan trmdef block BCLR #7,D0 ; Use ACR=0 CALL PINIT ; Init other chanel REST A5,D0 JMP SBAUD TRYB0: LEA A0,BAUD0 ; Index baud rate table ACR=0 MOVB 0(A0)[D0],D4 CMPB D4,#-1 BEQ CHGB1 BCLR #7,D3 MOVB 0(A0)[D3],D4 CMPB D4,#-1 JNE SBAUD ; Set baud rate to ACR=0 ; Try to change ACR=1 CHGB1: LEA A0,BAUD1 MOVB 0(A0)[D0],D4 ; Both baud rate defined CMPB D4,#-1 JEQ BAUDER BCLR #7,D3 MOVB 0(A0)[D3],D4 CMPB D4,#-1 JEQ BAUDER SAVE D0,A5 ; Reset baud rate on other channel MOV D3,D0 ; Old baud rate BSET #7,D0 ; Indicate that port has ACR=1 LEA A0,TCB0 LSL D1,#2 ; Port NUM * 4 for LWORD offset MOV 0(A0)[D1],A5 ; Pntr to other chan trmdef block CALL PINIT ; Init other channel REST A5,D0 BSET #7,D0 ; Use ACR=1 on ther port JMP SBAUD BAUDER: TYPECR ERRXIT: RTN NEWINI: LEA A0,BAUD1 ; Index the baud rate table ACR=1 MOVB 0(A0)[D0],D4 ; Is it a valid baud rate? CMPB D4,#-1 BEQ NOTB0 BSET #7,D0 ; ACR=1 JMP SBAUD NOTB0: LEA A0,BAUD0 ; Index baud rate table ACR=0 MOVB 0(A0)[D0],D4 CMPB D4,#-1 JEQ BAUDER SBAUD: ; Get port number and base address of DUART and channel PINIT: LEA A0,BAUD0 MOV D0,D3 CLR D6 BCLR #7,D0 ; Baud1? BEQ ACR0 LEA A0,BAUD1 MOVB #^H80,D6 ; ACR Value ACR0: ADD D0,A0 ; Offset to baud rate init value MOV T.IHM(A5),D2 ; Use port number displacement LEA A1,BVAL ; Save baud rate value on cur port MOVB D3,0(A1)[D2] LEA A1,ADDTBL ; Index port address table MOV D2,D3 SUB A3,A3 ; Clear A3 BCLR #0,D2 ; Even or odd port BEQ EADDR MOV #8,A3 ; Base address of second channel EADDR: LSL D2,#1 ADD D2,A1 MOV @A1,A2 ADD A2,A3 MOVB D6,4(A2) ; Set Aux control register MOVB @A0,D1 ROLB D1,#4 ORB @A0,D1 MOVB D1,1(A3) ; Clock select MOVB #010,2(A3) ; Reset MR Pointer MOVB #020,2(A3) ; Reset receiver MOVB #030,2(A3) ; Reset transmitter MOVB #040,2(A3) ; Reset error status MOVB 1(A3),D1 ; Read status register A INCB D1 BNE 5$ TYPECR <16 Port not detected> JMP ERRXIT 5$: MOVB #013,@A3 ; Setup Register 1 MOVB #017,D1 ; One stop bit CMPB D0,#4 ; Did we want 110 baud BNE 10$ ; No, Branch MOVB #01F,D1 ; Set 2 stop bits 10$: MOVB D1,@A3 ; Output control bits for Register 2 MOVB #0A,2(A3) ; Disable RCV and XMIT CLR D1 ; Init enabled on uarts MOVB #3,D1 BTST #0,D3 ; Channel A? BEQ 40$ ; Go if true ROLB D1,#4 ; Shift up for Channel B 40$: LEA A0,IMASK1 ; Base address of IMR byte table MOV D3,D2 ; Save channel number LSR D2,#1 ; Index correct mask register ADD D2,A0 ORB D1,@A0 ; Add to existing mask value MOVB @A0,D1 ; D1 Reflects both channels MOVB D1,5(A2) ; Program DUART ; Enable RTS MOVB #5,D1 ; Setup channel A BTST #0,D3 ; Test if channel B BEQ 50$ MOVB #012,D1 ; Setup channel B 50$: LEA A0,OPBIT1 ; Base of output byte table ADD D2,A0 ORB D1,@A0 ; Add to existing bit pattern MOVB @A0,D1 ; D1 reflects both channels MOVB D1,0E(A2) ; Set output port bits MOVB #0,0D(A2) ; Output port configuration ; Set local memory flag and pointers LEA A0,PORTS ; Port inited indicator MOVW @A0,D2 ; Get previous inited ports BSET D3,D2 ; Mark current port as inited MOVW D2,@A0 ; Save indicator LSL D3,#2 ; Index long words LEA A0,TCB0 ADD D3,A0 MOV A5,@A0 ; Trmdef block address MOV A3,T.IHW(A5) ; Save duart address in trmdef block MOVB #1,2(A3) ; Enable receiver interupt RTN GETPIN: CLR D6 MOV #AVLPIN,D7 RTN SETPIN: RTN INTRPT: SAVE D0-D7,A0-A6 ; Save used registers MOV #INTADD,A0 ;[102] Index interupt regsiter MOVB @A0,D0 ; Get the port mask CLR D2 ; Set port number MOVW #3,D3 ; Set mask byte RORB D0,#1 ; Shift into CC register CCC DOIO ; Branch if needs work LSLW D3,#2 ; Shift mask ADD #2,D2 ; Index port RORB D0,#1 ; Shift in next bit CCC DOIO LSLW D3,#2 ADD #2,D2 RORB D0,#1 CCC DOIO LSLW D3,#2 ADD #2,D2 RORB D0,#1 CCC DOIO LSLW D3,#2 ADD #2,D2 RORB D0,#1 CCC DOIO LSLW D3,#2 ADD #2,D2 RORB D0,#1 CCC DOIO LSLW D3,#2 ADD #2,D2 RORB D0,#1 CCC DOIO LSLW D3,#2 ADD #2,D2 RORB D0,#1 CCC DOIO REST D0-D7,A0-A6 RTE DOIO: SAVE D0,D2,D3 ANDW PORTS,D3 ; Get Mask port initialized BEQ DONE ; Branch if not initialized LEA A2,ADDTBL ; Index address table ADDW D2,D2 ; Double port number MOV 0(A2)[D2],A2 ; Get address of port LEA A5,TCB0 ; Index baud rate table ADDW D2,D2 ; MOVB 5(A2),D7 ; Get status register B ANDB #3,D7 ; Mask off status bits BNE 10$ ; Branch ADDW #4,D2 10$: MOV 0(A5)[D2],A5 ; Get TCB MOV T.IHW(A5),A4 ; Index hardware address MOVB 1(A4),D5 ; Get uart status BTST #0,D5 ; Test data in available BEQ 30$ ; Branch if no data MOVB 3(A4),D1 ; Get data character MOV T.INC(A5),D7 ; Input char routine? BNE 20$ ; Branch one TRMICP ; Put into input buffer BR 30$ ; Try output 20$: MOV D7,A6 ; Move address into register CALL @A6 ; Call input routine 30$: BTST #2,D5 ; Test data out possible BEQ DONE ; Exit if not [101] MOV T.OTC(A5),D7 ; Get output character link BNE DONE ; Branch if ALT input TRMOCP 40$: TST D1 ; Any character available? BMI 60$ ; Yes, branch 50$: MOVB D1,3(A4) ; Output data to port BR DONE 60$: ANDW #^C80,@A5 ; Clear the OIP bit MOVB #8,2(A4) ; Disable Interupt on port BR DONE 70$: MOV D7,A6 ; Get into register CALL @A6 ; Call alt output routine BR 40$ ; Back to routine DONE: REST D0,D2,D3 RTN BAUD1: BYTE -1 ; 50 0 BYTE 0 ; 75 1 BYTE 1 ; 110 2 BYTE 2 ; 134.5 3 BYTE 3 ; 150 4 BYTE -1 ; 200 5 BYTE 4 ; 300 6 BYTE 5 ; 600 7 BYTE 6 ; 1200 8 BYTE 0A ; 1800 9 BYTE 07 ; 2000 10 BYTE 08 ; 2400 11 BYTE -1 ; 3600 12 BYTE 9 ; 4800 13 BYTE -1 ; 7200 14 BYTE 0B ; 9600 15 BYTE 0C ; 19200 16 BYTE -1 ; 38400 17 BYTE 0 ; 57600 18 (Clk/4) (Not Valid) BAUD0: BYTE 0 ; 50 0 BYTE -1 ; 75 1 BYTE 1 ; 110 2 BYTE 2 ; 134.5 3 BYTE -1 ; 150 4 BYTE 3 ; 200 5 BYTE 4 ; 300 6 BYTE 5 ; 600 7 BYTE 6 ; 1200 8 BYTE -1 ; 1800 9 BYTE -1 ; 200 10 BYTE 8 ; 2400 11 BYTE -1 ; 3600 12 BYTE 9 ; 4800 13 BYTE 0A ; 7200 14 BYTE 0B ; 9600 15 BYTE -1 ; 19200 16 BYTE 0C ; 38400 17 BYTE 0 ; 57600 18 (Clk/4) (Not Valid) EVEN BVAL: BLKB 16. EVEN ;[102] Updated for 32 bit Adressing ADDTBL: LWORD 0FFFFFF10 LWORD 0FFFFFF20 LWORD 0FFFFFF30 LWORD 0FFFFFF40 LWORD 0FFFFFF50 LWORD 0FFFFFF60 LWORD 0FFFFFF70 LWORD 0FFFFFF80 TCB0: BLKL 16. PORTS: WORD 0 IMASK1: BLKB 16. OPBIT1: BLKB 16. EVEN END .