* Filename      : SCI.ASM
* Programmer    : Michael Hattermann
* Date          : February 4, 2002
* Version       : 1.0
* Description   : This file contains SCI communication
*                  functions for input and output of
*                  data.  The following functions are
*                  available:
*
*                  WAIT_TC - wait for transmit complete
*                  SET_BAUD - change the baud rate
*                  TX_ON - turn transmitter on
*                  TX_OFF - turn transmitter off
*                  RX_ON - turn receiver on
*                  RX_OFF - turn receiver off
*                  RX_INT_ON - turn receiver interrupts on
*                  RX_INT_OFF - turn receiver interrupts off
*                  OUTCHAR - prints character to screen
*                  OUTSTR - prints string to screen
*                  INCHARWAIT - waits for character input
*                  INCHAR - get character input if any
*                  OUTNUM - prints number to screen
*                  NIBTOCHAR - prints nibble to screen
*                  OUTADDR - prints 16-bit num to screen
*                  INITSCI - turns on SCI for 9600 baud
*
*
*#define __DEBUGSCI_    1

#include "hc12.asm"

*
************************************************************
* SCI Equates
************************************************************
*
****Baud rate equates****
BAUD19200   EQU     0
BAUD14400   EQU     2
BAUD9600    EQU     4
BAUD4800    EQU     6
BAUD2400    EQU     8
BAUD1200    EQU     10
BAUD600     EQU     12
BAUD300     EQU     14

****ASCII character equates****
EOS         EQU     $04             ; User-defined End Of String (EOS) character
CR          EQU     $0D             ; Carriage Return Character
LF          EQU     $0A             ; Line Feed Character
ESC         EQU     $1B             ; ESC character

*
************************************************************
* SCI Test Program
************************************************************
*
#ifdef __DEBUGSCI_
            ORG     $0900

HELLO       DC.B    'Hello world!!!'
NEWLINE     DC.B    CR,LF           ; Newline string
            DC.B    EOS

PRESSKEY    DC.B    'Press any key to continue'
            DC.B    CR,LF,EOS

CHANGETO    DC.B    'Change baud rate to: '
            DC.B    EOS

PROMPT      DC.B    'Start typing...'
            DC.B    CR,LF,EOS

TEST        LDAA    #$00            ; turn off COP watchdog timer
            STAA    COPCTL

            LDS     #$0bff          ; init the stack pointer

            JSR     INITSCI         ; init SCI system
            LDX     #HELLO          ; print "hello world"
            JSR     OUTSTR          ;
            LDX     #CHANGETO       ; print change baud message
            JSR     OUTSTR          ;
            LDX     #$1200          ; print new baud rate
            JSR     OUTADDR         ;
            LDX     #NEWLINE        ; print new line
            JSR     OUTSTR          ;

            LDX     #PRESSKEY       ; print "press any key"
            JSR     OUTSTR          ;
            JSR     INCHARWAIT      ; wait for character

            LDAA    #BAUD1200       ; change baud rate
            JSR     SET_BAUD        ;
            LDX     #HELLO          ; print "hello world"
            JSR     OUTSTR          ;
            LDX     #$1234          ; test print address
            JSR     OUTADDR         ;
            LDX     #PROMPT         ; print prompt
            JSR     OUTSTR          ;
HERE        JSR     INCHARWAIT      ; get character
            JSR     OUTCHAR         ; echo to screen
            BRA     HERE            ; end of program

#endif
*
************************************************************
* Constant Definitions
************************************************************
*
BAUDTBL     DC.W    13              ; (0) BAUD rate = 19200
            DC.W    17              ; (1) BAUD rate = 14400
            DC.W    26              ; (2) BAUD rate = 9600
            DC.W    52              ; (3) BAUD rate = 4800
            DC.W    104             ; (4) BAUD rate = 2400
            DC.W    208             ; (5) BAUD rate = 1200
            DC.W    417             ; (6) BAUD rate = 600
            DC.W    833             ; (7) BAUD rate = 300
*
*******************************************************************************
*                       SUBROUTINE -  WAIT_TC
* Description: Waits for the current transmit operation to complete (polls the
*                TC flag in SCI status register 1)
* Input         : None.
* Output        : None.
* Destroys      : None.
* Calls         : None.
*******************************************************************************
*
WAIT_TC
            BRCLR   SC0SR1,BIT6,WAIT_TC     ; wait until done sending
            RTS                             ; Return to caller
*
*
*******************************************************************************
*                       SUBROUTINE -  SET_BAUD
* Description: Sets the baud rate to the rate specified in register A.  Reg A
*               can only take on these predefined values:
*       BAUD19200     = BAUD rate 19200
*       BAUD14400     = BAUD rate 14400
*       BAUD9600      = BAUD rate 9600
*       BAUD4800      = BAUD rate 4800
*       BAUD2400      = BAUD rate 2400
*       BAUD1200      = BAUD rate 1200
*       BAUD600       = BAUD rate 600
*       BAUD300       = BAUD rate 300
*
* Input         : New baud rate in reg A
* Output        : None.
* Destroys      : SC0BDH, SC0BDL.
* Calls         : None.
*******************************************************************************
*
SET_BAUD
            PSHX                    ; Preserve reg X

            LDX     #BAUDTBL        ; Load address of baud table
            LDX     A,X             ; Load baud rate from table
            STX     SC0BD           ; Set baud rate in register

            PULX                    ; Restore reg X
            RTS                     ; Return to caller
*
*******************************************************************************
*                       SUBROUTINE -  TX_ON, TX_OFF
* Description: Enables transmitter, disables transmitter
* Input         : None.
* Output        : None.
* Destroys      : SC0CR2.
* Calls         : None.
*******************************************************************************
*
TX_ON
            BSET    SC0CR2,BIT3     ; turn on the transmitter
            RTS                     ; return to caller
TX_OFF
            BCLR    SC0CR2,BIT3     ; turn off the transmitter
            RTS                     ; return to caller
*
*******************************************************************************
*                       SUBROUTINE -  RX_ON, RX_OFF,RX_INT_ON,RX_INT_OFF
* Description: Enables receiver, disables receiver, enables receive interrupts,
*               disables receive interrupts
* Input         : None.
* Output        : None.
* Destroys      : SC0CR2.
* Calls         : None.
*******************************************************************************
*
RX_ON
            BSET    SC0CR2,BIT2     ; turn on the receiver
            RTS                     ; return to caller
RX_OFF
            BCLR    SC0CR2,BIT2     ; turn off the receiver
            RTS                     ; return to caller
RX_INT_ON
            BSET    SC0CR2,BIT5     ; enable receiver interrupts
            RTS                     ; return to caller
RX_INT_OFF
            BCLR    SC0CR2,BIT5     ; disable receiver interrupts
            RTS                     ; return to caller
*
************************************************************************
*                       SUBROUTINE -  OUTCHAR
* Description: Outputs the character in register A to the screen
* Input         : Data to be transmitted in register A.
* Output        : Transmits the data.
* Destroys      : None.
* Calls         : WAIT_TC
************************************************************************
*
OUTCHAR
            JSR     WAIT_TC         ; wait until transmitter is idle
            STAA    SC0DRL          ; output character
            RTS                     ; Return from subtoutine
*
************************************************************************
*                       SUBROUTINE -  OUTSTR
* Description: Outputs the string pointed to by X.  String must be
*               terminated by EOS character.
* Input         : String to be output in reg X
* Output        : Transmits the string.
* Destroys      : None.
* Calls         : OUTCHAR
************************************************************************
*
OUTSTR
            PSHA                    ; preserve reg A
            PSHX                    ; preserve reg X
OUTSTR1
            LDAA    1,X+            ; Get a character (put in reg A)
            CMPA    #EOS            ; Check if it's EOS
            BEQ     OUTSTR2         ; Branch to Done if it's EOS
            JSR     OUTCHAR         ; Print the character
            BRA     OUTSTR1
OUTSTR2
            PULX                    ; restore reg X
            PULA                    ; restore reg A
            RTS                     ; Return from subtoutine
*
************************************************************************
*                SUBROUTINE  -  INCHARWAIT
* Description: Waits for a character to be pressed and reads it into
*               reg A
* Input         : None
* Output        : Character pressed in reg. A
* Destroys      : A.
* Calls         : None
************************************************************************
*
INCHARWAIT
            BRCLR   SC0SR1,BIT5,INCHARWAIT  ; wait until buffer full
            LDAA    SC0DRL                  ; input character
            RTS                             ; Return from subroutine
*
************************************************************************
*                SUBROUTINE  -  INCHAR
* Description: Checks to see if character recevied - if so returns the
*               character, if not returns 0
* Input         : None
* Output        : Character pressed in reg A; 0 if none
* Destroys      : A.
* Calls         : None
************************************************************************
*
INCHAR
            BRCLR   SC0SR1,BIT5,INCHAR1     ; if there is no data, get out
            LDAA    SC0DRL                  ; yes, read data
INCHAR1
            RTS                             ; return to caller
*
************************************************************************
*                       SUBROUTINE -  OUTNUM
* Description: Outputs the number in register A to the screen
* Input         : Data to be transmitted in register A.
* Output        : Transmits the data.
* Destroys      : None.
* Calls         : NIBTOCHAR
************************************************************************
*
OUTNUM
            PSHA                    ; preserve reg A
            PSHA                    ; preserve reg A
            ANDA    #%11110000      ; get upper nibble
            LSRA                    ; shift it right to get the nibble
            LSRA
            LSRA
            LSRA
            JSR     NIBTOCHAR       ; change A and print it
            PULA                    ; restore reg A
            ANDA    #%00001111      ; get lower nibble
            JSR     NIBTOCHAR       ; change A and print it
            PULA                    ; restore reg A
            RTS                     ; return to caller
*
************************************************************************
*                       SUBROUTINE -  NIBTOCHAR
* Description: Converts lower nibble of A to ASCII and prints it
* Input         : Data to convert in A.
* Output        : Transmits the data.
* Destroys      : None.
* Calls         : OUTCHAR
************************************************************************
*
NIBTOCHAR
            CMPA    #9             ; is it greater than 9?
            BGT     NIBTOCHAR1     ; if so, print a character
            ADDA    #48            ; if not, print a number starting at 48 ASCII
            BRA     NIBTOCHAR2     ;
NIBTOCHAR1
            ADDA    #55            ; if so, print a letter starting at 55 = 65-10
NIBTOCHAR2
            JSR     OUTCHAR        ; print it
            RTS
*
************************************************************************
*                       SUBROUTINE -  OUTADDR
* Description: Outputs the number in reg X to the screen
* Input         : Data to print in X.
* Output        : Transmits the data.
* Destroys      : None.
* Calls         : OUTNUM
************************************************************************
*
OUTADDR
            PSHD                    ; save reg D
            TFR     X,D             ; load X into D
            JSR     OUTNUM          ; prints whats in A -- MSB
            TBA                     ; B -> A
            JSR     OUTNUM          ; prints whats in B -- LSB
            PULD                    ; restore D
            RTS                     ; return to caller
*
************************************************************************
*                       SUBROUTINE - INITSCI
* Description: This subroutine initializes the BAUD rate to 9600 and
*              sets up the SCI port for 1 start bit, 8 data bits and
*              1 stop bit.  It also enables the transmitter and receiver
* Input         : None.
* Output        : Initializes SCI.
* Destroys      : None.
* Calls         : SET_BAUD,TX_ON,RX_ON
************************************************************************
*
INITSCI     PSHA                    ; save reg A
            LDAA    #BAUD9600       ; set the baud rate to 9600
            JSR     SET_BAUD        ;
            JSR     TX_ON           ; turn on the transmitter
            JSR     RX_ON           ; turn on the receiver
            PULA                    ; restore reg A
            RTS                     ; Return from subtoutine
*
************************************************************************
