Merge branch '86Box:master' into mirocrystal_3d

This commit is contained in:
MaxwellS04
2024-08-21 07:22:01 +07:00
committed by GitHub
10 changed files with 936 additions and 748 deletions

View File

@@ -53,10 +53,14 @@ We operate an IRC channel and a Discord server for discussing 86Box, its develop
[![Visit our Discord server](https://discordapp.com/api/guilds/262614059009048590/embed.png)](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
---------

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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);

View File

@@ -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)

179
src/qt/win_thread.c Normal file
View File

@@ -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, <http://pcem-emulator.co.uk/>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2017-2018 Fred N. van Kempen.
*/
#define UNICODE
#define BITMAP WINDOWS_BITMAP
#include <windows.h>
#include <windowsx.h>
#include <process.h>
#undef BITMAP
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#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);
}

View File

@@ -9930,8 +9930,14 @@ s3_init(const device_t *info)
s3->width = 1024;
svga->ramdac = device_add(&sc11483_ramdac_device);
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:

View File

@@ -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;
@@ -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,96 +1428,46 @@ 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) {
virge_t *virge = (virge_t *)param;
while (virge->fifo_thread_run) {
thread_set_event(virge->fifo_not_full_event);
thread_wait_event(virge->wake_fifo_thread, -1);
thread_reset_event(virge->wake_fifo_thread);
virge->virge_busy = 1;
while (!FIFO_EMPTY) {
uint64_t start_time = plat_timer_read();
uint64_t end_time;
fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK];
uint32_t val = fifo->val;
switch (fifo->addr_type & FIFO_TYPE) {
case FIFO_WRITE_BYTE:
if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 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 (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;
break;
case FIFO_WRITE_DWORD:
if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) {
if (virge->s3d.cmd_set & CMD_SET_MS)
s3_virge_bitblt(virge, 32,
((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) |
((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;
s3_virge_mmio_write_fifo_l(virge_t *virge, uint32_t addr, uint32_t val)
{
switch (addr) {
case 0xa000 ... 0xa1fc:
{
int x = (fifo->addr_type & FIFO_ADDR) & 4;
int y = ((fifo->addr_type & FIFO_ADDR) >> 3) & 7;
int x = addr & 4;
int y = (addr >> 3) & 7;
int color;
int byte;
uint32_t addr = (fifo->addr_type & FIFO_ADDR);
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 = ((fifo->addr_type & FIFO_ADDR) >> 1) & 6;
y = ((fifo->addr_type & FIFO_ADDR) >> 4) & 7;
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;
addr &= 0x00ff;
newaddr &= 0x00ff;
for (uint8_t xx = 0; xx < 4; xx++) {
x = ((addr + xx) / 3) % 8;
y = ((addr + xx) / 24) % 8;
color = ((addr + xx) % 3) << 3;
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 = ((fifo->addr_type & FIFO_ADDR) >> 2) & 7;
y = ((fifo->addr_type & FIFO_ADDR) >> 5) & 7;
x = (addr >> 2) & 7;
y = (addr >> 5) & 7;
virge->s3d.pattern_32[y * 8 + x] = val & 0xffffff;
} break;
@@ -1787,6 +1740,46 @@ fifo_thread(void *param) {
break;
}
}
static void
fifo_thread(void *param)
{
virge_t *virge = (virge_t *)param;
while (virge->fifo_thread_run) {
thread_set_event(virge->fifo_not_full_event);
thread_wait_event(virge->wake_fifo_thread, -1);
thread_reset_event(virge->wake_fifo_thread);
virge->virge_busy = 1;
while (!FIFO_EMPTY) {
uint64_t start_time = plat_timer_read();
uint64_t end_time;
fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK];
uint32_t val = fifo->val;
switch (fifo->addr_type & FIFO_TYPE) {
case FIFO_WRITE_BYTE:
if (((fifo->addr_type & FIFO_ADDR) & 0xffff) < 0x8000)
s3_virge_bitblt(virge, 8, val);
break;
case FIFO_WRITE_WORD:
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);
}
break;
case FIFO_WRITE_DWORD:
if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) {
if (virge->s3d.cmd_set & CMD_SET_MS)
s3_virge_bitblt(virge, 32,
((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) |
((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
else
s3_virge_bitblt(virge, 32, val);
} else
s3_virge_mmio_write_fifo_l(virge, (fifo->addr_type & FIFO_ADDR) & 0xfffc, val);
break;
}
@@ -1801,19 +1794,43 @@ 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 (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;
fifo->addr_type = (addr & FIFO_ADDR) | type;
@@ -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);
@@ -1871,7 +1889,8 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
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) {
else {
switch (addr & 0xfffc) {
case 0x8180:
virge->streams.pri_ctrl = val;
svga_recalctimings(svga);
@@ -1905,38 +1924,38 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
case 0x81c0:
virge->streams.pri_fb0 = val & ((virge->memory_size == 8) ?
(val & 0x7fffff) : (val & 0x3fffff));
svga_recalctimings(svga);
s3_virge_update_buffer(virge);
svga->fullchange = changeframecount;
break;
case 0x81c4:
virge->streams.pri_fb1 = ((virge->memory_size == 8) ?
(val & 0x7fffff) : (val & 0x3fffff));
svga_recalctimings(svga);
s3_virge_update_buffer(virge);
svga->fullchange = changeframecount;
break;
case 0x81c8:
virge->streams.pri_stride = val & 0xfff;
svga_recalctimings(svga);
s3_virge_update_buffer(virge);
svga->fullchange = changeframecount;
break;
case 0x81cc:
virge->streams.buffer_ctrl = val;
svga_recalctimings(svga);
s3_virge_update_buffer(virge);
svga->fullchange = changeframecount;
break;
case 0x81d0:
virge->streams.sec_fb0 = val;
svga_recalctimings(svga);
s3_virge_update_buffer(virge);
svga->fullchange = changeframecount;
break;
case 0x81d4:
virge->streams.sec_fb1 = val;
svga_recalctimings(svga);
s3_virge_update_buffer(virge);
svga->fullchange = changeframecount;
break;
case 0x81d8:
virge->streams.sec_stride = val;
svga_recalctimings(svga);
s3_virge_update_buffer(virge);
svga->fullchange = changeframecount;
break;
case 0x81dc:
@@ -2000,32 +2019,79 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
s3_virge_updatemapping(virge);
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;
}
}
}
#define READ(addr, val) \
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 { \
@@ -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);
@@ -3321,16 +3385,17 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int
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;
}
@@ -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;

View File

@@ -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;