home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
SIMTEL
/
HITECH-C
/
Z8051H83.EXE
/
FEATH83.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-21
|
4KB
|
139 lines
#include <intrpt.h>
#include <h83.h>
/*
* This source file demonstrates some of the special features
* of the HI-TECH H8/300 C Cross Compiler. This file should
* be compiled with H8/300 code generation selected.
*
* To generate the best possible code from this source file, select
* H8/300 code generation from the "Options" menu and "Full Optimization"
* from the "Optimization" menu. This will demonstrate the quality of
* code which can be obtained using HI-TECH C, for a fraction of the
* effort required to write equivalent assember code.
*
* HI-TECH C has a number of features designed to make programming
* embedded processors simpler and more efficient, these include:
*
* interrupt functions: interrupt handlers may be written entirely
* in C (no messy assembler code required).
*
* absolute variables: variables of any type (even complex
* structures and arrays) can be placed at
* any absolute address in memory - great
* for handling memory mapped devices.
*
* in-line assembler: assembler code can be place in line. This
* is useful for accessing special instructions.
*
* register arguments: some function arguments are passed in the
* the R1, R2 and R3 registers. Register based
* argument passing is much faster and more
* compact than stack based passing.
*/
#ifndef h8300
#error This program should be compiled to H8/300 code
#endif
volatile unsigned char PIA_STATUS @ 0x2080; /* mem mapped PIA */
volatile unsigned char PIA_BUFFER @ 0x2081; /* at 2080 - 2081 */
unsigned char rxbuf[256]; /* 256 byte circular buffer */
unsigned char ri_ptr, ro_ptr; /* head, tail pointers */
/* serial i/o for H8/330 */
#define BAUD_RATE 19200 /* Serial baud rate */
#define OSC 16000000L /* Xtal frequency */
#define DIVIDER (OSC/(64*BAUD_RATE)-1)
/*
* rx_intr handles receive interrupts from serial port
*/
interrupt void
rx_intr(void)
{
if (SSR & (ORER|PER|FER)) { /* serial port error ? */
SSR &= ~(ORER|FER|PER);
} else {
rxbuf[ri_ptr++] = RDR;
SSR &= ~RDRF;
if (ro_ptr == ri_ptr) /* buffer overflow ? */
--ri_ptr; /* discard last byte received */
}
}
/*
* sio_char_avail: returns 1 if a char is available, 0 otherwise
*/
unsigned char
sio_char_avail(void)
{
return (ri_ptr != ro_ptr);
}
/*
* sio_get_char: returns one char from the tail of the circular
* buffer. Assumes that a char is available.
*/
unsigned char
sio_get_char(void)
{
unsigned char ch;
di();
ch = rxbuf[ro_ptr++];
ei();
return ch;
}
/*
* Transmit a character via the memory mapped PIA
* bit 0 of STATUS register indicates it is ready to accept data
*
* Note: register based argument passing is used with this
* function. "ch" will be passed in the R1 register. If FULL
* optimization is performed, "ch" probably won't ever be stored
* to a stack location.
*/
void
pia_send(unsigned char ch)
{
while (!(PIA_STATUS & 1))
continue;
PIA_BUFFER = ch;
}
/*
* Initialize the SIO and PIA
*/
void
device_inits(void)
{
di(); /* interrupts of while programming devices */
SCR = TE|RE; /* enable transmitter & receiver */
BRR = DIVIDER; /* set baud rate */
SSR &= ~(ORER|FER|PER);
SSR |= RIE; /* receive interrupts ON */
set_vector((isr *) RXI, rx_intr);
PIA_STATUS = 0x80; /* reset PIA */
PIA_STATUS = 0x40; /* mode 2: bidirectional, interrupts off */
ei();
}
main()
{
device_inits();
for (;;) {
if (sio_char_avail())
pia_send(sio_get_char());
/* other processing */
}
}