Merge branch 'master' into pc98x1

This commit is contained in:
TC1995
2024-08-29 00:49:26 +02:00
29 changed files with 683 additions and 263 deletions

View File

@@ -535,6 +535,14 @@ then
sudo sed -i -e 's/-no-feature-vulkan/-feature-vulkan/g' "$qt5_portfile"
sudo sed -i -e 's/configure.env-append MAKE=/configure.env-append VULKAN_SDK=${prefix} MAKE=/g' "$qt5_portfile"
fi
# Patch wget to remove libproxy support, as it depends on shared-mime-info which
# fails to build for a 10.14 target, which we have to do despite wget only being
# a host dependency. MacPorts issue 69406 strongly implies this will not be fixed.
wget_portfile="$macports/var/macports/sources/rsync.macports.org/macports/release/tarballs/ports/net/wget/Portfile"
sudo sed -i -e 's/--enable-libproxy/--disable-libproxy/g' "$wget_portfile"
sudo sed -i -e 's/port:libproxy//g' "$wget_portfile"
while :
do
# Attempt to install dependencies.

View File

@@ -131,7 +131,6 @@ option(RTMIDI "RtMidi"
option(FLUIDSYNTH "FluidSynth" ON)
option(MUNT "MUNT" ON)
option(VNC "VNC renderer" OFF)
option(CPPTHREADS "C++11 threads" ON)
option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF)
option(GDBSTUB "Enable GDB stub server for debugging" OFF)
@@ -141,8 +140,10 @@ option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs"
if(WIN32)
set(QT ON)
option(CPPTHREADS "C++11 threads" OFF)
else()
option(QT "Qt GUI" ON)
option(CPPTHREADS "C++11 threads" ON)
endif()
# Development branch features

View File

@@ -27,9 +27,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1)
endif()
if(WIN32)
target_sources(86Box PRIVATE qt/win_thread.c)
else()
if(CPPTHREADS)
target_sources(86Box PRIVATE thread.cpp)
endif()

View File

@@ -861,16 +861,46 @@ load_storage_controllers(void)
cassette_enable = !!ini_section_get_int(cat, "cassette_enabled", 0);
else
cassette_enable = 0;
p = ini_section_get_string(cat, "cassette_file", "");
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511\n");
else
strncpy(cassette_fname, p, 511);
if (!strcmp(p, usr_path))
p[0] = 0x00;
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511 (cassette_fname)\n");
else
strncpy(cassette_fname, p, 511);
} else
path_append_filename(cassette_fname, usr_path, p);
path_normalize(cassette_fname);
}
p = ini_section_get_string(cat, "cassette_mode", "");
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511\n");
else
strncpy(cassette_mode, p, 511);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
cassette_image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
sprintf(temp, "cassette_image_history_%02i", i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("load_storage_controllers(): strlen(p) > 2047 "
"(cassette_image_history[%i])\n", i);
else
snprintf(cassette_image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p);
} else
snprintf(cassette_image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
path_get_slash(usr_path), p);
path_normalize(cassette_image_history[i]);
}
}
cassette_pos = ini_section_get_int(cat, "cassette_position", 0);
cassette_srate = ini_section_get_int(cat, "cassette_srate", 44100);
cassette_append = !!ini_section_get_int(cat, "cassette_append", 0);
@@ -894,6 +924,24 @@ load_storage_controllers(void)
path_append_filename(cart_fns[c], usr_path, p);
path_normalize(cart_fns[c]);
}
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
cart_image_history[c][i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
sprintf(temp, "cartridge_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("load_storage_controllers(): strlen(p) > 2047 "
"(cart_image_history[%i][%i])\n", c, i);
else
snprintf(cart_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s", p);
} else
snprintf(cart_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
path_get_slash(usr_path), p);
path_normalize(cart_image_history[c][i]);
}
}
}
lba_enhancer_enabled = !!ini_section_get_int(cat, "lba_enhancer_enabled", 0);
@@ -2330,14 +2378,32 @@ save_storage_controllers(void)
if (strlen(cassette_fname) == 0)
ini_section_delete_var(cat, "cassette_file");
else
ini_section_set_string(cat, "cassette_file", cassette_fname);
else {
path_normalize(cassette_fname);
if (!strnicmp(cassette_fname, usr_path, strlen(usr_path)))
ini_section_set_string(cat, "cassette_file", &cassette_fname[strlen(usr_path)]);
else
ini_section_set_string(cat, "cassette_file", cassette_fname);
}
if (strlen(cassette_mode) == 0)
ini_section_delete_var(cat, "cassette_mode");
else
ini_section_set_string(cat, "cassette_mode", cassette_mode);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cassette_image_history_%02i", i + 1);
if ((cassette_image_history[i] == 0) || strlen(cassette_image_history[i]) == 0)
ini_section_delete_var(cat, temp);
else {
path_normalize(cassette_image_history[i]);
if (!strnicmp(cassette_image_history[i], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cassette_image_history[i][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cassette_image_history[i]);
}
}
if (cassette_pos == 0)
ini_section_delete_var(cat, "cassette_position");
else
@@ -2365,10 +2431,29 @@ save_storage_controllers(void)
for (c = 0; c < 2; c++) {
sprintf(temp, "cartridge_%02i_fn", c + 1);
if (strlen(cart_fns[c]) == 0)
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp, cart_fns[c]);
else {
path_normalize(cart_fns[c]);
if (!strnicmp(cart_fns[c], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cart_fns[c][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cart_fns[c]);
}
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cartridge_%02i_image_history_%02i", c + 1, i + 1);
if ((cart_image_history[c][i] == 0) || strlen(cart_image_history[c][i]) == 0)
ini_section_delete_var(cat, temp);
else {
path_normalize(cart_image_history[c][i]);
if (!strnicmp(cart_image_history[c][i], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cart_image_history[c][i][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cart_image_history[c][i]);
}
}
}
if (lba_enhancer_enabled == 0)

View File

@@ -304,6 +304,14 @@ exec386_2386(int32_t cycs)
cpu_state.pc &= 0xffff;
#endif
if (cpu_flush_pending == 1)
cpu_flush_pending++;
else if (cpu_flush_pending == 2) {
cpu_flush_pending = 0;
cr0 ^= 0x80000000;
flushmmucache();
}
if (cpu_end_block_after_ins)
cpu_end_block_after_ins--;

View File

@@ -933,6 +933,14 @@ exec386(int32_t cycs)
x386_dynarec_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc);
#endif
if (cpu_flush_pending == 1)
cpu_flush_pending++;
else if (cpu_flush_pending == 2) {
cpu_flush_pending = 0;
cr0 ^= 0x80000000;
flushmmucache();
}
#ifndef USE_NEW_DYNAREC
if (!use32)
cpu_state.pc &= 0xffff;

View File

@@ -182,6 +182,7 @@ int cpu_rom_prefetch_cycles;
int cpu_waitstates;
int cpu_cache_int_enabled;
int cpu_cache_ext_enabled;
int cpu_flush_pending;
int cpu_isa_speed;
int cpu_pci_speed;
int cpu_isa_pci_div;
@@ -1537,6 +1538,52 @@ cpu_set(void)
#ifdef USE_AMD_K5
case CPU_K5:
case CPU_5K86:
#ifdef USE_DYNAREC
x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f);
#else
x86_setopcodes(ops_386, ops_pentiummmx_0f);
#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 2; /* register dest - memory src */
timing_mr = 3; /* memory dest - register src */
timing_mm = 3;
timing_rml = 2; /* register dest - memory src long */
timing_mrl = 3; /* memory dest - register src long */
timing_mml = 3;
timing_bt = 0; /* branch taken */
timing_bnt = 1; /* branch not taken */
timing_int = 6;
timing_int_rm = 11;
timing_int_v86 = 54;
timing_int_pm = 25;
timing_int_pm_outer = 42;
timing_iret_rm = 7;
timing_iret_v86 = 27; /* unknown */
timing_iret_pm = 10;
timing_iret_pm_outer = 27;
timing_call_rm = 4;
timing_call_pm = 4;
timing_call_pm_gate = 22;
timing_call_pm_gate_inner = 44;
timing_retf_rm = 4;
timing_retf_pm = 4;
timing_retf_pm_outer = 23;
timing_jmp_rm = 3;
timing_jmp_pm = 3;
timing_jmp_pm_gate = 18;
timing_misaligned = 3;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PGE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_k5);
#endif /* USE_DYNAREC */
break;
#endif /* USE_AMD_K5 */
case CPU_K6:
case CPU_K6_2:
@@ -1547,27 +1594,13 @@ cpu_set(void)
#ifdef USE_DYNAREC
if (cpu_s->cpu_type >= CPU_K6_2)
x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f);
# ifdef USE_AMD_K5
else if (cpu_s->cpu_type == CPU_K6)
x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f);
else
x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f);
# else
else
x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f);
# endif /* USE_AMD_K5 */
#else
if (cpu_s->cpu_type >= CPU_K6_2)
x86_setopcodes(ops_386, ops_k62_0f);
# ifdef USE_AMD_K5
else if (cpu_s->cpu_type == CPU_K6)
x86_setopcodes(ops_386, ops_k6_0f);
else
x86_setopcodes(ops_386, ops_pentiummmx_0f);
# else
else
x86_setopcodes(ops_386, ops_k6_0f);
# endif /* USE_AMD_K5 */
#endif /* USE_DYNAREC */
if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) {
@@ -1614,23 +1647,11 @@ cpu_set(void)
cpu_features |= CPU_FEATURE_3DNOW;
if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P))
cpu_features |= CPU_FEATURE_3DNOWE;
#ifdef USE_AMD_K5
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE;
if (cpu_s->cpu_type >= CPU_K6) {
cpu_CR4_mask |= (CR4_VME | CR4_PVI | CR4_PSE);
if (cpu_s->cpu_type <= CPU_K6)
cpu_CR4_mask |= CR4_PCE;
else if (cpu_s->cpu_type >= CPU_K6_2C)
cpu_CR4_mask |= CR4_PGE;
} else
cpu_CR4_mask |= CR4_PGE;
#else
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE;
if (cpu_s->cpu_type == CPU_K6)
cpu_CR4_mask |= CR4_PCE;
else if (cpu_s->cpu_type >= CPU_K6_2C)
cpu_CR4_mask |= CR4_PGE;
#endif /* USE_AMD_K5 */
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_k6);

View File

@@ -617,6 +617,7 @@ extern int cpu_prefetch_width;
extern int cpu_mem_prefetch_cycles;
extern int cpu_rom_prefetch_cycles;
extern int cpu_waitstates;
extern int cpu_flush_pending;
extern int cpu_cache_int_enabled;
extern int cpu_cache_ext_enabled;
extern int cpu_isa_speed;

View File

@@ -277,7 +277,7 @@ reset_common(int hard)
cr0 = 0;
if (is386 && !is486 && (fpu_type == FPU_387))
cr0 |= 0x10;
cpu_cache_int_enabled = 0;
cpu_cache_int_enabled = 0;
cpu_update_waitstates();
cr4 = 0;
cpu_state.eflags = 0;
@@ -325,6 +325,7 @@ reset_common(int hard)
if (hard)
codegen_reset();
#endif
cpu_flush_pending = 0;
if (!hard)
flushmmucache();
x86_was_reset = 1;

View File

@@ -9,6 +9,8 @@ opMOV_r_CRx_a16(uint32_t fetchdat)
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (cpu_flush_pending)
cpu_state.regs[cpu_rm].l ^= 0x80000000;
if (is486 || isibm486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
else {
@@ -49,6 +51,8 @@ opMOV_r_CRx_a32(uint32_t fetchdat)
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (cpu_flush_pending)
cpu_state.regs[cpu_rm].l ^= 0x80000000;
if (is486 || isibm486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
else {
@@ -180,12 +184,21 @@ opMOV_CRx_r_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001)
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
if (is_p6 || cpu_use_dynarec)
flushmmucache();
else
cpu_flush_pending = 1;
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
cr0 = cpu_state.regs[cpu_rm].l;
if (!is_p6 && !cpu_use_dynarec && ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000))
cr0 = (cr0 & 0x80000000) | (cpu_state.regs[cpu_rm].l & 0x7fffffff);
else
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
@@ -237,12 +250,21 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
fetch_ea_32(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001)
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
if (is_p6 || cpu_use_dynarec)
flushmmucache();
else
cpu_flush_pending = 1;
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
cr0 = cpu_state.regs[cpu_rm].l;
if (!is_p6 && !cpu_use_dynarec && ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000))
cr0 = (cr0 & 0x80000000) | (cpu_state.regs[cpu_rm].l & 0x7fffffff);
else
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))

View File

@@ -9,6 +9,8 @@ opMOV_r_CRx_a16(uint32_t fetchdat)
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (cpu_flush_pending)
cpu_state.regs[cpu_rm].l ^= 0x80000000;
if (is486 || isibm486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
else {
@@ -49,6 +51,8 @@ opMOV_r_CRx_a32(uint32_t fetchdat)
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (cpu_flush_pending)
cpu_state.regs[cpu_rm].l ^= 0x80000000;
if (is486 || isibm486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
else {
@@ -176,12 +180,17 @@ opMOV_CRx_r_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001)
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000)
cpu_flush_pending = 1;
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
cr0 = cpu_state.regs[cpu_rm].l;
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000)
cr0 = (cr0 & 0x80000000) | (cpu_state.regs[cpu_rm].l & 0x7fffffff);
else
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
@@ -233,12 +242,17 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
fetch_ea_32(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001)
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000)
cpu_flush_pending = 1;
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
cr0 = cpu_state.regs[cpu_rm].l;
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000)
cr0 = (cr0 & 0x80000000) | (cpu_state.regs[cpu_rm].l & 0x7fffffff);
else
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))

View File

@@ -431,12 +431,21 @@ op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
if (is386 && is32 && (cpu_mod == 3)) {
if (is486 || isibm486)
seteaw(cr0);
else if (is386 && !cpu_16bitbus)
seteaw(cr0 | /* 0x7FFFFF00 */ 0x7FFFFFE0);
else
seteaw(cr0 | 0x7FFFFFF0);
if (cpu_flush_pending) {
if (is486 || isibm486)
seteaw(cr0 ^ 0x80000000);
else if (is386 && !cpu_16bitbus)
seteaw((cr0 ^ 0x80000000) | /* 0x7FFFFF00 */ 0x7FFFFFE0);
else
seteaw((cr0 ^ 0x80000000) | 0x7FFFFFF0);
} else {
if (is486 || isibm486)
seteaw(cr0);
else if (is386 && !cpu_16bitbus)
seteaw(cr0 | /* 0x7FFFFF00 */ 0x7FFFFFE0);
else
seteaw(cr0 | 0x7FFFFFF0);
}
} else {
if (is486 || isibm486)
seteaw(msw);

View File

@@ -35,6 +35,7 @@ typedef struct cart_t {
} cart_t;
char cart_fns[2][512];
char *cart_image_history[2][CART_IMAGE_HISTORY];
static cart_t carts[2];

View File

@@ -45,6 +45,7 @@ pc_cassette_t *cassette;
char cassette_fname[512];
char cassette_mode[512];
char * cassette_image_history[CASSETTE_IMAGE_HISTORY];
unsigned long cassette_pos;
unsigned long cassette_srate;
int cassette_enable;

View File

@@ -21,7 +21,10 @@
extern "C" {
#endif
#define CART_IMAGE_HISTORY 4
extern char cart_fns[2][512];
extern char *cart_image_history[2][CART_IMAGE_HISTORY];
extern void cart_load(int drive, char *fn);
extern void cart_close(int drive);

View File

@@ -153,10 +153,13 @@ void pc_cas_print_state(const pc_cassette_t *cas);
void pc_cas_clock(pc_cassette_t *cas, unsigned long cnt);
void pc_cas_advance(pc_cassette_t *cas);
#define CASSETTE_IMAGE_HISTORY 4
extern pc_cassette_t *cassette;
extern char cassette_fname[512];
extern char cassette_mode[512];
extern char * cassette_image_history[CASSETTE_IMAGE_HISTORY];
extern unsigned long cassette_pos;
extern unsigned long cassette_srate;
extern int cassette_enable;

View File

@@ -529,6 +529,7 @@ extern const device_t s3_trio64v2_dx_onboard_pci_device;
extern const device_t s3_virge_325_pci_device;
extern const device_t s3_virge_325_onboard_pci_device;
extern const device_t s3_diamond_stealth_2000_pci_device;
extern const device_t s3_mirocrystal_3d_pci_device;
extern const device_t s3_diamond_stealth_3000_pci_device;
extern const device_t s3_stb_velocity_3d_pci_device;
extern const device_t s3_virge_375_pci_device;

View File

@@ -1438,6 +1438,34 @@ speed_changed(void *priv)
recalc_timings(pcjr);
}
static void
pcjr_vid_init(pcjr_t *pcjr)
{
int display_type;
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram);
pcjr->memctrl = -1;
if (mem_size < 128)
pcjr->memctrl &= ~0x24;
display_type = device_get_config_int("display_type");
pcjr->composite = (display_type != PCJR_RGB);
pcjr->apply_hd = device_get_config_int("apply_hd");
overscan_x = 256;
overscan_y = 32;
mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000,
vid_read, NULL, NULL,
vid_write, NULL, NULL, NULL, 0, pcjr);
io_sethandler(0x03d0, 16,
vid_in, NULL, NULL, vid_out, NULL, NULL, pcjr);
timer_add(&pcjr->timer, vid_poll, pcjr, 1);
cga_palette = 0;
cgapal_rebuild();
}
void
pit_irq0_timer_pcjr(int new_out, int old_out, UNUSED(void *priv))
{
@@ -1494,7 +1522,6 @@ const device_t pcjr_device = {
int
machine_pcjr_init(UNUSED(const machine_t *model))
{
int display_type;
pcjr_t *pcjr;
int ret;
@@ -1507,14 +1534,6 @@ machine_pcjr_init(UNUSED(const machine_t *model))
pcjr = malloc(sizeof(pcjr_t));
memset(pcjr, 0x00, sizeof(pcjr_t));
pcjr->memctrl = -1;
if (mem_size < 128)
pcjr->memctrl &= ~0x24;
display_type = machine_get_config_int("display_type");
pcjr->composite = (display_type != PCJR_RGB);
pcjr->apply_hd = machine_get_config_int("apply_hd");
overscan_x = 256;
overscan_y = 32;
pic_init_pcjr();
pit_common_init(0, pit_irq0_timer_pcjr, NULL);
@@ -1524,16 +1543,10 @@ machine_pcjr_init(UNUSED(const machine_t *model))
/* Initialize the video controller. */
video_reset(gfxcard[0]);
loadfont("roms/video/mda/mda.rom", 0);
mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000,
vid_read, NULL, NULL,
vid_write, NULL, NULL, NULL, 0, pcjr);
io_sethandler(0x03d0, 16,
vid_in, NULL, NULL, vid_out, NULL, NULL, pcjr);
timer_add(&pcjr->timer, vid_poll, pcjr, 1);
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram);
device_context(&pcjr_device);
pcjr_vid_init(pcjr);
device_context_restore();
device_add_ex(&pcjr_device, pcjr);
cga_palette = 0;
cgapal_rebuild();
/* Initialize the keyboard. */
keyboard_scan = 1;

View File

@@ -1328,11 +1328,10 @@ vid_init(tandy_t *dev)
vid = malloc(sizeof(t1kvid_t));
memset(vid, 0x00, sizeof(t1kvid_t));
vid->memctrl = -1;
dev->vid = vid;
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram);
display_type = machine_get_config_int("display_type");
display_type = device_get_config_int("display_type");
vid->composite = (display_type != TANDY_RGB);
cga_comp_init(1);
@@ -1345,11 +1344,14 @@ vid_init(tandy_t *dev)
io_sethandler(0x0065, 1, vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
} else
vid->b8000_mask = 0x3fff;
timer_add(&vid->timer, vid_poll, dev, 1);
mem_mapping_add(&vid->mapping, 0xb8000, 0x08000,
vid_read, NULL, NULL, vid_write, NULL, NULL, NULL, 0, dev);
io_sethandler(0x03d0, 16,
vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
dev->vid = vid;
}
const device_config_t vid_config[] = {
@@ -1771,7 +1773,9 @@ machine_tandy1k_init(const machine_t *model, int type)
keyboard_set_table(scancode_tandy);
io_sethandler(0x00a0, 1,
tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev);
device_context(&vid_device);
vid_init(dev);
device_context_restore();
device_add_ex(&vid_device, dev);
device_add((type == TYPE_TANDY1000SX) ? &ncr8496_device : &sn76489_device);
break;
@@ -1781,8 +1785,10 @@ machine_tandy1k_init(const machine_t *model, int type)
keyboard_set_table(scancode_tandy);
io_sethandler(0x00a0, 1,
tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev);
device_context(&vid_device_hx);
vid_init(dev);
device_add_ex(&vid_device, dev);
device_context_restore();
device_add_ex(&vid_device_hx, dev);
device_add(&ncr8496_device);
device_add(&eep_1000hx_device);
break;
@@ -1792,7 +1798,9 @@ machine_tandy1k_init(const machine_t *model, int type)
init_rom(dev);
io_sethandler(0xffe8, 8,
tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev);
device_context(&vid_device_sl);
vid_init(dev);
device_context_restore();
device_add_ex(&vid_device_sl, dev);
device_add(&pssj_device);
device_add(&eep_1000sl2_device);

View File

@@ -14678,7 +14678,7 @@ const machine_t machines[] = {
/* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC
firmware. */
{
.name = "[SMSC VictoryBX-66] A-Trend ATC-6310BXII",
.name = "[SMSC VictoryBX-66] A-Trend ATC6310BXII",
.internal_name = "atc6310bxii",
.type = MACHINE_TYPE_SLOT1,
.chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66,
@@ -15397,7 +15397,7 @@ const machine_t machines[] = {
/* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC
firmware. */
{
.name = "[SMSC VictoryBX-66] A-Trend ATC-7020BXII",
.name = "[SMSC VictoryBX-66] A-Trend ATC7020BXII",
.internal_name = "atc7020bxii",
.type = MACHINE_TYPE_SOCKET370,
.chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66,

View File

@@ -1638,7 +1638,7 @@ nic_init(const device_t *info)
s->pci_conf[0x04] = 7;
/* Enable our BIOS space in PCI, if needed. */
if (s->bios_addr > 0) {
if (s->has_bios) {
rom_init(&s->bios_rom, ROM_PATH_DEC21140, s->bios_addr, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
tulip_pci_bar[2].addr = 0xffff0000;
} else

View File

@@ -227,6 +227,10 @@ if(WIN32 AND NOT MINGW)
target_sources(plat PRIVATE win_opendir.c)
endif()
if(WIN32 AND NOT CPPTHREADS)
target_sources(plat PRIVATE win_thread.c)
endif()
if(WIN32)
target_sources(plat PRIVATE win_serial_passthrough.c win_netsocket.c)
else()

View File

@@ -24,8 +24,15 @@
extern "C" {
#include <86box/timer.h>
#include <86box/cdrom.h>
#include <86box/device.h>
#include <86box/cassette.h>
#include <86box/cartridge.h>
#include <86box/fdd.h>
#include <86box/cdrom.h>
#include <86box/scsi_device.h>
#include <86box/zip.h>
#include <86box/mo.h>
#include <86box/path.h>
}
namespace ui {
@@ -100,7 +107,14 @@ MediaHistoryManager::getImageForSlot(int index, int slot, ui::MediaType type)
int
MediaHistoryManager::maxDevicesSupported(ui::MediaType type)
{
return type == ui::MediaType::Cassette ? 1 : 4;
switch (type) {
default:
return 4;
case ui::MediaType::Cassette:
return 1;
case ui::MediaType::Cartridge:
return 2;
}
}
void
@@ -163,14 +177,26 @@ MediaHistoryManager::initialDeduplication()
for (int device_index = 0; device_index < maxDevicesSupported(device_type); device_index++) {
device_index_list_t device_history = getHistoryListForDeviceIndex(device_index, device_type);
switch (device_type) {
case ui::MediaType::Optical:
current_image = cdrom[device_index].image_path;
default:
continue;
break;
case ui::MediaType::Cassette:
current_image = cassette_fname;
break;
case ui::MediaType::Cartridge:
current_image = cart_fns[device_index];
break;
case ui::MediaType::Floppy:
current_image = floppyfns[device_index];
break;
default:
continue;
case ui::MediaType::Optical:
current_image = cdrom[device_index].image_path;
break;
case ui::MediaType::Zip:
current_image = zip_drives[device_index].image_path;
break;
case ui::MediaType::Mo:
current_image = mo_drives[device_index].image_path;
break;
}
deduplicateList(device_history, QVector<QString>(1, current_image));
@@ -190,12 +216,20 @@ char **
MediaHistoryManager::getEmuHistoryVarForType(ui::MediaType type, int index)
{
switch (type) {
case ui::MediaType::Optical:
return &cdrom[index].image_history[0];
case ui::MediaType::Floppy:
return &fdd_image_history[index][0];
default:
return nullptr;
case ui::MediaType::Cassette:
return &cassette_image_history[0];
case ui::MediaType::Cartridge:
return &cart_image_history[index][0];
case ui::MediaType::Floppy:
return &fdd_image_history[index][0];
case ui::MediaType::Optical:
return &cdrom[index].image_history[0];
case ui::MediaType::Zip:
return &zip_drives[index].image_history[0];
case ui::MediaType::Mo:
return &mo_drives[index].image_history[0];
}
}
@@ -275,9 +309,6 @@ MediaHistoryManager::pathAdjustSingle(QString checked_path)
if (file_info.filePath().isEmpty() || current_usr_path.isEmpty() || file_info.isRelative()) {
return checked_path;
}
if (file_info.filePath().startsWith(current_usr_path)) {
checked_path = file_info.filePath().remove(current_usr_path);
}
return checked_path;
}
@@ -304,10 +335,25 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history)
if (file_info.filePath().isEmpty()) {
continue;
}
// For this check, explicitly prepend `usr_path` to relative paths to account for $CWD platform variances
QFileInfo absolute_path = file_info.isRelative() ? QFileInfo(getUsrPath().append(file_info.filePath())) : file_info;
if ((file_info.filePath().left(8) != "ioctl://") && !absolute_path.exists()) {
qWarning("Image file %s does not exist - removing from history", qPrintable(file_info.filePath()));
char *p = checked_path.toUtf8().data();
char temp[1024] = { 0 };
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("removeMissingImages(): strlen(p) > 2047\n");
else
snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s", p);
} else
snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
path_get_slash(usr_path), p);
path_normalize(temp);
QString qstr = QString::fromUtf8(temp);
QFileInfo new_fi(qstr);
if ((new_fi.filePath().left(8) != "ioctl://") && !new_fi.exists()) {
qWarning("Image file %s does not exist - removing from history", qPrintable(new_fi.filePath()));
checked_path = "";
}
}

View File

@@ -47,7 +47,8 @@ enum class MediaType {
Optical,
Zip,
Mo,
Cassette
Cassette,
Cartridge
};
// This macro allows us to do a reverse lookup of the enum with `QMetaEnum`
Q_ENUM_NS(MediaType)
@@ -61,6 +62,10 @@ typedef QHash<ui::MediaType, device_media_history_t> master_list_t;
static const MediaType AllSupportedMediaHistoryTypes[] = {
MediaType::Optical,
MediaType::Floppy,
MediaType::Zip,
MediaType::Mo,
MediaType::Cassette,
MediaType::Cartridge
};
class MediaHistoryManager {

View File

@@ -91,6 +91,11 @@ MediaMenu::refresh(QMenu *parentMenu)
cassetteMenu->addAction(tr("&Existing image..."), [this]() { cassetteSelectImage(false); });
cassetteMenu->addAction(tr("Existing image (&Write-protected)..."), [this]() { cassetteSelectImage(true); });
cassetteMenu->addSeparator();
for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) {
cassetteImageHistoryPos[slot] = cassetteMenu->children().count();
cassetteMenu->addAction(QString::asprintf(tr("Image %i").toUtf8().constData(), slot), [this, slot]() { cassetteMenuSelect(slot); })->setCheckable(false);
}
cassetteMenu->addSeparator();
cassetteRecordPos = cassetteMenu->children().count();
cassetteMenu->addAction(tr("&Record"), [this] { pc_cas_set_mode(cassette, 1); cassetteUpdateMenu(); })->setCheckable(true);
cassettePlayPos = cassetteMenu->children().count();
@@ -111,6 +116,11 @@ MediaMenu::refresh(QMenu *parentMenu)
auto *menu = parentMenu->addMenu("");
menu->addAction(tr("&Image..."), [this, i]() { cartridgeSelectImage(i); });
menu->addSeparator();
for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) {
cartridgeImageHistoryPos[slot] = menu->children().count();
menu->addAction(QString::asprintf(tr("Image %i").toUtf8().constData(), slot), [this, i, slot]() { cartridgeMenuSelect(i, slot); })->setCheckable(false);
}
menu->addSeparator();
cartridgeEjectPos = menu->children().count();
menu->addAction(tr("E&ject"), [this, i]() { cartridgeEject(i); });
cartridgeMenus[i] = menu;
@@ -179,10 +189,13 @@ MediaMenu::refresh(QMenu *parentMenu)
menu->addAction(tr("&Existing image..."), [this, i]() { zipSelectImage(i, false); });
menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { zipSelectImage(i, true); });
menu->addSeparator();
for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) {
zipImageHistoryPos[slot] = menu->children().count();
menu->addAction(QString::asprintf(tr("Image %i").toUtf8().constData(), slot), [this, i, slot]() { zipReload(i, slot); })->setCheckable(false);
}
menu->addSeparator();
zipEjectPos = menu->children().count();
menu->addAction(tr("E&ject"), [this, i]() { zipEject(i); });
zipReloadPos = menu->children().count();
menu->addAction(tr("&Reload previous image"), [this, i]() { zipReload(i); });
zipMenus[i] = menu;
zipUpdateMenu(i);
});
@@ -195,10 +208,13 @@ MediaMenu::refresh(QMenu *parentMenu)
menu->addAction(tr("&Existing image..."), [this, i]() { moSelectImage(i, false); });
menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { moSelectImage(i, true); });
menu->addSeparator();
for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) {
moImageHistoryPos[slot] = menu->children().count();
menu->addAction(QString::asprintf(tr("Image %i").toUtf8().constData(), slot), [this, i, slot]() { moReload(i, slot); })->setCheckable(false);
}
menu->addSeparator();
moEjectPos = menu->children().count();
menu->addAction(tr("E&ject"), [this, i]() { moEject(i); });
moReloadPos = menu->children().count();
menu->addAction(tr("&Reload previous image"), [this, i]() { moReload(i); });
moMenus[i] = menu;
moUpdateMenu(i);
});
@@ -243,9 +259,19 @@ MediaMenu::cassetteSelectImage(bool wp)
cassetteMount(filename, wp);
}
void
MediaMenu::cassetteMenuSelect(int slot)
{
QString filename = mhm.getImageForSlot(0, slot, ui::MediaType::Cassette);
cassetteMount(filename.toUtf8().constData(), 0);
cassetteUpdateMenu();
ui_sb_update_tip(SB_CASSETTE);
}
void
MediaMenu::cassetteMount(const QString &filename, bool wp)
{
auto previous_image = QFileInfo(cassette_fname);
pc_cas_set_fname(cassette, nullptr);
memset(cassette_fname, 0, sizeof(cassette_fname));
cassette_ui_writeprot = wp ? 1 : 0;
@@ -257,6 +283,7 @@ MediaMenu::cassetteMount(const QString &filename, bool wp)
}
ui_sb_update_icon_state(SB_CASSETTE, filename.isEmpty() ? 1 : 0);
mhm.addImageToHistory(0, ui::MediaType::Cassette, previous_image.filePath(), filename);
cassetteUpdateMenu();
ui_sb_update_tip(SB_CASSETTE);
config_save();
@@ -265,6 +292,7 @@ MediaMenu::cassetteMount(const QString &filename, bool wp)
void
MediaMenu::cassetteEject()
{
mhm.addImageToHistory(0, ui::MediaType::Cassette, cassette_fname, QString());
pc_cas_set_fname(cassette, nullptr);
memset(cassette_fname, 0, sizeof(cassette_fname));
ui_sb_update_icon_state(SB_CASSETTE, 1);
@@ -297,16 +325,22 @@ MediaMenu::cassetteUpdateMenu()
cassetteMenu->setTitle(QString::asprintf(tr("Cassette: %s").toUtf8().constData(),
(name.isEmpty() ? tr("(empty)") : name).toUtf8().constData()));
for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) {
updateImageHistory(0, slot, ui::MediaType::Cassette);
}
}
void
MediaMenu::cartridgeMount(int i, const QString &filename)
{
auto previous_image = QFileInfo(cart_fns[i]);
cart_close(i);
QByteArray filenameBytes = filename.toUtf8();
cart_load(i, filenameBytes.data());
ui_sb_update_icon_state(SB_CARTRIDGE | i, filename.isEmpty() ? 1 : 0);
mhm.addImageToHistory(i, ui::MediaType::Cartridge, previous_image.filePath(), filename);
cartridgeUpdateMenu(i);
ui_sb_update_tip(SB_CARTRIDGE | i);
config_save();
@@ -327,9 +361,19 @@ MediaMenu::cartridgeSelectImage(int i)
cartridgeMount(i, filename);
}
void
MediaMenu::cartridgeMenuSelect(int index, int slot)
{
QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Cartridge);
cartridgeMount(index, filename.toUtf8().constData());
cartridgeUpdateMenu(index);
ui_sb_update_tip(SB_CARTRIDGE | index);
}
void
MediaMenu::cartridgeEject(int i)
{
mhm.addImageToHistory(i, ui::MediaType::Cartridge, cart_fns[i], QString());
cart_close(i);
ui_sb_update_icon_state(SB_CARTRIDGE | i, 1);
cartridgeUpdateMenu(i);
@@ -347,6 +391,10 @@ MediaMenu::cartridgeUpdateMenu(int i)
ejectMenu->setEnabled(!name.isEmpty());
// menu->setTitle(tr("Cartridge %1: %2").arg(QString::number(i+1), name.isEmpty() ? tr("(empty)") : name));
menu->setTitle(QString::asprintf(tr("Cartridge %i: %ls").toUtf8().constData(), i + 1, name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data()));
for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) {
updateImageHistory(i, slot, ui::MediaType::Cartridge);
}
}
void
@@ -580,6 +628,36 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type)
QString menu_item_name;
switch (type) {
default:
menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData();
return;
case ui::MediaType::Cassette:
if (!MachineStatus::hasCassette())
return;
menu = cassetteMenu;
children = menu->children();
imageHistoryUpdatePos = dynamic_cast<QAction *>(children[cassetteImageHistoryPos[slot]]);
fi.setFile(fn);
menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData();
break;
case ui::MediaType::Cartridge:
if (!machine_has_cartridge(machine))
return;
menu = cartridgeMenus[index];
children = menu->children();
imageHistoryUpdatePos = dynamic_cast<QAction *>(children[cartridgeImageHistoryPos[slot]]);
fi.setFile(fn);
menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData();
break;
case ui::MediaType::Floppy:
if (!floppyMenus.contains(index))
return;
menu = floppyMenus[index];
children = menu->children();
imageHistoryUpdatePos = dynamic_cast<QAction *>(children[floppyImageHistoryPos[slot]]);
fi.setFile(fn);
menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData();
break;
case ui::MediaType::Optical:
if (!cdromMenus.contains(index))
return;
@@ -600,18 +678,24 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type)
}
imageHistoryUpdatePos->setIcon(menu_icon);
break;
case ui::MediaType::Floppy:
if (!floppyMenus.contains(index))
case ui::MediaType::Zip:
if (!zipMenus.contains(index))
return;
menu = floppyMenus[index];
menu = zipMenus[index];
children = menu->children();
imageHistoryUpdatePos = dynamic_cast<QAction *>(children[floppyImageHistoryPos[slot]]);
imageHistoryUpdatePos = dynamic_cast<QAction *>(children[zipImageHistoryPos[slot]]);
fi.setFile(fn);
menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData();
break;
default:
case ui::MediaType::Mo:
if (!moMenus.contains(index))
return;
menu = moMenus[index];
children = menu->children();
imageHistoryUpdatePos = dynamic_cast<QAction *>(children[moImageHistoryPos[slot]]);
fi.setFile(fn);
menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData();
return;
break;
}
imageHistoryUpdatePos->setText(QString::asprintf(tr("%s").toUtf8().constData(), menu_item_name.toUtf8().constData()));
@@ -727,6 +811,7 @@ MediaMenu::zipMount(int i, const QString &filename, bool wp)
zip_load(dev, filenameBytes.data());
zip_insert(dev);
}
mhm.addImageToHistory(i, ui::MediaType::Zip, zip_drives[i].prev_image_path, zip_drives[i].image_path);
ui_sb_update_icon_state(SB_ZIP | i, filename.isEmpty() ? 1 : 0);
zipUpdateMenu(i);
@@ -740,6 +825,7 @@ MediaMenu::zipEject(int i)
{
const auto dev = static_cast<zip_t *>(zip_drives[i].priv);
mhm.addImageToHistory(i, ui::MediaType::Zip, zip_drives[i].image_path, QString());
zip_disk_close(dev);
zip_drives[i].image_path[0] = 0;
if (zip_drives[i].bus_type) {
@@ -754,7 +840,7 @@ MediaMenu::zipEject(int i)
}
void
MediaMenu::zipReload(int i)
MediaMenu::zipReloadPrev(int i)
{
const auto dev = static_cast<zip_t *>(zip_drives[i].priv);
@@ -771,6 +857,15 @@ MediaMenu::zipReload(int i)
config_save();
}
void
MediaMenu::zipReload(int index, int slot)
{
const QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Zip);
zipMount(index, filename, false);
zipUpdateMenu(index);
ui_sb_update_tip(SB_ZIP | index);
}
void
MediaMenu::zipUpdateMenu(int i)
{
@@ -800,6 +895,9 @@ MediaMenu::zipUpdateMenu(int i)
// menu->setTitle(tr("ZIP %1 %2 (%3): %4").arg((zip_drives[i].is_250 > 0) ? "250" : "100", QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name));
menu->setTitle(QString::asprintf(tr("ZIP %03i %i (%s): %ls").toUtf8().constData(), (zip_drives[i].is_250 > 0) ? 250 : 100, i + 1, busName.toUtf8().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data()));
for (int slot = 0; slot < MAX_PREV_IMAGES; slot++)
updateImageHistory(i, slot, ui::MediaType::Zip);
}
void
@@ -844,6 +942,7 @@ MediaMenu::moMount(int i, const QString &filename, bool wp)
mo_load(dev, filenameBytes.data());
mo_insert(dev);
}
mhm.addImageToHistory(i, ui::MediaType::Mo, mo_drives[i].prev_image_path, mo_drives[i].image_path);
ui_sb_update_icon_state(SB_MO | i, filename.isEmpty() ? 1 : 0);
moUpdateMenu(i);
@@ -857,6 +956,7 @@ MediaMenu::moEject(int i)
{
const auto dev = static_cast<mo_t *>(mo_drives[i].priv);
mhm.addImageToHistory(i, ui::MediaType::Mo, mo_drives[i].image_path, QString());
mo_disk_close(dev);
mo_drives[i].image_path[0] = 0;
if (mo_drives[i].bus_type) {
@@ -871,7 +971,7 @@ MediaMenu::moEject(int i)
}
void
MediaMenu::moReload(int i)
MediaMenu::moReloadPrev(int i)
{
mo_t *dev = (mo_t *) mo_drives[i].priv;
@@ -888,6 +988,15 @@ MediaMenu::moReload(int i)
config_save();
}
void
MediaMenu::moReload(int index, int slot)
{
const QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Mo);
moMount(index, filename, false);
moUpdateMenu(index);
ui_sb_update_tip(SB_MO | index);
}
void
MediaMenu::moUpdateMenu(int i)
{
@@ -916,6 +1025,9 @@ MediaMenu::moUpdateMenu(int i)
}
menu->setTitle(QString::asprintf(tr("MO %i (%ls): %ls").toUtf8().constData(), i + 1, busName.toStdU16String().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data()));
for (int slot = 0; slot < MAX_PREV_IMAGES; slot++)
updateImageHistory(i, slot, ui::MediaType::Mo);
}
void
@@ -1043,7 +1155,7 @@ zip_mount(uint8_t id, char *fn, uint8_t wp)
void
zip_reload(uint8_t id)
{
MediaMenu::ptr->zipReload(id);
MediaMenu::ptr->zipReloadPrev(id);
}
void
@@ -1061,6 +1173,6 @@ mo_mount(uint8_t id, char *fn, uint8_t wp)
void
mo_reload(uint8_t id)
{
MediaMenu::ptr->moReload(id);
MediaMenu::ptr->moReloadPrev(id);
}
}

View File

@@ -24,12 +24,14 @@ public:
void cassetteNewImage();
void cassetteSelectImage(bool wp);
void cassetteMount(const QString &filename, bool wp);
void cassetteMenuSelect(int slot);
void cassetteEject();
void cassetteUpdateMenu();
void cartridgeSelectImage(int i);
void cartridgeMount(int i, const QString &filename);
void cartridgeEject(int i);
void cartridgeMenuSelect(int index, int slot);
void cartridgeUpdateMenu(int i);
void floppyNewImage(int i);
@@ -53,14 +55,16 @@ public:
void zipSelectImage(int i, bool wp);
void zipMount(int i, const QString &filename, bool wp);
void zipEject(int i);
void zipReload(int i);
void zipReloadPrev(int i);
void zipReload(int index, int slot);
void zipUpdateMenu(int i);
void moNewImage(int i);
void moSelectImage(int i, bool wp);
void moMount(int i, const QString &filename, bool wp);
void moEject(int i);
void moReload(int i);
void moReloadPrev(int i);
void moReload(int index, int slot);
void moUpdateMenu(int i);
void nicConnect(int i);
@@ -94,24 +98,28 @@ private:
int cassetteRewindPos;
int cassetteFastFwdPos;
int cassetteEjectPos;
int cassetteImageHistoryPos[MAX_PREV_IMAGES];
int cartridgeEjectPos;
int cartridgeImageHistoryPos[MAX_PREV_IMAGES];
int floppyExportPos;
int floppyEjectPos;
int floppyImageHistoryPos[MAX_PREV_IMAGES];
int cdromMutePos;
int cdromReloadPos;
int cdromImagePos;
int cdromDirPos;
int cdromImageHistoryPos[MAX_PREV_IMAGES];
int floppyImageHistoryPos[MAX_PREV_IMAGES];
int zipEjectPos;
int zipReloadPos;
int zipImageHistoryPos[MAX_PREV_IMAGES];
int moEjectPos;
int moReloadPos;
int moImageHistoryPos[MAX_PREV_IMAGES];
int netDisconnPos;

View File

@@ -9219,18 +9219,19 @@ s3_pci_read(UNUSED(int func), int addr, void *priv)
return s3->pci_regs[PCI_REG_COMMAND] | 0x80; /*Respond to IO and memory accesses*/
else
return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/
break;
break;
case 0x07:
return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x07] & 0x36) : (1 << 1); /*Medium DEVSEL timing*/
case 0x08: switch (s3->chip) { /*Revision ID*/
case S3_TRIO64V:
return 0x40;
case S3_TRIO64V2:
return 0x16; /*Confirmed on an onboard 64V2/DX*/
default:
return 0x00;
case 0x08:
switch (s3->chip) { /*Revision ID*/
case S3_TRIO64V:
return 0x40;
case S3_TRIO64V2:
return 0x16; /*Confirmed on an onboard 64V2/DX*/
default:
return 0x00;
}
break;
case 0x09:
@@ -9252,24 +9253,13 @@ s3_pci_read(UNUSED(int func), int addr, void *priv)
case 0x0d:
return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x0d] & 0xf8) : 0x00;
case 0x10:
return 0x00; /*Linear frame buffer address*/
case 0x11:
return 0x00;
case 0x12:
if (svga->crtc[0x53] & 0x08)
return 0x00;
else
return (svga->crtc[0x5a] & 0x80);
break;
return ((s3->chip == S3_VISION868) || (s3->chip == S3_VISION968) || (s3->chip >= S3_TRIO64V)) ? 0x00 :
(svga->crtc[0x5a] & 0x80);
case 0x13:
if (svga->crtc[0x53] & 0x08) {
return (s3->chip >= S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe);
} else {
return svga->crtc[0x59];
}
break;
return ((s3->chip == S3_VISION868) || (s3->chip == S3_VISION968) || (s3->chip >= S3_TRIO64V)) ?
(svga->crtc[0x59] & 0xfc) : svga->crtc[0x59];
case 0x30:
return s3->has_bios ? (s3->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/
@@ -9323,13 +9313,16 @@ s3_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
s3_io_set(s3);
else
s3_io_remove(s3);
s3->pci_regs[PCI_REG_COMMAND] = (val & 0x23);
if (s3->chip >= S3_TRIO64V)
s3->pci_regs[PCI_REG_COMMAND] = (val & 0x27);
else
s3->pci_regs[PCI_REG_COMMAND] = (val & 0x23);
s3_updatemapping(s3);
break;
case 0x07:
if (s3->chip == S3_TRIO64V2) {
s3->pci_regs[0x07] = val & 0x3e;
s3->pci_regs[0x07] &= ~(val & 0x30);
return;
}
break;
@@ -9342,18 +9335,14 @@ s3_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
break;
case 0x12:
if (!(svga->crtc[0x53] & 0x08)) {
svga->crtc[0x5a] = (svga->crtc[0x5a] & 0x7f) | (val & 0x80);
if (s3->chip < S3_TRIO64V) {
svga->crtc[0x5a] = val & 0x80;
s3_updatemapping(s3);
}
break;
case 0x13:
if (svga->crtc[0x53] & 0x08) {
svga->crtc[0x59] = (s3->chip >= S3_TRIO64V) ? (val & 0xfc) : (val & 0xfe);
} else {
svga->crtc[0x59] = val;
}
svga->crtc[0x59] = (s3->chip >= S3_TRIO64V) ? (val & 0xfc) : val;
s3_updatemapping(s3);
break;

View File

@@ -61,6 +61,7 @@ static int dither[4][4] = {
#define ROM_VIRGE_325 "roms/video/s3virge/86c325.bin"
#define ROM_DIAMOND_STEALTH3D_2000 "roms/video/s3virge/s3virge.bin"
#define ROM_MIROCRYSTAL_3D "roms/video/s3virge/miro Crystal 3D 1.02.bin"
#define ROM_DIAMOND_STEALTH3D_3000 "roms/video/s3virge/diamondstealth3000.vbi"
#define ROM_STB_VELOCITY_3D "roms/video/s3virge/stb_velocity3d_110.BIN"
#define ROM_VIRGE_DX "roms/video/s3virge/86c375_1.bin"
@@ -91,6 +92,7 @@ static int dither[4][4] = {
enum {
S3_VIRGE_325,
S3_DIAMOND_STEALTH3D_2000,
S3_MIROCRYSTAL_3D,
S3_DIAMOND_STEALTH3D_3000,
S3_STB_VELOCITY_3D,
S3_VIRGE_DX,
@@ -865,7 +867,7 @@ s3_virge_recalctimings(svga_t *svga)
video_force_resize_set_monitor(1, svga->monitor_index);
}
if (((svga->crtc[0x67] & 0xc) != 0xc) || (virge->chip >= S3_VIRGEGX2)) { /*VGA mode*/
if ((svga->crtc[0x67] & 0xc) != 0xc) { /*VGA mode*/
svga->ma_latch |= (virge->ma_ext << 16);
if (svga->crtc[0x51] & 0x30)
svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4;
@@ -896,7 +898,7 @@ s3_virge_recalctimings(svga_t *svga)
case 24:
svga->render = svga_render_24bpp_highres;
if ((virge->chip != S3_VIRGEVX) && (virge->chip < S3_VIRGEGX2))
svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/
svga->rowoffset = (svga->rowoffset * 3) >> 2; /*Hack*/
break;
case 32:
svga->render = svga_render_32bpp_highres;
@@ -908,37 +910,32 @@ s3_virge_recalctimings(svga_t *svga)
svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) &&
(svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask;
svga->overlay.ena = 0;
if (virge->chip >= S3_VIRGEGX2 && (svga->crtc[0x67] & 0xc) == 0xc) {
/* ViRGE/GX2 and later does not use primary stream registers. */
svga->overlay.x = virge->streams.sec_x;
svga->overlay.y = virge->streams.sec_y;
svga->overlay.cur_ysize = virge->streams.sec_h;
if (virge->streams.buffer_ctrl & 2)
svga->overlay.addr = virge->streams.sec_fb1;
else
svga->overlay.addr = virge->streams.sec_fb0;
svga->overlay.ena = (svga->overlay.x >= 0) && !!(virge->streams.blend_ctrl & 0x20);
svga->overlay.v_acc = virge->streams.dda_vert_accumulator;
svga->rowoffset = virge->streams.pri_stride >> 3;
svga->vram_display_mask = virge->vram_mask;
}
} else { /*Streams mode*/
if (virge->streams.buffer_ctrl & 1)
svga->ma_latch = virge->streams.pri_fb1 >> 2;
else
svga->ma_latch = virge->streams.pri_fb0 >> 2;
if (virge->chip < S3_VIRGEGX2) {
if (virge->streams.buffer_ctrl & 1)
svga->ma_latch = virge->streams.pri_fb1 >> 2;
else
svga->ma_latch = virge->streams.pri_fb0 >> 2;
svga->hdisp = virge->streams.pri_w + 1;
if (virge->streams.pri_h < svga->dispend)
svga->dispend = virge->streams.pri_h;
svga->hdisp = virge->streams.pri_w + 1;
if (virge->streams.pri_h < svga->dispend)
svga->dispend = virge->streams.pri_h;
svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x;
svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y;
} else {
svga->ma_latch |= (virge->ma_ext << 16);
if (svga->crtc[0x51] & 0x30)
svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4;
else if (svga->crtc[0x43] & 0x04)
svga->rowoffset |= 0x100;
if (!svga->rowoffset)
svga->rowoffset = 256;
svga->overlay.x = virge->streams.sec_x;
svga->overlay.y = virge->streams.sec_y;
}
svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x;
svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y;
svga->overlay.cur_ysize = virge->streams.sec_h;
if (virge->streams.buffer_ctrl & 2)
@@ -947,35 +944,60 @@ s3_virge_recalctimings(svga_t *svga)
svga->overlay.addr = virge->streams.sec_fb0;
svga->overlay.ena = (svga->overlay.x >= 0);
svga->overlay.h_acc = virge->streams.dda_horiz_accumulator;
svga->overlay.v_acc = virge->streams.dda_vert_accumulator;
svga->rowoffset = virge->streams.pri_stride >> 3;
if (virge->chip < S3_VIRGEGX2)
svga->rowoffset = virge->streams.pri_stride >> 3;
if (virge->chip <= S3_VIRGEDX && svga->overlay.ena) {
svga->overlay.ena = (((virge->streams.blend_ctrl >> 24) & 7) == 0b000) ||
(((virge->streams.blend_ctrl >> 24) & 7) == 0b101);
} else if (virge->chip == S3_VIRGEGX2 && svga->overlay.ena) {
} else if (virge->chip >= S3_VIRGEGX2 && svga->overlay.ena) {
/* 0x20 = Secondary Stream enabled */
/* 0x2000 = Primary Stream enabled */
svga->overlay.ena = !!(virge->streams.blend_ctrl & 0x20);
}
switch ((virge->streams.pri_ctrl >> 24) & 0x7) {
case 0: /*RGB-8 (CLUT)*/
svga->render = svga_render_8bpp_highres;
break;
case 3: /*KRGB-16 (1.5.5.5)*/
svga->render = svga_render_15bpp_highres;
break;
case 5: /*RGB-16 (5.6.5)*/
svga->render = svga_render_16bpp_highres;
break;
case 6: /*RGB-24 (8.8.8)*/
svga->render = svga_render_24bpp_highres;
break;
case 7: /*XRGB-32 (X.8.8.8)*/
svga->render = svga_render_32bpp_highres;
break;
if (virge->chip >= S3_VIRGEGX2) {
switch (svga->bpp) {
case 8:
svga->render = svga_render_8bpp_highres;
break;
case 15:
svga->render = svga_render_15bpp_highres;
break;
case 16:
svga->render = svga_render_16bpp_highres;
break;
case 24:
svga->render = svga_render_24bpp_highres;
break;
case 32:
svga->render = svga_render_32bpp_highres;
break;
default:
break;
}
} else {
switch ((virge->streams.pri_ctrl >> 24) & 0x7) {
case 0: /*RGB-8 (CLUT)*/
svga->render = svga_render_8bpp_highres;
break;
case 3: /*KRGB-16 (1.5.5.5)*/
svga->render = svga_render_15bpp_highres;
break;
case 5: /*RGB-16 (5.6.5)*/
svga->render = svga_render_16bpp_highres;
break;
case 6: /*RGB-24 (8.8.8)*/
svga->render = svga_render_24bpp_highres;
break;
case 7: /*XRGB-32 (X.8.8.8)*/
svga->render = svga_render_32bpp_highres;
break;
}
}
svga->vram_display_mask = virge->vram_mask;
}
@@ -988,29 +1010,6 @@ s3_virge_recalctimings(svga_t *svga)
svga->render = svga_render_2bpp_s3_highres;
}
static void
s3_virge_update_buffer(virge_t *virge)
{
svga_t *svga = &virge->svga;
if ((svga->crtc[0x67] & 0xc) != 0xc)
return;
if (virge->chip < S3_VIRGEGX2) {
if (virge->streams.buffer_ctrl & 1)
svga->ma_latch = virge->streams.pri_fb1 >> 2;
else
svga->ma_latch = virge->streams.pri_fb0 >> 2;
}
if (virge->streams.buffer_ctrl & 2)
svga->overlay.addr = virge->streams.sec_fb1;
else
svga->overlay.addr = virge->streams.sec_fb0;
svga->rowoffset = virge->streams.pri_stride >> 3;
}
static void
s3_virge_updatemapping(virge_t *virge) {
svga_t *svga = &virge->svga;
@@ -1842,39 +1841,46 @@ s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type)
}
static void
s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv) {
s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv)
{
virge_t *virge = (virge_t *) priv;
if ((addr & 0xffff) < 0x8000)
s3_virge_queue(virge, addr, val, FIFO_WRITE_BYTE);
else switch (addr & 0xffff) {
case 0x83b0 ... 0x83df:
s3_virge_out(addr & 0x3ff, val, priv);
break;
else {
switch (addr & 0xffff) {
default:
case 0x83b0 ... 0x83df:
s3_virge_out(addr & 0x3ff, val, priv);
break;
case 0xff20:
virge->serialport = val;
i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW));
break;
case 0xff20:
virge->serialport = val;
i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW));
break;
}
}
}
static void
s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv) {
s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv)
{
virge_t *virge = (virge_t *) priv;
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);
break;
else {
switch (addr & 0xfffe) {
default:
case 0x83d4:
s3_virge_mmio_write(addr, val, priv);
s3_virge_mmio_write(addr + 1, val >> 8, priv);
break;
case 0xff20:
s3_virge_mmio_write(addr, val, priv);
break;
case 0xff20:
s3_virge_mmio_write(addr, val, priv);
break;
}
}
}
@@ -1900,8 +1906,9 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
case 0x8190:
virge->streams.sec_ctrl = val;
virge->streams.dda_horiz_accumulator = val & 0xfff;
if (val & (1 << 11))
virge->streams.dda_horiz_accumulator |= 0xfffff800;
if (val & 0x1000)
virge->streams.dda_horiz_accumulator |= ~0xfff;
virge->streams.sdif = (val >> 24) & 7;
break;
case 0x8194:
@@ -1910,50 +1917,56 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
case 0x8198:
virge->streams.sec_filter = val;
virge->streams.k1_horiz_scale = val & 0x7ff;
if (val & (1 << 10))
virge->streams.k1_horiz_scale |= 0xfffff800;
if (val & 0x800)
virge->streams.k1_horiz_scale |= ~0x7ff;
virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff;
if ((val >> 16) & (1 << 10))
virge->streams.k2_horiz_scale |= 0xfffff800;
if ((val >> 16) & 0x800)
virge->streams.k2_horiz_scale |= ~0x7ff;
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81a0:
virge->streams.blend_ctrl = val;
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81c0:
virge->streams.pri_fb0 = val & ((virge->memory_size == 8) ?
(val & 0x7fffff) : (val & 0x3fffff));
s3_virge_update_buffer(virge);
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81c4:
virge->streams.pri_fb1 = ((virge->memory_size == 8) ?
(val & 0x7fffff) : (val & 0x3fffff));
s3_virge_update_buffer(virge);
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81c8:
virge->streams.pri_stride = val & 0xfff;
s3_virge_update_buffer(virge);
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81cc:
virge->streams.buffer_ctrl = val;
s3_virge_update_buffer(virge);
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81d0:
virge->streams.sec_fb0 = val;
s3_virge_update_buffer(virge);
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81d4:
virge->streams.sec_fb1 = val;
s3_virge_update_buffer(virge);
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81d8:
virge->streams.sec_stride = val;
s3_virge_update_buffer(virge);
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81dc:
@@ -1961,18 +1974,21 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
break;
case 0x81e0:
virge->streams.k1_vert_scale = val & 0x7ff;
if (val & (1 << 10))
virge->streams.k1_vert_scale |= 0xfffff800;
if (val & 0x800)
virge->streams.k1_vert_scale |= ~0x7ff;
break;
case 0x81e4:
virge->streams.k2_vert_scale = val & 0x7ff;
if (val & (1 << 10))
virge->streams.k2_vert_scale |= 0xfffff800;
if (val & 0x800)
virge->streams.k2_vert_scale |= ~0x7ff;
break;
case 0x81e8:
virge->streams.dda_vert_accumulator = val & 0xfff;
if (val & (1 << 11))
virge->streams.dda_vert_accumulator |= 0xfffff800;
if (val & 0x1000)
virge->streams.dda_vert_accumulator |= ~0xfff;
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81ec:
virge->streams.fifo_ctrl = val;
@@ -3966,10 +3982,10 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) {
} while (0)
static void
s3_virge_overlay_draw(svga_t *svga, int displine) {
s3_virge_overlay_draw(svga_t *svga, int displine)
{
virge_t *virge = (virge_t *) svga->priv;
int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1;
int h_acc = virge->streams.dda_horiz_accumulator;
int offset;
int r[8];
int g[8];
int b[8];
@@ -3980,11 +3996,19 @@ s3_virge_overlay_draw(svga_t *svga, int displine) {
uint32_t *p;
uint8_t *src = &svga->vram[svga->overlay_latch.addr];
if (virge->chip < S3_VIRGEGX2)
offset = (virge->streams.sec_x - virge->streams.pri_x) + 1;
else
offset = virge->streams.sec_x + 1;
p = &((uint32_t *)buffer32->line[displine])[offset + svga->x_add];
if ((offset + virge->streams.sec_w) > virge->streams.pri_w)
x_size = (virge->streams.pri_w - virge->streams.sec_x) + 1;
else
if (virge->chip < S3_VIRGEGX2) {
if ((offset + virge->streams.sec_w) > virge->streams.pri_w)
x_size = (virge->streams.pri_w - virge->streams.sec_x) + 1;
else
x_size = virge->streams.sec_w + 1;
} else
x_size = virge->streams.sec_w + 1;
OVERLAY_SAMPLE();
@@ -3992,13 +4016,14 @@ s3_virge_overlay_draw(svga_t *svga, int displine) {
for (x = 0; x < x_size; x++) {
*p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16);
h_acc += virge->streams.k1_horiz_scale;
if (h_acc >= 0) {
svga->overlay_latch.h_acc += virge->streams.k1_horiz_scale;
if (svga->overlay_latch.h_acc >= 0) {
if ((x_read ^ (x_read + 1)) & ~3)
OVERLAY_SAMPLE();
x_read = (x_read + 1) & 7;
h_acc += (virge->streams.k2_horiz_scale - virge->streams.k1_horiz_scale);
svga->overlay_latch.h_acc += (virge->streams.k2_horiz_scale - virge->streams.k1_horiz_scale);
}
}
@@ -4203,7 +4228,7 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
s3_virge_updatemapping(virge);
return;
case 0x07:
virge->pci_regs[0x07] = val & 0x3e;
virge->pci_regs[0x07] &= ~(val & 0x30);
return;
case 0x0d:
virge->pci_regs[0x0d] = val & 0xf8;
@@ -4326,6 +4351,9 @@ s3_virge_init(const device_t *info)
case S3_DIAMOND_STEALTH3D_2000:
bios_fn = ROM_DIAMOND_STEALTH3D_2000;
break;
case S3_MIROCRYSTAL_3D:
bios_fn = ROM_MIROCRYSTAL_3D;
break;
case S3_DIAMOND_STEALTH3D_3000:
bios_fn = ROM_DIAMOND_STEALTH3D_3000;
break;
@@ -4420,6 +4448,7 @@ s3_virge_init(const device_t *info)
switch (info->local) {
case S3_VIRGE_325:
case S3_DIAMOND_STEALTH3D_2000:
case S3_MIROCRYSTAL_3D:
virge->fifo_slots_num = 8;
virge->svga.decode_mask = (4 << 20) - 1;
virge->virge_id_high = 0x56;
@@ -4597,6 +4626,12 @@ s3_virge_325_available(void)
return rom_present(ROM_VIRGE_325);
}
static int
s3_mirocrystal_3d_available(void)
{
return rom_present(ROM_MIROCRYSTAL_3D);
}
static int
s3_virge_988_diamond_available(void)
{
@@ -4844,6 +4879,20 @@ const device_t s3_diamond_stealth_2000_pci_device = {
.config = s3_virge_config
};
const device_t s3_mirocrystal_3d_pci_device = {
.name = "S3 ViRGE (miroCRYSTAL 3D) PCI",
.internal_name = "mirocrystal_3d_pci",
.flags = DEVICE_PCI,
.local = S3_MIROCRYSTAL_3D,
.init = s3_virge_init,
.close = s3_virge_close,
.reset = s3_virge_reset,
{ .available = s3_mirocrystal_3d_available },
.speed_changed = s3_virge_speed_changed,
.force_redraw = s3_virge_force_redraw,
.config = s3_virge_config
};
const device_t s3_diamond_stealth_3000_pci_device = {
.name = "S3 ViRGE/VX (Diamond Stealth 3D 3000) PCI",
.internal_name = "stealth3d_3000_pci",

View File

@@ -174,6 +174,7 @@ video_cards[] = {
{ &s3_trio64v2_dx_pci_device },
{ &s3_virge_325_pci_device },
{ &s3_diamond_stealth_2000_pci_device },
{ &s3_mirocrystal_3d_pci_device },
{ &s3_diamond_stealth_3000_pci_device },
{ &s3_stb_velocity_3d_pci_device },
{ &s3_virge_375_pci_device },