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örflerstatus_t
160c6f7795SAxel Dörflervga_set_indexed_colors(uint8 first, uint8 *colors, uint16 count)
170c6f7795SAxel Dörfler{
18bb693d77SAxel Dörfler	if (first + count > 256)
19bb693d77SAxel Dörfler		count = 256 - first;
20bb693d77SAxel Dörfler
210c6f7795SAxel Dörfler	gISA->write_io_8(VGA_COLOR_WRITE_MODE, first);
220c6f7795SAxel Dörfler
230c6f7795SAxel Dörfler	// write VGA palette
240c6f7795SAxel Dörfler	for (int32 i = first; i < count; i++) {
250c6f7795SAxel Dörfler		uint8 color[3];
260c6f7795SAxel Dörfler		if (user_memcpy(color, &colors[i * 3], 3) < B_OK)
270c6f7795SAxel Dörfler			return B_BAD_ADDRESS;
280c6f7795SAxel Dörfler
290c6f7795SAxel Dörfler		// VGA (usually) has only 6 bits per gun
300c6f7795SAxel Dörfler		gISA->write_io_8(VGA_COLOR_DATA, color[0] >> 2);
310c6f7795SAxel Dörfler		gISA->write_io_8(VGA_COLOR_DATA, color[1] >> 2);
320c6f7795SAxel Dörfler		gISA->write_io_8(VGA_COLOR_DATA, color[2] >> 2);
330c6f7795SAxel Dörfler	}
340c6f7795SAxel Dörfler	return B_OK;
350c6f7795SAxel Dörfler}
360c6f7795SAxel Dörfler
370c6f7795SAxel Dörfler
380c6f7795SAxel Dörflerstatus_t
390c6f7795SAxel Dörflervga_planar_blit(vesa_shared_info *info, uint8 *src, int32 srcBPR,
400c6f7795SAxel Dörfler	int32 left, int32 top, int32 right, int32 bottom)
410c6f7795SAxel Dörfler{
42122efe3aSAlexander von Gluck IV	// If we don't actually have a frame_buffer, bail.
43122efe3aSAlexander von Gluck IV	if (info->frame_buffer == NULL)
44122efe3aSAlexander von Gluck IV		return B_BAD_ADDRESS;
45122efe3aSAlexander von Gluck IV
460c6f7795SAxel Dörfler	int32 dstBPR = info->bytes_per_row;
470c6f7795SAxel Dörfler	uint8 *dst = info->frame_buffer + top * dstBPR + left / 8;
480c6f7795SAxel Dörfler
490c6f7795SAxel Dörfler	// TODO: this is awfully slow...
500c6f7795SAxel Dörfler	// TODO: assumes BGR order
510c6f7795SAxel Dörfler	for (int32 y = top; y <= bottom; y++) {
520c6f7795SAxel Dörfler		for (int32 plane = 0; plane < 4; plane++) {
530c6f7795SAxel Dörfler			// select the plane we intend to write to and read from
540c6f7795SAxel Dörfler			gISA->write_io_16(VGA_SEQUENCER_INDEX, (1 << (plane + 8)) | 0x02);
550c6f7795SAxel Dörfler			gISA->write_io_16(VGA_GRAPHICS_INDEX, (plane << 8) | 0x04);
560c6f7795SAxel Dörfler
570c6f7795SAxel Dörfler			uint8* srcHandle = src;
580c6f7795SAxel Dörfler			uint8* dstHandle = dst;
590c6f7795SAxel Dörfler			uint8 current8 = dstHandle[0];
600c6f7795SAxel Dörfler				// we store 8 pixels before writing them back
610c6f7795SAxel Dörfler
620c6f7795SAxel Dörfler			int32 x = left;
630c6f7795SAxel Dörfler			for (; x <= right; x++) {
640c6f7795SAxel Dörfler				uint8 rgba[4];
650c6f7795SAxel Dörfler				if (user_memcpy(rgba, srcHandle, 4) < B_OK)
660c6f7795SAxel Dörfler					return B_BAD_ADDRESS;
670c6f7795SAxel Dörfler				uint8 pixel = (308 * rgba[2] + 600 * rgba[1]
680c6f7795SAxel Dörfler					+ 116 * rgba[0]) / 16384;
690c6f7795SAxel Dörfler				srcHandle += 4;
700c6f7795SAxel Dörfler
710c6f7795SAxel Dörfler				if (pixel & (1 << plane))
720c6f7795SAxel Dörfler					current8 |= 0x80 >> (x & 7);
730c6f7795SAxel Dörfler				else
740c6f7795SAxel Dörfler					current8 &= ~(0x80 >> (x & 7));
750c6f7795SAxel Dörfler
760c6f7795SAxel Dörfler				if ((x & 7) == 7) {
770c6f7795SAxel Dörfler					// last pixel in 8 pixel group
780c6f7795SAxel Dörfler					dstHandle[0] = current8;
790c6f7795SAxel Dörfler					dstHandle++;
800c6f7795SAxel Dörfler					current8 = dstHandle[0];
810c6f7795SAxel Dörfler				}
820c6f7795SAxel Dörfler			}
830c6f7795SAxel Dörfler
840c6f7795SAxel Dörfler			if (x & 7) {
850c6f7795SAxel Dörfler				// last pixel has not been written yet
860c6f7795SAxel Dörfler				dstHandle[0] = current8;
870c6f7795SAxel Dörfler			}
880c6f7795SAxel Dörfler		}
890c6f7795SAxel Dörfler		dst += dstBPR;
900c6f7795SAxel Dörfler		src += srcBPR;
910c6f7795SAxel Dörfler	}
920c6f7795SAxel Dörfler	return B_OK;
930c6f7795SAxel Dörfler}
940c6f7795SAxel Dörfler
95