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