*****************************************************
*  AutoBaud Programming Example Using Interrupts    *
*         and the Control Character Table.          *
*                                                   *
* This code is derived from the UART sample code    *
* on page 7-170 of the 68360 UM but uses 4 transmit *
* and 4 receive BDs along with an interrupt driven  *
* receive routine and an entry in the control char. *
* table.                                            *
*****************************************************
* 1) The code sets up SCC3 in UART mode
* 1a) Code sets up SCC4 to receive  (LAW)               *
* 2) It sets up 4 transmit buffer descriptors that      *
*    will send data when the transmitter is enabled.    *
* 3) It sets up 4 receive buffer descriptors to receive *
* the incoming data                                     *
* 4) It sets up the vectors to the interrupt handling   *
* routines                         						*
* 5) It turns on the SCC4 receiver. ATB will not 
*    interrupt until SCC4 gets three full clocks fr BRG4* 
*    so there is a large delay loop to insure this      *  
* 6) It sets the ATB bit in BRGC4 to one                *
* 7) Finally, it turns on SCC3 TX and RX                *
* in local loopback mode                                *
* 8) When there is a sucessful ATB lock, the interrupt  *
*    routine for ATB will save the new BRGC4 value into	*
*    address 404000 and then trap back to the monitor   *
*    with a graceful exit                               *
*                                    JS 7/13/94 (ORG)   *
*                                    JS 7/13/94 (ORG)   * 
*                                    SI 9/25/94			*
*                                    LAW 1/18/95        * 
*********************************************************
* If you wish to move this code so that it works on     *
* another SCC, there are quite a few things that need to*
* be done.                                              *
*       1) Change the names of all of the SCC equates   *
*       2) Change the SCC4PB equate to SCCx and set it  *
*          to the correct offset (see page 3-4)         *
*       3) Change the equate for the SCC Vector         *
*       4) Change the port pin setup instructions so    *
*          that they activate the correct pins          *
*       5) Change the SICR register so that the correct *
*          SCC gets clocking                            *
*       6) Change the INIT RX&TX PARAMETERS command so  *
*          that it refers to the correct SCC (p. 7-7)   *
*       7) Change the CIMR setup so that the new SCC    *
*          can generate interrupts                      *
*       8) Change the CISR clearing in the interrupt    *
*          service routine so that it clears the bit    *
*          corresponding to the new SCC       			*
*														*
*NOTE: Autobaud REQUIRES the Autobauding SCC to be 		*
*      connected to it's own BRG                        *
*      SCC4 <- BRG4										*
*      SCC3 <- BRG3										*
*      SCC2 <- BRG2										*
*      etc												*
***********************************************************************
*
* Board Specific Equates
INIT      EQU     $0403000        ; QUADS Board DRAM User Space
AUTOBD_DV EQU   $0404000        ; saved DIV and CD bits to check
DELAY     EQU   $7fff           ; BIG delay loop
************************** DUAL PORT RAM ******************************
MBAR    EQU     $03FF00 ; Module Base Address, (MBAR)=REGB
*
***********************************************************************
* The following equates assume that they will be used in register
* indirect addressing.  The address register  should hold the base
* address of the QUICC internal memory.  All system equates are
* offsets into this memory
REGB    EQU     $1000   ; Base address of Internal Registers
SCC3PB  EQU     $0E00   ; SCC3 Protocol Base address
SCC4PB  EQU     $0F00   ; SCC4 Protocol Base Address                       ; LAW add one SCC for testing
************************ SIM Module registers **************************
MCR     EQU     REGB+$0000      ; Module Configuration
*
************************ CPM Module registers *******************
*
*** SDMA
SDSR    EQU     REGB+$051C      ; SDMA Status
SDCR    EQU     REGB+$051E      ; SDMA Configuration Register
SDAR    EQU     REGB+$0520      ; SDMA Address Register
*** CP Interrupt
CICR    EQU     REGB+$0540      ; CP Interrupt Configuration
CIPR    EQU     REGB+$0544      ; CP Interrupt Pending
CIMR    EQU     REGB+$0548      ; CP Interrupt Mask
CISR    EQU     REGB+$054C      ; CP Interrupt In-service
*** Port A, B, C
PADIR   EQU     REGB+$0550      ; Port A Data Direction Assignment
PAPAR   EQU     REGB+$0552      ; Port A Pin Function Assignment
PAODR   EQU     REGB+$0554      ; Port A Open Drain Assignment
PADAT   EQU     REGB+$0556      ; Port A Data Content
*
PBDIR   EQU     REGB+$06B8      ; Port B Data Direction Assignment
PBPAR   EQU     REGB+$06BC      ; Port B Pin Function Assignment
PBODR   EQU     REGB+$06C0      ; Port B Open Drain Assignment
PBDAT   EQU     REGB+$06C4      ; Port B Data Content
*
PCDIR   EQU     REGB+$0560      ; Port C Data Direction Assignment
PCPAR   EQU     REGB+$0562      ; Port C Pin Assignment
PCSO    EQU     REGB+$0564      ; Port C Special Options
PCDAT   EQU     REGB+$0566      ; Port C Data Content
PCINT   EQU     REGB+$0568      ; Port C Interrupt Control
*** CP
CR      EQU     REGB+$05C0      ; CP Command
RCCR    EQU     REGB+$05C4      ; RISC Configuration
RTER    EQU     REGB+$05D6      ; RISC Timer Event Register
RTMR    EQU     REGB+$05DA      ; RISC Timer Mask Register
* BRG 1, 2, 3, 4
BRGC1   EQU     REGB+$05F0      ; BRG1 Configuration
BRGC2   EQU     REGB+$05F4      ; BRG2 Configuration
BRGC3   EQU     REGB+$05F8      ; BRG3 Configuration
BRGC4   EQU     REGB+$05FC      ; BRG4 Configuration
*** SCC 1, 2, 3, 4
* SCC3
GSMR_L3 EQU     REGB+$0640      ; SCC3 General Mode
GSMR_H3 EQU     REGB+$0644      ; SCC3 General Mode
PSMR3   EQU     REGB+$0648      ; SCC3 Protocol Specific Mode
TODR3   EQU     REGB+$064C      ; SCC3 Transmit On Demand
DSR3    EQU     REGB+$064E      ; SCC3 Data Sync
SCCE3   EQU     REGB+$0650      ; SCC3 Event
SCCM3   EQU     REGB+$0654      ; SCC3 Mask
SCCS3   EQU     REGB+$0657      ; SCC3 Status
* SCC4
GSMR_L4 EQU     REGB+$0660      ; SCC4 General Mode
GSMR_H4 EQU     REGB+$0664      ; SCC4 General Mode
PSMR4   EQU     REGB+$0668      ; SCC4 Protocol Specific Mode
TODR4   EQU     REGB+$066C      ; SCC4 Transmit On Demand
DSR4    EQU     REGB+$066E      ; SCC4 Data Sync
SCCE4   EQU     REGB+$0670      ; SCC4 Event
SCCM4   EQU     REGB+$0674      ; SCC4 Mask
SCCS4   EQU     REGB+$0677      ; SCC4 Status
*** Serial Interface
SIMODE  EQU     REGB+$06E0      ; SI Mode
SIGMR   EQU     REGB+$06E4      ; SI Global Mode
SISTR   EQU     REGB+$06E6      ; SI Status
SICMR   EQU     REGB+$06E7      ; SI Command
SICR    EQU     REGB+$06EC      ; SI Clock Routing
SIRP    EQU     REGB+$06F0      ; SI RAM Pointer
SIRAM   EQU     REGB+$0700      ; SI Routing RAM

************************ END of SIM/CPM Register MAP *******************

************************ SCC Parameters ********************************
****** SCC3
RBASE3  EQU     SCC3PB+$000     ; SCC3 RX BD Base Address
TBASE3  EQU     SCC3PB+$002     ; SCC3 TX BD Base Address
RFCR3   EQU     SCC3PB+$004     ; SCC3 RX Function Code
TFCR3   EQU     SCC3PB+$005     ; SCC3 TX Function Code
MRBLR3  EQU     SCC3PB+$006     ; SCC3 MAX Buffer Length - RX
RSTATE3 EQU     SCC3PB+$008     ; SCC3 RX Internal State
RBPRT3  EQU     SCC3PB+$010     ; SCC3 RX BD Pointer
TSTATE3 EQU     SCC3PB+$018     ; SCC3 TX Internal State
TBPRT3  EQU     SCC3PB+$020     ; SCC3 TX BD Pointer
RCRC3   EQU     SCC3PB+$028     ; SCC3 Temp Receive CRC
TCRC3   EQU     SCC3PB+$02C     ; SCC3 Temp Transmit CRC
CRC_C3  EQU     SCC3PB+$030     ; SCC3 CRC Constant Total-Transparent
CRC_P3  EQU     SCC3PB+$034     ; SCC3 CRC Preset Total-Transparent

************************** Specific Parameters ******************************

* SCC3, UART Specific Parameters
MAXIDL3 EQU     SCC3PB+$38      ; SCC3 MAX IDLe cchars
IDLC3   EQU     SCC3PB+$3A      ; SCC3 temp IDLe Counter
BRKCR3  EQU     SCC3PB+$3C      ; SCC3 BReaK Count Register (TX)
PAREC3  EQU     SCC3PB+$3E      ; SCC3 Parity Error Counter (RX)
FRMER3  EQU     SCC3PB+$40      ; SCC3 Framing Error Counter (RX)
NOSEC3  EQU     SCC3PB+$42      ; SCC3 Noise Counter (RX)
BRKEC3  EQU     SCC3PB+$44      ; SCC3 BReaK Condition Counter (RX)
BRKLN3  EQU     SCC3PB+$46      ; SCC3 Last BReaK Length (RX)
UADDR13 EQU     SCC3PB+$48      ; SCC3 UART Address Character 1
UADDR23 EQU     SCC3PB+$4A      ; SCC3 UART Address Character 2
RETMP3  EQU     SCC3PB+$4C      ; SCC3 Temp storage
TOSEQ3  EQU     SCC3PB+$4E      ; SCC3 TX out of sequence Character
CCHAR13 EQU     SCC3PB+$50      ; SCC3 Control Character 1
CCHAR23 EQU     SCC3PB+$52      ; SCC3 Control Character 2
CCHAR33 EQU     SCC3PB+$54      ; SCC3 Control Character 3
CCHAR43 EQU     SCC3PB+$56      ; SCC3 Control Character 4
CCHAR53 EQU     SCC3PB+$58      ; SCC3 Control Character 5
CCHAR63 EQU     SCC3PB+$5A      ; SCC3 Control Character 6
CCHAR73 EQU     SCC3PB+$5C      ; SCC3 Control Character 7
CCHAR83 EQU     SCC3PB+$5E      ; SCC3 Control Character 8
RCCM3   EQU     SCC3PB+$60      ; SCC3 RX Control Character Mask
RCCR3   EQU     SCC3PB+$62      ; SCC3 RX Control Character
RLBC3   EQU     SCC3PB+$64      ; SCC3 RX Last Break Character

****** SCC4
RBASE4  EQU     SCC4PB+$000     ; SCC4 RX BD Base Address
TBASE4  EQU     SCC4PB+$002     ; SCC4 TX BD Base Address
RFCR4   EQU     SCC4PB+$004     ; SCC4 RX Function Code
TFCR4   EQU     SCC4PB+$005     ; SCC4 TX Function Code
MRBLR4  EQU     SCC4PB+$006     ; SCC4 MAX Buffer Length - RX
RSTATE4 EQU     SCC4PB+$008     ; SCC4 RX Internal State
RBPRT4  EQU     SCC4PB+$010     ; SCC4 RX BD Pointer
TSTATE4 EQU     SCC4PB+$018     ; SCC4 TX Internal State
TBPRT4  EQU     SCC4PB+$020     ; SCC4 TX BD Pointer
RCRC4   EQU     SCC4PB+$028     ; SCC4 Temp Receive CRC
TCRC4   EQU     SCC4PB+$02C     ; SCC4 Temp Transmit CRC
CRC_C4  EQU     SCC4PB+$030     ; SCC4 CRC Constant Total-Transparent
CRC_P4  EQU     SCC4PB+$034     ; SCC4 CRC Preset Total-Transparent

************************** Specific Parameters ******************************

* SCC4, UART Specific Parameters
MAXIDL4 EQU     SCC4PB+$48      ; SCC4 MAX IDLe cchars
IDLC4   EQU     SCC4PB+$4A      ; SCC4 temp IDLe Counter
BRKCR4  EQU     SCC4PB+$4C      ; SCC4 BReaK Count Register (TX)
PAREC4  EQU     SCC4PB+$4E      ; SCC4 Parity Error Counter (RX)
FRMER4  EQU     SCC4PB+$40      ; SCC4 Framing Error Counter (RX)
NOSEC4  EQU     SCC4PB+$42      ; SCC4 Noise Counter (RX)
BRKEC4  EQU     SCC4PB+$44      ; SCC4 BReaK Condition Counter (RX)
BRKLN4  EQU     SCC4PB+$46      ; SCC4 Last BReaK Length (RX)
UADDR14 EQU     SCC4PB+$48      ; SCC4 UART Address Character 1
UADDR24 EQU     SCC4PB+$4A      ; SCC4 UART Address Character 2
RETMP4  EQU     SCC4PB+$4C      ; SCC4 Temp storage
TOSEQ4  EQU     SCC4PB+$4E      ; SCC4 TX out of sequence Character
CCHAR14 EQU     SCC4PB+$50      ; SCC4 Control Character 1
CCHAR24 EQU     SCC4PB+$52      ; SCC4 Control Character 2
CCHAR34 EQU     SCC4PB+$54      ; SCC4 Control Character 3
CCHAR44 EQU     SCC4PB+$56      ; SCC4 Control Character 4
CCHAR54 EQU     SCC4PB+$58      ; SCC4 Control Character 5
CCHAR64 EQU     SCC4PB+$5A      ; SCC4 Control Character 6
CCHAR74 EQU     SCC4PB+$5C      ; SCC4 Control Character 7
CCHAR84 EQU     SCC4PB+$5E      ; SCC4 Control Character 8
RCCM4   EQU     SCC4PB+$60      ; SCC4 RX Control Character Mask
RCCR4   EQU     SCC4PB+$62      ; SCC4 RX Control Character
RLBC4   EQU     SCC4PB+$64      ; SCC4 RX Last Break Character

* Program Specific Equates
MBUFS   EQU     $0010           ; Max Buffer Size = 16 bytes
SCC3VEC EQU     $1C             ; Vector for SCC3 (5 bits)
SCC4VEC EQU     $1b             ; Vector for SCC4 (5 bits)
*********
* Start of Program
*********

	ORG     INIT

*** Get Pointer to Base of DPRAM
	move.l  #7,d0           ; "0111" is the function code for CPU Space
	movec   d0,SFC          ; Store "0111" into both the Src Fcn Code Reg
	movec   d0,DFC          ; and the Dest. Fcn Code Reg
	moves.l MBAR,a0         ; Move MBAR into a0
	move.l  a0,d0
	andi.l  #$ffffe000,d0   ; Extract the base address from MBAR
	move.l  d0,a5           ; Move it to a5 for register indexing

*** Set up SDMA Control Register for SCCs
	move.w  #$0740,SDCR(a5) ; SDMA interrupt service mask = 7,
*                               ;  bus arbit. priority = 4

*** Set up Port A Pins
* to get PA4&5 to be Rxd3 & Txd3, PA6 is RXD4, set PAPAR, PADIR, and PAODR as in
* Table 7-16 on page 7-351.
	or.w    #$4170,PAPAR(a5)        ; bits 4&5&6 must be 1
	and.w   #$BEDF,PAODR(a5)        ; bit 5 must be zero
	and.w   #$FF8F,PADIR(a5)        ; bits 4&5&6 must be 0
	ori.w   #$4100,PADIR(a5)	    ; want to see BRG1 and 4 


*** Set up Port C pins
* to get PC8&PC9 to be CTS3 and CD3 and PC2 to be RTS3,
* we set PCPAR, PCDIR, and PCODR as in Table 7-18 on page 7-358.
	and.w   #$F0FF,PCPAR(a5)        ; bits 8,9,10,11 must = 0
	or.w    #$0004,PCPAR(a5)        ; ad bit 2 must =1         
	and.w   #$FFF3,PCDIR(a5)        ; bits 2, 8, & 9,10,11 must be = 0
	or.w	#$ff00,PCDIR(a5)		; LAW - ignore CTS3/4 CD3/4 - external loop on board RXD4 <-TXD3
	or.w    #$00FF,PCSO(a5)         ; bits 8&9,10,11 =0 cd/cts always on
*                                       ; bit 2 is a don't care  



*** Set up BRG1 for SCC3
	move.l  #$010144,BRGC1(a5)      ; set brg1 to baud rate 9600bits/s
*                                       ; CD=$A2, EN=1, DIV16=0
*                                       ; 25Mhz/($A2+1)=153374=~9,585 * 16
*                                       ; and GSMR selects 16x clock
*** Set up BRG4 for SCC4
	move.l  #$01001A,BRGC4(a5)      ; set brg4 to baud rate 115Kbits/s to test ATB
*                                       ; CD=$A2, EN=1, DIV16=0 - 
*										; can't turn ATB on yet - must give BRG 3 clocks
*										; at fastest clock rate or no interrupt occurs on SCC4
*                                       ; 25Mhz/($A2+1)=153374=~9,585 * 16
*                                       ; and GSMR selects 16x clock
*										; also BRG must be identical to SCC number when ATB 
	move.l  #$1B000000,SICR(a5)     ; route brg4 to scc4, brg1 to scc3 and select nmsi

 
*** Set up General SCC3 Parameters
	move.w  #$0000,RBASE3(a5)       ; Receive BDs start at 0(a5)
	move.w  #$0020,TBASE3(a5)       ; Transmit BDs start at 32(a5) 
	move.b  #$18,RFCR3(a5)  ; mot=1(msbyte first), rx function code = 1000
	move.b  #$18,TFCR3(a5)  ; mot=1(msbyte first), tx function code = 1000
	move.w  #MBUFS,MRBLR3(a5)       ; max. bytes per Buffer (16)

*** Execute the INIT RX & TX Parameters for SCC3
	move.w  #$0081,CR(a5)   ; initialize transmit and receive parameter
*                               ; in the parameter ram of scc3
*** Set up General SCC4 Parameters
	move.w  #$0000,RBASE4(a5)       ; Receive BDs start at 0(a5)
	move.w  #$0020,TBASE4(a5)       ; Transmit BDs start at 32(a5) 
	move.b  #$18,RFCR4(a5)  ; mot=1(msbyte first), rx function code = 1000
	move.b  #$18,TFCR4(a5)  ; mot=1(msbyte first), tx function code = 1000
	move.w  #MBUFS,MRBLR4(a5)       ; max. bytes per Buffer (16)
	move.w  #$00C1,CR(a5)   ; initialize transmit and receive parameter
*                               ; in the parameter ram of scc4

*** Set up UART Specific Parameters
	move.w  #$0005,MAXIDL3(a5)      ; set idle timeout to a value
	move.w  #$0001,BRKCR3(a5)       ; stop trans issues 1 break chara.
	move.w  #$0,PAREC3(a5)          ; clear error counters
	move.w  #$0,FRMER3(a5)
	move.w  #$0,NOSEC3(a5)
	move.w  #$0,BRKEC3(a5)
	move.w  #$0,UADDR13(a5)         ; no multidrop address
	move.w  #$0,UADDR23(a5)
	move.w  #$0,TOSEQ3(a5)          ; No CTRL Char to be sent
	move.w  #$000D,CCHAR13(a5)      ; CR will close buffer
	move.w  #$8000,CCHAR23(a5)      ; No more control Characters
	move.w  #$c0ff,RCCM3(a5)        ; No masking of received Ctl Chars

	move.w  #$0005,MAXIDL4(a5)      ; set idle timeout to a value
	move.w  #$0001,BRKCR4(a5)       ; stop trans issues 1 break chara.
	move.w  #$0,PAREC4(a5)          ; clear error counters
	move.w  #$0,FRMER4(a5)
	move.w  #$0,NOSEC4(a5)
	move.w  #$0,BRKEC4(a5)
	move.w  #$0,UADDR13(a5)         ; no multidrop address
	move.w  #$0,UADDR23(a5)
	move.w  #$0,TOSEQ4(a5)          ; No CTRL Char to be sent
	move.w  #$000D,CCHAR13(a5)      ; CR will close buffer
	move.w  #$8000,CCHAR23(a5)      ; No more control Characters
	move.w  #$c0ff,RCCM4(a5)        ; No masking of received Ctl Chars

*** Set up the Receive BDs for SCC3
* (set the ready bit after the Buffer pointer is set up)
	move.l  a5,a0
	add.w   RBASE3(a5),a0           ; make pointer to Receive BDs
* BD1
	clr.w   2(a0)                   ; initialize length
	move.l  #RXBUF+0*MBUFS,4(a0)    ; pointer to buffer number 0
	move.w  #$9000,(a0)             ; empty, nowrap, int
* BD2
	clr.w   10(a0)                  ; initialize length
	move.l  #RXBUF+1*MBUFS,12(a0)   ; pointer to buffer number 1
	move.w  #$9000,8(a0)            ; empty, nowrap, int
* BD3
	clr.w   18(a0)                  ; initialize length
	move.l  #RXBUF+2*MBUFS,20(a0)   ; pointer to buffer number 2
	move.w  #$9000,16(a0)           ; empty, nowrap, int
* BD4
	clr.w   26(a0)                  ; initialize length
	move.l  #RXBUF+3*MBUFS,28(a0)   ; pointer to buffer number 3
	move.w  #$b000,24(a0)           ; empty, wrap, int

*** Set up Process Receive Data Pointer (part of interrupt service routine)
	move.w  RBASE3(a5),PRDPTR       ; PRDPTR points to BD#1

**** Set up rx decriptors for SCC4
* (set the ready bit after the Buffer pointer is set up)
	move.l  a5,a0
	add.w   RBASE4(a5),a0           ; make pointer to Receive BDs
* BD1
	clr.w   2(a0)                   ; initialize length
	move.l  #RXBUF+0*MBUFS,4(a0)    ; pointer to buffer number 0
	move.w  #$9000,(a0)             ; empty, nowrap, int
* BD2
	clr.w   10(a0)                  ; initialize length
	move.l  #RXBUF+1*MBUFS,12(a0)   ; pointer to buffer number 1
	move.w  #$9000,8(a0)            ; empty, nowrap, int
* BD3
	clr.w   18(a0)                  ; initialize length
	move.l  #RXBUF+2*MBUFS,20(a0)   ; pointer to buffer number 2
	move.w  #$9000,16(a0)           ; empty, nowrap, int
* BD4
	clr.w   26(a0)                  ; initialize length
	move.l  #RXBUF+3*MBUFS,28(a0)   ; pointer to buffer number 3
	move.w  #$b000,24(a0)           ; empty, wrap, int

*** Set up Process Receive Data Pointer (part of interrupt service routine)
	move.w  RBASE4(a5),PRDPTR       ; PRDPTR points to BD#1

*** Set up Transmit BDs for SCC3
* (set the ready bit after the Buffer pointer & length is set up)
	movea.l a5,a0                   ; get pointer to base of DPRAM
	adda.w  TBASE3(a5),a0           ; make pointer to Transmit BDs
* BD1
	move.w  #13,2(a0)               ; length 13
	move.l  #TBUF0,4(a0)            ; pointer to buffer #0
	move.w  #$8800,(a0)             ; ready, nowrap, noint, Normal CTS
* BD2
	move.w  #13,10(a0)              ; length 13
	move.l  #TBUF1,12(a0)           ; pointer to buffer #1
	move.w  #$8800,8(a0)            ; ready, nowrap, noint, normal CTS
* BD3
	move.w  #13,18(a0)              ; length 13
	move.l  #TBUF2,20(a0)           ; pointer to buffer #2
	move.w  #$8800,16(a0)           ; ready, nowrap, noint, normal CTS
* BD4
	move.w  #13,26(a0)              ; length 13
	move.l  #TBUF3,28(a0)           ; pointer to buffer #3
	move.w  #$a800,24(a0)           ; ready, nowrap, noint, normal CTS



*** Set up Vector Table, Configure SCC3 to be SCCa.
* 
* Set up CICR. (In most situations, the VBA2-0 bits and the IRL2-0 bits
* would be set by the kernal and the SCC Priority bits would be set
* by the SCC control program ("user code")).  The QUADS boot rom
* does not set up this register so this code will do both in separate
* steps.

* kernel step
	move.l  #$00008040,CICR(a5)     ; Int Level=4, Vec Base=2
*                                       ; *note* VEC BASE Must Be >=2

* user steps
	move.l  CICR(a5),d0             ; get CICR
	andi.l  #$0000e0e0,d0           ; mask out all but IRL & VBA
	clr.l   d1
	clr.l   d2
	move.b  d0,d1                   ; store copy of VBA
	move.b  d0,d2                   ; store 2ce for other vec calc 10/3/94
	ori.l   #$001B1f00,d0           ; Priority=4,3,2,1; LAW 10/3/94
*                                       ; Grouped SCCs
	move.l  d0,CICR(a5)                     

* now calculate the Vector Table Location for SCCa Exception Vector
	ori.b   #SCC4VEC,d1             ; concatenate VBA with Vec Num
	asl.l   #2,d1                   ; create offset into vector table
	movec.l VBR,a4                  ; get Vector Base Register
	move.l  #SCC4INT,0(a4,d1)       ; put address of service routine
*                                       ; into vector table     


* now calculate the Vector Table Location for SCCb Exception Vector
	ori.b   #SCC3VEC,d2             ; concatenate VBA with Vec Num
	asl.l   #2,d2                   ; create offset into vector table
	movec.l VBR,a4                  ; get Vector Base Register
	move.l  #SCC3INT,0(a4,d2)       ; put address of service routine
*                                       ; into vector table     


*** Final Set up
	move.w  #$ffff,SCCE3(a5)        ; clear scc3 event register
	move.w  #$0001,SCCM3(a5)        ; enable rx interrupts
	or.l  #$10000000,CIMR(a5)       ; Allow SCC3 interrupts
	andi.w  #$f8ff,SR               ; Set CPU IMASK to 0
	
	move.l  #$00000060,GSMR_H3(a5)  ; rx fifo set to 3 bytes
*                                       ; tx FIFO is 1 byte
	move.l  #$00028044,GSMR_L3(a5)  ; tdcr ='10', txclk is 16* clock mode
*                               ; rdcr ='10', rxclk is 16* clock mode
*                               ; norml mode 4 atb tst 
*                               ; channel protocol mode = uart
	move.w  #$b000,PSMR3(a5)        ; set automatic flow control
*                               ; character length set to 8 bits


	move.w  #$ffff,SCCE4(a5)        ; clear scc4 event register
	move.w  #$0200,SCCM4(a5)        ; enable rx interrupts & autobaud interrupt 10/3/94
	or.l  #$18000000,CIMR(a5)       ; Allow SCC4 interrupts
	
	move.l  #$00000060,GSMR_H4(a5)  ; rx fifo set to 3 bytes
*                                       ; tx FIFO is 1 byte
	move.l  #$00028004,GSMR_L4(a5)  ; tdcr ='10', txclk is 16* clock mode
*                               ; rdcr ='10', rxclk is 16* clock mode
*                               ; local loopback mode
*                               ; channel protocol mode = uart
	ori.l   #$00000020,GSMR_L4(a5) ; enable receiver 
	move.w  #$b000,PSMR4(a5)        ; set automatic flow control
*                               ; character length set to 8 bits
    clr.l   d5
    move.w  #DELAY,d5
WAIT dbeq   d5,WAIT             ; set up a delay loop to make sure
CNTNU  NOP 						;SCC gets enough clocks to wake up
*    
    move.l  #$01200D,BRGC4(a5)  ; turn ATB bit on at last minute
	ori.l   #$00000030,GSMR_L3(a5)  ; enable transmitter and receiver

self    bra     self                    ; loop forever


*** When this code is "done", all four TX Buffers will have been sent (and
*thus the Ready Bit in each BD will be clear).  The Rx Routine will "service"
*each Rx BD when the RXB event bit is set in the Event Register.
*The TXB bit does not generate an interrupt but will be set each time the
*TX Buffer is sent.
*The received data will appear in the RX Buffers, but they will not 
*correspond to the sending TX buffers because there is no framing 
*structure in UART.  However, the control character settings tell
*the receiver to close a buffer when the $D is received and thus
*the fourth TX buffer will fill a separate BD from the first 3. 

**** SCC3 Interrupt Routine
* The framework for this routine can be found on page D-12 of the 68302 UM
* It has been changed to accomodate CM mode.  The condition for stopping
* is no longer the E bit set (because in CM mode, the E bit is ALWAYS set)
* The BD processing now stops when PRDPTR=RBPRT4.  ***Note that RBPRT4 is
* now an offset into DPRAM rather than the BD number (1..8)

SCC3INT movem.l d0-d2/a0-a2,-(a7)       ; save context registers
	move.w  SCCE3(a5),-(a7) ; temporarily store SCC event 
*                               ; register on stack
	move.w  #$ffff,SCCE3(a5)        ; Clear all SCC events 
	move.w  (a7),d2         ; get a copy of the register
	andi.w  #1,d2           ; is RX set?
	beq     INT1
	bsr     REC_BD          ;   if so, process the BD
INT1    move.l  #$10000000,CISR(a5)     ; clear SCC3 bit in ISR 
	move.w  (a7)+,d2        ; remove SCCE3 from stack
	movem.l (a7)+,d0-d2/a0-a2       ; Restore Context
	rte

REC_BD  move.w  PRDPTR,d0       ; put PRDPTR into d0
	move.l  a5,a0
	add.w   d0,a0           ; a0 is absolute pointer to unprocessed BD
	move.w  (a0),d0         ; get copy of BD status word
	andi.w  #$001f,d0       ; save error indicators
	bne     ERR_HAND        ; branch to error handler if errors
*
** Process the received data here
*
	clr.w   2(a0)           ; Clear the length word
	andi.w  #$f200,(a0)     ; clear status bits
	bset.b  #7,(a0)         ; Set the Empty Bit
	btst.b  #5,(a0)         ; Is the wrap bit set?
	bne     WRAP_R          ;  if so, point PRD to RBASE
	addq.w  #$8,PRDPTR      ; else increment PRDPTR to next BD
	bra     CHKMOR          ; and check the next BD
WRAP_R  move.w  RBASE3(a5),PRDPTR       
CHKMOR  move.w  PRDPTR,d0       
	cmp.w   RBPRT3(a5),d0   ; if PRDPTR=RBPRT3
	bne     REC_BD
	rts                     ; done servicing RXB/RXF
	
SCC4INT movem.l d0-d2/a0-a2,-(a7)       ; save context registers
	move.w  SCCE4(a5),-(a7) ; temporarily store SCC event 
*                               ; register on stack
	move.w  #$ffff,SCCE4(a5)        ; Clear all SCC events 
	move.w  (a7),d2         ; get a copy of the register
	andi.w  #$200,d2           ; is AB set?
	beq     INT4      
	bsr     REC_AB
INT4    move.l  #$08000000,CISR(a5)     ; clear SCC4 bit in ISR 
	move.w  (a7)+,d2        ; remove SCCE4 from stack
	movem.l (a7)+,d0-d2/a0-a2       ; Restore Context
	rte

REC_AB  move.l  BRGC4(a5),d1    ; get CD and DIV bits from BRG4
	andi.w  #$001FFF,d1
	move.l  d1,AUTOBD_DV    ; save the div and CD bits to chk later
	trap    #15             ; just testing if AB interpt occurs
	dc.w    $0063           ; graceful exit

	move.w  PRDPTR,d0       ; put PRDPTR into d0
	move.l  a5,a0
	add.w   d0,a0           ; a0 is absolute pointer to unprocessed BD
	move.w  (a0),d0         ; get copy of BD status word
	andi.w  #$001f,d0       ; save error indicators
	bne     ERR_HAND        ; branch to error handler if errors
*
** Process the received data here
*
	clr.w   2(a0)           ; Clear the length word
	andi.w  #$f200,(a0)     ; clear status bits
	bset.b  #7,(a0)         ; Set the Empty Bit
	btst.b  #5,(a0)         ; Is the wrap bit set?
	bne     WRAP_R4          ;  if so, point PRD to RBASE
	addq.w  #$8,PRDPTR      ; else increment PRDPTR to next BD
	bra     CHKMOR4          ; and check the next BD
WRAP_R4  move.w  RBASE4(a5),PRDPTR       
CHKMOR4  move.w  PRDPTR,d0       
	cmp.w   RBPRT4(a5),d0   ; if PRDPTR=RBPRT4
	bne     REC_BD
	rts                    ; done servicing RXB/RXF
		
*** Error Handler Ignores Receive Errors
ERR_HAND        rts


**** demo data
		ORG INIT+$2000
		
RXBUF:  ds.b    MBUFS*4                 ; reserve space for 4 buffers


*put data in send buffers
TBUF0:  dc.b    'ABuffer1 data'
TBUF1:  dc.b    'ABuffer2 data'
TBUF2:  dc.b    'ABuf3plus CR',$0d      ; CR in data will close Receive BD 
TBUF3:  dc.b    'Buffer 4 data'          
					  
PRDPTR: ds.w    1                       ; pointer to next Receive BD to
*                                       ; process
	END
