1 /* 2 * Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 6 * Distributed under the terms of the NewOS License. 7 */ 8 9 10 #include <KernelExport.h> 11 #include <Drivers.h> 12 #include <ISA.h> 13 14 #include <console.h> 15 16 #include <string.h> 17 18 19 #define SCREEN_START 0xb8000 20 #define SCREEN_END 0xc0000 21 #define LINES 25 22 #define COLUMNS 80 23 24 #define TEXT_INDEX 0x3d4 25 #define TEXT_DATA 0x3d5 26 27 #define TEXT_CURSOR_LO 0x0f 28 #define TEXT_CURSOR_HI 0x0e 29 30 static uint16 *sOrigin; 31 static isa_module_info *sISA; 32 33 34 static int 35 text_init(void) 36 { 37 addr_t i; 38 39 if (get_module(B_ISA_MODULE_NAME, (module_info **)&sISA) < 0) { 40 dprintf("text module_init: no isa bus found..\n"); 41 return -1; 42 } 43 44 map_physical_memory("video_mem", SCREEN_START, SCREEN_END - SCREEN_START, 45 B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void *)&sOrigin); 46 dprintf("console/text: mapped vid mem to virtual address %p\n", sOrigin); 47 48 /* pre-touch all of the memory so that we dont fault while deep inside the kernel and displaying something */ 49 for (i = (addr_t)sOrigin; i < (addr_t)sOrigin + (SCREEN_END - SCREEN_START); 50 i += B_PAGE_SIZE) { 51 uint16 val = *(volatile uint16 *)i; 52 *(volatile uint16 *)i = val; 53 } 54 return 0; 55 } 56 57 58 static int 59 text_uninit(void) 60 { 61 put_module(B_ISA_MODULE_NAME); 62 63 // ToDo: unmap video memory (someday) 64 return 0; 65 } 66 67 68 static status_t 69 get_size(int32 *width, int32 *height) 70 { 71 *width = COLUMNS; 72 *height = LINES; 73 return 0; 74 } 75 76 77 static void 78 move_cursor(int32 x, int32 y) 79 { 80 short int pos; 81 82 if (x < 0 || y < 0) 83 pos = LINES * COLUMNS + 1; 84 else 85 pos = y * COLUMNS + x; 86 87 sISA->write_io_8(TEXT_INDEX, TEXT_CURSOR_LO); 88 sISA->write_io_8(TEXT_DATA, (char)pos); 89 sISA->write_io_8(TEXT_INDEX, TEXT_CURSOR_HI); 90 sISA->write_io_8(TEXT_DATA, (char)(pos >> 8)); 91 } 92 93 94 static void 95 put_glyph(int32 x, int32 y, uint8 glyph, uint8 attr) 96 { 97 uint16 pair = ((uint16)attr << 8) | (uint16)glyph; 98 uint16 *p = sOrigin + (y * COLUMNS) + x; 99 *p = pair; 100 } 101 102 103 static void 104 fill_glyph(int32 x, int32 y, int32 width, int32 height, uint8 glyph, uint8 attr) 105 { 106 uint16 pair = ((uint16)attr << 8) | (uint16)glyph; 107 int32 y_limit = y + height; 108 109 while (y < y_limit) { 110 uint16 *p = sOrigin + (y * COLUMNS) + x; 111 uint16 *p_limit = p + width; 112 while (p < p_limit) *p++ = pair; 113 y++; 114 } 115 } 116 117 118 static void 119 blit(int32 srcx, int32 srcy, int32 width, int32 height, int32 destx, int32 desty) 120 { 121 if ((srcx == 0) && (width == COLUMNS)) { 122 // whole lines 123 memmove(sOrigin + (desty * COLUMNS), sOrigin + (srcy * COLUMNS), height * COLUMNS * 2); 124 } else { 125 // FIXME 126 } 127 } 128 129 130 static void 131 clear(uint8 attr) 132 { 133 uint16 *base = (uint16 *)sOrigin; 134 uint32 i; 135 136 for (i = 0; i < COLUMNS * LINES; i++) 137 base[i] = (attr << 8) | 0x20; 138 } 139 140 141 static status_t 142 text_std_ops(int32 op, ...) 143 { 144 switch (op) { 145 case B_MODULE_INIT: 146 return text_init(); 147 case B_MODULE_UNINIT: 148 return text_uninit(); 149 150 default: 151 return B_ERROR; 152 } 153 } 154 155 156 static console_module_info sVGATextConsole = { 157 { 158 "console/vga_text/v1", 159 0, 160 text_std_ops 161 }, 162 get_size, 163 move_cursor, 164 put_glyph, 165 fill_glyph, 166 blit, 167 clear, 168 }; 169 170 module_info *modules[] = { 171 (module_info *)&sVGATextConsole, 172 NULL 173 }; 174