Listing 1Much 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 lets 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 numberset 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;