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.
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"); }