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 / FEATZ80.C < prev    next >
C/C++ Source or Header  |  1993-05-21  |  5KB  |  161 lines

  1. #include    <intrpt.h>
  2.  
  3. /*
  4.  *    This source file demonstrates some of the special features
  5.  *    of the HI-TECH Z80/Z180/64180 C Cross Compiler.  This file should
  6.  *    be compiled with Z80 or Z180 code generation selected.
  7.  *    
  8.  *    To generate the best possible code from this source file, select
  9.  *    Z180 code generation from the "Options" menu and "Full Optimization"
  10.  *    from the "Optimization" menu.  This will demonstrate the quality of
  11.  *    code which can be obtained using HI-TECH C, for a fraction of the
  12.  *    effort required to write equivalent assember code.
  13.  *
  14.  *    HI-TECH C has a number of features designed to make programming
  15.  *    embedded processors simpler and more efficient, these include:
  16.  *
  17.  *    interrupt functions: interrupt handlers may be written entirely
  18.  *                 in C (no messy assembler code required).
  19.  *                 The Z80 cross compiler also allows functions
  20.  *                 to be declared as "fast interrupt" or
  21.  *                 "nmi interrupt".
  22.  *
  23.  *                 "nmi interrupt" functions return with a RETN
  24.  *                 instruction.
  25.  *
  26.  *                 "fast interrupt" functions preserve the
  27.  *                 general purpose register using the EXX and
  28.  *                 EX AF,AF' instructions, thereby saving the
  29.  *                 overhead of pushing registers onto the stack
  30.  *
  31.  *    port variables:         Z80 ports can be accessed directly from
  32.  *                 C - just like any other variable or
  33.  *                 memory location.
  34.  *
  35.  *    absolute variables:  variables of any type (even complex
  36.  *                 structures and arrays) can be placed at
  37.  *                 any absolute address in memory - great
  38.  *                 for handling memory mapped devices.
  39.  *
  40.  *    in-line assembler:   assembler code can be place in line.  This
  41.  *                 is useful for accessing special instructions.
  42.  *
  43.  *    register arguments:  some function arguments are passed in
  44.  *                 the DE and BC registers.  Register based
  45.  *                 argument passing is much faster and more
  46.  *                 compact than stack based passing.
  47.  */
  48.  
  49. #ifndef    z80
  50. #error    This program should be compiled to Z80/Z180 code
  51. #endif
  52.  
  53. volatile port unsigned char    SIO_CMD  @ 0x20;    /* SIO command reg */
  54. volatile port unsigned char    SIO_DATA @ 0x21;    /* SIO data reg */
  55.  
  56. volatile unsigned char        PIA_STATUS @ 0xFF80;    /* mem mapped PIA */
  57. volatile unsigned char        PIA_BUFFER @ 0xFF81;    /* at FF80 - FF81 */
  58.  
  59. unsigned char    rxbuf[256];            /* 256 byte circular buffer */
  60. unsigned char    ri_ptr, ro_ptr;            /* head, tail pointers */
  61.  
  62. /*
  63.  *    rx_intr handles receive interrupts from a Z80 sio
  64.  */
  65.  
  66. fast interrupt void
  67. rx_intr(void)
  68. {
  69.     rxbuf[ri_ptr++] = SIO_DATA;
  70.     if (ro_ptr == ri_ptr)        /* buffer overflow ? */
  71.         --ri_ptr;        /* discard last byte received */
  72. }
  73.  
  74. /*
  75.  *    sio_char_avail: returns 1 if a char is available, 0 otherwise
  76.  */
  77.  
  78. unsigned char
  79. sio_char_avail(void)
  80. {
  81.     return (ri_ptr != ro_ptr);
  82. }
  83.  
  84. /*
  85.  *    sio_get_char: returns one char from the tail of the circular
  86.  *                  buffer.  Assumes that a char is available.
  87.  */
  88.  
  89. unsigned char
  90. sio_get_char(void)
  91. {
  92.     unsigned char    ch;
  93.  
  94.     di();
  95.     ch = rxbuf[ro_ptr++];
  96.     ei();
  97.     return ch;
  98. }
  99.  
  100. /*
  101.  *    Transmit a character via the memory mapped PIA
  102.  *    bit 0 of STATUS register indicates it is ready to accept data
  103.  *
  104.  *    Note: register based argument passing is used with this
  105.  *    function.  "ch" will be passed in the E register.  If FULL
  106.  *    optimization is performed, "ch" probably won't ever be stored
  107.  *    to a stack location.
  108.  */
  109.  
  110. void
  111. pia_send(unsigned char ch)
  112. {
  113.     while (!(PIA_STATUS & 1))
  114.         continue;
  115.     PIA_BUFFER = ch;
  116. }
  117.  
  118. /*
  119.  *    Initialize the SIO and PIA - demo code only, not intended to be
  120.  *    an accurate example of Z80 SIO programming
  121.  *
  122.  *    Notes:     the post-pass optimizer will eliminate redundant LD BC,xxx
  123.  *               instructions in the SIO init code sequence.
  124.  *
  125.  *        If Z180 code is selected, OUT0 instructions will be used
  126.  *        instead of OUT (C),A.  The full version of the compiler
  127.  *        allows the user to specify whether port I/O code is to
  128.  *        be generated for 8 or 16 bit port address decoding.
  129.  */
  130.  
  131. void
  132. device_inits(void)
  133. {
  134.     di();            /* interrupts of while programming devices */
  135. #asm
  136.     IM    2        ;interrupt mode 2
  137.     LD    A,0xFF        ;vector page: 0xFF00 - 0xFFFF
  138.     LD    I,A
  139. #endasm
  140.     SIO_CMD = 0x01;        /* write to register 1 */
  141.     SIO_CMD = 0xC1;        /* register 1 = 0xC1 */
  142.     SIO_CMD = 0x02;        /* write to register 2 */
  143.     SIO_CMD = 0x3E;        /* register 2 = 0x3E */
  144.     SIO_CMD = 0x06;        /* register 6: interrupt vector */
  145.     SIO_CMD = 0x10;        /* vector: 0xFF10 */
  146.     set_vector((isr *) 0xFF10, rx_intr);
  147.     PIA_STATUS = 0x80;    /* reset PIA */
  148.     PIA_STATUS = 0x40;    /* mode 2: bidirectional, interrupts off */
  149.     ei();
  150. }
  151.  
  152. main()
  153. {
  154.     device_inits();
  155.     for (;;) {
  156.         if (sio_char_avail())
  157.             pia_send(sio_get_char());
  158.         /* other processing */
  159.     }
  160. }
  161.