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