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
vga_set_indexed_colors(uint8 first,uint8 * colors,uint16 count)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
vga_planar_blit(vesa_shared_info * info,uint8 * src,int32 srcBPR,int32 left,int32 top,int32 right,int32 bottom)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