;**************************************************************
;* *
;* INNER ACCESS 8 PORT SERIAL I/O DRIVER *
;* *
;**************************************************************
;
; REVISED 12/31/83 GW
; totally re-worked at Computerized Business Systems by NED 1/22/85
; increased efficiency & reliability of interrupt routine
; and multiple board handling.
;
;
; Initialize Port Number to Baud Rate in D0
;
INIT: MOV #IOADR,A4 ; get base address
MOV T.IHM(A5),D5 ; get port number
CMP D5,#<<NUMBRD*8>-1> ; greater than configuration?
JGT INIX ; yes - its in error
CLR D1 ;
LSR D5,#3 ; calc board select
BSET D5,D1 ;
MOVB D1,11(A4) ; enable one of eight boards
MOV T.IHM(A5),D5 ; get port number
AND #7,D5 ; mask for duart select
LSR D5,#1 ; calc duart select code
CLR D1
BSET D5,D1 ; enable duart chip
MOVB D1,10(A4) ;
MOVB #033,5(A4) ; enable chip interrupts
ADD #3,A4 ; initially select channel a
MOV T.IHM(A5),D5 ; get port number
AND #1,D5 ; even or odd?
BEQ INIT1 ; even select channel a
ADD #8,A4 ; select channel b
;Initialize Duart
INIT1: MOV A4,T.IHW(A5) ; save selected data port
MOVB #30,-1(A4) ; reset mr1 pointer & receiver
MOVB #13,-3(A4) ; set no parity, 8 bits, no rx rts
MOVB #17,-3(A4) ; set no tx rts,cts,1 stop bit
ASL D0,#1 ; turn baud rate code into offset
LEA A0,BAUDTB ; get base of baud rate table
MOVB 0(A0)[D0],D5 ; get first byte of entry
CMPB D5,#-1 ; is this a valid entry?
BNE 10$ ; no - display message
CALL BDBAUD
MOVB #0BB,D5
MOVB D5,-2(A4)
BR 20$
10$: MOVB D5,1(A4) ; yes - use it
MOVB 1(A0)[D0],-2(A4) ; send second byte of entry
; Store the Terminal Definition Table Base for this port
20$: LEA A6,TRMTBL
MOV T.IHM(A5),D5 ; get port number
LSL D5,#2 ; turn into offset
MOV A5,0(A6)[D5] ; store terminal def address
; Initialize the Interrupt Vector
LEA A1,INTRPT ; index interrupt routine
MOV A1,<11C-<AMV*4>> ; store interrupt address
MOVB #09,-1(A4) ; enable rcv , disable xmit
RTN
INIX: CRLF
TYPECR ?Unsupported Port Number
RTN
BDBAUD: TYPECR ?Invalid baud rate will default to 9600
RTN
;*************
;* CHROUT *
;*************
; Initiate Output to Port
CHROUT: MOV #IOADR,A6 ; get base address
MOV T.IHM(A5),D7 ; get port #
LSRW D7,#3 ; calc board number
CLRB D1
BSET D7,D1 ; form board select code
MOVB D1,11(A6) ; enable one of 8 i/o boards
MOV T.IHM(A5),D7 ; get port # again
AND #7,D7 ; mask for duart select
LSRW D7,#1 ; calc chip number
CLRB D1 ;
BSET D7,D1 ; form chip select code
MOVB D1,10(A6) ; enable duart chip
MOV T.IHW(A5),A6 ; get ch data port address
MOVB #4,-1(A6) ; enable channel xmit
RTN
;***********************
;* INTERRUPT ROUTINE *
;***********************
INTRPT: SVLOK ; lock processor
SAVE D1-D7,A4-A6
MOV #IOADR,A4
CLR D4 ; board number
CLR D5 ; will be chip number
INLUP: CLRB D7
BSET D4,D7 ; set up board enable code
MOVB D7,11(A4) ; enable board
MOVB 10(A4),D3 ; get interrupt status register
COMB D3 ; reverse bits
BNE INLP1 ; is int. coming from this board?
N.BRD: ADDW #1,D4 ; no - increment board number
CMPB D4,#NUMBRD ; is it greater than our configuration
BLT INLUP ; no - check next board
REST D1-D7,A4-A6
RTE
; D3 contains bits indicating chips generating interrupts
INLP1: BTST D5,D3 ; test for chip number in D5
BNE INLP2 ; its this one - go get it
N.CHP: ADDW #1,D5 ; increment to next chip
CMPB D5,#4 ; have we checked all chips?
BLT INLP1 ; no - do next one
CLRW D5
BR N.BRD ; yes - continue on
; D4 contains board number
; D5 contains chip number
INLP2: CLRB D7
BSET D5,D7 ; form chip select code
MOVB D7,10(A4) ; select chip
MOVW D4,D2 ; get board number
LSLW D2,#5 ; multiply by 32 to form offset
MOVW D5,D7 ; save chip number
LSLB D7,#3 ; chip number X 8 to form offset
ADDW D7,D2 ; form port number X 4
MOVB 5(A4),D1 ; read int. status register
ANDB #03,D1 ; is it Ch. A ?
BEQ 10$ ; yes - process
CALL INTPRT
10$: ADDW #4,D2 ; no - increment to CH. B
MOVB 5(A4),D1 ; read int. status register
LSRB D1,#4 ; shift down for processing
ANDB #03,D1 ; is it CH. B ?
BEQ 20$ ; yes - process
CALL INTPRT
20$: BR INLUP ; go check for more interrupts
INTPRT: MOV TRMTBL[~D2],A5 ; get address of Terminal Table
BTST #0,D1 ; is it the transmitter?
BNE TX.INT ; yes - go process
;
; PROCESS RECEIVE INTERRUPT
;
MOV T.IHW(A5),A6 ; get hardware address of port
MOVB @A6,D1 ; get character from port
TRMICP ; and process it
RTN
;
; PROCESS TRANSMIT INTERRUPT
;
TX.INT: TRMOCP ; get next character to output
MOV T.IHW(A5),A6 ; get hardware address of port
TST D1 ; check for valid character
BMI NO.MOR ; yes - output it
MOVB D1,@A6
RTN
NO.MOR: ANDW #^C<OIP>,@A5 ; clear output in progress flag
MOVB #8.,-1(A6) ; and disable xmitter
RTN
;
; Table to store addresses of Terminal Definition Tables for each port
TRMTBL:
LWORD 0 ; port 0
LWORD 0 ; port 1
LWORD 0 ; port 2
LWORD 0 ; port 3
LWORD 0 ; port 4
LWORD 0 ; port 5
LWORD 0 ; port 6
LWORD 0 ; port 7
IF GE,NUMBRD-2
LWORD 0 ; port 8
LWORD 0 ; port 9
LWORD 0 ; port 10
LWORD 0 ; port 11
LWORD 0 ; port 12
LWORD 0 ; port 13
LWORD 0 ; port 14
LWORD 0 ; port 15
ENDC
IF GE,NUMBRD-3
INTTB3: LWORD 0 ; port 16
LWORD 0 ; port 17
LWORD 0 ; port 18
LWORD 0 ; port 19
LWORD 0 ; port 20
LWORD 0 ; port 21
LWORD 0 ; port 22
LWORD 0 ; port 23
ENDC
IF GE,NUMBRD-4
INTTB4: LWORD 0 ; port 24
LWORD 0 ; port 25
LWORD 0 ; port 26
LWORD 0 ; port 27
LWORD 0 ; port 28
LWORD 0 ; port 29
LWORD 0 ; port 30
LWORD 0 ; port 31
ENDC
IF GE,NUMBRD-5
INTTB5: LWORD 0 ; port 32
LWORD 0 ; port 33
LWORD 0 ; port 34
LWORD 0 ; port 35
LWORD 0 ; port 36
LWORD 0 ; port 37
LWORD 0 ; port 38
LWORD 0 ; port 39
ENDC
IF GE,NUMBRD-6
INTTB6: LWORD 0 ; port 40
LWORD 0 ; port 41
LWORD 0 ; port 42
LWORD 0 ; port 43
LWORD 0 ; port 44
LWORD 0 ; port 45
LWORD 0 ; port 46
LWORD 0 ; port 47
ENDC
IF GE,NUMBRD-7
INTTB7: LWORD 0 ; port 48
LWORD 0 ; port 49
LWORD 0 ; port 50
LWORD 0 ; port 51
LWORD 0 ; port 52
LWORD 0 ; port 53
LWORD 0 ; port 54
LWORD 0 ; port 55
ENDC
IF GE,NUMBRD-8. ;
INTTB8: LWORD 0 ; port 56
LWORD 0 ; port 57
LWORD 0 ; port 58
LWORD 0 ; port 59
LWORD 0 ; port 60
LWORD 0 ; port 61
LWORD 0 ; port 62
LWORD 0 ; port 63
ENDC