;AM100L Serial Port Interface Driver for the AM-100/L ; ; ASL-02017-00 ; NOTICE ; ;All rights reserved. This software is the property of Alpha Microsystems ;and the material contained herein is the proprietary property and trade ;secrets of Alpha Microsystems, embodying substantial creative efforts and ;confidential information, ideas and expressions, no part of which may be ;reproduced or transmitted in any form or by any means, electronic, ;mechanical, or otherwise, including photocopying or input into any ;information storage or retrieval system without the express written ;permission of Alpha Microsystems. ; ;CAUTION: Unauthorized distribution or reproduction of this material may ;subject you to legal action. ; ; ;This interface driver supports the two serial ports contained on the ;AM-100/L CPU board. Unlike the AM-100/T, both ports have full modem ;(and therefore printer) control. ; ;Ports are addressed in the TRMDEF statement as 0 and 1. ; ;Edit History: ; ;[102] 27 October 1982 ; Changed to turn off interrupts faster. ;[101] 22 April 1982 ; Make sure our size is even. ;[100] 9 April 1982 ; Fix baud rate terminal to reflect BR1941-05 baud rate generator ; since that is what is used on the new rev. L and A boards. ; SEARCH SYS SEARCH SYSSYM SEARCH TRM OBJNAM AM100L.IDV PORT0 = ^H0FFFE20 ; I/O base for port 0 PORT1 = ^H0FFFE24 ; I/O base for port 1 PORTB = ^H0FFFE28 ; Baud rate generator port INTV0 = ^H068 ; Interrupt vector for port 0 INTV1 = ^H06C ; Interrupt vector for port 1 FTDEBUG=0 ; set to 1 for debug features DEFINE DEBUG ARG IF NE, FTDEBUG MOVB #^H0'ARG,^H0FFFE00 ENDC ENDM PAGE ;Define Miscellaneous Parameters and Constants ; ;Define 6850 Status Register Bits ; ST$RDRF = 0 ; 1 = Receive Data Register Full ST$TDRE = 1 ; 1 = Transmit Data Register Empty ST$DCD = 2 ; 1 = DCD bar has gone high (no carrier) ST$CTS = 3 ; 0 = CTS bar is low (OK to transmit) ST$FE = 4 ; 1 = Framing Error ST$OVRN = 5 ; 1 = Overrun Error ST$PE = 6 ; 1 = Parity Error ST$IRQ = 7 ; 1 = Interrupt has been requested ;Define 6850 Command Register Bits ; CM$RESET = 3 ; Master Reset for ACIA CM$16 = 1 ; Clock is divide by 16 CM$1STP = 24 ; 8 data bits, 1 stop bit, no parity CM$2STP = 20 ; 8 data bits, 2 stop bits, no parity CM$TXD = 0 ; RTS bar low, transmitter disabled CM$TXE = 40 ; RTS bar low, transmitter enabled CM$BREAK = 140 ; Force break CM$RCE = 200 ; Receiver Enabled ;Define I/O Port Offsets ; ;These are defined as offset to the base of the serial port block (i.e., base ;of the board + 4). ; P.SR = 0 ; Status Register (Input) P.CMD = 0 ; Command Register (Output) P.RCV = 2 ; Receiver Holding Register (Input) P.TXM = 2 ; Tranmitter Holding Register (Output) PAGE ;Driver Commumnications Area ; ;This is the standard branch table used by TRMDEF and TRMSER. Only TRMDEF ;is allowed to call the initialization routine. ; AM1: BR CHROUT ; character output routine BR INIT ; initialization routine NOP PAGE ;INIT Initialize the AM-100/L Port ; ;This routine is called by TRMDEF each time a port on the AM-100/L is defined. ;The routine must intialize the proper port to the specified configuration, ;or, if the default is specified, it must set the 100/L up for async 19200 baud ;operation. ; ;Inputs: D0 Specified baud rate code. ; A5 Points to terminal definition block. ; ;Outputs: Outputs to 100/L board only. ; ;Modifies: D1, A3, A4; 100/L command register; ; INIT: LEA A6,BAUDTB ; index the baud rate table MOVB 0(A6)[D0],D0 ; is it valid? JMI BDBAUD ; no - invalid baud rate TST T.IHM(A5) ; are we selecting port 0? BEQ 10$ ; yes - ;Set up port 1 baud rate load, I/O port, and interrupt vector MOVB #40,D2 ; no - select port 1 baud rate load MOV #PORT1,A4 ; and I/O port LEA A3,INTR1 ; index port 1 interrupt routine MOV A3,INTV1 ; store it BR 20$ ;Set up port 0 baud rate load, I/O port, and interrupt vector 10$: MOVB #20,D2 ; get port 0 select bit MOV #PORT0,A4 ; index port 0 LEA A3,INTR0 ; index port 0 interrupt routine MOV A3,INTV0 ; store it ;Send baud rate code to baud rate generator and reset ACIA 20$: ORB D0,D2 ; combine selector code with baud rate MOVB D2,PORTB ; send to baud rate generator MOV A4,T.IHW(A5) ; store I/O addr terminal definition blk MOV A5,OFF(A3) ; store term def ptr in interrupt routine MOVB #CM$RESET,@A4 ; reset the 6850 ACIA chip ;Set up the ACIA for 16X clock, correct # of stop bits, transmitter disabled, ; and receiver enabled MOVB #CM$16!CM$1STP!CM$TXD!CM$RCE,D2 CMPB D0,#2 ; did we want 110 baud? BNE 30$ ; no - MOVB #CM$16!CM$2STP!CM$TXD!CM$RCE,D2 30$: MOVB D2,@A4 ; set up ACIA DEBUG F0 RTN PAGE ;CHROUT Output Character Initiation Routine ; ;Enable the 6850 transmitter which generates an initial interrupt which ;will be dispatched to the transmitter routine, starting the output ;process. This routine is called by clock routine set up by TRMSER. ; ;Inputs: A5 Pointer to terminal definition block ; ;Outputs: None ; ;Modifies: None ; CHROUT: MOVB #CM$16!CM$1STP!CM$TXD!CM$RCE!CM$TXE,D7 CMPW T.BAU(A5),#2 ; are we set to 110 baud? BNE 10$ ; no - MOVB #CM$16!CM$2STP!CM$TXD!CM$RCE!CM$TXE,D7 10$: MOV T.IHW(A5),A6 ; set terminal definition index MOVB D7,@A6 ; enable transmitter DEBUG F1 RTN PAGE ;INTRn Define Serial Port Routines ; ;These routines contain code that is modified by the initialization routine. ;Called at interrupt level. ; ;Inputs: None ; ;Outputs: A5 Terminal definition block index ; ;Modifies: A5 INTR0: SVLOK ; turn off interrupts [102] SAVE A0-A6,D0-D7 ; save registers OFF=.-INTR0+2 ; define offset for modifying code MOV #7777,A5 ; set channel 0 terminal definition index BR GINTRP INTR1: SVLOK ; turn off interrupts [102] SAVE A0-A6,D0-D7 ; save registers MOV #7777,A5 ; set channel 1 terminal definition index ;fall thru to GINTRP... PAGE ;GINTRP Handle Serial Port Interrupt ; ;Come here whenever we get a serial port interrupt. Determine what type it ;is and dispatch to appropriate routine. Called at interrupt level. ; ;Inputs: A5 Terminal definition index ; All registers SAVEd on stack ; ;Outputs: D1 6850 Status Register ; A4 Pointer to base of I/O ports ; ;Modifies: D1, A4 ; GINTRP: MOV T.IHW(A5),A4 ; get I/O register base into A4 MOVB @A4,D1 ; read the 6850 status register BTST #ST$RDRF,D1 ; check receiver data register full flag BNE INPR ; and go process if set BTST #ST$TDRE,D1 ; check transmitter empty flag BNE OUTPR ; and go process if set BR INFI ; handle false interrupt ;INPR Input Character Interrupt Routine ; ;Come here whenever we get a receiver interrupt. Read the character from ;the AM-100/L and pass on to TRMSER. ; ;Inputs: A4 I/O register base ; All registers SAVEd on stack ; ;Outputs: None ; ;Modifies: Restores registers ; INPR: DEBUG F2 MOVB P.RCV(A4),D1 ; read the data character TRMICP ; go process the character INTX: REST A0-A6,D0-D7 ; restore registers RTE PAGE ;INFI False Interrupt Routine ; ;Come here when interrupt was caused by neither transmitter or receiver. ;The interrupt is either DCD change or spurious. In either case, we just ;ignore the interrupt. ; ;Inputs: D1 6850 Status Register ; A4 I/O register base address ; All registers SAVEd on stack ; ;Outputs: None ; ;Modifies: Restores registers ; INFI: DEBUG F3 REST A0-A6,D0-D7 ; restore register RTE ; return PAGE ;OUTPR Transmitter Interrupt Routine ; ;Come here on a transmitter interrupt. If another character is available ;for output, grab it and send it to the 6850. ;Otherwise, clear the OIP flag and dismiss interrupt. ; ;Inputs: D1 6850 Status Register ; A4 I/O register base address ; A5 Terminal definition index ; All registers SAVEd on the stack ; ;Outputs: Only to AM-100/L ; ;Modifies: Registers restored ; OUTPR: DEBUG F4 TRMOCP ; get next output character from TRMSER TST D1 ; data available? BPL OPRG ; yes - ANDW #^C,@A5 ; no - clear the OIP flag MOVB #CM$16!CM$1STP!CM$TXD!CM$RCE,D7 CMPW T.BAU(A5),#2 ; is terminal set for 110 baud? BNE 10$ ; no - MOVB #CM$16!CM$2STP!CM$TXD!CM$RCE,D7 10$: MOVB D7,@A4 ; set mode bits OPRD: BR INTX ; return ;Send character to transmitter OPRG: MOVB D1,P.TXM(A4) ; send character to 6850 BR INTX ; return PAGE ;Come here if an invalid baud rate was specified BDBAUD: TYPECR RTN ; just ignore initialization ;Define baud rate table BAUDTB: BYTE 0 ; 50 baud BYTE 1 ; 75 baud BYTE 2 ; 110 baud BYTE 3 ; 134.5 baud BYTE 4 ; 150 baud BYTE -1 ; 200 baud (not valid on 1941-05) [100] BYTE 5 ; 300 baud BYTE 6 ; 600 baud BYTE 7 ; 1200 baud BYTE 10 ; 1800 baud BYTE 11 ; 2000 baud [100] BYTE 12 ; 2400 baud BYTE 13 ; 3600 baud BYTE 14 ; 4800 baud BYTE 15 ; 7200 baud BYTE 16 ; 9600 baud BYTE 17 ; 19200 baud EVEN END .