Merge branch 'master' of https://github.com/86Box/86Box
This commit is contained in:
@@ -320,6 +320,8 @@ typedef struct voodoo_t {
|
||||
uint32_t cmdfifo_amin, cmdfifo_amax;
|
||||
int cmdfifo_holecount;
|
||||
|
||||
atomic_uint cmd_status;
|
||||
|
||||
uint32_t sSetupMode;
|
||||
vert_t verts[4];
|
||||
unsigned int vertex_ages[3];
|
||||
|
@@ -511,6 +511,7 @@ void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) {
|
||||
QString menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData();
|
||||
imageHistoryUpdatePos->setText(QString::asprintf(tr("%s").toUtf8().constData(), menu_item_name.toUtf8().constData()));
|
||||
imageHistoryUpdatePos->setVisible(!fi.fileName().isEmpty());
|
||||
imageHistoryUpdatePos->setVisible(fi.exists());
|
||||
}
|
||||
|
||||
void MediaMenu::clearImageHistory() {
|
||||
|
@@ -1,16 +1,16 @@
|
||||
#
|
||||
# 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.
|
||||
# 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.
|
||||
# This file is part of the 86Box distribution.
|
||||
#
|
||||
# CMake build script.
|
||||
# CMake build script.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
#
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
#
|
||||
|
||||
add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c
|
||||
@@ -20,12 +20,12 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c
|
||||
vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c
|
||||
vid_ati28800.c vid_ati_mach64.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_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_tvp3026_ramdac.c vid_att2xc498_ramdac.c
|
||||
vid_xga.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_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c)
|
||||
|
||||
if(MGA)
|
||||
target_compile_definitions(vid PRIVATE USE_MGA)
|
||||
|
301
src/video/vid_et3000.c
Normal file
301
src/video/vid_et3000.c
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* 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 Tseng Labs ET3000.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/mca.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
#include <86box/vid_svga_render.h>
|
||||
|
||||
#define BIOS_ROM_PATH "roms/video/et3000/Tseng ET3000AX ISA VGA-VGA ULTRA.bin"
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int type;
|
||||
|
||||
svga_t svga;
|
||||
|
||||
rom_t bios_rom;
|
||||
|
||||
uint8_t banking;
|
||||
} et3000_t;
|
||||
|
||||
static video_timings_t timing_et3000_isa = { VIDEO_ISA, 3, 3, 6, 5, 5, 10 };
|
||||
|
||||
static uint8_t et3000_in(uint16_t addr, void *priv);
|
||||
static void et3000_out(uint16_t addr, uint8_t val, void *priv);
|
||||
|
||||
static uint8_t
|
||||
et3000_in(uint16_t addr, void *priv)
|
||||
{
|
||||
et3000_t *dev = (et3000_t *) priv;
|
||||
svga_t *svga = &dev->svga;
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3cd: /*Banking*/
|
||||
return dev->banking;
|
||||
|
||||
case 0x3d4:
|
||||
return svga->crtcreg;
|
||||
|
||||
case 0x3d5:
|
||||
return svga->crtc[svga->crtcreg];
|
||||
}
|
||||
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
||||
static void
|
||||
et3000_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
et3000_t *dev = (et3000_t *) priv;
|
||||
svga_t *svga = &dev->svga;
|
||||
uint8_t old;
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3c0:
|
||||
case 0x3c1:
|
||||
if (svga->attrff && (svga->attraddr == 0x16)) {
|
||||
svga->attrregs[0x16] = val;
|
||||
svga->chain4 &= ~0x10;
|
||||
if (svga->gdcreg[5] & 0x40)
|
||||
svga->chain4 |= (svga->attrregs[0x16] & 0x10);
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3c5:
|
||||
if (svga->seqaddr == 4) {
|
||||
svga->seqregs[4] = val;
|
||||
|
||||
svga->chain2_write = !(val & 4);
|
||||
svga->chain4 = (svga->chain4 & ~8) | (val & 8);
|
||||
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4 && !(svga->adv_flags & FLAG_ADDR_BY8);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3cf:
|
||||
if ((svga->gdcaddr & 15) == 5) {
|
||||
svga->chain4 &= ~0x10;
|
||||
if (val & 0x40)
|
||||
svga->chain4 |= (svga->attrregs[0x16] & 0x10);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3cd: /*Banking*/
|
||||
dev->banking = val;
|
||||
if (!(svga->crtc[0x23] & 0x80) && !(svga->gdcreg[6] & 0x08)) {
|
||||
switch ((val >> 6) & 3) {
|
||||
case 0: /*128K segments*/
|
||||
svga->write_bank = (val & 7) << 17;
|
||||
svga->read_bank = ((val >> 3) & 7) << 17;
|
||||
break;
|
||||
case 1: /*64K segments*/
|
||||
svga->write_bank = (val & 7) << 16;
|
||||
svga->read_bank = ((val >> 3) & 7) << 16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case 0x3d4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
|
||||
case 0x3d5:
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
|
||||
if (old != val) {
|
||||
if (svga->crtcreg < 0x0e || svga->crtcreg > 0x10) {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
static void
|
||||
et3000_recalctimings(svga_t *svga)
|
||||
{
|
||||
svga->ma_latch |= (svga->crtc[0x23] & 2) << 15;
|
||||
if (svga->crtc[0x25] & 1)
|
||||
svga->vblankstart |= 0x400;
|
||||
if (svga->crtc[0x25] & 2)
|
||||
svga->vtotal |= 0x400;
|
||||
if (svga->crtc[0x25] & 4)
|
||||
svga->dispend |= 0x400;
|
||||
if (svga->crtc[0x25] & 8)
|
||||
svga->vsyncstart |= 0x400;
|
||||
if (svga->crtc[0x25] & 0x10)
|
||||
svga->split |= 0x400;
|
||||
|
||||
svga->interlace = !!(svga->crtc[0x25] & 0x80);
|
||||
|
||||
if (svga->attrregs[0x16] & 0x10) {
|
||||
svga->ma_latch <<= (1 << 0);
|
||||
svga->rowoffset <<= (1 << 0);
|
||||
switch (svga->gdcreg[5] & 0x60) {
|
||||
case 0x00:
|
||||
svga->render = svga_render_4bpp_highres;
|
||||
svga->hdisp *= 2;
|
||||
break;
|
||||
case 0x20:
|
||||
svga->render = svga_render_2bpp_highres;
|
||||
break;
|
||||
case 0x40:
|
||||
case 0x60:
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* pclog("HDISP = %i, HTOTAL = %i, ROWOFFSET = %i, INTERLACE = %i\n",
|
||||
svga->hdisp, svga->htotal, svga->rowoffset, svga->interlace); */
|
||||
|
||||
switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x24] << 1) & 4)) {
|
||||
case 0:
|
||||
case 1:
|
||||
break;
|
||||
case 3:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 40000000.0;
|
||||
break;
|
||||
case 5:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 65000000.0;
|
||||
break;
|
||||
default:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 36000000.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
et3000_init(const device_t *info)
|
||||
{
|
||||
const char *fn;
|
||||
et3000_t *dev;
|
||||
|
||||
dev = (et3000_t *) malloc(sizeof(et3000_t));
|
||||
memset(dev, 0x00, sizeof(et3000_t));
|
||||
dev->name = info->name;
|
||||
dev->type = info->local;
|
||||
fn = BIOS_ROM_PATH;
|
||||
|
||||
switch (dev->type) {
|
||||
case 0: /* ISA ET3000AX */
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et3000_isa);
|
||||
svga_init(info, &dev->svga, dev, device_get_config_int("memory") << 10,
|
||||
et3000_recalctimings, et3000_in, et3000_out,
|
||||
NULL, NULL);
|
||||
io_sethandler(0x03c0, 32,
|
||||
et3000_in, NULL, NULL, et3000_out, NULL, NULL, dev);
|
||||
break;
|
||||
}
|
||||
|
||||
rom_init(&dev->bios_rom, (char *) fn,
|
||||
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
dev->svga.bpp = 8;
|
||||
dev->svga.miscout = 1;
|
||||
|
||||
dev->svga.packed_chain4 = 1;
|
||||
|
||||
return (dev);
|
||||
}
|
||||
|
||||
static void
|
||||
et3000_close(void *priv)
|
||||
{
|
||||
et3000_t *dev = (et3000_t *) priv;
|
||||
|
||||
svga_close(&dev->svga);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
et3000_speed_changed(void *priv)
|
||||
{
|
||||
et3000_t *dev = (et3000_t *) priv;
|
||||
|
||||
svga_recalctimings(&dev->svga);
|
||||
}
|
||||
|
||||
static void
|
||||
et3000_force_redraw(void *priv)
|
||||
{
|
||||
et3000_t *dev = (et3000_t *) priv;
|
||||
|
||||
dev->svga.fullchange = changeframecount;
|
||||
}
|
||||
|
||||
static int
|
||||
et3000_available(void)
|
||||
{
|
||||
return rom_present(BIOS_ROM_PATH);
|
||||
}
|
||||
|
||||
static const device_config_t et3000_config[] = {
|
||||
{ .name = "memory",
|
||||
.description = "Memory size",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_int = 512,
|
||||
.selection = {
|
||||
{ .description = "256 KB",
|
||||
.value = 256 },
|
||||
{ .description = "512 KB",
|
||||
.value = 512 },
|
||||
{ .description = "1 MB",
|
||||
.value = 1024 },
|
||||
{ .description = "" } } },
|
||||
{ .type = CONFIG_END }
|
||||
};
|
||||
|
||||
const device_t et3000_isa_device = {
|
||||
.name = "Tseng Labs ET3000AX (ISA)",
|
||||
.internal_name = "et3000ax",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = et3000_init,
|
||||
.close = et3000_close,
|
||||
.reset = NULL,
|
||||
{ .available = et3000_available },
|
||||
.speed_changed = et3000_speed_changed,
|
||||
.force_redraw = et3000_force_redraw,
|
||||
.config = et3000_config
|
||||
};
|
@@ -143,6 +143,7 @@ video_cards[] = {
|
||||
{ &nec_sv9000_device },
|
||||
{ &et4000k_isa_device },
|
||||
{ &et2000_device },
|
||||
{ &et3000_isa_device },
|
||||
{ &et4000_isa_device },
|
||||
{ &et4000w32_device },
|
||||
{ &et4000w32i_isa_device },
|
||||
|
@@ -178,6 +178,7 @@ enum {
|
||||
cmdRdPtrH0 = 0x30,
|
||||
cmdAMin0 = 0x34,
|
||||
cmdAMax0 = 0x3c,
|
||||
cmdStatus0 = 0x40,
|
||||
cmdFifoDepth0 = 0x44,
|
||||
cmdHoleCnt0 = 0x48,
|
||||
|
||||
@@ -1170,6 +1171,10 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr)
|
||||
// banshee_log("Read cmdfifo_depth %08x\n", ret);
|
||||
break;
|
||||
|
||||
case cmdStatus0:
|
||||
ret = voodoo->cmd_status;
|
||||
break;
|
||||
|
||||
case 0x108:
|
||||
break;
|
||||
|
||||
@@ -2981,6 +2986,7 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int
|
||||
banshee->voodoo->tex_mem[1] = banshee->svga.vram;
|
||||
banshee->voodoo->tex_mem_w[1] = (uint16_t *) banshee->svga.vram;
|
||||
banshee->voodoo->texture_mask = banshee->svga.vram_mask;
|
||||
banshee->voodoo->cmd_status = (1 << 28);
|
||||
voodoo_generate_filter_v1(banshee->voodoo);
|
||||
|
||||
banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W;
|
||||
|
@@ -106,6 +106,7 @@ voodoo_queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val)
|
||||
fifo->addr_type = addr_type;
|
||||
|
||||
voodoo->fifo_write_idx++;
|
||||
voodoo->cmd_status &= ~(1 << 24);
|
||||
|
||||
if (FIFO_ENTRIES > 0xe000)
|
||||
voodoo_wake_fifo_thread(voodoo);
|
||||
@@ -283,6 +284,8 @@ voodoo_fifo_thread(void *param)
|
||||
voodoo->time += end_time - start_time;
|
||||
}
|
||||
|
||||
voodoo->cmd_status |= (1 << 24);
|
||||
|
||||
while (voodoo->cmdfifo_enabled && (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr || voodoo->cmdfifo_in_sub)) {
|
||||
uint64_t start_time = plat_timer_read();
|
||||
uint64_t end_time;
|
||||
@@ -296,9 +299,13 @@ voodoo_fifo_thread(void *param)
|
||||
|
||||
// voodoo_fifo_log(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp);
|
||||
|
||||
voodoo->cmd_status &= ~7;
|
||||
voodoo->cmd_status |= (header & 7);
|
||||
voodoo->cmd_status |= (1 << 11);
|
||||
switch (header & 7) {
|
||||
case 0:
|
||||
// voodoo_fifo_log("CMDFIFO0\n");
|
||||
voodoo->cmd_status = (voodoo->cmd_status & 0xffff8fff) | (((header >> 3) & 7) << 12);
|
||||
switch ((header >> 3) & 7) {
|
||||
case 0: /*NOP*/
|
||||
break;
|
||||
@@ -323,6 +330,7 @@ voodoo_fifo_thread(void *param)
|
||||
default:
|
||||
fatal("Bad CMDFIFO0 %08x\n", header);
|
||||
}
|
||||
voodoo->cmd_status = (voodoo->cmd_status & ~(1 << 27)) | (voodoo->cmdfifo_in_sub << 27);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@@ -708,6 +708,7 @@ VIDOBJ := agpgart.o video.o \
|
||||
vid_bt48x_ramdac.o \
|
||||
vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \
|
||||
vid_cl54xx.o \
|
||||
vid_et3000.o \
|
||||
vid_et4000.o vid_sc1148x_ramdac.o \
|
||||
vid_sc1502x_ramdac.o \
|
||||
vid_et4000w32.o vid_stg_ramdac.o \
|
||||
|
Reference in New Issue
Block a user