diff --git a/README.md b/README.md
index b4b4142be..ce38632e6 100644
--- a/README.md
+++ b/README.md
@@ -53,10 +53,14 @@ We operate an IRC channel and a Discord server for discussing 86Box, its develop
[](https://discord.gg/QXK9XTv)
Contributions
----------
+-------------
We welcome all contributions to the project, as long as the [contribution guidelines](CONTRIBUTING.md) are followed.
+Building
+---------
+For instructions on how to build 86Box from source, see the [build guide](https://86box.readthedocs.io/en/latest/dev/buildguide.html).
+
Licensing
---------
diff --git a/scripts/86Box-install-roms.sh b/scripts/86Box-install-roms.sh
deleted file mode 100755
index b13d93acc..000000000
--- a/scripts/86Box-install-roms.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/sh
-
-URL="https://github.com/86Box/roms/archive/refs/tags/v4.2.zip"
-TMP_FILE="/tmp/86Box-ROMS.zip"
-EXTRACT_DIR="/tmp/86Box-ROMS-extracted"
-DEFAULT_TARGET_DIR="$HOME/.local/share/86Box/roms/"
-TARGET_DIR=${TARGET_DIR:-$DEFAULT_TARGET_DIR}
-
-install_roms() {
- if [ -d "$TARGET_DIR" ] && [ "$(ls -A $TARGET_DIR)" ]; then
- echo "ROMS already installed in $TARGET_DIR"
- echo "To (re)install, please first remove ROMS with -r parameter"
- exit 1
- fi
- fetch -o "$TMP_FILE" "$URL"
-
- if [ $? -ne 0 ]; then
- echo "Failed to download the file from $URL"
- exit 1
- fi
-
- mkdir -p "$EXTRACT_DIR"
- unzip "$TMP_FILE" -d "$EXTRACT_DIR"
-
- if [ $? -ne 0 ]; then
- echo "Failed to decompress the file"
- rm "$TMP_FILE"
- exit 1
- fi
-
- mkdir -p "$TARGET_DIR"
- cd "$EXTRACT_DIR"
- TOP_LEVEL_DIR=$(find . -mindepth 1 -maxdepth 1 -type d)
-
- if [ -d "$TOP_LEVEL_DIR" ]; then
- mv "$TOP_LEVEL_DIR"/* "$TARGET_DIR"
- fi
-
- rm -rf "$TMP_FILE" "$EXTRACT_DIR"
- echo "ROMS installed successfully in $TARGET_DIR"
-}
-
-remove_roms() {
- if [ -d "$TARGET_DIR" ]; then
- rm -rf "$TARGET_DIR"
- echo "ROMS removed successfully from $TARGET_DIR"
- else
- echo "No ROMS directory found in $TARGET_DIR"
- fi
-}
-
-help() {
- echo ""
- echo "$0 [-h|-i|-r]"
- echo " -h : this help"
- echo " -i : install (this parameter can be omitted)"
- echo " -r : remove the ROMS"
- echo ""
-}
-
-case "$1" in
- -h)
- help
- ;;
- -r)
- remove_roms
- ;;
- -i|*)
- install_roms
- ;;
-esac
-
-exit 0
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0841fabdd..ad339040f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -27,7 +27,9 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1)
endif()
-if(CPPTHREADS)
+if(WIN32)
+ target_sources(86Box PRIVATE qt/win_thread.c)
+else()
target_sources(86Box PRIVATE thread.cpp)
endif()
diff --git a/src/device/cartridge.c b/src/device/cartridge.c
index edabd3ed0..a40c29c9b 100644
--- a/src/device/cartridge.c
+++ b/src/device/cartridge.c
@@ -169,6 +169,7 @@ cart_close(int drive)
cart_image_close(drive);
cart_fns[drive][0] = 0;
ui_sb_update_icon_state(SB_CARTRIDGE | drive, 1);
+ resetx86();
}
void
diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c
index 3fd492bd2..6baef8ab8 100644
--- a/src/floppy/fdc.c
+++ b/src/floppy/fdc.c
@@ -1635,6 +1635,8 @@ fdc_callback(void *priv)
return;
}
if (fdd_get_head(real_drive(fdc, fdc->drive)) == 0) {
+ fdc->sector = 1;
+ fdc->head |= 1;
fdd_set_head(real_drive(fdc, fdc->drive), 1);
if (!fdd_is_double_sided(real_drive(fdc, fdc->drive))) {
fdc_noidam(fdc);
diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c
index 9ac4ff631..e569dc674 100644
--- a/src/machine/m_pcjr.c
+++ b/src/machine/m_pcjr.c
@@ -443,16 +443,16 @@ vid_poll(void *priv)
pcjr->ma++;
buffer32->line[l][ef_x] = buffer32->line[l][ef_x + 1] =
buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] =
- pcjr->array[((dat >> 12) & pcjr->array[1]) + 16] + 16;
+ pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16;
buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] =
buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] =
- pcjr->array[((dat >> 8) & pcjr->array[1]) + 16] + 16;
+ pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16;
buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] =
buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] =
- pcjr->array[((dat >> 4) & pcjr->array[1]) + 16] + 16;
+ pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] =
buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] =
- pcjr->array[(dat & pcjr->array[1]) + 16] + 16;
+ pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16;
}
break;
case 0x12: /*160x200x16*/
@@ -493,7 +493,7 @@ vid_poll(void *priv)
chr = (dat >> 7) & 1;
chr |= ((dat >> 14) & 2);
buffer32->line[l][ef_x + c] = buffer32->line[l + 1][ef_x + c] =
- pcjr->array[(chr & pcjr->array[1]) + 16] + 16;
+ pcjr->array[(chr & pcjr->array[1] & 0x0f) + 16] + 16;
dat <<= 1;
}
}
@@ -505,13 +505,13 @@ vid_poll(void *priv)
attr = pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron);
if (pcjr->array[3] & 4) {
- cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16] + 16;
- cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16] + 16;
+ cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
+ cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16;
if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor)
cols[1] = cols[0];
} else {
- cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16] + 16;
- cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16] + 16;
+ cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
+ cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
}
if (pcjr->sc & 8)
for (uint8_t c = 0; c < 8; c++)
@@ -537,13 +537,13 @@ vid_poll(void *priv)
attr = pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron);
if (pcjr->array[3] & 4) {
- cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16] + 16;
- cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16] + 16;
+ cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
+ cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16;
if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor)
cols[1] = cols[0];
} else {
- cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16] + 16;
- cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16] + 16;
+ cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
+ cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
}
pcjr->ma++;
if (pcjr->sc & 8)
diff --git a/src/qt/win_thread.c b/src/qt/win_thread.c
new file mode 100644
index 000000000..9a4f046b3
--- /dev/null
+++ b/src/qt/win_thread.c
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ *
+ * Implement threads and mutexes for the Win32 platform.
+ *
+ *
+ *
+ * Authors: Sarah Walker,
+ * Fred N. van Kempen,
+ *
+ * Copyright 2008-2018 Sarah Walker.
+ * Copyright 2017-2018 Fred N. van Kempen.
+ */
+#define UNICODE
+#define BITMAP WINDOWS_BITMAP
+#include
+#include
+#include
+#undef BITMAP
+#include
+#include
+#include
+#include
+#include
+#include <86box/86box.h>
+#include <86box/plat.h>
+#include <86box/thread.h>
+
+typedef struct {
+ HANDLE handle;
+} win_event_t;
+
+/* For compatibility with thread.h, but Win32 does not allow named threads. */
+thread_t *
+thread_create_named(void (*func)(void *param), void *param, UNUSED(const char *name))
+{
+ uintptr_t bt = _beginthread(func, 0, param);
+ return ((thread_t *) bt);
+}
+
+int
+thread_test_mutex(thread_t *arg)
+{
+ if (arg == NULL)
+ return (0);
+
+ return (WaitForSingleObject(arg, 0) == WAIT_OBJECT_0) ? 1 : 0;
+}
+
+int
+thread_wait(thread_t *arg)
+{
+ if (arg == NULL)
+ return (0);
+
+ if (WaitForSingleObject(arg, INFINITE))
+ return (1);
+
+ return (0);
+}
+
+event_t *
+thread_create_event(void)
+{
+ win_event_t *ev = malloc(sizeof(win_event_t));
+
+ ev->handle = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ return ((event_t *) ev);
+}
+
+void
+thread_set_event(event_t *arg)
+{
+ win_event_t *ev = (win_event_t *) arg;
+
+ if (arg == NULL)
+ return;
+
+ SetEvent(ev->handle);
+}
+
+void
+thread_reset_event(event_t *arg)
+{
+ win_event_t *ev = (win_event_t *) arg;
+
+ if (arg == NULL)
+ return;
+
+ ResetEvent(ev->handle);
+}
+
+int
+thread_wait_event(event_t *arg, int timeout)
+{
+ win_event_t *ev = (win_event_t *) arg;
+
+ if (arg == NULL)
+ return (0);
+
+ if (ev->handle == NULL)
+ return (0);
+
+ if (timeout == -1)
+ timeout = INFINITE;
+
+ if (WaitForSingleObject(ev->handle, timeout))
+ return (1);
+
+ return (0);
+}
+
+void
+thread_destroy_event(event_t *arg)
+{
+ win_event_t *ev = (win_event_t *) arg;
+
+ if (arg == NULL)
+ return;
+
+ CloseHandle(ev->handle);
+
+ free(ev);
+}
+
+mutex_t *
+thread_create_mutex(void)
+{
+ mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION));
+
+ InitializeCriticalSection(mutex);
+
+ return mutex;
+}
+
+int
+thread_wait_mutex(mutex_t *mutex)
+{
+ if (mutex == NULL)
+ return (0);
+
+ LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex;
+
+ EnterCriticalSection(critsec);
+
+ return 1;
+}
+
+int
+thread_release_mutex(mutex_t *mutex)
+{
+ if (mutex == NULL)
+ return (0);
+
+ LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex;
+
+ LeaveCriticalSection(critsec);
+
+ return 1;
+}
+
+void
+thread_close_mutex(mutex_t *mutex)
+{
+ if (mutex == NULL)
+ return;
+
+ LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex;
+
+ DeleteCriticalSection(critsec);
+
+ free(critsec);
+}
diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c
index d2b5a87fe..8a9bedf02 100644
--- a/src/video/vid_s3.c
+++ b/src/video/vid_s3.c
@@ -9930,8 +9930,14 @@ s3_init(const device_t *info)
s3->width = 1024;
svga->ramdac = device_add(&sc11483_ramdac_device);
- svga->clock_gen = device_add(&av9194_device);
- svga->getclock = av9194_getclock;
+ if (s3->card_type == S3_ORCHID_86C911) {
+ svga->clock_gen = device_add(&av9194_device);
+ svga->getclock = av9194_getclock;
+ } else {
+ /* DCS2824-0 = Diamond ICD2061A-compatible. */
+ svga->clock_gen = device_add(&icd2061_device);
+ svga->getclock = icd2061_getclock;
+ }
break;
case S3_AMI_86C924:
diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c
index 700722253..a5448fa66 100644
--- a/src/video/vid_s3_virge.c
+++ b/src/video/vid_s3_virge.c
@@ -68,7 +68,7 @@ static int dither[4][4] = {
#define ROM_DIAMOND_STEALTH3D_2000PRO "roms/video/s3virge/virgedxdiamond.vbi"
#define ROM_VIRGE_GX "roms/video/s3virge/86c375_4.bin"
#define ROM_VIRGE_GX2 "roms/video/s3virge/flagpoint.VBI"
-#define ROM_DIAMOND_STEALTH3D_4000 "roms/video/s3virge/86c357.bin"
+#define ROM_DIAMOND_STEALTH3D_4000 "roms/video/s3virge/DS3D4K v1.03 Brightness bug fix.bin"
#define ROM_TRIO3D2X "roms/video/s3virge/TRIO3D2X_8mbsdr.VBI"
#define RB_SIZE 256
@@ -288,9 +288,9 @@ typedef struct virge_t {
s3d_t s3d_tri;
s3d_t s3d_buffer[RB_SIZE];
- int s3d_read_idx;
- int s3d_write_idx;
- int s3d_busy;
+ atomic_int s3d_read_idx;
+ atomic_int s3d_write_idx;
+ atomic_int s3d_busy;
struct {
uint32_t pri_ctrl;
@@ -330,15 +330,14 @@ typedef struct virge_t {
} streams;
fifo_entry_t fifo[FIFO_SIZE];
- volatile int fifo_read_idx, fifo_write_idx;
-
- volatile int fifo_thread_run, render_thread_run;
+ atomic_int fifo_read_idx, fifo_write_idx;
+ atomic_int fifo_thread_run, render_thread_run;
thread_t * fifo_thread;
event_t *wake_fifo_thread;
event_t * fifo_not_full_event;
- int virge_busy;
+ atomic_int virge_busy;
uint8_t subsys_stat;
uint8_t subsys_cntl;
@@ -363,7 +362,16 @@ typedef struct virge_t {
uint8_t cmd_dma;
uint32_t cmd_dma_base;
- uint32_t dma_ptr;
+ uint32_t cmd_dma_buf_size;
+ uint32_t cmd_dma_buf_size_mask;
+ uint32_t cmd_base_addr;
+ uint32_t cmd_dma_write_ptr_reg;
+ uint32_t cmd_dma_write_ptr_update;
+ uint32_t cmd_dma_read_ptr_reg;
+ uint32_t dma_val;
+ uint32_t dma_dbl_words;
+ uint32_t dma_mmio_addr;
+ uint32_t dma_data_type;
int pci;
int is_agp;
@@ -396,6 +404,8 @@ static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv);
static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv);
static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv);
+static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type);
+
enum {
CMD_SET_AE = 1,
CMD_SET_HC = (1 << 1),
@@ -442,6 +452,8 @@ enum {
#define INT_S3D_DONE (1 << 1)
#define INT_FIFO_OVF (1 << 2)
#define INT_FIFO_EMP (1 << 3)
+#define INT_HOST_DONE (1 << 4)
+#define INT_CMD_DONE (1 << 5)
#define INT_3DF_EMP (1 << 6)
#define INT_MASK 0xff
@@ -722,12 +734,12 @@ s3_virge_in(uint16_t addr, void *priv) {
case 0x31:
ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4);
break;
+ case 0x33:
+ ret = (svga->crtc[0x33] | 0x04);
+ break;
case 0x35:
ret = (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf);
break;
- case 0x36:
- ret = (svga->crtc[0x36] & 0xfc) | 2;
- break; /*PCI bus*/
case 0x45:
virge->hwc_col_stack_pos = 0;
ret = svga->crtc[0x45];
@@ -782,7 +794,8 @@ s3_virge_in(uint16_t addr, void *priv) {
}
static void
-s3_virge_recalctimings(svga_t *svga) {
+s3_virge_recalctimings(svga_t *svga)
+{
virge_t *virge = (virge_t *) svga->priv;
svga->hdisp = svga->hdisp_old;
@@ -854,7 +867,7 @@ s3_virge_recalctimings(svga_t *svga) {
video_force_resize_set_monitor(1, svga->monitor_index);
}
- if ((svga->crtc[0x67] & 0xc) != 0xc) { /*VGA mode*/
+ if (((svga->crtc[0x67] & 0xc) != 0xc) || (virge->chip >= S3_VIRGEGX2)) { /*VGA mode*/
svga->ma_latch |= (virge->ma_ext << 16);
if (svga->crtc[0x51] & 0x30)
svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4;
@@ -891,8 +904,8 @@ s3_virge_recalctimings(svga_t *svga) {
svga->render = svga_render_32bpp_highres;
break;
- default:
- break;
+ default:
+ break;
}
svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) &&
@@ -1034,7 +1047,7 @@ s3_virge_updatemapping(virge_t *virge) {
virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
if ((svga->crtc[0x58] & 0x10) || (virge->advfunc_cntl & 0x10)) { /*Linear framebuffer*/
- switch (svga->crtc[0x58] & 3) {
+ switch (svga->crtc[0x58] & 7) {
case 0: /*64k*/
virge->linear_size = 0x10000;
break;
@@ -1103,7 +1116,8 @@ s3_virge_wait_fifo_idle(virge_t *virge) {
}
static uint8_t
-s3_virge_mmio_read(uint32_t addr, void *priv) {
+s3_virge_mmio_read(uint32_t addr, void *priv)
+{
virge_t *virge = (virge_t *) priv;
uint8_t ret;
@@ -1120,6 +1134,7 @@ s3_virge_mmio_read(uint32_t addr, void *priv) {
ret |= 0x10;
else
ret |= 0x30;
+
if (!virge->virge_busy)
wake_fifo_thread(virge);
return ret;
@@ -1152,7 +1167,8 @@ s3_virge_mmio_read(uint32_t addr, void *priv) {
}
static uint16_t
-s3_virge_mmio_read_w(uint32_t addr, void *priv) {
+s3_virge_mmio_read_w(uint32_t addr, void *priv)
+{
virge_t *virge = (virge_t *) priv;
uint16_t ret;
@@ -1186,7 +1202,6 @@ s3_virge_mmio_read_w(uint32_t addr, void *priv) {
static uint32_t
s3_virge_mmio_read_l(uint32_t addr, void *priv) {
virge_t *virge = (virge_t *) priv;
- svga_t *svga = &virge->svga;
uint32_t ret = 0xffffffff;
switch (addr & 0xfffc) {
@@ -1207,46 +1222,30 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) {
break;
case 0x81a0:
ret = virge->streams.blend_ctrl;
- svga_recalctimings(svga);
break;
case 0x81c0:
ret = virge->streams.pri_fb0;
- s3_virge_update_buffer(virge);
- svga->fullchange = changeframecount;
break;
case 0x81c4:
ret = virge->streams.pri_fb1;
- s3_virge_update_buffer(virge);
- svga->fullchange = changeframecount;
break;
case 0x81c8:
ret = virge->streams.pri_stride;
- s3_virge_update_buffer(virge);
- svga->fullchange = changeframecount;
break;
case 0x81cc:
ret = virge->streams.buffer_ctrl;
- s3_virge_update_buffer(virge);
- svga->fullchange = changeframecount;
break;
case 0x81d0:
ret = virge->streams.sec_fb0;
- s3_virge_update_buffer(virge);
- svga->fullchange = changeframecount;
break;
case 0x81d4:
ret = virge->streams.sec_fb1;
- s3_virge_update_buffer(virge);
- svga->fullchange = changeframecount;
break;
case 0x81d8:
ret = virge->streams.sec_stride;
- s3_virge_update_buffer(virge);
- svga->fullchange = changeframecount;
break;
case 0x81dc:
ret = virge->streams.overlay_ctrl;
- svga->fullchange = changeframecount;
break;
case 0x81e0:
ret = virge->streams.k1_vert_scale;
@@ -1279,6 +1278,7 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) {
ret |= 0x00001000;
else
ret |= 0x00003000;
+
ret |= virge->subsys_stat;
if (!virge->virge_busy)
wake_fifo_thread(virge);
@@ -1293,12 +1293,15 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) {
ret = virge->cmd_dma_base;
break;
case 0x8594:
+ ret = virge->cmd_dma_write_ptr_reg;
break;
case 0x8598:
- ret = virge->dma_ptr;
+ ret = virge->cmd_dma_read_ptr_reg;
+ if (ret > virge->cmd_dma_write_ptr_reg)
+ ret = virge->cmd_dma_write_ptr_reg;
break;
case 0x859c:
- ret = virge->cmd_dma;
+ ret = 0; /*To prevent DMA overflows.*/
break;
case 0xa4d4:
@@ -1425,13 +1428,322 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) {
default:
ret = s3_virge_mmio_read_w(addr, priv) | (s3_virge_mmio_read_w(addr + 2, priv) << 16);
+ break;
}
+ //pclog("MMIO ReadL=%04x, ret=%08x.\n", addr & 0xfffc, ret);
return ret;
}
static void
-fifo_thread(void *param) {
+s3_virge_mmio_write_fifo_l(virge_t *virge, uint32_t addr, uint32_t val)
+{
+ switch (addr) {
+ case 0xa000 ... 0xa1fc:
+ {
+ int x = addr & 4;
+ int y = (addr >> 3) & 7;
+ int color;
+ int byte;
+ uint32_t newaddr = addr;
+ virge->s3d.pattern_8[y * 8 + x] = val & 0xff;
+ virge->s3d.pattern_8[y * 8 + x + 1] = val >> 8;
+ virge->s3d.pattern_8[y * 8 + x + 2] = val >> 16;
+ virge->s3d.pattern_8[y * 8 + x + 3] = val >> 24;
+
+ x = (addr >> 1) & 6;
+ y = (addr >> 4) & 7;
+ virge->s3d.pattern_16[y * 8 + x] = val & 0xffff;
+ virge->s3d.pattern_16[y * 8 + x + 1] = val >> 16;
+
+ newaddr &= 0x00ff;
+ for (uint8_t xx = 0; xx < 4; xx++) {
+ x = ((newaddr + xx) / 3) % 8;
+ y = ((newaddr + xx) / 24) % 8;
+ color = ((newaddr + xx) % 3) << 3;
+ byte = (xx << 3);
+ virge->s3d.pattern_24[y * 8 + x] &= ~(0xff << color);
+ virge->s3d.pattern_24[y * 8 + x] |= ((val >> byte) & 0xff) << color;
+ }
+
+ x = (addr >> 2) & 7;
+ y = (addr >> 5) & 7;
+ virge->s3d.pattern_32[y * 8 + x] = val & 0xffffff;
+ } break;
+
+ case 0xa4d4:
+ case 0xa8d4:
+ case 0xacd4:
+ virge->s3d.src_base = val & ((virge->memory_size == 8) ?
+ (val & 0x7ffff8) : (val & 0x3ffff8));
+ break;
+ case 0xa4d8:
+ case 0xa8d8:
+ case 0xacd8:
+ virge->s3d.dest_base = val & ((virge->memory_size == 8) ?
+ (val & 0x7ffff8) : (val & 0x3ffff8));
+ break;
+ case 0xa4dc:
+ case 0xa8dc:
+ case 0xacdc:
+ virge->s3d.clip_l = (val >> 16) & 0x7ff;
+ virge->s3d.clip_r = val & 0x7ff;
+ break;
+ case 0xa4e0:
+ case 0xa8e0:
+ case 0xace0:
+ virge->s3d.clip_t = (val >> 16) & 0x7ff;
+ virge->s3d.clip_b = val & 0x7ff;
+ break;
+ case 0xa4e4:
+ case 0xa8e4:
+ case 0xace4:
+ virge->s3d.dest_str = (val >> 16) & 0xff8;
+ virge->s3d.src_str = val & 0xff8;
+ break;
+ case 0xa4e8:
+ case 0xace8:
+ virge->s3d.mono_pat_0 = val;
+ break;
+ case 0xa4ec:
+ case 0xacec:
+ virge->s3d.mono_pat_1 = val;
+ break;
+ case 0xa4f0:
+ case 0xacf0:
+ virge->s3d.pat_bg_clr = val;
+ break;
+ case 0xa4f4:
+ case 0xa8f4:
+ case 0xacf4:
+ virge->s3d.pat_fg_clr = val;
+ break;
+ case 0xa4f8:
+ virge->s3d.src_bg_clr = val;
+ break;
+ case 0xa4fc:
+ virge->s3d.src_fg_clr = val;
+ break;
+ case 0xa500:
+ case 0xa900:
+ case 0xad00:
+ virge->s3d.cmd_set = val;
+ if (!(val & CMD_SET_AE))
+ s3_virge_bitblt(virge, -1, 0);
+ break;
+ case 0xa504:
+ virge->s3d.r_width = (val >> 16) & 0x7ff;
+ virge->s3d.r_height = val & 0x7ff;
+ break;
+ case 0xa508:
+ virge->s3d.rsrc_x = (val >> 16) & 0x7ff;
+ virge->s3d.rsrc_y = val & 0x7ff;
+ break;
+ case 0xa50c:
+ virge->s3d.rdest_x = (val >> 16) & 0x7ff;
+ virge->s3d.rdest_y = val & 0x7ff;
+ if (virge->s3d.cmd_set & CMD_SET_AE)
+ s3_virge_bitblt(virge, -1, 0);
+ break;
+ case 0xa96c:
+ virge->s3d.lxend0 = (val >> 16) & 0x7ff;
+ virge->s3d.lxend1 = val & 0x7ff;
+ break;
+ case 0xa970:
+ virge->s3d.ldx = (int32_t)val;
+ break;
+ case 0xa974:
+ virge->s3d.lxstart = val;
+ break;
+ case 0xa978:
+ virge->s3d.lystart = val & 0x7ff;
+ break;
+ case 0xa97c:
+ virge->s3d.lycnt = val & 0x7ff;
+ virge->s3d.line_dir = val >> 31;
+ if (virge->s3d.cmd_set & CMD_SET_AE)
+ s3_virge_bitblt(virge, -1, 0);
+ break;
+
+ case 0xad68:
+ virge->s3d.prdx = val;
+ break;
+ case 0xad6c:
+ virge->s3d.prxstart = val;
+ break;
+ case 0xad70:
+ virge->s3d.pldx = val;
+ break;
+ case 0xad74:
+ virge->s3d.plxstart = val;
+ break;
+ case 0xad78:
+ virge->s3d.pystart = val & 0x7ff;
+ break;
+ case 0xad7c:
+ virge->s3d.pycnt = val & 0x300007ff;
+ if (virge->s3d.cmd_set & CMD_SET_AE)
+ s3_virge_bitblt(virge, -1, 0);
+ break;
+
+ case 0xb0d4:
+ case 0xb4d4:
+ virge->s3d_tri.z_base = val & ((virge->memory_size == 8) ?
+ (val & 0x7ffff8) : (val & 0x3ffff8));
+ break;
+ case 0xb0d8:
+ case 0xb4d8:
+ virge->s3d_tri.dest_base = val & ((virge->memory_size == 8) ?
+ (val & 0x7ffff8) : (val & 0x3ffff8));
+ break;
+ case 0xb0dc:
+ case 0xb4dc:
+ virge->s3d_tri.clip_l = (val >> 16) & 0x7ff;
+ virge->s3d_tri.clip_r = val & 0x7ff;
+ break;
+ case 0xb0e0:
+ case 0xb4e0:
+ virge->s3d_tri.clip_t = (val >> 16) & 0x7ff;
+ virge->s3d_tri.clip_b = val & 0x7ff;
+ break;
+ case 0xb0e4:
+ case 0xb4e4:
+ virge->s3d_tri.dest_str = (val >> 16) & 0xff8;
+ virge->s3d.src_str = val & 0xff8;
+ break;
+ case 0xb0e8:
+ case 0xb4e8:
+ virge->s3d_tri.z_str = val & 0xff8;
+ break;
+ case 0xb4ec:
+ virge->s3d_tri.tex_base = val & ((virge->memory_size == 8) ?
+ (val & 0x7ffff8) : (val & 0x3ffff8));
+ break;
+ case 0xb4f0:
+ virge->s3d_tri.tex_bdr_clr = val & 0xffffff;
+ break;
+ case 0xb0f4:
+ case 0xb4f4:
+ virge->s3d_tri.fog_b = val & 0xff;
+ virge->s3d_tri.fog_g = (val >> 8) & 0xff;
+ virge->s3d_tri.fog_r = (val >> 16) & 0xff;
+ break;
+ case 0xb100:
+ case 0xb500:
+ virge->s3d_tri.cmd_set = val;
+ if (!(val & CMD_SET_AE))
+ queue_triangle(virge);
+ break;
+ case 0xb504:
+ virge->s3d_tri.tbv = val & 0xfffff;
+ break;
+ case 0xb508:
+ virge->s3d_tri.tbu = val & 0xfffff;
+ break;
+ case 0xb50c:
+ virge->s3d_tri.TdWdX = val;
+ break;
+ case 0xb510:
+ virge->s3d_tri.TdWdY = val;
+ break;
+ case 0xb514:
+ virge->s3d_tri.tws = val;
+ break;
+ case 0xb518:
+ virge->s3d_tri.TdDdX = val;
+ break;
+ case 0xb51c:
+ virge->s3d_tri.TdVdX = val;
+ break;
+ case 0xb520:
+ virge->s3d_tri.TdUdX = val;
+ break;
+ case 0xb524:
+ virge->s3d_tri.TdDdY = val;
+ break;
+ case 0xb528:
+ virge->s3d_tri.TdVdY = val;
+ break;
+ case 0xb52c:
+ virge->s3d_tri.TdUdY = val;
+ break;
+ case 0xb530:
+ virge->s3d_tri.tds = val;
+ break;
+ case 0xb534:
+ virge->s3d_tri.tvs = val;
+ break;
+ case 0xb538:
+ virge->s3d_tri.tus = val;
+ break;
+ case 0xb53c:
+ virge->s3d_tri.TdGdX = val >> 16;
+ virge->s3d_tri.TdBdX = val & 0xffff;
+ break;
+ case 0xb540:
+ virge->s3d_tri.TdAdX = val >> 16;
+ virge->s3d_tri.TdRdX = val & 0xffff;
+ break;
+ case 0xb544:
+ virge->s3d_tri.TdGdY = val >> 16;
+ virge->s3d_tri.TdBdY = val & 0xffff;
+ break;
+ case 0xb548:
+ virge->s3d_tri.TdAdY = val >> 16;
+ virge->s3d_tri.TdRdY = val & 0xffff;
+ break;
+ case 0xb54c:
+ virge->s3d_tri.tgs = (val >> 16) & 0xffff;
+ virge->s3d_tri.tbs = val & 0xffff;
+ break;
+ case 0xb550:
+ virge->s3d_tri.tas = (val >> 16) & 0xffff;
+ virge->s3d_tri.trs = val & 0xffff;
+ break;
+
+ case 0xb554:
+ virge->s3d_tri.TdZdX = val;
+ break;
+ case 0xb558:
+ virge->s3d_tri.TdZdY = val;
+ break;
+ case 0xb55c:
+ virge->s3d_tri.tzs = val;
+ break;
+ case 0xb560:
+ virge->s3d_tri.TdXdY12 = val;
+ break;
+ case 0xb564:
+ virge->s3d_tri.txend12 = val;
+ break;
+ case 0xb568:
+ virge->s3d_tri.TdXdY01 = val;
+ break;
+ case 0xb56c:
+ virge->s3d_tri.txend01 = val;
+ break;
+ case 0xb570:
+ virge->s3d_tri.TdXdY02 = val;
+ break;
+ case 0xb574:
+ virge->s3d_tri.txs = val;
+ break;
+ case 0xb578:
+ virge->s3d_tri.tys = val;
+ break;
+ case 0xb57c:
+ virge->s3d_tri.ty01 = (val >> 16) & 0x7ff;
+ virge->s3d_tri.ty12 = val & 0x7ff;
+ virge->s3d_tri.tlr = val >> 31;
+ if (virge->s3d_tri.cmd_set & CMD_SET_AE)
+ queue_triangle(virge);
+ break;
+ }
+}
+
+static void
+fifo_thread(void *param)
+{
virge_t *virge = (virge_t *)param;
while (virge->fifo_thread_run) {
@@ -1447,19 +1759,16 @@ fifo_thread(void *param) {
switch (fifo->addr_type & FIFO_TYPE) {
case FIFO_WRITE_BYTE:
- if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000)
+ if (((fifo->addr_type & FIFO_ADDR) & 0xffff) < 0x8000)
s3_virge_bitblt(virge, 8, val);
- else if (((fifo->addr_type & FIFO_ADDR) & 0xffff) == 0x859c)
- virge->cmd_dma = val;
break;
case FIFO_WRITE_WORD:
- if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) {
+ if (((fifo->addr_type & FIFO_ADDR) & 0xfffe) < 0x8000) {
if (virge->s3d.cmd_set & CMD_SET_MS)
s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16);
else
- s3_virge_bitblt(virge, 16, val);
- } else if (((fifo->addr_type & FIFO_ADDR) & 0xfffe) == 0x859c)
- virge->cmd_dma = val;
+ s3_virge_bitblt(virge, 16, val);
+ }
break;
case FIFO_WRITE_DWORD:
if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) {
@@ -1469,324 +1778,8 @@ fifo_thread(void *param) {
((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
else
s3_virge_bitblt(virge, 32, val);
- } else {
- switch ((fifo->addr_type & FIFO_ADDR) & 0xfffc) {
- case 0x8590:
- virge->cmd_dma_base = val;
- break;
-
- case 0x8594:
- virge->dma_ptr = val;
- break;
-
- case 0x8598:
- break;
-
- case 0x859c:
- virge->cmd_dma = val;
- break;
-
- case 0xa000 ... 0xa1fc:
- {
- int x = (fifo->addr_type & FIFO_ADDR) & 4;
- int y = ((fifo->addr_type & FIFO_ADDR) >> 3) & 7;
- int color;
- int byte;
- uint32_t addr = (fifo->addr_type & FIFO_ADDR);
- virge->s3d.pattern_8[y * 8 + x] = val & 0xff;
- virge->s3d.pattern_8[y * 8 + x + 1] = val >> 8;
- virge->s3d.pattern_8[y * 8 + x + 2] = val >> 16;
- virge->s3d.pattern_8[y * 8 + x + 3] = val >> 24;
-
- x = ((fifo->addr_type & FIFO_ADDR) >> 1) & 6;
- y = ((fifo->addr_type & FIFO_ADDR) >> 4) & 7;
- virge->s3d.pattern_16[y * 8 + x] = val & 0xffff;
- virge->s3d.pattern_16[y * 8 + x + 1] = val >> 16;
-
- addr &= 0x00ff;
- for (uint8_t xx = 0; xx < 4; xx++) {
- x = ((addr + xx) / 3) % 8;
- y = ((addr + xx) / 24) % 8;
- color = ((addr + xx) % 3) << 3;
- byte = (xx << 3);
- virge->s3d.pattern_24[y * 8 + x] &= ~(0xff << color);
- virge->s3d.pattern_24[y * 8 + x] |= ((val >> byte) & 0xff) << color;
- }
-
- x = ((fifo->addr_type & FIFO_ADDR) >> 2) & 7;
- y = ((fifo->addr_type & FIFO_ADDR) >> 5) & 7;
- virge->s3d.pattern_32[y * 8 + x] = val & 0xffffff;
- } break;
-
- case 0xa4d4:
- case 0xa8d4:
- case 0xacd4:
- virge->s3d.src_base = val & ((virge->memory_size == 8) ?
- (val & 0x7ffff8) : (val & 0x3ffff8));
- break;
- case 0xa4d8:
- case 0xa8d8:
- case 0xacd8:
- virge->s3d.dest_base = val & ((virge->memory_size == 8) ?
- (val & 0x7ffff8) : (val & 0x3ffff8));
- break;
- case 0xa4dc:
- case 0xa8dc:
- case 0xacdc:
- virge->s3d.clip_l = (val >> 16) & 0x7ff;
- virge->s3d.clip_r = val & 0x7ff;
- break;
- case 0xa4e0:
- case 0xa8e0:
- case 0xace0:
- virge->s3d.clip_t = (val >> 16) & 0x7ff;
- virge->s3d.clip_b = val & 0x7ff;
- break;
- case 0xa4e4:
- case 0xa8e4:
- case 0xace4:
- virge->s3d.dest_str = (val >> 16) & 0xff8;
- virge->s3d.src_str = val & 0xff8;
- break;
- case 0xa4e8:
- case 0xace8:
- virge->s3d.mono_pat_0 = val;
- break;
- case 0xa4ec:
- case 0xacec:
- virge->s3d.mono_pat_1 = val;
- break;
- case 0xa4f0:
- case 0xacf0:
- virge->s3d.pat_bg_clr = val;
- break;
- case 0xa4f4:
- case 0xa8f4:
- case 0xacf4:
- virge->s3d.pat_fg_clr = val;
- break;
- case 0xa4f8:
- virge->s3d.src_bg_clr = val;
- break;
- case 0xa4fc:
- virge->s3d.src_fg_clr = val;
- break;
- case 0xa500:
- case 0xa900:
- case 0xad00:
- virge->s3d.cmd_set = val;
- if (!(val & CMD_SET_AE))
- s3_virge_bitblt(virge, -1, 0);
- break;
- case 0xa504:
- virge->s3d.r_width = (val >> 16) & 0x7ff;
- virge->s3d.r_height = val & 0x7ff;
- break;
- case 0xa508:
- virge->s3d.rsrc_x = (val >> 16) & 0x7ff;
- virge->s3d.rsrc_y = val & 0x7ff;
- break;
- case 0xa50c:
- virge->s3d.rdest_x = (val >> 16) & 0x7ff;
- virge->s3d.rdest_y = val & 0x7ff;
- if (virge->s3d.cmd_set & CMD_SET_AE)
- s3_virge_bitblt(virge, -1, 0);
- break;
- case 0xa96c:
- virge->s3d.lxend0 = (val >> 16) & 0x7ff;
- virge->s3d.lxend1 = val & 0x7ff;
- break;
- case 0xa970:
- virge->s3d.ldx = (int32_t)val;
- break;
- case 0xa974:
- virge->s3d.lxstart = val;
- break;
- case 0xa978:
- virge->s3d.lystart = val & 0x7ff;
- break;
- case 0xa97c:
- virge->s3d.lycnt = val & 0x7ff;
- virge->s3d.line_dir = val >> 31;
- if (virge->s3d.cmd_set & CMD_SET_AE)
- s3_virge_bitblt(virge, -1, 0);
- break;
-
- case 0xad68:
- virge->s3d.prdx = val;
- break;
- case 0xad6c:
- virge->s3d.prxstart = val;
- break;
- case 0xad70:
- virge->s3d.pldx = val;
- break;
- case 0xad74:
- virge->s3d.plxstart = val;
- break;
- case 0xad78:
- virge->s3d.pystart = val & 0x7ff;
- break;
- case 0xad7c:
- virge->s3d.pycnt = val & 0x300007ff;
- if (virge->s3d.cmd_set & CMD_SET_AE)
- s3_virge_bitblt(virge, -1, 0);
- break;
-
- case 0xb0d4:
- case 0xb4d4:
- virge->s3d_tri.z_base = val & ((virge->memory_size == 8) ?
- (val & 0x7ffff8) : (val & 0x3ffff8));
- break;
- case 0xb0d8:
- case 0xb4d8:
- virge->s3d_tri.dest_base = val & ((virge->memory_size == 8) ?
- (val & 0x7ffff8) : (val & 0x3ffff8));
- break;
- case 0xb0dc:
- case 0xb4dc:
- virge->s3d_tri.clip_l = (val >> 16) & 0x7ff;
- virge->s3d_tri.clip_r = val & 0x7ff;
- break;
- case 0xb0e0:
- case 0xb4e0:
- virge->s3d_tri.clip_t = (val >> 16) & 0x7ff;
- virge->s3d_tri.clip_b = val & 0x7ff;
- break;
- case 0xb0e4:
- case 0xb4e4:
- virge->s3d_tri.dest_str = (val >> 16) & 0xff8;
- virge->s3d.src_str = val & 0xff8;
- break;
- case 0xb0e8:
- case 0xb4e8:
- virge->s3d_tri.z_str = val & 0xff8;
- break;
- case 0xb4ec:
- virge->s3d_tri.tex_base = val & ((virge->memory_size == 8) ?
- (val & 0x7ffff8) : (val & 0x3ffff8));
- break;
- case 0xb4f0:
- virge->s3d_tri.tex_bdr_clr = val & 0xffffff;
- break;
- case 0xb0f4:
- case 0xb4f4:
- virge->s3d_tri.fog_b = val & 0xff;
- virge->s3d_tri.fog_g = (val >> 8) & 0xff;
- virge->s3d_tri.fog_r = (val >> 16) & 0xff;
- break;
- case 0xb100:
- case 0xb500:
- virge->s3d_tri.cmd_set = val;
- if (!(val & CMD_SET_AE))
- queue_triangle(virge);
- break;
- case 0xb504:
- virge->s3d_tri.tbv = val & 0xfffff;
- break;
- case 0xb508:
- virge->s3d_tri.tbu = val & 0xfffff;
- break;
- case 0xb50c:
- virge->s3d_tri.TdWdX = val;
- break;
- case 0xb510:
- virge->s3d_tri.TdWdY = val;
- break;
- case 0xb514:
- virge->s3d_tri.tws = val;
- break;
- case 0xb518:
- virge->s3d_tri.TdDdX = val;
- break;
- case 0xb51c:
- virge->s3d_tri.TdVdX = val;
- break;
- case 0xb520:
- virge->s3d_tri.TdUdX = val;
- break;
- case 0xb524:
- virge->s3d_tri.TdDdY = val;
- break;
- case 0xb528:
- virge->s3d_tri.TdVdY = val;
- break;
- case 0xb52c:
- virge->s3d_tri.TdUdY = val;
- break;
- case 0xb530:
- virge->s3d_tri.tds = val;
- break;
- case 0xb534:
- virge->s3d_tri.tvs = val;
- break;
- case 0xb538:
- virge->s3d_tri.tus = val;
- break;
- case 0xb53c:
- virge->s3d_tri.TdGdX = val >> 16;
- virge->s3d_tri.TdBdX = val & 0xffff;
- break;
- case 0xb540:
- virge->s3d_tri.TdAdX = val >> 16;
- virge->s3d_tri.TdRdX = val & 0xffff;
- break;
- case 0xb544:
- virge->s3d_tri.TdGdY = val >> 16;
- virge->s3d_tri.TdBdY = val & 0xffff;
- break;
- case 0xb548:
- virge->s3d_tri.TdAdY = val >> 16;
- virge->s3d_tri.TdRdY = val & 0xffff;
- break;
- case 0xb54c:
- virge->s3d_tri.tgs = (val >> 16) & 0xffff;
- virge->s3d_tri.tbs = val & 0xffff;
- break;
- case 0xb550:
- virge->s3d_tri.tas = (val >> 16) & 0xffff;
- virge->s3d_tri.trs = val & 0xffff;
- break;
-
- case 0xb554:
- virge->s3d_tri.TdZdX = val;
- break;
- case 0xb558:
- virge->s3d_tri.TdZdY = val;
- break;
- case 0xb55c:
- virge->s3d_tri.tzs = val;
- break;
- case 0xb560:
- virge->s3d_tri.TdXdY12 = val;
- break;
- case 0xb564:
- virge->s3d_tri.txend12 = val;
- break;
- case 0xb568:
- virge->s3d_tri.TdXdY01 = val;
- break;
- case 0xb56c:
- virge->s3d_tri.txend01 = val;
- break;
- case 0xb570:
- virge->s3d_tri.TdXdY02 = val;
- break;
- case 0xb574:
- virge->s3d_tri.txs = val;
- break;
- case 0xb578:
- virge->s3d_tri.tys = val;
- break;
- case 0xb57c:
- virge->s3d_tri.ty01 = (val >> 16) & 0x7ff;
- virge->s3d_tri.ty12 = val & 0x7ff;
- virge->s3d_tri.tlr = val >> 31;
- if (virge->s3d_tri.cmd_set & CMD_SET_AE)
- queue_triangle(virge);
- break;
- }
- }
+ } else
+ s3_virge_mmio_write_fifo_l(virge, (fifo->addr_type & FIFO_ADDR) & 0xfffc, val);
break;
}
@@ -1801,18 +1794,42 @@ fifo_thread(void *param) {
}
virge->virge_busy = 0;
virge->subsys_stat |= INT_FIFO_EMP | INT_3DF_EMP;
+ if (virge->cmd_dma)
+ virge->subsys_stat |= INT_HOST_DONE | INT_CMD_DONE;
+
s3_virge_update_irqs(virge);
}
}
static void
-s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type) {
+s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type)
+{
fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx & FIFO_MASK];
+ int limit = 0;
- if (FIFO_FULL) {
- thread_reset_event(virge->fifo_not_full_event);
- if (FIFO_FULL)
- thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/
+ if (type == FIFO_WRITE_DWORD) {
+ switch (addr & 0xfffc) {
+ case 0xa500:
+ if (val & CMD_SET_AE)
+ limit = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (limit) {
+ if (FIFO_ENTRIES >= 16) {
+ thread_reset_event(virge->fifo_not_full_event);
+ if (FIFO_ENTRIES >= 16)
+ thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/
+ }
+ } else {
+ if (FIFO_FULL) {
+ thread_reset_event(virge->fifo_not_full_event);
+ if (FIFO_FULL)
+ thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/
+ }
}
fifo->val = val;
@@ -1830,7 +1847,7 @@ static void
s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv) {
virge_t *virge = (virge_t *) priv;
- if ((addr & 0xfffc) < 0x8000)
+ if ((addr & 0xffff) < 0x8000)
s3_virge_queue(virge, addr, val, FIFO_WRITE_BYTE);
else switch (addr & 0xffff) {
case 0x83b0 ... 0x83df:
@@ -1848,9 +1865,10 @@ static void
s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv) {
virge_t *virge = (virge_t *) priv;
- if ((addr & 0xfffc) < 0x8000)
+ if ((addr & 0xfffe) < 0x8000)
s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD);
else switch (addr & 0xfffe) {
+ default:
case 0x83d4:
s3_virge_mmio_write(addr, val, priv);
s3_virge_mmio_write(addr + 1, val >> 8, priv);
@@ -1865,144 +1883,192 @@ s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv) {
static void
s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
virge_t *virge = (virge_t *) priv;
- svga_t * svga = &virge->svga;
+ svga_t *svga = &virge->svga;
if ((addr & 0xfffc) < 0x8000)
s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD);
else if ((addr & 0xe000) == 0xa000)
s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD);
- else switch (addr & 0xfffc) {
- case 0x8180:
- virge->streams.pri_ctrl = val;
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
- case 0x8184:
- virge->streams.chroma_ctrl = val;
- break;
- case 0x8190:
- virge->streams.sec_ctrl = val;
- virge->streams.dda_horiz_accumulator = val & 0xfff;
- if (val & (1 << 11))
- virge->streams.dda_horiz_accumulator |= 0xfffff800;
- virge->streams.sdif = (val >> 24) & 7;
- break;
- case 0x8194:
- virge->streams.chroma_upper_bound = val;
- break;
- case 0x8198:
- virge->streams.sec_filter = val;
- virge->streams.k1_horiz_scale = val & 0x7ff;
- if (val & (1 << 10))
- virge->streams.k1_horiz_scale |= 0xfffff800;
- virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff;
- if ((val >> 16) & (1 << 10))
- virge->streams.k2_horiz_scale |= 0xfffff800;
- break;
- case 0x81a0:
- virge->streams.blend_ctrl = val;
- break;
- case 0x81c0:
- virge->streams.pri_fb0 = val & ((virge->memory_size == 8) ?
- (val & 0x7fffff) : (val & 0x3fffff));
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
- case 0x81c4:
- virge->streams.pri_fb1 = ((virge->memory_size == 8) ?
- (val & 0x7fffff) : (val & 0x3fffff));
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
- case 0x81c8:
- virge->streams.pri_stride = val & 0xfff;
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
- case 0x81cc:
- virge->streams.buffer_ctrl = val;
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
- case 0x81d0:
- virge->streams.sec_fb0 = val;
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
- case 0x81d4:
- virge->streams.sec_fb1 = val;
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
- case 0x81d8:
- virge->streams.sec_stride = val;
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
- case 0x81dc:
- virge->streams.overlay_ctrl = val;
- break;
- case 0x81e0:
- virge->streams.k1_vert_scale = val & 0x7ff;
- if (val & (1 << 10))
- virge->streams.k1_vert_scale |= 0xfffff800;
- break;
- case 0x81e4:
- virge->streams.k2_vert_scale = val & 0x7ff;
- if (val & (1 << 10))
- virge->streams.k2_vert_scale |= 0xfffff800;
- break;
- case 0x81e8:
- virge->streams.dda_vert_accumulator = val & 0xfff;
- if (val & (1 << 11))
- virge->streams.dda_vert_accumulator |= 0xfffff800;
- break;
- case 0x81ec:
- virge->streams.fifo_ctrl = val;
- break;
- case 0x81f0:
- virge->streams.pri_start = val;
- virge->streams.pri_x = (val >> 16) & 0x7ff;
- virge->streams.pri_y = val & 0x7ff;
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
- case 0x81f4:
- virge->streams.pri_size = val;
- virge->streams.pri_w = (val >> 16) & 0x7ff;
- virge->streams.pri_h = val & 0x7ff;
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
- case 0x81f8:
- virge->streams.sec_start = val;
- virge->streams.sec_x = (val >> 16) & 0x7ff;
- virge->streams.sec_y = val & 0x7ff;
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
- case 0x81fc:
- virge->streams.sec_size = val;
- virge->streams.sec_w = (val >> 16) & 0x7ff;
- virge->streams.sec_h = val & 0x7ff;
- svga_recalctimings(svga);
- svga->fullchange = changeframecount;
- break;
+ else {
+ switch (addr & 0xfffc) {
+ case 0x8180:
+ virge->streams.pri_ctrl = val;
+ svga_recalctimings(svga);
+ svga->fullchange = changeframecount;
+ break;
+ case 0x8184:
+ virge->streams.chroma_ctrl = val;
+ break;
+ case 0x8190:
+ virge->streams.sec_ctrl = val;
+ virge->streams.dda_horiz_accumulator = val & 0xfff;
+ if (val & (1 << 11))
+ virge->streams.dda_horiz_accumulator |= 0xfffff800;
+ virge->streams.sdif = (val >> 24) & 7;
+ break;
+ case 0x8194:
+ virge->streams.chroma_upper_bound = val;
+ break;
+ case 0x8198:
+ virge->streams.sec_filter = val;
+ virge->streams.k1_horiz_scale = val & 0x7ff;
+ if (val & (1 << 10))
+ virge->streams.k1_horiz_scale |= 0xfffff800;
+ virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff;
+ if ((val >> 16) & (1 << 10))
+ virge->streams.k2_horiz_scale |= 0xfffff800;
+ break;
+ case 0x81a0:
+ virge->streams.blend_ctrl = val;
+ break;
+ case 0x81c0:
+ virge->streams.pri_fb0 = val & ((virge->memory_size == 8) ?
+ (val & 0x7fffff) : (val & 0x3fffff));
+ s3_virge_update_buffer(virge);
+ svga->fullchange = changeframecount;
+ break;
+ case 0x81c4:
+ virge->streams.pri_fb1 = ((virge->memory_size == 8) ?
+ (val & 0x7fffff) : (val & 0x3fffff));
+ s3_virge_update_buffer(virge);
+ svga->fullchange = changeframecount;
+ break;
+ case 0x81c8:
+ virge->streams.pri_stride = val & 0xfff;
+ s3_virge_update_buffer(virge);
+ svga->fullchange = changeframecount;
+ break;
+ case 0x81cc:
+ virge->streams.buffer_ctrl = val;
+ s3_virge_update_buffer(virge);
+ svga->fullchange = changeframecount;
+ break;
+ case 0x81d0:
+ virge->streams.sec_fb0 = val;
+ s3_virge_update_buffer(virge);
+ svga->fullchange = changeframecount;
+ break;
+ case 0x81d4:
+ virge->streams.sec_fb1 = val;
+ s3_virge_update_buffer(virge);
+ svga->fullchange = changeframecount;
+ break;
+ case 0x81d8:
+ virge->streams.sec_stride = val;
+ s3_virge_update_buffer(virge);
+ svga->fullchange = changeframecount;
+ break;
+ case 0x81dc:
+ virge->streams.overlay_ctrl = val;
+ break;
+ case 0x81e0:
+ virge->streams.k1_vert_scale = val & 0x7ff;
+ if (val & (1 << 10))
+ virge->streams.k1_vert_scale |= 0xfffff800;
+ break;
+ case 0x81e4:
+ virge->streams.k2_vert_scale = val & 0x7ff;
+ if (val & (1 << 10))
+ virge->streams.k2_vert_scale |= 0xfffff800;
+ break;
+ case 0x81e8:
+ virge->streams.dda_vert_accumulator = val & 0xfff;
+ if (val & (1 << 11))
+ virge->streams.dda_vert_accumulator |= 0xfffff800;
+ break;
+ case 0x81ec:
+ virge->streams.fifo_ctrl = val;
+ break;
+ case 0x81f0:
+ virge->streams.pri_start = val;
+ virge->streams.pri_x = (val >> 16) & 0x7ff;
+ virge->streams.pri_y = val & 0x7ff;
+ svga_recalctimings(svga);
+ svga->fullchange = changeframecount;
+ break;
+ case 0x81f4:
+ virge->streams.pri_size = val;
+ virge->streams.pri_w = (val >> 16) & 0x7ff;
+ virge->streams.pri_h = val & 0x7ff;
+ svga_recalctimings(svga);
+ svga->fullchange = changeframecount;
+ break;
+ case 0x81f8:
+ virge->streams.sec_start = val;
+ virge->streams.sec_x = (val >> 16) & 0x7ff;
+ virge->streams.sec_y = val & 0x7ff;
+ svga_recalctimings(svga);
+ svga->fullchange = changeframecount;
+ break;
+ case 0x81fc:
+ virge->streams.sec_size = val;
+ virge->streams.sec_w = (val >> 16) & 0x7ff;
+ virge->streams.sec_h = val & 0x7ff;
+ svga_recalctimings(svga);
+ svga->fullchange = changeframecount;
+ break;
- case 0x8504:
- virge->subsys_stat &= ~(val & 0xff);
- virge->subsys_cntl = (val >> 8);
- s3_virge_update_irqs(virge);
- break;
+ case 0x8504:
+ virge->subsys_stat &= ~(val & 0xff);
+ virge->subsys_cntl = (val >> 8);
+ s3_virge_update_irqs(virge);
+ break;
- case 0x850c:
- virge->advfunc_cntl = val & 0xff;
- s3_virge_updatemapping(virge);
- break;
+ case 0x850c:
+ virge->advfunc_cntl = val & 0xff;
+ s3_virge_updatemapping(virge);
+ break;
- case 0xff20:
- s3_virge_mmio_write(addr, val, priv);
- break;
+ case 0x8590:
+ virge->cmd_dma_base = val;
+ virge->cmd_dma_buf_size = (val & 2) ? 0x10000 : 0x1000;
+ virge->cmd_dma_buf_size_mask = virge->cmd_dma_buf_size - 1;
+ virge->cmd_base_addr = (val & 2) ? (val & 0xffff0000) : (val & 0xfffff000);
+ break;
+
+ case 0x8594:
+ virge->cmd_dma_write_ptr_update = val & (1 << 16);
+ if (virge->cmd_dma_write_ptr_update) {
+ virge->cmd_dma_write_ptr_reg = (virge->cmd_dma_buf_size == 0x10000) ? (val & 0xffff) : (val & 0xfff);
+ virge->dma_dbl_words = 0;
+ virge->dma_data_type = 0;
+ virge->dma_val = 0;
+ if (virge->cmd_dma) {
+ while (virge->cmd_dma_read_ptr_reg != virge->cmd_dma_write_ptr_reg) {
+ virge->cmd_dma_write_ptr_update = 0;
+ dma_bm_read(virge->cmd_base_addr + virge->cmd_dma_read_ptr_reg, (uint8_t *)&virge->dma_val, 4, 4);
+ if (!virge->dma_dbl_words) {
+ virge->dma_dbl_words = (virge->dma_val & 0xffff);
+ virge->dma_data_type = !!(virge->dma_val & (1 << 31));
+ if (virge->dma_data_type)
+ virge->dma_mmio_addr = 0;
+ else
+ virge->dma_mmio_addr = ((virge->dma_val >> 16) << 2) & 0xfffc;
+ } else {
+ s3_virge_mmio_write_l(virge->dma_mmio_addr, virge->dma_val, virge);
+ virge->dma_dbl_words--;
+ virge->dma_mmio_addr = (virge->dma_mmio_addr + 4) & 0xfffc;
+ }
+ virge->cmd_dma_read_ptr_reg = (virge->cmd_dma_read_ptr_reg + 4) & (virge->cmd_dma_buf_size_mask - 3);
+ }
+ }
+ }
+ break;
+
+ case 0x8598:
+ virge->cmd_dma_read_ptr_reg = (virge->cmd_dma_buf_size == 0x10000) ? (val & 0xffff) : (val & 0xfff);
+ break;
+
+ case 0x859c:
+ virge->cmd_dma = val & 1;
+ virge->cmd_dma_write_ptr_reg = 0;
+ virge->cmd_dma_read_ptr_reg = 0;
+ break;
+
+ case 0xff20:
+ s3_virge_mmio_write(addr, val, priv);
+ break;
+ }
}
}
@@ -2010,22 +2076,22 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
do { \
switch (bpp) { \
case 0: /*8 bpp*/ \
- val = vram[addr & svga->vram_mask]; \
+ val = vram[addr & virge->vram_mask]; \
break; \
case 1: /*16 bpp*/ \
- val = *(uint16_t *)&vram[addr & svga->vram_mask]; \
+ val = *(uint16_t *)&vram[addr & virge->vram_mask]; \
break; \
case 2: /*24 bpp*/ \
- val = (*(uint32_t *)&vram[addr & svga->vram_mask]) & 0xffffff; \
+ val = (*(uint32_t *)&vram[addr & virge->vram_mask]) & 0xffffff; \
break; \
} \
} while (0)
-#define Z_READ(addr) *(uint16_t *)&vram[addr & svga->vram_mask]
+#define Z_READ(addr) *(uint16_t *)&vram[addr & virge->vram_mask]
#define Z_WRITE(addr, val) \
if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) \
- *(uint16_t *)&vram[addr & svga->vram_mask] = val
+ *(uint16_t *)&vram[addr & virge->vram_mask] = val
#define CLIP(x, y) \
do { \
@@ -2040,7 +2106,7 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
if ((s3d_tri->cmd_set & CMD_SET_HC) && (x < s3d_tri->clip_l || \
x > s3d_tri->clip_r || y < s3d_tri->clip_t || \
y > s3d_tri->clip_b)) \
- update = 0; \
+ update = 0; \
} while (0)
#define Z_CLIP(Zzb, Zs) \
@@ -2111,19 +2177,19 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
do { \
switch (bpp) { \
case 0: /*8 bpp*/ \
- vram[addr & svga->vram_mask] = val; \
- virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = \
+ vram[addr & virge->vram_mask] = val; \
+ virge->svga.changedvram[(addr & virge->vram_mask) >> 12] = \
changeframecount; \
break; \
case 1: /*16 bpp*/ \
- *(uint16_t *)&vram[addr & svga->vram_mask] = val; \
- virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = \
+ *(uint16_t *)&vram[addr & virge->vram_mask] = val; \
+ virge->svga.changedvram[(addr & virge->vram_mask) >> 12] = \
changeframecount; \
break; \
case 2: /*24 bpp*/ \
- *(uint32_t *)&vram[addr & svga->vram_mask] = (val & 0xffffff) |\
- (vram[(addr + 3) & svga->vram_mask] << 24); \
- virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = \
+ *(uint32_t *)&vram[addr & virge->vram_mask] = (val & 0xffffff) |\
+ (vram[(addr + 3) & virge->vram_mask] << 24); \
+ virge->svga.changedvram[(addr & virge->vram_mask) >> 12] = \
changeframecount; \
break; \
} \
@@ -2131,7 +2197,6 @@ 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;
@@ -2192,13 +2257,13 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) {
for (y = 0; y < 4; y++) {
for (x = 0; x < 8; x++) {
if (virge->s3d.mono_pat_0 & (1 << (x + y * 8)))
- mono_pattern[y * 8 + x] = virge->s3d.pat_fg_clr;
+ mono_pattern[y * 8 + (7 - x)] = virge->s3d.pat_fg_clr;
else
- mono_pattern[y * 8 + x] = virge->s3d.pat_bg_clr;
+ mono_pattern[y * 8 + (7 - x)] = virge->s3d.pat_bg_clr;
if (virge->s3d.mono_pat_1 & (1 << (x + y * 8)))
- mono_pattern[(y + 4) * 8 + x] = virge->s3d.pat_fg_clr;
+ mono_pattern[(y + 4) * 8 + (7 - x)] = virge->s3d.pat_fg_clr;
else
- mono_pattern[(y + 4) * 8 + x] = virge->s3d.pat_bg_clr;
+ mono_pattern[(y + 4) * 8 + (7 - x)] = virge->s3d.pat_bg_clr;
}
}
}
@@ -2228,7 +2293,7 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) {
uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) +
(virge->s3d.dest_y * virge->s3d.dest_str);
uint32_t source = 0;
- uint32_t dest;
+ uint32_t dest = 0;
uint32_t pattern;
uint32_t out = 0;
int update = 1;
@@ -2333,7 +2398,7 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) {
uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) +
(virge->s3d.dest_y * virge->s3d.dest_str);
uint32_t source = 0;
- uint32_t dest;
+ uint32_t dest = 0;
uint32_t pattern = virge->s3d.pat_fg_clr;
uint32_t out = 0;
int update = 1;
@@ -2398,7 +2463,7 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) {
uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) +
(virge->s3d.dest_y * virge->s3d.dest_str);
uint32_t source = 0;
- uint32_t dest;
+ uint32_t dest = 0;
uint32_t pattern;
uint32_t out = 0;
int update = 1;
@@ -2454,7 +2519,7 @@ skip_line:
do {
uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (y * virge->s3d.dest_str);
uint32_t source = 0;
- uint32_t dest;
+ uint32_t dest = 0;
uint32_t pattern;
uint32_t out = 0;
int update = 1;
@@ -3163,7 +3228,6 @@ dest_pixel_lit_texture_modulate(s3d_state_t *state) {
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 = virge->svga.vram;
int x_dir = s3d_tri->tlr ? 1 : -1;
int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE);
@@ -3283,7 +3347,7 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int
}
}
- virge->svga.changedvram[(dest_offset & svga->vram_mask) >> 12] = changeframecount;
+ virge->svga.changedvram[(dest_offset & virge->vram_mask) >> 12] = changeframecount;
dest_addr = dest_offset + (x * (bpp + 1));
z_addr = z_offset + (x << 1);
@@ -3314,23 +3378,24 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int
state->dest_rgba.g = ((state->dest_rgba.g * a) + (s3d_tri->fog_g * (255 - a))) / 255;
state->dest_rgba.b = ((state->dest_rgba.b * a) + (s3d_tri->fog_b * (255 - a))) / 255;
}
-
+
if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) {
uint32_t src_col;
int src_r = 0;
uint32_t src_g = 0;
uint32_t src_b = 0;
+
switch (bpp) {
case 0: /*8 bpp*/
/*Not implemented yet*/
break;
case 1: /*16 bpp*/
- src_col = *(uint16_t *)&vram[dest_addr & svga->vram_mask];
+ src_col = *(uint16_t *)&vram[dest_addr & virge->vram_mask];
RGB15_TO_24(src_col, src_r, src_g, src_b);
break;
case 2: /*24 bpp*/
- src_col = (*(uint32_t *)&vram[dest_addr & svga->vram_mask]) & 0xffffff;
+ src_col = (*(uint32_t *)&vram[dest_addr & virge->vram_mask]) & 0xffffff;
RGB24_TO_24(src_col, src_r, src_g, src_b);
break;
}
@@ -3377,7 +3442,7 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int
virge->pixel_count++;
}
}
-
+
tri_skip_line:
state->x1 += dx1;
state->x2 += dx2;
@@ -3543,7 +3608,8 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) {
}
static void
-render_thread(void *param) {
+render_thread(void *param)
+{
virge_t *virge = (virge_t *)param;
while (virge->render_thread_run) {
@@ -3554,7 +3620,7 @@ render_thread(void *param) {
s3_virge_triangle(virge, &virge->s3d_buffer[virge->s3d_read_idx & RB_MASK]);
virge->s3d_read_idx++;
- if (RB_ENTRIES == (RB_SIZE - 1))
+ if (RB_ENTRIES == RB_MASK)
thread_set_event(virge->not_full_event);
}
virge->s3d_busy = 0;
@@ -3564,7 +3630,8 @@ render_thread(void *param) {
}
static void
-queue_triangle(virge_t *virge) {
+queue_triangle(virge_t *virge)
+{
if (RB_FULL) {
thread_reset_event(virge->not_full_event);
if (RB_FULL)
@@ -4342,7 +4409,7 @@ s3_virge_init(const device_t *info)
io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge);
- virge->pci_regs[PCI_REG_COMMAND] = 3;
+ virge->pci_regs[PCI_REG_COMMAND] = 7;
virge->pci_regs[0x05] = 0;
virge->pci_regs[0x06] = 0;
virge->pci_regs[0x07] = 2;
diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c
index 74d9a4d0c..c05d308fa 100644
--- a/src/video/vid_svga_render.c
+++ b/src/video/vid_svga_render.c
@@ -178,14 +178,14 @@ svga_render_text_40(svga_t *svga)
charaddr = svga->charseta + (chr * 128);
if (drawcursor) {
- bg = svga->pallook[svga->egapal[attr & 15]];
- fg = svga->pallook[svga->egapal[attr >> 4]];
+ bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask];
+ fg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask];
} else {
- fg = svga->pallook[svga->egapal[attr & 15]];
- bg = svga->pallook[svga->egapal[attr >> 4]];
+ fg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask];
+ bg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask];
if (attr & 0x80 && svga->attrregs[0x10] & 8) {
- bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
+ bg = svga->pallook[svga->egapal[(attr >> 4) & 7] & svga->dac_mask];
if (svga->blink & 16)
fg = bg;
}
@@ -256,13 +256,13 @@ svga_render_text_80(svga_t *svga)
charaddr = svga->charseta + (chr * 128);
if (drawcursor) {
- bg = svga->pallook[svga->egapal[attr & 15]];
- fg = svga->pallook[svga->egapal[attr >> 4]];
+ bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask];
+ fg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask];
} else {
- fg = svga->pallook[svga->egapal[attr & 15]];
- bg = svga->pallook[svga->egapal[attr >> 4]];
+ fg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask];
+ bg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask];
if (attr & 0x80 && svga->attrregs[0x10] & 8) {
- bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
+ bg = svga->pallook[svga->egapal[(attr >> 4) & 7] & svga->dac_mask];
if (svga->blink & 16)
fg = bg;
}
@@ -323,13 +323,13 @@ svga_render_text_80_ksc5601(svga_t *svga)
attr = svga->vram[addr + 1];
if (drawcursor) {
- bg = svga->pallook[svga->egapal[attr & 15]];
- fg = svga->pallook[svga->egapal[attr >> 4]];
+ bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask];
+ fg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask];
} else {
- fg = svga->pallook[svga->egapal[attr & 15]];
- bg = svga->pallook[svga->egapal[attr >> 4]];
+ fg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask];
+ bg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask];
if (attr & 0x80 && svga->attrregs[0x10] & 8) {
- bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
+ bg = svga->pallook[svga->egapal[(attr >> 4) & 7] & svga->dac_mask];
if (svga->blink & 16)
fg = bg;
}
@@ -378,13 +378,13 @@ svga_render_text_80_ksc5601(svga_t *svga)
attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
if (drawcursor) {
- bg = svga->pallook[svga->egapal[attr & 15]];
- fg = svga->pallook[svga->egapal[attr >> 4]];
+ bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask];
+ fg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask];
} else {
- fg = svga->pallook[svga->egapal[attr & 15]];
- bg = svga->pallook[svga->egapal[attr >> 4]];
+ fg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask];
+ bg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask];
if (attr & 0x80 && svga->attrregs[0x10] & 8) {
- bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
+ bg = svga->pallook[svga->egapal[(attr >> 4) & 7] & svga->dac_mask];
if (svga->blink & 16)
fg = bg;
}
@@ -468,14 +468,14 @@ svga_render_2bpp_s3_lowres(svga_t *svga)
else
svga->ma += 4;
svga->ma &= svga->vram_mask;
- p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
- p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
- p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
- p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]];
- p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
- p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
- p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
- p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]];
+ p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask];
+ p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask];
+ p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3] & svga->dac_mask];
+ p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask];
+ p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask];
+ p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask];
+ p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask];
+ p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask];
p += 16;
}
}
@@ -501,14 +501,14 @@ svga_render_2bpp_s3_lowres(svga_t *svga)
svga->ma &= svga->vram_mask;
- p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
- p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
- p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
- p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]];
- p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
- p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
- p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
- p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]];
+ p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask];
+ p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask];
+ p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3] & svga->dac_mask];
+ p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask];
+ p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask];
+ p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask];
+ p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask];
+ p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask];
p += 16;
}
@@ -566,14 +566,14 @@ svga_render_2bpp_s3_highres(svga_t *svga)
else
svga->ma += 4;
svga->ma &= svga->vram_mask;
- p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
- p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
- p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
- p[3] = svga->pallook[svga->egapal[dat[0] & 3]];
- p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
- p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
- p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
- p[7] = svga->pallook[svga->egapal[dat[1] & 3]];
+ p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask];
+ p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask];
+ p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3] & svga->dac_mask];
+ p[3] = svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask];
+ p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask];
+ p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask];
+ p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask];
+ p[7] = svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask];
p += 8;
}
}
@@ -599,14 +599,14 @@ svga_render_2bpp_s3_highres(svga_t *svga)
svga->ma &= svga->vram_mask;
- p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
- p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
- p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
- p[3] = svga->pallook[svga->egapal[dat[0] & 3]];
- p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
- p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
- p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
- p[7] = svga->pallook[svga->egapal[dat[1] & 3]];
+ p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask];
+ p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask];
+ p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3] & svga->dac_mask];
+ p[3] = svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask];
+ p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask];
+ p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask];
+ p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask];
+ p[7] = svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask];
p += 8;
}
@@ -652,17 +652,17 @@ svga_render_2bpp_headland_highres(svga_t *svga)
svga->ma &= svga->vram_mask;
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
- p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask];
+ p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
- p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask];
+ p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
- p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask];
+ p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
- p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask];
+ p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask];
p += 8;
}
@@ -868,8 +868,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits)
}
} else if (combine8bits) {
if (svga->packed_4bpp) {
- uint32_t p0 = svga->map8[c0];
- uint32_t p1 = svga->map8[c1];
+ uint32_t p0 = svga->map8[c0 & svga->dac_mask];
+ uint32_t p1 = svga->map8[c1 & svga->dac_mask];
const int outoffs = i << dwshift;
for (int subx = 0; subx < dotwidth; subx++)
p[outoffs + subx] = p0;
@@ -877,14 +877,14 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits)
p[outoffs + subx + dotwidth] = p1;
} else {
uint32_t ccombined = (c0 << 4) | c1;
- uint32_t p0 = svga->map8[ccombined];
+ uint32_t p0 = svga->map8[ccombined & svga->dac_mask];
const int outoffs = (i >> 1) << dwshift;
for (int subx = 0; subx < dotwidth; subx++)
p[outoffs + subx] = p0;
}
} else {
- uint32_t p0 = svga->pallook[svga->egapal[c0]];
- uint32_t p1 = svga->pallook[svga->egapal[c1]];
+ uint32_t p0 = svga->pallook[svga->egapal[c0] & svga->dac_mask];
+ uint32_t p1 = svga->pallook[svga->egapal[c1] & svga->dac_mask];
const int outoffs = i << dwshift;
for (int subx = 0; subx < dotwidth; subx++)
p[outoffs + subx] = p0;
@@ -934,16 +934,16 @@ svga_render_8bpp_clone_highres(svga_t *svga)
for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) {
dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]);
- p[0] = svga->map8[dat & 0xff];
- p[1] = svga->map8[(dat >> 8) & 0xff];
- p[2] = svga->map8[(dat >> 16) & 0xff];
- p[3] = svga->map8[(dat >> 24) & 0xff];
+ p[0] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
- p[4] = svga->map8[dat & 0xff];
- p[5] = svga->map8[(dat >> 8) & 0xff];
- p[6] = svga->map8[(dat >> 16) & 0xff];
- p[7] = svga->map8[(dat >> 24) & 0xff];
+ p[4] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[5] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[6] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
svga->ma += 8;
p += 8;
@@ -963,16 +963,16 @@ svga_render_8bpp_clone_highres(svga_t *svga)
if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) {
dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]);
- p[0] = svga->map8[dat & 0xff];
- p[1] = svga->map8[(dat >> 8) & 0xff];
- p[2] = svga->map8[(dat >> 16) & 0xff];
- p[3] = svga->map8[(dat >> 24) & 0xff];
+ p[0] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
- p[4] = svga->map8[dat & 0xff];
- p[5] = svga->map8[(dat >> 8) & 0xff];
- p[6] = svga->map8[(dat >> 16) & 0xff];
- p[7] = svga->map8[(dat >> 24) & 0xff];
+ p[4] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[5] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[6] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
svga->ma += 8;
p += 8;
@@ -981,10 +981,10 @@ svga_render_8bpp_clone_highres(svga_t *svga)
for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 4) {
addr = svga->remap_func(svga, svga->ma);
dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]);
- p[0] = svga->map8[dat & 0xff];
- p[1] = svga->map8[(dat >> 8) & 0xff];
- p[2] = svga->map8[(dat >> 16) & 0xff];
- p[3] = svga->map8[(dat >> 24) & 0xff];
+ p[0] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
svga->ma += 4;
p += 4;
@@ -1043,10 +1043,10 @@ svga_render_8bpp_lowres(svga_t *svga)
if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]);
- p[0] = p[1] = svga->map8[dat & 0xff];
- p[2] = p[3] = svga->map8[(dat >> 8) & 0xff];
- p[4] = p[5] = svga->map8[(dat >> 16) & 0xff];
- p[6] = p[7] = svga->map8[(dat >> 24) & 0xff];
+ p[0] = p[1] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[2] = p[3] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[4] = p[5] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[6] = p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
svga->ma += 4;
p += 8;
@@ -1055,10 +1055,10 @@ svga_render_8bpp_lowres(svga_t *svga)
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
addr = svga->remap_func(svga, svga->ma);
dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]);
- p[0] = p[1] = svga->map8[dat & 0xff];
- p[2] = p[3] = svga->map8[(dat >> 8) & 0xff];
- p[4] = p[5] = svga->map8[(dat >> 16) & 0xff];
- p[6] = p[7] = svga->map8[(dat >> 24) & 0xff];
+ p[0] = p[1] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[2] = p[3] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[4] = p[5] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[6] = p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
svga->ma += 4;
p += 8;
@@ -1091,16 +1091,16 @@ svga_render_8bpp_highres(svga_t *svga)
for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) {
dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]);
- p[0] = svga->map8[dat & 0xff];
- p[1] = svga->map8[(dat >> 8) & 0xff];
- p[2] = svga->map8[(dat >> 16) & 0xff];
- p[3] = svga->map8[(dat >> 24) & 0xff];
+ p[0] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
- p[4] = svga->map8[dat & 0xff];
- p[5] = svga->map8[(dat >> 8) & 0xff];
- p[6] = svga->map8[(dat >> 16) & 0xff];
- p[7] = svga->map8[(dat >> 24) & 0xff];
+ p[4] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[5] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[6] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
svga->ma += 8;
p += 8;
@@ -1120,16 +1120,16 @@ svga_render_8bpp_highres(svga_t *svga)
if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) {
dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]);
- p[0] = svga->map8[dat & 0xff];
- p[1] = svga->map8[(dat >> 8) & 0xff];
- p[2] = svga->map8[(dat >> 16) & 0xff];
- p[3] = svga->map8[(dat >> 24) & 0xff];
+ p[0] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
- p[4] = svga->map8[dat & 0xff];
- p[5] = svga->map8[(dat >> 8) & 0xff];
- p[6] = svga->map8[(dat >> 16) & 0xff];
- p[7] = svga->map8[(dat >> 24) & 0xff];
+ p[4] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[5] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[6] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
svga->ma += 8;
p += 8;
@@ -1138,10 +1138,10 @@ svga_render_8bpp_highres(svga_t *svga)
for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 4) {
addr = svga->remap_func(svga, svga->ma);
dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]);
- p[0] = svga->map8[dat & 0xff];
- p[1] = svga->map8[(dat >> 8) & 0xff];
- p[2] = svga->map8[(dat >> 16) & 0xff];
- p[3] = svga->map8[(dat >> 24) & 0xff];
+ p[0] = svga->map8[dat & svga->dac_mask & 0xff];
+ p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff];
+ p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff];
+ p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff];
svga->ma += 4;
p += 4;
@@ -1173,19 +1173,19 @@ svga_render_8bpp_tseng_lowres(svga_t *svga)
dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]);
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[0] = p[1] = svga->map8[dat & 0xff];
+ p[0] = p[1] = svga->map8[dat & svga->dac_mask & 0xff];
dat >>= 8;
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[2] = p[3] = svga->map8[dat & 0xff];
+ p[2] = p[3] = svga->map8[dat & svga->dac_mask & 0xff];
dat >>= 8;
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[4] = p[5] = svga->map8[dat & 0xff];
+ p[4] = p[5] = svga->map8[dat & svga->dac_mask & 0xff];
dat >>= 8;
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[6] = p[7] = svga->map8[dat & 0xff];
+ p[6] = p[7] = svga->map8[dat & svga->dac_mask & 0xff];
svga->ma += 4;
p += 8;
@@ -1214,36 +1214,36 @@ svga_render_8bpp_tseng_highres(svga_t *svga)
dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]);
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[0] = svga->map8[dat & 0xff];
+ p[0] = svga->map8[dat & svga->dac_mask & 0xff];
dat >>= 8;
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[1] = svga->map8[dat & 0xff];
+ p[1] = svga->map8[dat & svga->dac_mask & 0xff];
dat >>= 8;
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[2] = svga->map8[dat & 0xff];
+ p[2] = svga->map8[dat & svga->dac_mask & 0xff];
dat >>= 8;
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[3] = svga->map8[dat & 0xff];
+ p[3] = svga->map8[dat & svga->dac_mask & 0xff];
dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[4] = svga->map8[dat & 0xff];
+ p[4] = svga->map8[dat & svga->dac_mask & 0xff];
dat >>= 8;
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[5] = svga->map8[dat & 0xff];
+ p[5] = svga->map8[dat & svga->dac_mask & 0xff];
dat >>= 8;
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[6] = svga->map8[dat & 0xff];
+ p[6] = svga->map8[dat & svga->dac_mask & 0xff];
dat >>= 8;
if (svga->attrregs[0x10] & 0x80)
dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4);
- p[7] = svga->map8[dat & 0xff];
+ p[7] = svga->map8[dat & svga->dac_mask & 0xff];
svga->ma += 8;
p += 8;