Thursday, December 17, 2009

SCIDRV.S

;*****************************************************************************
;*                                                                           *
;*                 S C I   D R I V E R   M O D U L E                         *
;*             UNDER HC16 MULTITASKING EXECUTIVE (MCX16)                     *
;*                         WITH SLIP PROTOCOL                                *
;*                                                                           *
;            Compiled with Whitesmith Cross Assember ver 1.9                 *
;*                        (c) 11 December 1994                               *
;*                            by M. Lutfi                                    *
;*                          Thesis Project                                   *
;*                 Instrumentation and Controls lab.                         *
;*                 Department of Engineering Physics                         *
;*                  FACULTY OF INDUSTRIAL TECHNOLOGY                         *
;*                  BANDUNG INSTITUTE OF TECHNOLOGY                          *
;*****************************************************************************
.PROCESSOR M68HC16
.TITLE "SCI DRIVER MODULE"

.INCLUDE "lgrset.s"

          .PAGE "SCIDRV"
;*******************************************************************************
;*                                                                             *
;*                       S C I   I N P U T   D R I V E R                       *
;*                      with SLIP data-link layer protocol                     *
;*******************************************************************************


sciidrv:
      orp    #INTS_OFF   ; Turn off interrupts while enabling SCI
      ldab   #0Fh
      tbek               ; EK = F (K=Fxxxh)

      ldd    #008Ah
      std    QMCR        ; Set IARB=10 for intermodule bus arbitration

      ldd    QILR        ; Get content of QSM Interrupt Levels Register
      anda   #0E8h       ; Clear out ILSCI field
      oraa   #SCIINTLV   ; Set SCI interrupt level in ILSCI field
      ldab   #SCIINTV    ; Load SCI Interrupt Vector #
      std    QILR        ; Update QILR

      ldd    #RIE+RE+TE  ; Receiver enabled with interrupts active,
                         ; Transmitter enabled without interrupts,
                         ; 1 Start Bit, 1 Stop Bit, 8 Data Bits
      std    SCCR1       ; Set up SCI operating conditions
      ldd    #BR9600     ; Set up 9600 baud rate
      std    SCCR0

rdclr:
      ldd    SCSR        ; Get current status of SCI
      bitb   #RDRF       ; See if receive data ready
      beq    scirdy      ; if not SCI is a
      ldab   SCDR        ; Read input data
      bra    rdclr       ; Loop until clear

scirdy:
      andp   #0FF1Fh      ; Turn interrupts on again

inloop:
      ldab   #1
      tbek               ; EK = 1
      tbxk               ; XK = 1 (K=11xxh)
      ldab   #SCIISEMA
      ldaa   #MCX_WAIT   ; Wait for input character
      swi

      ldaa   inchar      ; Get input character captured by isr
      ldx    #EQ3src     ; Move it to safe place
      staa   0,x
      ldab   #SCIIQ      ; Then move the character into SCIIQ
      ldaa   #MCX_ENQUEUE_W
      swi

      bra    inloop      ; Loop forever

          .PAGE "SCIDRV"
;*******************************************************************************
;*                                                                             *
;*                     S C I   O U T P U T   D R I V E R                       *
;*                                                                             *
;*******************************************************************************

sciodrv:  ldab   #0Fh
          tbek               ; EK=F  (K=Fxxxh)
          ldab   #1
          tbxk               ; XK=1  (K=F1xxh)

scioloop: ldx    #DQ4dest
          ldab   #SCIOQ      ; Get next character from SCIOQ and put it into
          ldaa   #MCX_QUEUE_W  ; DQ4dest as temporary location
          swi

          ldab   0,x         ; Get the character
          cmpb   #0Ah        ; New Line?
          bne    notnl       ; Branch if not "\n"
          ldd    SCSR        ; Get SCI status
          ldaa   #0Dh
          staa   SCDR+1      ; Output a "\r"
          ldd    #RIE+RE+TE+TIE
          std    SCCR1       ; Enable transmitter interrupts
;         ldab   #RIE+RE+TE+TIE
;         stab   SCCR1+1     ; Enable transmitter interrupts

          ldab   #SCIOSEMA   ; Wait for it to be output completely
          ldaa   #MCX_WAIT
          swi

notnl:    ldd    SCSR        ; Read status
          ldaa   0,x         ; Get character to output
          staa   SCDR+1      ; Output it
          ldd    #RIE+RE+TE+TIE
          std    SCCR1       ; Enable transmitter interrupts
;         ldab   #RIE+RE+TE+TIE
;         stab   SCCR1+1     ; Enable transmitter interrupts

          ldab   #SCIOSEMA   ; Wait for it to be output completely
          ldaa   #MCX_WAIT
          swi

          bra    scioloop    ; Loop forever

          .PAGE "SCIDRV"
;�����������������������������������������������������������������������������Ŀ
;�                                                                             �
;�           S C I   I N T E R R U P T   S E R V I C E   R O U T I N E         �
;�                                                                             �
 �������������������������������������������������������������������������������

.MACRO pshsema
          ldab   ?1
          orp    #INTS_OFF
          lde    06h,x
          stab   e,z
          incw   06h,x
          andp   #SCIINTON
 .EXITM

sciisr:
          orp    #INTS_OFF   ; Save the interrupt context
          pshm   d,e,x,y,z,k
          ldab   #1
          tbek               ; EK=1  (K=1xxxh)
          tbyk               ; YK=1  (K=1x1xh)
          tbzk               ; ZK=1  (K=1x11h)
          clrb
          tbxk               ; XK=0  (K=1011h)
          ldx    0000h
          tst    000Ah
          bne    notlvl0
          ldy    0004
          sts    8,y
          lds    14h,x
notlvl0:  inc    000Ah
          andp   #SCIINTON   ; Interrupts back on
          ldz    12h,x

          ldab   #0Fh         ; EK = F  (K=$Fx11)
          tbek
          ldab   #1
          tbxk               ; XK = 1  (K=$F111)
          ldx    #0000
          ldy    #inchar

          ldd    SCCR1       ; If TDRE is set, see if SCCR1 has TIE set
          bitb   #TIE
          beq    notout      ; If not, this is not an output interrupt
          ldd    SCSR        ; Check SCI status register for TDRE
          bita   #TDRE
          beq    chkrd       ; TDRE not set
          ldd    #RIE+RE+TE  ; If so, this is a transmitter interrupt, turn
                             ;  TIE off now that the character is out
          std    SCCR1       ; Update SCCR1. That takes care of the output side

          ldd    SCSR        ; Now treat a possible input interrupt that is
                             ;  simultaneous with the output. Reread the status
          bitb   #RDRF       ; Check for RDRF set
          beq    noin        ; Branch if no input occurred
          ldd    SCDR        ; Yes it did. Read the input character
          andb   #7Fh        ; Strip it to 7 bits
          stab   0,y         ; Store in temporary location (inchar)
          pshsema SCIISEMA   ; Put SCIISEMA into Signal List
noin:     ldaa   #SCIOSEMA   ; Now signal the SCI output semaphore
          jmp    isrrtn

notout:   ldd    SCSR        ; Read status again
chkrd:    bitb   #RDRF       ; See if this is an input interrupt. Check RDRF
          beq    notin       ; It is not an input interrupt. So what was it?
          ldd    SCDR        ; If it was an input interrupt, get the character
          andb   #7Fh        ; Strip it to 7 bits
          stab   0,y         ; Store in temporary location (inchar)
                             ; That takes care of the input. Now see if there
                             ;  was a simultaneous output interrupt
          ldd    SCSR        ; Check SCI status register for TDRE
          bita   #TDRE
          beq    noout       ; TDRE not set
          ldd    SCCR1       ; If TDRE is set, see if SCCR1 has TIE set
          bitb   #TIE
          beq    noout       ; If not, this cannot be an output interrupt
          ldd    #RIE+RE+TE  ; If so, this is a transmitter interrupt, turn
                             ;  TIE off now that the character is out
          std    SCCR1       ; Update SCCR1
          pshsema SCIOSEMA   ; Signal SCI Output Semaphore

noout:    ldaa   #SCIISEMA   ; Now signal the input semaphore
          jmp    isrrtn

notin:    clra               ; This wasn't a recognizable SCI interrupt
          jmp    isrrtn

          .PAGE "SCIDRV"
;���������������������������������������������������������������������������Ŀ
;� SCI VECTOR                                                                �
;�����������������������������������������������������������������������������

          .PSECT   _text
          .ADDR    sciisr

;���������������������������������������������������������������������������Ŀ
;� SCI DRIVER DATA VARIABLES                                                 �
;�����������������������������������������������������������������������������

          .PSECT _data ; 003FDh

inchar:   .BYTE     1
DQ4dest:  .BYTE     1
EQ3src:   .BYTE     1

.END

No comments:

Post a Comment