The sortix vga terminal now can delete tabs and newlines properly.

A nice little vga attribute array takes care of remembering what indexes
actually contains a character.
This commit is contained in:
Jonas 'Sortie' Termansen 2012-03-18 18:06:13 +01:00
parent 14a9149f17
commit c9ab4fa6b4
1 changed files with 41 additions and 11 deletions

View File

@ -35,6 +35,8 @@ namespace Sortix
const nat height = 25; const nat height = 25;
const uint16_t defaultcolor = (COLOR8_LIGHT_GREY << 8) | (COLOR8_BLACK << 12); const uint16_t defaultcolor = (COLOR8_LIGHT_GREY << 8) | (COLOR8_BLACK << 12);
uint16_t* const vga = (uint16_t* const) 0xB8000; uint16_t* const vga = (uint16_t* const) 0xB8000;
uint16_t vgaattr[width * height];
const uint16_t VGAATTR_CHAR = (1U<<0U);
nat line; nat line;
nat column; nat column;
uint16_t currentcolor; uint16_t currentcolor;
@ -78,7 +80,9 @@ namespace Sortix
{ {
for ( nat x = 0; x < width; x++ ) for ( nat x = 0; x < width; x++ )
{ {
vga[y * width + x] = ' ' | defaultcolor; unsigned index = y * width + x;
vga[index] = ' ' | defaultcolor;
vgaattr[index] = 0;
} }
} }
@ -100,13 +104,18 @@ namespace Sortix
{ {
for ( nat x = 0; x < width; x++ ) for ( nat x = 0; x < width; x++ )
{ {
vga[(y-1) * width + x] = vga[y * width + x]; unsigned oldindex = y * width + x;
unsigned newindex = (y-1) * width + x;
vga[newindex] = vga[oldindex];
vgaattr[newindex] = vgaattr[oldindex];
} }
} }
for ( nat x = 0; x < width; x++ ) for ( nat x = 0; x < width; x++ )
{ {
vga[(height-1) * width + x] = ' ' | currentcolor; unsigned index = (height-1) * width + x;
vga[index] = ' ' | currentcolor;
vgaattr[index] = 0;
} }
} }
@ -117,19 +126,25 @@ namespace Sortix
{ {
for ( nat x = 0; x < width; x++ ) for ( nat x = 0; x < width; x++ )
{ {
vga[(y) * width + x] = vga[(y-1) * width + x]; unsigned oldindex = (y-1) * width + x;
unsigned newindex = y * width + x;
vga[newindex] = vga[oldindex];
vgaattr[newindex] = vgaattr[oldindex];
} }
} }
for ( nat x = 0; x < width; x++ ) for ( nat x = 0; x < width; x++ )
{ {
vga[x] = ' ' | currentcolor; unsigned index = x;
vga[index] = ' ' | currentcolor;
vgaattr[index] = 0;
} }
} }
// Move to the next line. If at bottom, scroll one line up. // Move to the next line. If at bottom, scroll one line up.
void Newline() void Newline()
{ {
vgaattr[line * width + column] |= VGAATTR_CHAR;
if ( line < height - 1 ) if ( line < height - 1 )
{ {
line++; column = 0; line++; column = 0;
@ -185,12 +200,21 @@ namespace Sortix
column = 0; column = 0;
break; break;
} }
// Delete the previous char on this line. // Delete the previous character.
case '\b': case '\b':
{ {
// TODO: Properly handle backspace over lines and tabs. unsigned pos = line * width + column;
if ( column < 1 ) { break; } while ( pos )
vga[line * width + (--column)] = ' ' | currentcolor; {
unsigned nextpos = pos-1;
vga[nextpos] = ' ' | currentcolor;
pos = nextpos;
uint16_t attr = vgaattr[pos];
vgaattr[pos] = 0;
if ( attr & VGAATTR_CHAR ) { break; }
}
column = pos % width;
line = pos / width;
break; break;
} }
// Expand a tab to a few spaces. // Expand a tab to a few spaces.
@ -199,6 +223,7 @@ namespace Sortix
if ( column == width ) { Newline(); } if ( column == width ) { Newline(); }
nat until = 4 - (column % 4); nat until = 4 - (column % 4);
vgaattr[line * width + (column)] |= VGAATTR_CHAR;
while ( (until--) != 0 ) while ( (until--) != 0 )
{ {
vga[line * width + (column++)] = ' ' | currentcolor; vga[line * width + (column++)] = ' ' | currentcolor;
@ -216,7 +241,9 @@ namespace Sortix
default: default:
{ {
if ( column == width ) { Newline(); } if ( column == width ) { Newline(); }
vga[line * width + (column++)] = c | currentcolor; unsigned index = line * width + (column++);
vga[index] = c | currentcolor;
vgaattr[index] |= VGAATTR_CHAR;
break; break;
} }
} }
@ -373,6 +400,7 @@ namespace Sortix
for ( nat i = from; i <= to; i++ ) for ( nat i = from; i <= to; i++ )
{ {
vga[i] = ' ' | currentcolor; vga[i] = ' ' | currentcolor;
vgaattr[i] = 0;
} }
break; break;
@ -396,7 +424,9 @@ namespace Sortix
for ( nat i = from; i <= to; i++ ) for ( nat i = from; i <= to; i++ )
{ {
vga[line * width + i] = ' ' | currentcolor; unsigned index = line * width + i;
vga[index] = ' ' | currentcolor;
vgaattr[index] = 0;
} }
break; break;