/*
���������������������������������������������������������������������������
� �
� THERMOCOUPLE TASK �
� �
� Copyright (c) 1994 �
� by Lutfi Shahab �
� Instrumentation and Controls Laboratory �
� Dept. of Engineering Physics �
� Institut Teknologi Bandung �
� �
� Date: 20/11/94 �
� �
� Platform : Motorola 68HC16 Microcontroller �
� running mcx16 multitasking kernel �
� Compiler : Whitesmith HC16 Compiler �
� Target : EPROM-targeted binary code �
� �
� Description: �
� This module contains routines for Thermocouple Linearization using �
� polynomial curvefitting. Only thermocouple type K can be calculated. �
� Temperature adjusted to Celcius. �
� �
���������������������������������������������������������������������������;
*/
#define _WSC_
#define _FAR_
#ifdef _WSC_
#include <wslxa.h>
#else
enum {ADC_1, ADC_2, ADC_3, ADC_4, ADC_5,ADC_6, ADC_7, ADC_8, N_ADC_CHANNELS};
#endif
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#ifdef _WSC_
#include "mcxapi.h"
#include "sysdef.h"
#endif
#define VREF_PLUS +2500.0 /* mV */
#define VREF_MIN -2500.0 /* mV */
#define RESOLUTION 10 /* bits */
#define KELVIN_TO_C 273.20 /* based on IPTS-68 */
#define LM335_VT 10.00 /* mV per Kelvin degree */
#define TC_GAIN_AMP (10000/40) /* gain of TC op-amp; uV/uV */
#define DIGIT_TO_MILLIVOLT(d) (((d)*scale)+VREF_MIN) /* mV */
/* seebeck coefficients for all TC types */
#define SEEBECK_COEF_K 40.01 /* uV/K */
#define SEEBECK_COEF_TC 5.20
#define SEEBECK_COEF_BN 18.05
#define SEEBECK_COEF_E 59.80
#define SEEBECK_COEF_JT 51.08
#define SEEBECK_COEF_JP 17.94
#define SEEBECK_COEF_JN 33.10
#define SEEBECK_COEF_K 40.01
#define SEEBECK_COEF_KP 26.47
#define SEEBECK_COEF_KN 13.54
#define SEEBECK_COEF_R 5.62
#define SEEBECK_COEF_S 5.70
#define SEEBECK_COEF_T 39.67
#define SEEBECK_COEF_TP 6.33
#define SEEBECK_COEF_TN 33.32
#define SEEBECK_COEF SEEBECK_COEF_K
/* number of linearization polynomial equations as T(V) */
#define NUMEQN_V 5
/* number of linearization polynomial equations as V(T) */
#define NUMEQN_T 2
#define ORDE_T 10
#define ORDE_V 4
#define TC_VOLT_MIN tc_table.v_range[0].min
#define TC_VOLT_MAX tc_table.v_range[NUMEQN_V-1].max
typedef struct {
double min, max;
}RANGE;
typedef struct {
RANGE t_range[NUMEQN_T]; /* temperature range */
RANGE v_range[NUMEQN_V]; /* voltage range */
double coef_t[NUMEQN_T][ORDE_T+1]; /* polynomial coefficients for every equation of V(T) */
double coef_v[NUMEQN_V][ORDE_V+1]; /* polynomial coefficients for every equation of T(V) */
} TCRECTYPE;
TCRECTYPE tc_table = {
/* Temperature ranges (in C) for each polynomial equation of type K */
{
{-270.00, 0.00},
{ 0.00, 1372.00},
},
/* Voltage ranges in microvolts */
{
{-6.457816e+03, -6.441148e+03},
{-6.441148e+03, -5.891361e+03},
{-5.891361e+03, 1.853306e+01},
{ 1.853306e+01, 8.136555e+03},
{ 8.136555e+03, 5.487490e+04}
},
{
/* Coefficients for each polynomial equation V(T) */
{
0.0000000000E+00, 3.9475433139E+01, 2.7465251138E-02,
-1.6565406716E-04,-1.5190912392E-06,-2.4581670924E-08,
-2.4757917816E-10,-1.5585276173E-12,-5.9729921255E-0015,
-1.2688801216E-17,-1.1382797374E-20
},
{
-1.8533063273E+01, 3.8918344612E+01, 1.6645154356E-02,
-7.8702374448E-05, 2.2835785557E-07,-3.5700231258E-10,
2.9932909136E-13,-1.2849848798E-16, 2.2239974336E-20,
0.00, 0.00
}
},
/* Coefficients for each polynomial equation T(V) in C */
{
{-8.887677e+05,-2.054743e+02, 1.307316e-02, 5.611858e-06, 3.034392e-10},
{-1.215521e+06,-7.993152e+02,-1.971155e-01,-2.160351e-05,-8.879453e-10},
{0.0000000e+00, 2.382475e-02,-2.372981e-06,-6.567714e-10,-9.208444e-14},
{0.0000000e+00, 2.548081e-02,-5.270562e-07, 7.989244e-11,-3.520933e-15},
{-1.035821e+01, 2.712314e-02,-1.781781e-07, 3.243000e-12,-1.166816e-17}
}
};
double scale; /* transformation scale */
/* calculate seebeck voltage value for a given temperature and TC */
/*
double calc_seebeck(double tempin)
{
return (SEEBECK_COEF * tempin);
}
*/
/* calculate TC temperature given volts using polynomial equations */
double volt2temp_poly(double voltin) /* input voltage */
{
int pi; /* index to appropriate polynom */
int i;
double yout;
if (voltin < TC_VOLT_MIN) /* check to see if voltage in valid range */
{
voltin = TC_VOLT_MIN;
}
else if (voltin > TC_VOLT_MAX)
{
voltin = TC_VOLT_MAX;
}
pi = 0;
/* search through breakpoint list looking for proper interval */
while ( (pi < NUMEQN_V) &&
!((voltin >= tc_table.v_range[pi].min) &&
(voltin <= tc_table.v_range[pi].max)))
{
pi++;
}
/* calculate TC temperature as a function of volts */
yout = tc_table.coef_v[pi][ORDE_V];
for (i=ORDE_V-1; i<=0; i--)
{
/* efficient, nested polynomial calculation */
yout = yout*voltin+tc_table.coef_v[pi][i];
}
return (yout);
}
/******************************************************************************
CONVERTS TC VOLTS TO TEMPERATURE
--------------------------------
Reference temperature sensored by IC LM335Z, which has output
characteristic: 10 mV/K. Scale has been stated 5/1023 = 4.9 mV/LSB,
so if we have vi (in integer), it must be multiplied by scale to convert
to voltage temperature, and divided it by resolution of sensor to get
real temperature. ref_scale = scale/LM335_VT = (4.9 mV/LSB)/(10 mV/K) =
0.49 K/LSB. Increasing vi in its LSB will increase temperature by 0.49 K.
When calibrate (T=25 C), LM335 generate 2.982 volts (273.2+25) according
to his current temperature. In Differential op-amp, this temperature-based
voltage used to compute temperature reference. We don't need to compute it
in MCU.
All of 'kerumitan' has been handled by op-amps.
*******************************************************************************/
void tc_converter(unsigned int *vi, /* measured TC volts */
double *temp) /* linearized temperature */
/* return: error code, 0 = no error */
{
int i;
double v;
for (i=ADC_1; i<=ADC_8; i++)
{
v = DIGIT_TO_MILLIVOLT(vi[i])/TC_GAIN_AMP*1000; /* unit in microvolts !*/
temp[i] = volt2temp_poly(&v);
}
}
double lin_t[N_ADC_CHANNELS]; /* linearized temperature */
void TC_Task(void)
{
unsigned int *mbx;
/* ADC resolution */
scale = (double)(VREF_PLUS-VREF_MIN)/(double)((1<<RESOLUTION)-1); /* mV/bit */
#ifdef _WSC_
FOREVER
{
mbx = _mcx_receive_w(CNV_SEMA);
tc_converter((mbx, (double *)lin_t);
_mcx_send_mbx_w(TC_MBX, lin_t, CNV_FINISH_SEMA);
_mcx_msg_done(mbx);
}
#endif
}
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
;� 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
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
;* *
;* 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
SCIDRV.ASM
******************************************************************************
* S C I D R I V E R M O D U L E *
* *
*******************************************************************************
isrrtn equ $360 ; Address of Common Interrupt Exit routine
SCIINTLV equ 5 ; SCI Interrupt Level
SCIINTV equ $3A ; SCI Interrupt Vector
QMCR equ $FC00
QILR equ $FC04 ; QSM Interrupt Levels Register
QIVR equ $FC05 ; QSM Interrupt Vector Register
SCCR0 equ $FC08 ; SCI Control Register 0
SCCR1 equ $FC0A ; SCI Control Register 1
SCSR equ $FC0C ; SCI Status Register
SCDR equ $FC0E ; SCI Data Register
*******************************************************************************
* SCCR1 REGISTER FIELDS *
*******************************************************************************
SRK equ $01 ; Send Break
RWU equ $02 ; Receiver Wakeup
RE equ $04 ; Receiver Enable
TE equ $08 ; Transmitter Enable
RIE equ $20 ; Receiver Interrupt Enable
TIE equ $80 ; Transmitter Interrupt Enable
*******************************************************************************
* SCI STATUS REGISTER FIELDS *
*******************************************************************************
RDRF equ $40 ; Receive Data Register Full
TDRE equ $01 ; Transmit Data Register Empty (high byte of $0100)
*******************************************************************************
* SCI DRIVER EQUATES *
*******************************************************************************
INTS_OFF equ $00E0 ; Disable interrupts
SCIINTON equ (SCIINTLV<<5+$FF1F) ; Enable interrupts at SCIINTLV (2)
BR9600 equ $37 ; SCCR0(0-12) setting for 9600 Baud
PAGE
*******************************************************************************
* *
* S C I I N P U T D R I V E R *
* *
*******************************************************************************
sciidrv: orp #INTS_OFF ; Turn off interrupts while enabling SCI
ldab #$F
tbek ; EK = F (K=$Fxxx)
ldd #$008A
std QMCR ; Set IARB=10 for intermodule bus arbitration
ldd QILR ; Get content of QSM Interrupt Levels Register
anda #$E8 ; 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 #$FF1F ; Turn interrupts on again
inloop: ldab #1 ; bank 1
tbek ; EK = 1
tbxk ; XK = 1 (K=$11xx)
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
*******************************************************************************
* *
* S C I O U T P U T D R I V E R *
* *
*******************************************************************************
sciodrv: ldab #$F
tbek ; EK=F (K=$Fxxx)
ldab #1
tbxk ; XK=1 (K=$F1xx)
scioloop: ldx #DQ4dest
ldab #SCIOQ ; Get next character from SCIOQ and put it into
ldaa #MCX_DEQUEUE_W ; DQ4dest as temporary location
swi
ldab 0,x ; Get the character
cmpb #$0A ; New Line?
bne notnl ; Branch if not "\n"
ldd SCSR ; Get SCI status
ldaa #$0D
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
*******************************************************************************
* *
* 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 *
* *
*******************************************************************************
pshsema macro
ldab #\1
orp #INTS_OFF
lde $06,x
stab e,z
incw $06,x
andp #SCIINTON
endm
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 $0000 ; x = [$10000]
tst $000A
bne notlvl0
ldy $0004 ; y = [$10004]
sts 8,y ; [y+8] = SP
lds $14,x ; SP = [X+20]
notlvl0: inc $000A ; [$1000A] = [$1000A]+1
andp #SCIINTON ; Interrupts back on
ldz $12,x
ldab #$F ; EK = F (K=$Fx11)
tbek
ldab #1
tbxk ; XK = 1 (K=$F111)
ldx #$0000 ;
ldy #inchar ; 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 #$7F ; 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 #$7F ; 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
*******************************************************************************
* SCI VECTOR *
*******************************************************************************
ORG SCIINTV*2
dc.w sciisr
*******************************************************************************
* SCI DRIVER DATA VARIABLES *
*******************************************************************************
ORG $003FD
inchar: ds 1
DQ4dest: ds 1
EQ3src: ds 1
*******************************************************************************
* *
* S C I D R I V E R M O D U L E *
*
* S C I D R I V E R M O D U L E *
* *
*******************************************************************************
isrrtn equ $360 ; Address of Common Interrupt Exit routine
SCIINTLV equ 5 ; SCI Interrupt Level
SCIINTV equ $3A ; SCI Interrupt Vector
QMCR equ $FC00
QILR equ $FC04 ; QSM Interrupt Levels Register
QIVR equ $FC05 ; QSM Interrupt Vector Register
SCCR0 equ $FC08 ; SCI Control Register 0
SCCR1 equ $FC0A ; SCI Control Register 1
SCSR equ $FC0C ; SCI Status Register
SCDR equ $FC0E ; SCI Data Register
*******************************************************************************
* SCCR1 REGISTER FIELDS *
*******************************************************************************
SRK equ $01 ; Send Break
RWU equ $02 ; Receiver Wakeup
RE equ $04 ; Receiver Enable
TE equ $08 ; Transmitter Enable
RIE equ $20 ; Receiver Interrupt Enable
TIE equ $80 ; Transmitter Interrupt Enable
*******************************************************************************
* SCI STATUS REGISTER FIELDS *
*******************************************************************************
RDRF equ $40 ; Receive Data Register Full
TDRE equ $01 ; Transmit Data Register Empty (high byte of $0100)
*******************************************************************************
* SCI DRIVER EQUATES *
*******************************************************************************
INTS_OFF equ $00E0 ; Disable interrupts
SCIINTON equ (SCIINTLV<<5+$FF1F) ; Enable interrupts at SCIINTLV (2)
BR9600 equ $37 ; SCCR0(0-12) setting for 9600 Baud
PAGE
*******************************************************************************
* *
* S C I I N P U T D R I V E R *
* *
*******************************************************************************
sciidrv: orp #INTS_OFF ; Turn off interrupts while enabling SCI
ldab #$F
tbek ; EK = F (K=$Fxxx)
ldd #$008A
std QMCR ; Set IARB=10 for intermodule bus arbitration
ldd QILR ; Get content of QSM Interrupt Levels Register
anda #$E8 ; 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 #$FF1F ; Turn interrupts on again
inloop: ldab #1 ; bank 1
tbek ; EK = 1
tbxk ; XK = 1 (K=$11xx)
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
*******************************************************************************
* *
* S C I O U T P U T D R I V E R *
* *
*******************************************************************************
sciodrv: ldab #$F
tbek ; EK=F (K=$Fxxx)
ldab #1
tbxk ; XK=1 (K=$F1xx)
scioloop: ldx #DQ4dest
ldab #SCIOQ ; Get next character from SCIOQ and put it into
ldaa #MCX_DEQUEUE_W ; DQ4dest as temporary location
swi
ldab 0,x ; Get the character
cmpb #$0A ; New Line?
bne notnl ; Branch if not "\n"
ldd SCSR ; Get SCI status
ldaa #$0D
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
*******************************************************************************
* *
* 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 *
* *
*******************************************************************************
pshsema macro
ldab #\1
orp #INTS_OFF
lde $06,x
stab e,z
incw $06,x
andp #SCIINTON
endm
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 $0000 ; x = [$10000]
tst $000A
bne notlvl0
ldy $0004 ; y = [$10004]
sts 8,y ; [y+8] = SP
lds $14,x ; SP = [X+20]
notlvl0: inc $000A ; [$1000A] = [$1000A]+1
andp #SCIINTON ; Interrupts back on
ldz $12,x
ldab #$F ; EK = F (K=$Fx11)
tbek
ldab #1
tbxk ; XK = 1 (K=$F111)
ldx #$0000 ;
ldy #inchar ; 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 #$7F ; 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 #$7F ; 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
*******************************************************************************
* SCI VECTOR *
*******************************************************************************
ORG SCIINTV*2
dc.w sciisr
*******************************************************************************
* SCI DRIVER DATA VARIABLES *
*******************************************************************************
ORG $003FD
inchar: ds 1
DQ4dest: ds 1
EQ3src: ds 1
*******************************************************************************
* *
* S C I D R I V E R M O D U L E *
*
Subscribe to:
Posts (Atom)