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 (first + count > 256) 19 count = 256 - first; 20 21 gISA->write_io_8(VGA_COLOR_WRITE_MODE, first); 22 23 // write VGA palette 24 for (int32 i = first; i < count; i++) { 25 uint8 color[3]; 26 if (user_memcpy(color, &colors[i * 3], 3) < B_OK) 27 return B_BAD_ADDRESS; 28 29 // VGA (usually) has only 6 bits per gun 30 gISA->write_io_8(VGA_COLOR_DATA, color[0] >> 2); 31 gISA->write_io_8(VGA_COLOR_DATA, color[1] >> 2); 32 gISA->write_io_8(VGA_COLOR_DATA, color[2] >> 2); 33 } 34 return B_OK; 35 } 36 37 38 status_t 39 vga_planar_blit(vesa_shared_info *info, uint8 *src, int32 srcBPR, 40 int32 left, int32 top, int32 right, int32 bottom) 41 { 42 // If we don't actually have a frame_buffer, bail. 43 if (info->frame_buffer == NULL) 44 return B_BAD_ADDRESS; 45 46 int32 dstBPR = info->bytes_per_row; 47 uint8 *dst = info->frame_buffer + top * dstBPR + left / 8; 48 49 // TODO: this is awfully slow... 50 // TODO: assumes BGR order 51 for (int32 y = top; y <= bottom; y++) { 52 for (int32 plane = 0; plane < 4; plane++) { 53 // select the plane we intend to write to and read from 54 gISA->write_io_16(VGA_SEQUENCER_INDEX, (1 << (plane + 8)) | 0x02); 55 gISA->write_io_16(VGA_GRAPHICS_INDEX, (plane << 8) | 0x04); 56 57 uint8* srcHandle = src; 58 uint8* dstHandle = dst; 59 uint8 current8 = dstHandle[0]; 60 // we store 8 pixels before writing them back 61 62 int32 x = left; 63 for (; x <= right; x++) { 64 uint8 rgba[4]; 65 if (user_memcpy(rgba, srcHandle, 4) < B_OK) 66 return B_BAD_ADDRESS; 67 uint8 pixel = (308 * rgba[2] + 600 * rgba[1] 68 + 116 * rgba[0]) / 16384; 69 srcHandle += 4; 70 71 if (pixel & (1 << plane)) 72 current8 |= 0x80 >> (x & 7); 73 else 74 current8 &= ~(0x80 >> (x & 7)); 75 76 if ((x & 7) == 7) { 77 // last pixel in 8 pixel group 78 dstHandle[0] = current8; 79 dstHandle++; 80 current8 = dstHandle[0]; 81 } 82 } 83 84 if (x & 7) { 85 // last pixel has not been written yet 86 dstHandle[0] = current8; 87 } 88 } 89 dst += dstBPR; 90 src += srcBPR; 91 } 92 return B_OK; 93 } 94 95