10c6f7795SAxel Dörfler /*
2bb693d77SAxel Dörfler * Copyright 2006-2009, Axel Dörfler, axeld@pinc-software.de.
30c6f7795SAxel Dörfler * Distributed under the terms of the MIT License.
40c6f7795SAxel Dörfler */
50c6f7795SAxel Dörfler
60c6f7795SAxel Dörfler
70c6f7795SAxel Dörfler #include "vga.h"
80c6f7795SAxel Dörfler #include "driver.h"
90c6f7795SAxel Dörfler
100c6f7795SAxel Dörfler #include <vga.h>
110c6f7795SAxel Dörfler
120c6f7795SAxel Dörfler #include <KernelExport.h>
130c6f7795SAxel Dörfler
140c6f7795SAxel Dörfler
150c6f7795SAxel Dörfler status_t
vga_set_indexed_colors(uint8 first,uint8 * colors,uint16 count)160c6f7795SAxel Dörfler vga_set_indexed_colors(uint8 first, uint8 *colors, uint16 count)
170c6f7795SAxel Dörfler {
18*5ae7ac5fSX512 // If we don't actually have an ISA bus, bail.
19*5ae7ac5fSX512 if (gISA == NULL)
20*5ae7ac5fSX512 return B_BAD_ADDRESS;
21*5ae7ac5fSX512
22bb693d77SAxel Dörfler if (first + count > 256)
23bb693d77SAxel Dörfler count = 256 - first;
24bb693d77SAxel Dörfler
250c6f7795SAxel Dörfler gISA->write_io_8(VGA_COLOR_WRITE_MODE, first);
260c6f7795SAxel Dörfler
270c6f7795SAxel Dörfler // write VGA palette
280c6f7795SAxel Dörfler for (int32 i = first; i < count; i++) {
290c6f7795SAxel Dörfler uint8 color[3];
300c6f7795SAxel Dörfler if (user_memcpy(color, &colors[i * 3], 3) < B_OK)
310c6f7795SAxel Dörfler return B_BAD_ADDRESS;
320c6f7795SAxel Dörfler
330c6f7795SAxel Dörfler // VGA (usually) has only 6 bits per gun
340c6f7795SAxel Dörfler gISA->write_io_8(VGA_COLOR_DATA, color[0] >> 2);
350c6f7795SAxel Dörfler gISA->write_io_8(VGA_COLOR_DATA, color[1] >> 2);
360c6f7795SAxel Dörfler gISA->write_io_8(VGA_COLOR_DATA, color[2] >> 2);
370c6f7795SAxel Dörfler }
380c6f7795SAxel Dörfler return B_OK;
390c6f7795SAxel Dörfler }
400c6f7795SAxel Dörfler
410c6f7795SAxel Dörfler
420c6f7795SAxel Dörfler status_t
vga_planar_blit(vesa_shared_info * info,uint8 * src,int32 srcBPR,int32 left,int32 top,int32 right,int32 bottom)430c6f7795SAxel Dörfler vga_planar_blit(vesa_shared_info *info, uint8 *src, int32 srcBPR,
440c6f7795SAxel Dörfler int32 left, int32 top, int32 right, int32 bottom)
450c6f7795SAxel Dörfler {
46*5ae7ac5fSX512 // If we don't actually have an ISA bus, bail.
47*5ae7ac5fSX512 if (gISA == NULL)
48*5ae7ac5fSX512 return B_BAD_ADDRESS;
49*5ae7ac5fSX512
50122efe3aSAlexander von Gluck IV // If we don't actually have a frame_buffer, bail.
51122efe3aSAlexander von Gluck IV if (info->frame_buffer == NULL)
52122efe3aSAlexander von Gluck IV return B_BAD_ADDRESS;
53122efe3aSAlexander von Gluck IV
540c6f7795SAxel Dörfler int32 dstBPR = info->bytes_per_row;
550c6f7795SAxel Dörfler uint8 *dst = info->frame_buffer + top * dstBPR + left / 8;
560c6f7795SAxel Dörfler
570c6f7795SAxel Dörfler // TODO: this is awfully slow...
580c6f7795SAxel Dörfler // TODO: assumes BGR order
590c6f7795SAxel Dörfler for (int32 y = top; y <= bottom; y++) {
600c6f7795SAxel Dörfler for (int32 plane = 0; plane < 4; plane++) {
610c6f7795SAxel Dörfler // select the plane we intend to write to and read from
620c6f7795SAxel Dörfler gISA->write_io_16(VGA_SEQUENCER_INDEX, (1 << (plane + 8)) | 0x02);
630c6f7795SAxel Dörfler gISA->write_io_16(VGA_GRAPHICS_INDEX, (plane << 8) | 0x04);
640c6f7795SAxel Dörfler
650c6f7795SAxel Dörfler uint8* srcHandle = src;
660c6f7795SAxel Dörfler uint8* dstHandle = dst;
670c6f7795SAxel Dörfler uint8 current8 = dstHandle[0];
680c6f7795SAxel Dörfler // we store 8 pixels before writing them back
690c6f7795SAxel Dörfler
700c6f7795SAxel Dörfler int32 x = left;
710c6f7795SAxel Dörfler for (; x <= right; x++) {
720c6f7795SAxel Dörfler uint8 rgba[4];
730c6f7795SAxel Dörfler if (user_memcpy(rgba, srcHandle, 4) < B_OK)
740c6f7795SAxel Dörfler return B_BAD_ADDRESS;
750c6f7795SAxel Dörfler uint8 pixel = (308 * rgba[2] + 600 * rgba[1]
760c6f7795SAxel Dörfler + 116 * rgba[0]) / 16384;
770c6f7795SAxel Dörfler srcHandle += 4;
780c6f7795SAxel Dörfler
790c6f7795SAxel Dörfler if (pixel & (1 << plane))
800c6f7795SAxel Dörfler current8 |= 0x80 >> (x & 7);
810c6f7795SAxel Dörfler else
820c6f7795SAxel Dörfler current8 &= ~(0x80 >> (x & 7));
830c6f7795SAxel Dörfler
840c6f7795SAxel Dörfler if ((x & 7) == 7) {
850c6f7795SAxel Dörfler // last pixel in 8 pixel group
860c6f7795SAxel Dörfler dstHandle[0] = current8;
870c6f7795SAxel Dörfler dstHandle++;
880c6f7795SAxel Dörfler current8 = dstHandle[0];
890c6f7795SAxel Dörfler }
900c6f7795SAxel Dörfler }
910c6f7795SAxel Dörfler
920c6f7795SAxel Dörfler if (x & 7) {
930c6f7795SAxel Dörfler // last pixel has not been written yet
940c6f7795SAxel Dörfler dstHandle[0] = current8;
950c6f7795SAxel Dörfler }
960c6f7795SAxel Dörfler }
970c6f7795SAxel Dörfler dst += dstBPR;
980c6f7795SAxel Dörfler src += srcBPR;
990c6f7795SAxel Dörfler }
1000c6f7795SAxel Dörfler return B_OK;
1010c6f7795SAxel Dörfler }
1020c6f7795SAxel Dörfler
103