1 /* 2 * Copyright 2006-2009, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "vga.h" 8 #include "driver.h" 9 10 #include <vga.h> 11 12 #include <KernelExport.h> 13 14 15 status_t 16 vga_set_indexed_colors(uint8 first, uint8 *colors, uint16 count) 17 { 18 // If we don't actually have an ISA bus, bail. 19 if (gISA == NULL) 20 return B_BAD_ADDRESS; 21 22 if (first + count > 256) 23 count = 256 - first; 24 25 gISA->write_io_8(VGA_COLOR_WRITE_MODE, first); 26 27 // write VGA palette 28 for (int32 i = first; i < count; i++) { 29 uint8 color[3]; 30 if (user_memcpy(color, &colors[i * 3], 3) < B_OK) 31 return B_BAD_ADDRESS; 32 33 // VGA (usually) has only 6 bits per gun 34 gISA->write_io_8(VGA_COLOR_DATA, color[0] >> 2); 35 gISA->write_io_8(VGA_COLOR_DATA, color[1] >> 2); 36 gISA->write_io_8(VGA_COLOR_DATA, color[2] >> 2); 37 } 38 return B_OK; 39 } 40 41 42 status_t 43 vga_planar_blit(vesa_shared_info *info, uint8 *src, int32 srcBPR, 44 int32 left, int32 top, int32 right, int32 bottom) 45 { 46 // If we don't actually have an ISA bus, bail. 47 if (gISA == NULL) 48 return B_BAD_ADDRESS; 49 50 // If we don't actually have a frame_buffer, bail. 51 if (info->frame_buffer == NULL) 52 return B_BAD_ADDRESS; 53 54 int32 dstBPR = info->bytes_per_row; 55 uint8 *dst = info->frame_buffer + top * dstBPR + left / 8; 56 57 // TODO: this is awfully slow... 58 // TODO: assumes BGR order 59 for (int32 y = top; y <= bottom; y++) { 60 for (int32 plane = 0; plane < 4; plane++) { 61 // select the plane we intend to write to and read from 62 gISA->write_io_16(VGA_SEQUENCER_INDEX, (1 << (plane + 8)) | 0x02); 63 gISA->write_io_16(VGA_GRAPHICS_INDEX, (plane << 8) | 0x04); 64 65 uint8* srcHandle = src; 66 uint8* dstHandle = dst; 67 uint8 current8 = dstHandle[0]; 68 // we store 8 pixels before writing them back 69 70 int32 x = left; 71 for (; x <= right; x++) { 72 uint8 rgba[4]; 73 if (user_memcpy(rgba, srcHandle, 4) < B_OK) 74 return B_BAD_ADDRESS; 75 uint8 pixel = (308 * rgba[2] + 600 * rgba[1] 76 + 116 * rgba[0]) / 16384; 77 srcHandle += 4; 78 79 if (pixel & (1 << plane)) 80 current8 |= 0x80 >> (x & 7); 81 else 82 current8 &= ~(0x80 >> (x & 7)); 83 84 if ((x & 7) == 7) { 85 // last pixel in 8 pixel group 86 dstHandle[0] = current8; 87 dstHandle++; 88 current8 = dstHandle[0]; 89 } 90 } 91 92 if (x & 7) { 93 // last pixel has not been written yet 94 dstHandle[0] = current8; 95 } 96 } 97 dst += dstBPR; 98 src += srcBPR; 99 } 100 return B_OK; 101 } 102 103