OpenCores
URL https://opencores.org/ocsvn/c16/c16/trunk

Subversion Repositories c16

[/] [c16/] [trunk/] [test.c] - Diff between revs 2 and 26

Show entire file | Details | Blame | View Log

Rev 2 Rev 26
Line 1... Line 1...
 
/*******************************************************************************
 
********************************************************************************
 
**                                                                            **
 
**                     INTERRUPT HANDLING                                     **
 
**                                                                            **
 
********************************************************************************
 
*******************************************************************************/
 
 
 
unsigned char serial_in_buffer[16];
 
unsigned char serial_in_get      = 0;
 
unsigned char serial_in_put      = 0;
 
unsigned char serial_in_length   = 0;
 
unsigned char serial_in_overflow = 0;
 
 
 
void rx_interrupt()
 
{
 
char c = ASM(" IN   (IN_RX_DATA), RU");
 
 
 
   if (serial_in_length < sizeof(serial_in_buffer))
 
      {
 
        serial_in_buffer[serial_in_put] = c;
 
        serial_in_put = ++serial_in_put & 15;
 
        ++serial_in_length;
 
      }
 
   else
 
      {
 
        serial_in_overflow = 0xFF;
 
      }
 
}
 
//-----------------------------------------------------------------------------
 
 
 
unsigned char serial_out_buffer[16];
 
unsigned char serial_out_get      = 0;
 
unsigned char serial_out_put      = 0;
 
unsigned char serial_out_length   = 0;
 
 
 
void tx_interrupt()
 
{
 
   if (serial_out_length)
 
      {
 
        serial_out_buffer[serial_out_get];
 
        ASM(" OUT  R, (OUT_TX_DATA)");
 
        serial_out_get = ++serial_out_get & 15;
 
        --serial_out_length;
 
      }
 
   else
 
      {
 
        ASM(" MOVE #0x05, RR");            // RxInt and TimerInt
 
        ASM(" OUT  R, (OUT_INT_MASK)");
 
      }
 
}
 
 
 
//-----------------------------------------------------------------------------
 
 
 
unsigned int  milliseconds    = 0;
 
unsigned int  seconds_low     = 0;
 
unsigned int  seconds_mid     = 0;
 
unsigned int  seconds_high    = 0;
 
unsigned char seconds_changed = 0;
 
 
 
void timer_interrupt()
 
{
 
   ASM(" OUT  R, (OUT_RESET_TIMER)");
 
   if (++milliseconds == 1000)
 
      {
 
         milliseconds = 0;
 
         seconds_changed = 0xFF;
 
         if (++seconds_low == 0)
 
            {
 
              if (++seconds_mid == 0)   ++seconds_high;
 
            }
 
      }
 
}
 
//-----------------------------------------------------------------------------
 
void interrupt()
 
{
 
   ASM(" MOVE RR, -(SP)");
 
   ASM(" MOVE LL, RR");
 
   ASM(" MOVE RR, -(SP)");
 
 
 
   if (ASM(" IN   (IN_STATUS), RU") & 0x10)   rx_interrupt();
 
   if (ASM(" IN   (IN_STATUS), RU") & 0x20)   tx_interrupt();
 
   if (ASM(" IN   (IN_STATUS), RU") & 0x40)   timer_interrupt();
 
 
 
   ASM(" MOVE (SP)+, RR");
 
   ASM(" MOVE RR, LL");
 
   ASM(" MOVE (SP)+, RR");
 
   ASM(" RETI");
 
}
 
/*******************************************************************************
 
********************************************************************************
 
**                                                                            **
 
**                     UTILITY FUNCTIONS                                      **
 
**                                                                            **
 
********************************************************************************
 
*******************************************************************************/
 
 
 
int strlen(const char * buffer)
 
{
 
const char * from = buffer;
 
 
 
    while (*buffer)   buffer++;
 
 
 
   return buffer - from;
 
}
 
/*******************************************************************************
 
********************************************************************************
 
**                                                                            **
 
**                     SERIAL OUTPUT                                          **
 
**                                                                            **
 
********************************************************************************
 
*******************************************************************************/
 
 
 
int putchr(char c)
 
{
 
   while (serial_out_length == sizeof(serial_out_buffer))   /* wait */ ;
 
 
 
   serial_out_buffer[serial_out_put] = c;
 
   serial_out_put = ++serial_out_put & 15;
 
   ASM(" DI");   ++serial_out_length;   ASM(" EI");
 
   ASM(" MOVE #0x07, RR");            // RxInt and TxInt and TimerInt
 
   ASM(" OUT  R, (OUT_INT_MASK)");
 
   1;
 
}
 
//-----------------------------------------------------------------------------
 
void print_string(const char * buffer)
 
{
 
    while (*buffer)   putchr(*buffer++);
 
}
 
//-----------------------------------------------------------------------------
 
void print_hex(char * dest, unsigned int value, const char * hex)
 
{
 
   if (value >= 0x1000)   *dest++ = hex[(value >> 12) & 0x0F];
 
   if (value >=  0x100)   *dest++ = hex[(value >>  8) & 0x0F];
 
   if (value >=   0x10)   *dest++ = hex[(value >>  4) & 0x0F];
 
   *dest++ = hex[value  & 0x0F];
 
   *dest = 0;
 
}
 
//-----------------------------------------------------------------------------
 
void print_unsigned(char * dest, unsigned int value)
 
{
 
   if (value >= 10000)   { *dest++ = '0' + value / 10000;   value %= 10000; }
 
   if (value >=  1000)   { *dest++ = '0' + value /  1000;   value %=  1000; }
 
   if (value >=   100)   { *dest++ = '0' + value /   100;   value %=   100; }
 
   if (value >=    10)   { *dest++ = '0' + value /    10;   value %=    10; }
 
   *dest++ = '0' + value;
 
   *dest = 0;
 
}
 
//-----------------------------------------------------------------------------
 
int print_item(const char * buffer, char flags, char sign, char pad,
 
               const char * alt, int field_w, int min_w, char min_p)
 
{
 
   // [fill] [sign] [alt] [pad] [buffer] [fill]
 
   //        ----------- len ----------- 
 
int filllen = 0;
 
int signlen = 0;
 
int altlen  = 0;
 
int padlen  = 0;
 
int buflen  = strlen(buffer);
 
int len;
 
int i;
 
 
 
   if (min_w > buflen)          padlen = min_w - buflen;
 
   if (sign)                    signlen = 1;
 
   if (alt && (flags & 0x01))   altlen = strlen(alt);
 
 
 
   len = signlen + altlen + padlen + buflen;
 
 
 
   if (0x02 & ~flags)   // right align
 
      {
 
        for (i = len; i < field_w; i++)   putchr(pad);
 
      }
 
 
 
   if (sign)   putchr(sign);
 
   if (alt)
 
      {
 
        if (flags & 0x01)   print_string(alt);
 
      }
 
 
 
   for (i = 0; i < padlen; i++)   putchr(min_p);
 
   print_string(buffer);
 
 
 
   if (0x02 & flags)   // left align
 
      {
 
        for (i = len; i < field_w; i++)   putchr(pad);
 
      }
 
 
 
   return len;
 
}
 
//-----------------------------------------------------------------------------
 
int printf(const char * format, ...)
 
{
 
const char **  args = 1 + &format;
 
int            len = 0;
 
char           c;
 
char           flags;
 
char           sign;
 
char           pad;
 
const char *   alt;
 
int            field_w;
 
int            min_w;
 
unsigned int * which_w;
 
char           buffer[12];
 
 
 
   while (c = *format++)
 
       {
 
         if (c != '%')   { len +=putchr(c);   continue; }
 
 
 
         flags   = 0;
 
         sign    = 0;
 
         pad     = ' ';
 
         field_w = 0;
 
         min_w   = 0;
 
         which_w = &field_w;
 
         for (;;)
 
             {
 
               switch(c = *format++)
 
                  {
 
                    case 'X': print_hex(buffer, (unsigned int)*args++,
 
                                        "0123456789ABCDEF");
 
                              len += print_item(buffer, flags, sign, pad,
 
                                                "0X", field_w, min_w, '0');
 
                              break;
 
 
 
                    case 'd': if (((int)*args) < 0)
 
                                 {
 
                                   sign = '-';
 
                                   *args = (char *)(- ((int)*args));
 
                                 }
 
                              print_unsigned(buffer, (unsigned int)*args++);
 
                              len += print_item(buffer, flags, sign, pad,
 
                                                "", field_w, min_w, '0');
 
                              break;
 
 
 
                    case 's': len += print_item(*args++, flags & 0x02, 0, ' ',
 
                                                "", field_w, min_w, ' ');
 
                              break;
 
 
 
                    case 'u': print_unsigned(buffer, (unsigned int)*args++);
 
                              len += print_item(buffer, flags, sign, pad,
 
                                                "", field_w, min_w, '0');
 
                              break;
 
 
 
                    case 'x': print_hex(buffer, (unsigned int)*args++,
 
                                        "0123456789abcdef");
 
                              len += print_item(buffer, flags, sign, pad,
 
                                                "0x", field_w, min_w, '0');
 
                              break;
 
 
 
                    case 'c': len += putchr((int)*args++);    break;
 
 
 
                    case '#': flags |= 0x01;                  continue;
 
                    case '-': flags |= 0x02;                  continue;
 
                    case ' ': if (!sign)  sign = ' ';         continue;
 
                    case '+': sign = '+';                     continue;
 
                    case '.': which_w = &min_w;               continue;
 
 
 
                    case '0': if (*which_w)   *which_w *= 10;
 
                              else            pad = '0';
 
                              continue;
 
 
 
                    case '1': *which_w = 10 * *which_w + 1;   continue;
 
                    case '2': *which_w = 10 * *which_w + 2;   continue;
 
                    case '3': *which_w = 10 * *which_w + 3;   continue;
 
                    case '4': *which_w = 10 * *which_w + 4;   continue;
 
                    case '5': *which_w = 10 * *which_w + 5;   continue;
 
                    case '6': *which_w = 10 * *which_w + 6;   continue;
 
                    case '7': *which_w = 10 * *which_w + 7;   continue;
 
                    case '8': *which_w = 10 * *which_w + 8;   continue;
 
                    case '9': *which_w = 10 * *which_w + 9;   continue;
 
                    case '*': *which_w = (int)*args++;        continue;
 
 
 
                    case 0:   format--;   // premature end of format
 
                              break;
 
 
 
                    default:  len += putchr(c);
 
                              break;
 
                  }
 
                break;
 
             }
 
       }
 
   return len;
 
}
 
/*******************************************************************************
 
********************************************************************************
 
**                                                                            **
 
**                     SERIAL INPUT                                           **
 
**                                                                            **
 
********************************************************************************
 
*******************************************************************************/
 
 
 
int getchr()
 
{
 
char c;
 
 
 
   while (! serial_in_length)   /* wait */ ;
 
   c = serial_in_buffer[serial_in_get];
 
   serial_in_get = ++serial_in_get & 15;
 
   ASM(" DI");   --serial_in_length;   ASM(" EI");
 
   return c;
 
}
 
//-----------------------------------------------------------------------------
 
int peekchr()
 
{
 
   while (! serial_in_length)   /* wait */ ;
 
   return serial_in_buffer[serial_in_get];
 
}
 
//-----------------------------------------------------------------------------
 
char getnibble(char echo)
 
{
 
char c  = peekchr();
 
int ret = -1;
 
 
 
   if      ((c >= '0') && (c <= '9'))   ret = c - '0';
 
   else if ((c >= 'A') && (c <= 'F'))   ret = c - 0x37;
 
   else if ((c >= 'a') && (c <= 'f'))   ret = c - 0x57;
 
 
 
   if (ret != -1)   // valid hex char
 
      {
 
        getchr();
 
        if (echo)   putchr(c);
 
      }
 
   return ret;
 
}
 
//-----------------------------------------------------------------------------
 
int gethex(char echo)
 
{
 
int  ret = 0;
 
char c;
 
 
 
   while ((c = getnibble(echo)) != -1)   ret = (ret << 4) | c;
 
   return ret;
 
}
 
/*******************************************************************************
 
********************************************************************************
 
**                                                                            **
 
**                     main and its helpers                                   **
 
**                                                                            **
 
********************************************************************************
 
*******************************************************************************/
 
 
 
void show_time()
 
{
 
unsigned int sl;
 
unsigned int sm;
 
unsigned int sh;
 
 
 
   do {
 
        seconds_changed = 0;
 
        sl = seconds_low;
 
        sm = seconds_mid;
 
        sh = seconds_high;
 
      } while (seconds_changed);
 
 
 
   printf("Uptime is %4.4X%4.4X%4.4X seconds\r\n", sh, sm, sl);
 
}
 
//-----------------------------------------------------------------------------
 
void display_memory(unsigned char * address)
 
{
 
char c;
 
int  row;
 
int  col;
 
 
 
   for (row = 0; row < 16; row++)
 
       {
 
         printf("%4.4X:", address);
 
         for (col = 0; col < 16; col++)   printf(" %2.2X", *address++);
 
         address -= 16;
 
         printf(" - ");
 
         for (col = 0; col < 16; col++)
 
             {
 
               c = *address++;
 
               if (c < ' ')         putchr('.');
 
               else if (c < 0x7F)   putchr(c);
 
               else                 putchr('.');
 
             }
 
         printf("\r\n");
 
       }
 
}
 
//-----------------------------------------------------------------------------
 
int main(int argc, char * argv[])
 
{
 
char            c;
 
char            noprompt;
 
char            last_c;
 
unsigned char * address;
 
 
 
   ASM(" MOVE #0x05, RR");            // RxInterrupt enable bit
 
   ASM(" OUT  R, (OUT_INT_MASK)");
 
   for (;;)
 
      {
 
        last_c = c;
 
        if (!noprompt)   printf("-> ");
 
        noprompt = 0;
 
        switch(c = getchr())
 
           {
 
             case '\r':
 
             case '\n':
 
                  if (last_c == 'd')
 
                     {
 
                       address += 0x100;
 
                       printf("\b\b\b\b");
 
                       display_memory(address);
 
                       c = 'd';
 
                     }
 
                  noprompt = 1;
 
                  break;
 
 
 
             case 'C':
 
             case 'c':
 
                  show_time();
 
                  break;
 
 
 
             case 'D':
 
             case 'd':
 
                  last_c = 'd';
 
                  printf("Display ");
 
                  address = (unsigned char *)gethex(1);
 
                  printf("\r\n");
 
                  getchr();
 
                  display_memory(address);
 
                  break;
 
 
 
             case 'E':
 
             case 'e':
 
                  printf("LEDs ");
 
                  gethex(1);    ASM(" OUT R, (OUT_LEDS)");
 
                  printf("\r\n");
 
                  getchr();
 
                  break;
 
 
 
             case 'M':
 
             case 'm':
 
                  printf("Memory ");
 
                  address = (unsigned char *)gethex(1);
 
                  printf(" Value ");
 
                  getchr();
 
                  *address = gethex(1);
 
                  getchr();
 
                  printf("\r\n");
 
                  break;
 
 
 
             case 'S':
 
             case 's':
 
                  printf("DIP switch is 0x%X\r\n",
 
                         ASM(" IN (IN_DIP_SWITCH), RU"));
 
                  break;
 
 
 
             case 'T':
 
             case 't':
 
                  printf("Temperature is %d degrees Celsius\r\n",
 
                         ASM(" IN (IN_TEMPERAT), RU"));
 
                  break;
 
 
 
             case 'Q':
 
             case 'q':
 
             case 'X':
 
             case 'x': printf("Halted.\r\n");
 
                       while (serial_out_length)   /* wait */ ;
 
                       ASM(" DI");
 
                       ASM(" HALT");
 
                  break;
 
 
 
             default:
 
                  printf("\r\n"
 
                         "C - show time\r\n"
 
                         "D - display memory\r\n"
 
                         "E - set LEDs\r\n"
 
                         "M - modify memory\r\n"
 
                         "S - read DIP switch\r\n"
 
                         "T - read temperature\r\n"
 
                         "Q - quit\r\n"
 
                         "X - exit\r\n"
 
                         "\r\n");
 
           }
 
      }
 
}
 
//-----------------------------------------------------------------------------
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.