55
66use neotron_common_bios:: video:: { Attr , TextBackgroundColour , TextForegroundColour } ;
77
8- #[ derive( Debug ) ]
98pub struct VgaConsole {
109 addr : * mut u8 ,
1110 width : isize ,
1211 height : isize ,
1312 row : isize ,
1413 col : isize ,
14+ attr : Attr ,
1515}
1616
1717impl VgaConsole {
@@ -29,6 +29,7 @@ impl VgaConsole {
2929 height,
3030 row : 0 ,
3131 col : 0 ,
32+ attr : Self :: DEFAULT_ATTR ,
3233 }
3334 }
3435
@@ -60,24 +61,56 @@ impl VgaConsole {
6061 pub fn clear ( & mut self ) {
6162 for row in 0 ..self . height {
6263 for col in 0 ..self . width {
63- self . write_at ( row, col, b' ' , Some ( Self :: DEFAULT_ATTR ) ) ;
64+ self . write_at ( row, col, b' ' ) ;
6465 }
6566 }
6667 self . reset_cursor ( ) ;
6768 }
6869
69- fn write ( & mut self , glyph : u8 , attr : Option < Attr > ) {
70- self . write_at ( self . row , self . col , glyph, attr) ;
70+ pub fn write_bstr ( & mut self , bstr : & [ u8 ] ) {
71+ for b in bstr {
72+ self . scroll_as_required ( ) ;
73+ match b {
74+ 0x08 => {
75+ // This is a backspace, so we go back one character (if we
76+ // can). We expect the caller to provide "\u{0008} \u{0008}"
77+ // to actually erase the char then move the cursor over it.
78+ if self . col > 0 {
79+ self . col -= 1 ;
80+ }
81+ }
82+ b'\r' => {
83+ self . col = 0 ;
84+ }
85+ b'\n' => {
86+ self . col = 0 ;
87+ self . move_char_down ( ) ;
88+ }
89+ _ => {
90+ self . write ( * b) ;
91+ self . move_char_right ( ) ;
92+ }
93+ }
94+ }
7195 }
7296
73- fn write_at ( & mut self , row : isize , col : isize , glyph : u8 , attr : Option < Attr > ) {
97+ /// Set the default attribute for any future text.
98+ pub fn set_attr ( & mut self , attr : Attr ) {
99+ self . attr = attr;
100+ }
101+
102+ /// Put a glyph at the next position on the screen.
103+ fn write ( & mut self , glyph : u8 ) {
104+ self . write_at ( self . row , self . col , glyph) ;
105+ }
106+
107+ /// Put a glyph at a given position on the screen.
108+ fn write_at ( & mut self , row : isize , col : isize , glyph : u8 ) {
74109 assert ! ( row < self . height, "{} >= {}?" , row, self . height) ;
75110 assert ! ( col < self . width, "{} => {}?" , col, self . width) ;
76111 let offset = ( ( row * self . width ) + col) * 2 ;
77112 unsafe { core:: ptr:: write_volatile ( self . addr . offset ( offset) , glyph) } ;
78- if let Some ( a) = attr {
79- unsafe { core:: ptr:: write_volatile ( self . addr . offset ( offset + 1 ) , a. 0 ) } ;
80- }
113+ unsafe { core:: ptr:: write_volatile ( self . addr . offset ( offset + 1 ) , self . attr . as_u8 ( ) ) } ;
81114 }
82115
83116 fn scroll_page ( & mut self ) {
@@ -91,7 +124,7 @@ impl VgaConsole {
91124 ) ;
92125 // Blank the bottom line of the screen (rows[height-1]).
93126 for col in 0 ..self . width {
94- self . write_at ( self . height - 1 , col, b' ' , Some ( Self :: DEFAULT_ATTR ) ) ;
127+ self . write_at ( self . height - 1 , col, b' ' ) ;
95128 }
96129 }
97130 }
@@ -260,7 +293,7 @@ impl core::fmt::Write for VgaConsole {
260293 self . move_char_down ( ) ;
261294 }
262295 _ => {
263- self . write ( Self :: map_char_to_glyph ( ch) , None ) ;
296+ self . write ( Self :: map_char_to_glyph ( ch) ) ;
264297 self . move_char_right ( ) ;
265298 }
266299 }
0 commit comments