Thursday, December 17, 2009

SLIISR.S

;����������������������������������������������������������������������������Ŀ
;�                            SLIP PROTOCOL                                   �
;�                          INTERRUPT HANDLER                                 �
;�             for 68HC16Z1 Microcontroller running MCX-16                    �
;�                                                                            �
;�                 compiled with Whitesmiths C compiler                       �
;�                                                                            �
;�                            (c) June 1995                                   �
;�                               M. Lutfi                                     �
;�                      Engineering Physics Dept.                             �
;�                     Faculty of Industrial Tech.                            �
;�                     Institut Technologi Bandung                            �
;�                                                                            �
;������������������������������������������������������������������������������

.PROCESSOR M68HC16
.TITLE "Thesis Project : SLIP - communication handler"
.INCLUDE "hc16regs.mac"
.INCLUDE "mcx16.mac"
.INCLUDE "lgrset.mac"

;*******************************************************************************
;*  SCI DRIVER DATA VARIABLES                                                  *
;*******************************************************************************
.PUBLIC _in_char, _out_char
    .psect  _data

_in_char:    .BYTE (1)
_out_char:   .BYTE (1)
_dest_temp:  .BYTE (1)
_src_temp:   .BYTE (1)


    .psect    _text
    .even

.LIST + .MACRO

;*******************************************************************************
;*                                                                             *
;*                       S C I   I N P U T   D R I V E R                       *
;*                                                                             *
;*******************************************************************************
.PUBLIC _sciidrv
_sciidrv:

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          ; bank 1
          tbek               ; EK = 1
          tbxk               ; XK = 1 (K=$11xx)
          ldab   #SCI_RCV_SEMA
          ldaa   #MCX_WAIT_  ; Wait for input character
          swi

          ldaa   _in_char         ; Get input character captured by isr
          ldx    #_src_temp       ; Move it to safe place
          staa   0,x
          ldab   #SCI_RCV_Q       ; Then move the character into SCIIQ
          ldaa   #MCX_ENQUEUE_W_
          swi

          bra    inloop      ; Loop forever

;*******************************************************************************
;*                                                                             *
;*                     S C I   O U T P U T   D R I V E R                       *
;*                                                                             *
;*******************************************************************************

sciodrv:  ldab   #0Fh
          tbek               ; EK=F  (K=$Fxxx)
          ldab   #1
          tbxk               ; XK=1  (K=$F1xx)

scioloop:
          ldx    #_dest_temp
          ldab   #SCI_TRM_Q      ; Get next character from SCI_TRM_Q and put it into
          ldaa   #MCX_DEQUEUE_W_ ; _dest_temp 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   #SCI_TRM_SEMA   ; 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   #SCI_TRM_SEMA   ; Wait for it to be output completely
          ldaa   #MCX_WAIT_
          swi

          bra    scioloop    ; Loop forever

;*******************************************************************************
;*                                                                             *
;*           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         *
;*                                                                             *
;*******************************************************************************


sciisr:   orp    #INTS_OFF   ; Save the interrupt context
          pshm   d,e,x,y,z,k
          ldab   #1
          tbek               ; EK=1  (K=$1xxx)
          tbyk               ; YK=1  (K=$1x1x)
          tbzk               ; ZK=1  (K=$1x11)
          clrb
          tbxk               ; XK=0  (K=$1011)
          ldx    0000h       ; x = [$10000]
          tst    000Ah
          bne    notlvl0
          ldy    0004h       ; y = [$10004]
          sts    8,y         ; [y+8] = SP
          lds    14h,x       ; SP = [X+20]
notlvl0:  inc    000Ah       ; [$1000A] = [$1000A]+1
          andp   #SCIINTON   ; Interrupts back on
          ldz    12h,x

          ldab   #0Fh        ; EK = F  (K=$Fx11)
          tbek
          ldab   #1
          tbxk               ; XK = 1  (K=$F111)
          ldx    #0000      ;h
          ldy    #_in_char   ; y = &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 SCI_TRM_SEMA   ; Put SCI_TRM_SEMA into Signal List
noin:     ldaa   #SCI_TRM_SEMA   ; 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
          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 SCI_TRM_SEMA   ; Signal SCI Output Semaphore

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

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

;*******************************************************************************
;*  SCI VECTOR                                                                 *
;*******************************************************************************


.END

No comments:

Post a Comment