1/** 2 * \file 3 */ 4 5/* 6 * Copyright (c) 2009, ETH Zurich. 7 * All rights reserved. 8 * 9 * This file is distributed under the terms in the attached LICENSE file. 10 * If you do not find this file, copies can be found by writing to: 11 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 12 */ 13 14#include "vmkitmon.h" 15#include "console.h" 16#include <stdlib.h> 17#include <barrelfish/terminal.h> 18 19struct console * 20console_new (void) 21{ 22 struct console *ret = calloc(1, sizeof(struct console)); 23 return ret; 24} 25 26static int 27handle_set_cursor_position (struct console *c, struct guest *g) 28{ 29 // only support mode 0 for now 30 if (guest_get_bh(g) != 0) { 31 return HANDLER_ERR_UNHANDELED; 32 } 33 34 c->cursor_pos_x = guest_get_dl(g); 35 c->cursor_pos_y = guest_get_dh(g); 36 37 return HANDLER_ERR_OK; 38} 39 40static int 41handle_write_char_with_attr (struct console *c, struct guest *g) 42{ 43 // only support mode 0 for now 44 if (guest_get_bh(g) != 0) { 45 return HANDLER_ERR_UNHANDELED; 46 } 47 // we only support "normal" text output atm 48 if (guest_get_bl(g) != 7) { 49 return HANDLER_ERR_UNHANDELED; 50 } 51 52 // FIXME: Here we completely ignore the postition of the cursor atm since we 53 // do not have proper terminal support in BF. 54 // We also ignore multiple char writes, they make no sense atm. 55 int r; 56 char chr = guest_get_al(g); 57 58 r = terminal_write(&chr, 1); 59 assert(r == 1); 60 61 return HANDLER_ERR_OK; 62} 63 64static int 65handle_teletype_output (struct console *c, struct guest *g) 66{ 67 // only support mode 0 for now 68 if (guest_get_bh(g) != 0) { 69 return HANDLER_ERR_UNHANDELED; 70 } 71 72 // we do not yet have a real understanding of the terminal, assume it is 73 // 80x25 and we simply insert new lines at the end of the "screen" 74 int r; 75 char chr = guest_get_al(g); 76 77 // treat CR and LF as column clearing chars 78 if (chr == '\r' || chr == '\n') { 79 c->cursor_pos_x = 0; 80 } 81 // insert a CR if we are passed the last column of the screen 82 else if (c->cursor_pos_x > 79) { 83 r = terminal_write("\n", 1); 84 assert(r == 1); 85 c->cursor_pos_x = 0; 86 } 87 // in all other cases just increase the column 88 else { 89 c->cursor_pos_x++; 90 } 91 92 r = terminal_write(&chr, 1); 93 assert(r == 1); 94 95 return HANDLER_ERR_OK; 96} 97 98static int 99handle_get_cursor_pos_and_size (struct console *c, struct guest *g) 100{ 101 // only support mode 0 for now 102 if (guest_get_bh(g) != 0) { 103 return HANDLER_ERR_UNHANDELED; 104 } 105 106 // set ax to 0 107 guest_set_ax(g, 0); 108 // we do not support scan-lines 109 guest_set_cx(g, 0); 110 111 // set the position 112 guest_set_dl(g, c->cursor_pos_x); 113 guest_set_dh(g, c->cursor_pos_y); 114 115 return HANDLER_ERR_OK; 116} 117 118static int 119handle_set_text_cursor_shape (struct console *c, struct guest *g) 120{ 121 // we only handle primitive cursors 122 if (guest_get_cx(g) != 0) { 123 printf("console: Unsupported cursor requested\n"); 124 return HANDLER_ERR_FATAL; 125 } 126 127 return HANDLER_ERR_OK; 128} 129 130static int 131handle_get_current_video_mode (struct console *c, struct guest *g) 132{ 133 // FIXME: for the terminal to be more flexible this should not be hardcoded 134 guest_set_ah(g, 80), 135 guest_set_al(g, 0x6); // VGA, 80x25, 8x8 box, res 640x200, 2 colors 136 guest_set_bh(g, 0); 137 138 return HANDLER_ERR_OK; 139} 140 141static int 142handle_get_ega_info (struct console *c, struct guest *g) 143{ 144 // FIXME: only partially implemented, linux wants BX to be 0x10 to believe 145 // it is confronted with a CGA card. 146 guest_set_bx(g, 0x10); 147 148 return HANDLER_ERR_OK; 149} 150 151static int 152handle_get_svga_info (struct console *c, struct guest *g) 153{ 154 // we do not support vesa yet 155 guest_set_ax(g, 0); 156 157 return HANDLER_ERR_OK; 158} 159 160static int 161handle_set_video_mode (struct console *c, struct guest *g) 162{ 163 // FIXME: Ignored for now. 164 165 return HANDLER_ERR_OK; 166} 167 168int 169console_handle_int10 (struct console *c, struct guest *g) 170{ 171 // VESA SuperVGA BIOS (VBE) - GET SuperVGA INFORMATION 172 if (guest_get_ax(g) == 0x4f00) { 173 return handle_get_svga_info(c, g); 174 } 175 // VIDEO - SET VIDEO MODE 176 if (guest_get_ah(g) == 0x0) { 177 return handle_set_video_mode(c, g); 178 } 179 // VIDEO - SET TEXT-MODE CURSOR SHAPE 180 if (guest_get_ah(g) == 0x1) { 181 return handle_set_text_cursor_shape(c, g); 182 } 183 // VIDEO - SET CURSOR POSITION 184 else if (guest_get_ah(g) == 0x2) { 185 return handle_set_cursor_position(c, g); 186 } 187 // VIDEO - GET CURSOR POSITION AND SIZE 188 else if (guest_get_ah(g) == 0x3) { 189 return handle_get_cursor_pos_and_size(c, g); 190 } 191 // VIDEO - WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION 192 else if (guest_get_ah(g) == 0x9) { 193 return handle_write_char_with_attr(c, g); 194 } 195 // VIDEO - TELETYPE OUTPUT 196 else if (guest_get_ah(g) == 0xe) { 197 return handle_teletype_output(c, g); 198 } 199 // VIDEO - GET CURRENT VIDEO MODEL_CGA 200 else if (guest_get_ah(g) == 0xf) { 201 return handle_get_current_video_mode(c, g); 202 } 203 // VIDEO - ALTERNATE FUNCTION SELECT (PS, EGA, VGA, MCGA) - GET EGA INFO 204 else if (guest_get_ah(g) == 0x12 && guest_get_bl(g) == 0x10) { 205 return handle_get_ega_info(c, g); 206 } 207 208 return HANDLER_ERR_UNHANDELED; 209} 210