mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 01:48:21 -07:00
Merge branch 'master' into pc98x1
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
101
src/config.c
101
src/config.c
@@ -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)
|
||||
|
||||
@@ -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--;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 },
|
||||
|
||||
Reference in New Issue
Block a user