Some classes and macros to enable quick single line trace and watch facilities. Three macros DBUG_INIT, TRACE & WATCH are used to implement all functions. DBUG_INIT is used to allocate the maximum number of watch items that are to be displayed at any time. The remainder of the VT100 emulation screen will be dedicated to the scrolling trace function. The use of macros means that they will be ignored by the compiler when the debug declaration is removed. To assist in formatting the string output I have implemented a caret field that is interpreted as a screen attribute eg ^R reverse video on ^r reverse video off. Look at the VT100 class for further details. This was completed for a rush project about 10 minutes ago so expect a few issues to become apparent.

Dependencies:   mbed

VT100.cpp

Committer:
ChrisHatfield
Date:
2010-01-04
Revision:
0:0c4137d26c2e

File content as of revision 0:0c4137d26c2e:

#include <stdio.h>
#include "mbed.h"
#include "VT100.h"

CVT100::CVT100(void)
 : m_pVT100(NULL)
{
  m_pVT100 = new Serial(USBTX, USBRX);
}

CVT100::~CVT100(void)
{
  delete m_pVT100;
}

void CVT100::printf(const char *lpszFormat, ...)
{
    char szBuffer[256];
    va_list args;
    va_start(args, lpszFormat);
    vsprintf(szBuffer, lpszFormat, args);
    va_end(args);
    PutString(FormatString(szBuffer));
}

void CVT100::vprintf(const char *lpszFormat, va_list args)
{
    char szBuffer[256];
    vsprintf(szBuffer, lpszFormat, args);
    printf(szBuffer);
}

void CVT100::printf(unsigned char nCol, unsigned char nRow, const char *lpszFormat, ...)
{
    char szBuffer[256];
    SaveCursor();
    MoveXY(nCol, nRow);
    va_list    args;
    va_start(args, lpszFormat);
    vsprintf(szBuffer, lpszFormat, args);
    va_end(args);
    printf(szBuffer);
    RestoreCursor();
}

void CVT100::vprintf(unsigned char nCol, unsigned char nRow, const char *lpszFormat, va_list args)
{
    char szBuffer[256];
    vsprintf(szBuffer, lpszFormat, args);
    printf(nCol, nRow, szBuffer);
}

void CVT100::ClearScreen(void)
{
    PutString("\x1b[2J\x1b[0m");
}

void CVT100::MoveXY(unsigned char nCol, unsigned char nRow)
{
    char szBuffer[32];
    sprintf(szBuffer, "\x1b[%d;%dH", nRow, nCol);
    PutString(szBuffer);
}

void CVT100::SetScroll(unsigned char nStart, unsigned char nEnd)
{
    char szBuffer[32];
    sprintf(szBuffer, "\x1b[%d;%dr", nStart, nEnd);
    PutString(szBuffer);
}

void CVT100::SaveCursor(void)
{
    PutString("\x1b""7");
}

void CVT100::RestoreCursor(void)
{
  PutString("\x1b""8");
}

char* CVT100::FormatString(const char *lpszFormat)
{
  static char buffer[4096];
  static char copy[4096];

  strcpy(copy, lpszFormat);  // Store Copies
  strcpy(buffer, lpszFormat);

  char *p = strstr(copy, "^");
  while(p)  // Is substr in str?
    {
      strncpy(buffer, copy, p - copy); // Copy characters
      switch (p[1])
      {
        case 'B': // Bold On
          sprintf(buffer + (p - copy), "%s%s", "\x1b[1m", p + 2);
          break;
        case 'b': // Bold off
          sprintf(buffer + (p - copy), "%s%s", "\x1b[21m", p + 2);
          break;
        case 'F': // Blink On
          sprintf(buffer + (p - copy), "%s%s", "\x1b[5m", p + 2);
          break;
        case 'f': // Blink off
          sprintf(buffer + (p - copy), "%s%s", "\x1b[25m", p + 2);
          break;
        case 'L': // Low Intensity On
          sprintf(buffer + (p - copy), "%s%s", "\x1b[2m", p + 2);
          break;
        case 'l': // Low Intensity off
          sprintf(buffer + (p - copy), "%s%s", "\x1b[22m", p + 2);
          break;
        case 'R': // Reverse Video On
          sprintf(buffer + (p - copy), "%s%s", "\x1b[7m", p + 2);
          break;
        case 'r': //  Reverse Video off
          sprintf(buffer + (p - copy), "%s%s", "\x1b[27m", p + 2);
          break;
        case 'U': // Underline On
          sprintf(buffer + (p - copy), "%s%s", "\x1b[4m", p + 2);
          break;
        case 'u': // Underline off
          sprintf(buffer + (p - copy), "%s%s", "\x1b[24m", p + 2);
          break;
        case '_': // All Attributes off
          sprintf(buffer + (p - copy), "%s%s", "\x1b[0m", p + 2);
          break;
        case '^': // Caret Character
          sprintf(buffer + (p - copy), "%s%s", "^", p + 2);
          break;
        default: // Delete the Caret (or Infinite Loop)
          sprintf(buffer + (p - copy), "%s", p + 2);
          break;    
      }
      strcpy(copy, buffer);
      p = strstr(copy, "^");
  }
  return buffer;
}

void CVT100::PutString(const char *lpszOutput)
{
  int i(0);
  while(lpszOutput[i])
    m_pVT100->putc(lpszOutput[i++]);
}

void CVT100::CursorOff(bool bOff /*= true*/)
{
  if (bOff)
    PutString("\x1b[?25l");
  else
    PutString("\x1b[?25h");
}