Listing 1—Much of the PIC-TV code is dedicated to processing escape commands embedded in strings sent from the HCS-II. Functions such as module mode, cursor movement, and color commands are handled here. Some similar commands have been removed for brevity.

byte get_ansi_number() {
  int tval1, tval2;

  // Routine grabs numbers for ANSI commands out of current buffer
  // Used for both row & column numbers, which may be one or two digits
  tval1 = read_buffer(process_idx) & 0x0F;  
  // Quick & dirty ASCII conversion
  tval2 = read_buffer(++process_idx);
  if ((tval2 > '/') && (tval2 < ':')) {// Add together and skip the ;
    tval1 *= 10;	// Move first digit to tens position
    tval1 += (tval2 & 0x0F);	// Grab ones digit & point to next char
    process_idx++;
  }
  return tval1;
}

>> The code below is called when a \e is found in a string
case 'e':       // Escape char!  Could be lots of things!
                // ESC[(idx);(scratch)(command letter)
  process_idx += 2;            // Skip [ sign
  scratch = 0;  // Default if not specified (idx is set below)
  idx = read_buffer(process_idx);  // Figure out what digits we have
  if (idx > '/' && idx < ':') {	// We have a number – let’s get it
    idx = get_ansi_number();
    if (read_buffer(process_idx) == ';') {  // We have a second number
      process_idx++;	// Point to next number
      scratch = get_ansi_number();
    }
  } else {	
    idx = 0;    // Command with no number—set to default value
  }
// Execute routine based on command letter, Some will set this true 
//   to skip moving cursor
skipgoto = FALSE;  
switch (read_buffer(process_idx)) {
  case 'A':	// Cursor up
    if (y > idx) {
      y -= idx;
    } else {
      y = 0;
    }
  break;

  case 'B':	// Cursor down
    y += idx;
    if (y > rows) { y = rows; }
  break;

  [other similar cursor movement commands]

  case 'f':	// Move cursor to x,y
    y = idx; x = scratch;
  break;

  case 'g':	// Beep for a given period of time
    if (idx > 10) idx = 10;
    beepout = 1;
    b_time = idx * 10;
    set_rtcc(0x00);
    timeok = TRUE;
  break;

  [other similar cursor movement commands]

  case 'K':	// Clear to end of line
    for(idx = x; idx <= cols; idx++) {
      restart_wdt();
      putc(' ');
    }
  break;

  case 'J':	// ANSI clear screen
    if (idx == 2) {	// Clear Screen
      printf(send_uart_serial, "{A");
      delay_ms(5);
      x = 0; y = 0;
    }
    skipgoto = TRUE;
  break;

  // Color commands
  case 'M':                // Set screen color in local mode only
    if (local_mode && (idx < 8)) {
      printf(send_uart_serial, "{F%u", idx);
    }
    skipgoto = TRUE;	// No need to move the cursor
  break;

  [Other similar color set commands]

  case 's':	// Save current cursor position
    sx = x; sy = y;
    skipgoto = TRUE;
  break;

  case 'u': 	// Restore saved cursor position
    x = sx; y = sy;	
  break;

  default:
  skipgoto = TRUE;
  break;
}
if (!skipgoto) { move_cursor(x, y); }  // A few commands don't  
	       //  require cursor to move 
break;