*
*       SMC UART Example Code
*       based upon the SMC UART Example User's Manual Page 7-296
*       The example programs the SMC1 of the 360 to communicate in
*       UART protocol with 9600 baud 8 bit data no parity, and 1
*       stop bit. The program assumes 25MHz system clock.
*                                                          JS 7/15/94
* The following example will
* 1) set the SMC1 in UART mode
* 2) set up two buffer descriptors one for Rx one for Tx
* 3) Enable the transmitter and receiver
*
* To change this file to use SMC2 you must
* Change all the equate refrence from SMC1 to SMC2.
* Change the SIMODE to route the clk to SMC2
* Change the value to initialize the correct SMC upon INIT RX&TX
* Change the parallel port settings so that SMC2 pins are sent out
***********************************************************************
*
INIT    EQU     $0403000        ; QUADS Board DRAM User Space
************************** 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
RXBD    EQU     $0400           ; Receive Buffer Discriptor address
TXBD    EQU     $0408           ; Transmit Buffer Discriptor address
REGB    EQU     $1000           ; Base address of Internal Registers
SPIPB   EQU     $0D80           ; SPI Protocol Base
SMC1PB  EQU     $0E80           ; SMC1 Protocol Base

************************ SIM Module registers **************************
MCR     EQU     REGB+$0000      ; Module Configuration
AVR     EQU     REGB+$0008      ; Auto Vector
RSR     EQU     REGB+$0009      ; Reset Status
CLKOCR  EQU     REGB+$000C      ; CLKO Control
PLLCR   EQU     REGB+$0010      ; PLL Control
CDVCR   EQU     REGB+$0014      ; Clock Divider Control
*
PEPAR   EQU     REGB+$0016      ; Port E Pin Assignment
*
SYPCR   EQU     REGB+$0022      ; System Protection Control
SWIV    EQU     REGB+$0023      ; S/w Interrupt Vector
PICR    EQU     REGB+$0026      ; Periodic Interrupt Control
PITR    EQU     REGB+$002A      ; Periodic Interrupt Timing
SWSR    EQU     REGB+$002F      ; S/w Service
BKAR    EQU     REGB+$0032      ; Breakpoint Address
BKCQ    EQU     REGB+$0034      ; Breakpoint Control
*
GMR     EQU     REGB+$0040      ; Global Memory
MSTAT   EQU     REGB+$0044      ; MEMC Status
*
*
************************ CPM Module registers *******************

SDCR    EQU     REGB+$051E      ; SDMA Configuration Register
*** Port A, B, C
*
PBDIR   EQU     REGB+$06B8      ; Port B Data Direction Assignment
PBPAR   EQU     REGB+$06BC      ; Port B Pin Function Assignment
PBODR   EQU     REGB+$06C2      ; Port B Open Drain Assignment
PBDAT   EQU     REGB+$06C4      ; Port B Data Content
*
*** 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
BRGC1   EQU     REGB+$05F0      ; BRG1 Configuration

*** SMC 1
SMCMR1  EQU     REGB+$0682      ; SMC1 Mode
SMCE1   EQU     REGB+$0686      ; SMC1 Event
SMCM1   EQU     REGB+$068A      ; SMC1 Mask
*** 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 *******************

****** SMC1 => SMCA, simplify assembly coding
RBASEA  EQU     SMC1PB+$000     ; SMC1 RX BD Base Address
TBASEA  EQU     SMC1PB+$002     ; SMC1 TX BD Base Address
RFCRA   EQU     SMC1PB+$004     ; SMC1 RX Function Code
TFCRA   EQU     SMC1PB+$005     ; SMC1 TX Function Code
MRBLRA  EQU     SMC1PB+$006     ; SMC1 MAX Buffer Length - RX
RSTATEA EQU     SMC1PB+$008     ; SMC1 RX Internal State
RBPRTA  EQU     SMC1PB+$010     ; SMC1 RX BD Pointer
TSTATEA EQU     SMC1PB+$018     ; SMC1 TX Internal State
TBPRTA  EQU     SMC1PB+$020     ; SMC1 TX BD Pointer


* SMC1, UART Specific Parameters
MAXIDLA EQU     SMC1PB+$28      ; SMC1 MAX IDLe cchars
IDLCA   EQU     SMC1PB+$2A      ; SMC1 temp IDLe Counter
BRKLA   EQU     SMC1PB+$2C      ; SMC1 last Received BReaK char length
BRKECA  EQU     SMC1PB+$2E      ; SMC1 receive BReaK Condition Counter
BRKCRA  EQU     SMC1PB+$30      ; SMC1 BReaK Count Register (TX)



        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 Config Register
        move.w  #$0740,SDCR(a5) ; SDMA interrupt service mask = 7,
*                               ;  bus arbit. priority = 4
*** Set up Port B pins
        OR.L    #$000000D0,PBPAR(a5)    ; To allow SMC TX & RX & BRG1 out
        AND.L   #$FFFFFF2F,PBDIR(a5)    ; PBDIR4,6,7=0 PBPAR4,6,7=1
        AND.w   #$FF2F,PBODR(a5)        ; BRG0 and TXD are not open drain

*** Set up Clocking
        move.l  #$000010144,BRGC1(a5)   ; 9600 Bps for UART (Assuming 25MHz system clock)
        AND.L   #$FFFF02FF,SIMODE(a5)   ; Send BRG1 to SMC1
        or.l    #$00000000,SIMODE(a5)
*                                       ; SMC1=0 --> NMSI
*                                       ; SMC1CS=000 --> BRG1
*                                       ; SDM=00 --> Meaningless in NMSI

*** Set up SMC Channel
        move.w  #$0400,RBASEA(a5)       ; Set RXBD tbl start at DPRBASE+$0400
        move.w  #$0408,TBASEA(a5)       ; Set TXBD tbl start at DPRBASE+$0408

        move.w  #$0091,CR(a5)           ; INIT RX&TX Params for SMC1
        move.b  #$18,RFCRA(a5)          ; Standard Values...
        move.b  #$18,TFCRA(A5)          ; ....

*** Protocol Specific Parameters
        move.w  #$0006,MRBLRA(a5)       ; Max Receive Buffer Length = 6
        move.w  #$0005,MAXIDLA(a5)      ; 5 Idles before RCV Buf Closed
        move.w  #$0000,BRKLA(a5)        ; No last brk char received
        move.w  #$0000,BRKECA(a5)       ; No break conditions occurred
        move.w  #$0001,BRKCRA(a5)       ; 1 break char sent on STOP XMIT

** Program RXBD
        move.w  #$0000,RXBD+2(a5)       ; Initialize Length to 0
        move.l  #RXBUF,RXBD+4(a5)       ; Point to rcv buffer space
        move.w  #$A000,RXBD(a5)         ; Ready, Wrap, no interrupt

** Program TXBD
        move.w  #$0001,TXBD+2(a5)       ; Length of data = 1
        move.l  #TXBUF,TXBD+4(a5)       ; points to data to send
        move.w  #$a000,TXBD(a5)         ; Ready, Wrap, no interrupt

        move.b  #$ff,SMCE1(a5)          ; clear SMC events
        move.b  #$00,SMCM1(a5)          ; Mask out all interrupts
        move.w  #$4824,SMCMR1(a5)       ; 8 bit char, UART mode, Loopback
        ori.w   #$0003,SMCMR1(a5)       ; turn on transmitter & receiver

self    tst.w   TXBD(a5)                ; Wait until ready bit is reset
        bmi     self

label   bra     label                   ; loop for ever
*                                       ; After reaching this point
*                                       ; TXBD ready bit and RXBD empty bit should be cleared
*                                       ; (closed due to 5 IDLE chars being received)
*                                       ; SMCE should have its TX and RX bit set
*                                       ; RXBUF should contain 'A'
        org     INIT+$200
RXBUF   ds.b    6
TXBUF   dc.b    'A'
CHARCNT ds.w    1
END

