/*STG1702 true colour RAMDAC emulation*/
#include "ibm.h"
#include "mem.h"
#include "video.h"
#include "vid_svga.h"
#include "vid_stg_ramdac.h"

static int stg_state_read[2][8] = {{1, 2, 3, 4, 0, 0, 0, 0}, {1, 2, 3, 4, 5, 6, 7, 7}};
static int stg_state_write[8] = {0, 0, 0, 0, 0, 6, 7, 7};

void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga) {
	int didwrite;
	//if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc);
	switch (addr) {
	case 0x3c6:
		switch (ramdac->magic_count) {
		case 0:
		case 1:
		case 2:
		case 3:break;
		case 4:ramdac->command = val;
			/*pclog("Write RAMDAC command %02X\n",val);*/
			break;
		case 5:ramdac->index = (ramdac->index & 0xff00) | val;
			break;
		case 6:ramdac->index = (ramdac->index & 0xff) | (val << 8);
			break;
		case 7:pclog("Write RAMDAC reg %02X %02X\n", ramdac->index, val);
			if (ramdac->index < 0x100)
				ramdac->regs[ramdac->index] = val;
			ramdac->index++;
			break;
		}
		didwrite = (ramdac->magic_count >= 4);
		ramdac->magic_count = stg_state_write[ramdac->magic_count & 7];
		if (ramdac->command & 8) {
			switch (ramdac->regs[3]) {
			case 0:
			case 5:
			case 7:svga->bpp = 8;
				break;
			case 1:
			case 2:
			case 8:svga->bpp = 15;
				break;
			case 3:
			case 6:svga->bpp = 16;
				break;
			case 4:
			case 9:svga->bpp = 24;
				break;
			default:svga->bpp = 8;
				break;
			}
		} else {
			switch (ramdac->command >> 5) {
			case 0:svga->bpp = 8;
				break;
			case 5:svga->bpp = 15;
				break;
			case 6:svga->bpp = 16;
				break;
			case 7:svga->bpp = 24;
				break;
			default:svga->bpp = 8;
				break;
			}
		}
		svga_recalctimings(svga);
		if (didwrite)
			return;
		break;
	case 0x3c7:
	case 0x3c8:
	case 0x3c9:ramdac->magic_count = 0;
		break;
	}
	svga_out(addr, val, svga);
}

uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga) {
	uint8_t temp = 0xff;
	//if (CS!=0xC000) pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc);
	switch (addr) {
	case 0x3c6:
		switch (ramdac->magic_count) {
		case 0:
		case 1:
		case 2:
		case 3:temp = 0xff;
			break;
		case 4:temp = ramdac->command;
			break;
		case 5:temp = ramdac->index & 0xff;
			break;
		case 6:temp = ramdac->index >> 8;
			break;
		case 7:
//                                pclog("Read RAMDAC index %04X\n",stg_ramdac.index);
			switch (ramdac->index) {
			case 0:temp = 0x44;
				break;
			case 1:temp = 0x02;
				break;
			default:
				if (ramdac->index < 0x100)
					temp = ramdac->regs[ramdac->index];
				else
					temp = 0xff;
				break;
			}
			ramdac->index++;
			break;
		}
		ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7];
		return temp;
	case 0x3c8:
	case 0x3c9:ramdac->magic_count = 0;
		break;
	}
	return svga_in(addr, svga);
}
