Conflict resolution.

This commit is contained in:
OBattler
2024-01-10 08:59:46 +01:00
716 changed files with 71690 additions and 41327 deletions

View File

@@ -18,20 +18,16 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c
vid_incolor.c vid_colorplus.c vid_genius.c vid_pgc.c vid_im1024.c
vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c vid_8514a.c
vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c
vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c
vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68875_ramdac.c
vid_ati68860_ramdac.c vid_bt48x_ramdac.c
vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c
vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c
vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c
vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c
vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c
vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_nga.c
vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c
vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c)
if(MGA)
target_compile_definitions(vid PRIVATE USE_MGA)
target_sources(vid PRIVATE vid_mga.c)
endif()
if(VGAWONDER)
target_compile_definitions(vid PRIVATE USE_VGAWONDER)
endif()

File diff suppressed because it is too large Load Diff

View File

@@ -35,8 +35,8 @@
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
# define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin"
#endif
#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin"
#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi"
#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin"
#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi"
enum {
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
@@ -57,6 +57,8 @@ typedef struct ati18800_t {
uint8_t regs[256];
int index;
int type;
uint32_t memory;
} ati18800_t;
static video_timings_t timing_ati18800 = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
@@ -76,19 +78,20 @@ ati18800_out(uint16_t addr, uint8_t val, void *priv)
ati18800->index = val;
break;
case 0x1cf:
old = ati18800->regs[ati18800->index];
ati18800->regs[ati18800->index] = val;
switch (ati18800->index) {
case 0xb0:
svga_recalctimings(svga);
if ((old ^ val) & 6)
svga_recalctimings(svga);
break;
case 0xb2:
case 0xbe:
if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/
{
svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000;
svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000;
if (ati18800->regs[0xbe] & 8) { /*Read/write bank mode*/
svga->read_bank = ((ati18800->regs[0xb2] & 0xe0) >> 5) * 0x10000;
svga->write_bank = ((ati18800->regs[0xb2] & 0x0e) >> 1) * 0x10000;
} else /*Single bank mode*/
svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000;
svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] & 0x0e) >> 1) * 0x10000;
break;
case 0xb3:
ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1);
@@ -172,21 +175,73 @@ static void
ati18800_recalctimings(svga_t *svga)
{
const ati18800_t *ati18800 = (ati18800_t *) svga->priv;
int clock_sel;
if (svga->crtc[0x17] & 4) {
svga->vtotal <<= 1;
svga->dispend <<= 1;
svga->vsyncstart <<= 1;
svga->split <<= 1;
svga->vblankstart <<= 1;
clock_sel = ((svga->miscout >> 2) & 3) | ((ati18800->regs[0xbe] & 0x10) >> 1) | ((ati18800->regs[0xb9] & 2) << 1);
if (ati18800->regs[0xb6] & 0x10) {
svga->hdisp <<= 1;
svga->htotal <<= 1;
svga->rowoffset <<= 1;
svga->gdcreg[5] &= ~0x40;
}
if (!svga->scrblank && ((ati18800->regs[0xb0] & 0x02) || (ati18800->regs[0xb0] & 0x04))) /*Extended 256 colour modes*/
{
svga->render = svga_render_8bpp_highres;
svga->bpp = 8;
svga->rowoffset <<= 1;
svga->ma <<= 1;
if (ati18800->regs[0xb0] & 6) {
svga->gdcreg[5] |= 0x40;
if ((ati18800->regs[0xb6] & 0x18) >= 0x10)
svga->packed_4bpp = 1;
else
svga->packed_4bpp = 0;
} else
svga->packed_4bpp = 0;
if ((ati18800->regs[0xb6] & 0x18) == 8) {
svga->hdisp <<= 1;
svga->htotal <<= 1;
svga->ati_4color = 1;
} else
svga->ati_4color = 0;
if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) {
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen);
switch (svga->gdcreg[5] & 0x60) {
case 0x00:
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_4bpp_lowres;
else
svga->render = svga_render_4bpp_highres;
break;
case 0x20: /*4 colours*/
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_2bpp_lowres;
else
svga->render = svga_render_2bpp_highres;
break;
case 0x40:
case 0x60: /*256+ colours*/
switch (svga->bpp) {
default:
case 8:
svga->map8 = svga->pallook;
if (svga->lowres)
svga->render = svga_render_8bpp_lowres;
else {
svga->render = svga_render_8bpp_highres;
if (!svga->packed_4bpp) {
svga->ma_latch <<= 1;
svga->rowoffset <<= 1;
}
}
break;
}
break;
default:
break;
}
}
}
}
@@ -198,6 +253,8 @@ ati18800_init(const device_t *info)
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati18800);
ati18800->type = info->local;
switch (info->local) {
default:
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
@@ -207,30 +264,27 @@ ati18800_init(const device_t *info)
#endif
case ATI18800_VGA88:
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
ati18800->memory = 256;
break;
case ATI18800_EDGE16:
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
ati18800->memory = 512;
break;
}
if (info->local == ATI18800_EDGE16) {
svga_init(info, &ati18800->svga, ati18800, 1 << 18, /*256kb*/
ati18800_recalctimings,
ati18800_in, ati18800_out,
NULL,
NULL);
} else {
svga_init(info, &ati18800->svga, ati18800, 1 << 19, /*512kb*/
ati18800_recalctimings,
ati18800_in, ati18800_out,
NULL,
NULL);
}
svga_init(info, &ati18800->svga, ati18800, ati18800->memory << 10,
ati18800_recalctimings,
ati18800_in, ati18800_out,
NULL,
NULL);
ati18800->svga.clock_gen = device_add(&ati18810_device);
ati18800->svga.getclock = ics2494_getclock;
io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800);
io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800);
ati18800->svga.miscout = 1;
ati18800->svga.bpp = 8;
ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0);
@@ -300,7 +354,7 @@ const device_t ati18800_wonder_device = {
#endif
const device_t ati18800_vga88_device = {
.name = "ATI-18800-1",
.name = "ATI 18800-1",
.internal_name = "ati18800v",
.flags = DEVICE_ISA,
.local = ATI18800_VGA88,
@@ -314,7 +368,7 @@ const device_t ati18800_vga88_device = {
};
const device_t ati18800_device = {
.name = "ATI-18800-5",
.name = "ATI VGA Edge 16",
.internal_name = "ati18800",
.flags = DEVICE_ISA,
.local = ATI18800_EDGE16,

View File

@@ -400,7 +400,10 @@ ati28800k_in(uint16_t addr, void *priv)
static void
ati28800_recalctimings(svga_t *svga)
{
const ati28800_t *ati28800 = (ati28800_t *) svga->priv;
ati28800_t *ati28800 = (ati28800_t *) svga->priv;
int clock_sel;
clock_sel = ((svga->miscout >> 2) & 3) | ((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1);
if (ati28800->regs[0xa3] & 0x10)
svga->ma_latch |= 0x10000;
@@ -408,66 +411,13 @@ ati28800_recalctimings(svga_t *svga)
if (ati28800->regs[0xb0] & 0x40)
svga->ma_latch |= 0x20000;
switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) {
case 0x00:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 42954000.0;
break;
case 0x01:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 48771000.0;
break;
case 0x02:
ati28800_log("clock 2\n");
break;
case 0x03:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 36000000.0;
break;
case 0x04:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0;
break;
case 0x05:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 56640000.0;
break;
case 0x06:
ati28800_log("clock 2\n");
break;
case 0x07:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
break;
case 0x08:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 30240000.0;
break;
case 0x09:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 32000000.0;
break;
case 0x0A:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 37500000.0;
break;
case 0x0B:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 39000000.0;
break;
case 0x0C:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0;
break;
case 0x0D:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 56644000.0;
break;
case 0x0E:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 75000000.0;
break;
case 0x0F:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 65000000.0;
break;
default:
break;
}
if (ati28800->regs[0xb8] & 0x40)
svga->clock *= 2;
if (ati28800->regs[0xa7] & 0x80)
svga->clock *= 3;
if (ati28800->regs[0xb6] & 0x10) {
if ((ati28800->regs[0xb6] & 0x18) >= 0x10) {
svga->hdisp <<= 1;
svga->htotal <<= 1;
svga->rowoffset <<= 1;
@@ -476,10 +426,24 @@ ati28800_recalctimings(svga_t *svga)
if (ati28800->regs[0xb0] & 0x20) {
svga->gdcreg[5] |= 0x40;
}
if ((ati28800->regs[0xb6] & 0x18) >= 0x10)
svga->packed_4bpp = 1;
else
svga->packed_4bpp = 0;
} else
svga->packed_4bpp = 0;
if (!svga->scrblank && svga->attr_palette_enable) {
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
if ((ati28800->regs[0xb6] & 0x18) == 8) {
svga->hdisp <<= 1;
svga->htotal <<= 1;
svga->ati_4color = 1;
} else
svga->ati_4color = 0;
if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) {
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen);
ati28800_log("SEQREG1 bit 3=%x. gdcreg5 bits 5-6=%02x, 4bit pel=%02x, planar 16color=%02x, apa mode=%02x, attregs10 bit 7=%02x.\n", svga->seqregs[1] & 8, svga->gdcreg[5] & 0x60, ati28800->regs[0xb3] & 0x40, ati28800->regs[0xac] & 0x40, ati28800->regs[0xb6] & 0x18, ati28800->svga.attrregs[0x10] & 0x80);
switch (svga->gdcreg[5] & 0x60) {
case 0x00:
if (svga->seqregs[1] & 8) /*Low res (320)*/
@@ -502,8 +466,10 @@ ati28800_recalctimings(svga_t *svga)
svga->render = svga_render_8bpp_lowres;
else {
svga->render = svga_render_8bpp_highres;
svga->rowoffset <<= 1;
svga->ma_latch <<= 1;
if (!svga->packed_4bpp) {
svga->ma_latch <<= 1;
svga->rowoffset <<= 1;
}
}
break;
case 15:
@@ -516,7 +482,6 @@ ati28800_recalctimings(svga_t *svga)
svga->ma_latch <<= 1;
}
break;
default:
break;
}
@@ -586,6 +551,8 @@ ati28800k_init(const device_t *info)
ati28800k_in, ati28800k_out,
NULL,
NULL);
ati28800->svga.clock_gen = device_add(&ati18810_device);
ati28800->svga.getclock = ics2494_getclock;
io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800);
io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800);
@@ -652,6 +619,8 @@ ati28800_init(const device_t *info)
ati28800_in, ati28800_out,
NULL,
NULL);
ati28800->svga.clock_gen = device_add(&ati18810_device);
ati28800->svga.getclock = ics2494_getclock;
io_sethandler(0x01ce, 2,
ati28800_in, NULL, NULL,

View File

@@ -46,6 +46,7 @@
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/video.h>
#include <86box/vid_8514a.h>
#include <86box/vid_svga.h>
#include <86box/vid_svga_render.h>
#include <86box/plat_unused.h>
@@ -65,22 +66,23 @@ typedef struct ati68860_ramdac_t {
} ati68860_ramdac_t;
void
ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga)
{
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
switch (addr) {
case 0:
svga_out(0x3c8, val, svga);
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ec : 0x3c8, val, svga);
break;
case 1:
svga_out(0x3c9, val, svga);
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ed : 0x3c9, val, svga);
break;
case 2:
svga_out(0x3c6, val, svga);
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ea : 0x3c6, val, svga);
break;
case 3:
svga_out(0x3c7, val, svga);
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2eb : 0x3c7, val, svga);
break;
default:
ramdac->regs[addr & 0xf] = val;
@@ -168,23 +170,24 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
}
uint8_t
ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga)
ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga)
{
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
uint8_t temp = 0;
const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t temp = 0;
switch (addr) {
case 0:
temp = svga_in(0x3c8, svga);
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ec : 0x3c8, svga);
break;
case 1:
temp = svga_in(0x3c9, svga);
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ed : 0x3c9, svga);
break;
case 2:
temp = svga_in(0x3c6, svga);
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ea : 0x3c6, svga);
break;
case 3:
temp = svga_in(0x3c7, svga);
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2eb : 0x3c7, svga);
break;
case 4:
case 8:
@@ -207,9 +210,9 @@ ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga)
}
void
ati68860_set_ramdac_type(void *p, int type)
ati68860_set_ramdac_type(void *priv, int type)
{
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
if (ramdac->ramdac_type != type) {
ramdac->ramdac_type = type;
@@ -237,17 +240,17 @@ ati68860_ramdac_init(UNUSED(const device_t *info))
}
void
ati68860_ramdac_set_render(void *p, svga_t *svga)
ati68860_ramdac_set_render(void *priv, svga_t *svga)
{
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
svga->render = ramdac->render;
}
void
ati68860_ramdac_set_pallook(void *p, int i, uint32_t col)
ati68860_ramdac_set_pallook(void *priv, int i, uint32_t col)
{
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
ramdac->pallook[i] = col;
}
@@ -255,11 +258,11 @@ ati68860_ramdac_set_pallook(void *p, int i, uint32_t col)
void
ati68860_hwcursor_draw(svga_t *svga, int displine)
{
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac;
int offset;
uint8_t dat;
uint32_t col0 = ramdac->pallook[0];
uint32_t col1 = ramdac->pallook[1];
const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac;
int offset;
uint8_t dat;
uint32_t col0 = ramdac->pallook[0];
uint32_t col1 = ramdac->pallook[1];
offset = svga->dac_hwcursor_latch.xoff;
for (uint32_t x = 0; x < 64 - svga->dac_hwcursor_latch.xoff; x += 4) {

View File

@@ -0,0 +1,167 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the Mach32-compatible ATI 68875 RAMDAC and clones.
*
*
*
* Authors: TheCollector1995.
*
* Copyright 2022-2023 TheCollector1995.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_svga_render.h>
#include <86box/plat_unused.h>
typedef struct ati68875_ramdac_t {
uint8_t gen_cntl;
uint8_t in_clk_sel;
uint8_t out_clk_sel;
uint8_t mux_cntl;
uint8_t palette_page_sel;
uint8_t test_reg;
} ati68875_ramdac_t;
void
ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga)
{
ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) priv;
uint8_t rs = (addr & 0x03);
rs |= (!!rs2 << 2);
rs |= (!!rs3 << 3);
switch (rs) {
case 0x00: /* Palette Write Index Register (RS value = 0000) */
case 0x01: /* Palette Data Register (RS value = 0001) */
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
case 0x03:
svga_out(addr, val, svga);
break;
case 0x08: /* General Control Register (RS value = 1000) */
ramdac->gen_cntl = val;
break;
case 0x09: /* Input Clock Selection Register (RS value = 1001) */
ramdac->in_clk_sel = val;
break;
case 0x0a: /* Output Clock Selection Register (RS value = 1010) */
ramdac->out_clk_sel = val;
break;
case 0x0b: /* MUX Control Register (RS value = 1011) */
ramdac->mux_cntl = val;
break;
case 0x0c: /* Palette Page Register (RS value = 1100) */
ramdac->palette_page_sel = val;
break;
case 0x0e: /* Test Register (RS value = 1110) */
ramdac->test_reg = val;
break;
case 0x0f: /* Reset State (RS value = 1111) */
ramdac->mux_cntl = 0x2d;
break;
default:
break;
}
return;
}
uint8_t
ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga)
{
const ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) priv;
uint8_t rs = (addr & 0x03);
uint8_t temp = 0;
rs |= (!!rs2 << 2);
rs |= (!!rs3 << 3);
switch (rs) {
case 0x00: /* Palette Write Index Register (RS value = 0000) */
case 0x01: /* Palette Data Register (RS value = 0001) */
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
case 0x03:
temp = svga_in(addr, svga);
break;
case 0x08: /* General Control Register (RS value = 1000) */
temp = ramdac->gen_cntl;
break;
case 0x09: /* Input Clock Selection Register (RS value = 1001) */
temp = ramdac->in_clk_sel;
break;
case 0x0a: /* Output Clock Selection Register (RS value = 1010) */
temp = ramdac->out_clk_sel;
break;
case 0x0b: /* MUX Control Register (RS value = 1011) */
temp = ramdac->mux_cntl;
break;
case 0x0c: /* Palette Page Register (RS value = 1100) */
temp = ramdac->palette_page_sel;
break;
case 0x0e: /* Test Register (RS value = 1110) */
switch (ramdac->test_reg & 0x07) {
case 0x03:
temp = 0x75;
break;
default:
break;
}
break;
default:
break;
}
return temp;
}
static void *
ati68875_ramdac_init(UNUSED(const device_t *info))
{
ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) malloc(sizeof(ati68875_ramdac_t));
memset(ramdac, 0, sizeof(ati68875_ramdac_t));
ramdac->mux_cntl = 0x2d;
return ramdac;
}
static void
ati68875_ramdac_close(void *priv)
{
ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) priv;
if (ramdac)
free(ramdac);
}
const device_t ati68875_ramdac_device = {
.name = "ATI 68875 RAMDAC",
.internal_name = "ati68875_ramdac",
.flags = 0,
.local = 0,
.init = ati68875_ramdac_init,
.close = ati68875_ramdac_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -94,9 +94,7 @@ ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat)
if (!dat)
break;
eeprom->state = EEPROM_OPCODE;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case EEPROM_OPCODE:
eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0);
eeprom->count--;

View File

@@ -94,9 +94,11 @@ typedef struct mach64_t {
int type;
int pci;
uint8_t pci_slot;
uint8_t irq_state;
uint8_t pci_regs[256];
uint8_t int_line;
int card;
int bank_r[2];
int bank_w[2];
@@ -227,6 +229,7 @@ typedef struct mach64_t {
int dst_size;
int src_size;
int host_size;
int temp_cnt;
uint32_t dp_bkgd_clr;
uint32_t dp_frgd_clr;
@@ -418,7 +421,7 @@ mach64_out(uint16_t addr, uint8_t val, void *priv)
case 0x3C8:
case 0x3C9:
if (mach64->type == MACH64_GX)
ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, svga);
ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga);
else
svga_out(addr, val, svga);
return;
@@ -437,12 +440,12 @@ mach64_out(uint16_t addr, uint8_t val, void *priv)
svga->crtcreg = val & 0x3f;
return;
case 0x3D5:
if (svga->crtcreg > 0x20)
return;
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
if (svga->crtcreg > 0x18)
return;
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
@@ -452,7 +455,7 @@ mach64_out(uint16_t addr, uint8_t val, void *priv)
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga->fullchange = svga->monitor->mon_changeframecount;
svga_recalctimings(svga);
}
}
@@ -485,13 +488,13 @@ mach64_in(uint16_t addr, void *priv)
case 0x3C8:
case 0x3C9:
if (mach64->type == MACH64_GX)
return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, svga);
return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), svga->ramdac, svga);
return svga_in(addr, svga);
case 0x3D4:
return svga->crtcreg;
case 0x3D5:
if (svga->crtcreg > 0x18)
if (svga->crtcreg > 0x20)
return 0xff;
return svga->crtc[svga->crtcreg];
@@ -647,11 +650,12 @@ mach64_update_irqs(mach64_t *mach64)
}
if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024))
pci_set_irq(mach64->card, PCI_INTA);
pci_set_irq(mach64->pci_slot, PCI_INTA, &mach64->irq_state);
else
pci_clear_irq(mach64->card, PCI_INTA);
pci_clear_irq(mach64->pci_slot, PCI_INTA, &mach64->irq_state);
}
#if 0
static __inline void
wake_fifo_thread(mach64_t *mach64)
{
@@ -666,6 +670,7 @@ mach64_wait_fifo_idle(mach64_t *mach64)
thread_wait_event(mach64->fifo_not_full_event, 1);
}
}
#endif
#define READ8(addr, var) \
switch ((addr) &3) { \
@@ -738,9 +743,7 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val)
case 0x11e:
case 0x11f:
WRITE8(addr, mach64->dst_height_width, val);
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x113:
if (((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || (addr & 0x3ff) == 0x113) && !(val & 0x80)) {
mach64_start_fill(mach64);
@@ -963,9 +966,7 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val)
case 0x2a4:
case 0x2a5:
addr += 2;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x2aa:
case 0x2ab:
WRITE8(addr, mach64->sc_left_right, val);
@@ -980,9 +981,7 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val)
case 0x2b0:
case 0x2b1:
addr += 2;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x2b6:
case 0x2b7:
WRITE8(addr, mach64->sc_top_bottom, val);
@@ -1171,6 +1170,7 @@ mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t val)
}
}
#if 0
static void
fifo_thread(void *param)
{
@@ -1196,6 +1196,9 @@ fifo_thread(void *param)
case FIFO_WRITE_DWORD:
mach64_accel_write_fifo_l(mach64, fifo->addr_type & FIFO_ADDR, fifo->val);
break;
default:
break;
}
mach64->fifo_read_idx++;
@@ -1231,6 +1234,7 @@ mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t type)
if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8)
wake_fifo_thread(mach64);
}
#endif
void
mach64_start_fill(mach64_t *mach64)
@@ -1323,10 +1327,12 @@ mach64_start_fill(mach64_t *mach64)
mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST);
for (uint8_t y = 0; y < 8; y++) {
for (uint8_t x = 0; x < 8; x++) {
uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0;
mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1;
if (mach64->pat_cntl & 1) {
for (uint8_t y = 0; y < 8; y++) {
for (uint8_t x = 0; x < 8; x++) {
uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0;
mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) << 3))) & 1;
}
}
}
@@ -1339,7 +1345,9 @@ mach64_start_fill(mach64_t *mach64)
mach64->accel.pattern_clr4x2[1][1] = ((mach64->pat_reg1 >> 8) & 0xff);
mach64->accel.pattern_clr4x2[1][2] = ((mach64->pat_reg1 >> 16) & 0xff);
mach64->accel.pattern_clr4x2[1][3] = ((mach64->pat_reg1 >> 24) & 0xff);
} else if (mach64->pat_cntl & 4) {
}
if (mach64->pat_cntl & 4) {
mach64->accel.pattern_clr8x1[0] = (mach64->pat_reg0 & 0xff);
mach64->accel.pattern_clr8x1[1] = ((mach64->pat_reg0 >> 8) & 0xff);
mach64->accel.pattern_clr8x1[2] = ((mach64->pat_reg0 >> 16) & 0xff);
@@ -1422,10 +1430,12 @@ mach64_start_line(mach64_t *mach64)
mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST);
for (uint8_t y = 0; y < 8; y++) {
for (uint8_t x = 0; x < 8; x++) {
uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0;
mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1;
if (mach64->pat_cntl & 1) {
for (uint8_t y = 0; y < 8; y++) {
for (uint8_t x = 0; x < 8; x++) {
uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0;
mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) << 3))) & 1;
}
}
}
@@ -1525,13 +1535,13 @@ mach64_start_line(mach64_t *mach64)
#define WRITE(addr, width) \
if (width == 0) { \
svga->vram[(addr) &mach64->vram_mask] = dest_dat; \
svga->changedvram[((addr) &mach64->vram_mask) >> 12] = changeframecount; \
svga->changedvram[((addr) &mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \
} else if (width == 1) { \
*(uint16_t *) &svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \
svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \
svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \
} else if (width == 2) { \
*(uint32_t *) &svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \
svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \
svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \
} else { \
if (dest_dat & 1) { \
if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \
@@ -1544,7 +1554,7 @@ mach64_start_line(mach64_t *mach64)
else \
svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << (7 - ((addr) &7))); \
} \
svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = changeframecount; \
svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \
}
void
@@ -1552,6 +1562,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
{
svga_t *svga = &mach64->svga;
int cmp_clr = 0;
int mix = 0;
if (!mach64->accel.busy) {
mach64_log("mach64_blit : return as not busy\n");
@@ -1562,11 +1573,10 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
case OP_RECT:
while (count) {
uint8_t write_mask = 0;
uint32_t src_dat = 0;
uint32_t src_dat = 0;
uint32_t dest_dat;
uint32_t host_dat = 0;
uint32_t old_dest_dat;
int mix = 0;
int dst_x;
int dst_y;
int src_x;
@@ -1614,7 +1624,11 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
}
break;
case MONO_SRC_PAT:
mix = mach64->accel.pattern[dst_y & 7][dst_x & 7];
if (mach64->dst_cntl & DST_24_ROT_EN) {
if (!mach64->accel.xx_count)
mix = mach64->accel.pattern[dst_y & 7][dst_x & 7];
} else
mix = mach64->accel.pattern[dst_y & 7][dst_x & 7];
break;
case MONO_SRC_1:
mix = 1;
@@ -1640,18 +1654,18 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size);
break;
case SRC_FG:
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) {
if (mach64->dst_cntl & DST_24_ROT_EN) {
if (mach64->accel.xinc == -1) {
if ((mach64->accel.xx_count % 3) == 2)
if (mach64->accel.xx_count == 2)
src_dat = mach64->accel.dp_frgd_clr & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
else if (mach64->accel.xx_count == 1)
src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff;
else
src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff;
} else {
if ((mach64->accel.xx_count % 3) == 2)
if (mach64->accel.xx_count == 2)
src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
else if (mach64->accel.xx_count == 1)
src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff;
else
src_dat = mach64->accel.dp_frgd_clr & 0xff;
@@ -1660,18 +1674,18 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
src_dat = mach64->accel.dp_frgd_clr;
break;
case SRC_BG:
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) {
if (mach64->dst_cntl & DST_24_ROT_EN) {
if (mach64->accel.xinc == -1) {
if ((mach64->accel.xx_count % 3) == 2)
if (mach64->accel.xx_count == 2)
src_dat = mach64->accel.dp_bkgd_clr & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
else if (mach64->accel.xx_count == 1)
src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff;
else
src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff;
} else {
if ((mach64->accel.xx_count % 3) == 2)
if (mach64->accel.xx_count == 2)
src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
else if (mach64->accel.xx_count == 1)
src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff;
else
src_dat = mach64->accel.dp_bkgd_clr & 0xff;
@@ -1687,6 +1701,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
src_dat = mach64->accel.pattern_clr8x1[dst_x & 7];
break;
}
default:
src_dat = 0;
break;
@@ -1720,27 +1735,25 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
if (!cmp_clr) {
old_dest_dat = dest_dat;
MIX
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) {
if (mach64->dst_cntl & DST_24_ROT_EN) {
if (mach64->accel.xinc == -1) {
if ((mach64->accel.xx_count % 3) == 2)
if (mach64->accel.xx_count == 2)
write_mask = mach64->accel.write_mask & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
else if (mach64->accel.xx_count == 1)
write_mask = (mach64->accel.write_mask >> 8) & 0xff;
else
write_mask = (mach64->accel.write_mask >> 16) & 0xff;
} else {
if ((mach64->accel.xx_count % 3) == 2)
if (mach64->accel.xx_count == 2)
write_mask = (mach64->accel.write_mask >> 16) & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
else if (mach64->accel.xx_count == 1)
write_mask = (mach64->accel.write_mask >> 8) & 0xff;
else
write_mask = mach64->accel.write_mask & 0xff;
}
dest_dat = (dest_dat & write_mask) | (old_dest_dat & ~write_mask);
} else {
} else
dest_dat = (dest_dat & mach64->accel.write_mask) | (old_dest_dat & ~mach64->accel.write_mask);
}
}
WRITE(mach64->accel.dst_offset + ((dst_y) * mach64->accel.dst_pitch) + (dst_x), mach64->accel.dst_size);
@@ -1763,11 +1776,11 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
}
}
mach64->accel.xx_count++;
mach64->accel.x_count--;
mach64->accel.xx_count = (mach64->accel.xx_count + 1) % 3;
if (mach64->accel.x_count <= 0) {
mach64->accel.xx_count = 0;
mach64->accel.x_count = mach64->accel.dst_width;
mach64->accel.xx_count = 0;
mach64->accel.dst_x = 0;
mach64->accel.dst_y += mach64->accel.yinc;
mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff;
@@ -1790,9 +1803,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
}
mach64->accel.poly_draw = 0;
mach64->accel.dst_height--;
if (mach64->accel.dst_height <= 0) {
/*Blit finished*/
mach64_log("mach64 blit finished\n");
@@ -2517,32 +2528,32 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x101:
case 0x102:
case 0x103:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dst_off_pitch);
break;
case 0x104:
case 0x105:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dst_y_x);
break;
case 0x108:
case 0x109:
case 0x11c:
case 0x11d:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr + 2, mach64->dst_y_x);
break;
case 0x10c:
case 0x10d:
case 0x10e:
case 0x10f:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dst_y_x);
break;
case 0x110:
case 0x111:
addr += 2;
/*FALLTHROUGH*/
fallthrough;
case 0x114:
case 0x115:
case 0x118:
@@ -2551,7 +2562,7 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x11b:
case 0x11e:
case 0x11f:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dst_height_width);
break;
@@ -2559,28 +2570,28 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x121:
case 0x122:
case 0x123:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dst_bres_lnth);
break;
case 0x124:
case 0x125:
case 0x126:
case 0x127:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dst_bres_err);
break;
case 0x128:
case 0x129:
case 0x12a:
case 0x12b:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dst_bres_inc);
break;
case 0x12c:
case 0x12d:
case 0x12e:
case 0x12f:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dst_bres_dec);
break;
@@ -2588,7 +2599,7 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x131:
case 0x132:
case 0x133:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dst_cntl);
break;
@@ -2596,75 +2607,75 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x181:
case 0x182:
case 0x183:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->src_off_pitch);
break;
case 0x184:
case 0x185:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->src_y_x);
break;
case 0x188:
case 0x189:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr + 2, mach64->src_y_x);
break;
case 0x18c:
case 0x18d:
case 0x18e:
case 0x18f:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->src_y_x);
break;
case 0x190:
case 0x191:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr + 2, mach64->src_height1_width1);
break;
case 0x194:
case 0x195:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->src_height1_width1);
break;
case 0x198:
case 0x199:
case 0x19a:
case 0x19b:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->src_height1_width1);
break;
case 0x19c:
case 0x19d:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->src_y_x_start);
break;
case 0x1a0:
case 0x1a1:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr + 2, mach64->src_y_x_start);
break;
case 0x1a4:
case 0x1a5:
case 0x1a6:
case 0x1a7:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->src_y_x_start);
break;
case 0x1a8:
case 0x1a9:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr + 2, mach64->src_height2_width2);
break;
case 0x1ac:
case 0x1ad:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->src_height2_width2);
break;
case 0x1b0:
case 0x1b1:
case 0x1b2:
case 0x1b3:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->src_height2_width2);
break;
@@ -2672,7 +2683,7 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x1b5:
case 0x1b6:
case 0x1b7:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->src_cntl);
break;
@@ -2680,7 +2691,7 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x241:
case 0x242:
case 0x243:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->host_cntl);
break;
@@ -2688,14 +2699,14 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x281:
case 0x282:
case 0x283:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->pat_reg0);
break;
case 0x284:
case 0x285:
case 0x286:
case 0x287:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->pat_reg1);
break;
@@ -2703,7 +2714,7 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x289:
case 0x28a:
case 0x28b:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->pat_cntl);
break;
@@ -2711,16 +2722,16 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x2a1:
case 0x2a8:
case 0x2a9:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->sc_left_right);
break;
case 0x2a4:
case 0x2a5:
addr += 2;
/*FALLTHROUGH*/
fallthrough;
case 0x2aa:
case 0x2ab:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->sc_left_right);
break;
@@ -2728,16 +2739,16 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x2ad:
case 0x2b4:
case 0x2b5:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->sc_top_bottom);
break;
case 0x2b0:
case 0x2b1:
addr += 2;
/*FALLTHROUGH*/
fallthrough;
case 0x2b6:
case 0x2b7:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->sc_top_bottom);
break;
@@ -2745,14 +2756,14 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x2c1:
case 0x2c2:
case 0x2c3:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dp_bkgd_clr);
break;
case 0x2c4:
case 0x2c5:
case 0x2c6:
case 0x2c7:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dp_frgd_clr);
break;
@@ -2760,7 +2771,7 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x2c9:
case 0x2ca:
case 0x2cb:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->write_mask);
break;
@@ -2768,7 +2779,7 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x2cd:
case 0x2ce:
case 0x2cf:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->chain_mask);
break;
@@ -2776,21 +2787,21 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x2d1:
case 0x2d2:
case 0x2d3:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dp_pix_width);
break;
case 0x2d4:
case 0x2d5:
case 0x2d6:
case 0x2d7:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dp_mix);
break;
case 0x2d8:
case 0x2d9:
case 0x2da:
case 0x2db:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dp_src);
break;
@@ -2798,64 +2809,53 @@ mach64_ext_readb(uint32_t addr, void *priv)
case 0x301:
case 0x302:
case 0x303:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->clr_cmp_clr);
break;
case 0x304:
case 0x305:
case 0x306:
case 0x307:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->clr_cmp_mask);
break;
case 0x308:
case 0x309:
case 0x30a:
case 0x30b:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->clr_cmp_cntl);
break;
case 0x310:
case 0x311:
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) {
ret = 0;
} else {
if (!FIFO_EMPTY)
wake_fifo_thread(mach64);
ret = 0;
if (FIFO_FULL)
ret = 0xff;
}
ret = 0;
break;
case 0x320:
case 0x321:
case 0x322:
case 0x323:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->context_mask);
break;
case 0x330:
case 0x331:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr, mach64->dst_cntl);
break;
case 0x332:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr - 2, mach64->src_cntl);
break;
case 0x333:
mach64_wait_fifo_idle(mach64);
//mach64_wait_fifo_idle(mach64);
READ8(addr - 3, mach64->pat_cntl);
break;
case 0x338:
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24)
ret = 0;
else
ret = FIFO_EMPTY ? 0 : 1;
ret = 0;
break;
default:
@@ -3039,10 +3039,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
mach64_log("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val);
} else if (addr & 0x300) {
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24)
mach64_accel_write_fifo(mach64, addr & 0x3ff, val);
else
mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE);
mach64_accel_write_fifo(mach64, addr & 0x3ff, val);
} else
switch (addr & 0x3ff) {
case 0x00:
@@ -3051,6 +3048,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
case 0x03:
WRITE8(addr, mach64->crtc_h_total_disp, val);
svga_recalctimings(&mach64->svga);
svga->fullchange = svga->monitor->mon_changeframecount;
break;
case 0x08:
case 0x09:
@@ -3058,6 +3056,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
case 0x0b:
WRITE8(addr, mach64->crtc_v_total_disp, val);
svga_recalctimings(&mach64->svga);
svga->fullchange = svga->monitor->mon_changeframecount;
break;
case 0x0c:
case 0x0d:
@@ -3065,6 +3064,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
case 0x0f:
WRITE8(addr, mach64->crtc_v_sync_strt_wid, val);
svga_recalctimings(&mach64->svga);
svga->fullchange = svga->monitor->mon_changeframecount;
break;
case 0x14:
@@ -3073,7 +3073,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
case 0x17:
WRITE8(addr, mach64->crtc_off_pitch, val);
svga_recalctimings(&mach64->svga);
svga->fullchange = changeframecount;
svga->fullchange = svga->monitor->mon_changeframecount;
break;
case 0x18:
@@ -3094,6 +3094,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
svga->fb_only = 0;
svga->dpms = !!(mach64->crtc_gen_cntl & 0x0c);
svga_recalctimings(&mach64->svga);
svga->fullchange = svga->monitor->mon_changeframecount;
break;
case 0x40:
@@ -3268,10 +3269,7 @@ mach64_ext_writew(uint32_t addr, uint16_t val, void *priv)
mach64_ext_writeb(addr, val, priv);
mach64_ext_writeb(addr + 1, val >> 8, priv);
} else if (addr & 0x300) {
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24)
mach64_accel_write_fifo_w(mach64, addr & 0x3fe, val);
else
mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD);
mach64_accel_write_fifo_w(mach64, addr & 0x3fe, val);
} else
switch (addr & 0x3fe) {
default:
@@ -3292,10 +3290,7 @@ mach64_ext_writel(uint32_t addr, uint32_t val, void *priv)
mach64_ext_writew(addr, val, priv);
mach64_ext_writew(addr + 2, val >> 16, priv);
} else if (addr & 0x300) {
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24)
mach64_accel_write_fifo_l(mach64, addr & 0x3fc, val);
else
mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD);
mach64_accel_write_fifo_l(mach64, addr & 0x3fc, val);
} else
switch (addr & 0x3fc) {
default:
@@ -3708,6 +3703,9 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *priv)
WRITE8(port, mach64->config_cntl, val);
mach64_updatemapping(mach64);
break;
default:
break;
}
}
void
@@ -4379,20 +4377,23 @@ mach64_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
static void *
mach64_common_init(const device_t *info)
{
svga_t *svga;
mach64_t *mach64 = malloc(sizeof(mach64_t));
memset(mach64, 0, sizeof(mach64_t));
svga = &mach64->svga;
mach64->vram_size = device_get_config_int("memory");
mach64->vram_mask = (mach64->vram_size << 20) - 1;
svga_init(info, &mach64->svga, mach64, mach64->vram_size << 20,
svga_init(info, svga, mach64, mach64->vram_size << 20,
mach64_recalctimings,
mach64_in, mach64_out,
NULL,
mach64_overlay_draw);
mach64->svga.dac_hwcursor.cur_ysize = 64;
svga->dac_hwcursor.cur_ysize = 64;
mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &mach64->svga);
mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga);
mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64);
mem_mapping_add(&mach64->mmio_linear_mapping_2, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64);
mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64);
@@ -4401,28 +4402,23 @@ mach64_common_init(const device_t *info)
mach64_io_set(mach64);
if (info->flags & DEVICE_PCI)
mach64->card = pci_add_card(PCI_ADD_VIDEO, mach64_pci_read, mach64_pci_write, mach64);
pci_add_card(PCI_ADD_NORMAL, mach64_pci_read, mach64_pci_write, mach64, &mach64->pci_slot);
mach64->pci_regs[PCI_REG_COMMAND] = 3;
mach64->pci_regs[0x30] = 0x00;
mach64->pci_regs[0x32] = 0x0c;
mach64->pci_regs[0x33] = 0x00;
mach64->svga.ramdac = device_add(&ati68860_ramdac_device);
mach64->svga.dac_hwcursor_draw = ati68860_hwcursor_draw;
svga->ramdac = device_add(&ati68860_ramdac_device);
svga->dac_hwcursor_draw = ati68860_hwcursor_draw;
mach64->svga.clock_gen = device_add(&ics2595_device);
svga->clock_gen = device_add(&ics2595_device);
mach64->dst_cntl = 3;
mach64->i2c = i2c_gpio_init("ddc_ati_mach64");
mach64->ddc = ddc_init(i2c_gpio_get_bus(mach64->i2c));
mach64->wake_fifo_thread = thread_create_event();
mach64->fifo_not_full_event = thread_create_event();
mach64->thread_run = 1;
mach64->fifo_thread = thread_create(fifo_thread, mach64);
return mach64;
}
@@ -4518,12 +4514,6 @@ mach64_close(void *priv)
{
mach64_t *mach64 = (mach64_t *) priv;
mach64->thread_run = 0;
thread_set_event(mach64->wake_fifo_thread);
thread_wait(mach64->fifo_thread);
thread_destroy_event(mach64->fifo_not_full_event);
thread_destroy_event(mach64->wake_fifo_thread);
svga_close(&mach64->svga);
ddc_close(mach64->ddc);
@@ -4545,7 +4535,7 @@ mach64_force_redraw(void *priv)
{
mach64_t *mach64 = (mach64_t *) priv;
mach64->svga.fullchange = changeframecount;
mach64->svga.fullchange = mach64->svga.monitor->mon_changeframecount;
}
// clang-format off

File diff suppressed because it is too large Load Diff

View File

@@ -10,10 +10,8 @@
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
@@ -28,8 +26,7 @@
#include <86box/video.h>
#include <86box/vid_svga.h>
typedef struct
{
typedef struct att49x_ramdac_t {
int type;
int state;
uint8_t ctrl;
@@ -42,9 +39,9 @@ enum {
};
static void
att49x_ramdac_control(uint8_t val, void *p, svga_t *svga)
att49x_ramdac_control(uint8_t val, void *priv, svga_t *svga)
{
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p;
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv;
ramdac->ctrl = val;
switch ((ramdac->ctrl >> 5) & 7) {
case 0:
@@ -73,9 +70,9 @@ att49x_ramdac_control(uint8_t val, void *p, svga_t *svga)
}
void
att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga)
{
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p;
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv;
uint8_t rs = (addr & 0x03);
rs |= ((!!rs2) << 2);
@@ -110,9 +107,9 @@ att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
}
uint8_t
att49x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
att49x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga)
{
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p;
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv;
uint8_t temp = 0xff;
uint8_t rs = (addr & 0x03);
rs |= ((!!rs2) << 2);

View File

@@ -10,10 +10,8 @@
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
@@ -28,8 +26,7 @@
#include <86box/video.h>
#include <86box/vid_svga.h>
typedef struct
{
typedef struct att498_ramdac_t {
int type;
int state;
int loop;
@@ -37,9 +34,9 @@ typedef struct
} att498_ramdac_t;
static void
att498_ramdac_control(uint8_t val, void *p, svga_t *svga)
att498_ramdac_control(uint8_t val, void *priv, svga_t *svga)
{
att498_ramdac_t *ramdac = (att498_ramdac_t *) p;
att498_ramdac_t *ramdac = (att498_ramdac_t *) priv;
ramdac->ctrl = val;
if (val == 0xff)
@@ -73,9 +70,9 @@ att498_ramdac_control(uint8_t val, void *p, svga_t *svga)
}
void
att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga)
{
att498_ramdac_t *ramdac = (att498_ramdac_t *) p;
att498_ramdac_t *ramdac = (att498_ramdac_t *) priv;
uint8_t rs = (addr & 0x03);
rs |= ((!!rs2) << 2);
@@ -109,9 +106,9 @@ att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
}
uint8_t
att498_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
att498_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga)
{
att498_ramdac_t *ramdac = (att498_ramdac_t *) p;
att498_ramdac_t *ramdac = (att498_ramdac_t *) priv;
uint8_t temp = 0xff;
uint8_t rs = (addr & 0x03);
rs |= ((!!rs2) << 2);

View File

@@ -29,13 +29,13 @@
#include <86box/video.h>
#include <86box/vid_svga.h>
typedef struct
{
typedef struct bt48x_ramdac_t {
PALETTE extpal;
uint32_t extpallook[256];
uint8_t cursor32_data[256];
uint8_t cursor64_data[1024];
int hwc_y, hwc_x;
int hwc_y;
int hwc_x;
uint8_t cmd_r0;
uint8_t cmd_r1;
uint8_t cmd_r2;
@@ -85,9 +85,9 @@ bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga)
}
void
bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga)
bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga)
{
bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p;
bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv;
uint32_t o32;
uint8_t *cd;
uint16_t index;
@@ -233,11 +233,11 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *
}
uint8_t
bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga)
{
bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p;
bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv;
uint8_t temp = 0xff;
uint8_t *cd;
const uint8_t *cd;
uint16_t index;
uint8_t rs = (addr & 0x03);
uint16_t da_mask = 0x03ff;
@@ -360,9 +360,9 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
}
void
bt48x_recalctimings(void *p, svga_t *svga)
bt48x_recalctimings(void *priv, svga_t *svga)
{
bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p;
const bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv;
svga->interlace = ramdac->cmd_r2 & 0x08;
if (ramdac->cmd_r3 & 0x08)
@@ -386,7 +386,7 @@ bt48x_hwcursor_draw(svga_t *svga, int displine)
uint32_t clr2;
uint32_t clr3;
uint32_t *p;
uint8_t *cd;
const uint8_t *cd;
bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) svga->ramdac;
clr1 = ramdac->extpallook[1];

View File

@@ -12,9 +12,11 @@
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* W. M. Martinez, <anikom15@outlook.com>
*
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
* Copyright 2023 W. M. Martinez
*/
#include <stdio.h>
#include <stdint.h>
@@ -41,11 +43,29 @@
#define COMPOSITE_OLD 0
#define COMPOSITE_NEW 1
#define DOUBLE_NONE 0
#define DOUBLE_SIMPLE 1
#define DOUBLE_INTERPOLATE_SRGB 2
#define DOUBLE_INTERPOLATE_LINEAR 3
typedef union
{
uint32_t color;
struct {
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
};
} color_t;
static uint8_t crtcmask[32] = {
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static uint8_t interp_lut[2][256][256];
static video_timings_t timing_cga = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
void cga_recalctimings(cga_t *cga);
@@ -199,24 +219,275 @@ cga_recalctimings(cga_t *cga)
cga->dispofftime = (uint64_t) (_dispofftime);
}
void
cga_poll(void *priv)
static void
cga_render(cga_t *cga, int line)
{
cga_t *cga = (cga_t *) priv;
uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff;
int drawcursor;
int x;
int c;
int xs_temp;
int ys_temp;
int oldvc;
uint8_t chr;
uint8_t attr;
uint8_t border;
uint16_t dat;
int cols[4];
int col;
if ((cga->cgamode & 0x12) == 0x12) {
for (c = 0; c < 8; ++c) {
buffer32->line[line][c] = 0;
if (cga->cgamode & 1)
buffer32->line[line][c + (cga->crtc[1] << 3) + 8] = 0;
else
buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = 0;
}
} else {
for (c = 0; c < 8; ++c) {
buffer32->line[line][c] = (cga->cgacol & 15) + 16;
if (cga->cgamode & 1)
buffer32->line[line][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16;
else
buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16;
}
}
if (cga->cgamode & 1) {
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8) {
chr = cga->charbuffer[x << 1];
attr = cga->charbuffer[(x << 1) + 1];
} else
chr = attr = 0;
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
cols[1] = (attr & 15) + 16;
if (cga->cgamode & 0x20) {
cols[0] = ((attr >> 4) & 7) + 16;
if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor)
cols[1] = cols[0];
} else
cols[0] = (attr >> 4) + 16;
if (drawcursor) {
for (c = 0; c < 8; c++) {
buffer32->line[line][(x << 3) + c + 8]
= cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
}
} else {
for (c = 0; c < 8; c++) {
buffer32->line[line][(x << 3) + c + 8]
= cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
}
cga->ma++;
}
} else if (!(cga->cgamode & 2)) {
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8) {
chr = cga->vram[(cga->ma << 1) & 0x3fff];
attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff];
} else
chr = attr = 0;
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
cols[1] = (attr & 15) + 16;
if (cga->cgamode & 0x20) {
cols[0] = ((attr >> 4) & 7) + 16;
if ((cga->cgablink & 8) && (attr & 0x80))
cols[1] = cols[0];
} else
cols[0] = (attr >> 4) + 16;
cga->ma++;
if (drawcursor) {
for (c = 0; c < 8; c++) {
buffer32->line[line][(x << 4) + (c << 1) + 8]
= buffer32->line[line][(x << 4) + (c << 1) + 9]
= cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
}
} else {
for (c = 0; c < 8; c++) {
buffer32->line[line][(x << 4) + (c << 1) + 8]
= buffer32->line[line][(x << 4) + (c << 1) + 9]
= cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
}
}
} else if (!(cga->cgamode & 16)) {
cols[0] = (cga->cgacol & 15) | 16;
col = (cga->cgacol & 16) ? 24 : 16;
if (cga->cgamode & 4) {
cols[1] = col | 3; /* Cyan */
cols[2] = col | 4; /* Red */
cols[3] = col | 7; /* White */
} else if (cga->cgacol & 32) {
cols[1] = col | 3; /* Cyan */
cols[2] = col | 5; /* Magenta */
cols[3] = col | 7; /* White */
} else {
cols[1] = col | 2; /* Green */
cols[2] = col | 4; /* Red */
cols[3] = col | 6; /* Yellow */
}
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8)
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) |
cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
else
dat = 0;
cga->ma++;
for (c = 0; c < 8; c++) {
buffer32->line[line][(x << 4) + (c << 1) + 8]
= buffer32->line[line][(x << 4) + (c << 1) + 9]
= cols[dat >> 14];
dat <<= 2;
}
}
} else {
cols[0] = 0;
cols[1] = (cga->cgacol & 15) + 16;
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8)
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) |
cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
else
dat = 0;
cga->ma++;
for (c = 0; c < 16; c++) {
buffer32->line[line][(x << 4) + c + 8] = cols[dat >> 15];
dat <<= 1;
}
}
}
}
static void
cga_render_blank(cga_t *cga, int line)
{
int col = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16;
if (cga->cgamode & 1)
hline(buffer32, 0, line, (cga->crtc[1] << 3) + 16, col);
else
hline(buffer32, 0, line, (cga->crtc[1] << 4) + 16, col);
}
static void
cga_render_process(cga_t *cga, int line)
{
int x;
uint8_t border;
if (cga->cgamode & 1)
x = (cga->crtc[1] << 3) + 16;
else
x = (cga->crtc[1] << 4) + 16;
if (cga->composite) {
border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15);
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[line]);
} else
video_process_8(x, line);
}
static uint8_t
cga_interpolate_srgb(uint8_t co1, uint8_t co2, double fraction)
{
uint8_t ret = ((co2 - co1) * fraction + co1);
return ret;
}
static uint8_t
cga_interpolate_linear(uint8_t co1, uint8_t co2, double fraction)
{
double c1, c2;
double r1, r2;
uint8_t ret;
c1 = ((double) co1) / 255.0;
c1 = pow((co1 >= 0) ? c1 : -c1, 2.19921875);
if (co1 <= 0)
c1 = -c1;
c2 = ((double) co2) / 255.0;
c2 = pow((co2 >= 0) ? c2 : -c2, 2.19921875);
if (co2 <= 0)
c2 = -c2;
r1 = ((c2 - c1) * fraction + c1);
r2 = pow((r1 >= 0.0) ? r1 : -r1, 1.0 / 2.19921875);
if (r1 <= 0.0)
r2 = -r2;
ret = (uint8_t) (r2 * 255.0);
return ret;
}
static color_t
cga_interpolate_lookup(cga_t *cga, color_t color1, color_t color2, double fraction)
{
color_t ret;
uint8_t dt = cga->double_type - DOUBLE_INTERPOLATE_SRGB;
ret.a = 0x00;
ret.r = interp_lut[dt][color1.r][color2.r];
ret.g = interp_lut[dt][color1.g][color2.g];
ret.b = interp_lut[dt][color1.b][color2.b];
return ret;
}
static void
cga_interpolate(cga_t *cga, int x, int y, int w, int h)
{
double quotient = 0.5;
for (int i = y; i < (y + h); i++) {
if (i & 1) for (int j = x; j < (x + w); j++) {
int prev = i - 1;
int next = i + 1;
color_t prev_color, next_color;
color_t black;
color_t interim_1, interim_2;
color_t final;
if (i < 0)
continue;
black.color = 0x00000000;
if ((prev >= 0) && (prev < (y + h)))
prev_color.color = buffer32->line[prev][j];
else
prev_color.color = 0x00000000;
if ((next >= 0) && (next < (y + h)))
next_color.color = buffer32->line[next][j];
else
next_color.color = 0x00000000;
interim_1 = cga_interpolate_lookup(cga, prev_color, black, quotient);
interim_2 = cga_interpolate_lookup(cga, black, next_color, quotient);
final = cga_interpolate_lookup(cga, interim_1, interim_2, quotient);
buffer32->line[i][j] = final.color;
}
}
}
static void
cga_blit_memtoscreen(cga_t *cga, int x, int y, int w, int h)
{
if (cga->double_type > DOUBLE_SIMPLE)
cga_interpolate(cga, x, y, w, h);
video_blit_memtoscreen(x, y, w, h);
}
void
cga_poll(void *priv)
{
cga_t *cga = (cga_t *) priv;
int x;
int oldsc;
int oldvc;
int xs_temp;
int ys_temp;
int old_ma;
if (!cga->linepos) {
timer_advance_u64(&cga->timer, cga->dispofftime);
@@ -231,141 +502,44 @@ cga_poll(void *priv)
video_wait_for_buffer();
}
cga->lastline = cga->displine;
for (c = 0; c < 8; c++) {
if ((cga->cgamode & 0x12) == 0x12) {
buffer32->line[cga->displine << 1][c] = buffer32->line[(cga->displine << 1) + 1][c] = 0;
if (cga->cgamode & 1) {
buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = 0;
} else {
buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = 0;
}
} else {
buffer32->line[cga->displine << 1][c] = buffer32->line[(cga->displine << 1) + 1][c] = (cga->cgacol & 15) + 16;
if (cga->cgamode & 1) {
buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16;
} else {
buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16;
}
}
}
if (cga->cgamode & 1) {
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8) {
chr = cga->charbuffer[x << 1];
attr = cga->charbuffer[(x << 1) + 1];
} else
chr = attr = 0;
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
cols[1] = (attr & 15) + 16;
if (cga->cgamode & 0x20) {
cols[0] = ((attr >> 4) & 7) + 16;
if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor)
cols[1] = cols[0];
} else
cols[0] = (attr >> 4) + 16;
if (drawcursor) {
for (c = 0; c < 8; c++) {
buffer32->line[cga->displine << 1][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
}
} else {
for (c = 0; c < 8; c++) {
buffer32->line[cga->displine << 1][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
}
cga->ma++;
}
} else if (!(cga->cgamode & 2)) {
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8) {
chr = cga->vram[(cga->ma << 1) & 0x3fff];
attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff];
} else
chr = attr = 0;
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
cols[1] = (attr & 15) + 16;
if (cga->cgamode & 0x20) {
cols[0] = ((attr >> 4) & 7) + 16;
if ((cga->cgablink & 8) && (attr & 0x80))
cols[1] = cols[0];
} else
cols[0] = (attr >> 4) + 16;
cga->ma++;
if (drawcursor) {
for (c = 0; c < 8; c++) {
buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
}
} else {
for (c = 0; c < 8; c++) {
buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
}
}
} else if (!(cga->cgamode & 16)) {
cols[0] = (cga->cgacol & 15) | 16;
col = (cga->cgacol & 16) ? 24 : 16;
if (cga->cgamode & 4) {
cols[1] = col | 3; /* Cyan */
cols[2] = col | 4; /* Red */
cols[3] = col | 7; /* White */
} else if (cga->cgacol & 32) {
cols[1] = col | 3; /* Cyan */
cols[2] = col | 5; /* Magenta */
cols[3] = col | 7; /* White */
} else {
cols[1] = col | 2; /* Green */
cols[2] = col | 4; /* Red */
cols[3] = col | 6; /* Yellow */
}
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8)
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
else
dat = 0;
cga->ma++;
for (c = 0; c < 8; c++) {
buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
dat <<= 2;
}
}
} else {
cols[0] = 0;
cols[1] = (cga->cgacol & 15) + 16;
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8)
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
else
dat = 0;
cga->ma++;
for (c = 0; c < 16; c++) {
buffer32->line[cga->displine << 1][(x << 4) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15];
dat <<= 1;
}
}
switch (cga->double_type) {
default:
cga_render(cga, cga->displine << 1);
cga_render_blank(cga, (cga->displine << 1) + 1);
break;
case DOUBLE_NONE:
cga_render(cga, cga->displine);
break;
case DOUBLE_SIMPLE:
old_ma = cga->ma;
cga_render(cga, cga->displine << 1);
cga->ma = old_ma;
cga_render(cga, (cga->displine << 1) + 1);
break;
}
} else {
cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16;
if (cga->cgamode & 1) {
hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 3) + 16) << 2, cols[0]);
hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 3) + 16) << 2, cols[0]);
} else {
hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 4) + 16) << 2, cols[0]);
hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 4) + 16) << 2, cols[0]);
switch (cga->double_type) {
default:
cga_render_blank(cga, cga->displine << 1);
break;
case DOUBLE_NONE:
cga_render_blank(cga, cga->displine);
break;
case DOUBLE_SIMPLE:
cga_render_blank(cga, cga->displine << 1);
cga_render_blank(cga, (cga->displine << 1) + 1);
break;
}
}
if (cga->cgamode & 1)
x = (cga->crtc[1] << 3) + 16;
else
x = (cga->crtc[1] << 4) + 16;
if (cga->composite) {
border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15);
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[cga->displine << 1]);
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1) + 1]);
} else {
video_process_8(x, cga->displine << 1);
video_process_8(x, (cga->displine << 1) + 1);
switch (cga->double_type) {
default:
cga_render_process(cga, cga->displine << 1);
cga_render_process(cga, (cga->displine << 1) + 1);
break;
case DOUBLE_NONE:
cga_render_process(cga, cga->displine);
break;
}
cga->sc = oldsc;
@@ -382,7 +556,8 @@ cga_poll(void *priv)
if (!cga->vsynctime)
cga->cgastat &= ~8;
}
if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) {
if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 &&
cga->sc == ((cga->crtc[11] & 31) >> 1))) {
cga->con = 0;
cga->coff = 1;
}
@@ -440,31 +615,45 @@ cga_poll(void *priv)
cga->lastline++;
xs_temp = x;
ys_temp = (cga->lastline - cga->firstline) << 1;
ys_temp = cga->lastline - cga->firstline;
if (cga->double_type > DOUBLE_NONE)
ys_temp <<= 1;
if ((xs_temp > 0) && (ys_temp > 0)) {
if (xs_temp < 64)
xs_temp = 656;
if (ys_temp < 32)
ys_temp = 400;
ys_temp = 200;
if (!enable_overscan)
xs_temp -= 16;
if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
if ((cga->cgamode & 8) && ((xs_temp != xsize) ||
(ys_temp != ysize) || video_force_resize_get())) {
xsize = xs_temp;
ysize = ys_temp;
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
if (cga->double_type > DOUBLE_NONE)
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
else
set_screen_size(xsize, ysize + (enable_overscan ? 8 : 0));
if (video_force_resize_get())
video_force_resize_set(0);
}
if (enable_overscan) {
video_blit_memtoscreen(0, (cga->firstline - 4) << 1,
xsize, ((cga->lastline - cga->firstline) + 8) << 1);
if (cga->double_type > DOUBLE_NONE) {
if (enable_overscan)
cga_blit_memtoscreen(cga, 0, (cga->firstline - 4) << 1,
xsize, ((cga->lastline - cga->firstline) << 1) + 16);
else
cga_blit_memtoscreen(cga, 8, cga->firstline << 1,
xsize, (cga->lastline - cga->firstline) << 1);
} else {
video_blit_memtoscreen(8, cga->firstline << 1,
xsize, (cga->lastline - cga->firstline) << 1);
if (enable_overscan)
video_blit_memtoscreen(0, cga->firstline - 4,
xsize, (cga->lastline - cga->firstline) + 8);
else
video_blit_memtoscreen(8, cga->firstline,
xsize, cga->lastline - cga->firstline);
}
}
@@ -498,7 +687,8 @@ cga_poll(void *priv)
}
if (cga->cgadispon)
cga->cgastat &= ~1;
if (cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))
if (cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 &&
cga->sc == ((cga->crtc[10] & 31) >> 1)))
cga->con = 1;
if (cga->cgadispon && (cga->cgamode & 1)) {
for (x = 0; x < (cga->crtc[1] << 1); x++)
@@ -542,6 +732,15 @@ cga_standalone_init(UNUSED(const device_t *info))
cgapal_rebuild();
update_cga16_color(cga->cgamode);
cga->double_type = device_get_config_int("double_type");
for (uint16_t i = 0; i < 256; i++) {
for (uint16_t j = 0; j < 256; j++) {
interp_lut[0][i][j] = cga_interpolate_srgb(i, j, 0.5);
interp_lut[1][i][j] = cga_interpolate_linear(i, j, 0.5);
}
}
return cga;
}
@@ -621,10 +820,10 @@ const device_config_t cga_config[] = {
.name = "rgb_type",
.description = "RGB type",
.type = CONFIG_SELECTION,
.default_int = 0,
.default_int = 5,
.selection = {
{
.description = "Color",
.description = "Color (generic)",
.value = 0
},
{
@@ -643,6 +842,37 @@ const device_config_t cga_config[] = {
.description = "Color (no brown)",
.value = 4
},
{
.description = "Color (IBM 5153)",
.value = 5
},
{
.description = ""
}
}
},
{
.name = "double_type",
.description = "Line doubling type",
.type = CONFIG_SELECTION,
.default_int = DOUBLE_NONE,
.selection = {
{
.description = "None",
.value = DOUBLE_NONE
},
{
.description = "Simple doubling",
.value = DOUBLE_SIMPLE
},
{
.description = "sRGB interpolation",
.value = DOUBLE_INTERPOLATE_SRGB
},
{
.description = "Linear interpolation",
.value = DOUBLE_INTERPOLATE_LINEAR
},
{
.description = ""
}

View File

@@ -44,22 +44,22 @@ static const double tau = 6.28318531; /* == 2*pi */
static unsigned char chroma_multiplexer[256] = {
// clang-format off
2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4,
133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152,
2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5,
140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135,
32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77,
177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192,
4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117,
147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193,
72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1,
248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130,
1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2,
162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112,
78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37,
252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200,
61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107,
198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252
2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4,
133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152,
2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5,
140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135,
32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77,
177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192,
4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117,
147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193,
72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1,
248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130,
1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2,
162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112,
78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37,
252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200,
61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107,
198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252
// clang-format on
};

File diff suppressed because it is too large Load Diff

View File

@@ -135,8 +135,8 @@ colorplus_poll(void *priv)
0x18, 0x1A, 0x1C, 0x1E,
0x11, 0x13, 0x15, 0x17,
0x19, 0x1B, 0x1D, 0x1F };
uint8_t *plane0 = colorplus->cga.vram;
uint8_t *plane1 = colorplus->cga.vram + 0x4000;
const uint8_t *plane0 = colorplus->cga.vram;
const uint8_t *plane1 = colorplus->cga.vram + 0x4000;
/* If one of the extra modes is not selected, drop down to the CGA
* drawing code. */

View File

@@ -121,7 +121,7 @@ compaq_cga_poll(void *priv)
if (self->cga.displine < self->cga.firstline) {
self->cga.firstline = self->cga.displine;
video_wait_for_buffer();
compaq_cga_log("Firstline %i\n", firstline);
compaq_cga_log("Firstline %i\n", self->cga.firstline);
}
self->cga.lastline = self->cga.displine;

View File

@@ -17,6 +17,7 @@
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
@@ -26,6 +27,7 @@
#include "cpu.h"
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/pic.h>
#include <86box/pit.h>
#include <86box/mem.h>
#include <86box/rom.h>
@@ -39,7 +41,7 @@ void ega_doblit(int wx, int wy, ega_t *ega);
#define BIOS_IBM_PATH "roms/video/ega/ibm_6277356_ega_card_u44_27128.bin"
#define BIOS_CPQ_PATH "roms/video/ega/108281-001.bin"
#define BIOS_SEGA_PATH "roms/video/ega/lega.vbi"
#define BIOS_ATIEGA_PATH "roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN"
#define BIOS_ATIEGA800P_PATH "roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN"
#define BIOS_ISKRA_PATH "roms/video/ega/143-02.bin", "roms/video/ega/143-03.bin"
#define BIOS_TSENG_PATH "roms/video/ega/EGA ET2000.BIN"
@@ -47,7 +49,7 @@ enum {
EGA_IBM = 0,
EGA_COMPAQ,
EGA_SUPEREGA,
EGA_ATI,
EGA_ATI800P,
EGA_ISKRA,
EGA_TSENG
};
@@ -59,8 +61,6 @@ static uint32_t pallook64[256];
static int ega_type = 0;
static int old_overscan_color = 0;
uint8_t egaremap2bpp[256];
/* 3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour):
7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines). */
int egaswitchread;
@@ -89,16 +89,6 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
case 0xb0:
ega_recalctimings(ega);
break;
case 0xb2:
case 0xbe:
#if 0
if (ega->regs[0xbe] & 8) { /*Read/write bank mode*/
svga->read_bank = ((ega->regs[0xb2] >> 5) & 7) * 0x10000;
svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000;
} else /*Single bank mode*/
svga->read_bank = svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000;
#endif
break;
case 0xb3:
ati_eeprom_write((ati_eeprom_t *) ega->eeprom, val & 8, val & 2, val & 1);
break;
@@ -118,6 +108,8 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
ega_recalctimings(ega);
}
} else {
if ((ega->attraddr == 0x13) && (ega->attrregs[0x13] != val))
ega->fullchange = changeframecount;
o = ega->attrregs[ega->attraddr & 31];
ega->attrregs[ega->attraddr & 31] = val;
if (ega->attraddr < 16)
@@ -156,8 +148,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
io_removehandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
if (!(val & 1))
io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
if ((o ^ val) & 0x80)
ega_recalctimings(ega);
ega_recalctimings(ega);
break;
case 0x3c4:
ega->seqaddr = val;
@@ -188,6 +179,10 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
break;
}
break;
case 0x3c6:
if (ega_type == 2)
ega->ctl_mode = val;
break;
case 0x3ce:
ega->gdcaddr = val;
break;
@@ -234,14 +229,24 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
break;
case 0x3d0:
case 0x3d4:
ega->crtcreg = val & 31;
if (ega->chipset)
ega->crtcreg = val & 0x3f;
else
ega->crtcreg = val & 0x1f;
return;
case 0x3d1:
case 0x3d5:
if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80))
return;
if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80))
val = (ega->crtc[7] & ~0x10) | (val & 0x10);
if (ega->chipset) {
if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80))
return;
if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80))
val = (ega->crtc[7] & ~0x10) | (val & 0x10);
} else {
if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80))
return;
if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80))
val = (ega->crtc[7] & ~0x10) | (val & 0x10);
}
old = ega->crtc[ega->crtcreg];
ega->crtc[ega->crtcreg] = val;
if (old != val) {
@@ -308,6 +313,10 @@ ega_in(uint16_t addr, void *priv)
if (ega_type)
ret = ega->seqregs[ega->seqaddr & 0xf];
break;
case 0x3c6:
if (ega_type == 2)
ret = ega->ctl_mode;
break;
case 0x3c8:
if (ega_type)
ret = 2;
@@ -341,7 +350,7 @@ ega_in(uint16_t addr, void *priv)
case 0x10:
case 0x11:
// TODO: Return light pen address once implemented
/* TODO: Return light pen address once implemented. */
if (ega_type)
ret = ega->crtc[ega->crtcreg];
break;
@@ -349,12 +358,50 @@ ega_in(uint16_t addr, void *priv)
default:
if (ega_type)
ret = ega->crtc[ega->crtcreg];
break;
}
break;
case 0x3da:
ega->attrff = 0;
ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/
ret = ega->stat;
if (ega_type == 2) {
ret = ega->stat & 0xcf;
switch ((ega->attrregs[0x12] >> 4) & 0x03) {
case 0x00:
/* 00 = Pri. Red (5), Pri. Blue (4) */
ret |= (ega->color_mux & 0x04) ? 0x20 : 0x00;
ret |= (ega->color_mux & 0x01) ? 0x10 : 0x00;
break;
case 0x01:
case 0x03:
/* 01 = Sec. Red (5), Sec. Green (4) */
/* 11 = Sec. Red (5), Sec. Green (4) */
ret |= (ega->color_mux & 0x20) ? 0x20 : 0x00;
ret |= (ega->color_mux & 0x10) ? 0x10 : 0x00;
break;
case 0x02:
/* 10 = Sec. Blue (5), Pri. Green (4) */
ret |= (ega->color_mux & 0x08) ? 0x20 : 0x00;
ret |= (ega->color_mux & 0x02) ? 0x10 : 0x00;
break;
}
} else {
ega->stat ^= 0x30; /* Fools IBM EGA video BIOS self-test. */
ret = ega->stat;
}
break;
case 0x7c6:
ret = 0xfd; /* EGA mode supported. */
break;
case 0xbc6:
/* 0000 = None;
0001 = Compaq Dual-Mode (DM) Monitor;
0010 = RGBI Color Monitor;
0011 = COMPAQ Color Monitor (RrGgBb) or Compatible;
0100 - 1111 = Reserved. */
ret = 0x01;
break;
case 0xfc6:
ret = 0xfd;
break;
default:
@@ -368,6 +415,7 @@ void
ega_recalctimings(ega_t *ega)
{
int clksel;
int color;
double _dispontime;
double _dispofftime;
@@ -411,7 +459,26 @@ ega_recalctimings(ega_t *ega)
ega->linedbl = ega->crtc[9] & 0x80;
ega->rowcount = ega->crtc[9] & 0x1f;
if (ega->eeprom) {
if (ega_type == 2) {
color = (ega->miscout & 1);
clksel = ((ega->miscout & 0xc) >> 2);
if (color) {
if (ega->vidclock)
crtcconst = (cpuclock / 16257000.0 * (double) (1ULL << 32));
else
crtcconst = (cpuclock / (157500000.0 / 11.0) * (double) (1ULL << 32));
} else {
if (ega->vidclock)
crtcconst = (cpuclock / 18981000.0 * (double) (1ULL << 32));
else
crtcconst = (cpuclock / 16872000.0 * (double) (1ULL << 32));
}
if (!(ega->seqregs[1] & 1))
crtcconst *= 9.0;
else
crtcconst *= 8.0;
} else if (ega->eeprom) {
clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0);
switch (clksel) {
@@ -442,6 +509,10 @@ ega_recalctimings(ega_t *ega)
else
crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0));
}
if (!(ega->seqregs[1] & 1))
ega->dot_clock = crtcconst / 9.0;
else
ega->dot_clock = crtcconst / 8.0;
ega->interlace = 0;
@@ -463,21 +534,34 @@ ega_recalctimings(ega_t *ega)
}
}
if (enable_overscan) {
overscan_y = (ega->rowcount + 1) << 1;
if (overscan_y < 16)
overscan_y = 16;
if (ega->chipset) {
if (ega->hdisp > 640) {
ega->dispend <<= 1;
ega->vtotal <<= 1;
ega->split <<= 1;
ega->vsyncstart <<= 1;
}
}
overscan_y = (ega->rowcount + 1) << 1;
if (overscan_y < 16)
overscan_y = 16;
overscan_x = (ega->seqregs[1] & 1) ? 16 : 18;
if (ega->vres)
overscan_y <<= 1;
if (ega->seqregs[1] & 8)
overscan_x <<= 1;
ega->y_add = (overscan_y >> 1) - (ega->crtc[8] & 0x1f);
ega->y_add = (overscan_y >> 1);
ega->x_add = (overscan_x >> 1);
if (ega->vres)
ega->y_add >>= 1;
if (ega->seqregs[1] & 8) {
disptime = (double) ((ega->crtc[0] + 2) << 1);
_dispontime = (double) ((ega->crtc[1] + 1) << 1);
@@ -496,14 +580,115 @@ ega_recalctimings(ega_t *ega)
if (ega->dispofftime < TIMER_USEC)
ega->dispofftime = TIMER_USEC;
ega->dot_time = (uint64_t) (ega->dot_clock);
if (ega->dot_time < TIMER_USEC)
ega->dot_time = TIMER_USEC;
ega_recalc_remap_func(ega);
}
/* This is needed for the Compaq EGA so that it can pass the 3DA
palette mux part of the self-test. */
void
ega_dot_poll(void *priv)
{
ega_t *ega = (ega_t *) priv;
static uint8_t chr;
static uint8_t attr;
const bool doublewidth = ((ega->seqregs[1] & 8) != 0);
const bool attrblink = ((ega->attrregs[0x10] & 8) != 0);
const bool attrlinechars = (ega->attrregs[0x10] & 4);
const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0);
const bool seq9dot = ((ega->seqregs[1] & 1) == 0);
const bool blinked = ega->blink & 0x10;
const int dwshift = doublewidth ? 1 : 0;
const int dotwidth = 1 << dwshift;
const int charwidth = dotwidth * (seq9dot ? 9 : 8);
const int cursoron = (ega->sc == (ega->crtc[10] & 31));
const int cursoraddr = (ega->crtc[0xe] << 8) | ega->crtc[0xf];
uint32_t addr;
int drawcursor;
uint32_t charaddr;
static int fg;
static int bg;
static uint32_t dat;
static int disptime;
static int _dispontime;
static int _dispofftime;
static int cclock = 0;
static int active = 0;
if (ega->seqregs[1] & 8) {
disptime = ((ega->crtc[0] + 2) << 1);
_dispontime = ((ega->crtc[1] + 1) << 1);
} else {
disptime = (ega->crtc[0] + 2);
_dispontime = (ega->crtc[1] + 1);
}
_dispofftime = disptime - _dispontime;
timer_advance_u64(&ega->dot_timer, ega->dot_time);
if (ega->render == ega_render_text)
ega->color_mux = (dat & (0x100 >> (ega->dot >> dwshift))) ? fg : bg;
else
ega->color_mux = 0x00;
addr = ega->remap_func(ega, ega->cca) & ega->vrammask;
if (!crtcreset) {
chr = ega->vram[addr];
attr = ega->vram[addr + 1];
} else
chr = attr = 0;
drawcursor = ((ega->cca == cursoraddr) && cursoron && ega->cursoron);
if (attr & 8)
charaddr = ega->charsetb + (chr * 0x80);
else
charaddr = ega->charseta + (chr * 0x80);
dat = ega->vram[charaddr + (ega->sc << 2)];
dat <<= 1;
if ((chr & ~0x1F) == 0xC0 && attrlinechars)
dat |= (dat >> 1) & 1;
if (!active)
dat = 0x200;
if (drawcursor) {
bg = ega->egapal[attr & 0x0f];
fg = ega->egapal[attr >> 4];
} else {
fg = ega->egapal[attr & 0x0f];
bg = ega->egapal[attr >> 4];
if ((attr & 0x80) && attrblink) {
bg = ega->egapal[(attr >> 4) & 7];
if (blinked)
fg = bg;
}
}
ega->dot = (ega->dot + 1) % charwidth;
if (ega->dot == 0) {
ega->cca = (ega->cca + 4) & 0x3ffff;
cclock++;
if (active && (cclock == _dispofftime))
active = 0;
else if (!active && (cclock == _dispontime))
active = 1;
}
}
void
ega_poll(void *priv)
{
ega_t *ega = (ega_t *) priv;
int x;
int x, y;
int old_ma;
int wx = 640;
int wy = 350;
@@ -523,37 +708,26 @@ ega_poll(void *priv)
video_wait_for_buffer();
}
if (ega->vres) {
old_ma = ega->ma;
ega->displine <<= 1;
ega->y_add <<= 1;
old_ma = ega->ma;
ega->displine *= ega->vres + 1;
ega->y_add *= ega->vres + 1;
for (y = 0; y <= ega->vres; y++) {
/* Render scanline */
ega->render(ega);
/* Render overscan */
ega->x_add = (overscan_x >> 1);
ega_render_overscan_left(ega);
ega_render_overscan_right(ega);
ega->x_add = (overscan_x >> 1) - ega->scrollcache;
ega->displine++;
ega->ma = old_ma;
ega->render(ega);
ega->x_add = (overscan_x >> 1);
ega_render_overscan_left(ega);
ega_render_overscan_right(ega);
ega->x_add = (overscan_x >> 1) - ega->scrollcache;
ega->y_add >>= 1;
ega->displine >>= 1;
} else {
ega_render_overscan_left(ega);
ega->render(ega);
ega_render_overscan_right(ega);
if (y != ega->vres) {
ega->ma = old_ma;
ega->displine++;
}
}
ega->displine /= ega->vres + 1;
ega->y_add /= ega->vres + 1;
if (ega->lastline < ega->displine)
ega->lastline = ega->displine;
@@ -565,8 +739,18 @@ ega_poll(void *priv)
if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines)
ega->stat &= ~8;
ega->vslines++;
if (ega->displine > 500)
ega->displine = 0;
if (ega->chipset) {
if (ega->hdisp > 640) {
if (ega->displine > 2000)
ega->displine = 0;
} else {
if (ega->displine > 500)
ega->displine = 0;
}
} else {
if (ega->displine > 500)
ega->displine = 0;
}
} else {
timer_advance_u64(&ega->timer, ega->dispontime);
@@ -578,9 +762,11 @@ ega_poll(void *priv)
if ((ega->sc == (ega->crtc[11] & 31)) || (ega->sc == ega->rowcount))
ega->con = 0;
if (ega->dispon) {
/* TODO: Verify real hardware behaviour for out-of-range fine vertical scroll */
if (ega->linedbl && !ega->linecountff) {
ega->linecountff = 1;
ega->ma = ega->maback;
ega->cca = ega->maback;
}
if (ega->sc == (ega->crtc[9] & 31)) {
ega->linecountff = 0;
@@ -591,15 +777,23 @@ ega_poll(void *priv)
ega->maback += (ega->rowoffset << 3);
ega->maback &= ega->vrammask;
ega->ma = ega->maback;
ega->cca = ega->maback;
} else {
ega->linecountff = 0;
ega->sc++;
ega->sc &= 31;
ega->ma = ega->maback;
ega->cca = ega->maback;
}
}
ega->vc++;
ega->vc &= 511;
if (ega->chipset) {
if (ega->hdisp > 640)
ega->vc &= 1023;
else
ega->vc &= 511;
} else
ega->vc &= 511;
if (ega->vc == ega->split) {
// TODO: Implement the hardware bug where the first scanline is drawn twice when the split happens
if (ega->interlace && ega->oddeven)
@@ -607,6 +801,7 @@ ega_poll(void *priv)
else
ega->ma = ega->maback = 0;
ega->ma <<= 2;
ega->cca = ega->ma;
ega->maback <<= 2;
ega->sc = 0;
if (ega->attrregs[0x10] & 0x20) {
@@ -634,6 +829,9 @@ ega_poll(void *priv)
if (ega->vc == ega->vsyncstart) {
ega->dispon = 0;
ega->stat |= 8;
#if 0
picint(1 << 2);
#endif
x = ega->hdisp;
if (ega->interlace && !ega->oddeven)
@@ -673,24 +871,19 @@ ega_poll(void *priv)
ega->ma <<= 2;
ega->maback <<= 2;
ega->ca <<= 2;
ega->cca = ega->ma;
}
if (ega->vc == ega->vtotal) {
ega->vc = 0;
ega->sc = 0;
ega->sc = (ega->crtc[0x8] & 0x1f);
ega->dispon = 1;
ega->displine = (ega->interlace && ega->oddeven) ? 1 : 0;
ega->scrollcache = (ega->attrregs[0x13] & 0x0f);
if (!(ega->gdcreg[6] & 1) && !(ega->attrregs[0x10] & 1)) { /*Text mode*/
if (ega->seqregs[1] & 1)
ega->scrollcache &= 0x07;
else {
ega->scrollcache++;
if (ega->scrollcache > 8)
ega->scrollcache = 0;
}
} else
ega->scrollcache &= 0x07;
if (ega->scrollcache >= 0x8)
ega->scrollcache = 0;
else
ega->scrollcache++;
if (ega->seqregs[1] & 8)
ega->scrollcache <<= 1;
@@ -707,11 +900,12 @@ ega_poll(void *priv)
void
ega_doblit(int wx, int wy, ega_t *ega)
{
int y_add = enable_overscan ? overscan_y : 0;
int unscaled_overscan_y = ega->vres ? overscan_y >> 1 : overscan_y;
int y_add = enable_overscan ? unscaled_overscan_y : 0;
int x_add = enable_overscan ? overscan_x : 0;
int y_start = enable_overscan ? 0 : (overscan_y >> 1);
int y_start = enable_overscan ? 0 : (unscaled_overscan_y >> 1);
int x_start = enable_overscan ? 0 : (overscan_x >> 1);
int bottom = (overscan_y >> 1) + (ega->crtc[8] & 0x1f);
int bottom = (unscaled_overscan_y >> 1);
uint32_t *p;
int i;
int j;
@@ -1102,32 +1296,6 @@ ega_init(ega_t *ega, int monitor_type, int is_mono)
}
}
for (c = 0; c < 4; c++) {
for (d = 0; d < 4; d++) {
edatlookup[c][d] = 0;
if (c & 1)
edatlookup[c][d] |= 1;
if (d & 1)
edatlookup[c][d] |= 2;
if (c & 2)
edatlookup[c][d] |= 0x10;
if (d & 2)
edatlookup[c][d] |= 0x20;
}
}
for (c = 0; c < 256; c++) {
egaremap2bpp[c] = 0;
if (c & 0x01)
egaremap2bpp[c] |= 0x01;
if (c & 0x04)
egaremap2bpp[c] |= 0x02;
if (c & 0x10)
egaremap2bpp[c] |= 0x04;
if (c & 0x40)
egaremap2bpp[c] |= 0x08;
}
if (is_mono) {
for (c = 0; c < 256; c++) {
if (((c >> 3) & 3) == 0)
@@ -1221,6 +1389,8 @@ ega_init(ega_t *ega, int monitor_type, int is_mono)
ega->crtc[6] = 255;
timer_add(&ega->timer, ega_poll, ega, 1);
if (ega_type == 2)
timer_add(&ega->dot_timer, ega_dot_poll, ega, 1);
}
static void *
@@ -1229,7 +1399,7 @@ ega_standalone_init(const device_t *info)
ega_t *ega = malloc(sizeof(ega_t));
int monitor_type;
memset(ega, 0, sizeof(ega_t));
memset(ega, 0x00, sizeof(ega_t));
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ega);
@@ -1240,9 +1410,14 @@ ega_standalone_init(const device_t *info)
if ((info->local == EGA_IBM) || (info->local == EGA_ISKRA) || (info->local == EGA_TSENG))
ega_type = 0;
else if (info->local == EGA_COMPAQ)
ega_type = 2;
else
ega_type = 1;
ega->actual_type = info->local;
ega->chipset = 0;
switch (info->local) {
default:
case EGA_IBM:
@@ -1250,6 +1425,7 @@ ega_standalone_init(const device_t *info)
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
break;
case EGA_COMPAQ:
ega->ctl_mode = 0x21;
rom_init(&ega->bios_rom, BIOS_CPQ_PATH,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
break;
@@ -1257,9 +1433,10 @@ ega_standalone_init(const device_t *info)
rom_init(&ega->bios_rom, BIOS_SEGA_PATH,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
break;
case EGA_ATI:
rom_init(&ega->bios_rom, BIOS_ATIEGA_PATH,
case EGA_ATI800P:
rom_init(&ega->bios_rom, BIOS_ATIEGA800P_PATH,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
ega->chipset = 1;
break;
case EGA_ISKRA:
rom_init_interleaved(&ega->bios_rom, BIOS_ISKRA_PATH,
@@ -1288,11 +1465,16 @@ ega_standalone_init(const device_t *info)
mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega);
io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
if (info->local == EGA_ATI) {
if (ega->chipset) {
io_sethandler(0x01ce, 0x0002, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
ega->eeprom = malloc(sizeof(ati_eeprom_t));
memset(ega->eeprom, 0, sizeof(ati_eeprom_t));
ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800.nvr", 0);
ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800p.nvr", 0);
} else if (info->local == EGA_COMPAQ) {
io_sethandler(0x0084, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
io_sethandler(0x07c6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
io_sethandler(0x0bc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
io_sethandler(0x0fc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
}
return ega;
@@ -1317,9 +1499,9 @@ sega_standalone_available(void)
}
static int
atiega_standalone_available(void)
atiega800p_standalone_available(void)
{
return rom_present(BIOS_ATIEGA_PATH);
return rom_present(BIOS_ATIEGA800P_PATH);
}
static int
@@ -1354,11 +1536,11 @@ ega_speed_changed(void *priv)
}
/* SW1 SW2 SW3 SW4
OFF OFF ON OFF Monochrome (5151) 1011 0x0B
ON OFF OFF ON Color 40x25 (5153) 0110 0x06
OFF OFF OFF ON Color 80x25 (5153) 0111 0x07
ON ON ON OFF Enhanced Color - Normal Mode (5154) 1000 0x08
OFF ON ON OFF Enhanced Color - Enhanced Mode (5154) 1001 0x09
OFF OFF ON OFF Monochrome (5151) 1011 0x0B
ON OFF OFF ON Color 40x25 (5153) 0110 0x06
OFF OFF OFF ON Color 80x25 (5153) 0111 0x07
ON ON ON OFF Enhanced Color - Normal Mode (5154) 1000 0x08
OFF ON ON OFF Enhanced Color - Enhanced Mode (5154) 1001 0x09
0 = Switch closed (ON);
1 = Switch open (OFF). */
@@ -1478,15 +1660,15 @@ const device_t sega_device = {
.config = ega_config
};
const device_t atiega_device = {
const device_t atiega800p_device = {
.name = "ATI EGA Wonder 800+",
.internal_name = "egawonder800",
.internal_name = "egawonder800p",
.flags = DEVICE_ISA,
.local = EGA_ATI,
.local = EGA_ATI800P,
.init = ega_standalone_init,
.close = ega_close,
.reset = NULL,
{ .available = atiega_standalone_available },
{ .available = atiega800p_standalone_available },
.speed_changed = ega_speed_changed,
.force_redraw = NULL,
.config = ega_config

View File

@@ -126,6 +126,14 @@ ega_render_text(ega_t *ega)
const bool blinked = ega->blink & 0x10;
uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
/* Compensate for 8dot scroll */
if (!seq9dot) {
for (int x = 0; x < dotwidth; x++) {
p[x] = ega->overscan_color;
}
p += dotwidth;
}
for (int x = 0; x < (ega->hdisp + ega->scrollcache); x += charwidth) {
uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask;

View File

@@ -246,7 +246,7 @@ et3000_init(const device_t *info)
break;
}
rom_init(&dev->bios_rom, (char *) fn,
rom_init(&dev->bios_rom, fn,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
dev->svga.bpp = 8;

View File

@@ -416,8 +416,8 @@ et4000k_out(uint16_t addr, uint8_t val, void *priv)
static uint8_t
et4000_kasan_in(uint16_t addr, void *priv)
{
et4000_t *et4000 = (et4000_t *) priv;
uint8_t val = 0xFF;
const et4000_t *et4000 = (et4000_t *) priv;
uint8_t val = 0xFF;
if (addr == 0x258) {
val = et4000->kasan_cfg_index;
@@ -483,9 +483,7 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv)
case 5:
et4000->kasan_cfg_regs[5] = val;
et4000->svga.ksc5601_english_font_type = 0x100 | val;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 6:
case 7:
et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val;
@@ -538,8 +536,8 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv)
uint32_t
get_et4000_addr(uint32_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
uint32_t nbank;
const svga_t *svga = (svga_t *) priv;
uint32_t nbank;
switch (svga->crtc[0x37] & 0x0B) {
case 0x00:
@@ -598,7 +596,7 @@ get_et4000_addr(uint32_t addr, void *priv)
static void
et4000_recalctimings(svga_t *svga)
{
et4000_t *dev = (et4000_t *) svga->priv;
const et4000_t *dev = (et4000_t *) svga->priv;
svga->ma_latch |= (svga->crtc[0x33] & 3) << 16;
if (svga->crtc[0x35] & 1)
@@ -671,12 +669,20 @@ et4000_recalctimings(svga_t *svga)
else if (svga->render == svga_render_8bpp_highres)
svga->render = svga_render_8bpp_tseng_highres;
}
if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x40)) {
svga->map8 = svga->pallook;
if (svga->lowres)
svga->render = svga_render_8bpp_lowres;
else
svga->render = svga_render_8bpp_highres;
}
}
static void
et4000_kasan_recalctimings(svga_t *svga)
{
et4000_t *et4000 = (et4000_t *) svga->priv;
const et4000_t *et4000 = (et4000_t *) svga->priv;
et4000_recalctimings(svga);
@@ -692,7 +698,7 @@ et4000_kasan_recalctimings(svga_t *svga)
static uint8_t
et4000_mca_read(int port, void *priv)
{
et4000_t *et4000 = (et4000_t *) priv;
const et4000_t *et4000 = (et4000_t *) priv;
return (et4000->pos_regs[port & 7]);
}
@@ -815,6 +821,9 @@ et4000_init(const device_t *info)
loadfont(KASAN_FONT_ROM_PATH, 6);
fn = KASAN_BIOS_ROM_PATH;
break;
default:
break;
}
if (dev->type >= ET4000_TYPE_ISA)
@@ -822,7 +831,7 @@ et4000_init(const device_t *info)
dev->vram_mask = dev->vram_size - 1;
rom_init(&dev->bios_rom, (char *) fn,
rom_init(&dev->bios_rom, fn,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
dev->svga.translate_address = get_et4000_addr;

View File

@@ -69,7 +69,7 @@ typedef struct et4000w32p_t {
svga_t svga;
uint8_t banking, banking2, adjust_cursor, rev;
uint8_t banking, banking2, adjust_cursor, rev, pci_slot;
uint8_t regs[256], pci_regs[256];
@@ -210,6 +210,9 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv)
svga->gdcreg[svga->gdcaddr & 15] = val;
et4000w32p_recalcmapping(et4000);
return;
default:
break;
}
break;
case 0x3d4:
@@ -290,6 +293,9 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv)
case 8:
svga->hwcursor.xoff += 32;
break;
default:
break;
}
}
@@ -315,6 +321,9 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv)
add2addr = svga->hwcursor.yoff * ((svga->hwcursor.cur_xsize == 128) ? 32 : 16);
svga->hwcursor.addr += add2addr;
return;
default:
break;
}
svga_out(addr, val, svga);
@@ -408,6 +417,9 @@ et4000w32p_in(uint16_t addr, void *priv)
return (et4000->regs[0xef] & 0x8f) | (et4000->rev << 4) | et4000->vlb;
}
return et4000->regs[et4000->index];
default:
break;
}
return svga_in(addr, svga);
@@ -452,6 +464,9 @@ et4000w32p_recalctimings(svga_t *svga)
case 24:
svga->clock /= 4;
break;
default:
break;
}
}
}
@@ -492,6 +507,9 @@ et4000w32p_recalctimings(svga_t *svga)
break;
svga->hdisp -= 24;
break;
default:
break;
}
}
}
@@ -502,7 +520,8 @@ et4000w32p_recalctimings(svga_t *svga)
switch (svga->bpp) {
case 15:
case 16:
svga->hdisp >>= 1;
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))
svga->hdisp >>= 1;
if (et4000->type <= ET4000W32P_REVC) {
if (et4000->type == ET4000W32P_REVC) {
if (svga->hdisp != 1024)
@@ -515,10 +534,13 @@ et4000w32p_recalctimings(svga_t *svga)
svga->hdisp /= 3;
if (et4000->type <= ET4000W32P_REVC)
et4000->adjust_cursor = 2;
if (et4000->type == ET4000W32P_DIAMOND && (svga->hdisp == 640 / 2 || svga->hdisp == 1232)) {
if ((et4000->type == ET4000W32P_DIAMOND) && ((svga->hdisp == (640 / 2)) || (svga->hdisp == 1232))) {
svga->hdisp = 640;
}
break;
default:
break;
}
svga->render = svga_render_blank;
@@ -592,8 +614,14 @@ et4000w32p_recalctimings(svga_t *svga)
else
svga->render = svga_render_32bpp_highres;
break;
default:
break;
}
break;
default:
break;
}
}
}
@@ -668,6 +696,9 @@ et4000w32p_recalcmapping(et4000w32p_t *et4000)
mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000);
svga->banked_mask = 0x7fff;
break;
default:
break;
}
}
@@ -834,6 +865,9 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val)
case 0xaf:
et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8);
break;
default:
break;
}
}
@@ -969,9 +1003,15 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv)
case 0x31:
et4000->acl.osr = val;
break;
default:
break;
}
}
break;
default:
break;
}
}
@@ -979,7 +1019,7 @@ static uint8_t
et4000w32p_mmu_read(uint32_t addr, void *priv)
{
et4000w32p_t *et4000 = (et4000w32p_t *) priv;
svga_t *svga = &et4000->svga;
const svga_t *svga = &et4000->svga;
uint8_t temp;
switch (addr & 0x6000) {
@@ -1074,8 +1114,7 @@ et4000w32p_mmu_read(uint32_t addr, void *priv)
case 0x8e:
if (et4000->type >= ET4000W32P_REVC)
return et4000->acl.internal.pixel_depth;
else
return et4000->acl.internal.vbus;
return et4000->acl.internal.vbus;
case 0x8f:
return et4000->acl.internal.xy_dir;
case 0x90:
@@ -1106,9 +1145,15 @@ et4000w32p_mmu_read(uint32_t addr, void *priv)
return et4000->acl.internal.dest_addr >> 16;
case 0xa3:
return et4000->acl.internal.dest_addr >> 24;
default:
break;
}
return 0xff;
default:
break;
}
return 0xff;
@@ -2341,6 +2386,9 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32
case 7: /* X- */
et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000);
break;
default:
break;
}
et4000->acl.internal.error += et4000->acl.internal.dmin;
if (et4000->acl.internal.error > et4000->acl.internal.dmaj) {
@@ -2366,6 +2414,9 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32
et4000w32_decy(et4000);
et4000->acl.internal.pos_y++;
break;
default:
break;
}
}
if ((et4000->acl.internal.pos_x > et4000->acl.internal.count_x) || (et4000->acl.internal.pos_y > et4000->acl.internal.count_y)) {
@@ -2453,16 +2504,17 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32
void
et4000w32p_hwcursor_draw(svga_t *svga, int displine)
{
et4000w32p_t *et4000 = (et4000w32p_t *) svga->priv;
int offset;
int xx;
int xx2;
int shift = (et4000->adjust_cursor + 1);
int width = (svga->hwcursor_latch.cur_xsize - svga->hwcursor_latch.xoff);
int pitch = (svga->hwcursor_latch.cur_xsize == 128) ? 32 : 16;
int x_acc = 4;
int minus_width = 0;
uint8_t dat;
const et4000w32p_t *et4000 = (et4000w32p_t *) svga->priv;
int offset;
int xx;
int xx2;
int shift = (et4000->adjust_cursor + 1);
int width = (svga->hwcursor_latch.cur_xsize - svga->hwcursor_latch.xoff);
int pitch = (svga->hwcursor_latch.cur_xsize == 128) ? 32 : 16;
int x_acc = 4;
int minus_width = 0;
uint8_t dat;
offset = svga->hwcursor_latch.xoff;
if ((et4000->type == ET4000W32) && (pitch == 32)) {
@@ -2476,6 +2528,9 @@ et4000w32p_hwcursor_draw(svga_t *svga, int displine)
minus_width = 64;
x_acc = 2;
break;
default:
break;
}
}
@@ -2561,7 +2616,7 @@ et4000w32p_io_set(et4000w32p_t *et4000)
uint8_t
et4000w32p_pci_read(UNUSED(int func), int addr, void *priv)
{
et4000w32p_t *et4000 = (et4000w32p_t *) priv;
const et4000w32p_t *et4000 = (et4000w32p_t *) priv;
if (func > 0)
return 0xff;
@@ -2612,6 +2667,9 @@ et4000w32p_pci_read(UNUSED(int func), int addr, void *priv)
return 0x00;
case 0x33:
return et4000->pci_regs[0x33] & 0xf0;
default:
break;
}
return 0;
@@ -2666,6 +2724,9 @@ et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
mem_mapping_disable(&et4000->bios_rom.mapping);
}
return;
default:
break;
}
}
@@ -2798,6 +2859,9 @@ et4000w32p_init(const device_t *info)
et4000->svga.clock_gen = device_add(&icd2061_device);
et4000->svga.getclock = icd2061_getclock;
break;
default:
break;
}
if (info->flags & DEVICE_PCI)
mem_mapping_disable(&et4000->bios_rom.mapping);
@@ -2808,7 +2872,7 @@ et4000w32p_init(const device_t *info)
et4000w32p_io_set(et4000);
if (info->flags & DEVICE_PCI)
pci_add_card(PCI_ADD_VIDEO, et4000w32p_pci_read, et4000w32p_pci_write, et4000);
pci_add_card(PCI_ADD_NORMAL, et4000w32p_pci_read, et4000w32p_pci_write, et4000, &et4000->pci_slot);
/* Hardwired bits: 00000000 1xx0x0xx */
/* R/W bits: xx xxxx */

View File

@@ -24,12 +24,12 @@
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <https://pcem-emulator.co.uk/>
* John Elliott, <jce@seasip.info>
* Lubomir Rintel, <lkundrak@v3.sk>
*
* Copyright 2018-2019 Fred N. van Kempen.
* Copyright 2018-2019 Miran Grca.
* Copyright 2018-2019 Sarah Walker.
* Copyright 2018-2019 John Elliott.
* Copyright 2021 Lubomir Rintel.
*
* This program is free software; you can redistribute it and/or modify
@@ -39,7 +39,7 @@
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -268,6 +268,9 @@ f82c425_out(uint16_t addr, uint8_t val, void *priv)
f82c425_smartmap(f82c425);
f82c425_colormap(f82c425);
break;
default:
break;
}
}
@@ -300,6 +303,9 @@ f82c425_in(uint16_t addr, void *priv)
return f82c425->timing;
case 0xdf:
return f82c425->function;
default:
break;
}
return 0xff;
@@ -317,7 +323,8 @@ f82c425_write(uint32_t addr, uint8_t val, void *priv)
static uint8_t
f82c425_read(uint32_t addr, void *priv)
{
f82c425_t *f82c425 = (f82c425_t *) priv;
const f82c425_t *f82c425 = (f82c425_t *) priv;
cycles -= 4;
return f82c425->vram[addr & 0x3fff];
@@ -391,12 +398,12 @@ f82c425_text_row(f82c425_t *f82c425)
if (f82c425->cga.cgamode & 0x01) {
/* High resolution (80 cols) */
for (c = 0; c < sl; c++) {
((uint32_t *) buffer32->line[f82c425->displine])[(x << 3) + c] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0];
(buffer32->line[f82c425->displine])[(x << 3) + c] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0];
}
} else {
/* Low resolution (40 columns, stretch pixels horizontally) */
for (c = 0; c < sl; c++) {
((uint32_t *) buffer32->line[f82c425->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[f82c425->displine])[(x << 4) + c * 2 + 1] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0];
(buffer32->line[f82c425->displine])[(x << 4) + c * 2] = (buffer32->line[f82c425->displine])[(x << 4) + c * 2 + 1] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0];
}
}
@@ -420,7 +427,7 @@ f82c425_cgaline6(f82c425_t *f82c425)
addr++;
for (uint8_t c = 0; c < 8; c++) {
((uint32_t *) buffer32->line[f82c425->displine])[x * 8 + c] = colormap[dat & 0x80 ? 3 : 0];
(buffer32->line[f82c425->displine])[x * 8 + c] = colormap[dat & 0x80 ? 3 : 0];
dat = dat << 1;
}
@@ -447,7 +454,7 @@ f82c425_cgaline4(f82c425_t *f82c425)
if (!(f82c425->cga.cgamode & 0x08))
pattern = 0;
((uint32_t *) buffer32->line[f82c425->displine])[x * 8 + 2 * c] = ((uint32_t *) buffer32->line[f82c425->displine])[x * 8 + 2 * c + 1] = colormap[pattern & 3];
(buffer32->line[f82c425->displine])[x * 8 + 2 * c] = (buffer32->line[f82c425->displine])[x * 8 + 2 * c + 1] = colormap[pattern & 3];
dat = dat << 2;
}
@@ -506,6 +513,9 @@ f82c425_poll(void *priv)
case 0x01:
f82c425_text_row(f82c425);
break;
default:
break;
}
}
f82c425->displine++;

View File

@@ -10,10 +10,10 @@
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Authors: John Elliott, <jce@seasip.info>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2019 Sarah Walker.
* Copyright 2008-2019 John Elliott.
* Copyright 2016-2019 Miran Grca.
*/
#include <stdio.h>
@@ -74,7 +74,7 @@ static video_timings_t timing_genius = { .type = VIDEO_ISA, .write_b = 8, .write
* Two card-specific registers control text and graphics display:
*
* 03B0: Control register.
* Bit 0: Map all graphics framebuffer into memory.
* Bit 0: Map all graphics framebuffer into memory.
* Bit 2: Unknown. Set by GMC /M; cleared by mode set or GMC /T.
* Bit 4: Set for CGA-compatible graphics, clear for native graphics.
* Bit 5: Set for black on white, clear for white on black.
@@ -204,14 +204,17 @@ genius_out(uint16_t addr, uint8_t val, void *priv)
case 0x3d9:
genius->cga_colour = val;
return;
default:
break;
}
}
uint8_t
genius_in(uint16_t addr, void *priv)
{
genius_t *genius = (genius_t *) priv;
uint8_t ret = 0xff;
const genius_t *genius = (genius_t *) priv;
uint8_t ret = 0xff;
switch (addr) {
case 0x3b0:
@@ -253,6 +256,9 @@ genius_in(uint16_t addr, void *priv)
case 0x3da:
ret = genius->cga_stat;
break;
default:
break;
}
return ret;
@@ -295,8 +301,9 @@ genius_write(uint32_t addr, uint8_t val, void *priv)
uint8_t
genius_read(uint32_t addr, void *priv)
{
genius_t *genius = (genius_t *) priv;
uint8_t ret;
const genius_t *genius = (genius_t *) priv;
uint8_t ret;
genius_waitstates();
if (genius->genius_control & 1) {
@@ -364,6 +371,9 @@ genius_lines(genius_t *genius)
case 0x13:
ret = 492; /* 80x41 */
break;
default:
break;
}
return ret;
@@ -379,7 +389,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
uint8_t attr;
uint8_t sc;
uint8_t ctrl;
uint8_t *crtc;
const uint8_t *crtc;
uint8_t bitmap[2];
int blink;
int c;
@@ -390,7 +400,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
uint16_t addr;
uint16_t ma = (genius->mda_crtc[13] | (genius->mda_crtc[12] << 8)) & 0x3fff;
uint16_t ca = (genius->mda_crtc[15] | (genius->mda_crtc[14] << 8)) & 0x3fff;
unsigned char *framebuf = genius->vram + 0x10000;
const uint8_t *framebuf = genius->vram + 0x10000;
uint32_t col;
uint32_t dl = genius->displine;
@@ -404,13 +414,13 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
charh = 15 - (genius->genius_charh & 3);
#if 0
if (genius->genius_charh & 0x10) {
row = ((dl >> 1) / charh);
sc = ((dl >> 1) % charh);
} else {
row = (dl / charh);
sc = (dl % charh);
}
if (genius->genius_charh & 0x10) {
row = ((dl >> 1) / charh);
sc = ((dl >> 1) % charh);
} else {
row = (dl / charh);
sc = (dl % charh);
}
#else
row = (dl / charh);
sc = (dl % charh);
@@ -449,10 +459,10 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
for (int x = 0; x < w; x++) {
#if 0
if ((genius->genius_charh & 0x10) && ((addr + 2 * x) > 0x0FFF))
chr = 0x00;
if ((genius->genius_charh & 0x10) && ((addr + 2 * x + 1) > 0x0FFF))
attr = 0x00;
if ((genius->genius_charh & 0x10) && ((addr + 2 * x) > 0x0FFF))
chr = 0x00;
if ((genius->genius_charh & 0x10) && ((addr + 2 * x + 1) > 0x0FFF))
attr = 0x00;
#endif
chr = framebuf[(addr + 2 * x) & 0x3FFF];
attr = framebuf[(addr + 2 * x + 1) & 0x3FFF];
@@ -466,6 +476,9 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
case 0x60:
drawcursor = drawcursor && (genius->blink & 32);
break;
default:
break;
}
blink = ((genius->blink & 16) && (ctrl & 0x20) && (attr & 0x80) && !drawcursor);
@@ -721,9 +734,8 @@ genius_poll(void *priv)
}
}
void
*
genius_init(const device_t *info)
void *
genius_init(UNUSED(const device_t *info))
{
genius_t *genius = malloc(sizeof(genius_t));

View File

@@ -152,8 +152,8 @@ hercules_out(uint16_t addr, uint8_t val, void *priv)
static uint8_t
hercules_in(uint16_t addr, void *priv)
{
hercules_t *dev = (hercules_t *) priv;
uint8_t ret = 0xff;
const hercules_t *dev = (hercules_t *) priv;
uint8_t ret = 0xff;
switch (addr) {
case 0x03b0:

View File

@@ -139,6 +139,7 @@ herculesplus_out(uint16_t port, uint8_t val, void *priv)
return;
old = dev->crtc[dev->crtcreg];
dev->crtc[dev->crtcreg] = val;
if (dev->crtc[10] == 6 && dev->crtc[11] == 7) {
/*Fix for Generic Turbo XT BIOS,
*which sets up cursor registers wrong*/
@@ -172,8 +173,8 @@ herculesplus_out(uint16_t port, uint8_t val, void *priv)
static uint8_t
herculesplus_in(uint16_t port, void *priv)
{
herculesplus_t *dev = (herculesplus_t *) priv;
uint8_t ret = 0xff;
const herculesplus_t *dev = (herculesplus_t *) priv;
uint8_t ret = 0xff;
switch (port) {
case 0x3b0:
@@ -214,7 +215,7 @@ herculesplus_write(uint32_t addr, uint8_t val, void *priv)
static uint8_t
herculesplus_read(uint32_t addr, void *priv)
{
herculesplus_t *dev = (herculesplus_t *) priv;
const herculesplus_t *dev = (herculesplus_t *) priv;
return dev->vram[addr & 0xffff];
}
@@ -230,9 +231,10 @@ draw_char_rom(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
int elg;
int blk;
int cw = HERCULESPLUS_CW;
int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK;
blk = 0;
if (dev->ctrl & HERCULESPLUS_CTRL_BLINK) {
if (blink) {
if (attr & 0x80)
blk = (dev->blink & 16);
attr &= 0x7f;
@@ -282,8 +284,8 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
{
unsigned ull;
unsigned val;
unsigned ifg;
unsigned ibg;
unsigned cfg;
const uint8_t *fnt;
int elg;
int blk;
@@ -299,42 +301,39 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
/* MDA-compatible attributes */
ibg = 0;
ifg = 7;
if ((attr & 0x77) == 0x70) { /* Invert */
ifg = 0;
ibg = 7;
}
if (attr & 8)
if (attr & 0x80)
ibg |= 8; /* High intensity BG */
ifg |= 8; /* High intensity FG */
if (attr & 0x80)
ibg |= 8; /* High intensity BG */
if ((attr & 0x77) == 0) /* Blank */
ull = ((attr & 0x07) == 1) ? 13 : 0xffff;
ifg = ibg;
ull = ((attr & 0x07) == 1) ? 13 : 0xffff;
if (dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL)
elg = 0;
else
elg = ((chr >= 0xc0) && (chr <= 0xdf));
fnt = dev->vram + 0x4000 + 16 * chr + dev->sc;
if (blk) {
/* Blinking, draw all background */
val = 0x000;
val = 0x000; /* Blinking, draw all background */
} else if (dev->sc == ull) {
/* Underscore, draw all foreground */
val = 0x1ff;
val = 0x1ff; /* Underscore, draw all foreground */
} else {
val = fnt[0x00000] << 1;
val = fnt[0] << 1;
if (elg)
val |= (val >> 1) & 1;
}
for (int i = 0; i < cw; i++) {
/* Generate pixel colour */
cfg = 0;
/* cfg = colour of foreground pixels */
if ((attr & 0x77) == 0)
cfg = ibg; /* 'blank' attribute */
buffer32->line[dev->displine][x * cw + i] = dev->cols[attr][!!blink][cfg];
buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? ifg : ibg;
val = val << 1;
}
}
@@ -342,96 +341,65 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
static void
draw_char_ram48(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
{
int elg;
int blk;
int ul;
int ol;
int bld;
unsigned ull;
unsigned oll;
unsigned ulc = 0;
unsigned olc = 0;
unsigned val;
unsigned ibg;
unsigned cfg;
const unsigned char *fnt;
int cw = HERCULESPLUS_CW;
int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK;
int font = (attr & 0x0F);
unsigned ull;
unsigned val;
unsigned ifg;
unsigned ibg;
const uint8_t *fnt;
int elg;
int blk;
int cw = HERCULESPLUS_CW;
int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK;
int font = (attr & 0x0F);
if (font >= 12)
font &= 7;
attr = (attr >> 4) ^ 0x0f;
blk = 0;
if (blink) {
if (attr & 0x40)
if (attr & 0x80)
blk = (dev->blink & 16);
attr &= 0x7f;
}
/* MDA-compatible attributes */
if (blink) {
ibg = (attr & 0x80) ? 8 : 0;
bld = 0;
ol = (attr & 0x20) ? 1 : 0;
ul = (attr & 0x10) ? 1 : 0;
} else {
bld = (attr & 0x80) ? 1 : 0;
ibg = (attr & 0x40) ? 0x0F : 0;
ol = (attr & 0x20) ? 1 : 0;
ul = (attr & 0x10) ? 1 : 0;
}
if (ul) {
ull = dev->crtc[HERCULESPLUS_CRTC_UNDER] & 0x0F;
ulc = (dev->crtc[HERCULESPLUS_CRTC_UNDER] >> 4) & 0x0F;
if (ulc == 0)
ulc = 7;
} else {
ull = 0xFFFF;
}
if (ol) {
oll = dev->crtc[HERCULESPLUS_CRTC_OVER] & 0x0F;
olc = (dev->crtc[HERCULESPLUS_CRTC_OVER] >> 4) & 0x0F;
if (olc == 0)
olc = 7;
} else {
oll = 0xFFFF;
ibg = 0;
ifg = 7;
if ((attr & 0x77) == 0x70) { /* Invert */
ifg = 0;
ibg = 7;
}
if (attr & 8)
ifg |= 8; /* High intensity FG */
if (attr & 0x80)
ibg |= 8; /* High intensity BG */
if ((attr & 0x77) == 0) /* Blank */
ifg = ibg;
ull = ((attr & 0x07) == 1) ? 13 : 0xffff;
if (dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL)
elg = 0;
else
elg = ((chr >= 0xc0) && (chr <= 0xdf));
fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->sc;
if (blk) { /* Blinking, draw all background */
val = 0x000;
if (blk) {
val = 0x000; /* Blinking, draw all background */
} else if (dev->sc == ull) {
/* Underscore, draw all foreground */
val = 0x1ff;
val = 0x1ff; /* Underscore, draw all foreground */
} else {
val = fnt[0x00000] << 1;
val = fnt[0] << 1;
if (elg)
val |= (val >> 1) & 1;
if (bld)
val |= (val >> 1);
}
for (int i = 0; i < cw; i++) {
/* Generate pixel colour */
cfg = val & 0x100;
if (dev->sc == oll)
cfg = olc ^ ibg; /* Strikethrough */
else if (dev->sc == ull)
cfg = ulc ^ ibg; /* Underline */
else
cfg |= ibg;
buffer32->line[dev->displine][(x * cw) + i] = dev->cols[attr][!!blink][cfg];
val = val << 1;
buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? ifg : ibg;
val = val << 1;
}
}
@@ -445,8 +413,8 @@ text_line(herculesplus_t *dev, uint16_t ca)
for (uint8_t x = 0; x < dev->crtc[1]; x++) {
if (dev->ctrl & 8) {
chr = dev->vram[(dev->ma << 1) & 0xfff];
attr = dev->vram[((dev->ma << 1) + 1) & 0xfff];
chr = dev->vram[(dev->ma << 1) & 0x3fff];
attr = dev->vram[((dev->ma << 1) + 1) & 0x3fff];
} else
chr = attr = 0;
@@ -521,6 +489,7 @@ herculesplus_poll(void *priv)
int x;
int oldvc;
int oldsc;
int cw = HERCULESPLUS_CW;
VIDEO_MONITOR_PROLOGUE();
if (!dev->linepos) {
@@ -544,7 +513,7 @@ herculesplus_poll(void *priv)
if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH))
x = dev->crtc[1] << 4;
else
x = dev->crtc[1] * 9;
x = dev->crtc[1] * cw;
video_process_8(x, dev->displine);
}
@@ -607,7 +576,7 @@ herculesplus_poll(void *priv)
if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH))
x = dev->crtc[1] << 4;
else
x = dev->crtc[1] * 9;
x = dev->crtc[1] * cw;
dev->lastline++;
if ((dev->ctrl & 8) && ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) {
xsize = x;

View File

@@ -136,7 +136,7 @@ dword_remap(svga_t *svga, uint32_t in_addr)
static void
ht216_recalc_bank_regs(ht216_t *ht216, int mode)
{
svga_t *svga = &ht216->svga;
const svga_t *svga = &ht216->svga;
if (mode) {
ht216->read_bank_reg[0] = ht216->ht_regs[0xe8];
@@ -321,9 +321,7 @@ ht216_out(uint16_t addr, uint8_t val, void *priv)
svga->adv_flags &= ~FLAG_RAMDAC_SHIFT;
if (val & 0x04)
svga->adv_flags |= FLAG_RAMDAC_SHIFT;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
/*Bank registers*/
case 0xe8:
case 0xe9:
@@ -384,6 +382,9 @@ ht216_out(uint16_t addr, uint8_t val, void *priv)
svga->fullchange = changeframecount;
svga_recalctimings(svga);
break;
default:
break;
}
return;
}
@@ -461,6 +462,9 @@ ht216_out(uint16_t addr, uint8_t val, void *priv)
ht216_remap(ht216);
}
break;
default:
break;
}
svga_out(addr, val, svga);
@@ -529,6 +533,9 @@ ht216_in(uint16_t addr, void *priv)
ret = svga->latch.b[ht216->bg_plane_sel];
ht216->bg_plane_sel = 0;
break;
default:
break;
}
return ret;
@@ -559,6 +566,9 @@ ht216_in(uint16_t addr, void *priv)
if (svga->crtcreg == 0x1f)
return svga->crtc[0xc] ^ 0xea;
return svga->crtc[svga->crtcreg];
default:
break;
}
return svga_in(addr, svga);
@@ -706,11 +716,11 @@ ht216_recalctimings(svga_t *svga)
static void
ht216_hwcursor_draw(svga_t *svga, int displine)
{
ht216_t *ht216 = (ht216_t *) svga->priv;
int shift = (ht216->adjust_cursor ? 2 : 1);
uint32_t dat[2];
int offset = svga->hwcursor_latch.x + svga->hwcursor_latch.xoff;
int width = (ht216->adjust_cursor ? 16 : 32);
const ht216_t *ht216 = (ht216_t *) svga->priv;
int shift = (ht216->adjust_cursor ? 2 : 1);
uint32_t dat[2];
int offset = svga->hwcursor_latch.x + svga->hwcursor_latch.xoff;
int width = (ht216->adjust_cursor ? 16 : 32);
if (ht216->adjust_cursor)
offset >>= 1;
@@ -723,9 +733,9 @@ ht216_hwcursor_draw(svga_t *svga, int displine)
for (int x = 0; x < width; x++) {
if (!(dat[0] & 0x80000000))
((uint32_t *) buffer32->line[displine])[svga->x_add + offset + x] = 0;
(buffer32->line[displine])[svga->x_add + offset + x] = 0;
if (dat[1] & 0x80000000)
((uint32_t *) buffer32->line[displine])[svga->x_add + offset + x] ^= 0xffffff;
(buffer32->line[displine])[svga->x_add + offset + x] ^= 0xffffff;
dat[0] <<= shift;
dat[1] <<= shift;
@@ -861,6 +871,9 @@ ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_u
for (i = 0; i < count; i++)
fg_data[i] = ht216->fg_latch[i];
break;
default:
break;
}
switch (svga->writemode) {
@@ -922,6 +935,9 @@ ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_u
reset_wm = 1;
break;
default:
break;
}
switch (svga->gdcreg[3] & 0x18) {
@@ -969,6 +985,9 @@ ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_u
}
}
break;
default:
break;
}
if (reset_wm)
@@ -1019,6 +1038,9 @@ ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bi
case 0x0c:
input_a = ht216->bg_latch[addr & 7];
break;
default:
break;
}
fg = extalu(ht216->ht_regs[0xce] >> 4, input_a, input_b);
@@ -1106,10 +1128,10 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val)
01 = Bit mask (3CF:8)
1x = (3C4:F5)
*/
svga_t *svga = &ht216->svga;
int i;
uint8_t bit_mask = 0;
uint8_t rop_select = 0;
const svga_t *svga = &ht216->svga;
int i;
uint8_t bit_mask = 0;
uint8_t rop_select = 0;
cycles -= video_timing_write_b;
@@ -1130,6 +1152,9 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val)
case 0x30:
rop_select = ht216->ht_regs[0xf5];
break;
default:
break;
}
switch (ht216->ht_regs[0xcd] & HT_REG_CD_BMSKSL) {
case 0x00:
@@ -1142,6 +1167,9 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val)
case 0x0c:
bit_mask = ht216->ht_regs[0xf5];
break;
default:
break;
}
if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) { /*1->8 bit expansion*/
@@ -1378,9 +1406,9 @@ ht216_read_common(ht216_t *ht216, uint32_t addr)
static uint8_t
ht216_read(uint32_t addr, void *priv)
{
ht216_t *ht216 = (ht216_t *) priv;
svga_t *svga = &ht216->svga;
uint32_t prev_addr = addr;
ht216_t *ht216 = (ht216_t *) priv;
const svga_t *svga = &ht216->svga;
uint32_t prev_addr = addr;
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + ht216->read_banks[(addr >> 15) & 1];
@@ -1396,8 +1424,8 @@ ht216_read(uint32_t addr, void *priv)
static uint8_t
ht216_read_linear(uint32_t addr, void *priv)
{
ht216_t *ht216 = (ht216_t *) priv;
svga_t *svga = &ht216->svga;
ht216_t *ht216 = (ht216_t *) priv;
const svga_t *svga = &ht216->svga;
addr -= ht216->linear_base;
if (!svga->chain4) /*Bits 16 and 17 of linear address are unused in planar modes*/
@@ -1410,8 +1438,10 @@ ht216_read_linear(uint32_t addr, void *priv)
static uint8_t
radius_mca_read(int port, void *priv)
{
ht216_t *ht216 = (ht216_t *) priv;
const ht216_t *ht216 = (ht216_t *) priv;
ht216_log("Port %03x MCA read = %02x\n", port, ht216->pos_regs[port & 7]);
return (ht216->pos_regs[port & 7]);
}
@@ -1506,6 +1536,9 @@ void
}
rom_init(&ht216->bios_rom, BIOS_RADIUS_SVGA_MULTIVIEW_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
break;
default:
break;
}
svga->hwcursor.cur_ysize = 32;

View File

@@ -27,32 +27,41 @@
#include <86box/vid_svga.h>
#include <86box/plat_unused.h>
typedef union {
typedef union ibm_rgb528_pixel8_t {
uint8_t pixel;
struct {
uint8_t b : 2, g : 3, r : 2;
uint8_t b : 2;
uint8_t g : 3;
uint8_t r : 2;
};
} ibm_rgb528_pixel8_t;
typedef union {
typedef union ibm_rgb528_pixel16_t {
uint16_t pixel;
struct {
uint16_t b_ : 5, g_ : 6, r_ : 5;
uint16_t b_ : 5;
uint16_t g_ : 6;
uint16_t r_ : 5;
};
struct {
uint16_t b : 5, g : 5, r : 5, c : 1;
uint16_t b : 5;
uint16_t g : 5;
uint16_t r : 5;
uint16_t c : 1;
};
} ibm_rgb528_pixel16_t;
typedef union {
typedef union ibm_rgb528_pixel32_t {
uint32_t pixel;
struct {
uint8_t b, g, r, a;
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
};
} ibm_rgb528_pixel32_t;
typedef struct
{
typedef struct ibm_rgb528_ramdac_t {
PALETTE extpal;
uint32_t extpallook[256];
uint8_t indexed_data[2048];
@@ -60,33 +69,37 @@ typedef struct
uint8_t cursor64_data[1024];
uint8_t palettes[3][256];
ibm_rgb528_pixel32_t extra_pal[4];
int16_t hwc_y, hwc_x;
uint16_t index, smlc_part;
int16_t hwc_y;
int16_t hwc_x;
uint16_t index;
uint16_t smlc_part;
uint8_t cmd_r0;
uint8_t cmd_r1;
uint8_t cmd_r2;
uint8_t cmd_r3;
uint8_t cmd_r4;
uint8_t status, indx_cntl;
uint8_t cursor_array,
cursor_hotspot_x, cursor_hotspot_y;
uint8_t status;
uint8_t indx_cntl;
uint8_t cursor_array;
uint8_t cursor_hotspot_x;
uint8_t cursor_hotspot_y;
} ibm_rgb528_ramdac_t;
void
ibm_rgb528_render_4bpp(svga_t *svga)
{
uint32_t *p;
ibm_rgb528_pixel32_t dat_out;
uint8_t dat;
uint32_t dat32 = 0x00000000;
uint64_t dat64 = 0x0000000000000000ULL;
uint64_t dat642 = 0x0000000000000000ULL;
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6;
uint8_t partition = (ramdac->indexed_data[0x07] & 0x0f) << 4;
uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10;
uint8_t swap_nib = ramdac->indexed_data[0x72] & 0x21;
uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03;
uint32_t *p;
ibm_rgb528_pixel32_t dat_out;
uint8_t dat;
uint32_t dat32 = 0x00000000;
uint64_t dat64 = 0x0000000000000000ULL;
uint64_t dat642 = 0x0000000000000000ULL;
const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6;
uint8_t partition = (ramdac->indexed_data[0x07] & 0x0f) << 4;
uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10;
uint8_t swap_nib = ramdac->indexed_data[0x72] & 0x21;
uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03;
if ((svga->displine + svga->y_add) < 0)
return;
@@ -155,16 +168,16 @@ ibm_rgb528_render_4bpp(svga_t *svga)
void
ibm_rgb528_render_8bpp(svga_t *svga)
{
uint32_t *p;
ibm_rgb528_pixel32_t dat_out;
uint8_t dat;
uint32_t dat32 = 0x00000000;
uint64_t dat64 = 0x0000000000000000ULL;
uint64_t dat642 = 0x0000000000000000ULL;
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6;
uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10;
uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03;
uint32_t *p;
ibm_rgb528_pixel32_t dat_out;
uint8_t dat;
uint32_t dat32 = 0x00000000;
uint64_t dat64 = 0x0000000000000000ULL;
uint64_t dat642 = 0x0000000000000000ULL;
const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6;
uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10;
uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03;
if ((svga->displine + svga->y_add) < 0)
return;
@@ -224,24 +237,24 @@ ibm_rgb528_render_8bpp(svga_t *svga)
void
ibm_rgb528_render_15_16bpp(svga_t *svga)
{
uint32_t *p;
ibm_rgb528_pixel16_t *dat_ex;
ibm_rgb528_pixel32_t dat_out;
uint16_t dat;
uint32_t dat32 = 0x00000000;
uint64_t dat64 = 0x0000000000000000ULL;
uint64_t dat642 = 0x0000000000000000ULL;
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t b16_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6;
uint8_t by16_pol = ramdac->indexed_data[0x0c] & 0x20;
uint8_t b555_565 = ramdac->indexed_data[0x0c] & 0x02;
uint8_t bspr_cnt = ramdac->indexed_data[0x0c] & 0x01;
uint8_t partition = (ramdac->indexed_data[0x07] & 0x0e) << 4;
uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80;
uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80;
uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10;
uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01;
uint8_t temp;
uint32_t *p;
ibm_rgb528_pixel16_t *dat_ex;
ibm_rgb528_pixel32_t dat_out;
uint16_t dat;
uint32_t dat32 = 0x00000000;
uint64_t dat64 = 0x0000000000000000ULL;
uint64_t dat642 = 0x0000000000000000ULL;
const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t b16_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6;
uint8_t by16_pol = ramdac->indexed_data[0x0c] & 0x20;
uint8_t b555_565 = ramdac->indexed_data[0x0c] & 0x02;
uint8_t bspr_cnt = ramdac->indexed_data[0x0c] & 0x01;
uint8_t partition = (ramdac->indexed_data[0x07] & 0x0e) << 4;
uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80;
uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80;
uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10;
uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01;
uint8_t temp;
if ((svga->displine + svga->y_add) < 0)
return;
@@ -349,18 +362,18 @@ ibm_rgb528_render_15_16bpp(svga_t *svga)
void
ibm_rgb528_render_24bpp(svga_t *svga)
{
uint32_t *p;
ibm_rgb528_pixel32_t *dat_ex;
uint32_t dat;
uint64_t dat64[6];
uint8_t *dat8 = (uint8_t *) dat64;
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t b24_dcol = ramdac->indexed_data[0x0d] & 0x01;
uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80;
uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10;
uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01;
uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80;
uint8_t temp;
uint32_t *p;
ibm_rgb528_pixel32_t *dat_ex;
uint32_t dat;
uint64_t dat64[6];
uint8_t *dat8 = (uint8_t *) dat64;
const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t b24_dcol = ramdac->indexed_data[0x0d] & 0x01;
uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80;
uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10;
uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01;
uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80;
uint8_t temp;
if ((svga->displine + svga->y_add) < 0)
return;
@@ -438,19 +451,19 @@ ibm_rgb528_render_24bpp(svga_t *svga)
void
ibm_rgb528_render_32bpp(svga_t *svga)
{
uint32_t *p;
ibm_rgb528_pixel32_t *dat_ex;
uint32_t dat = 0x00000000;
uint64_t dat64 = 0x0000000000000000ULL;
uint64_t dat642 = 0x0000000000000000ULL;
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t b32_dcol = ramdac->indexed_data[0x0e] & 0x03;
uint8_t by32_pol = ramdac->indexed_data[0x0e] & 0x04;
uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80;
uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10;
uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01;
uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80;
uint8_t temp;
uint32_t *p;
ibm_rgb528_pixel32_t *dat_ex;
uint32_t dat = 0x00000000;
uint64_t dat64 = 0x0000000000000000ULL;
uint64_t dat642 = 0x0000000000000000ULL;
const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t b32_dcol = ramdac->indexed_data[0x0e] & 0x03;
uint8_t by32_pol = ramdac->indexed_data[0x0e] & 0x04;
uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80;
uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10;
uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01;
uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80;
uint8_t temp;
if ((svga->displine + svga->y_add) < 0)
return;
@@ -551,9 +564,9 @@ ibm_rgb528_set_bpp(ibm_rgb528_ramdac_t *ramdac, svga_t *svga)
}
void
ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga)
{
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p;
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv;
uint16_t index;
uint8_t rs = (addr & 0x03);
uint16_t da_mask = 0x03ff;
@@ -612,6 +625,9 @@ ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga
case 0xc0:
ramdac->smlc_part = 0x0400;
break;
default:
break;
}
svga->dac_hwcursor.addr = ramdac->smlc_part;
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = (val & 0x04) ? 64 : 32;
@@ -712,15 +728,18 @@ ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga
case 0x07:
ramdac->indx_cntl = val & 0x01;
break;
default:
break;
}
return;
}
uint8_t
ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga)
{
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p;
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv;
uint8_t temp = 0xff;
uint8_t rs = (addr & 0x03);
uint8_t loc_read = (ramdac->indexed_data[0x30] & 0x10);
@@ -781,15 +800,18 @@ ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
case 0x07:
temp = ramdac->indx_cntl;
break;
default:
break;
}
return temp;
}
void
ibm_rgb528_recalctimings(void *p, svga_t *svga)
ibm_rgb528_recalctimings(void *priv, svga_t *svga)
{
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p;
const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv;
svga->interlace = ramdac->indexed_data[0x071] & 0x20;
@@ -814,6 +836,9 @@ ibm_rgb528_recalctimings(void *p, svga_t *svga)
case 32:
svga->render = ibm_rgb528_render_32bpp;
break;
default:
break;
}
}
}
@@ -824,16 +849,16 @@ ibm_rgb528_recalctimings(void *p, svga_t *svga)
void
ibm_rgb528_hwcursor_draw(svga_t *svga, int displine)
{
uint8_t dat;
uint8_t four_pixels = 0x00;
int pitch;
int x_pos;
int y_pos;
int offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff;
uint32_t *p;
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t pix_ordr = ramdac->indexed_data[0x30] & 0x20;
uint8_t cursor_mode = ramdac->indexed_data[0x30] & 0x03;
uint8_t dat;
uint8_t four_pixels = 0x00;
int pitch;
int x_pos;
int y_pos;
int offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff;
uint32_t *p;
const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac;
uint8_t pix_ordr = ramdac->indexed_data[0x30] & 0x20;
uint8_t cursor_mode = ramdac->indexed_data[0x30] & 0x03;
/* The planes come in one part, and each plane is 2bpp,
so a 32x32 cursor has 8 bytes per line, and a 64x64
@@ -873,6 +898,9 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine)
/* Cursor Color 3 */
p[x_pos] = ramdac->extra_pal[2].pixel;
break;
default:
break;
}
break;
case 0x02:
@@ -889,6 +917,9 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine)
/* Complement */
p[x_pos] ^= 0xffffff;
break;
default:
break;
}
break;
case 0x03:
@@ -901,8 +932,14 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine)
/* Cursor Color 2 */
p[x_pos] = ramdac->extra_pal[1].pixel;
break;
default:
break;
}
break;
default:
break;
}
if ((x & 3) == 3)

View File

@@ -34,9 +34,12 @@
typedef struct icd2061_t {
float freq[3];
int count, bit_count,
unlocked, state;
uint32_t data, ctrl;
int count;
int bit_count;
int unlocked;
int state;
uint32_t data;
uint32_t ctrl;
} icd2061_t;
#ifdef ENABLE_ICD2061_LOG
@@ -58,9 +61,9 @@ icd2061_log(const char *fmt, ...)
#endif
void
icd2061_write(void *p, int val)
icd2061_write(void *priv, int val)
{
icd2061_t *icd2061 = (icd2061_t *) p;
icd2061_t *icd2061 = (icd2061_t *) priv;
int nd;
int oc;
@@ -138,7 +141,7 @@ icd2061_write(void *p, int val)
float
icd2061_getclock(int clock, void *priv)
{
icd2061_t *icd2061 = (icd2061_t *) priv;
const icd2061_t *icd2061 = (icd2061_t *) priv;
if (clock > 2)
clock = 2;

View File

@@ -51,7 +51,7 @@ ics2494_log(const char *fmt, ...)
float
ics2494_getclock(int clock, void *priv)
{
ics2494_t *ics2494 = (ics2494_t *) priv;
const ics2494_t *ics2494 = (ics2494_t *) priv;
if (clock > 15)
clock = 15;
@@ -66,6 +66,63 @@ ics2494_init(const device_t *info)
memset(ics2494, 0, sizeof(ics2494_t));
switch (info->local) {
case 10:
/* ATI 18810 for ATI 28800 */
ics2494->freq[0x0] = 30240000.0;
ics2494->freq[0x1] = 32000000.0;
ics2494->freq[0x2] = 37500000.0;
ics2494->freq[0x3] = 39000000.0;
ics2494->freq[0x4] = 42954000.0;
ics2494->freq[0x5] = 48771000.0;
ics2494->freq[0x6] = 16657000.0;
ics2494->freq[0x7] = 36000000.0;
ics2494->freq[0x8] = 40000000.0;
ics2494->freq[0x9] = 56644000.0;
ics2494->freq[0xa] = 75000000.0;
ics2494->freq[0xb] = 65000000.0;
ics2494->freq[0xc] = 50350000.0;
ics2494->freq[0xd] = 56640000.0;
ics2494->freq[0xe] = 28322000.0;
ics2494->freq[0xf] = 44900000.0;
break;
case 110:
/* ATI 18811-0 for ATI Mach32 */
ics2494->freq[0x0] = 30240000.0;
ics2494->freq[0x1] = 32000000.0;
ics2494->freq[0x2] = 110000000.0;
ics2494->freq[0x3] = 80000000.0;
ics2494->freq[0x4] = 42954000.0;
ics2494->freq[0x5] = 48771000.0;
ics2494->freq[0x6] = 92400000.0;
ics2494->freq[0x7] = 36000000.0;
ics2494->freq[0x8] = 39910000.0;
ics2494->freq[0x9] = 44900000.0;
ics2494->freq[0xa] = 75000000.0;
ics2494->freq[0xb] = 65000000.0;
ics2494->freq[0xc] = 50350000.0;
ics2494->freq[0xd] = 56640000.0;
ics2494->freq[0xe] = 0.0;
ics2494->freq[0xf] = 44900000.0;
break;
case 111:
/* ATI 18811-1 for ATI Mach32 MCA */
ics2494->freq[0x0] = 135000000.0;
ics2494->freq[0x1] = 32000000.0;
ics2494->freq[0x2] = 110000000.0;
ics2494->freq[0x3] = 80000000.0;
ics2494->freq[0x4] = 100000000.0;
ics2494->freq[0x5] = 126000000.0;
ics2494->freq[0x6] = 92400000.0;
ics2494->freq[0x7] = 36000000.0;
ics2494->freq[0x8] = 39910000.0;
ics2494->freq[0x9] = 44900000.0;
ics2494->freq[0xa] = 75000000.0;
ics2494->freq[0xb] = 65000000.0;
ics2494->freq[0xc] = 50350000.0;
ics2494->freq[0xd] = 56640000.0;
ics2494->freq[0xe] = 0.0;
ics2494->freq[0xf] = 44900000.0;
break;
case 305:
/* ICS2494A(N)-205 for S3 86C924 */
ics2494->freq[0x0] = 25175000.0;
@@ -85,6 +142,9 @@ ics2494_init(const device_t *info)
ics2494->freq[0xe] = 75000000.0;
ics2494->freq[0xf] = 94500000.0;
break;
default:
break;
}
return ics2494;
@@ -112,3 +172,45 @@ const device_t ics2494an_305_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t ati18810_device = {
.name = "ATI 18810 Clock Generator",
.internal_name = "ati18810",
.flags = 0,
.local = 10,
.init = ics2494_init,
.close = ics2494_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t ati18811_0_device = {
.name = "ATI 18811-0 Clock Generator",
.internal_name = "ati18811_0",
.flags = 0,
.local = 110,
.init = ics2494_init,
.close = ics2494_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t ati18811_1_device = {
.name = "ATI 18811-1 Clock Generator",
.internal_name = "ati18811_1",
.flags = 0,
.local = 111,
.init = ics2494_init,
.close = ics2494_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -26,9 +26,11 @@
#include <86box/plat_unused.h>
typedef struct ics2595_t {
int oldfs3, oldfs2;
int oldfs3;
int oldfs2;
int dat;
int pos, state;
int pos;
int state;
double clocks[16];
double output_clock;
@@ -43,9 +45,9 @@ enum {
static int ics2595_div[4] = { 8, 4, 2, 1 };
void
ics2595_write(void *p, int strobe, int dat)
ics2595_write(void *priv, int strobe, int dat)
{
ics2595_t *ics2595 = (ics2595_t *) p;
ics2595_t *ics2595 = (ics2595_t *) priv;
int d;
int n;
int l;
@@ -88,6 +90,7 @@ static void *
ics2595_init(UNUSED(const device_t *info))
{
ics2595_t *ics2595 = (ics2595_t *) malloc(sizeof(ics2595_t));
memset(ics2595, 0, sizeof(ics2595_t));
return ics2595;
@@ -105,15 +108,15 @@ ics2595_close(void *priv)
double
ics2595_getclock(void *priv)
{
ics2595_t *ics2595 = (ics2595_t *) priv;
const ics2595_t *ics2595 = (ics2595_t *) priv;
return ics2595->output_clock;
}
void
ics2595_setclock(void *p, double clock)
ics2595_setclock(void *priv, double clock)
{
ics2595_t *ics2595 = (ics2595_t *) p;
ics2595_t *ics2595 = (ics2595_t *) priv;
ics2595->output_clock = clock;
}

View File

@@ -763,15 +763,15 @@ hndl_tsize(pgc_t *pgc)
static void
hndl_twrite(pgc_t *pgc)
{
uint8_t buf[256];
im1024_t *dev = (im1024_t *) pgc;
uint8_t count;
uint8_t mask;
uint8_t *row;
int wb;
int n;
int16_t x0 = pgc->x >> 16;
int16_t y0 = pgc->y >> 16;
uint8_t buf[256];
const im1024_t *dev = (im1024_t *) pgc;
uint8_t count;
uint8_t mask;
const uint8_t *row;
int wb;
int n;
int16_t x0 = pgc->x >> 16;
int16_t y0 = pgc->y >> 16;
if (!pgc_param_byte(pgc, &count))
return;
@@ -811,13 +811,13 @@ hndl_twrite(pgc_t *pgc)
static void
hndl_txt88(pgc_t *pgc)
{
uint8_t buf[256];
uint8_t count;
uint8_t mask;
uint8_t *row;
int16_t x0 = pgc->x >> 16;
int16_t y0 = pgc->y >> 16;
unsigned n;
uint8_t buf[256];
uint8_t count;
uint8_t mask;
const uint8_t *row;
int16_t x0 = pgc->x >> 16;
int16_t y0 = pgc->y >> 16;
unsigned int n;
if (!pgc_param_byte(pgc, &count))
return;
@@ -1085,7 +1085,7 @@ im1024_speed_changed(void *priv)
const device_t im1024_device = {
.name = "ImageManager 1024",
.internal_name = "im1024",
.flags = DEVICE_ISA | DEVICE_AT,
.flags = DEVICE_ISA,
.local = 0,
.init = im1024_init,
.close = im1024_close,

View File

@@ -252,6 +252,9 @@ incolor_out(uint16_t port, uint8_t val, void *priv)
else
mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000);
return;
default:
break;
}
}
@@ -354,6 +357,9 @@ incolor_write(uint32_t addr, uint8_t val, void *priv)
else
w = ((~latch) & vmask);
break;
default:
break;
}
/* w is nonzero to write a 1, zero to write a 0 */
@@ -749,8 +755,8 @@ text_line(incolor_t *dev, uint16_t ca)
for (uint8_t x = 0; x < dev->crtc[1]; x++) {
if (dev->ctrl & 8) {
chr = dev->vram[(dev->ma << 1) & 0xfff];
attr = dev->vram[((dev->ma << 1) + 1) & 0xfff];
chr = dev->vram[(dev->ma << 1) & 0x3fff];
attr = dev->vram[((dev->ma << 1) + 1) & 0x3fff];
} else
chr = attr = 0;
@@ -769,6 +775,9 @@ text_line(incolor_t *dev, uint16_t ca)
case 5: /* 48k RAMfont */
draw_char_ram48(dev, x, chr, attr);
break;
default:
break;
}
++dev->ma;
@@ -850,6 +859,7 @@ incolor_poll(void *priv)
int x;
int oldvc;
int oldsc;
int cw = INCOLOR_CW;
if (!dev->linepos) {
timer_advance_u64(&dev->timer, dev->dispofftime);
@@ -931,7 +941,7 @@ incolor_poll(void *priv)
if ((dev->ctrl & INCOLOR_CTRL_GRAPH) && (dev->ctrl2 & INCOLOR_CTRL2_GRAPH))
x = dev->crtc[1] << 4;
else
x = dev->crtc[1] * 9;
x = dev->crtc[1] * cw;
dev->lastline++;
if ((dev->ctrl & 8) && ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) {
xsize = x;

View File

@@ -165,9 +165,9 @@ mda_poll(void *priv)
buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1];
} else {
for (c = 0; c < 8; c++)
buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0];
buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr + mda->fontbase][mda->sc] & (1 << (c ^ 7))) ? 1 : 0];
if ((chr & ~0x1f) == 0xc0)
buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1];
buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr + mda->fontbase][mda->sc] & 1];
else
buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0];
}

File diff suppressed because it is too large Load Diff

View File

@@ -38,11 +38,11 @@
#define BIOS_077_PATH "roms/video/oti/oti077.vbi"
enum {
OTI_037C,
OTI_067 = 2,
OTI_067_AMA932J,
OTI_067_M300 = 4,
OTI_077 = 5
OTI_037C = 0,
OTI_067 = 2,
OTI_067_AMA932J = 3,
OTI_067_M300 = 4,
OTI_077 = 5
};
typedef struct {
@@ -84,8 +84,9 @@ oti_out(uint16_t addr, uint8_t val, void *priv)
if (!oti->chip_id) {
oti->enable_register = val & 1;
return;
} else
break;
}
svga_out(addr, val, svga);
return;
case 0x3c6:
case 0x3c7:
@@ -156,8 +157,8 @@ oti_out(uint16_t addr, uint8_t val, void *priv)
svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff;
switch ((val & 0xc0) >> 6) {
case 0x00: /* 256 kB of memory */
default:
case 0x00: /* 256 kB of memory */
enable = (oti->vram_size >= 256);
if (val & 0x0c)
svga->vram_display_mask = MIN(oti->vram_mask, 0x3ffff);
@@ -191,8 +192,14 @@ oti_out(uint16_t addr, uint8_t val, void *priv)
svga->read_bank = (val & 0xf) * 65536;
svga->write_bank = (val >> 4) * 65536;
break;
default:
break;
}
return;
default:
break;
}
svga_out(addr, val, svga);
@@ -290,6 +297,9 @@ oti_in(uint16_t addr, void *priv)
if (svga->attrregs[0x11] & 0x80)
svga->cgastat |= 0x20;
break;
default:
break;
}
temp = svga->cgastat;
break;
@@ -338,7 +348,7 @@ oti_pos_out(UNUSED(uint16_t addr), uint8_t val, void *priv)
static uint8_t
oti_pos_in(UNUSED(uint16_t addr), void *priv)
{
oti_t *oti = (oti_t *) priv;
const oti_t *oti = (oti_t *) priv;
return (oti->pos);
}
@@ -349,8 +359,8 @@ oti_getclock(int clock)
float ret = 0.0;
switch (clock) {
case 0:
default:
case 0:
ret = 25175000.0;
break;
case 1:
@@ -373,8 +383,8 @@ oti_getclock(int clock)
static void
oti_recalctimings(svga_t *svga)
{
oti_t *oti = (oti_t *) svga->priv;
int clk_sel = ((svga->miscout >> 2) & 3) | ((oti->regs[0x0d] & 0x20) >> 3);
const oti_t *oti = (oti_t *) svga->priv;
int clk_sel = ((svga->miscout >> 2) & 3) | ((oti->regs[0x0d] & 0x20) >> 3);
svga->clock = (cpuclock * (double) (1ULL << 32)) / oti_getclock(clk_sel);
@@ -409,8 +419,8 @@ oti_recalctimings(svga_t *svga)
static void *
oti_init(const device_t *info)
{
oti_t *oti = malloc(sizeof(oti_t));
char *romfn = NULL;
oti_t *oti = malloc(sizeof(oti_t));
const char *romfn = NULL;
memset(oti, 0x00, sizeof(oti_t));
oti->chip_id = info->local;
@@ -422,8 +432,10 @@ oti_init(const device_t *info)
romfn = BIOS_037C_PATH;
oti->vram_size = 256;
oti->regs[0] = 0x08; /* FIXME: The BIOS wants to read this at index 0? This index is undocumented. */
/* io_sethandler(0x03c0, 32,
oti_in, NULL, NULL, oti_out, NULL, NULL, oti); */
#if 0
io_sethandler(0x03c0, 32,
oti_in, NULL, NULL, oti_out, NULL, NULL, oti);
#endif
break;
case OTI_067_AMA932J:
@@ -452,6 +464,9 @@ oti_init(const device_t *info)
oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
break;
default:
break;
}
if (romfn != NULL) {

View File

@@ -84,9 +84,10 @@ ogc_out(uint16_t addr, uint8_t val, void *priv)
{
ogc_t *ogc = (ogc_t *) priv;
// if (addr >= 0x3c0 && addr <= 0x3cf){
// addr = addr + 16;
// }
#if 0
if (addr >= 0x3c0 && addr <= 0x3cf)
addr = addr + 16;
#endif
switch (addr) {
case 0x3d4:
@@ -102,6 +103,9 @@ ogc_out(uint16_t addr, uint8_t val, void *priv)
/* select 1st or 2nd 16k vram block to be used */
ogc->base = (val & 0x08) ? 0x4000 : 0;
break;
default:
break;
}
}
@@ -110,9 +114,10 @@ ogc_in(uint16_t addr, void *priv)
{
ogc_t *ogc = (ogc_t *) priv;
// if (addr >= 0x3c0 && addr <= 0x3cf){
// addr = addr + 16;
// }
#if 0
if (addr >= 0x3c0 && addr <= 0x3cf)
addr = addr + 16;
#endif
uint8_t ret = 0xff;
@@ -133,8 +138,11 @@ ogc_in(uint16_t addr, void *priv)
ret = ret | 0xe0;
if (ogc->mono_display)
ret = ret | 0x10;
break;
}
break;
default:
break;
}
return ret;
@@ -513,7 +521,7 @@ ogc_poll(void *priv)
if (ogc->cga.cgadispon)
ogc->cga.cgastat &= ~1;
if ((ogc->cga.sc == (ogc->cga.crtc[10] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[10] & 31) >> 1))))
if (ogc->cga.sc == (ogc->cga.crtc[10] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[10] & 31) >> 1)))
ogc->cga.con = 1;
}
/* 80-columns */
@@ -575,7 +583,9 @@ ogc_mdaattr_rebuild(void)
void *
ogc_init(UNUSED(const device_t *info))
{
// int display_type;
#if 0
int display_type;
#endif
ogc_t *ogc = (ogc_t *) malloc(sizeof(ogc_t));
memset(ogc, 0x00, sizeof(ogc_t));
@@ -583,8 +593,10 @@ ogc_init(UNUSED(const device_t *info))
loadfont("roms/video/ogc/ogc graphics board go380 258 pqbq.bin", 1);
/* composite is not working yet */
// display_type = device_get_config_int("display_type");
/* FIXME: composite is not working yet */
#if 0
display_type = device_get_config_int("display_type");
#endif
ogc->cga.composite = 0; // (display_type != CGA_RGB);
ogc->cga.revision = device_get_config_int("composite_type");
ogc->cga.snow_enabled = device_get_config_int("snow_enabled");

View File

@@ -119,6 +119,9 @@ paradise_in(uint16_t addr, void *priv)
case 0x0f:
return (svga->gdcreg[0x0f] & 0x17) | 0x80;
default:
break;
}
break;
@@ -130,6 +133,9 @@ paradise_in(uint16_t addr, void *priv)
if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80)
return 0xff;
return svga->crtc[svga->crtcreg];
default:
break;
}
return svga_in(addr, svga);
}
@@ -198,6 +204,9 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
svga->banked_mask = 0x7fff;
break;
default:
break;
}
}
svga->gdcreg[6] = val;
@@ -213,6 +222,9 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
svga->gdcreg[0x0b] = val;
paradise_remap(paradise);
return;
default:
break;
}
break;
@@ -254,6 +266,9 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
mem_mapping_enable(&paradise->svga.mapping);
}
break;
default:
break;
}
svga_out(addr, val, svga);
@@ -262,7 +277,8 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
void
paradise_remap(paradise_t *paradise)
{
svga_t *svga = &paradise->svga;
const svga_t *svga = &paradise->svga;
paradise->check = 0;
if (svga->seqregs[0x11] & 0x80) {
@@ -301,7 +317,7 @@ paradise_remap(paradise_t *paradise)
void
paradise_recalctimings(svga_t *svga)
{
paradise_t *paradise = (paradise_t *) svga->priv;
const paradise_t *paradise = (paradise_t *) svga->priv;
svga->lowres = !(svga->gdcreg[0x0e] & 0x01);
@@ -325,23 +341,44 @@ paradise_recalctimings(svga_t *svga)
}
}
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
svga->interlace = 0;
}
if (paradise->type < WD90C30) {
if (svga->bpp >= 8 && !svga->lowres) {
if ((svga->bpp >= 8) && !svga->lowres) {
svga->render = svga_render_8bpp_highres;
}
} else {
if (svga->bpp >= 8 && !svga->lowres) {
if ((svga->bpp >= 8) && !svga->lowres) {
if (svga->bpp == 16) {
svga->render = svga_render_16bpp_highres;
svga->hdisp >>= 1;
if (svga->hdisp == 788)
svga->hdisp += 12;
if (svga->hdisp == 800)
svga->ma_latch -= 3;
} else if (svga->bpp == 15) {
svga->render = svga_render_15bpp_highres;
svga->hdisp >>= 1;
if (svga->hdisp == 788)
svga->hdisp += 12;
if (svga->hdisp == 800)
svga->ma_latch -= 3;
} else {
svga->render = svga_render_8bpp_highres;
}
}
}
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->hdisp == 360)
svga->hdisp <<= 1;
if (svga->seqregs[1] & 8) {
svga->render = svga_render_text_40;
} else
svga->render = svga_render_text_80;
}
}
static void
@@ -583,6 +620,9 @@ paradise_init(const device_t *info, uint32_t memsize)
svga->decode_mask = memsize - 1;
svga->ramdac = device_add(&sc11487_ramdac_device); /*Actually a Winbond W82c487-80, probably a clone.*/
break;
default:
break;
}
mem_mapping_set_handler(&svga->mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL);
@@ -607,6 +647,9 @@ paradise_init(const device_t *info, uint32_t memsize)
svga->crtc[0x36] = '3';
svga->crtc[0x37] = '0';
break;
default:
break;
}
svga->bpp = 8;

View File

@@ -682,7 +682,7 @@ pgc_write_pixel(pgc_t *dev, uint16_t x, uint16_t y, uint8_t ink)
uint8_t
pgc_read_pixel(pgc_t *dev, uint16_t x, uint16_t y)
{
uint8_t *vram;
const uint8_t *vram;
/* Suppress out-of-range reads. */
if (x >= dev->maxw || y >= dev->maxh)
@@ -747,7 +747,7 @@ pgc_plot(pgc_t *dev, uint16_t x, uint16_t y)
* Draw a line (using raster coordinates).
*
* Bresenham's Algorithm from:
* <https://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C>
* <https://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C>
*
* The line pattern mask to use is passed in. Return value is the
* line pattern mask, rotated by the number of points drawn.
@@ -1384,11 +1384,11 @@ hndl_window(pgc_t *dev)
* core commands (listed below) and subclass commands (listed in the clone).
*
* Each row has five parameters:
* ASCII-mode command
* Hex-mode command
* Function that executes this command
* Function that parses this command when building a command list
* Parameter for the parse function
* ASCII-mode command
* Hex-mode command
* Function that executes this command
* Function that parses this command when building a command list
* Parameter for the parse function
*
* TODO: This list omits numerous commands present in a genuine PGC
* (ARC, AREA, AREABC, BUFFER, CIRCLE etc etc).
@@ -2196,6 +2196,9 @@ pgc_out(uint16_t addr, uint8_t val, void *priv)
case 0x03d9: /* CRTC Color Select register */
dev->mapram[0x03d9] = val;
break;
default:
break;
}
}
@@ -2203,8 +2206,8 @@ pgc_out(uint16_t addr, uint8_t val, void *priv)
uint8_t
pgc_in(uint16_t addr, void *priv)
{
pgc_t *dev = (pgc_t *) priv;
uint8_t ret = 0xff;
const pgc_t *dev = (pgc_t *) priv;
uint8_t ret = 0xff;
switch (addr) {
case 0x03d0: /* CRTC Index register */
@@ -2233,6 +2236,9 @@ pgc_in(uint16_t addr, void *priv)
case 0x03da: /* CRTC Status register */
ret = dev->mapram[0x03da];
break;
default:
break;
}
pgc_log("PGC: in(%04x) = %02x\n", addr, ret);
@@ -2296,6 +2302,9 @@ pgc_write(uint32_t addr, uint8_t val, void *priv)
case 0x3ff: /* reboot the PGC */
pgc_wake(dev);
break;
default:
break;
}
}
}
@@ -2310,8 +2319,8 @@ pgc_write(uint32_t addr, uint8_t val, void *priv)
uint8_t
pgc_read(uint32_t addr, void *priv)
{
pgc_t *dev = (pgc_t *) priv;
uint8_t ret = 0xff;
const pgc_t *dev = (pgc_t *) priv;
uint8_t ret = 0xff;
if (addr >= 0xc6000 && addr < 0xc6800) {
addr &= 0x7ff;
@@ -2328,17 +2337,17 @@ pgc_read(uint32_t addr, void *priv)
void
pgc_cga_text(pgc_t *dev, int w)
{
uint8_t chr;
uint8_t attr;
int drawcursor = 0;
uint32_t cols[2];
int pitch = (dev->mapram[0x3e9] + 1) * 2;
uint16_t sc = (dev->displine & 0x0f) % pitch;
uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
uint16_t ca = (dev->mapram[0x3ef] | (dev->mapram[0x3ee] << 8)) & 0x3fff;
uint8_t *addr;
uint32_t val;
int cw = (w == 80) ? 8 : 16;
uint8_t chr;
uint8_t attr;
int drawcursor = 0;
uint32_t cols[2];
int pitch = (dev->mapram[0x3e9] + 1) * 2;
uint16_t sc = (dev->displine & 0x0f) % pitch;
uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
uint16_t ca = (dev->mapram[0x3ef] | (dev->mapram[0x3ee] << 8)) & 0x3fff;
const uint8_t *addr;
uint32_t val;
int cw = (w == 80) ? 8 : 16;
addr = &dev->cga_vram[((ma + ((dev->displine / pitch) * w)) * 2) & 0x3ffe];
ma += (dev->displine / pitch) * w;
@@ -2384,11 +2393,11 @@ pgc_cga_text(pgc_t *dev, int w)
void
pgc_cga_gfx40(pgc_t *dev)
{
uint32_t cols[4];
int col;
uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
uint8_t *addr;
uint16_t dat;
uint32_t cols[4];
int col;
uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
const uint8_t *addr;
uint16_t dat;
cols[0] = (dev->mapram[0x3d9] & 15) + 16;
col = ((dev->mapram[0x3d9] & 16) ? 8 : 0) + 16;
@@ -2427,10 +2436,10 @@ pgc_cga_gfx40(pgc_t *dev)
void
pgc_cga_gfx80(pgc_t *dev)
{
uint32_t cols[2];
uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
uint8_t *addr;
uint16_t dat;
uint32_t cols[2];
uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
const uint8_t *addr;
uint16_t dat;
cols[0] = 16;
cols[1] = (dev->mapram[0x3d9] & 15) + 16;

View File

@@ -106,6 +106,9 @@ rtg_in(uint16_t addr, void *priv)
case 0x3d7:
return dev->bank3d7;
default:
break;
}
return svga_in(addr, svga);
@@ -140,6 +143,9 @@ rtg_out(uint16_t addr, uint8_t val, void *priv)
case 0x0f:
rtg_recalcbanking(dev);
return;
default:
break;
}
}
break;
@@ -163,6 +169,9 @@ rtg_out(uint16_t addr, uint8_t val, void *priv)
svga->fullchange = changeframecount;
svga_recalctimings(svga);
break;
default:
break;
}
}
@@ -188,6 +197,9 @@ rtg_out(uint16_t addr, uint8_t val, void *priv)
dev->bank3d7 = val;
rtg_recalcbanking(dev);
return;
default:
break;
}
svga_out(addr, val, svga);
@@ -226,6 +238,9 @@ rtg_recalctimings(svga_t *svga)
case 7:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 75000000.0;
break;
default:
break;
}
switch (svga->gdcreg[0x0c] & 3) {
@@ -238,6 +253,9 @@ rtg_recalctimings(svga_t *svga)
case 3:
svga->clock /= 4;
break;
default:
break;
}
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
@@ -281,6 +299,9 @@ rtg_recalctimings(svga_t *svga)
svga->render = svga_render_8bpp_highres;
}
break;
default:
break;
}
}
}
@@ -307,6 +328,9 @@ rtg_init(const device_t *info)
io_sethandler(0x03c0, 32,
rtg_in, NULL, NULL, rtg_out, NULL, NULL, dev);
break;
default:
break;
}
dev->svga.bpp = 8;
@@ -314,7 +338,7 @@ rtg_init(const device_t *info)
dev->vram_mask = dev->vram_size - 1;
rom_init(&dev->bios_rom, (char *) fn,
rom_init(&dev->bios_rom, fn,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
return dev;

File diff suppressed because it is too large Load Diff

View File

@@ -172,7 +172,9 @@ typedef struct virge_t {
uint32_t linear_base, linear_size;
uint8_t pci_regs[256];
int card;
uint8_t pci_slot;
uint8_t irq_state;
int pci;
int chip;
@@ -278,7 +280,6 @@ typedef struct virge_t {
uint32_t cmd_dma_base;
uint32_t dma_ptr;
uint64_t blitter_time;
volatile int fifo_slot;
int fifo_slots_num;
pc_timer_t tri_timer;
@@ -419,9 +420,9 @@ static void
s3_virge_update_irqs(virge_t *virge)
{
if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & (virge->subsys_cntl & INT_MASK)))
pci_set_irq(virge->card, PCI_INTA);
pci_set_irq(virge->pci_slot, PCI_INTA, &virge->irq_state);
else
pci_clear_irq(virge->card, PCI_INTA);
pci_clear_irq(virge->pci_slot, PCI_INTA, &virge->irq_state);
}
static void
@@ -574,6 +575,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv)
case 2:
virge->hwc_fg_col = (virge->hwc_fg_col & 0x00ffff) | (val << 16);
break;
default:
break;
}
virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3;
break;
@@ -588,6 +592,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv)
case 2:
virge->hwc_bg_col = (virge->hwc_bg_col & 0x00ffff) | (val << 16);
break;
default:
break;
}
virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3;
break;
@@ -634,6 +641,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv)
case 0xaa:
i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW));
break;
default:
break;
}
if (old != val) {
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
@@ -649,6 +659,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv)
}
}
break;
default:
break;
}
svga_out(addr, val, svga);
}
@@ -761,7 +774,7 @@ s3_virge_in(uint16_t addr, void *priv)
static void
s3_virge_recalctimings(svga_t *svga)
{
virge_t *virge = (virge_t *) svga->priv;
const virge_t *virge = (virge_t *) svga->priv;
svga->hdisp = svga->hdisp_old;
@@ -838,6 +851,9 @@ s3_virge_recalctimings(svga_t *svga)
case 32:
svga->render = svga_render_32bpp_highres;
break;
default:
break;
}
}
svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask;
@@ -884,6 +900,9 @@ s3_virge_recalctimings(svga_t *svga)
case 7: /*XRGB-32 (X.8.8.8)*/
svga->render = svga_render_32bpp_highres;
break;
default:
break;
}
svga->vram_display_mask = virge->vram_mask;
}
@@ -921,6 +940,9 @@ s3_virge_updatemapping(virge_t *virge)
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
svga->banked_mask = 0x7fff;
break;
default:
break;
}
virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
@@ -946,6 +968,9 @@ s3_virge_updatemapping(virge_t *virge)
case 7:
virge->linear_size = 0x800000;
break;
default:
break;
}
virge->linear_base &= ~(virge->linear_size - 1);
s3_virge_log("Linear framebuffer at %08X size %08X, mask = %08x, CRTC58 sel = %02x\n", virge->linear_base, virge->linear_size, virge->vram_mask, svga->crtc[0x58] & 7);
@@ -998,13 +1023,16 @@ s3_virge_vblank_start(svga_t *svga)
static void
s3_virge_mmio_fifo_write(uint32_t addr, uint8_t val, virge_t *virge)
{
if ((addr & 0xffff) < 0x8000) {
if ((addr & 0xffff) < 0x8000)
s3_virge_bitblt(virge, 8, val);
} else {
else {
switch (addr & 0xffff) {
case 0x859c:
virge->cmd_dma = val;
break;
default:
break;
}
}
}
@@ -1032,9 +1060,6 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge)
else
s3_virge_bitblt(virge, 32, val);
} else {
if (virge->fifo_slot >= virge->fifo_slots_num)
return;
virge->fifo_slot++;
switch (addr & 0xfffc) {
case 0x8590:
virge->cmd_dma_base = val;
@@ -1469,6 +1494,9 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge)
queue_triangle(virge);
}
break;
default:
break;
}
}
}
@@ -1482,25 +1510,25 @@ s3_virge_mmio_read(uint32_t addr, void *priv)
s3_virge_log("[%04X:%08X]: MMIO ReadB addr = %04x\n", CS, cpu_state.pc, addr & 0xffff);
switch (addr & 0xffff) {
case 0x8504:
virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP);
ret = virge->subsys_stat;
s3_virge_update_irqs(virge);
return ret;
case 0x8505:
ret = 0xc0;
if (!virge->s3d_busy && !virge->fifo_slot)
ret = 0xd0;
if (!virge->s3d_busy)
ret |= 0x20;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot);
return ret;
case 0x850c:
ret = virge->advfunc_cntl & 0x3f;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot) << 6;
ret |= virge->fifo_slots_num << 6;
ret &= 0xff;
break;
return ret;
case 0x850d:
ret = (virge->fifo_slots_num - virge->fifo_slot) >> 2;
break;
ret = virge->fifo_slots_num >> 2;
return ret;
case 0x83b0:
case 0x83b1:
@@ -1563,6 +1591,9 @@ s3_virge_mmio_read(uint32_t addr, void *priv)
if ((virge->serialport & SERIAL_PORT_SDW) && i2c_gpio_get_sda(virge->i2c))
ret |= SERIAL_PORT_SDR;
return ret;
default:
break;
}
return 0xff;
}
@@ -1576,24 +1607,18 @@ s3_virge_mmio_read_w(uint32_t addr, void *priv)
switch (addr & 0xfffe) {
case 0x8504:
ret = 0xc000;
if (!virge->s3d_busy && !virge->fifo_slot)
ret = 0xd000;
if (!virge->s3d_busy)
ret |= 0x2000;
if (!virge->fifo_slot)
virge->subsys_stat |= INT_FIFO_EMP;
virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP);
ret |= virge->subsys_stat;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot) << 8;
s3_virge_update_irqs(virge);
return ret;
case 0x850c:
ret = virge->advfunc_cntl & 0x3f;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot) << 6;
break;
ret |= virge->fifo_slots_num << 6;
return ret;
case 0x859c:
return virge->cmd_dma;
@@ -1682,26 +1707,17 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv)
break;
case 0x8504:
ret = 0x0000c000;
if (!virge->s3d_busy && !virge->fifo_slot) {
ret = 0x0000d000;
if (!virge->s3d_busy)
ret |= 0x00002000;
if (!virge->s3d_busy)
virge->subsys_stat |= INT_3DF_EMP;
if (!virge->fifo_slot)
virge->subsys_stat |= INT_FIFO_EMP;
}
virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP);
ret |= virge->subsys_stat;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot) << 8;
s3_virge_update_irqs(virge);
break;
case 0x850c:
ret = virge->advfunc_cntl & 0x3f;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot) << 6;
ret |= virge->fifo_slots_num << 6;
break;
case 0x8590:
@@ -1836,6 +1852,9 @@ s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv)
case 0x83df:
s3_virge_out(addr & 0x3ff, val, virge);
break;
default:
break;
}
}
}
@@ -1998,6 +2017,9 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
virge->advfunc_cntl = val & 0xff;
s3_virge_updatemapping(virge);
break;
default:
break;
}
}
}
@@ -2064,25 +2086,25 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
static void
s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
{
svga_t *svga = &virge->svga;
uint8_t *vram = virge->svga.vram;
uint32_t mono_pattern[64];
int count_mask;
int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1;
int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1;
int bpp;
int x_mul;
int cpu_dat_shift;
uint32_t *pattern_data;
uint32_t src_fg_clr;
uint32_t src_bg_clr;
uint32_t src_addr;
uint32_t dest_addr;
uint32_t source = 0;
uint32_t dest = 0;
uint32_t pattern;
uint32_t out = 0;
int update;
svga_t *svga = &virge->svga;
uint8_t *vram = virge->svga.vram;
uint32_t mono_pattern[64];
int count_mask;
int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1;
int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1;
int bpp;
int x_mul;
int cpu_dat_shift;
const uint32_t *pattern_data;
uint32_t src_fg_clr;
uint32_t src_bg_clr;
uint32_t src_addr;
uint32_t dest_addr;
uint32_t source = 0;
uint32_t dest = 0;
uint32_t pattern;
uint32_t out = 0;
int update;
switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) {
case CMD_SET_FORMAT_8:
@@ -2214,6 +2236,9 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
cpu_dat <<= 1;
count--;
break;
default:
break;
}
CLIP(virge->s3d.dest_x, virge->s3d.dest_y);
@@ -2250,6 +2275,9 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
cpu_dat <<= (count - (count & count_mask));
count &= count_mask;
break;
default:
break;
}
if (!virge->s3d.h) {
return;
@@ -2422,6 +2450,9 @@ skip_line:
case CMD_SET_COMMAND_NOP:
break;
default:
break;
}
}
@@ -3053,7 +3084,10 @@ dest_pixel_lit_texture_reflection(s3d_state_t *state)
static void
dest_pixel_lit_texture_modulate(s3d_state_t *state)
{
int r = state->r >> 7, g = state->g >> 7, b = state->b >> 7, a = state->a >> 7;
int r = state->r >> 7;
int g = state->g >> 7;
int b = state->b >> 7;
int a = state->a >> 7;
tex_sample(state);
@@ -3071,7 +3105,7 @@ static void
tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2)
{
svga_t *svga = &virge->svga;
uint8_t *vram = (uint8_t *) svga->vram;
uint8_t *vram = svga->vram;
int x_dir = s3d_tri->tlr ? 1 : -1;
@@ -3265,6 +3299,9 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int
case 7:
src_z = (z >> 16);
break;
default:
break;
}
}
@@ -3283,7 +3320,7 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int
if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) {
switch (bpp) {
case 0: /*8 bpp*/
/*Not implemented yet*/
/*TODO: Not implemented yet*/
break;
case 1: /*16 bpp*/
src_col = *(uint16_t *) &vram[dest_addr & virge->vram_mask];
@@ -3293,6 +3330,9 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int
src_col = (*(uint32_t *) &vram[dest_addr & virge->vram_mask]) & 0xffffff;
RGB24_TO_24(src_col, src_r, src_g, src_b);
break;
default:
break;
}
state->dest_rgba.r = ((state->dest_rgba.r * state->dest_rgba.a) + (src_r * (255 - state->dest_rgba.a))) / 255;
@@ -3302,7 +3342,7 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int
switch (bpp) {
case 0: /*8 bpp*/
/*Not implemented yet*/
/*TODO: Not implemented yet*/
break;
case 1: /*16 bpp*/
RGB15(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, dest_col);
@@ -3316,6 +3356,9 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int
*(uint8_t *) &vram[(dest_addr + 2) & virge->vram_mask] = (dest_col >> 16) & 0xff;
svga->changedvram[(dest_addr & virge->vram_mask) >> 12] = changeframecount;
break;
default:
break;
}
}
@@ -3482,6 +3525,9 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri)
else
tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal;
break;
default:
break;
}
switch ((s3d_tri->cmd_set >> 5) & 7) {
@@ -3515,13 +3561,13 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri)
static void
s3_virge_hwcursor_draw(svga_t *svga, int displine)
{
virge_t *virge = (virge_t *) svga->priv;
uint16_t dat[2];
int xx;
int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
uint32_t fg;
uint32_t bg;
uint32_t vram_mask = virge->vram_mask;
const virge_t *virge = (virge_t *) svga->priv;
uint16_t dat[2];
int xx;
int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
uint32_t fg;
uint32_t bg;
uint32_t vram_mask = virge->vram_mask;
if (svga->interlace && svga->hwcursor_oddeven)
svga->hwcursor_latch.addr += 16;
@@ -3533,9 +3579,7 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine)
bg = svga->pallook[virge->hwc_bg_col & 0xff];
break;
}
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 15:
if (virge->chip != S3_VIRGEGX2) {
@@ -3543,9 +3587,7 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine)
bg = video_15to32[virge->hwc_bg_col & 0xffff];
break;
}
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 16:
if (virge->chip != S3_VIRGEGX2) {
@@ -3553,9 +3595,7 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine)
bg = video_16to32[virge->hwc_bg_col & 0xffff];
break;
}
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 24:
case 32:
@@ -3818,17 +3858,17 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine)
static void
s3_virge_overlay_draw(svga_t *svga, int displine)
{
virge_t *virge = (virge_t *) svga->priv;
int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1;
int h_acc = virge->streams.dda_horiz_accumulator;
int r[8];
int g[8];
int b[8];
int x_size;
int x_read = 4;
int x_write = 4;
uint32_t *p;
uint8_t *src = &svga->vram[svga->overlay_latch.addr];
const virge_t *virge = (virge_t *) svga->priv;
int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1;
int h_acc = virge->streams.dda_horiz_accumulator;
int r[8];
int g[8];
int b[8];
int x_size;
int x_read = 4;
int x_write = 4;
uint32_t *p;
uint8_t *src = &svga->vram[svga->overlay_latch.addr];
p = &(buffer32->line[displine][offset + svga->x_add]);
@@ -3862,9 +3902,9 @@ s3_virge_overlay_draw(svga_t *svga, int displine)
static uint8_t
s3_virge_pci_read(UNUSED(int func), int addr, void *priv)
{
virge_t *virge = (virge_t *) priv;
svga_t *svga = &virge->svga;
uint8_t ret = 0;
const virge_t *virge = (virge_t *) priv;
const svga_t *svga = &virge->svga;
uint8_t ret = 0;
switch (addr) {
case 0x00:
@@ -4017,6 +4057,9 @@ s3_virge_pci_read(UNUSED(int func), int addr, void *priv)
case 0xe3:
ret = virge->pci_regs[0xe3];
break;
default:
break;
}
return ret;
}
@@ -4100,6 +4143,9 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
case 0xe2:
virge->pci_regs[0xe2] = val & 0xc0;
return;
default:
break;
}
}
@@ -4185,6 +4231,9 @@ s3_virge_reset(void *priv)
else
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5);
break;
default:
break;
}
if (virge->local == S3_VIRGE_GX)
virge->svga.crtc[0x36] |= (1 << 2);
@@ -4261,9 +4310,9 @@ s3_virge_init(const device_t *info)
if (bios_fn != NULL) {
if (info->local == S3_VIRGE_GX2)
rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
else
rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
}
mem_mapping_disable(&virge->bios_rom.mapping);
@@ -4360,9 +4409,7 @@ s3_virge_init(const device_t *info)
case S3_VIRGE_GX:
virge->virge_rev = 0x01;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
default:
virge->fifo_slots_num = 8;
@@ -4413,6 +4460,9 @@ s3_virge_init(const device_t *info)
else
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5);
break;
default:
break;
}
if (info->local == S3_VIRGE_GX)
virge->svga.crtc[0x36] |= (1 << 2);
@@ -4421,7 +4471,10 @@ s3_virge_init(const device_t *info)
virge->svga.crtc[0x37] = 1 | (7 << 5);
virge->svga.crtc[0x53] = 8;
virge->card = pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge);
if (bios_fn == NULL)
pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge, &virge->pci_slot);
else
pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_NORMAL, s3_virge_pci_read, s3_virge_pci_write, virge, &virge->pci_slot);
virge->i2c = i2c_gpio_init("ddc_s3_virge");
virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c));

View File

@@ -28,8 +28,7 @@
#include <86box/video.h>
#include <86box/vid_svga.h>
typedef struct
{
typedef struct sc1148x_ramdac_t {
int type;
int state;
int rs2;
@@ -37,9 +36,9 @@ typedef struct
} sc1148x_ramdac_t;
void
sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga)
{
sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p;
sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) priv;
uint8_t rs = (addr & 0x03) | ((!!rs2) << 2);
int oldbpp = 0;
@@ -72,6 +71,9 @@ sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
} else if (val == 0x00)
svga->bpp = 8;
break;
default:
break;
}
if (oldbpp != svga->bpp)
svga_recalctimings(svga);
@@ -90,9 +92,9 @@ sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
}
uint8_t
sc1148x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
sc1148x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga)
{
sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p;
sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) priv;
uint8_t ret = 0xff;
uint8_t rs = (addr & 0x03) | ((!!rs2) << 2);

View File

@@ -29,86 +29,138 @@
#include <86box/timer.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/plat_unused.h>
typedef struct
{
typedef struct sc1502x_ramdac_t {
int state;
uint8_t ctrl;
uint8_t idx;
uint8_t regs[256];
uint32_t pixel_mask;
uint8_t enable_ext;
} sc1502x_ramdac_t;
void
sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
static void
sc1502x_ramdac_bpp(uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga)
{
sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p;
int oldbpp = 0;
int oldbpp = 0;
if (val == 0xff)
return;
ramdac->ctrl = val;
oldbpp = svga->bpp;
switch ((val & 1) | ((val & 0xc0) >> 5)) {
case 0:
svga->bpp = 8;
break;
case 2:
case 3:
switch (val & 0x20) {
case 0x00:
svga->bpp = 32;
break;
case 0x20:
svga->bpp = 24;
break;
default:
break;
}
break;
case 4:
case 5:
svga->bpp = 15;
break;
case 6:
svga->bpp = 16;
break;
case 7:
if (val & 4) {
switch (val & 0x20) {
case 0x00:
svga->bpp = 32;
break;
case 0x20:
svga->bpp = 24;
break;
default:
break;
}
} else
svga->bpp = 16;
break;
default:
break;
}
if (oldbpp != svga->bpp)
svga_recalctimings(svga);
}
void
sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga)
{
sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv;
switch (addr) {
case 0x3C6:
if (ramdac->state == 0)
ramdac->enable_ext = (val == 0x10);
if (ramdac->state == 4) {
ramdac->state = 0;
if (val == 0xFF)
break;
ramdac->ctrl = val;
oldbpp = svga->bpp;
switch ((val & 1) | ((val & 0xc0) >> 5)) {
case 0:
svga->bpp = 8;
break;
case 2:
case 3:
switch (val & 0x20) {
case 0x00:
svga->bpp = 32;
break;
case 0x20:
svga->bpp = 24;
break;
}
break;
case 4:
case 5:
svga->bpp = 15;
break;
case 6:
svga->bpp = 16;
break;
case 7:
if (val & 4) {
switch (val & 0x20) {
case 0x00:
svga->bpp = 32;
break;
case 0x20:
svga->bpp = 24;
break;
}
break;
} else {
svga->bpp = 16;
break;
}
break;
}
if (oldbpp != svga->bpp)
svga_recalctimings(svga);
sc1502x_ramdac_bpp(val, ramdac, svga);
return;
}
ramdac->state = 0;
break;
case 0x3C7:
case 0x3C8:
case 0x3C9:
if (ramdac->enable_ext) {
ramdac->idx = val;
return;
}
ramdac->state = 0;
break;
case 0x3C8:
if (ramdac->enable_ext) {
switch (ramdac->idx) {
case 8:
ramdac->regs[ramdac->idx] = val;
svga_set_ramdac_type(svga, (ramdac->regs[ramdac->idx] & 1) ? RAMDAC_8BIT : RAMDAC_6BIT);
break;
case 0x0d:
ramdac->pixel_mask = val & svga->dac_mask;
break;
case 0x0e:
ramdac->pixel_mask |= ((val & svga->dac_mask) << 8);
break;
case 0x0f:
ramdac->pixel_mask |= ((val & svga->dac_mask) << 16);
break;
default:
ramdac->regs[ramdac->idx] = val;
break;
}
return;
}
ramdac->state = 0;
break;
case 0x3C9:
if (ramdac->enable_ext)
return;
ramdac->state = 0;
break;
}
default:
break;
}
svga_out(addr, val, svga);
}
uint8_t
sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga)
sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga)
{
sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p;
sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv;
uint8_t temp = svga_in(addr, svga);
switch (addr) {
@@ -121,21 +173,62 @@ sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga)
ramdac->state++;
break;
case 0x3C7:
case 0x3C8:
case 0x3C9:
ramdac->state = 0;
break;
case 0x3C8:
if (ramdac->enable_ext) {
switch (ramdac->idx) {
case 9:
temp = 0x53;
break;
case 0x0a:
temp = 0x3a;
break;
case 0x0b:
temp = 0xb1;
break;
case 0x0c:
temp = 0x41;
break;
case 0x0d:
temp = ramdac->pixel_mask & 0xff;
break;
case 0x0e:
temp = ramdac->pixel_mask >> 8;
break;
case 0x0f:
temp = ramdac->pixel_mask >> 16;
break;
default:
temp = ramdac->regs[ramdac->idx];
break;
}
} else
ramdac->state = 0;
break;
case 0x3C9:
if (ramdac->enable_ext)
temp = ramdac->idx;
else
ramdac->state = 0;
break;
default:
break;
}
return temp;
}
static void *
sc1502x_ramdac_init(const device_t *info)
sc1502x_ramdac_init(UNUSED(const device_t *info))
{
sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) malloc(sizeof(sc1502x_ramdac_t));
memset(ramdac, 0, sizeof(sc1502x_ramdac_t));
ramdac->ctrl = 0;
ramdac->pixel_mask = 0xffffff;
return ramdac;
}

View File

@@ -44,10 +44,13 @@ enum {
typedef struct sdac_ramdac_t {
uint16_t regs[256];
int magic_count,
windex, rindex,
reg_ff, rs2;
uint8_t type, command;
int magic_count;
int windex;
int rindex;
int reg_ff;
int rs2;
uint8_t type;
uint8_t command;
} sdac_ramdac_t;
static void
@@ -59,8 +62,8 @@ sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val)
case ICS_5300:
case ICS_5301:
switch (val >> 5) {
case 0x00:
default:
case 0x00:
svga->bpp = 8;
break;
case 0x01:
@@ -82,9 +85,9 @@ sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val)
case ICS_5341:
case ICS_5342:
switch (val >> 4) {
default:
case 0x00:
case 0x01: /* This is actually 8bpp with two pixels read at a time. */
default:
svga->bpp = 8;
break;
case 0x02:
@@ -108,6 +111,9 @@ sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val)
break;
}
break;
default:
break;
}
svga_recalctimings(svga);
@@ -144,9 +150,9 @@ sdac_reg_read(sdac_ramdac_t *ramdac, int reg)
}
void
sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga)
{
sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p;
sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv;
uint8_t rs = (addr & 0x03);
rs |= ((!!rs2) << 2);
@@ -184,13 +190,16 @@ sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
ramdac->rindex = val;
ramdac->reg_ff = 0;
break;
default:
break;
}
}
uint8_t
sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
sdac_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga)
{
sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p;
sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv;
uint8_t temp = 0xff;
uint8_t rs = (addr & 0x03);
rs |= ((!!rs2) << 2);
@@ -237,6 +246,9 @@ sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
case 0x07:
temp = ramdac->rindex;
break;
default:
break;
}
return temp;
@@ -245,11 +257,11 @@ sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
float
sdac_getclock(int clock, void *priv)
{
sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv;
float t;
int m;
int n1;
int n2;
const sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv;
float t;
int m;
int n1;
int n2;
if (ramdac->regs[0xe] & (1 << 5))
clock = ramdac->regs[0xe] & 7;

View File

@@ -29,6 +29,7 @@
#include <86box/rom.h>
#include <86box/device.h>
#include <86box/video.h>
#include <86box/plat_unused.h>
#define ROM_SIGMA_FONT "roms/video/sigma/sigma400_font.rom"
#define ROM_SIGMA_BIOS "roms/video/sigma/sigma400_bios.rom"
@@ -109,8 +110,8 @@
* 0x2DC: On write: Resets the NMI.
* 0x2DD: Memory paging. The memory from 0xC1800 to 0xC1FFF can be either:
*
* > ROM: A 128 character 8x16 font for use in graphics modes
* > RAM: Use by the video BIOS to hold its settings.
* > ROM: A 128 character 8x16 font for use in graphics modes
* > RAM: Use by the video BIOS to hold its settings.
*
* Reading port 2DD switches to ROM. Bit 7 of the value read gives the
* previous paging state: bit 7 set if ROM was paged, clear if RAM was
@@ -256,6 +257,9 @@ sigma_out(uint16_t addr, uint8_t val, void *priv)
else
sigma->plane = val & 3;
return;
default:
break;
}
}
@@ -326,6 +330,9 @@ sigma_in(uint16_t addr, void *priv)
result = sigma->fake_stat;
}
break;
default:
break;
}
return result;
@@ -343,9 +350,10 @@ sigma_write(uint32_t addr, uint8_t val, void *priv)
static uint8_t
sigma_read(uint32_t addr, void *priv)
{
sigma_t *sigma = (sigma_t *) priv;
const sigma_t *sigma = (sigma_t *) priv;
cycles -= 4;
return sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)];
}
@@ -364,8 +372,8 @@ sigma_bwrite(uint32_t addr, uint8_t val, void *priv)
static uint8_t
sigma_bread(uint32_t addr, void *priv)
{
sigma_t *sigma = (sigma_t *) priv;
uint8_t result;
const sigma_t *sigma = (sigma_t *) priv;
uint8_t result;
addr &= 0x3FFF;
if (addr >= 0x2000)
@@ -404,13 +412,13 @@ sigma_recalctimings(sigma_t *sigma)
static void
sigma_text80(sigma_t *sigma)
{
uint8_t chr;
uint8_t attr;
uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8));
uint16_t ma = ((sigma->ma & 0x3FFF) << 1);
int drawcursor;
uint32_t cols[4];
uint8_t *vram = sigma->vram + (ma << 1);
uint8_t chr;
uint8_t attr;
uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8));
uint16_t ma = ((sigma->ma & 0x3FFF) << 1);
int drawcursor;
uint32_t cols[4];
const uint8_t *vram = sigma->vram + (ma << 1);
ca = ca << 1;
if (sigma->sigma_ctl & CTL_CURSOR)
@@ -459,13 +467,13 @@ sigma_text80(sigma_t *sigma)
static void
sigma_text40(sigma_t *sigma)
{
uint8_t chr;
uint8_t attr;
uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8));
uint16_t ma = ((sigma->ma & 0x3FFF) << 1);
int drawcursor;
uint32_t cols[4];
uint8_t *vram = sigma->vram + ((ma << 1) & 0x3FFF);
uint8_t chr;
uint8_t attr;
uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8));
uint16_t ma = ((sigma->ma & 0x3FFF) << 1);
int drawcursor;
uint32_t cols[4];
const uint8_t *vram = sigma->vram + ((ma << 1) & 0x3FFF);
ca = ca << 1;
if (sigma->sigma_ctl & CTL_CURSOR)
@@ -508,7 +516,7 @@ sigma_text40(sigma_t *sigma)
static void
sigma_gfx400(sigma_t *sigma)
{
unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 3) * 0x2000];
const uint8_t *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 3) * 0x2000];
uint8_t plane[4];
uint8_t col;
@@ -536,7 +544,7 @@ sigma_gfx400(sigma_t *sigma)
static void
sigma_gfx200(sigma_t *sigma)
{
unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000];
const uint8_t *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000];
uint8_t plane[4];
uint8_t col;
@@ -561,7 +569,7 @@ sigma_gfx200(sigma_t *sigma)
static void
sigma_gfx4col(sigma_t *sigma)
{
unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000];
const uint8_t *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000];
uint8_t plane[4];
uint8_t mask;
uint8_t col;
@@ -772,12 +780,12 @@ sigma_poll(void *priv)
}
}
static void
*
sigma_init(const device_t *info)
static void *
sigma_init(UNUSED(const device_t *info))
{
int bios_addr;
sigma_t *sigma = malloc(sizeof(sigma_t));
memset(sigma, 0, sizeof(sigma_t));
bios_addr = device_get_config_hex20("bios_addr");

View File

@@ -27,6 +27,7 @@
#include <86box/timer.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/plat_unused.h>
typedef struct stg_ramdac_t {
int magic_count, index;
@@ -45,10 +46,10 @@ stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac)
{
if (ramdac->command & 0x8) {
switch (ramdac->regs[3]) {
default:
case 0:
case 5:
case 7:
default:
svga->bpp = 8;
break;
case 1:
@@ -67,8 +68,8 @@ stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac)
}
} else {
switch (ramdac->command >> 5) {
case 0:
default:
case 0:
svga->bpp = 8;
break;
case 5:
@@ -87,9 +88,9 @@ stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac)
}
void
stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
stg_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga)
{
stg_ramdac_t *ramdac = (stg_ramdac_t *) p;
stg_ramdac_t *ramdac = (stg_ramdac_t *) priv;
int didwrite;
int old;
@@ -125,6 +126,9 @@ stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
stg_ramdac_set_bpp(svga, ramdac);
ramdac->index++;
break;
default:
break;
}
didwrite = (ramdac->magic_count >= 4);
ramdac->magic_count = stg_state_write[ramdac->magic_count & 7];
@@ -136,15 +140,18 @@ stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
case 0x3c9:
ramdac->magic_count = 0;
break;
default:
break;
}
svga_out(addr, val, svga);
}
uint8_t
stg_ramdac_in(uint16_t addr, void *p, svga_t *svga)
stg_ramdac_in(uint16_t addr, void *priv, svga_t *svga)
{
stg_ramdac_t *ramdac = (stg_ramdac_t *) p;
stg_ramdac_t *ramdac = (stg_ramdac_t *) priv;
uint8_t temp = 0xff;
switch (addr) {
@@ -185,6 +192,9 @@ stg_ramdac_in(uint16_t addr, void *p, svga_t *svga)
}
ramdac->index++;
break;
default:
break;
}
ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7];
return temp;
@@ -193,6 +203,9 @@ stg_ramdac_in(uint16_t addr, void *p, svga_t *svga)
case 0x3c9:
ramdac->magic_count = 0;
break;
default:
break;
}
return svga_in(addr, svga);
@@ -201,12 +214,12 @@ stg_ramdac_in(uint16_t addr, void *p, svga_t *svga)
float
stg_getclock(int clock, void *priv)
{
stg_ramdac_t *ramdac = (stg_ramdac_t *) priv;
float t;
int m;
int n;
int n2;
uint16_t *c;
stg_ramdac_t *ramdac = (stg_ramdac_t *) priv;
float t;
int m;
int n;
int n2;
const uint16_t *c;
if (clock == 0)
return 25175000.0;
@@ -225,7 +238,7 @@ stg_getclock(int clock, void *priv)
}
static void *
stg_ramdac_init(const device_t *info)
stg_ramdac_init(UNUSED(const device_t *info))
{
stg_ramdac_t *ramdac = (stg_ramdac_t *) malloc(sizeof(stg_ramdac_t));
memset(ramdac, 0, sizeof(stg_ramdac_t));

View File

@@ -39,6 +39,8 @@
#include <86box/plat.h>
#include <86box/ui.h>
#include <86box/video.h>
#include <86box/vid_8514a.h>
#include <86box/vid_xga.h>
#include <86box/vid_svga.h>
#include <86box/vid_svga_render.h>
#include <86box/vid_xga_device.h>
@@ -56,7 +58,6 @@ uint8_t svga_rotate[8][256];
only SVGA device.*/
static svga_t *svga_pri;
int vga_on;
int ibm8514_on;
#ifdef ENABLE_SVGA_LOG
int svga_do_log = ENABLE_SVGA_LOG;
@@ -91,12 +92,10 @@ svga_set_override(svga_t *svga, int val)
if (!val) {
/* Override turned off, restore overscan X and Y per the CRTC. */
if (enable_overscan) {
svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1;
svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1;
if (svga->monitor->mon_overscan_y < 16)
svga->monitor->mon_overscan_y = 16;
}
if (svga->monitor->mon_overscan_y < 16)
svga->monitor->mon_overscan_y = 16;
svga->monitor->mon_overscan_x = (svga->seqregs[1] & 1) ? 16 : 18;
@@ -110,15 +109,60 @@ svga_set_override(svga_t *svga, int val)
void
svga_out(uint16_t addr, uint8_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
uint8_t o;
uint8_t index;
svga_t *svga = (svga_t *) priv;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
xga_t *xga = (xga_t *) svga->xga;
uint8_t o;
uint8_t index;
uint8_t pal4to16[16] = { 0, 7, 0x38, 0x3f, 0, 3, 4, 0x3f, 0, 2, 4, 0x3e, 0, 3, 5, 0x3f };
if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed))
return;
switch (addr) {
case 0x2ea:
dev->dac_mask = val;
break;
case 0x2eb:
case 0x2ec:
dev->dac_pos = 0;
dev->dac_status = addr & 0x03;
dev->dac_addr = (val + (addr & 0x01)) & 0xff;
break;
case 0x2ed:
svga->fullchange = svga->monitor->mon_changeframecount;
switch (dev->dac_pos) {
case 0:
dev->dac_r = val;
dev->dac_pos++;
break;
case 1:
dev->dac_g = val;
dev->dac_pos++;
break;
case 2:
index = dev->dac_addr & 0xff;
dev->dac_b = val;
svga->vgapal[index].r = dev->dac_r;
svga->vgapal[index].g = dev->dac_g;
svga->vgapal[index].b = dev->dac_b;
if (svga->ramdac_type == RAMDAC_8BIT)
dev->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b);
else
dev->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]);
dev->dac_pos = 0;
dev->dac_addr = (dev->dac_addr + 1) & 0xff;
break;
default:
break;
}
break;
case 0x3c0:
case 0x3c1:
if (!svga->attrff) {
svga->attraddr = val & 31;
svga->attraddr = val & 0x1f;
if ((val & 0x20) != svga->attr_palette_enable) {
svga->fullchange = 3;
svga->attr_palette_enable = val & 0x20;
@@ -127,17 +171,19 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
} else {
if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val))
svga->fullchange = svga->monitor->mon_changeframecount;
o = svga->attrregs[svga->attraddr & 31];
svga->attrregs[svga->attraddr & 31] = val;
if (svga->attraddr < 16)
o = svga->attrregs[svga->attraddr & 0x1f];
svga->attrregs[svga->attraddr & 0x1f] = val;
if (svga->attraddr < 0x10)
svga->fullchange = svga->monitor->mon_changeframecount;
if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) {
for (int c = 0; c < 16; c++) {
if (svga->attrregs[0x10] & 0x80) {
if ((svga->attraddr == 0x10) || (svga->attraddr == 0x14) || (svga->attraddr < 0x10)) {
for (int c = 0; c < 0x10; c++) {
if (svga->attrregs[0x10] & 0x80)
svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4);
} else {
else if (svga->ati_4color)
svga->egapal[c] = pal4to16[(c & 0x03) | ((val >> 2) & 0xc)];
else
svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4);
}
}
svga->fullchange = svga->monitor->mon_changeframecount;
}
@@ -167,10 +213,15 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
svga_recalctimings(svga);
break;
case 0x3c3:
if (xga_enabled) {
svga->xga.on = (val & 0x01) ? 0 : 1;
vga_on = !svga->xga.on;
if (xga_active && xga)
xga->on = (val & 0x01) ? 0 : 1;
if (ibm8514_active && dev) {
dev->on[0] = (val & 0x01) ? 0 : 1;
dev->on[1] = dev->on[0];
}
svga_log("3C3: VGA ON = %d.\n", val & 0x01);
vga_on = val & 0x01;
break;
case 0x3c4:
svga->seqaddr = val;
@@ -210,19 +261,15 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
break;
}
break;
case 0x2ea:
case 0x3c6:
svga->dac_mask = val;
break;
case 0x2eb:
case 0x2ec:
case 0x3c7:
case 0x3c8:
svga->dac_pos = 0;
svga->dac_status = addr & 0x03;
svga->dac_addr = (val + (addr & 0x01)) & 255;
break;
case 0x2ed:
case 0x3c9:
if (svga->adv_flags & FLAG_RAMDAC_SHIFT)
val <<= 2;
@@ -238,9 +285,10 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
break;
case 2:
index = svga->dac_addr & 255;
svga->dac_b = val;
svga->vgapal[index].r = svga->dac_r;
svga->vgapal[index].g = svga->dac_g;
svga->vgapal[index].b = val;
svga->vgapal[index].b = svga->dac_b;
if (svga->ramdac_type == RAMDAC_8BIT)
svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b);
else
@@ -319,11 +367,55 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
uint8_t
svga_in(uint16_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
uint8_t index;
uint8_t ret = 0xff;
svga_t *svga = (svga_t *) priv;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t index;
uint8_t ret = 0xff;
if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed))
return ret;
switch (addr) {
case 0x2ea:
ret = dev->dac_mask;
break;
case 0x2eb:
ret = dev->dac_status;
break;
case 0x2ec:
ret = dev->dac_addr;
break;
case 0x2ed:
index = (dev->dac_addr - 1) & 0xff;
switch (dev->dac_pos) {
case 0:
dev->dac_pos++;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[index].r;
else
ret = svga->vgapal[index].r & 0x3f;
break;
case 1:
dev->dac_pos++;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[index].g;
else
ret = svga->vgapal[index].g & 0x3f;
break;
case 2:
dev->dac_pos = 0;
dev->dac_addr = (dev->dac_addr + 1) & 0xff;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[index].b;
else
ret = svga->vgapal[index].b & 0x3f;
break;
default:
break;
}
break;
case 0x3c0:
ret = svga->attraddr | svga->attr_palette_enable;
break;
@@ -336,25 +428,24 @@ svga_in(uint16_t addr, void *priv)
else
ret = 0x10;
break;
case 0x3c3:
ret = vga_on;
break;
case 0x3c4:
ret = svga->seqaddr;
break;
case 0x3c5:
ret = svga->seqregs[svga->seqaddr & 0x0f];
break;
case 0x2ea:
case 0x3c6:
ret = svga->dac_mask;
break;
case 0x2eb:
case 0x3c7:
ret = svga->dac_status;
break;
case 0x2ec:
case 0x3c8:
ret = svga->dac_addr;
break;
case 0x2ed:
case 0x3c9:
index = (svga->dac_addr - 1) & 255;
switch (svga->dac_pos) {
@@ -440,10 +531,29 @@ svga_in(uint16_t addr, void *priv)
void
svga_set_ramdac_type(svga_t *svga, int type)
{
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
xga_t *xga = (xga_t *) svga->xga;
if (svga->ramdac_type != type) {
svga->ramdac_type = type;
for (int c = 0; c < 256; c++) {
if (ibm8514_active && dev) {
if (svga->ramdac_type == RAMDAC_8BIT)
dev->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
else
dev->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4,
(svga->vgapal[c].g & 0x3f) * 4,
(svga->vgapal[c].b & 0x3f) * 4);
}
if (xga_active && xga) {
if (svga->ramdac_type == RAMDAC_8BIT)
xga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
else
xga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4,
(svga->vgapal[c].g & 0x3f) * 4,
(svga->vgapal[c].b & 0x3f) * 4);
}
if (svga->ramdac_type == RAMDAC_8BIT)
svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
else
@@ -457,17 +567,18 @@ svga_set_ramdac_type(svga_t *svga, int type)
void
svga_recalctimings(svga_t *svga)
{
double crtcconst;
double _dispontime;
double _dispofftime;
double disptime;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
double crtcconst;
double _dispontime;
double _dispofftime;
double disptime;
#ifdef ENABLE_SVGA_LOG
int vsyncend;
int vblankend;
int hdispstart;
int hdispend;
int hsyncstart;
int hsyncend;
int vsyncend;
int vblankend;
int hdispstart;
int hdispend;
int hsyncstart;
int hsyncend;
#endif
svga->vtotal = svga->crtc[6];
@@ -511,20 +622,20 @@ svga_recalctimings(svga_t *svga)
svga->htotal = svga->crtc[0];
/* +5 has been verified by Sergi to be correct - +6 must have been an off by one error. */
svga->htotal += 5; /*+6 is required for Tyrian*/
svga->htotal += 5; /*+5 is required for Tyrian*/
svga->rowoffset = svga->crtc[0x13];
svga->clock = (svga->vidclock) ? VGACONST2 : VGACONST1;
svga->lowres = svga->attrregs[0x10] & 0x40;
svga->lowres = !!(svga->attrregs[0x10] & 0x40);
svga->interlace = 0;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
svga->ca_adj = 0;
svga->rowcount = svga->crtc[9] & 31;
svga->rowcount = svga->crtc[9] & 0x1f;
svga->hdisp_time = svga->hdisp;
svga->render = svga_render_blank;
@@ -545,67 +656,68 @@ svga_recalctimings(svga_t *svga)
} else {
svga->hdisp_old = svga->hdisp;
switch (svga->gdcreg[5] & 0x60) {
case 0x00:
if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) <= 0x20)) {
if ((svga->gdcreg[5] & 0x60) == 0x00) {
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_4bpp_lowres;
else
svga->render = svga_render_4bpp_highres;
break;
case 0x20: /*4 colours*/
} else if ((svga->gdcreg[5] & 0x60) == 0x20) {
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_2bpp_lowres;
else
svga->render = svga_render_2bpp_highres;
break;
case 0x40:
case 0x60: /*256+ colours*/
switch (svga->bpp) {
case 8:
svga->map8 = svga->pallook;
if (svga->lowres)
svga->render = svga_render_8bpp_lowres;
else
svga->render = svga_render_8bpp_highres;
break;
case 15:
if (svga->lowres)
svga->render = svga_render_15bpp_lowres;
else
svga->render = svga_render_15bpp_highres;
break;
case 16:
if (svga->lowres)
svga->render = svga_render_16bpp_lowres;
else
svga->render = svga_render_16bpp_highres;
break;
case 17:
if (svga->lowres)
svga->render = svga_render_15bpp_mix_lowres;
else
svga->render = svga_render_15bpp_mix_highres;
break;
case 24:
if (svga->lowres)
svga->render = svga_render_24bpp_lowres;
else
svga->render = svga_render_24bpp_highres;
break;
case 32:
if (svga->lowres)
svga->render = svga_render_32bpp_lowres;
else
svga->render = svga_render_32bpp_highres;
break;
} else {
svga->map8 = svga->pallook;
if (svga->lowres) /*Low res (320)*/
svga->render = svga_render_8bpp_lowres;
else
svga->render = svga_render_8bpp_highres;
}
} else {
switch (svga->gdcreg[5] & 0x60) {
case 0x40:
case 0x60: /*256+ colours*/
switch (svga->bpp) {
case 15:
if (svga->lowres)
svga->render = svga_render_15bpp_lowres;
else
svga->render = svga_render_15bpp_highres;
break;
case 16:
if (svga->lowres)
svga->render = svga_render_16bpp_lowres;
else
svga->render = svga_render_16bpp_highres;
break;
case 17:
if (svga->lowres)
svga->render = svga_render_15bpp_mix_lowres;
else
svga->render = svga_render_15bpp_mix_highres;
break;
case 24:
if (svga->lowres)
svga->render = svga_render_24bpp_lowres;
else
svga->render = svga_render_24bpp_highres;
break;
case 32:
if (svga->lowres)
svga->render = svga_render_32bpp_lowres;
else
svga->render = svga_render_32bpp_highres;
break;
default:
break;
}
break;
default:
break;
}
break;
default:
break;
default:
break;
}
}
}
}
@@ -613,12 +725,10 @@ svga_recalctimings(svga_t *svga)
svga->linedbl = svga->crtc[9] & 0x80;
svga->char_width = (svga->seqregs[1] & 1) ? 8 : 9;
if (enable_overscan) {
svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1;
svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1;
if (svga->monitor->mon_overscan_y < 16)
svga->monitor->mon_overscan_y = 16;
}
if (svga->monitor->mon_overscan_y < 16)
svga->monitor->mon_overscan_y = 16;
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) {
svga->monitor->mon_overscan_x = (svga->seqregs[1] & 1) ? 16 : 18;
@@ -646,25 +756,17 @@ svga_recalctimings(svga_t *svga)
} else
svga->dots_per_clock = 1;
/* Do svga->recalctimings_ex() here so that the above five variables can be
updated by said function. */
if (vga_on) {
if (svga->recalctimings_ex) {
svga->recalctimings_ex(svga);
}
} else {
if (ibm8514_enabled) {
if (svga->dev8514.local) {
if (svga->recalctimings_ex) {
svga->recalctimings_ex(svga);
}
} else
ibm8514_recalctimings(svga);
}
if (xga_enabled)
xga_recalctimings(svga);
if (svga->recalctimings_ex)
svga->recalctimings_ex(svga);
if (ibm8514_active && (svga->dev8514 != NULL)) {
if ((dev->local & 0xff) == 0x00)
ibm8514_recalctimings(svga);
}
if (xga_active && (svga->xga != NULL))
xga_recalctimings(svga);
svga->htotal += 6; /*+6 is required for Tyrian*/
svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val;
if (svga->hblankend <= svga->hblankstart)
@@ -682,7 +784,7 @@ svga_recalctimings(svga_t *svga)
if (svga->hdisp >= 2048)
svga->monitor->mon_overscan_x = 0;
svga->y_add = (svga->monitor->mon_overscan_y >> 1) - (svga->crtc[8] & 0x1f);
svga->y_add = (svga->monitor->mon_overscan_y >> 1);
svga->x_add = (svga->monitor->mon_overscan_x >> 1);
if (svga->vblankstart < svga->dispend)
@@ -727,13 +829,8 @@ svga_recalctimings(svga_t *svga)
svga->htotal, hdispstart, hdispend, hsyncstart, hsyncend,
svga->hblankstart, svga->hblankend);
if (ibm8514_on && !svga->dev8514.local) {
disptime = svga->dev8514.h_total;
_dispontime = svga->dev8514.h_disp;
} else {
disptime = svga->htotal;
_dispontime = svga->hdisp_time;
}
disptime = svga->htotal;
_dispontime = svga->hdisp_time;
if (svga->seqregs[1] & 8) {
disptime *= 2;
@@ -813,23 +910,26 @@ void
svga_poll(void *priv)
{
svga_t *svga = (svga_t *) priv;
ibm8514_t *dev = &svga->dev8514;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
xga_t *xga = (xga_t *) svga->xga;
uint32_t x;
uint32_t blink_delay;
int wx;
int wy;
int ret;
int old_ma;
int linecountff = 0;
if (!vga_on && ibm8514_enabled && ibm8514_on) {
if (!dev->local) {
if (!svga->override) {
if (ibm8514_active && dev && (dev->on[0] || dev->on[1])) {
ibm8514_poll(dev, svga);
return;
}
} else if (!vga_on && xga_enabled && svga->xga.on) {
xga_poll(&svga->xga, svga);
return;
if (xga_active && xga && xga->on) {
if ((xga->disp_cntl_2 & 7) >= 2) {
xga_poll(xga, svga);
return;
}
}
}
if (!svga->linepos) {
@@ -922,13 +1022,9 @@ svga_poll(void *priv)
if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount))
svga->con = 0;
if (svga->dispon) {
/*Real IBM 8514/A or compatibility mode doesn't have linedbl, so skip those.*/
if (dev->local && ibm8514_on) {
svga->linedbl = 0;
svga->linecountff = 0;
linecountff = 1;
}
if (svga->linedbl && !svga->linecountff && !linecountff) {
/* TODO: Verify real hardware behaviour for out-of-range fine vertical scroll
- S3 Trio64V2/DX: sc == rowcount, wrapping 5-bit counter. */
if (svga->linedbl && !svga->linecountff) {
svga->linecountff = 1;
svga->ma = svga->maback;
} else if (svga->sc == svga->rowcount) {
@@ -991,7 +1087,7 @@ svga_poll(void *priv)
else
svga->cursoron = svga->blink & (16 + (16 * blink_delay));
if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15))
if (!(svga->blink & 15))
svga->fullchange = 2;
svga->blink = (svga->blink + 1) & 0x7f;
@@ -1036,17 +1132,12 @@ svga_poll(void *priv)
svga->monitor->mon_changeframecount = svga->interlace ? 3 : 2;
svga->vslines = 0;
if ((dev->local && vga_on) || !dev->local) {
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub;
else
svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub;
} else if (dev->local && ibm8514_on) {
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1);
else
svga->ma = svga->maback = svga->ma_latch;
}
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) +
((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub;
else
svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub;
svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj;
svga->ma = (svga->ma << 2);
svga->maback = (svga->maback << 2);
@@ -1060,28 +1151,26 @@ svga_poll(void *priv)
#endif
if (svga->vc == svga->vtotal) {
svga->vc = 0;
svga->sc = 0;
svga->sc = (svga->crtc[0x8] & 0x1f);
svga->dispon = 1;
svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0;
if (!ibm8514_on) {
svga->scrollcache = (svga->attrregs[0x13] & 0x0f);
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 1)
svga->scrollcache &= 0x07;
else {
svga->scrollcache++;
if (svga->scrollcache > 8)
svga->scrollcache = 0;
}
} else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres))
svga->scrollcache = (svga->attrregs[0x13] & 0x0f);
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 1)
svga->scrollcache &= 0x07;
else
svga->scrollcache = (svga->scrollcache & 0x06) >> 1;
else {
svga->scrollcache++;
if (svga->scrollcache > 8)
svga->scrollcache = 0;
}
} else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres))
svga->scrollcache &= 0x07;
else
svga->scrollcache = (svga->scrollcache & 0x06) >> 1;
if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres))
svga->scrollcache <<= 1;
}
if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres))
svga->scrollcache <<= 1;
svga->x_add = (svga->monitor->mon_overscan_x >> 1) - svga->scrollcache;
@@ -1101,6 +1190,12 @@ svga_poll(void *priv)
}
}
uint32_t
svga_conv_16to32(struct svga_t *svga, uint16_t color, uint8_t bpp)
{
return (bpp == 15) ? video_15to32[color] : video_16to32[color];
}
int
svga_init(const device_t *info, svga_t *svga, void *priv, int memsize,
void (*recalctimings_ex)(struct svga_t *svga),
@@ -1147,6 +1242,7 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize,
svga->video_out = video_out;
svga->hwcursor_draw = hwcursor_draw;
svga->overlay_draw = overlay_draw;
svga->conv_16to32 = svga_conv_16to32;
svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = 32;
@@ -1242,12 +1338,12 @@ svga_decode_addr(svga_t *svga, uint32_t addr, int write)
static __inline void
svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
{
svga_t *svga = (svga_t *) priv;
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
int writemask2 = svga->writemask;
int reset_wm = 0;
latch_t vall;
uint8_t wm = svga->writemask;
uint8_t wm = svga->writemask;
uint8_t count;
uint8_t i;
@@ -1257,24 +1353,38 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
cycles -= svga->monitor->mon_video_timing_write_b;
if (!linear) {
if (xga_enabled) {
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl >= 1)) {
if (xga_active && xga) {
if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) {
if (val == 0xa5) { /*Memory size test of XGA*/
svga->xga.test = val;
svga->xga.a5_test = 1;
xga->test = val;
if (addr == 0xa0001)
xga->a5_test = 1;
else if (addr == 0xafffe)
xga->a5_test = 2;
xga->on = 0;
vga_on = 1;
xga->disp_cntl_2 = 0;
svga_log("XGA test1 addr = %05x.\n", addr);
return;
} else if (val == 0x5a) {
svga->xga.test = val;
xga->test = val;
xga->on = 0;
vga_on = 1;
xga->disp_cntl_2 = 0;
svga_log("XGA test2 addr = %05x.\n", addr);
return;
} else if ((val == 0x12) || (val == 0x34)) {
addr += svga->xga.write_bank;
svga->xga.vram[addr & svga->xga.vram_mask] = val;
svga->xga.linear_endian_reverse = 1;
} else if ((addr == 0xa0000) || (addr == 0xa0010)) {
addr += xga->write_bank;
xga->vram[addr & xga->vram_mask] = val;
svga_log("XGA Linear endian reverse write, val = %02x, addr = %05x, banked mask = %04x.\n", val, addr, svga->banked_mask);
if (!xga->a5_test)
xga->linear_endian_reverse = 1;
return;
}
} else {
svga->xga.on = 0;
vga_on = !svga->xga.on;
xga->on = 0;
vga_on = 1;
}
}
addr = svga_decode_addr(svga, addr, 1);
@@ -1303,18 +1413,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
if (addr & 1)
writemask2 <<= 1;
addr &= ~1;
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) {
addr &= svga->vram_mask;
} else
addr <<= 2;
} else {
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) {
writemask2 = 1 << (addr & 3);
addr &= ~3;
addr &= svga->vram_mask;
} else
addr <<= 2;
}
addr <<= 2;
} else
addr <<= 2;
addr &= svga->decode_mask;
if (svga->translate_address)
@@ -1459,6 +1561,7 @@ static __inline uint8_t
svga_read_common(uint32_t addr, uint8_t linear, void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
uint32_t latch_addr = 0;
int readplane = svga->readplane;
uint8_t count;
@@ -1471,23 +1574,37 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv)
cycles -= svga->monitor->mon_video_timing_read_b;
if (!linear) {
if (xga_enabled) {
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl >= 1)) {
if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/
svga->xga.on = 1;
vga_on = !svga->xga.on;
return svga->xga.test;
} else if (svga->xga.test == 0x5a) {
svga->xga.on = 1;
vga_on = !svga->xga.on;
return svga->xga.test;
if (xga_active && xga) {
if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) {
if (xga->test == 0xa5) { /*Memory size test of XGA*/
if (addr == 0xa0001) {
ret = xga->test;
xga->on = 1;
vga_on = 0;
} else if ((addr == 0xa0000) && (xga->a5_test == 1)) { /*This is required by XGAKIT to pass the memory test*/
svga_log("A5 test bank = %x.\n", addr);
addr += xga->read_bank;
ret = xga->vram[addr & xga->vram_mask];
} else {
ret = xga->test;
xga->on = 1;
vga_on = 0;
}
svga_log("A5 read: XGA ON = %d, addr = %05x, ret = %02x, test1 = %x.\n", xga->on, addr, ret, xga->a5_test);
return ret;
} else if (xga->test == 0x5a) {
ret = xga->test;
xga->on = 1;
vga_on = 0;
svga_log("5A read: XGA ON = %d.\n", xga->on);
return ret;
} else if ((addr == 0xa0000) || (addr == 0xa0010)) {
addr += svga->xga.read_bank;
return svga->xga.vram[addr & svga->xga.vram_mask];
addr += xga->read_bank;
return xga->vram[addr & xga->vram_mask];
}
} else {
svga->xga.on = 0;
vga_on = !svga->xga.on;
xga->on = 0;
vga_on = 1;
}
}
addr = svga_decode_addr(svga, addr, 0);
@@ -1523,22 +1640,10 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv)
} else if (svga->chain2_read) {
readplane = (readplane & 2) | (addr & 1);
addr &= ~1;
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI))
addr &= svga->vram_mask;
else
addr <<= 2;
} else {
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) {
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
return 0xff;
latch_addr = (addr & svga->vram_mask) & ~3;
for (uint8_t i = 0; i < count; i++)
svga->latch.b[i] = svga->vram[latch_addr | i];
return svga->vram[addr & svga->vram_mask];
} else
addr <<= 2;
}
addr <<= 2;
} else
addr <<= 2;
addr &= svga->decode_mask;
if (svga->translate_address) {
@@ -1624,7 +1729,7 @@ svga_doblit(int wx, int wy, svga_t *svga)
x_add = enable_overscan ? svga->monitor->mon_overscan_x : 0;
y_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_y >> 1);
x_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_x >> 1);
bottom = (svga->monitor->mon_overscan_y >> 1) + (svga->crtc[8] & 0x1f);
bottom = (svga->monitor->mon_overscan_y >> 1);
if (svga->vertical_linedbl) {
y_add <<= 1;
@@ -1708,7 +1813,7 @@ svga_writeb_linear(uint32_t addr, uint8_t val, void *priv)
return;
addr &= svga->vram_mask;
svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount;
*&svga->vram[addr] = val;
svga->vram[addr] = val;
}
void
@@ -1843,7 +1948,7 @@ svga_readb_linear(uint32_t addr, void *priv)
if (addr >= svga->vram_max)
return 0xff;
return *&svga->vram[addr & svga->vram_mask];
return svga->vram[addr & svga->vram_mask];
}
uint16_t
@@ -1898,9 +2003,8 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *priv)
{
svga_t *svga = (svga_t *) priv;
if (!svga->fast) {
if (!svga->fast)
return svga_read_common(addr, linear, priv) | (svga_read_common(addr + 1, linear, priv) << 8) | (svga_read_common(addr + 2, linear, priv) << 16) | (svga_read_common(addr + 3, linear, priv) << 24);
}
cycles -= svga->monitor->mon_video_timing_read_l;

File diff suppressed because it is too large Load Diff

View File

@@ -38,7 +38,7 @@
#include <86box/vid_mda.h>
#include <86box/vid_xga_device.h>
typedef struct {
typedef struct video_card_t {
const device_t *device;
int flags;
} VIDEO_CARD;
@@ -77,197 +77,199 @@ static const device_t vid_internal_device = {
static const VIDEO_CARD
video_cards[] = {
// clang-format off
{ &vid_none_device },
{ &vid_internal_device },
{ &atiega_device },
{ &mach8_isa_device, VIDEO_FLAG_TYPE_8514 },
{ &mach32_isa_device, VIDEO_FLAG_TYPE_8514 },
{ &mach64gx_isa_device },
{ &ati28800k_device },
{ &ati18800_vga88_device },
{ &ati28800_device },
{ &compaq_ati28800_device },
{ &vid_none_device },
{ &vid_internal_device },
{ &atiega800p_device },
{ &mach8_isa_device, VIDEO_FLAG_TYPE_8514 },
{ &mach32_isa_device, VIDEO_FLAG_TYPE_8514 },
{ &mach64gx_isa_device },
{ &ati28800k_device },
{ &ati18800_vga88_device },
{ &ati28800_device },
{ &compaq_ati28800_device },
#if defined(DEV_BRANCH) && defined(USE_XL24)
{ &ati28800_wonderxl24_device },
{ &ati28800_wonderxl24_device },
#endif
{ &ati18800_device },
{ &ati18800_device },
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
{ &ati18800_wonder_device },
{ &ati18800_wonder_device },
#endif
{ &cga_device },
{ &sega_device },
{ &gd5401_isa_device },
{ &gd5402_isa_device },
{ &gd5420_isa_device },
{ &gd5422_isa_device },
{ &gd5426_isa_device },
{ &gd5426_diamond_speedstar_pro_a1_isa_device },
{ &gd5428_boca_isa_device },
{ &gd5428_isa_device },
{ &gd5429_isa_device },
{ &gd5434_isa_device },
{ &gd5434_diamond_speedstar_64_a3_isa_device },
{ &compaq_cga_device },
{ &compaq_cga_2_device },
{ &cpqega_device },
{ &ega_device },
{ &g2_gc205_device },
{ &hercules_device, VIDEO_FLAG_TYPE_MDA },
{ &herculesplus_device, VIDEO_FLAG_TYPE_MDA },
{ &incolor_device },
{ &inmos_isa_device, VIDEO_FLAG_TYPE_XGA },
{ &im1024_device },
{ &iskra_ega_device },
{ &et4000_kasan_isa_device },
{ &mda_device, VIDEO_FLAG_TYPE_MDA },
{ &genius_device },
{ &nga_device },
{ &ogc_device },
{ &oti037c_device },
{ &oti067_device },
{ &oti077_device },
{ &paradise_pvga1a_device },
{ &paradise_wd90c11_device },
{ &paradise_wd90c30_device },
{ &colorplus_device },
{ &pgc_device },
{ &cga_pravetz_device },
{ &radius_svga_multiview_isa_device },
{ &realtek_rtg3106_device },
{ &s3_diamond_stealth_vram_isa_device },
{ &s3_orchid_86c911_isa_device },
{ &s3_ami_86c924_isa_device },
{ &s3_metheus_86c928_isa_device },
{ &s3_phoenix_86c801_isa_device },
{ &s3_spea_mirage_86c801_isa_device },
{ &sigma_device },
{ &tvga8900b_device },
{ &tvga8900d_device },
{ &tvga9000b_device },
{ &nec_sv9000_device },
{ &et4000k_isa_device },
{ &et2000_device },
{ &et3000_isa_device },
{ &et4000_tc6058af_isa_device },
{ &et4000_isa_device },
{ &et4000w32_device },
{ &et4000w32i_isa_device },
{ &vga_device },
{ &v7_vga_1024i_device },
{ &wy700_device },
{ &gd5426_mca_device },
{ &gd5428_mca_device },
{ &et4000_mca_device },
{ &radius_svga_multiview_mca_device },
{ &mach32_pci_device, VIDEO_FLAG_TYPE_8514 },
{ &mach64gx_pci_device },
{ &mach64vt2_device },
{ &et4000w32p_videomagic_revb_pci_device },
{ &et4000w32p_revc_pci_device },
{ &et4000w32p_cardex_pci_device },
{ &et4000w32p_noncardex_pci_device },
{ &et4000w32p_pci_device },
{ &gd5430_pci_device, },
{ &gd5434_pci_device },
{ &gd5436_pci_device, VIDEO_FLAG_TYPE_SPECIAL },
{ &gd5440_pci_device },
{ &gd5446_pci_device, VIDEO_FLAG_TYPE_SPECIAL },
{ &gd5446_stb_pci_device,VIDEO_FLAG_TYPE_SPECIAL },
{ &gd5480_pci_device },
{ &s3_spea_mercury_lite_86c928_pci_device },
{ &s3_diamond_stealth64_964_pci_device },
{ &s3_elsa_winner2000_pro_x_964_pci_device },
{ &s3_mirocrystal_20sv_964_pci_device },
{ &s3_bahamas64_pci_device },
{ &s3_phoenix_vision864_pci_device },
{ &s3_diamond_stealth_se_pci_device },
{ &s3_phoenix_trio32_pci_device },
{ &s3_diamond_stealth64_pci_device },
{ &s3_9fx_pci_device },
{ &s3_phoenix_trio64_pci_device },
{ &s3_elsa_winner2000_pro_x_pci_device },
{ &s3_mirovideo_40sv_ergo_968_pci_device },
{ &s3_9fx_771_pci_device },
{ &s3_phoenix_vision968_pci_device },
{ &s3_spea_mercury_p64v_pci_device },
{ &s3_9fx_531_pci_device },
{ &s3_phoenix_vision868_pci_device },
{ &s3_phoenix_trio64vplus_pci_device },
{ &s3_trio64v2_dx_pci_device },
{ &s3_virge_325_pci_device },
{ &s3_diamond_stealth_2000_pci_device },
{ &s3_diamond_stealth_3000_pci_device },
{ &s3_stb_velocity_3d_pci_device },
{ &s3_virge_375_pci_device },
{ &s3_diamond_stealth_2000pro_pci_device },
{ &s3_virge_385_pci_device },
{ &s3_virge_357_pci_device },
{ &s3_diamond_stealth_4000_pci_device },
{ &s3_trio3d2x_pci_device },
#if defined(DEV_BRANCH) && defined(USE_MGA)
{ &millennium_device, VIDEO_FLAG_TYPE_SPECIAL },
{ &mystique_device },
{ &mystique_220_device },
#endif
{ &tgui9440_pci_device },
{ &tgui9660_pci_device },
{ &tgui9680_pci_device },
{ &voodoo_banshee_device },
{ &creative_voodoo_banshee_device },
{ &voodoo_3_1000_device },
{ &voodoo_3_2000_device },
{ &voodoo_3_3000_device },
{ &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 },
{ &mach64gx_vlb_device },
{ &et4000w32i_vlb_device },
{ &et4000w32p_videomagic_revb_vlb_device },
{ &et4000w32p_revc_vlb_device },
{ &et4000w32p_cardex_vlb_device },
{ &et4000w32p_vlb_device },
{ &et4000w32p_noncardex_vlb_device },
{ &gd5424_vlb_device },
{ &gd5426_vlb_device },
{ &gd5428_vlb_device },
{ &gd5428_diamond_speedstar_pro_b1_vlb_device },
{ &gd5429_vlb_device },
{ &gd5430_diamond_speedstar_pro_se_a8_vlb_device },
{ &gd5430_vlb_device },
{ &gd5434_vlb_device },
{ &s3_metheus_86c928_vlb_device },
{ &s3_mirocrystal_8s_805_vlb_device },
{ &s3_mirocrystal_10sd_805_vlb_device },
{ &s3_phoenix_86c805_vlb_device },
{ &s3_spea_mirage_86c805_vlb_device },
{ &s3_diamond_stealth64_964_vlb_device },
{ &s3_mirocrystal_20sv_964_vlb_device },
{ &s3_mirocrystal_20sd_864_vlb_device },
{ &s3_bahamas64_vlb_device },
{ &s3_phoenix_vision864_vlb_device },
{ &s3_diamond_stealth_se_vlb_device },
{ &s3_phoenix_trio32_vlb_device },
{ &s3_diamond_stealth64_vlb_device },
{ &s3_9fx_vlb_device },
{ &s3_phoenix_trio64_vlb_device },
{ &s3_spea_mirage_p64_vlb_device },
{ &s3_phoenix_vision968_vlb_device },
{ &s3_phoenix_vision868_vlb_device },
{ &ht216_32_standalone_device },
{ &tgui9400cxi_device },
{ &tgui9440_vlb_device },
{ &s3_virge_357_agp_device },
{ &s3_diamond_stealth_4000_agp_device },
{ &s3_trio3d2x_agp_device },
{ &velocity_100_agp_device },
{ &velocity_200_agp_device },
{ &voodoo_3_1000_agp_device },
{ &voodoo_3_2000_agp_device },
{ &voodoo_3_3000_agp_device },
{ &voodoo_3_3500_agp_ntsc_device },
{ &voodoo_3_3500_agp_pal_device },
{ &compaq_voodoo_3_3500_agp_device },
{ &voodoo_3_3500_se_agp_device },
{ &voodoo_3_3500_si_agp_device },
{ NULL }
{ &cga_device },
{ &sega_device },
{ &gd5401_isa_device },
{ &gd5402_isa_device },
{ &gd5420_isa_device },
{ &gd5422_isa_device },
{ &gd5426_isa_device },
{ &gd5426_diamond_speedstar_pro_a1_isa_device },
{ &gd5428_boca_isa_device },
{ &gd5428_isa_device },
{ &gd5429_isa_device },
{ &gd5434_isa_device },
{ &gd5434_diamond_speedstar_64_a3_isa_device },
{ &compaq_cga_device },
{ &compaq_cga_2_device },
{ &cpqega_device },
{ &ega_device },
{ &g2_gc205_device },
{ &hercules_device, VIDEO_FLAG_TYPE_MDA },
{ &herculesplus_device, VIDEO_FLAG_TYPE_MDA },
{ &incolor_device },
{ &inmos_isa_device, VIDEO_FLAG_TYPE_XGA },
{ &im1024_device },
{ &iskra_ega_device },
{ &et4000_kasan_isa_device },
{ &mda_device, VIDEO_FLAG_TYPE_MDA },
{ &genius_device },
{ &nga_device },
{ &ogc_device },
{ &oti037c_device },
{ &oti067_device },
{ &oti077_device },
{ &paradise_pvga1a_device },
{ &paradise_wd90c11_device },
{ &paradise_wd90c30_device },
{ &colorplus_device },
{ &pgc_device },
{ &cga_pravetz_device },
{ &radius_svga_multiview_isa_device },
{ &realtek_rtg3106_device },
{ &s3_diamond_stealth_vram_isa_device },
{ &s3_orchid_86c911_isa_device },
{ &s3_ami_86c924_isa_device },
{ &s3_metheus_86c928_isa_device },
{ &s3_phoenix_86c801_isa_device },
{ &s3_spea_mirage_86c801_isa_device },
{ &sigma_device },
{ &tvga8900b_device },
{ &tvga8900d_device },
{ &tvga9000b_device },
{ &nec_sv9000_device },
{ &et4000k_isa_device },
{ &et2000_device },
{ &et3000_isa_device },
{ &et4000_tc6058af_isa_device },
{ &et4000_isa_device },
{ &et4000w32_device },
{ &et4000w32i_isa_device },
{ &vga_device },
{ &v7_vga_1024i_device },
{ &wy700_device },
{ &mach32_mca_device, VIDEO_FLAG_TYPE_8514 },
{ &gd5426_mca_device },
{ &gd5428_mca_device },
{ &et4000_mca_device },
{ &radius_svga_multiview_mca_device },
{ &mach32_pci_device, VIDEO_FLAG_TYPE_8514 },
{ &mach64gx_pci_device },
{ &mach64vt2_device },
{ &et4000w32p_videomagic_revb_pci_device },
{ &et4000w32p_revc_pci_device },
{ &et4000w32p_cardex_pci_device },
{ &et4000w32p_noncardex_pci_device },
{ &et4000w32p_pci_device },
{ &gd5430_pci_device, },
{ &gd5434_pci_device },
{ &gd5436_pci_device, VIDEO_FLAG_TYPE_SPECIAL },
{ &gd5440_pci_device },
{ &gd5446_pci_device, VIDEO_FLAG_TYPE_SPECIAL },
{ &gd5446_stb_pci_device, VIDEO_FLAG_TYPE_SPECIAL },
{ &gd5480_pci_device },
{ &s3_spea_mercury_lite_86c928_pci_device },
{ &s3_diamond_stealth64_964_pci_device },
{ &s3_elsa_winner2000_pro_x_964_pci_device },
{ &s3_mirocrystal_20sv_964_pci_device },
{ &s3_bahamas64_pci_device },
{ &s3_phoenix_vision864_pci_device },
{ &s3_diamond_stealth_se_pci_device },
{ &s3_phoenix_trio32_pci_device },
{ &s3_diamond_stealth64_pci_device },
{ &s3_9fx_pci_device },
{ &s3_phoenix_trio64_pci_device },
{ &s3_elsa_winner2000_pro_x_pci_device },
{ &s3_mirovideo_40sv_ergo_968_pci_device },
{ &s3_9fx_771_pci_device },
{ &s3_phoenix_vision968_pci_device },
{ &s3_spea_mercury_p64v_pci_device },
{ &s3_9fx_531_pci_device },
{ &s3_phoenix_vision868_pci_device },
{ &s3_cardex_trio64vplus_pci_device },
{ &s3_phoenix_trio64vplus_pci_device },
{ &s3_trio64v2_dx_pci_device },
{ &s3_virge_325_pci_device },
{ &s3_diamond_stealth_2000_pci_device },
{ &s3_diamond_stealth_3000_pci_device },
{ &s3_stb_velocity_3d_pci_device },
{ &s3_virge_375_pci_device },
{ &s3_diamond_stealth_2000pro_pci_device },
{ &s3_virge_385_pci_device },
{ &s3_virge_357_pci_device },
{ &s3_diamond_stealth_4000_pci_device },
{ &s3_trio3d2x_pci_device },
{ &millennium_device },
{ &millennium_ii_device },
{ &mystique_device },
{ &mystique_220_device },
{ &tgui9440_pci_device },
{ &tgui9660_pci_device },
{ &tgui9680_pci_device },
{ &voodoo_banshee_device },
{ &creative_voodoo_banshee_device },
{ &voodoo_3_1000_device },
{ &voodoo_3_2000_device },
{ &voodoo_3_3000_device },
{ &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 },
{ &mach64gx_vlb_device },
{ &et4000w32i_vlb_device },
{ &et4000w32p_videomagic_revb_vlb_device },
{ &et4000w32p_revc_vlb_device },
{ &et4000w32p_cardex_vlb_device },
{ &et4000w32p_vlb_device },
{ &et4000w32p_noncardex_vlb_device },
{ &gd5424_vlb_device },
{ &gd5426_vlb_device },
{ &gd5428_vlb_device },
{ &gd5428_diamond_speedstar_pro_b1_vlb_device },
{ &gd5429_vlb_device },
{ &gd5430_diamond_speedstar_pro_se_a8_vlb_device },
{ &gd5430_vlb_device },
{ &gd5434_vlb_device },
{ &s3_metheus_86c928_vlb_device },
{ &s3_mirocrystal_8s_805_vlb_device },
{ &s3_mirocrystal_10sd_805_vlb_device },
{ &s3_phoenix_86c805_vlb_device },
{ &s3_spea_mirage_86c805_vlb_device },
{ &s3_diamond_stealth64_964_vlb_device },
{ &s3_mirocrystal_20sv_964_vlb_device },
{ &s3_mirocrystal_20sd_864_vlb_device },
{ &s3_bahamas64_vlb_device },
{ &s3_phoenix_vision864_vlb_device },
{ &s3_diamond_stealth_se_vlb_device },
{ &s3_phoenix_trio32_vlb_device },
{ &s3_diamond_stealth64_vlb_device },
{ &s3_9fx_vlb_device },
{ &s3_phoenix_trio64_vlb_device },
{ &s3_spea_mirage_p64_vlb_device },
{ &s3_phoenix_vision968_vlb_device },
{ &s3_phoenix_vision868_vlb_device },
{ &ht216_32_standalone_device },
{ &tgui9400cxi_device },
{ &tgui9440_vlb_device },
{ &s3_virge_357_agp_device },
{ &s3_diamond_stealth_4000_agp_device },
{ &s3_trio3d2x_agp_device },
{ &productiva_g100_device, VIDEO_FLAG_TYPE_SPECIAL },
{ &velocity_100_agp_device },
{ &velocity_200_agp_device },
{ &voodoo_3_1000_agp_device },
{ &voodoo_3_2000_agp_device },
{ &voodoo_3_3000_agp_device },
{ &voodoo_3_3500_agp_ntsc_device },
{ &voodoo_3_3500_agp_pal_device },
{ &compaq_voodoo_3_3500_agp_device },
{ &voodoo_3_3500_se_agp_device },
{ &voodoo_3_3500_si_agp_device },
{ NULL }
// clang-format on
};
@@ -344,8 +346,16 @@ video_reset(int card)
monitor_index_global = 0;
loadfont("roms/video/mda/mda.rom", 0);
if ((card != VID_NONE) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY) &&
(gfxcard[1] > VID_INTERNAL) && device_is_valid(video_card_getdevice(gfxcard[1]), machine)) {
video_monitor_init(1);
monitor_index_global = 1;
device_add(video_cards[gfxcard[1]].device);
monitor_index_global = 0;
}
/* Do not initialize internal cards here. */
if (!(card == VID_NONE) && !(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) {
if ((card > VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) {
vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].device->name);
video_prepare();
@@ -354,21 +364,40 @@ video_reset(int card)
device_add(video_cards[card].device);
}
if (!(card == VID_NONE)
&& !machine_has_flags(machine, MACHINE_VIDEO_ONLY)
&& gfxcard[1] != 0
&& device_is_valid(video_card_getdevice(gfxcard[1]), machine)) {
video_monitor_init(1);
monitor_index_global = 1;
device_add(video_cards[gfxcard[1]].device);
monitor_index_global = 0;
}
was_reset = 1;
}
void
video_post_reset(void)
{
int ibm8514_has_vga = 0;
if (gfxcard[0] == VID_INTERNAL)
ibm8514_has_vga = (video_get_type_monitor(0) == VIDEO_FLAG_TYPE_8514);
else if (gfxcard[0] != VID_NONE)
ibm8514_has_vga = (video_card_get_flags(gfxcard[0]) == VIDEO_FLAG_TYPE_8514);
else
ibm8514_has_vga = 0;
if (ibm8514_has_vga)
ibm8514_active = 1;
if (ibm8514_standalone_enabled)
ibm8514_device_add();
if (xga_standalone_enabled)
xga_device_add();
/* Reset the graphics card (or do nothing if it was already done
by the machine's init function). */
video_reset(gfxcard[0]);
}
void
video_voodoo_init(void)
{
/* Enable the Voodoo if configured. */
if (voodoo_enabled)
device_add(&voodoo_device);
was_reset = 1;
}
int
@@ -401,7 +430,7 @@ video_card_has_config(int card)
return (device_has_config(video_cards[card].device) ? 1 : 0);
}
char *
const char *
video_get_internal_name(int card)
{
return device_get_internal_name(video_cards[card].device);

File diff suppressed because it is too large Load Diff

View File

@@ -91,7 +91,7 @@ vid_out(uint16_t addr, uint8_t val, void *priv)
#if 0
if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) &&
!(svga->miscout & 1)) addr ^= 0x60;
!(svga->miscout & 1)) addr ^= 0x60;
#endif
switch (addr) {
@@ -137,6 +137,9 @@ vid_out(uint16_t addr, uint8_t val, void *priv)
case 0x210a:
ti->reg_210a = val;
break;
default:
break;
}
svga_out(addr, val, svga);
@@ -151,7 +154,7 @@ vid_in(uint16_t addr, void *priv)
#if 0
if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) &&
!(svga->miscout & 1)) addr ^= 0x60;
!(svga->miscout & 1)) addr ^= 0x60;
#endif
switch (addr) {

View File

@@ -27,6 +27,7 @@
#include <86box/mem.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/plat_unused.h>
typedef struct tkd8001_ramdac_t {
int state;
@@ -34,9 +35,9 @@ typedef struct tkd8001_ramdac_t {
} tkd8001_ramdac_t;
void
tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga)
{
tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p;
tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) priv;
switch (addr) {
case 0x3C6:
@@ -59,6 +60,9 @@ tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
case 7:
svga->bpp = 16;
break;
default:
break;
}
return;
}
@@ -68,15 +72,18 @@ tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
case 0x3C9:
ramdac->state = 0;
break;
default:
break;
}
svga_out(addr, val, svga);
}
uint8_t
tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga)
tkd8001_ramdac_in(uint16_t addr, void *priv, svga_t *svga)
{
tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p;
tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) priv;
switch (addr) {
case 0x3C6:
@@ -89,12 +96,15 @@ tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga)
case 0x3C9:
ramdac->state = 0;
break;
default:
break;
}
return svga_in(addr, svga);
}
static void *
tkd8001_ramdac_init(const device_t *info)
tkd8001_ramdac_init(UNUSED(const device_t *info))
{
tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) malloc(sizeof(tkd8001_ramdac_t));
memset(ramdac, 0, sizeof(tkd8001_ramdac_t));

View File

@@ -111,6 +111,9 @@ tvga_out(uint16_t addr, uint8_t val, void *priv)
tvga_recalcbanking(tvga);
}
return;
default:
break;
}
break;
@@ -143,6 +146,9 @@ tvga_out(uint16_t addr, uint8_t val, void *priv)
svga->gdcreg[0xf] = val;
tvga_recalcbanking(tvga);
break;
default:
break;
}
break;
case 0x3D4:
@@ -171,6 +177,9 @@ tvga_out(uint16_t addr, uint8_t val, void *priv)
case 0x1e:
svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff;
break;
default:
break;
}
return;
case 0x3D8:
@@ -194,6 +203,9 @@ tvga_out(uint16_t addr, uint8_t val, void *priv)
svga_recalctimings(svga);
}
break;
default:
break;
}
svga_out(addr, val, svga);
}
@@ -241,6 +253,9 @@ tvga_in(uint16_t addr, void *priv)
return tvga->tvga_3d8;
case 0x3d9:
return tvga->tvga_3d9;
default:
break;
}
return svga_in(addr, svga);
}
@@ -261,9 +276,9 @@ tvga_recalcbanking(tvga_t *tvga)
void
tvga_recalctimings(svga_t *svga)
{
tvga_t *tvga = (tvga_t *) svga->priv;
int clksel;
int high_res_256 = 0;
const tvga_t *tvga = (tvga_t *) svga->priv;
int clksel;
int high_res_256 = 0;
if (!svga->rowoffset)
svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled,
@@ -346,6 +361,9 @@ tvga_recalctimings(svga_t *svga)
case 0xf:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 75000000.0;
break;
default:
break;
}
if (tvga->card_id != TVGA8900CLD_ID) {
@@ -378,6 +396,9 @@ tvga_recalctimings(svga_t *svga)
svga->render = svga_render_24bpp_highres;
svga->hdisp /= 3;
break;
default:
break;
}
svga->lowres = 0;
}
@@ -417,7 +438,7 @@ tvga_init(const device_t *info)
return NULL;
}
rom_init(&tvga->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&tvga->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
svga_init(info, &tvga->svga, tvga, tvga->vram_size,
tvga_recalctimings,

View File

@@ -27,15 +27,17 @@
#include <86box/timer.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/plat_fallthrough.h>
typedef struct
{
typedef struct tvp3026_ramdac_t {
PALETTE extpal;
uint32_t extpallook[256];
uint8_t cursor64_data[1024];
int hwc_y, hwc_x;
int hwc_y;
int hwc_x;
uint8_t ind_idx;
uint8_t dcc, dc_init;
uint8_t dcc;
uint8_t dc_init;
uint8_t ccr;
uint8_t true_color;
uint8_t latch_cntl;
@@ -48,10 +50,16 @@ typedef struct
uint8_t mode;
uint8_t pll_addr;
uint8_t clock_sel;
struct
{
uint8_t m, n, p;
struct {
uint8_t m;
uint8_t n;
uint8_t p;
} pix, mem, loop;
uint8_t gpio_cntl;
uint8_t gpio_data;
uint8_t (*gpio_read)(uint8_t cntl, void *priv);
void (*gpio_write)(uint8_t cntl, uint8_t val, void *priv);
void *gpio_priv;
} tvp3026_ramdac_t;
static void
@@ -83,15 +91,18 @@ tvp3026_set_bpp(tvp3026_ramdac_t *ramdac, svga_t *svga)
case 0x0f:
svga->bpp = 24;
break;
default:
break;
}
}
svga_recalctimings(svga);
}
void
tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga)
tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga)
{
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p;
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv;
uint32_t o32;
uint8_t *cd;
uint16_t index;
@@ -103,6 +114,7 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t
switch (rs) {
case 0x00: /* Palette Write Index Register (RS value = 0000) */
ramdac->ind_idx = val;
fallthrough;
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
case 0x03:
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
@@ -147,6 +159,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t
svga->dac_addr = (svga->dac_addr + 1) & 0xff;
svga->dac_pos = 0;
break;
default:
break;
}
break;
case 0x09: /* Direct Cursor Control (RS value = 1001) */
@@ -201,6 +216,16 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t
ramdac->misc = val;
svga->ramdac_type = (val & 0x08) ? RAMDAC_8BIT : RAMDAC_6BIT;
break;
case 0x2a: /* General-Purpose I/O Control */
ramdac->gpio_cntl = val;
if (ramdac->gpio_write)
ramdac->gpio_write(ramdac->gpio_cntl, ramdac->gpio_data, ramdac->gpio_priv);
break;
case 0x2b: /* General-Purpose I/O Data */
ramdac->gpio_data = val;
if (ramdac->gpio_write)
ramdac->gpio_write(ramdac->gpio_cntl, ramdac->gpio_data, ramdac->gpio_priv);
break;
case 0x2c: /* PLL Address */
ramdac->pll_addr = val;
break;
@@ -215,6 +240,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t
case 2:
ramdac->pix.p = val;
break;
default:
break;
}
ramdac->pll_addr = ((ramdac->pll_addr + 1) & 3) | (ramdac->pll_addr & 0xfc);
break;
@@ -229,6 +257,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t
case 2:
ramdac->mem.p = val;
break;
default:
break;
}
ramdac->pll_addr = ((ramdac->pll_addr + 4) & 0x0c) | (ramdac->pll_addr & 0xf3);
break;
@@ -243,12 +274,18 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t
case 2:
ramdac->loop.p = val;
break;
default:
break;
}
ramdac->pll_addr = ((ramdac->pll_addr + 0x10) & 0x30) | (ramdac->pll_addr & 0xcf);
break;
case 0x39: /* MCLK/Loop Clock Control */
ramdac->mclk = val;
break;
default:
break;
}
break;
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
@@ -273,17 +310,20 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t
ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8);
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
break;
default:
break;
}
return;
}
uint8_t
tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga)
{
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p;
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv;
uint8_t temp = 0xff;
uint8_t *cd;
const uint8_t *cd;
uint16_t index;
uint8_t rs = (addr & 0x03);
uint16_t da_mask = 0x03ff;
@@ -327,6 +367,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
else
temp = ramdac->extpal[index].b & 0x3f;
break;
default:
break;
}
break;
case 0x09: /* Direct Cursor Control (RS value = 1001) */
@@ -361,6 +404,16 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
case 0x1e: /* Miscellaneous Control */
temp = ramdac->misc;
break;
case 0x2a: /* General-Purpose I/O Control */
temp = ramdac->gpio_cntl;
break;
case 0x2b: /* General-Purpose I/O Data */
if (ramdac->gpio_read) {
temp = 0xe0 | (ramdac->gpio_cntl & 0x1f); /* keep upper bits untouched */
ramdac->gpio_data = (ramdac->gpio_data & temp) | (ramdac->gpio_read(ramdac->gpio_cntl, ramdac->gpio_priv) & ~temp);
}
temp = ramdac->gpio_data;
break;
case 0x2c: /* PLL Address */
temp = ramdac->pll_addr;
break;
@@ -378,6 +431,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
case 3:
temp = 0x40; /*PLL locked to frequency*/
break;
default:
break;
}
break;
case 0x2e: /* Memory Clock PLL Data */
@@ -394,6 +450,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
case 3:
temp = 0x40; /*PLL locked to frequency*/
break;
default:
break;
}
break;
case 0x2f: /* Loop Clock PLL Data */
@@ -407,6 +466,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
case 2:
temp = ramdac->loop.p;
break;
default:
break;
}
break;
case 0x39: /* MCLK/Loop Clock Control */
@@ -415,6 +477,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
case 0x3f: /* ID */
temp = 0x26;
break;
default:
break;
}
break;
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
@@ -436,17 +501,45 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
case 0x0f: /* Cursor Y High Register (RS value = 1111) */
temp = (ramdac->hwc_y >> 8) & 0xff;
break;
default:
break;
}
return temp;
}
void
tvp3026_recalctimings(void *p, svga_t *svga)
tvp3026_recalctimings(void *priv, svga_t *svga)
{
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p;
const tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv;
svga->interlace = (ramdac->ccr & 0x40);
/* TODO: Figure out gamma correction for 15/16 bpp color. */
svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00);
}
uint32_t
tvp3026_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp)
{
uint32_t ret = 0x00000000;
if (svga->lut_map) {
if (bpp == 15) {
uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]);
uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 2]);
uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 7]);
ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b);
} else {
uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]);
uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 3]);
uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 8]);
ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b);
}
} else
ret = (bpp == 15) ? video_15to32[color] : video_16to32[color];
return ret;
}
void
@@ -466,7 +559,7 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine)
uint32_t clr2;
uint32_t clr3;
uint32_t *p;
uint8_t *cd;
const uint8_t *cd;
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) svga->ramdac;
clr1 = ramdac->extpallook[1];
@@ -513,6 +606,9 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine)
case 3:
p[x_pos] = clr3;
break;
default:
break;
}
break;
case 2: /* XGA */
@@ -526,6 +622,9 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine)
case 3:
p[x_pos] ^= 0xffffff;
break;
default:
break;
}
break;
case 3: /* X-Windows */
@@ -536,8 +635,14 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine)
case 3:
p[x_pos] = clr2;
break;
default:
break;
}
break;
default:
break;
}
}
offset++;
@@ -552,12 +657,12 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine)
float
tvp3026_getclock(int clock, void *priv)
{
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv;
int n;
int m;
int pl;
float f_vco;
float f_pll;
const tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv;
int n;
int m;
int pl;
float f_vco;
float f_pll;
if (clock == 0)
return 25175000.0;
@@ -569,12 +674,24 @@ tvp3026_getclock(int clock, void *priv)
n = ramdac->pix.n & 0x3f;
m = ramdac->pix.m & 0x3f;
pl = ramdac->pix.p & 0x03;
f_vco = 8.0 * 14318184 * (float) (65 - m) / (float) (65 - n);
f_vco = 8.0f * 14318184 * (float) (65 - m) / (float) (65 - n);
f_pll = f_vco / (float) (1 << pl);
return f_pll;
}
void
tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv),
void (*write)(uint8_t cntl, uint8_t val, void *priv),
void *cb_priv, void *priv)
{
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv;
ramdac->gpio_read = read;
ramdac->gpio_write = write;
ramdac->gpio_priv = cb_priv;
}
void *
tvp3026_ramdac_init(const device_t *info)
{

View File

@@ -160,8 +160,8 @@ voodoo_readw(uint32_t addr, void *priv)
if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/
{
if (SLI_ENABLED) {
voodoo_set_t *set = voodoo->set;
int y = (addr >> 11) & 0x3ff;
const voodoo_set_t *set = voodoo->set;
int y = (addr >> 11) & 0x3ff;
if (y & 1)
voodoo = set->voodoos[1];
@@ -194,13 +194,12 @@ voodoo_readl(uint32_t addr, void *priv)
cycles -= voodoo->read_time;
if (addr & 0x800000) /*Texture*/
{
if (addr & 0x800000) { /*Texture*/
} else if (addr & 0x400000) /*Framebuffer*/
{
if (SLI_ENABLED) {
voodoo_set_t *set = voodoo->set;
int y = (addr >> 11) & 0x3ff;
const voodoo_set_t *set = voodoo->set;
int y = (addr >> 11) & 0x3ff;
if (y & 1)
voodoo = set->voodoos[1];
@@ -429,7 +428,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv)
{
voodoo_queue_command(voodoo, addr | FIFO_WRITEL_FB, val);
} else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) {
// voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask);
#if 0
voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask);
#endif
*(uint32_t *) &voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val;
voodoo->cmdfifo_depth_wr++;
if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20)
@@ -492,7 +493,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv)
if (voodoo->initEnable & 0x01) {
voodoo->fbiInit4 = val;
voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1);
// voodoo_log("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time);
#if 0
voodoo_log("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time);
#endif
}
break;
case SST_backPorch:
@@ -538,7 +541,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv)
voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5);
voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0);
voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1);
// voodoo_log("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time);
#if 0
voodoo_log("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time);
#endif
}
break;
case SST_fbiInit2:
@@ -590,6 +595,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv)
case 0x0b:
voodoo->dac_readdata = 0x79;
break;
default:
break;
}
} else
voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata & 7];
@@ -599,7 +607,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv)
voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val;
else
voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8);
// voodoo_log("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]);
#if 0
voodoo_log("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]);
#endif
voodoo->dac_reg_ff = !voodoo->dac_reg_ff;
if (!voodoo->dac_reg_ff)
voodoo->dac_data[4]++;
@@ -642,7 +652,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv)
case SST_cmdFifoBaseAddr:
voodoo->cmdfifo_base = (val & 0x3ff) << 12;
voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12;
// voodoo_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end);
#if 0
voodoo_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end);
#endif
break;
case SST_cmdFifoRdPtr:
@@ -672,14 +684,14 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv)
static uint16_t
voodoo_snoop_readw(uint32_t addr, void *priv)
{
voodoo_set_t *set = (voodoo_set_t *) priv;
const voodoo_set_t *set = (voodoo_set_t *) priv;
return voodoo_readw(addr, set->voodoos[0]);
}
static uint32_t
voodoo_snoop_readl(uint32_t addr, void *priv)
{
voodoo_set_t *set = (voodoo_set_t *) priv;
const voodoo_set_t *set = (voodoo_set_t *) priv;
return voodoo_readl(addr, set->voodoos[0]);
}
@@ -687,7 +699,7 @@ voodoo_snoop_readl(uint32_t addr, void *priv)
static void
voodoo_snoop_writew(uint32_t addr, uint16_t val, void *priv)
{
voodoo_set_t *set = (voodoo_set_t *) priv;
const voodoo_set_t *set = (voodoo_set_t *) priv;
voodoo_writew(addr, val, set->voodoos[0]);
voodoo_writew(addr, val, set->voodoos[1]);
@@ -695,7 +707,7 @@ voodoo_snoop_writew(uint32_t addr, uint16_t val, void *priv)
static void
voodoo_snoop_writel(uint32_t addr, uint32_t val, void *priv)
{
voodoo_set_t *set = (voodoo_set_t *) priv;
const voodoo_set_t *set = (voodoo_set_t *) priv;
voodoo_writel(addr, val, set->voodoos[0]);
voodoo_writel(addr, val, set->voodoos[1]);
@@ -749,7 +761,7 @@ voodoo_recalcmapping(voodoo_set_t *set)
uint8_t
voodoo_pci_read(int func, int addr, void *priv)
{
voodoo_t *voodoo = (voodoo_t *) priv;
const voodoo_t *voodoo = (voodoo_t *) priv;
if (func)
return 0;
@@ -803,6 +815,9 @@ voodoo_pci_read(int func, int addr, void *priv)
return (voodoo->initEnable >> 16) & 0xff;
case 0x43:
return (voodoo->initEnable >> 24) & 0xff;
default:
break;
}
return 0;
}
@@ -844,13 +859,16 @@ voodoo_pci_write(int func, int addr, uint8_t val, void *priv)
voodoo->initEnable = (voodoo->initEnable & ~0xff000000) | (val << 24);
voodoo_recalcmapping(voodoo->set);
break;
default:
break;
}
}
static void
voodoo_speed_changed(void *priv)
{
voodoo_set_t *voodoo_set = (voodoo_set_t *) priv;
const voodoo_set_t *voodoo_set = (voodoo_set_t *) priv;
voodoo_pixelclock_update(voodoo_set->voodoos[0]);
voodoo_set->voodoos[0]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit4 & 1) ? 2 : 1);
@@ -870,7 +888,7 @@ voodoo_speed_changed(void *priv)
static void
voodoo_force_blit(void *priv)
{
voodoo_set_t *voodoo_set = (voodoo_set_t *) priv;
const voodoo_set_t *voodoo_set = (voodoo_set_t *) priv;
thread_wait_mutex(voodoo_set->voodoos[0]->force_blit_mutex);
if (voodoo_set->voodoos[0]->can_blit) {
@@ -916,6 +934,9 @@ voodoo_card_init(void)
case VOODOO_2:
voodoo->dual_tmus = 1;
break;
default:
break;
}
if (voodoo->type == VOODOO_2) /*generate filter lookup tables*/
@@ -923,7 +944,7 @@ voodoo_card_init(void)
else
voodoo_generate_filter_v1(voodoo);
pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo);
pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo, &voodoo->pci_slot);
mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo);
@@ -1163,7 +1184,7 @@ voodoo_2d3d_card_init(int type)
}
void *
voodoo_init(const device_t *info)
voodoo_init(UNUSED(const device_t *info))
{
voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t));
uint32_t tmuConfig = 1;
@@ -1205,6 +1226,9 @@ voodoo_init(const device_t *info)
case VOODOO_2:
tmuConfig = 1 | (3 << 6);
break;
default:
break;
}
voodoo_set->voodoos[0]->tmuConfig = tmuConfig;

View File

@@ -142,8 +142,11 @@ typedef struct banshee_t {
int desktop_y;
uint32_t desktop_stride_tiled;
int type, card, agp, has_bios;
int vblank_irq;
int type, agp;
int has_bios, vblank_irq;
uint8_t pci_slot;
uint8_t irq_state;
void *i2c, *i2c_ddc, *ddc;
} banshee_t;
@@ -208,6 +211,7 @@ enum {
Agp_agpGraphicsStride = 0x10,
};
#define VGAINIT0_RAMDAC_8BIT (1 << 2)
#define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12)
#define VIDPROCCFG_VIDPROC_ENABLE (1 << 0)
@@ -215,7 +219,9 @@ enum {
#define VIDPROCCFG_INTERLACE (1 << 3)
#define VIDPROCCFG_HALF_MODE (1 << 4)
#define VIDPROCCFG_OVERLAY_ENABLE (1 << 8)
#define VIDPROCCFG_DESKTOP_CLUT_BYPASS (1 << 10)
#define VIDPROCCFG_OVERLAY_CLUT_BYPASS (1 << 11)
#define VIDPROCCFG_DESKTOP_CLUT_SEL (1 << 12)
#define VIDPROCCFG_OVERLAY_CLUT_SEL (1 << 13)
#define VIDPROCCFG_H_SCALE_ENABLE (1 << 14)
#define VIDPROCCFG_V_SCALE_ENABLE (1 << 15)
@@ -306,9 +312,9 @@ static void
banshee_update_irqs(banshee_t *banshee)
{
if (banshee->vblank_irq > 0 && banshee_vga_vsync_enabled(banshee)) {
pci_set_irq(banshee->card, PCI_INTA);
pci_set_irq(banshee->pci_slot, PCI_INTA, &banshee->irq_state);
} else {
pci_clear_irq(banshee->card, PCI_INTA);
pci_clear_irq(banshee->pci_slot, PCI_INTA, &banshee->irq_state);
}
}
@@ -370,6 +376,9 @@ banshee_out(uint16_t addr, uint8_t val, void *priv)
}
}
break;
default:
break;
}
svga_out(addr, val, svga);
}
@@ -430,8 +439,7 @@ banshee_updatemapping(banshee_t *banshee)
}
banshee_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc);
switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/
{
switch (svga->gdcreg[6] & 0xc) { /*Banked framebuffer*/
case 0x0: /*128k at A0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
svga->banked_mask = 0xffff;
@@ -448,6 +456,9 @@ banshee_updatemapping(banshee_t *banshee)
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
svga->banked_mask = 0x7fff;
break;
default:
break;
}
banshee_log("Linear framebuffer %08X ", banshee->memBaseAddr1);
@@ -457,11 +468,37 @@ banshee_updatemapping(banshee_t *banshee)
mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20);
}
uint32_t
banshee_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp)
{
banshee_t *banshee = (banshee_t *) svga->priv;
uint32_t ret = 0x00000000;
uint16_t src_b = (color & 0x1f) << 3;
uint16_t src_g = (color & 0x7e0) >> 3;
uint16_t src_r = (color & 0xf800) >> 8;
if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_CLUT_SEL) {
src_b += 256;
src_g += 256;
src_r += 256;
}
if (svga->lut_map) {
uint8_t b = getcolr(svga->pallook[src_b]);
uint8_t g = getcolg(svga->pallook[src_g]);
uint8_t r = getcolb(svga->pallook[src_r]);
ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b);
} else
ret = video_16to32[color];
return ret;
}
static void
banshee_render_16bpp_tiled(svga_t *svga)
{
banshee_t *banshee = (banshee_t *) svga->priv;
uint32_t *p = &((uint32_t *) svga->monitor->target_buffer->line[svga->displine + svga->y_add])[svga->x_add];
uint32_t *p = &(svga->monitor->target_buffer->line[svga->displine + svga->y_add])[svga->x_add];
uint32_t addr;
int drawn = 0;
@@ -477,10 +514,10 @@ banshee_render_16bpp_tiled(svga_t *svga)
if (svga->hwcursor_on || svga->overlay_on)
svga->changedvram[addr >> 12] = 2;
if (svga->changedvram[addr >> 12] || svga->fullchange) {
uint16_t *vram_p = (uint16_t *) &svga->vram[addr & svga->vram_display_mask];
const uint16_t *vram_p = (uint16_t *) &svga->vram[addr & svga->vram_display_mask];
for (uint8_t xx = 0; xx < 64; xx++)
*p++ = video_16to32[*vram_p++];
*p++ = banshee_conv_16to32(svga, *vram_p++, 16);
drawn = 1;
} else
@@ -500,8 +537,8 @@ banshee_render_16bpp_tiled(svga_t *svga)
static void
banshee_recalctimings(svga_t *svga)
{
banshee_t *banshee = (banshee_t *) svga->priv;
voodoo_t *voodoo = banshee->voodoo;
banshee_t *banshee = (banshee_t *) svga->priv;
const voodoo_t *voodoo = banshee->voodoo;
/*7 R/W Horizontal Retrace End bit 5. -
6 R/W Horizontal Retrace Start bit 8 0x4
@@ -757,6 +794,7 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv)
break;
case Init_vgaInit0:
banshee->vgaInit0 = val;
svga_set_ramdac_type(svga, (val & VGAINIT0_RAMDAC_8BIT ? RAMDAC_8BIT : RAMDAC_6BIT));
break;
case Init_vgaInit1:
banshee->vgaInit1 = val;
@@ -796,6 +834,7 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv)
banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT;
svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA;
svga->fullchange = changeframecount;
svga->lut_map = !(val & VIDPROCCFG_DESKTOP_CLUT_BYPASS) && (svga->bpp < 24);
svga_recalctimings(svga);
break;
@@ -905,10 +944,11 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv)
svga->fullchange = changeframecount;
svga_recalctimings(svga);
break;
#if 0
default:
#if 0
fatal("bad banshee_ext_outl: addr=%04x val=%08x\n", addr, val);
#endif
break;
}
}
@@ -996,15 +1036,14 @@ banshee_ext_in(uint16_t addr, void *priv)
static uint32_t
banshee_status(banshee_t *banshee)
{
voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
int fifo_entries = FIFO_ENTRIES;
int swap_count = voodoo->swap_count;
int written = voodoo->cmd_written + voodoo->cmd_written_fifo;
int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy;
uint32_t ret;
voodoo_t *voodoo = banshee->voodoo;
const svga_t *svga = &banshee->svga;
int fifo_entries = FIFO_ENTRIES;
int swap_count = voodoo->swap_count;
int written = voodoo->cmd_written + voodoo->cmd_written_fifo;
int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy;
uint32_t ret = 0;
ret = 0;
if (fifo_entries < 0x20)
ret |= 0x1f - fifo_entries;
else
@@ -1037,10 +1076,10 @@ banshee_status(banshee_t *banshee)
static uint32_t
banshee_ext_inl(uint16_t addr, void *priv)
{
banshee_t *banshee = (banshee_t *) priv;
voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
uint32_t ret = 0xffffffff;
banshee_t *banshee = (banshee_t *) priv;
const voodoo_t *voodoo = banshee->voodoo;
const svga_t *svga = &banshee->svga;
uint32_t ret = 0xffffffff;
cycles -= voodoo->read_time;
@@ -1212,8 +1251,8 @@ banshee_reg_readw(uint32_t addr, void *priv)
static uint32_t
banshee_cmd_read(banshee_t *banshee, uint32_t addr)
{
voodoo_t *voodoo = banshee->voodoo;
uint32_t ret = 0xffffffff;
const voodoo_t *voodoo = banshee->voodoo;
uint32_t ret = 0xffffffff;
switch (addr & 0x1fc) {
case Agp_agpHostAddressLow:
@@ -1419,6 +1458,9 @@ banshee_reg_readl(uint32_t addr, void *priv)
break;
}
break;
default:
break;
}
#if 0
@@ -1467,6 +1509,9 @@ banshee_reg_writew(uint32_t addr, uint16_t val, void *priv)
case 0x1f00000:
voodoo_queue_command(voodoo, (addr & 0xffffff) | FIFO_WRITEW_FB, val);
break;
default:
break;
}
}
@@ -1679,15 +1724,18 @@ banshee_reg_writel(uint32_t addr, uint32_t val, void *priv)
case 0x1f00000:
voodoo_queue_command(voodoo, (addr & 0xfffffc) | FIFO_WRITEL_FB, val);
break;
default:
break;
}
}
static uint8_t
banshee_read_linear(uint32_t addr, void *priv)
{
banshee_t *banshee = (banshee_t *) priv;
voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
banshee_t *banshee = (banshee_t *) priv;
const voodoo_t *voodoo = banshee->voodoo;
const svga_t *svga = &banshee->svga;
cycles -= voodoo->read_time;
@@ -1723,9 +1771,9 @@ banshee_read_linear(uint32_t addr, void *priv)
static uint16_t
banshee_read_linear_w(uint32_t addr, void *priv)
{
banshee_t *banshee = (banshee_t *) priv;
voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
banshee_t *banshee = (banshee_t *) priv;
const voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
if (addr & 1)
return banshee_read_linear(addr, priv) | (banshee_read_linear(addr + 1, priv) << 8);
@@ -1763,9 +1811,9 @@ banshee_read_linear_w(uint32_t addr, void *priv)
static uint32_t
banshee_read_linear_l(uint32_t addr, void *priv)
{
banshee_t *banshee = (banshee_t *) priv;
voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
banshee_t *banshee = (banshee_t *) priv;
const voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
if (addr & 3)
return banshee_read_linear_w(addr, priv) | (banshee_read_linear_w(addr + 2, priv) << 16);
@@ -1804,9 +1852,9 @@ banshee_read_linear_l(uint32_t addr, void *priv)
static void
banshee_write_linear(uint32_t addr, uint8_t val, void *priv)
{
banshee_t *banshee = (banshee_t *) priv;
voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
banshee_t *banshee = (banshee_t *) priv;
const voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
cycles -= voodoo->write_time;
@@ -1839,9 +1887,9 @@ banshee_write_linear(uint32_t addr, uint8_t val, void *priv)
static void
banshee_write_linear_w(uint32_t addr, uint16_t val, void *priv)
{
banshee_t *banshee = (banshee_t *) priv;
voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
banshee_t *banshee = (banshee_t *) priv;
const voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
if (addr & 1) {
banshee_write_linear(addr, val, priv);
@@ -1981,14 +2029,14 @@ banshee_write_linear_l(uint32_t addr, uint32_t val, void *priv)
void
banshee_hwcursor_draw(svga_t *svga, int displine)
{
banshee_t *banshee = (banshee_t *) svga->priv;
int x;
int x_off;
int xx;
uint32_t col0 = banshee->hwCurC0;
uint32_t col1 = banshee->hwCurC1;
uint8_t plane0[8];
uint8_t plane1[8];
const banshee_t *banshee = (banshee_t *) svga->priv;
int x;
int x_off;
int xx;
uint32_t col0 = banshee->hwCurC0;
uint32_t col1 = banshee->hwCurC1;
uint8_t plane0[8];
uint8_t plane1[8];
for (uint8_t c = 0; c < 8; c++)
plane0[c] = svga->vram[svga->hwcursor_latch.addr + c];
@@ -2004,7 +2052,7 @@ banshee_hwcursor_draw(svga_t *svga, int displine)
if (x_off > -8) {
for (xx = 0; xx < 8; xx++) {
if (plane0[x >> 3] & (1 << 7))
((uint32_t *) svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0;
(svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0;
plane0[x >> 3] <<= 1;
plane1[x >> 3] <<= 1;
@@ -2019,9 +2067,9 @@ banshee_hwcursor_draw(svga_t *svga, int displine)
if (x_off > -8) {
for (xx = 0; xx < 8; xx++) {
if (!(plane0[x >> 3] & (1 << 7)))
((uint32_t *) svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0;
(svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0;
else if (plane1[x >> 3] & (1 << 7))
((uint32_t *) svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff;
(svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff;
plane0[x >> 3] <<= 1;
plane1[x >> 3] <<= 1;
@@ -2186,8 +2234,6 @@ banshee_hwcursor_draw(svga_t *svga, int displine)
void
voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg)
{
int g;
int h;
float difference;
float diffg;
float thiscol;
@@ -2201,10 +2247,8 @@ voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg)
fcg *= hack;
/* box prefilter */
for (g = 0; g < 256; g++) // pixel 1 - our target pixel we want to bleed into
{
for (h = 0; h < 256; h++) // pixel 2 - our main pixel
{
for (uint16_t g = 0; g < 256; g++) { // pixel 1 - our target pixel we want to bleed into
for (uint16_t h = 0; h < 256; h++) { // pixel 2 - our main pixel
float avg;
float avgdiff;
@@ -2286,10 +2330,8 @@ voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg)
fcg *= 6;
#endif
for (g = 0; g < 256; g++) // pixel 1
{
for (h = 0; h < 256; h++) // pixel 2
{
for (uint16_t g = 0; g < 256; g++) { // pixel 1
for (uint16_t h = 0; h < 256; h++) { // pixel 2
difference = (float) (h - g);
diffg = difference;
@@ -2329,18 +2371,18 @@ voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg)
static void
banshee_overlay_draw(svga_t *svga, int displine)
{
banshee_t *banshee = (banshee_t *) svga->priv;
voodoo_t *voodoo = banshee->voodoo;
uint32_t *p;
int x;
int y = voodoo->overlay.src_y >> 20;
uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : y * svga->overlay_latch.pitch);
uint32_t src_addr2 = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? (((y + 1) & 31) * 128 + ((y + 1) >> 5) * svga->overlay_latch.pitch) : (y + 1) * svga->overlay_latch.pitch);
uint8_t *src = &svga->vram[src_addr & svga->vram_mask];
uint32_t src_x = 0;
unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4;
int skip_filtering;
uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0];
banshee_t *banshee = (banshee_t *) svga->priv;
voodoo_t *voodoo = banshee->voodoo;
uint32_t *p;
int x;
int y = voodoo->overlay.src_y >> 20;
uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : y * svga->overlay_latch.pitch);
uint32_t src_addr2 = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? (((y + 1) & 31) * 128 + ((y + 1) >> 5) * svga->overlay_latch.pitch) : (y + 1) * svga->overlay_latch.pitch);
uint8_t *src = &svga->vram[src_addr & svga->vram_mask];
uint32_t src_x = 0;
unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4;
int skip_filtering;
const uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0];
if (svga->render == svga_render_null && !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && !svga->fullchange && ((voodoo->overlay.src_y >> 20) < 2048 && !voodoo->dirty_line[voodoo->overlay.src_y >> 20]) && !(banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) {
voodoo->overlay.src_y += (1 << 20);
@@ -2354,7 +2396,7 @@ banshee_overlay_draw(svga_t *svga, int displine)
if (src_addr >= 0x800000)
fatal("overlay out of range!\n");
#endif
p = &((uint32_t *) svga->monitor->target_buffer->line[displine])[svga->overlay_latch.x + svga->x_add];
p = &(svga->monitor->target_buffer->line[displine])[svga->overlay_latch.x + svga->x_add];
if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled)
skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_4X4) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_2X2));
@@ -2608,7 +2650,7 @@ banshee_vsync_callback(svga_t *svga)
static uint8_t
banshee_pci_read(int func, int addr, void *priv)
{
banshee_t *banshee = (banshee_t *) priv;
const banshee_t *banshee = (banshee_t *) priv;
#if 0
svga_t *svga = &banshee->svga;
#endif
@@ -2803,6 +2845,9 @@ banshee_pci_read(int func, int addr, void *priv)
case 0x67:
ret = banshee->pci_regs[0x67];
break;
default:
break;
}
#if 0
banshee_log("%02X\n", ret);
@@ -2932,6 +2977,9 @@ banshee_pci_write(int func, int addr, uint8_t val, void *priv)
case 0x66:
banshee->pci_regs[0x66] = val & 0xc0;
return;
default:
break;
}
}
@@ -3146,10 +3194,13 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int
banshee->dramInit1 = 1 << 30; /*SDRAM*/
banshee->svga.decode_mask = 0x1ffffff;
banshee->card = pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee);
if (banshee->has_bios)
pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_NORMAL, banshee_pci_read, banshee_pci_write, banshee, &banshee->pci_slot);
else
pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee, &banshee->pci_slot);
banshee->voodoo = voodoo_2d3d_card_init(voodoo_type);
banshee->voodoo->p = banshee;
banshee->voodoo->priv = banshee;
banshee->voodoo->vram = banshee->svga.vram;
banshee->voodoo->changedvram = banshee->svga.changedvram;
banshee->voodoo->fb_mem = banshee->svga.vram;
@@ -3168,6 +3219,8 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int
banshee->i2c_ddc = i2c_gpio_init("ddc_voodoo_banshee");
banshee->ddc = ddc_init(i2c_gpio_get_bus(banshee->i2c_ddc));
banshee->svga.conv_16to32 = banshee_conv_16to32;
switch (type) {
case TYPE_BANSHEE:
if (has_sgram) {
@@ -3238,6 +3291,9 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int
banshee->pci_regs[0x2e] = 0x54;
banshee->pci_regs[0x2f] = 0x00;
break;
default:
break;
}
video_inform(VIDEO_FLAG_TYPE_SPECIAL, banshee->agp ? &timing_banshee_agp : &timing_banshee);

View File

@@ -250,6 +250,9 @@ PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask,
voodoo->changedvram[addr >> 12] = changeframecount;
break;
}
default:
break;
}
}
@@ -293,6 +296,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern,
voodoo->changedvram[addr >> 12] = changeframecount;
break;
}
default:
break;
}
}
@@ -364,6 +370,9 @@ update_src_stride(voodoo_t *voodoo)
bansheeblt_log("Dword packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest);
#endif
break;
default:
break;
}
}
@@ -385,12 +394,12 @@ end_command(voodoo_t *voodoo)
static void
banshee_do_rectfill(voodoo_t *voodoo)
{
clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
int dst_y = voodoo->banshee_blt.dstY;
uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern;
int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY);
int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO);
uint8_t rop = voodoo->banshee_blt.command >> 24;
const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
int dst_y = voodoo->banshee_blt.dstY;
const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern;
int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY);
int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO);
uint8_t rop = voodoo->banshee_blt.command >> 24;
#if 0
bansheeblt_log("banshee_do_rectfill: size=%i,%i dst=%i,%i\n", voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY);
@@ -519,13 +528,13 @@ DECODE_YUYV422_16BPP(uint16_t *buf, uint8_t *src)
static void
do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x, int src_tiled)
{
clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
int dst_y = voodoo->banshee_blt.dstY;
int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY);
uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern;
int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO);
uint8_t rop = voodoo->banshee_blt.command >> 24;
int src_colorkey;
const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
int dst_y = voodoo->banshee_blt.dstY;
int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY);
const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern;
int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO);
uint8_t rop = voodoo->banshee_blt.command >> 24;
int src_colorkey;
switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) {
case SRC_FORMAT_COL_8_BPP:
@@ -601,6 +610,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr
voodoo->changedvram[dst_addr >> 12] = changeframecount;
break;
}
default:
break;
}
}
if (use_x_dir) {
@@ -619,7 +631,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr
} else {
/*Conversion required*/
if (dst_y >= clip->y_min && dst_y < clip->y_max) {
// int src_x = voodoo->banshee_blt.srcX;
#if 0
int src_x = voodoo->banshee_blt.srcX;
#endif
int dst_x = voodoo->banshee_blt.dstX;
int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX;
uint8_t pattern_mask = pattern_mono[pat_y & 7];
@@ -777,7 +791,7 @@ banshee_do_screen_to_screen_blt(voodoo_t *voodoo)
}
static void
banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t data)
banshee_do_host_to_screen_blt(voodoo_t *voodoo, UNUSED(int count), uint32_t data)
{
#if 0
if (voodoo->banshee_blt.dstBaseAddr == 0xee5194)
@@ -849,15 +863,15 @@ banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t data)
static void
do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, int *src_y)
{
clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
#if 0
int src_y = voodoo->banshee_blt.srcY;
#endif
int dst_y = voodoo->banshee_blt.dstY;
int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY);
uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern;
int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO);
uint32_t *colorPattern = voodoo->banshee_blt.colorPattern;
int dst_y = voodoo->banshee_blt.dstY;
int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY);
const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern;
int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO);
const uint32_t *colorPattern = voodoo->banshee_blt.colorPattern;
#if 0
int error_y = voodoo->banshee_blt.dstSizeY / 2;
@@ -891,7 +905,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in
uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8];
voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8);
// bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]);
#if 0
bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]);
#endif
voodoo->changedvram[dst_addr >> 12] = changeframecount;
break;
}
@@ -937,6 +953,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in
voodoo->changedvram[dst_addr >> 12] = changeframecount;
break;
}
default:
break;
}
}
@@ -1063,16 +1082,16 @@ step_line(voodoo_t *voodoo)
static void
banshee_do_line(voodoo_t *voodoo, int draw_last_pixel)
{
clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
uint8_t rop = voodoo->banshee_blt.command >> 24;
int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX);
int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY);
int x_inc = (voodoo->banshee_blt.dstX > voodoo->banshee_blt.srcX) ? 1 : -1;
int y_inc = (voodoo->banshee_blt.dstY > voodoo->banshee_blt.srcY) ? 1 : -1;
int x = voodoo->banshee_blt.srcX;
int y = voodoo->banshee_blt.srcY;
int error;
uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ? voodoo->banshee_blt.lineStipple : ~0;
const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
uint8_t rop = voodoo->banshee_blt.command >> 24;
int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX);
int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY);
int x_inc = (voodoo->banshee_blt.dstX > voodoo->banshee_blt.srcX) ? 1 : -1;
int y_inc = (voodoo->banshee_blt.dstY > voodoo->banshee_blt.srcY) ? 1 : -1;
int x = voodoo->banshee_blt.srcX;
int y = voodoo->banshee_blt.srcY;
int error;
uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ? voodoo->banshee_blt.lineStipple : ~0;
if (dx > dy) /*X major*/
{
@@ -1143,12 +1162,12 @@ banshee_polyfill_start(voodoo_t *voodoo)
static void
banshee_polyfill_continue(voodoo_t *voodoo, uint32_t data)
{
clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern;
int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO);
uint8_t rop = voodoo->banshee_blt.command >> 24;
int y = MAX(voodoo->banshee_blt.ly[0], voodoo->banshee_blt.ry[0]);
int y_end;
const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern;
int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO);
uint8_t rop = voodoo->banshee_blt.command >> 24;
int y = MAX(voodoo->banshee_blt.ly[0], voodoo->banshee_blt.ry[0]);
int y_end;
#if 0
bansheeblt_log("Polyfill : data %08x\n", data);

View File

@@ -163,8 +163,6 @@ voodoo_v2_blit_start(voodoo_t *voodoo)
int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) : (voodoo->bltDstXYStride & 0xff8);
uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8);
uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8);
int x;
int y;
#if 0
voodooblt_log("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n",
@@ -175,13 +173,13 @@ voodoo_v2_blit_start(voodoo_t *voodoo)
switch (voodoo->bltCommand & BLIT_COMMAND_MASK) {
case BLIT_COMMAND_SCREEN_TO_SCREEN:
for (y = 0; y <= size_y; y++) {
uint16_t *src = (uint16_t *) &voodoo->fb_mem[src_base_addr + src_y * src_stride];
uint16_t *dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride];
int src_x = voodoo->bltSrcX;
int dst_x = voodoo->bltDstX;
for (int y = 0; y <= size_y; y++) {
const uint16_t *src = (uint16_t *) &voodoo->fb_mem[src_base_addr + src_y * src_stride];
uint16_t *dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride];
int src_x = voodoo->bltSrcX;
int dst_x = voodoo->bltDstX;
for (x = 0; x <= size_x; x++) {
for (int x = 0; x <= size_x; x++) {
uint16_t src_dat = src[src_x];
uint16_t dst_dat = dst[dst_x];
int rop = 0;
@@ -233,7 +231,7 @@ skip_pixel_blit:
break;
case BLIT_COMMAND_RECT_FILL:
for (y = 0; y <= size_y; y++) {
for (int y = 0; y <= size_y; y++) {
uint16_t *dst;
int dst_x = voodoo->bltDstX;
@@ -244,7 +242,7 @@ skip_pixel_blit:
} else
dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride];
for (x = 0; x <= size_x; x++) {
for (int x = 0; x <= size_x; x++) {
if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) {
if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY)
goto skip_pixel_fill;
@@ -267,7 +265,7 @@ skip_line_fill:
dat64 = voodoo->bltColorFg | ((uint64_t) voodoo->bltColorFg << 16) | ((uint64_t) voodoo->bltColorFg << 32) | ((uint64_t) voodoo->bltColorFg << 48);
for (y = 0; y <= size_y; y++) {
for (int y = 0; y <= size_y; y++) {
uint64_t *dst;
/*This may be wrong*/
@@ -284,7 +282,7 @@ skip_line_fill:
dst = (uint64_t *) &voodoo->fb_mem[(dst_y * 512 * 8 + dst_x * 8) & voodoo->fb_mask];
for (x = 0; x <= size_x; x++)
for (int x = 0; x <= size_x; x++)
dst[x] = dat64;
dst_y++;
@@ -347,6 +345,9 @@ voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data)
case BLIT_SRC_RGB_BGRA:
src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11);
break;
default:
break;
}
data >>= 16;
src_bits -= 16;
@@ -375,6 +376,9 @@ voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data)
g = (data >> 16) & 0xff;
b = (data >> 24) & 0xff;
break;
default:
break;
}
switch (voodoo->bltCommand & BLIT_SRC_FORMAT) {
case BLIT_SRC_24BPP:
@@ -392,9 +396,15 @@ voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data)
b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3];
src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8);
break;
default:
break;
}
src_bits = 0;
break;
default:
break;
}
if (SLI_ENABLED) {

View File

@@ -509,8 +509,8 @@ voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src,
void
voodoo_callback(void *priv)
{
voodoo_t *voodoo = (voodoo_t *) priv;
monitor_t *monitor = &monitors[voodoo->monitor_index];
voodoo_t *voodoo = (voodoo_t *) priv;
const monitor_t *monitor = &monitors[voodoo->monitor_index];
if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) {
if (voodoo->line < voodoo->v_disp) {

View File

@@ -76,7 +76,7 @@ voodoo_fb_readw(uint32_t addr, void *priv)
}
if (SLI_ENABLED) {
voodoo_set_t *set = voodoo->set;
const voodoo_set_t *set = voodoo->set;
if (y & 1)
voodoo = set->voodoos[1];
@@ -117,7 +117,7 @@ voodoo_fb_readl(uint32_t addr, void *priv)
}
if (SLI_ENABLED) {
voodoo_set_t *set = voodoo->set;
const voodoo_set_t *set = voodoo->set;
if (y & 1)
voodoo = set->voodoos[1];
@@ -170,16 +170,16 @@ do_dither(voodoo_params_t *params, rgba8_t col, int x, int y)
void
voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv)
{
voodoo_t *voodoo = (voodoo_t *) priv;
voodoo_params_t *params = &voodoo->params;
int x;
int y;
uint32_t write_addr;
uint32_t write_addr_aux;
rgba8_t colour_data;
uint16_t depth_data;
uint8_t alpha_data;
int write_mask = 0;
voodoo_t *voodoo = (voodoo_t *) priv;
const voodoo_params_t *params = &voodoo->params;
int x;
int y;
uint32_t write_addr;
uint32_t write_addr_aux;
rgba8_t colour_data;
uint16_t depth_data;
uint8_t alpha_data;
int write_mask = 0;
colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0;
@@ -310,17 +310,17 @@ skip_pixel:
void
voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv)
{
voodoo_t *voodoo = (voodoo_t *) priv;
voodoo_params_t *params = &voodoo->params;
int x;
int y;
uint32_t write_addr;
uint32_t write_addr_aux;
rgba8_t colour_data[2];
uint16_t depth_data[2];
uint8_t alpha_data[2];
int write_mask = 0;
int count = 1;
voodoo_t *voodoo = (voodoo_t *) priv;
const voodoo_params_t *params = &voodoo->params;
int x;
int y;
uint32_t write_addr;
uint32_t write_addr_aux;
rgba8_t colour_data[2];
uint16_t depth_data[2];
uint8_t alpha_data[2];
int write_mask = 0;
int count = 1;
depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff;
alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24;

View File

@@ -160,7 +160,7 @@ cmdfifo_get(voodoo_t *voodoo)
uint32_t val;
if (!voodoo->cmdfifo_in_sub) {
while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) {
while (voodoo->fifo_thread_run && (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr)) {
thread_wait_event(voodoo->wake_fifo_thread, -1);
thread_reset_event(voodoo->wake_fifo_thread);
}

View File

@@ -105,7 +105,7 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv)
voodoo_wait_for_render_thread_idle(voodoo);
if (!(val & 1)) {
banshee_set_overlay_addr(voodoo->p, voodoo->leftOverlayBuf);
banshee_set_overlay_addr(voodoo->priv, voodoo->leftOverlayBuf);
thread_wait_mutex(voodoo->swap_mutex);
if (voodoo->swap_count > 0)
voodoo->swap_count--;
@@ -1121,6 +1121,7 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv)
}
break;
}
fallthrough;
case SST_nccTable0_I2:
if (!(val & (1 << 31))) {
if (chip & CHIP_TREX0) {
@@ -1359,5 +1360,8 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv)
case SST_leftOverlayBuf:
voodoo->leftOverlayBuf = val;
break;
default:
break;
}
}

View File

@@ -475,6 +475,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta
case TC_MSELECT_LOD_FRAC:
factor_r = factor_g = factor_b = state->lod_frac[1];
break;
default:
break;
}
if (!c_reverse) {
r = (-state->tex_r[1] * (factor_r + 1)) >> 8;
@@ -520,6 +523,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta
case TCA_MSELECT_LOD_FRAC:
factor_a = state->lod_frac[1];
break;
default:
break;
}
if (!a_reverse)
a = (-state->tex_a[1] * ((factor_a ^ 0xff) + 1)) >> 8;
@@ -575,6 +581,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta
case TC_MSELECT_LOD_FRAC:
factor_r = factor_g = factor_b = state->lod_frac[0];
break;
default:
break;
}
if (!c_reverse) {
r = (r * (factor_r + 1)) >> 8;
@@ -622,6 +631,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta
case TCA_MSELECT_LOD_FRAC:
factor_a = state->lod_frac[0];
break;
default:
break;
}
if (a_reverse)
a = (a * ((factor_a ^ 0xff) + 1)) >> 8;
@@ -1073,6 +1085,9 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *
cother_g = src_g;
cother_b = src_b;
break;
default:
break;
}
switch (cca_localselect) {
@@ -1460,15 +1475,15 @@ voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even)
vertexCy_adjusted = (state.vertexCy + 7) >> 4;
if (state.vertexBy - state.vertexAy)
state.dxAB = (int) ((((int64_t) state.vertexBx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (int) (state.vertexBy - state.vertexAy);
state.dxAB = (int) ((((int64_t) state.vertexBx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (state.vertexBy - state.vertexAy);
else
state.dxAB = 0;
if (state.vertexCy - state.vertexAy)
state.dxAC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (int) (state.vertexCy - state.vertexAy);
state.dxAC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (state.vertexCy - state.vertexAy);
else
state.dxAC = 0;
if (state.vertexCy - state.vertexBy)
state.dxBC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexBx << 12)) << 4) / (int) (state.vertexCy - state.vertexBy);
state.dxBC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexBx << 12)) << 4) / (state.vertexCy - state.vertexBy);
else
state.dxBC = 0;

View File

@@ -192,7 +192,9 @@ voodoo_recalc_tex3(voodoo_t *voodoo, int tmu)
if ((voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) && (voodoo->params.tLOD[tmu] & LOD_ODD))
tex_lod++; /*Skip LOD 0*/
// voodoo_texture_log("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]);
#if 0
voodoo_texture_log("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]);
#endif
for (lod = 0; lod <= LOD_MAX + 1; lod++) {
if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) {
switch (tex_lod) {
@@ -302,18 +304,22 @@ voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu)
lod_min = (params->tLOD[tmu] >> 2) & 15;
lod_max = (params->tLOD[tmu] >> 8) & 15;
// voodoo_texture_log(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu);
#if 0
voodoo_texture_log(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu);
#endif
lod_min = MIN(lod_min, 8);
lod_max = MIN(lod_max, 8);
for (int lod = lod_min; lod <= lod_max; lod++) {
uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]];
uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask;
int x;
int y;
int shift = 8 - params->tex_lod[tmu][lod];
rgba_u *pal;
uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]];
uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask;
int x;
int y;
int shift = 8 - params->tex_lod[tmu][lod];
const rgba_u *pal;
// voodoo_texture_log(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]);
#if 0
voodoo_texture_log(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]);
#endif
switch (params->tformat[tmu]) {
case TEX_RGB332:
@@ -566,7 +572,9 @@ flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu)
if (addr_end_masked < addr_start_masked)
addr_end_masked = voodoo->texture_mask + 1;
if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked) {
// voodoo_texture_log(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base);
#if 0
voodoo_texture_log(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base);
#endif
if (voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[0] || (voodoo->render_threads == 2 && voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[1]))
wait_for_idle = 1;

View File

@@ -28,6 +28,7 @@
#include <86box/mem.h>
#include <86box/device.h>
#include <86box/video.h>
#include <86box/plat_unused.h>
#define WY700_XSIZE 1280
#define WY700_YSIZE 800
@@ -283,13 +284,17 @@ wy700_out(uint16_t addr, uint8_t val, void *priv)
case 0x3D9:
wy700->cga_colour = val;
return;
default:
break;
}
}
uint8_t
wy700_in(uint16_t addr, void *priv)
{
wy700_t *wy700 = (wy700_t *) priv;
const wy700_t *wy700 = (wy700_t *) priv;
switch (addr) {
case 0x3b0:
case 0x3b2:
@@ -318,6 +323,9 @@ wy700_in(uint16_t addr, void *priv)
return wy700->mda_stat;
case 0x3da:
return wy700->cga_stat;
default:
break;
}
return 0xff;
}
@@ -378,6 +386,9 @@ wy700_checkchanges(wy700_t *wy700)
case 7: /* Enable display */
wy700->enabled = 1;
break;
default:
break;
}
/* A control write with the top bit set selects graphics mode */
if (wy700->wy700_control & 0x80) {
@@ -477,9 +488,9 @@ wy700_write(uint32_t addr, uint8_t val, void *priv)
uint8_t
wy700_read(uint32_t addr, void *priv)
{
wy700_t *wy700 = (wy700_t *) priv;
if (wy700->wy700_mode & 0x80) /* High-res mode. */
{
const wy700_t *wy700 = (wy700_t *) priv;
if (wy700->wy700_mode & 0x80) { /* High-res mode. */
addr &= 0xFFFF;
/* In 800-line modes, bit 0 of the control register sets the high bit of the
* read address. */
@@ -512,21 +523,21 @@ wy700_recalctimings(wy700_t *wy700)
void
wy700_textline(wy700_t *wy700)
{
int w = (wy700->wy700_mode == 0) ? 40 : 80;
int cw = (wy700->wy700_mode == 0) ? 32 : 16;
uint8_t chr;
uint8_t attr;
uint8_t bitmap[2];
uint8_t *fontbase = &fontdatw[0][0];
int blink;
int c;
int drawcursor;
int cursorline;
int mda = 0;
uint16_t addr;
uint8_t sc;
uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff;
uint16_t ca = (wy700->cga_crtc[15] | (wy700->cga_crtc[14] << 8)) & 0x3fff;
int w = (wy700->wy700_mode == 0) ? 40 : 80;
int cw = (wy700->wy700_mode == 0) ? 32 : 16;
uint8_t chr;
uint8_t attr;
uint8_t bitmap[2];
const uint8_t *fontbase = &fontdatw[0][0];
int blink;
int c;
int drawcursor;
int cursorline;
int mda = 0;
uint16_t addr;
uint8_t sc;
uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff;
uint16_t ca = (wy700->cga_crtc[15] | (wy700->cga_crtc[14] << 8)) & 0x3fff;
/* The fake CRTC character height register selects whether MDA or CGA
* attributes are used */
@@ -629,6 +640,9 @@ wy700_cgaline(wy700_t *wy700)
case 3:
ink = 16 + 15;
break;
default:
break;
}
if (!(wy700->enabled) || !(wy700->cga_ctrl & 8))
ink = 16;
@@ -669,6 +683,9 @@ wy700_medresline(wy700_t *wy700)
case 3:
ink = 16 + 15;
break;
default:
break;
}
/* Display disabled? */
if (!(wy700->wy700_mode & 8))
@@ -724,6 +741,9 @@ wy700_hiresline(wy700_t *wy700)
case 3:
ink = 16 + 15;
break;
default:
break;
}
/* Display disabled? */
if (!(wy700->wy700_mode & 8))
@@ -857,10 +877,11 @@ wy700_poll(void *priv)
}
void *
wy700_init(const device_t *info)
wy700_init(UNUSED(const device_t *info))
{
int c;
wy700_t *wy700 = malloc(sizeof(wy700_t));
memset(wy700, 0, sizeof(wy700_t));
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_wy700);

File diff suppressed because it is too large Load Diff

View File

@@ -78,8 +78,11 @@
volatile int screenshots = 0;
uint8_t edatlookup[4][4];
uint8_t egaremap2bpp[256];
uint8_t fontdat[2048][8]; /* IBM CGA font */
uint8_t fontdatm[2048][16]; /* IBM MDA font */
uint8_t fontdat2[2048][8]; /* IBM CGA 2nd instance font */
uint8_t fontdatm2[2048][16]; /* IBM MDA 2nd instance font */
uint8_t fontdatw[512][32]; /* Wyse700 font */
uint8_t fontdat8x12[256][16]; /* MDSI Genius font */
uint8_t fontdat12x18[256][36]; /* IM1024 font */
@@ -106,7 +109,7 @@ void *__cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy
void *(*video_copy)(void *__restrict, const void *__restrict, size_t);
#endif
PALETTE cgapal = {
PALETTE cgapal = {
{0,0,0}, {0,42,0}, {42,0,0}, {42,21,0},
{0,0,0}, {0,42,42}, {42,0,42}, {42,42,42},
{0,0,0}, {21,63,21}, {63,21,21}, {63,63,21},
@@ -127,109 +130,108 @@ PALETTE cgapal = {
{0,0,0}, {0,63,63}, {63,0,0}, {63,63,63},
{0,0,0}, {0,63,63}, {63,0,0}, {63,63,63},
};
PALETTE cgapal_mono[6] = {
{ /* 0 - green, 4-color-optimized contrast. */
{0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05},
{0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a},
{0x03,0x39,0x0d},{0x03,0x3c,0x0e},{0x00,0x07,0x01},
{0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08},
{0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17},
PALETTE cgapal_mono[6] = {
{ /* 0 - green, 4-color-optimized contrast. */
{0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05},
{0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a},
{0x03,0x39,0x0d},{0x03,0x3c,0x0e},{0x00,0x07,0x01},
{0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08},
{0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17},
},
{ /* 1 - green, 16-color-optimized contrast. */
{0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05},
{0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08},
{0x02,0x2e,0x0b},{0x02,0x31,0x0b},{0x01,0x22,0x08},
{0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c},
{0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17},
{ /* 1 - green, 16-color-optimized contrast. */
{0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05},
{0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08},
{0x02,0x2e,0x0b},{0x02,0x31,0x0b},{0x01,0x22,0x08},
{0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c},
{0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17},
},
{ /* 2 - amber, 4-color-optimized contrast. */
{0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00},
{0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00},
{0x3f,0x26,0x01},{0x3f,0x2b,0x06},{0x0b,0x02,0x00},
{0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00},
{0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d},
{ /* 2 - amber, 4-color-optimized contrast. */
{0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00},
{0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00},
{0x3f,0x26,0x01},{0x3f,0x2b,0x06},{0x0b,0x02,0x00},
{0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00},
{0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d},
},
{ /* 3 - amber, 16-color-optimized contrast. */
{0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00},
{0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00},
{0x38,0x1c,0x00},{0x3b,0x1e,0x00},{0x2c,0x13,0x00},
{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},
{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d},
{ /* 3 - amber, 16-color-optimized contrast. */
{0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00},
{0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00},
{0x38,0x1c,0x00},{0x3b,0x1e,0x00},{0x2c,0x13,0x00},
{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},
{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d},
},
{ /* 4 - grey, 4-color-optimized contrast. */
{0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18},
{0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28},
{0x33,0x34,0x32},{0x37,0x38,0x35},{0x09,0x0a,0x0b},
{0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22},
{0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b},
{ /* 4 - grey, 4-color-optimized contrast. */
{0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18},
{0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28},
{0x33,0x34,0x32},{0x37,0x38,0x35},{0x09,0x0a,0x0b},
{0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22},
{0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b},
},
{ /* 5 - grey, 16-color-optimized contrast. */
{0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15},
{0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22},
{0x29,0x2a,0x2a},{0x2c,0x2d,0x2c},{0x1f,0x21,0x21},
{0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d},
{0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b},
{ /* 5 - grey, 16-color-optimized contrast. */
{0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15},
{0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22},
{0x29,0x2a,0x2a},{0x2c,0x2d,0x2c},{0x1f,0x21,0x21},
{0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d},
{0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b},
}
};
const uint32_t shade[5][256] =
{
{0}, // RGB Color (unused)
{0}, // RGB Grayscale (unused)
{ // Amber monitor
0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300,
0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00,
0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200,
0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00,
0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800,
0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400,
0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200,
0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100,
0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101,
0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201,
0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303,
0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606,
0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b,
0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14,
0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122,
0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739
},
{ // Green monitor
0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00,
0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401,
0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803,
0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906,
0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09,
0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d,
0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912,
0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718,
0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e,
0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325,
0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d,
0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36,
0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f,
0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749,
0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354,
0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60
},
{ // White monitor
0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12,
0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23,
0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33,
0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43,
0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52,
0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61,
0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70,
0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e,
0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c,
0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a,
0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8,
0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6,
0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3,
0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1,
0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf,
0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec
}
const uint32_t shade[5][256] = {
{0}, // RGB Color (unused)
{0}, // RGB Grayscale (unused)
{ // Amber monitor
0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300,
0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00,
0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200,
0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00,
0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800,
0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400,
0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200,
0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100,
0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101,
0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201,
0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303,
0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606,
0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b,
0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14,
0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122,
0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739
},
{ // Green monitor
0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00,
0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401,
0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803,
0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906,
0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09,
0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d,
0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912,
0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718,
0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e,
0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325,
0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d,
0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36,
0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f,
0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749,
0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354,
0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60
},
{ // White monitor
0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12,
0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23,
0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33,
0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43,
0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52,
0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61,
0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70,
0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e,
0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c,
0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a,
0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8,
0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6,
0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3,
0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1,
0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf,
0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec
}
};
typedef struct blit_data_struct {
@@ -308,13 +310,13 @@ static png_infop info_ptr[MONITORS_NUM];
static void
video_take_screenshot_monitor(const char *fn, uint32_t *buf, int start_x, int start_y, int row_len, int monitor_index)
{
png_bytep *b_rgb = NULL;
FILE *fp = NULL;
uint32_t temp = 0x00000000;
blit_data_t *blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr;
png_bytep *b_rgb = NULL;
FILE *fp = NULL;
uint32_t temp = 0x00000000;
const blit_data_t *blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr;
/* create file */
fp = plat_fopen((char *) fn, (char *) "wb");
fp = plat_fopen(fn, (const char *) "wb");
if (!fp) {
video_log("[video_take_screenshot] File %s could not be opened for writing", fn);
return;
@@ -423,8 +425,8 @@ void *
video_transform_copy(void *__restrict _Dst, const void *__restrict _Src, size_t _Size)
#endif
{
uint32_t *dest_ex = (uint32_t *) _Dst;
uint32_t *src_ex = (uint32_t *) _Src;
uint32_t *dest_ex = (uint32_t *) _Dst;
const uint32_t *src_ex = (const uint32_t *) _Src;
_Size /= sizeof(uint32_t);
@@ -496,8 +498,8 @@ pixel_to_color(uint8_t *pixels32, uint8_t pos)
uint32_t temp;
temp = *(pixels32 + pos) & 0x03;
switch (temp) {
case 0:
default:
case 0:
return 0x00;
case 1:
return 0x07;
@@ -599,8 +601,27 @@ cgapal_rebuild_monitor(int monitor_index)
}
}
if (cga_palette_monitor == 7)
if (cga_palette_monitor == 8)
palette_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]);
else if (cga_palette_monitor == 10) {
/* IBM 5153 CRT, colors by VileR */
palette_lookup[0x10] = 0x00000000;
palette_lookup[0x11] = 0x000000c4;
palette_lookup[0x12] = 0x0000c400;
palette_lookup[0x13] = 0x0000c4c4;
palette_lookup[0x14] = 0x00c40000;
palette_lookup[0x15] = 0x00c400c4;
palette_lookup[0x16] = 0x00c47e00;
palette_lookup[0x17] = 0x00c4c4c4;
palette_lookup[0x18] = 0x004e4e4e;
palette_lookup[0x19] = 0x004e4edc;
palette_lookup[0x1a] = 0x004edc4e;
palette_lookup[0x1b] = 0x004ef3f3;
palette_lookup[0x1c] = 0x00dc4e4e;
palette_lookup[0x1d] = 0x00f34ef3;
palette_lookup[0x1e] = 0x00f3f34e;
palette_lookup[0x1f] = 0x00ffffff;
}
}
void
@@ -774,23 +795,27 @@ hline(bitmap_t *b, int x1, int y, int x2, uint32_t col)
}
void
blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int x2, int y2, int xs, int ys)
blit(UNUSED(bitmap_t *src), UNUSED(bitmap_t *dst), UNUSED(int x1), UNUSED(int y1), UNUSED(int x2), UNUSED(int y2), UNUSED(int xs), UNUSED(int ys))
{
//
}
void
stretch_blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int xs1, int ys1, int x2, int y2, int xs2, int ys2)
stretch_blit(UNUSED(bitmap_t *src), UNUSED(bitmap_t *dst), UNUSED(int x1), UNUSED(int y1), UNUSED(int xs1), UNUSED(int ys1), UNUSED(int x2), UNUSED(int y2), UNUSED(int xs2), UNUSED(int ys2))
{
//
}
void
rectfill(bitmap_t *b, int x1, int y1, int x2, int y2, uint32_t col)
rectfill(UNUSED(bitmap_t *b), UNUSED(int x1), UNUSED(int y1), UNUSED(int x2), UNUSED(int y2), UNUSED(uint32_t col))
{
//
}
void
set_palette(PALETTE p)
set_palette(UNUSED(PALETTE p))
{
//
}
void
@@ -877,29 +902,27 @@ video_monitor_close(int monitor_index)
void
video_init(void)
{
int c;
int d;
uint8_t total[2] = { 0, 1 };
for (c = 0; c < 16; c++) {
for (uint8_t c = 0; c < 16; c++) {
cga_2_table[c] = (total[(c >> 3) & 1] << 0) | (total[(c >> 2) & 1] << 8) | (total[(c >> 1) & 1] << 16) | (total[(c >> 0) & 1] << 24);
}
for (c = 0; c < 64; c++) {
for (uint8_t c = 0; c < 64; c++) {
cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
if ((c & 0x17) == 6)
cgapal[c + 64].g >>= 1;
}
for (c = 0; c < 64; c++) {
for (uint8_t c = 0; c < 64; c++) {
cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21;
cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21;
}
for (c = 0; c < 4; c++) {
for (d = 0; d < 4; d++) {
for (uint8_t c = 0; c < 4; c++) {
for (uint8_t d = 0; d < 4; d++) {
edatlookup[c][d] = 0;
if (c & 1)
edatlookup[c][d] |= 1;
@@ -912,24 +935,36 @@ video_init(void)
}
}
for (uint16_t c = 0; c < 256; c++) {
egaremap2bpp[c] = 0;
if (c & 0x01)
egaremap2bpp[c] |= 0x01;
if (c & 0x04)
egaremap2bpp[c] |= 0x02;
if (c & 0x10)
egaremap2bpp[c] |= 0x04;
if (c & 0x40)
egaremap2bpp[c] |= 0x08;
}
video_6to8 = malloc(4 * 256);
for (c = 0; c < 256; c++)
for (uint16_t c = 0; c < 256; c++)
video_6to8[c] = calc_6to8(c);
video_8togs = malloc(4 * 256);
for (c = 0; c < 256; c++)
for (uint16_t c = 0; c < 256; c++)
video_8togs[c] = c | (c << 16) | (c << 24);
video_8to32 = malloc(4 * 256);
for (c = 0; c < 256; c++)
for (uint16_t c = 0; c < 256; c++)
video_8to32[c] = calc_8to32(c);
video_15to32 = malloc(4 * 65536);
for (c = 0; c < 65536; c++)
for (uint32_t c = 0; c < 65536; c++)
video_15to32[c] = calc_15to32(c & 0x7fff);
video_16to32 = malloc(4 * 65536);
for (c = 0; c < 65536; c++)
for (uint32_t c = 0; c < 65536; c++)
video_16to32[c] = calc_16to32(c);
memset(monitors, 0, sizeof(monitors));
@@ -1087,6 +1122,19 @@ loadfont_common(FILE *f, int format)
for (d = 0; d < 8; d++)
fontdat[c][d] = fgetc(f) & 0xff;
break;
case 11: /* PC200 */
for (d = 0; d < 4; d++) {
/* There are 4 fonts in the ROM */
for (c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */
(void) !fread(&fontdatm2[256 * d + c][0], 1, 16, f);
for (c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */
(void) !fread(&fontdat2[256 * d + c][0], 1, 8, f);
fseek(f, 8, SEEK_CUR);
}
}
break;
}
(void) fclose(f);
@@ -1095,14 +1143,14 @@ loadfont_common(FILE *f, int format)
void
loadfont_ex(char *s, int format, int offset)
{
FILE *f;
FILE *fp;
f = rom_fopen(s, "rb");
if (f == NULL)
fp = rom_fopen(s, "rb");
if (fp == NULL)
return;
fseek(f, offset, SEEK_SET);
loadfont_common(f, format);
fseek(fp, offset, SEEK_SET);
loadfont_common(fp, format);
}
void
@@ -1115,8 +1163,10 @@ uint32_t
video_color_transform(uint32_t color)
{
uint8_t *clr8 = (uint8_t *) &color;
/* if (!video_grayscale && !invert_display)
return color; */
#if 0
if (!video_grayscale && !invert_display)
return color;
#endif
if (video_grayscale) {
if (video_graytype) {
if (video_graytype == 1)
@@ -1129,7 +1179,7 @@ video_color_transform(uint32_t color)
case 2:
case 3:
case 4:
color = (uint32_t) shade[video_grayscale][color];
color = shade[video_grayscale][color];
break;
default:
clr8[3] = 0;