; ADITIO.M68 - interface software for MAcrotech Adit card. ; Disclaimer ; Macrotech makes no representations or warranties with respect to the ; contents hereof and specifically disclaims any implied warranties of ; merchantibility or fitness for any purpose, useful or otherwise. ; ; ; ;This interface driver supports an Adit serial i/o board upto 16 channels. ;All ports have full modem (and therefore printer) control. ; ;Ports are addressed in the TRMDEF statement as 0 through 17 octal. ; Beta-test prerelease version 0.1 01JUN84 - not for distribution ; This driver is not DMA driven. This driver supports only one ADIT ; upto 16 channels. Tested with AMOS 1.1A(68). Future release will ; incorporate DMA features, extended driver entry ; routines for advanced features (ie: high speed block i/o through ; DMA), etc. ; last update 01JUN84 ; base port = 0E0h ; interrupt level = 7 ADITP=^H0FFFFE0 SEARCH SYS SEARCH SYSSYM SEARCH TRM objnam 0,0,[IDV] ; i/o port register map AIC=0 ; command register AIR1=1 ; data register AIR2=2 ; for setup AIR3=3 ; ditto SEMA=4 ; semaphore, busy when bit 0 is high ACK=5 ; read acks interrupt & gets status ; status register defines STS.IN=0 ; input is available STS.OT=1 ; space for output data STS.BS=2 ; channel is busy STS.DC=4 ; data carrier detect STS.BR=5 ; break detected STS.PA=6 ; UART parity error STS.FR=7 ; framing error DEFINE NOTBSY 10$$: BTST #0, SEMA(A3) BNE 10$$ ENDM PSECT BR CHROUT ; output init routine BR INIT ; interface init routine INTLVL: WORD 7 CHROUT: SAVE A0-A6, D0-D7 MOV T.IHM(A5), D7 ; get unit number MOV T.IHW(A5),A3 ; and hardware address AND #17, D7 ; D7 gets channel number LEA A6,COMAND+2 MOVB D7, @A6 MOVB #^H70, D0 ; interrupt on buffer ready NOTBSY CALL COMAND REST A0-A6, D0-D7 RTN ; init sets up interrupt structure ,modem block parms and initializes modem ; board. INIT: SUPVR SVLOK ; lock cpu for init MOV #ADITP,A3 ; index baord LEA A6,INITA ; INDEX INIT FLAG TSTB @A6 ; ADIT given full reset yet ? BNE 10$ ; yes-once is enuf. SETB @A6 ; flag we did reset it NOTBSY ; wait for it MOVB #^H0C0,D0 ; reset board command CALL COMAND ; reset it CLR D7 MOVW INTLVL, D7 ; get interrupt level LSL D7, #2 ; make it lword offset MOVW #434, A6 ; index int vector table SUB D7, A6 ; A6 points to table entry LEA A1, IROUT MOV A1, @A6 10$: MOVL T.IHM(A5), D7 ; D7 gets unit # MOV D7, D6 ; copy it DIV D7, #16. ; get board unit number ASL D7, #3. ; multiply by eight for offset ADDW D7, A3 ; A3 gets board's base address MOV A3, T.IHW(A5) ; save it for later MOV #ADITP,A3 ; get base adress again ASL D6, #2. ; make offset longword/channel LEA A6, TTABL ADD D6, A6 ; A6 index interrupt TRMDEF table MOV A5, @A6 ; set TRMDEF refererence NOTBSY ; wait for not busy ; When set up for single buffer, the ADIT hangs up on output MOVB #304, AIR1(A3) ; set 8 data, 1 stop, no parity or XON/XOFF ; So for now, use multiple output buffers ;;; MOVB #344, AIR1(A3) ; set 8 data, 1 stop, no parity or XON/XOFF ; set up baud rate MOVW T.BAU(A5), D7 ; get system rate LEA A6, BTABLE-2 ; index baud rate table -4 40$: ADDW #2, A6 ; pre-increment MOVB (A6)+, D6 ; compare to possible BEQ 100$ ; end of list CMPW D6, D7 ; match ? BNE 40$ ; no-try next MOVB (A6)+, AIR2(A3) ; set AIR2 MOVB (A6)+, AIR3(A3) ; set AIR3 LEA A6, COMAND+2 MOV T.IHM(A5), D7 AND #17, D7 MOVB D7, @A6 ; set channel number MOV #^H30, D0 ; init channel command CALL COMAND ; wait for ADIT, give command MOV #^H50, D0 NOTBSY CALL COMAND ; enable receive interrupts LSTS #0 ; return to user mode, unlock CPU. RTN 100$: LSTS #0 TYPECR RTN ; interrupt routine for reading characters IROUT: SVLOK SAVE A0-A6, D0-D7 MOV #ADITP, A3 ; A3 indexs hardware 20$: MOVB ACK(A3), D0 ; acknowledge interrupt & get channel MOV D0,D2 ; use imbedded channel number to do table lookup. AND #17, D0 ; strip to channel only ;; This is NASTY, SELF MODIFYING CODE, used for economy & speed. LEA A6,COMAND+2 MOVB D0,@A6 ; save channel number ; This stores the current channel number in the OR #???,D0 op code in the ; COMAND subroutine, so we do not have to keep generating the channel number ; prior to each COMAND call. ASL D0, #2. ; x 4 LEA A6, TTABL MOV 0(A6)[D0], D7 ; D7 gets TRMDEF pointer JEQ SPUR ; if zero its spurious MOV D7, A5 ; else point A5 to TRMDEF AND #^H0F0,D2 ; strip out channel from interrupt poll CMPB D2,#^H050 ; is it input ? BEQ RECV ; no-check for input ; send output data to ADIT as long as it is not busy and data is available. ; limit transfer to 64 bytes for now. XMIT: MOV #10.,D3 ; set maximum transfer count to 11. 10$: PUSH D3 TRMOCP POP D3 TST D1 BMI DISARM ; disable transmitter NOTBSY MOVB D1, AIR2(A3) ; yes-set data output byte MOV #^H60, D0 ; set single out command CALL COMAND ; do it NOTBSY MOVB AIR1(A3), D2 ; D2 gets ADIT status BTST #STS.OT, D2 ; more output space ? BEQ 20$ ; no DBF D3,10$ ; yes-loop if max count no te exceeded. ; end output process 20$: MOV #^H70, D0 ; enable xmit interrupts for next time CALL COMAND BR DONE ; no more data to output - clear OIP bit in status word DISARM: BCLR #7, @A5 ; clear OIP BR DONE ; receive all characters buffered. RECV: MOV #^H40, D0 ; make it read single data NOTBSY CALL COMAND ; send the command NOTBSY MOVB AIR2(A3), D1 ; get the byte SAVE A3,A5 TRMICP ; pass it to TRMSER REST A3,A5 MOVB AIR1(A3), D2 ; check status BTST #STS.IN, D2 ; got more data ? BNE RECV ; yes-loop til gone MOV #^H50, D0 ; no-rearm input interrupt CALL COMAND ; send the command BR DONE SPUR: MOV #^H20, D0 NOTBSY CALL COMAND ; clear framing & parity errors DONE: REST A0-A6, D0-D7 RTE ; COMAND adds the channel bias (stored in the immediate field of the first op) ; and sends the command to the ADIT card. Then, it waits for the ADIT to become ; ready for another command. COMAND: ORB #0, D0 ; add channel bias to command MOVB D0, AIC(A3) ; give to ADIT RTN EVEN INITA: WORD 0 ; board inted flag TTABL: BLKL 32. ; map of 32 possible TRMDEFs DEFINE BBITS RATE, AIR2, AIR3 BYTE RATE, AIR2, AIR3 ENDM BTABLE: BBITS 021,002,300 ; 38400 BBITS 020,006,300 ; 19200 BBITS 017,016,300 ; 9600 BBITS 015,036,300 ; 4800 BBITS 013,076,300 ; 2400 BBITS 010,176,300 ; 1200 BBITS 007,376,300 ; 600 BBITS 006,376,301 ; 300 BBITS 004,376,303 ; 150 BBITS 002,162,305 ; 110 BYTE 0 EVEN END .