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