2017-10-11 05:40:44 -04:00
|
|
|
/*
|
2023-01-06 15:36:05 -05:00
|
|
|
* 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.
|
2017-10-11 05:40:44 -04:00
|
|
|
*
|
2023-01-06 15:36:05 -05:00
|
|
|
* This file is part of the 86Box distribution.
|
2017-10-11 05:40:44 -04:00
|
|
|
*
|
2023-01-06 15:36:05 -05:00
|
|
|
* Voodoo Graphics, 2, Banshee, 3 emulation.
|
2017-10-11 05:40:44 -04:00
|
|
|
*
|
2020-03-25 00:46:02 +02:00
|
|
|
*
|
2017-10-11 05:40:44 -04:00
|
|
|
*
|
2023-01-06 15:36:29 -05:00
|
|
|
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
2023-01-06 15:36:05 -05:00
|
|
|
* leilei
|
2017-10-11 05:40:44 -04:00
|
|
|
*
|
2023-01-06 15:36:05 -05:00
|
|
|
* Copyright 2008-2020 Sarah Walker.
|
2017-10-11 05:40:44 -04:00
|
|
|
*/
|
2022-10-27 11:20:31 -04:00
|
|
|
#include <stdarg.h>
|
2017-09-25 04:31:20 -04:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <string.h>
|
2016-06-26 00:34:39 +02:00
|
|
|
#include <stdlib.h>
|
2017-10-12 14:25:17 -04:00
|
|
|
#include <stddef.h>
|
2017-09-25 04:31:20 -04:00
|
|
|
#include <wchar.h>
|
2017-05-17 23:14:07 -05:00
|
|
|
#include <math.h>
|
2022-10-27 11:20:31 -04:00
|
|
|
#define HAVE_STDARG_H
|
2020-03-29 14:24:42 +02:00
|
|
|
#include <86box/86box.h>
|
2020-02-29 19:12:23 +01:00
|
|
|
#include "cpu.h"
|
2020-03-29 14:24:42 +02:00
|
|
|
#include <86box/machine.h>
|
|
|
|
|
#include <86box/device.h>
|
|
|
|
|
#include <86box/mem.h>
|
|
|
|
|
#include <86box/pci.h>
|
|
|
|
|
#include <86box/rom.h>
|
|
|
|
|
#include <86box/timer.h>
|
|
|
|
|
#include <86box/device.h>
|
|
|
|
|
#include <86box/plat.h>
|
2022-04-19 23:06:39 +02:00
|
|
|
#include <86box/thread.h>
|
2020-03-29 14:24:42 +02:00
|
|
|
#include <86box/video.h>
|
|
|
|
|
#include <86box/vid_svga.h>
|
2020-11-18 00:21:07 +01:00
|
|
|
#include <86box/vid_voodoo_common.h>
|
|
|
|
|
#include <86box/vid_voodoo_blitter.h>
|
|
|
|
|
#include <86box/vid_voodoo_display.h>
|
2020-03-29 14:24:42 +02:00
|
|
|
#include <86box/vid_voodoo_dither.h>
|
2020-11-18 00:21:07 +01:00
|
|
|
#include <86box/vid_voodoo_fb.h>
|
|
|
|
|
#include <86box/vid_voodoo_fifo.h>
|
|
|
|
|
#include <86box/vid_voodoo_reg.h>
|
|
|
|
|
#include <86box/vid_voodoo_regs.h>
|
|
|
|
|
#include <86box/vid_voodoo_render.h>
|
|
|
|
|
#include <86box/vid_voodoo_texture.h>
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2023-06-01 18:32:25 -04:00
|
|
|
rgba8_t rgb332[0x100];
|
|
|
|
|
rgba8_t ai44[0x100];
|
|
|
|
|
rgba8_t rgb565[0x10000];
|
|
|
|
|
rgba8_t argb1555[0x10000];
|
|
|
|
|
rgba8_t argb4444[0x10000];
|
|
|
|
|
rgba8_t ai88[0x10000];
|
2017-08-20 23:15:07 +02:00
|
|
|
|
2020-11-18 00:21:07 +01:00
|
|
|
int tris = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2020-11-18 00:21:07 +01:00
|
|
|
#ifdef ENABLE_VOODOO_LOG
|
|
|
|
|
int voodoo_do_log = ENABLE_VOODOO_LOG;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2020-11-18 00:21:07 +01:00
|
|
|
static void
|
|
|
|
|
voodoo_log(const char *fmt, ...)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2020-11-18 00:21:07 +01:00
|
|
|
va_list ap;
|
2017-08-20 23:15:07 +02:00
|
|
|
|
2020-11-18 00:21:07 +01:00
|
|
|
if (voodoo_do_log) {
|
2022-08-31 19:19:29 -04:00
|
|
|
va_start(ap, fmt);
|
|
|
|
|
pclog_ex(fmt, ap);
|
|
|
|
|
va_end(ap);
|
2020-11-18 00:21:07 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
2022-08-31 19:19:29 -04:00
|
|
|
# define voodoo_log(fmt, ...)
|
2020-11-18 00:21:07 +01:00
|
|
|
#endif
|
2017-08-20 23:15:07 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
void
|
|
|
|
|
voodoo_recalc(voodoo_t *voodoo)
|
2020-11-18 00:21:07 +01:00
|
|
|
{
|
2022-08-31 19:19:29 -04:00
|
|
|
uint32_t buffer_offset = ((voodoo->fbiInit2 >> 11) & 511) * 4096;
|
|
|
|
|
|
|
|
|
|
if (voodoo->type >= VOODOO_BANSHEE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
voodoo->params.front_offset = voodoo->disp_buffer * buffer_offset;
|
|
|
|
|
voodoo->back_offset = voodoo->draw_buffer * buffer_offset;
|
|
|
|
|
|
|
|
|
|
voodoo->buffer_cutoff = TRIPLE_BUFFER ? (buffer_offset * 4) : (buffer_offset * 3);
|
|
|
|
|
if (TRIPLE_BUFFER)
|
|
|
|
|
voodoo->params.aux_offset = buffer_offset * 3;
|
|
|
|
|
else
|
|
|
|
|
voodoo->params.aux_offset = buffer_offset * 2;
|
|
|
|
|
|
|
|
|
|
switch (voodoo->lfbMode & LFB_WRITE_MASK) {
|
|
|
|
|
case LFB_WRITE_FRONT:
|
|
|
|
|
voodoo->fb_write_offset = voodoo->params.front_offset;
|
|
|
|
|
voodoo->fb_write_buffer = voodoo->disp_buffer;
|
|
|
|
|
break;
|
|
|
|
|
case LFB_WRITE_BACK:
|
|
|
|
|
voodoo->fb_write_offset = voodoo->back_offset;
|
|
|
|
|
voodoo->fb_write_buffer = voodoo->draw_buffer;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
/*BreakNeck sets invalid LFB write buffer select*/
|
|
|
|
|
voodoo->fb_write_offset = voodoo->params.front_offset;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
switch (voodoo->lfbMode & LFB_READ_MASK) {
|
|
|
|
|
case LFB_READ_FRONT:
|
|
|
|
|
voodoo->fb_read_offset = voodoo->params.front_offset;
|
|
|
|
|
break;
|
|
|
|
|
case LFB_READ_BACK:
|
|
|
|
|
voodoo->fb_read_offset = voodoo->back_offset;
|
|
|
|
|
break;
|
|
|
|
|
case LFB_READ_AUX:
|
|
|
|
|
voodoo->fb_read_offset = voodoo->params.aux_offset;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
fatal("voodoo_recalc : unknown lfb source\n");
|
|
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
switch (voodoo->params.fbzMode & FBZ_DRAW_MASK) {
|
|
|
|
|
case FBZ_DRAW_FRONT:
|
|
|
|
|
voodoo->params.draw_offset = voodoo->params.front_offset;
|
|
|
|
|
voodoo->fb_draw_buffer = voodoo->disp_buffer;
|
|
|
|
|
break;
|
|
|
|
|
case FBZ_DRAW_BACK:
|
|
|
|
|
voodoo->params.draw_offset = voodoo->back_offset;
|
|
|
|
|
voodoo->fb_draw_buffer = voodoo->draw_buffer;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
fatal("voodoo_recalc : unknown draw buffer\n");
|
|
|
|
|
}
|
2016-12-23 03:16:24 +01:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->block_width = ((voodoo->fbiInit1 >> 4) & 15) * 2;
|
|
|
|
|
if (voodoo->fbiInit6 & (1 << 30))
|
|
|
|
|
voodoo->block_width += 1;
|
|
|
|
|
if (voodoo->fbiInit1 & (1 << 24))
|
|
|
|
|
voodoo->block_width += 32;
|
|
|
|
|
voodoo->row_width = voodoo->block_width * 32 * 2;
|
|
|
|
|
voodoo->params.row_width = voodoo->row_width;
|
|
|
|
|
voodoo->aux_row_width = voodoo->row_width;
|
|
|
|
|
voodoo->params.aux_row_width = voodoo->aux_row_width;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
static uint16_t
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_readw(uint32_t addr, void *priv)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_t *voodoo = (voodoo_t *) priv;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
addr &= 0xffffff;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
cycles -= voodoo->read_time;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/
|
|
|
|
|
{
|
|
|
|
|
if (SLI_ENABLED) {
|
2023-07-31 18:57:52 -04:00
|
|
|
const voodoo_set_t *set = voodoo->set;
|
|
|
|
|
int y = (addr >> 11) & 0x3ff;
|
2022-08-31 19:19:29 -04:00
|
|
|
|
|
|
|
|
if (y & 1)
|
|
|
|
|
voodoo = set->voodoos[1];
|
|
|
|
|
else
|
|
|
|
|
voodoo = set->voodoos[0];
|
|
|
|
|
}
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->flush = 1;
|
|
|
|
|
while (!FIFO_EMPTY) {
|
|
|
|
|
voodoo_wake_fifo_thread_now(voodoo);
|
|
|
|
|
thread_wait_event(voodoo->fifo_not_full_event, 1);
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_wait_for_render_thread_idle(voodoo);
|
|
|
|
|
voodoo->flush = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
return voodoo_fb_readw(addr, voodoo);
|
|
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
return 0xffff;
|
|
|
|
|
}
|
2017-08-20 23:15:07 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
static uint32_t
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_readl(uint32_t addr, void *priv)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_t *voodoo = (voodoo_t *) priv;
|
2022-08-31 19:19:29 -04:00
|
|
|
uint32_t temp = 0xffffffff;
|
|
|
|
|
int fifo_size;
|
|
|
|
|
voodoo->rd_count++;
|
|
|
|
|
addr &= 0xffffff;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
cycles -= voodoo->read_time;
|
2016-10-04 17:25:16 +02:00
|
|
|
|
2023-07-31 18:57:52 -04:00
|
|
|
if (addr & 0x800000) { /*Texture*/
|
2022-08-31 19:19:29 -04:00
|
|
|
} else if (addr & 0x400000) /*Framebuffer*/
|
|
|
|
|
{
|
|
|
|
|
if (SLI_ENABLED) {
|
2023-07-31 18:57:52 -04:00
|
|
|
const voodoo_set_t *set = voodoo->set;
|
|
|
|
|
int y = (addr >> 11) & 0x3ff;
|
2022-08-31 19:19:29 -04:00
|
|
|
|
|
|
|
|
if (y & 1)
|
|
|
|
|
voodoo = set->voodoos[1];
|
|
|
|
|
else
|
|
|
|
|
voodoo = set->voodoos[0];
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->flush = 1;
|
|
|
|
|
while (!FIFO_EMPTY) {
|
|
|
|
|
voodoo_wake_fifo_thread_now(voodoo);
|
|
|
|
|
thread_wait_event(voodoo->fifo_not_full_event, 1);
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_wait_for_render_thread_idle(voodoo);
|
|
|
|
|
voodoo->flush = 0;
|
2017-08-20 23:15:07 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
temp = voodoo_fb_readl(addr, voodoo);
|
|
|
|
|
} else
|
|
|
|
|
switch (addr & 0x3fc) {
|
|
|
|
|
case SST_status:
|
|
|
|
|
{
|
|
|
|
|
int fifo_entries = FIFO_ENTRIES;
|
|
|
|
|
int swap_count = voodoo->swap_count;
|
2024-09-04 15:22:24 +02:00
|
|
|
int written = voodoo->cmd_written + voodoo->cmd_written_fifo + voodoo->cmd_written_fifo_2;
|
2022-08-31 19:19:29 -04:00
|
|
|
int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr);
|
|
|
|
|
|
|
|
|
|
if (SLI_ENABLED && voodoo->type != VOODOO_2) {
|
|
|
|
|
voodoo_t *voodoo_other = (voodoo == voodoo->set->voodoos[0]) ? voodoo->set->voodoos[1] : voodoo->set->voodoos[0];
|
2024-09-04 15:22:24 +02:00
|
|
|
int other_written = voodoo_other->cmd_written + voodoo_other->cmd_written_fifo + voodoo->cmd_written_fifo_2;
|
2022-08-31 19:19:29 -04:00
|
|
|
|
|
|
|
|
if (voodoo_other->swap_count > swap_count)
|
|
|
|
|
swap_count = voodoo_other->swap_count;
|
|
|
|
|
if ((voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx) > fifo_entries)
|
|
|
|
|
fifo_entries = voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx;
|
|
|
|
|
if ((other_written - voodoo_other->cmd_read) || (voodoo_other->cmdfifo_depth_rd != voodoo_other->cmdfifo_depth_wr))
|
|
|
|
|
busy = 1;
|
|
|
|
|
if (!voodoo_other->voodoo_busy)
|
|
|
|
|
voodoo_wake_fifo_thread(voodoo_other);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fifo_size = 0xffff - fifo_entries;
|
|
|
|
|
temp = fifo_size << 12;
|
|
|
|
|
if (fifo_size < 0x40)
|
|
|
|
|
temp |= fifo_size;
|
|
|
|
|
else
|
|
|
|
|
temp |= 0x3f;
|
|
|
|
|
if (swap_count < 7)
|
|
|
|
|
temp |= (swap_count << 28);
|
|
|
|
|
else
|
|
|
|
|
temp |= (7 << 28);
|
|
|
|
|
if (!voodoo->v_retrace)
|
|
|
|
|
temp |= 0x40;
|
|
|
|
|
|
|
|
|
|
if (busy)
|
|
|
|
|
temp |= 0x380; /*Busy*/
|
|
|
|
|
|
|
|
|
|
if (!voodoo->voodoo_busy)
|
|
|
|
|
voodoo_wake_fifo_thread(voodoo);
|
2017-08-20 23:15:07 +02:00
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbzColorPath:
|
2017-02-23 19:52:14 +01:00
|
|
|
voodoo_flush(voodoo);
|
|
|
|
|
temp = voodoo->params.fbzColorPath;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fogMode:
|
2017-02-23 19:52:14 +01:00
|
|
|
voodoo_flush(voodoo);
|
|
|
|
|
temp = voodoo->params.fogMode;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_alphaMode:
|
2017-02-23 19:52:14 +01:00
|
|
|
voodoo_flush(voodoo);
|
|
|
|
|
temp = voodoo->params.alphaMode;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbzMode:
|
2017-02-23 19:52:14 +01:00
|
|
|
voodoo_flush(voodoo);
|
|
|
|
|
temp = voodoo->params.fbzMode;
|
2022-02-20 02:26:27 -05:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_lfbMode:
|
2017-02-23 19:52:14 +01:00
|
|
|
voodoo_flush(voodoo);
|
2016-06-26 00:34:39 +02:00
|
|
|
temp = voodoo->lfbMode;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_clipLeftRight:
|
2017-02-23 19:52:14 +01:00
|
|
|
voodoo_flush(voodoo);
|
|
|
|
|
temp = voodoo->params.clipRight | (voodoo->params.clipLeft << 16);
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_clipLowYHighY:
|
2017-02-23 19:52:14 +01:00
|
|
|
voodoo_flush(voodoo);
|
|
|
|
|
temp = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16);
|
|
|
|
|
break;
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_stipple:
|
2017-02-23 19:52:14 +01:00
|
|
|
voodoo_flush(voodoo);
|
|
|
|
|
temp = voodoo->params.stipple;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_color0:
|
2017-02-23 19:52:14 +01:00
|
|
|
voodoo_flush(voodoo);
|
|
|
|
|
temp = voodoo->params.color0;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_color1:
|
2017-02-23 19:52:14 +01:00
|
|
|
voodoo_flush(voodoo);
|
|
|
|
|
temp = voodoo->params.color1;
|
|
|
|
|
break;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiPixelsIn:
|
2016-06-26 00:34:39 +02:00
|
|
|
temp = voodoo->fbiPixelsIn & 0xffffff;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiChromaFail:
|
2016-06-26 00:34:39 +02:00
|
|
|
temp = voodoo->fbiChromaFail & 0xffffff;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiZFuncFail:
|
2016-06-26 00:34:39 +02:00
|
|
|
temp = voodoo->fbiZFuncFail & 0xffffff;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiAFuncFail:
|
2016-06-26 00:34:39 +02:00
|
|
|
temp = voodoo->fbiAFuncFail & 0xffffff;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiPixelsOut:
|
2016-06-26 00:34:39 +02:00
|
|
|
temp = voodoo->fbiPixelsOut & 0xffffff;
|
|
|
|
|
break;
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit4:
|
2016-06-26 00:34:39 +02:00
|
|
|
temp = voodoo->fbiInit4;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit0:
|
2016-06-26 00:34:39 +02:00
|
|
|
temp = voodoo->fbiInit0;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit1:
|
2017-08-20 23:15:07 +02:00
|
|
|
temp = voodoo->fbiInit1;
|
2022-02-20 02:26:27 -05:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit2:
|
2016-06-26 00:34:39 +02:00
|
|
|
if (voodoo->initEnable & 0x04)
|
2022-08-31 19:19:29 -04:00
|
|
|
temp = voodoo->dac_readdata;
|
2016-06-26 00:34:39 +02:00
|
|
|
else
|
2022-08-31 19:19:29 -04:00
|
|
|
temp = voodoo->fbiInit2;
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit3:
|
2017-08-20 23:15:07 +02:00
|
|
|
temp = voodoo->fbiInit3 | (1 << 10) | (2 << 8);
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
2016-11-02 22:39:07 +01:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_vRetrace:
|
2017-05-05 01:49:42 +02:00
|
|
|
temp = voodoo->line & 0x1fff;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_hvRetrace:
|
2020-11-18 00:21:07 +01:00
|
|
|
{
|
2022-08-31 19:19:29 -04:00
|
|
|
uint32_t line_time = (uint32_t) (voodoo->line_time >> 32);
|
|
|
|
|
uint32_t diff = (timer_get_ts_int(&voodoo->timer) > (tsc & 0xffffffff)) ? (timer_get_ts_int(&voodoo->timer) - (tsc & 0xffffffff)) : 0;
|
|
|
|
|
uint32_t pre_div = diff * voodoo->h_total;
|
|
|
|
|
uint32_t post_div = pre_div / line_time;
|
|
|
|
|
uint32_t h_pos = (voodoo->h_total - 1) - post_div;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
if (h_pos >= voodoo->h_total)
|
|
|
|
|
h_pos = 0;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
temp = voodoo->line & 0x1fff;
|
|
|
|
|
temp |= (h_pos << 16);
|
Added the IBM 5161 ISA expansion for PC and XT;
Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port;
Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX);
Finished the 586MC1;
Added 8087 emulation;
Moved Cyrix 6x86'es to the Dev branch;
Sanitized/cleaned up memregs.c/h and intel.c/h;
Split the chipsets from machines and sanitized Port 92 emulation;
Added support for the 15bpp mode to the Compaq ATI 28800;
Moved the MR 386DX and 486 machines to the Dev branch;
Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00;
Ported the new timer code from PCem;
Cleaned up the CPU table of unused stuff and better optimized its structure;
Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch;
Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem;
Added the AHA-1540A and the BusTek BT-542B;
Moved the Sumo SCSI-AT to the Dev branch;
Minor IDE, FDC, and floppy drive code clean-ups;
Made NCR 5380/53C400-based cards' BIOS address configurable;
Got rid of the legacy romset variable;
Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit;
Added the Amstead PPC512 per PCem patch by John Elliott;
Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages);
Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing;
Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem;
Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit;
Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement;
Amstrad MegaPC does now works correctly with non-internal graphics card;
The SLiRP code no longer casts a packed struct type to a non-packed struct type;
The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present;
The S3 Virge on BeOS is no longer broken (was broken by build #1591);
OS/2 2.0 build 6.167 now sees key presses again;
Xi8088 now work on CGA again;
86F images converted from either the old or new variants of the HxC MFM format now work correctly;
Hardware interrupts with a vector of 0xFF are now handled correctly;
OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct;
Fixed VNC keyboard input bugs;
Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver;
Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly;
Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4;
Compaq Portable now works with all graphics cards;
Fixed various MDSI Genius bugs;
Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly;
Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355;
OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400.
Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391.
Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389.
Fixed a minor IDE timing bug, fixes #388.
Fixed Toshiba T1000 RAM issues, fixes #379.
Fixed EGA/(S)VGA overscan border handling, fixes #378;
Got rid of the now long useless IDE channel 2 auto-removal, fixes #370;
Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366;
Ported the Unicode CD image file name fix from VARCem, fixes #365;
Fixed high density floppy disks on the Xi8088, fixes #359;
Fixed some bugs in the Hercules emulation, fixes #346, fixes #358;
Fixed the SCSI hard disk mode sense pages, fixes #356;
Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349;
Fixed bugs in the serial mouse emulation, fixes #344;
Compiled 86Box binaries now include all the required .DLL's, fixes #341;
Made some combo boxes in the Settings dialog slightly wider, fixes #276.
2019-09-20 14:02:30 +02:00
|
|
|
}
|
2020-11-18 00:21:07 +01:00
|
|
|
break;
|
2016-11-02 22:39:07 +01:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit5:
|
2017-08-20 23:15:07 +02:00
|
|
|
temp = voodoo->fbiInit5 & ~0x1ff;
|
2016-11-02 22:39:07 +01:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit6:
|
2016-11-02 22:39:07 +01:00
|
|
|
temp = voodoo->fbiInit6;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit7:
|
2016-11-02 22:39:07 +01:00
|
|
|
temp = voodoo->fbiInit7 & ~0xff;
|
|
|
|
|
break;
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_cmdFifoBaseAddr:
|
2016-11-02 22:39:07 +01:00
|
|
|
temp = voodoo->cmdfifo_base >> 12;
|
|
|
|
|
temp |= (voodoo->cmdfifo_end >> 12) << 16;
|
|
|
|
|
break;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_cmdFifoRdPtr:
|
2016-11-02 22:39:07 +01:00
|
|
|
temp = voodoo->cmdfifo_rp;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_cmdFifoAMin:
|
2016-11-02 22:39:07 +01:00
|
|
|
temp = voodoo->cmdfifo_amin;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_cmdFifoAMax:
|
2016-11-02 22:39:07 +01:00
|
|
|
temp = voodoo->cmdfifo_amax;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_cmdFifoDepth:
|
2016-11-02 22:39:07 +01:00
|
|
|
temp = voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd;
|
|
|
|
|
break;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
default:
|
2020-11-20 22:24:46 +01:00
|
|
|
voodoo_log("voodoo_readl : bad addr %08X\n", addr);
|
2016-06-26 00:34:39 +02:00
|
|
|
temp = 0xffffffff;
|
|
|
|
|
}
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
return temp;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
static void
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_writew(uint32_t addr, uint16_t val, void *priv)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_t *voodoo = (voodoo_t *) priv;
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->wr_count++;
|
|
|
|
|
addr &= 0xffffff;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
cycles -= voodoo->write_time;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/
|
|
|
|
|
voodoo_queue_command(voodoo, addr | FIFO_WRITEW_FB, val);
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
static void
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_writel(uint32_t addr, uint32_t val, void *priv)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_t *voodoo = (voodoo_t *) priv;
|
2016-11-02 22:39:07 +01:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->wr_count++;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
addr &= 0xffffff;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
if (addr == voodoo->last_write_addr + 4)
|
|
|
|
|
cycles -= voodoo->burst_time;
|
|
|
|
|
else
|
|
|
|
|
cycles -= voodoo->write_time;
|
|
|
|
|
voodoo->last_write_addr = addr;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
if (addr & 0x800000) /*Texture*/
|
|
|
|
|
{
|
|
|
|
|
voodoo->tex_count++;
|
|
|
|
|
voodoo_queue_command(voodoo, addr | FIFO_WRITEL_TEX, val);
|
|
|
|
|
} else if (addr & 0x400000) /*Framebuffer*/
|
|
|
|
|
{
|
|
|
|
|
voodoo_queue_command(voodoo, addr | FIFO_WRITEL_FB, val);
|
|
|
|
|
} else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) {
|
2023-07-31 18:57:52 -04:00
|
|
|
#if 0
|
|
|
|
|
voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask);
|
|
|
|
|
#endif
|
2022-08-31 19:19:29 -04:00
|
|
|
*(uint32_t *) &voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val;
|
|
|
|
|
voodoo->cmdfifo_depth_wr++;
|
|
|
|
|
if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20)
|
|
|
|
|
voodoo_wake_fifo_thread(voodoo);
|
|
|
|
|
} else
|
|
|
|
|
switch (addr & 0x3fc) {
|
|
|
|
|
case SST_intrCtrl:
|
2016-11-02 22:39:07 +01:00
|
|
|
fatal("intrCtrl write %08x\n", val);
|
|
|
|
|
break;
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_userIntrCMD:
|
2016-11-02 22:39:07 +01:00
|
|
|
fatal("userIntrCMD write %08x\n", val);
|
|
|
|
|
break;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_swapbufferCMD:
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->cmd_written++;
|
2020-11-18 16:15:01 +01:00
|
|
|
thread_wait_mutex(voodoo->swap_mutex);
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->swap_count++;
|
2020-11-18 16:15:01 +01:00
|
|
|
thread_release_mutex(voodoo->swap_mutex);
|
2016-11-02 22:39:07 +01:00
|
|
|
if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)
|
2022-08-31 19:19:29 -04:00
|
|
|
return;
|
2020-11-18 00:21:07 +01:00
|
|
|
voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val);
|
2016-06-26 00:34:39 +02:00
|
|
|
if (!voodoo->voodoo_busy)
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_wake_fifo_threads(voodoo->set, voodoo);
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_triangleCMD:
|
2016-11-02 22:39:07 +01:00
|
|
|
if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)
|
2022-08-31 19:19:29 -04:00
|
|
|
return;
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->cmd_written++;
|
2020-11-18 00:21:07 +01:00
|
|
|
voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val);
|
2016-06-26 00:34:39 +02:00
|
|
|
if (!voodoo->voodoo_busy)
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_wake_fifo_threads(voodoo->set, voodoo);
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_ftriangleCMD:
|
2016-11-02 22:39:07 +01:00
|
|
|
if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)
|
2022-08-31 19:19:29 -04:00
|
|
|
return;
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->cmd_written++;
|
2020-11-18 00:21:07 +01:00
|
|
|
voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val);
|
2016-06-26 00:34:39 +02:00
|
|
|
if (!voodoo->voodoo_busy)
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_wake_fifo_threads(voodoo->set, voodoo);
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fastfillCMD:
|
2016-11-02 22:39:07 +01:00
|
|
|
if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)
|
2022-08-31 19:19:29 -04:00
|
|
|
return;
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->cmd_written++;
|
2020-11-18 00:21:07 +01:00
|
|
|
voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val);
|
2016-06-26 00:34:39 +02:00
|
|
|
if (!voodoo->voodoo_busy)
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_wake_fifo_threads(voodoo->set, voodoo);
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_nopCMD:
|
2016-11-02 22:39:07 +01:00
|
|
|
if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)
|
2022-08-31 19:19:29 -04:00
|
|
|
return;
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->cmd_written++;
|
2020-11-18 00:21:07 +01:00
|
|
|
voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val);
|
2016-06-26 00:34:39 +02:00
|
|
|
if (!voodoo->voodoo_busy)
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_wake_fifo_threads(voodoo->set, voodoo);
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit4:
|
|
|
|
|
if (voodoo->initEnable & 0x01) {
|
|
|
|
|
voodoo->fbiInit4 = val;
|
|
|
|
|
voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1);
|
2023-07-31 18:57:52 -04:00
|
|
|
#if 0
|
|
|
|
|
voodoo_log("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time);
|
|
|
|
|
#endif
|
2016-11-02 22:39:07 +01:00
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_backPorch:
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->backPorch = val;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_videoDimensions:
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->videoDimensions = val;
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->h_disp = (val & 0xfff) + 1;
|
|
|
|
|
voodoo->v_disp = (val >> 16) & 0xfff;
|
2024-04-02 00:20:27 +02:00
|
|
|
if ((voodoo->v_disp == 386) || (voodoo->v_disp == 402) ||
|
|
|
|
|
(voodoo->v_disp == 482) || (voodoo->v_disp == 602))
|
|
|
|
|
voodoo->v_disp -= 2;
|
2022-08-31 19:19:29 -04:00
|
|
|
break;
|
|
|
|
|
case SST_fbiInit0:
|
|
|
|
|
if (voodoo->initEnable & 0x01) {
|
|
|
|
|
voodoo->fbiInit0 = val;
|
|
|
|
|
thread_wait_mutex(voodoo->force_blit_mutex);
|
|
|
|
|
voodoo->can_blit = (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) ? 1 : 0;
|
|
|
|
|
if (!voodoo->can_blit)
|
|
|
|
|
voodoo->force_blit_count = 0;
|
|
|
|
|
thread_release_mutex(voodoo->force_blit_mutex);
|
|
|
|
|
|
|
|
|
|
if (voodoo->set->nr_cards == 2)
|
|
|
|
|
svga_set_override(voodoo->svga, (voodoo->set->voodoos[0]->fbiInit0 | voodoo->set->voodoos[1]->fbiInit0) & 1);
|
|
|
|
|
else
|
|
|
|
|
svga_set_override(voodoo->svga, val & 1);
|
|
|
|
|
if (val & FBIINIT0_GRAPHICS_RESET) {
|
|
|
|
|
/*Reset display/draw buffer selection. This may not actually
|
|
|
|
|
happen here on a real Voodoo*/
|
|
|
|
|
voodoo->disp_buffer = 0;
|
|
|
|
|
voodoo->draw_buffer = 1;
|
|
|
|
|
voodoo_recalc(voodoo);
|
|
|
|
|
voodoo->front_offset = voodoo->params.front_offset;
|
|
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit1:
|
|
|
|
|
if (voodoo->initEnable & 0x01) {
|
|
|
|
|
if ((voodoo->fbiInit1 & FBIINIT1_VIDEO_RESET) && !(val & FBIINIT1_VIDEO_RESET)) {
|
|
|
|
|
voodoo->line = 0;
|
|
|
|
|
thread_wait_mutex(voodoo->swap_mutex);
|
|
|
|
|
voodoo->swap_count = 0;
|
|
|
|
|
thread_release_mutex(voodoo->swap_mutex);
|
|
|
|
|
voodoo->retrace_count = 0;
|
|
|
|
|
}
|
|
|
|
|
voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5);
|
|
|
|
|
voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0);
|
|
|
|
|
voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1);
|
2023-07-31 18:57:52 -04:00
|
|
|
#if 0
|
|
|
|
|
voodoo_log("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time);
|
|
|
|
|
#endif
|
2016-11-02 22:39:07 +01:00
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit2:
|
|
|
|
|
if (voodoo->initEnable & 0x01) {
|
|
|
|
|
voodoo->fbiInit2 = val;
|
|
|
|
|
voodoo_recalc(voodoo);
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit3:
|
2016-06-26 00:34:39 +02:00
|
|
|
if (voodoo->initEnable & 0x01)
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->fbiInit3 = val;
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_hSync:
|
|
|
|
|
voodoo->hSync = val;
|
2016-11-02 22:39:07 +01:00
|
|
|
voodoo->h_total = (val & 0xffff) + (val >> 16);
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo_pixelclock_update(voodoo);
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_vSync:
|
|
|
|
|
voodoo->vSync = val;
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->v_total = (val & 0xffff) + (val >> 16);
|
|
|
|
|
break;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_clutData:
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff;
|
|
|
|
|
voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff;
|
|
|
|
|
voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff;
|
2022-08-31 19:19:29 -04:00
|
|
|
if (val & 0x20000000) {
|
|
|
|
|
voodoo->clutData[(val >> 24) & 0x3f].b = 255;
|
|
|
|
|
voodoo->clutData[(val >> 24) & 0x3f].g = 255;
|
|
|
|
|
voodoo->clutData[(val >> 24) & 0x3f].r = 255;
|
2016-11-02 22:39:07 +01:00
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->clutData_dirty = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_dacData:
|
|
|
|
|
voodoo->dac_reg = (val >> 8) & 7;
|
2016-06-26 00:34:39 +02:00
|
|
|
voodoo->dac_readdata = 0xff;
|
2022-08-31 19:19:29 -04:00
|
|
|
if (val & 0x800) {
|
|
|
|
|
// voodoo_log(" dacData read %i %02X\n", voodoo->dac_reg, voodoo->dac_data[7]);
|
|
|
|
|
if (voodoo->dac_reg == 5) {
|
|
|
|
|
switch (voodoo->dac_data[7]) {
|
|
|
|
|
case 0x01:
|
|
|
|
|
voodoo->dac_readdata = 0x55;
|
|
|
|
|
break;
|
|
|
|
|
case 0x07:
|
|
|
|
|
voodoo->dac_readdata = 0x71;
|
|
|
|
|
break;
|
|
|
|
|
case 0x0b:
|
|
|
|
|
voodoo->dac_readdata = 0x79;
|
|
|
|
|
break;
|
2023-07-31 18:57:52 -04:00
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2022-08-31 19:19:29 -04:00
|
|
|
} else
|
|
|
|
|
voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata & 7];
|
|
|
|
|
} else {
|
|
|
|
|
if (voodoo->dac_reg == 5) {
|
|
|
|
|
if (!voodoo->dac_reg_ff)
|
|
|
|
|
voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val;
|
2016-06-26 00:34:39 +02:00
|
|
|
else
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8);
|
2023-07-31 18:57:52 -04:00
|
|
|
#if 0
|
|
|
|
|
voodoo_log("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]);
|
|
|
|
|
#endif
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->dac_reg_ff = !voodoo->dac_reg_ff;
|
|
|
|
|
if (!voodoo->dac_reg_ff)
|
|
|
|
|
voodoo->dac_data[4]++;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
voodoo->dac_data[voodoo->dac_reg] = val & 0xff;
|
|
|
|
|
voodoo->dac_reg_ff = 0;
|
|
|
|
|
}
|
|
|
|
|
voodoo_pixelclock_update(voodoo);
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_scrFilter:
|
|
|
|
|
if (voodoo->initEnable & 0x01) {
|
|
|
|
|
voodoo->scrfilterEnabled = 1;
|
|
|
|
|
voodoo->scrfilterThreshold = val; /* update the threshold values and generate a new lookup table if necessary */
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
if (val < 1)
|
|
|
|
|
voodoo->scrfilterEnabled = 0;
|
|
|
|
|
voodoo_threshold_check(voodoo);
|
|
|
|
|
voodoo_log("Voodoo Filter: %06x\n", val);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2016-12-23 03:16:24 +01:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit5:
|
2016-11-02 22:39:07 +01:00
|
|
|
if (voodoo->initEnable & 0x01)
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->fbiInit5 = (val & ~0x41e6) | (voodoo->fbiInit5 & 0x41e6);
|
2016-11-02 22:39:07 +01:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit6:
|
2016-11-02 22:39:07 +01:00
|
|
|
if (voodoo->initEnable & 0x01)
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->fbiInit6 = val;
|
2016-11-02 22:39:07 +01:00
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_fbiInit7:
|
|
|
|
|
if (voodoo->initEnable & 0x01) {
|
|
|
|
|
voodoo->fbiInit7 = val;
|
|
|
|
|
voodoo->cmdfifo_enabled = val & 0x100;
|
2020-11-18 00:21:07 +01:00
|
|
|
}
|
2016-11-02 22:39:07 +01:00
|
|
|
break;
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_cmdFifoBaseAddr:
|
2016-11-02 22:39:07 +01:00
|
|
|
voodoo->cmdfifo_base = (val & 0x3ff) << 12;
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12;
|
2023-07-31 18:57:52 -04:00
|
|
|
#if 0
|
|
|
|
|
voodoo_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end);
|
|
|
|
|
#endif
|
2016-11-02 22:39:07 +01:00
|
|
|
break;
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_cmdFifoRdPtr:
|
2016-11-02 22:39:07 +01:00
|
|
|
voodoo->cmdfifo_rp = val;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_cmdFifoAMin:
|
2016-11-02 22:39:07 +01:00
|
|
|
voodoo->cmdfifo_amin = val;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_cmdFifoAMax:
|
2016-11-02 22:39:07 +01:00
|
|
|
voodoo->cmdfifo_amax = val;
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
case SST_cmdFifoDepth:
|
2016-11-02 22:39:07 +01:00
|
|
|
voodoo->cmdfifo_depth_rd = 0;
|
|
|
|
|
voodoo->cmdfifo_depth_wr = val & 0xffff;
|
|
|
|
|
break;
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
default:
|
|
|
|
|
if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) {
|
|
|
|
|
voodoo_log("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val);
|
|
|
|
|
} else {
|
|
|
|
|
voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val);
|
2016-11-02 22:39:07 +01:00
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
static uint16_t
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_snoop_readw(uint32_t addr, void *priv)
|
2017-08-20 23:15:07 +02:00
|
|
|
{
|
2023-07-31 18:57:52 -04:00
|
|
|
const voodoo_set_t *set = (voodoo_set_t *) priv;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
return voodoo_readw(addr, set->voodoos[0]);
|
2017-08-20 23:15:07 +02:00
|
|
|
}
|
2022-08-31 19:19:29 -04:00
|
|
|
static uint32_t
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_snoop_readl(uint32_t addr, void *priv)
|
2017-08-20 23:15:07 +02:00
|
|
|
{
|
2023-07-31 18:57:52 -04:00
|
|
|
const voodoo_set_t *set = (voodoo_set_t *) priv;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
return voodoo_readl(addr, set->voodoos[0]);
|
2017-08-20 23:15:07 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
static void
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_snoop_writew(uint32_t addr, uint16_t val, void *priv)
|
2017-08-20 23:15:07 +02:00
|
|
|
{
|
2023-07-31 18:57:52 -04:00
|
|
|
const voodoo_set_t *set = (voodoo_set_t *) priv;
|
2017-08-20 23:15:07 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_writew(addr, val, set->voodoos[0]);
|
|
|
|
|
voodoo_writew(addr, val, set->voodoos[1]);
|
2017-08-20 23:15:07 +02:00
|
|
|
}
|
2022-08-31 19:19:29 -04:00
|
|
|
static void
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_snoop_writel(uint32_t addr, uint32_t val, void *priv)
|
2017-08-20 23:15:07 +02:00
|
|
|
{
|
2023-07-31 18:57:52 -04:00
|
|
|
const voodoo_set_t *set = (voodoo_set_t *) priv;
|
2017-08-20 23:15:07 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_writel(addr, val, set->voodoos[0]);
|
|
|
|
|
voodoo_writel(addr, val, set->voodoos[1]);
|
2017-08-20 23:15:07 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
static void
|
|
|
|
|
voodoo_recalcmapping(voodoo_set_t *set)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2022-08-31 19:19:29 -04:00
|
|
|
if (set->nr_cards == 2) {
|
|
|
|
|
if (set->voodoos[0]->pci_enable && set->voodoos[0]->memBaseAddr) {
|
|
|
|
|
if (set->voodoos[0]->type == VOODOO_2 && set->voodoos[1]->initEnable & (1 << 23)) {
|
|
|
|
|
voodoo_log("voodoo_recalcmapping (pri) with snoop : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr);
|
|
|
|
|
mem_mapping_disable(&set->voodoos[0]->mapping);
|
|
|
|
|
mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
|
|
|
|
|
} else if (set->voodoos[1]->pci_enable && (set->voodoos[0]->memBaseAddr == set->voodoos[1]->memBaseAddr)) {
|
|
|
|
|
voodoo_log("voodoo_recalcmapping (pri) (sec) same addr : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr);
|
|
|
|
|
mem_mapping_disable(&set->voodoos[0]->mapping);
|
|
|
|
|
mem_mapping_disable(&set->voodoos[1]->mapping);
|
|
|
|
|
mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
voodoo_log("voodoo_recalcmapping (pri) : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr);
|
|
|
|
|
mem_mapping_disable(&set->snoop_mapping);
|
|
|
|
|
mem_mapping_set_addr(&set->voodoos[0]->mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
voodoo_log("voodoo_recalcmapping (pri) : disabled\n");
|
|
|
|
|
mem_mapping_disable(&set->voodoos[0]->mapping);
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
if (set->voodoos[1]->pci_enable && set->voodoos[1]->memBaseAddr) {
|
|
|
|
|
voodoo_log("voodoo_recalcmapping (sec) : memBaseAddr %08X\n", set->voodoos[1]->memBaseAddr);
|
|
|
|
|
mem_mapping_set_addr(&set->voodoos[1]->mapping, set->voodoos[1]->memBaseAddr, 0x01000000);
|
|
|
|
|
} else {
|
|
|
|
|
voodoo_log("voodoo_recalcmapping (sec) : disabled\n");
|
|
|
|
|
mem_mapping_disable(&set->voodoos[1]->mapping);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
voodoo_t *voodoo = set->voodoos[0];
|
|
|
|
|
|
|
|
|
|
if (voodoo->pci_enable && voodoo->memBaseAddr) {
|
|
|
|
|
voodoo_log("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo->memBaseAddr);
|
|
|
|
|
mem_mapping_set_addr(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000);
|
|
|
|
|
} else {
|
|
|
|
|
voodoo_log("voodoo_recalcmapping : disabled\n");
|
|
|
|
|
mem_mapping_disable(&voodoo->mapping);
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2022-08-31 19:19:29 -04:00
|
|
|
}
|
2017-02-23 19:52:14 +01:00
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
uint8_t
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_pci_read(int func, int addr, void *priv)
|
2017-02-23 19:52:14 +01:00
|
|
|
{
|
2023-07-31 18:57:52 -04:00
|
|
|
const voodoo_t *voodoo = (voodoo_t *) priv;
|
2017-02-23 19:52:14 +01:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
if (func)
|
2020-11-18 00:21:07 +01:00
|
|
|
return 0;
|
2022-08-31 19:19:29 -04:00
|
|
|
|
2023-06-09 23:46:54 -04:00
|
|
|
#if 0
|
|
|
|
|
voodoo_log("Voodoo PCI read %08X PC=%08x\n", addr, cpu_state.pc);
|
|
|
|
|
#endif
|
2022-08-31 19:19:29 -04:00
|
|
|
|
|
|
|
|
switch (addr) {
|
|
|
|
|
case 0x00:
|
2024-01-28 01:54:28 +05:00
|
|
|
return 0x1a; /*3Dfx*/
|
2022-08-31 19:19:29 -04:00
|
|
|
case 0x01:
|
|
|
|
|
return 0x12;
|
|
|
|
|
|
|
|
|
|
case 0x02:
|
|
|
|
|
if (voodoo->type == VOODOO_2)
|
|
|
|
|
return 0x02; /*Voodoo 2*/
|
|
|
|
|
else
|
|
|
|
|
return 0x01; /*SST-1 (Voodoo Graphics)*/
|
|
|
|
|
case 0x03:
|
|
|
|
|
return 0x00;
|
|
|
|
|
|
|
|
|
|
case 0x04:
|
|
|
|
|
return voodoo->pci_enable ? 0x02 : 0x00; /*Respond to memory accesses*/
|
|
|
|
|
|
|
|
|
|
case 0x08:
|
|
|
|
|
return 2; /*Revision ID*/
|
|
|
|
|
case 0x09:
|
|
|
|
|
return 0; /*Programming interface*/
|
|
|
|
|
case 0x0a:
|
|
|
|
|
return 0;
|
|
|
|
|
case 0x0b:
|
|
|
|
|
return 0x04;
|
|
|
|
|
|
|
|
|
|
case 0x10:
|
|
|
|
|
return 0x00; /*memBaseAddr*/
|
|
|
|
|
case 0x11:
|
|
|
|
|
return 0x00;
|
|
|
|
|
case 0x12:
|
|
|
|
|
return 0x00;
|
|
|
|
|
case 0x13:
|
|
|
|
|
return voodoo->memBaseAddr >> 24;
|
|
|
|
|
|
|
|
|
|
case 0x40:
|
|
|
|
|
return voodoo->initEnable & 0xff;
|
|
|
|
|
case 0x41:
|
|
|
|
|
if (voodoo->type == VOODOO_2)
|
|
|
|
|
return 0x50 | ((voodoo->initEnable >> 8) & 0x0f);
|
|
|
|
|
return (voodoo->initEnable >> 8) & 0x0f;
|
|
|
|
|
case 0x42:
|
|
|
|
|
return (voodoo->initEnable >> 16) & 0xff;
|
|
|
|
|
case 0x43:
|
|
|
|
|
return (voodoo->initEnable >> 24) & 0xff;
|
2023-07-31 18:57:52 -04:00
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
}
|
|
|
|
|
return 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
void
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_pci_write(int func, int addr, uint8_t val, void *priv)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_t *voodoo = (voodoo_t *) priv;
|
2022-08-31 19:19:29 -04:00
|
|
|
|
|
|
|
|
if (func)
|
|
|
|
|
return;
|
|
|
|
|
|
2023-06-09 23:46:54 -04:00
|
|
|
#if 0
|
|
|
|
|
voodoo_log("Voodoo PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc);
|
|
|
|
|
#endif
|
2022-08-31 19:19:29 -04:00
|
|
|
|
|
|
|
|
switch (addr) {
|
|
|
|
|
case 0x04:
|
|
|
|
|
voodoo->pci_enable = val & 2;
|
|
|
|
|
voodoo_recalcmapping(voodoo->set);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x13:
|
|
|
|
|
voodoo->memBaseAddr = val << 24;
|
|
|
|
|
voodoo_recalcmapping(voodoo->set);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x40:
|
|
|
|
|
voodoo->initEnable = (voodoo->initEnable & ~0x000000ff) | val;
|
|
|
|
|
break;
|
|
|
|
|
case 0x41:
|
|
|
|
|
voodoo->initEnable = (voodoo->initEnable & ~0x0000ff00) | (val << 8);
|
|
|
|
|
break;
|
|
|
|
|
case 0x42:
|
|
|
|
|
voodoo->initEnable = (voodoo->initEnable & ~0x00ff0000) | (val << 16);
|
|
|
|
|
voodoo_recalcmapping(voodoo->set);
|
|
|
|
|
break;
|
|
|
|
|
case 0x43:
|
|
|
|
|
voodoo->initEnable = (voodoo->initEnable & ~0xff000000) | (val << 24);
|
|
|
|
|
voodoo_recalcmapping(voodoo->set);
|
|
|
|
|
break;
|
2023-07-31 18:57:52 -04:00
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
static void
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_speed_changed(void *priv)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2023-07-31 18:57:52 -04:00
|
|
|
const voodoo_set_t *voodoo_set = (voodoo_set_t *) priv;
|
2022-08-31 19:19:29 -04:00
|
|
|
|
|
|
|
|
voodoo_pixelclock_update(voodoo_set->voodoos[0]);
|
|
|
|
|
voodoo_set->voodoos[0]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit4 & 1) ? 2 : 1);
|
|
|
|
|
voodoo_set->voodoos[0]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 1 : 0);
|
|
|
|
|
voodoo_set->voodoos[0]->burst_time = pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 2 : 1);
|
|
|
|
|
if (voodoo_set->nr_cards == 2) {
|
|
|
|
|
voodoo_pixelclock_update(voodoo_set->voodoos[1]);
|
|
|
|
|
voodoo_set->voodoos[1]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit4 & 1) ? 2 : 1);
|
|
|
|
|
voodoo_set->voodoos[1]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 1 : 0);
|
|
|
|
|
voodoo_set->voodoos[1]->burst_time = pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 2 : 1);
|
|
|
|
|
}
|
2023-06-09 23:46:54 -04:00
|
|
|
#if 0
|
|
|
|
|
voodoo_log("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4);
|
|
|
|
|
#endif
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
static void
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_force_blit(void *priv)
|
2021-01-14 00:19:47 +00:00
|
|
|
{
|
2023-07-31 18:57:52 -04:00
|
|
|
const voodoo_set_t *voodoo_set = (voodoo_set_t *) priv;
|
2021-01-14 00:19:47 +00:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
thread_wait_mutex(voodoo_set->voodoos[0]->force_blit_mutex);
|
|
|
|
|
if (voodoo_set->voodoos[0]->can_blit) {
|
|
|
|
|
voodoo_set->voodoos[0]->force_blit_count++;
|
|
|
|
|
}
|
|
|
|
|
thread_release_mutex(voodoo_set->voodoos[0]->force_blit_mutex);
|
|
|
|
|
if (voodoo_set->nr_cards == 2) {
|
|
|
|
|
thread_wait_mutex(voodoo_set->voodoos[1]->force_blit_mutex);
|
|
|
|
|
if (voodoo_set->voodoos[1]->can_blit) {
|
|
|
|
|
voodoo_set->voodoos[1]->force_blit_count++;
|
2021-01-14 00:19:47 +00:00
|
|
|
}
|
2022-08-31 19:19:29 -04:00
|
|
|
thread_release_mutex(voodoo_set->voodoos[1]->force_blit_mutex);
|
|
|
|
|
}
|
2021-01-14 00:19:47 +00:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
void *
|
2022-11-17 22:44:06 +01:00
|
|
|
voodoo_card_init(void)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2022-08-31 19:19:29 -04:00
|
|
|
int c;
|
|
|
|
|
voodoo_t *voodoo = malloc(sizeof(voodoo_t));
|
|
|
|
|
memset(voodoo, 0, sizeof(voodoo_t));
|
|
|
|
|
|
|
|
|
|
voodoo->bilinear_enabled = device_get_config_int("bilinear");
|
|
|
|
|
voodoo->dithersub_enabled = device_get_config_int("dithersub");
|
|
|
|
|
voodoo->scrfilter = device_get_config_int("dacfilter");
|
|
|
|
|
voodoo->texture_size = device_get_config_int("texture_memory");
|
|
|
|
|
voodoo->texture_mask = (voodoo->texture_size << 20) - 1;
|
|
|
|
|
voodoo->fb_size = device_get_config_int("framebuffer_memory");
|
|
|
|
|
voodoo->fb_mask = (voodoo->fb_size << 20) - 1;
|
|
|
|
|
voodoo->render_threads = device_get_config_int("render_threads");
|
|
|
|
|
voodoo->odd_even_mask = voodoo->render_threads - 1;
|
2016-06-26 00:34:39 +02:00
|
|
|
#ifndef NO_CODEGEN
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->use_recompiler = device_get_config_int("recompiler");
|
2022-02-20 02:26:27 -05:00
|
|
|
#endif
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->type = device_get_config_int("type");
|
|
|
|
|
switch (voodoo->type) {
|
|
|
|
|
case VOODOO_1:
|
|
|
|
|
voodoo->dual_tmus = 0;
|
|
|
|
|
break;
|
|
|
|
|
case VOODOO_SB50:
|
|
|
|
|
voodoo->dual_tmus = 1;
|
|
|
|
|
break;
|
|
|
|
|
case VOODOO_2:
|
|
|
|
|
voodoo->dual_tmus = 1;
|
|
|
|
|
break;
|
2023-07-31 18:57:52 -04:00
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
if (voodoo->type == VOODOO_2) /*generate filter lookup tables*/
|
|
|
|
|
voodoo_generate_filter_v2(voodoo);
|
|
|
|
|
else
|
|
|
|
|
voodoo_generate_filter_v1(voodoo);
|
|
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo, &voodoo->pci_slot);
|
2022-08-31 19:19:29 -04:00
|
|
|
|
|
|
|
|
mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo);
|
|
|
|
|
|
|
|
|
|
voodoo->fb_mem = malloc(4 * 1024 * 1024);
|
|
|
|
|
voodoo->tex_mem[0] = malloc(voodoo->texture_size * 1024 * 1024);
|
|
|
|
|
if (voodoo->dual_tmus)
|
|
|
|
|
voodoo->tex_mem[1] = malloc(voodoo->texture_size * 1024 * 1024);
|
|
|
|
|
voodoo->tex_mem_w[0] = (uint16_t *) voodoo->tex_mem[0];
|
|
|
|
|
voodoo->tex_mem_w[1] = (uint16_t *) voodoo->tex_mem[1];
|
|
|
|
|
|
|
|
|
|
for (c = 0; c < TEX_CACHE_MAX; c++) {
|
|
|
|
|
voodoo->texture_cache[0][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4);
|
|
|
|
|
voodoo->texture_cache[0][c].base = -1; /*invalid*/
|
|
|
|
|
voodoo->texture_cache[0][c].refcount = 0;
|
|
|
|
|
if (voodoo->dual_tmus) {
|
|
|
|
|
voodoo->texture_cache[1][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4);
|
|
|
|
|
voodoo->texture_cache[1][c].base = -1; /*invalid*/
|
|
|
|
|
voodoo->texture_cache[1][c].refcount = 0;
|
2016-10-04 17:25:16 +02:00
|
|
|
}
|
2022-08-31 19:19:29 -04:00
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
timer_add(&voodoo->timer, voodoo_callback, voodoo, 1);
|
|
|
|
|
|
|
|
|
|
voodoo->svga = svga_get_pri();
|
|
|
|
|
voodoo->fbiInit0 = 0;
|
|
|
|
|
|
|
|
|
|
voodoo->wake_fifo_thread = thread_create_event();
|
|
|
|
|
voodoo->wake_render_thread[0] = thread_create_event();
|
|
|
|
|
voodoo->wake_render_thread[1] = thread_create_event();
|
|
|
|
|
voodoo->wake_render_thread[2] = thread_create_event();
|
|
|
|
|
voodoo->wake_render_thread[3] = thread_create_event();
|
|
|
|
|
voodoo->wake_main_thread = thread_create_event();
|
|
|
|
|
voodoo->fifo_not_full_event = thread_create_event();
|
|
|
|
|
voodoo->render_not_full_event[0] = thread_create_event();
|
|
|
|
|
voodoo->render_not_full_event[1] = thread_create_event();
|
|
|
|
|
voodoo->render_not_full_event[2] = thread_create_event();
|
|
|
|
|
voodoo->render_not_full_event[3] = thread_create_event();
|
|
|
|
|
voodoo->fifo_thread_run = 1;
|
|
|
|
|
voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo);
|
|
|
|
|
voodoo->render_thread_run[0] = 1;
|
|
|
|
|
voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo);
|
|
|
|
|
if (voodoo->render_threads >= 2) {
|
|
|
|
|
voodoo->render_thread_run[1] = 1;
|
|
|
|
|
voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo);
|
|
|
|
|
}
|
|
|
|
|
if (voodoo->render_threads == 4) {
|
|
|
|
|
voodoo->render_thread_run[2] = 1;
|
|
|
|
|
voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo);
|
|
|
|
|
voodoo->render_thread_run[3] = 1;
|
|
|
|
|
voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo);
|
|
|
|
|
}
|
|
|
|
|
voodoo->swap_mutex = thread_create_mutex();
|
|
|
|
|
timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *) voodoo, 0);
|
|
|
|
|
|
|
|
|
|
for (c = 0; c < 0x100; c++) {
|
|
|
|
|
rgb332[c].r = c & 0xe0;
|
|
|
|
|
rgb332[c].g = (c << 3) & 0xe0;
|
|
|
|
|
rgb332[c].b = (c << 6) & 0xc0;
|
|
|
|
|
rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6);
|
|
|
|
|
rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6);
|
|
|
|
|
rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2);
|
|
|
|
|
rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4);
|
|
|
|
|
rgb332[c].a = 0xff;
|
|
|
|
|
|
|
|
|
|
ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4);
|
|
|
|
|
ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4);
|
|
|
|
|
ai44[c].g = ai44[c].b = ai44[c].r;
|
|
|
|
|
}
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
for (c = 0; c < 0x10000; c++) {
|
|
|
|
|
rgb565[c].r = (c >> 8) & 0xf8;
|
|
|
|
|
rgb565[c].g = (c >> 3) & 0xfc;
|
|
|
|
|
rgb565[c].b = (c << 3) & 0xf8;
|
|
|
|
|
rgb565[c].r |= (rgb565[c].r >> 5);
|
|
|
|
|
rgb565[c].g |= (rgb565[c].g >> 6);
|
|
|
|
|
rgb565[c].b |= (rgb565[c].b >> 5);
|
|
|
|
|
rgb565[c].a = 0xff;
|
|
|
|
|
|
|
|
|
|
argb1555[c].r = (c >> 7) & 0xf8;
|
|
|
|
|
argb1555[c].g = (c >> 2) & 0xf8;
|
|
|
|
|
argb1555[c].b = (c << 3) & 0xf8;
|
|
|
|
|
argb1555[c].r |= (argb1555[c].r >> 5);
|
|
|
|
|
argb1555[c].g |= (argb1555[c].g >> 5);
|
|
|
|
|
argb1555[c].b |= (argb1555[c].b >> 5);
|
|
|
|
|
argb1555[c].a = (c & 0x8000) ? 0xff : 0;
|
|
|
|
|
|
|
|
|
|
argb4444[c].a = (c >> 8) & 0xf0;
|
|
|
|
|
argb4444[c].r = (c >> 4) & 0xf0;
|
|
|
|
|
argb4444[c].g = c & 0xf0;
|
|
|
|
|
argb4444[c].b = (c << 4) & 0xf0;
|
|
|
|
|
argb4444[c].a |= (argb4444[c].a >> 4);
|
|
|
|
|
argb4444[c].r |= (argb4444[c].r >> 4);
|
|
|
|
|
argb4444[c].g |= (argb4444[c].g >> 4);
|
|
|
|
|
argb4444[c].b |= (argb4444[c].b >> 4);
|
|
|
|
|
|
|
|
|
|
ai88[c].a = (c >> 8);
|
|
|
|
|
ai88[c].r = c & 0xff;
|
|
|
|
|
ai88[c].g = c & 0xff;
|
|
|
|
|
ai88[c].b = c & 0xff;
|
|
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
#ifndef NO_CODEGEN
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_codegen_init(voodoo);
|
2016-06-26 00:34:39 +02:00
|
|
|
#endif
|
2016-11-02 22:39:07 +01:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->disp_buffer = 0;
|
|
|
|
|
voodoo->draw_buffer = 1;
|
2021-01-14 00:19:47 +00:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->force_blit_count = 0;
|
|
|
|
|
voodoo->can_blit = 0;
|
|
|
|
|
voodoo->force_blit_mutex = thread_create_mutex();
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
return voodoo;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
void *
|
|
|
|
|
voodoo_2d3d_card_init(int type)
|
2020-11-18 00:21:07 +01:00
|
|
|
{
|
2022-08-31 19:19:29 -04:00
|
|
|
int c;
|
|
|
|
|
voodoo_t *voodoo = malloc(sizeof(voodoo_t));
|
|
|
|
|
memset(voodoo, 0, sizeof(voodoo_t));
|
|
|
|
|
|
|
|
|
|
voodoo->bilinear_enabled = device_get_config_int("bilinear");
|
|
|
|
|
voodoo->dithersub_enabled = device_get_config_int("dithersub");
|
|
|
|
|
voodoo->scrfilter = device_get_config_int("dacfilter");
|
|
|
|
|
voodoo->render_threads = device_get_config_int("render_threads");
|
|
|
|
|
voodoo->odd_even_mask = voodoo->render_threads - 1;
|
2020-11-18 00:21:07 +01:00
|
|
|
#ifndef NO_CODEGEN
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->use_recompiler = device_get_config_int("recompiler");
|
2020-11-18 00:21:07 +01:00
|
|
|
#endif
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->type = type;
|
|
|
|
|
voodoo->dual_tmus = (type == VOODOO_3) ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
/*generate filter lookup tables*/
|
|
|
|
|
voodoo_generate_filter_v2(voodoo);
|
|
|
|
|
|
|
|
|
|
for (c = 0; c < TEX_CACHE_MAX; c++) {
|
|
|
|
|
voodoo->texture_cache[0][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4);
|
|
|
|
|
voodoo->texture_cache[0][c].base = -1; /*invalid*/
|
|
|
|
|
voodoo->texture_cache[0][c].refcount = 0;
|
|
|
|
|
if (voodoo->dual_tmus) {
|
|
|
|
|
voodoo->texture_cache[1][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4);
|
|
|
|
|
voodoo->texture_cache[1][c].base = -1; /*invalid*/
|
|
|
|
|
voodoo->texture_cache[1][c].refcount = 0;
|
2020-11-18 00:21:07 +01:00
|
|
|
}
|
2022-08-31 19:19:29 -04:00
|
|
|
}
|
2020-11-18 00:21:07 +01:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
timer_add(&voodoo->timer, voodoo_callback, voodoo, 1);
|
|
|
|
|
|
|
|
|
|
voodoo->fbiInit0 = 0;
|
|
|
|
|
|
|
|
|
|
voodoo->wake_fifo_thread = thread_create_event();
|
|
|
|
|
voodoo->wake_render_thread[0] = thread_create_event();
|
|
|
|
|
voodoo->wake_render_thread[1] = thread_create_event();
|
|
|
|
|
voodoo->wake_render_thread[2] = thread_create_event();
|
|
|
|
|
voodoo->wake_render_thread[3] = thread_create_event();
|
|
|
|
|
voodoo->wake_main_thread = thread_create_event();
|
|
|
|
|
voodoo->fifo_not_full_event = thread_create_event();
|
|
|
|
|
voodoo->render_not_full_event[0] = thread_create_event();
|
|
|
|
|
voodoo->render_not_full_event[1] = thread_create_event();
|
|
|
|
|
voodoo->render_not_full_event[2] = thread_create_event();
|
|
|
|
|
voodoo->render_not_full_event[3] = thread_create_event();
|
|
|
|
|
voodoo->fifo_thread_run = 1;
|
|
|
|
|
voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo);
|
|
|
|
|
voodoo->render_thread_run[0] = 1;
|
|
|
|
|
voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo);
|
|
|
|
|
if (voodoo->render_threads >= 2) {
|
|
|
|
|
voodoo->render_thread_run[1] = 1;
|
|
|
|
|
voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo);
|
|
|
|
|
}
|
|
|
|
|
if (voodoo->render_threads == 4) {
|
|
|
|
|
voodoo->render_thread_run[2] = 1;
|
|
|
|
|
voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo);
|
|
|
|
|
voodoo->render_thread_run[3] = 1;
|
|
|
|
|
voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo);
|
|
|
|
|
}
|
|
|
|
|
voodoo->swap_mutex = thread_create_mutex();
|
|
|
|
|
timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *) voodoo, 0);
|
|
|
|
|
|
|
|
|
|
for (c = 0; c < 0x100; c++) {
|
|
|
|
|
rgb332[c].r = c & 0xe0;
|
|
|
|
|
rgb332[c].g = (c << 3) & 0xe0;
|
|
|
|
|
rgb332[c].b = (c << 6) & 0xc0;
|
|
|
|
|
rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6);
|
|
|
|
|
rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6);
|
|
|
|
|
rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2);
|
|
|
|
|
rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4);
|
|
|
|
|
rgb332[c].a = 0xff;
|
|
|
|
|
|
|
|
|
|
ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4);
|
|
|
|
|
ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4);
|
|
|
|
|
ai44[c].g = ai44[c].b = ai44[c].r;
|
|
|
|
|
}
|
2020-11-18 00:21:07 +01:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
for (c = 0; c < 0x10000; c++) {
|
|
|
|
|
rgb565[c].r = (c >> 8) & 0xf8;
|
|
|
|
|
rgb565[c].g = (c >> 3) & 0xfc;
|
|
|
|
|
rgb565[c].b = (c << 3) & 0xf8;
|
|
|
|
|
rgb565[c].r |= (rgb565[c].r >> 5);
|
|
|
|
|
rgb565[c].g |= (rgb565[c].g >> 6);
|
|
|
|
|
rgb565[c].b |= (rgb565[c].b >> 5);
|
|
|
|
|
rgb565[c].a = 0xff;
|
|
|
|
|
|
|
|
|
|
argb1555[c].r = (c >> 7) & 0xf8;
|
|
|
|
|
argb1555[c].g = (c >> 2) & 0xf8;
|
|
|
|
|
argb1555[c].b = (c << 3) & 0xf8;
|
|
|
|
|
argb1555[c].r |= (argb1555[c].r >> 5);
|
|
|
|
|
argb1555[c].g |= (argb1555[c].g >> 5);
|
|
|
|
|
argb1555[c].b |= (argb1555[c].b >> 5);
|
|
|
|
|
argb1555[c].a = (c & 0x8000) ? 0xff : 0;
|
|
|
|
|
|
|
|
|
|
argb4444[c].a = (c >> 8) & 0xf0;
|
|
|
|
|
argb4444[c].r = (c >> 4) & 0xf0;
|
|
|
|
|
argb4444[c].g = c & 0xf0;
|
|
|
|
|
argb4444[c].b = (c << 4) & 0xf0;
|
|
|
|
|
argb4444[c].a |= (argb4444[c].a >> 4);
|
|
|
|
|
argb4444[c].r |= (argb4444[c].r >> 4);
|
|
|
|
|
argb4444[c].g |= (argb4444[c].g >> 4);
|
|
|
|
|
argb4444[c].b |= (argb4444[c].b >> 4);
|
|
|
|
|
|
|
|
|
|
ai88[c].a = (c >> 8);
|
|
|
|
|
ai88[c].r = c & 0xff;
|
|
|
|
|
ai88[c].g = c & 0xff;
|
|
|
|
|
ai88[c].b = c & 0xff;
|
|
|
|
|
}
|
2020-11-18 00:21:07 +01:00
|
|
|
#ifndef NO_CODEGEN
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_codegen_init(voodoo);
|
2020-11-18 00:21:07 +01:00
|
|
|
#endif
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->disp_buffer = 0;
|
|
|
|
|
voodoo->draw_buffer = 1;
|
2020-11-18 00:21:07 +01:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->force_blit_count = 0;
|
|
|
|
|
voodoo->can_blit = 0;
|
|
|
|
|
voodoo->force_blit_mutex = thread_create_mutex();
|
2021-01-14 00:19:47 +00:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
return voodoo;
|
2020-11-18 00:21:07 +01:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
void *
|
2023-07-31 18:57:52 -04:00
|
|
|
voodoo_init(UNUSED(const device_t *info))
|
2017-08-20 23:15:07 +02:00
|
|
|
{
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t));
|
|
|
|
|
uint32_t tmuConfig = 1;
|
|
|
|
|
int type;
|
|
|
|
|
memset(voodoo_set, 0, sizeof(voodoo_set_t));
|
|
|
|
|
|
|
|
|
|
type = device_get_config_int("type");
|
|
|
|
|
|
|
|
|
|
voodoo_set->nr_cards = device_get_config_int("sli") ? 2 : 1;
|
|
|
|
|
voodoo_set->voodoos[0] = voodoo_card_init();
|
|
|
|
|
voodoo_set->voodoos[0]->set = voodoo_set;
|
|
|
|
|
if (voodoo_set->nr_cards == 2) {
|
|
|
|
|
voodoo_set->voodoos[1] = voodoo_card_init();
|
|
|
|
|
|
|
|
|
|
voodoo_set->voodoos[1]->set = voodoo_set;
|
|
|
|
|
|
|
|
|
|
if (type == VOODOO_2) {
|
|
|
|
|
voodoo_set->voodoos[0]->fbiInit5 |= FBIINIT5_MULTI_CVG;
|
|
|
|
|
voodoo_set->voodoos[1]->fbiInit5 |= FBIINIT5_MULTI_CVG;
|
|
|
|
|
} else {
|
|
|
|
|
voodoo_set->voodoos[0]->fbiInit1 |= FBIINIT1_MULTI_SST;
|
|
|
|
|
voodoo_set->voodoos[1]->fbiInit1 |= FBIINIT1_MULTI_SST;
|
2017-08-20 23:15:07 +02:00
|
|
|
}
|
2022-08-31 19:19:29 -04:00
|
|
|
}
|
2017-08-20 23:15:07 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
switch (type) {
|
|
|
|
|
case VOODOO_1:
|
|
|
|
|
if (voodoo_set->nr_cards == 2)
|
|
|
|
|
tmuConfig = 1 | (3 << 3);
|
|
|
|
|
else
|
|
|
|
|
tmuConfig = 1;
|
|
|
|
|
break;
|
|
|
|
|
case VOODOO_SB50:
|
|
|
|
|
if (voodoo_set->nr_cards == 2)
|
|
|
|
|
tmuConfig = 1 | (3 << 3) | (3 << 6) | (2 << 9);
|
|
|
|
|
else
|
2017-08-20 23:15:07 +02:00
|
|
|
tmuConfig = 1 | (3 << 6);
|
2022-08-31 19:19:29 -04:00
|
|
|
break;
|
|
|
|
|
case VOODOO_2:
|
|
|
|
|
tmuConfig = 1 | (3 << 6);
|
|
|
|
|
break;
|
2023-07-31 18:57:52 -04:00
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2022-08-31 19:19:29 -04:00
|
|
|
}
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_set->voodoos[0]->tmuConfig = tmuConfig;
|
|
|
|
|
if (voodoo_set->nr_cards == 2)
|
|
|
|
|
voodoo_set->voodoos[1]->tmuConfig = tmuConfig;
|
2017-08-20 23:15:07 +02:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
mem_mapping_add(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew, voodoo_snoop_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo_set);
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
return voodoo_set;
|
2017-08-20 23:15:07 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
void
|
|
|
|
|
voodoo_card_close(voodoo_t *voodoo)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo->fifo_thread_run = 0;
|
|
|
|
|
thread_set_event(voodoo->wake_fifo_thread);
|
|
|
|
|
thread_wait(voodoo->fifo_thread);
|
|
|
|
|
voodoo->render_thread_run[0] = 0;
|
|
|
|
|
thread_set_event(voodoo->wake_render_thread[0]);
|
|
|
|
|
thread_wait(voodoo->render_thread[0]);
|
|
|
|
|
if (voodoo->render_threads >= 2) {
|
|
|
|
|
voodoo->render_thread_run[1] = 0;
|
|
|
|
|
thread_set_event(voodoo->wake_render_thread[1]);
|
|
|
|
|
thread_wait(voodoo->render_thread[1]);
|
|
|
|
|
}
|
|
|
|
|
if (voodoo->render_threads == 4) {
|
|
|
|
|
voodoo->render_thread_run[2] = 0;
|
|
|
|
|
thread_set_event(voodoo->wake_render_thread[2]);
|
|
|
|
|
thread_wait(voodoo->render_thread[2]);
|
|
|
|
|
voodoo->render_thread_run[3] = 0;
|
|
|
|
|
thread_set_event(voodoo->wake_render_thread[3]);
|
|
|
|
|
thread_wait(voodoo->render_thread[3]);
|
|
|
|
|
}
|
|
|
|
|
thread_destroy_event(voodoo->fifo_not_full_event);
|
|
|
|
|
thread_destroy_event(voodoo->wake_main_thread);
|
|
|
|
|
thread_destroy_event(voodoo->wake_fifo_thread);
|
|
|
|
|
thread_destroy_event(voodoo->wake_render_thread[0]);
|
|
|
|
|
thread_destroy_event(voodoo->wake_render_thread[1]);
|
|
|
|
|
thread_destroy_event(voodoo->render_not_full_event[0]);
|
|
|
|
|
thread_destroy_event(voodoo->render_not_full_event[1]);
|
|
|
|
|
|
2023-06-01 18:32:25 -04:00
|
|
|
for (uint8_t c = 0; c < TEX_CACHE_MAX; c++) {
|
2022-08-31 19:19:29 -04:00
|
|
|
if (voodoo->dual_tmus)
|
|
|
|
|
free(voodoo->texture_cache[1][c].data);
|
|
|
|
|
free(voodoo->texture_cache[0][c].data);
|
|
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
#ifndef NO_CODEGEN
|
2022-08-31 19:19:29 -04:00
|
|
|
voodoo_codegen_close(voodoo);
|
2016-06-26 00:34:39 +02:00
|
|
|
#endif
|
2022-08-31 19:19:29 -04:00
|
|
|
if (voodoo->type < VOODOO_BANSHEE && voodoo->fb_mem) {
|
|
|
|
|
free(voodoo->fb_mem);
|
|
|
|
|
if (voodoo->dual_tmus)
|
|
|
|
|
free(voodoo->tex_mem[1]);
|
|
|
|
|
free(voodoo->tex_mem[0]);
|
|
|
|
|
}
|
2021-01-14 00:19:47 +00:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
thread_close_mutex(voodoo->force_blit_mutex);
|
2021-01-14 00:19:47 +00:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
free(voodoo);
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
void
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_close(void *priv)
|
2017-08-20 23:15:07 +02:00
|
|
|
{
|
2023-06-09 23:46:54 -04:00
|
|
|
voodoo_set_t *voodoo_set = (voodoo_set_t *) priv;
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
if (voodoo_set->nr_cards == 2)
|
|
|
|
|
voodoo_card_close(voodoo_set->voodoos[1]);
|
|
|
|
|
voodoo_card_close(voodoo_set->voodoos[0]);
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
free(voodoo_set);
|
2017-08-20 23:15:07 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-26 23:31:28 -05:00
|
|
|
static const device_config_t voodoo_config[] = {
|
2022-08-31 19:19:29 -04:00
|
|
|
// clang-format off
|
2022-02-26 23:31:28 -05:00
|
|
|
{
|
|
|
|
|
.name = "type",
|
|
|
|
|
.description = "Voodoo type",
|
|
|
|
|
.type = CONFIG_SELECTION,
|
|
|
|
|
.selection = {
|
|
|
|
|
{
|
2024-01-28 01:54:28 +05:00
|
|
|
.description = "3Dfx Voodoo Graphics",
|
2022-02-26 23:31:28 -05:00
|
|
|
.value = VOODOO_1
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "Obsidian SB50 + Amethyst (2 TMUs)",
|
|
|
|
|
.value = VOODOO_SB50
|
|
|
|
|
},
|
|
|
|
|
{
|
2024-01-28 01:54:28 +05:00
|
|
|
.description = "3Dfx Voodoo 2",
|
2022-02-26 23:31:28 -05:00
|
|
|
.value = VOODOO_2
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = ""
|
|
|
|
|
}
|
2021-07-05 01:21:02 +02:00
|
|
|
},
|
2022-02-26 23:31:28 -05:00
|
|
|
.default_int = 0
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.name = "framebuffer_memory",
|
|
|
|
|
.description = "Framebuffer memory size",
|
|
|
|
|
.type = CONFIG_SELECTION,
|
|
|
|
|
.selection = {
|
|
|
|
|
{
|
|
|
|
|
.description = "2 MB",
|
|
|
|
|
.value = 2
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "4 MB",
|
|
|
|
|
.value = 4
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = ""
|
|
|
|
|
}
|
2017-06-14 20:35:58 +02:00
|
|
|
},
|
2022-02-26 23:31:28 -05:00
|
|
|
.default_int = 2
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.name = "texture_memory",
|
|
|
|
|
.description = "Texture memory size",
|
|
|
|
|
.type = CONFIG_SELECTION,
|
|
|
|
|
.selection = {
|
|
|
|
|
{
|
|
|
|
|
.description = "2 MB",
|
|
|
|
|
.value = 2
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "4 MB",
|
|
|
|
|
.value = 4
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = ""
|
|
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
},
|
2022-02-26 23:31:28 -05:00
|
|
|
.default_int = 2
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.name = "bilinear",
|
|
|
|
|
.description = "Bilinear filtering",
|
|
|
|
|
.type = CONFIG_BINARY,
|
|
|
|
|
.default_int = 1
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.name = "dithersub",
|
|
|
|
|
.description = "Dither subtraction",
|
|
|
|
|
.type = CONFIG_BINARY,
|
|
|
|
|
.default_int = 1
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.name = "dacfilter",
|
|
|
|
|
.description = "Screen Filter",
|
|
|
|
|
.type = CONFIG_BINARY,
|
|
|
|
|
.default_int = 0
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.name = "render_threads",
|
|
|
|
|
.description = "Render threads",
|
|
|
|
|
.type = CONFIG_SELECTION,
|
|
|
|
|
.selection = {
|
|
|
|
|
{
|
|
|
|
|
.description = "1",
|
|
|
|
|
.value = 1
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "2",
|
|
|
|
|
.value = 2
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "4",
|
|
|
|
|
.value = 4
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = ""
|
|
|
|
|
}
|
2017-08-20 23:15:07 +02:00
|
|
|
},
|
2022-02-26 23:31:28 -05:00
|
|
|
.default_int = 2
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.name = "sli",
|
|
|
|
|
.description = "SLI",
|
|
|
|
|
.type = CONFIG_BINARY,
|
|
|
|
|
.default_int = 0
|
|
|
|
|
},
|
2016-06-26 00:34:39 +02:00
|
|
|
#ifndef NO_CODEGEN
|
2022-02-26 23:31:28 -05:00
|
|
|
{
|
|
|
|
|
.name = "recompiler",
|
2024-11-10 02:35:27 +01:00
|
|
|
.description = "Dynamic Recompiler",
|
2022-02-26 23:31:28 -05:00
|
|
|
.type = CONFIG_BINARY,
|
|
|
|
|
.default_int = 1
|
|
|
|
|
},
|
2016-06-26 00:34:39 +02:00
|
|
|
#endif
|
2022-02-26 23:31:28 -05:00
|
|
|
{
|
2022-04-09 20:09:14 -04:00
|
|
|
.type = CONFIG_END
|
2022-02-26 23:31:28 -05:00
|
|
|
}
|
2022-11-19 08:49:04 -05:00
|
|
|
// clang-format on
|
2016-06-26 00:34:39 +02:00
|
|
|
};
|
|
|
|
|
|
2022-08-31 19:19:29 -04:00
|
|
|
const device_t voodoo_device = {
|
2024-01-28 01:54:28 +05:00
|
|
|
.name = "3Dfx Voodoo Graphics",
|
2022-04-09 20:09:14 -04:00
|
|
|
.internal_name = "voodoo",
|
2022-08-31 19:19:29 -04:00
|
|
|
.flags = DEVICE_PCI,
|
|
|
|
|
.local = 0,
|
|
|
|
|
.init = voodoo_init,
|
|
|
|
|
.close = voodoo_close,
|
|
|
|
|
.reset = NULL,
|
2022-04-09 20:09:14 -04:00
|
|
|
{ .available = NULL },
|
|
|
|
|
.speed_changed = voodoo_speed_changed,
|
2022-08-31 19:19:29 -04:00
|
|
|
.force_redraw = voodoo_force_blit,
|
|
|
|
|
.config = voodoo_config
|
2016-06-26 00:34:39 +02:00
|
|
|
};
|