Merge remote-tracking branch 'upstream/master' into feature/mtrr

This commit is contained in:
Jasmine Iwanek
2023-05-09 15:41:23 -04:00
57 changed files with 2453 additions and 996 deletions

3
.gitignore vendored
View File

@@ -56,3 +56,6 @@ CMakeLists.txt.user
/debian/debhelper-build-stamp
/debian/files
/obj-*-linux-gnu
# MacOS Finder stuff
.DS_Store

View File

@@ -56,6 +56,72 @@
"NEW_DYNAREC": "ON"
},
"inherits": "base"
},
{
"name": "llvm-macos-aarch64.cmake",
"displayName": "MacOS clang regular",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "cmake/llvm-macos-aarch64.cmake",
"NEW_DYNAREC": "ON",
"QT": "ON",
"USE_QT6": "OFF",
"Qt5_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5",
"MOLTENVK_DIR": "/opt/homebrew/opt/molten-vk",
"Qt5LinguistTools_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5LinguistTools",
"OpenAL_ROOT": "/opt/homebrew/opt/openal-soft"
},
"inherits": "regular"
},
{
"name": "llvm-macos-aarch64-debug",
"displayName": "MacOS clang debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "cmake/llvm-macos-aarch64.cmake",
"NEW_DYNAREC": "ON",
"QT": "ON",
"USE_QT6": "OFF",
"Qt5_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5",
"MOLTENVK_DIR": "/opt/homebrew/opt/molten-vk",
"Qt5LinguistTools_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5LinguistTools",
"OpenAL_ROOT": "/opt/homebrew/opt/openal-soft",
"CMAKE_CXX_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG",
"CMAKE_C_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG"
},
"inherits": "debug"
},
{
"name": "flags-gcc-aarch64-debug",
"displayName": "Linux ARM 64 - Debug",
"description": "Linux ARM64 - Debug build",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"NEW_DYNAREC": "ON",
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_TOOLCHAIN_FILE": "cmake/flags-gcc-aarch64.cmake",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}",
"CMAKE_CXX_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG",
"CMAKE_C_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG"
},
"inherits": "debug"
},
{
"name": "flags-gcc-aarch64-regular",
"displayName": "Linux ARM 64 - Regular",
"description": "Linux ARM64 - Release build",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"NEW_DYNAREC": "ON",
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_TOOLCHAIN_FILE": "cmake/flags-gcc-aarch64.cmake",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
},
"inherits": "regular"
}
],
"buildPresets": [],

View File

@@ -59,6 +59,7 @@ typedef struct ali1543_t {
sff8038i_t *ide_controller[2];
smbus_ali7101_t *smbus;
usb_t *usb;
usb_params_t usb_params;
} ali1543_t;
@@ -905,7 +906,12 @@ ali5237_write(int func, int addr, uint8_t val, void *priv)
case 0x0c: /* Cache Line Size */
case 0x0d: /* Latency Timer */
dev->usb_conf[addr] = val;
break;
case 0x3c: /* Interrupt Line Register */
dev->usb_conf[addr] = val;
break;
case 0x42: /* Test Mode Register */
dev->usb_conf[addr] = val & 0x10;
@@ -1424,6 +1430,17 @@ ali7101_read(int func, int addr, void *priv)
return ret;
}
static void
ali5237_usb_update_interrupt(usb_t* usb, void *priv)
{
ali1543_t *dev = (ali1543_t *) priv;
if (usb->irq_level)
pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10));
else
pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10));
}
static void
ali1543_reset(void *priv)
{
@@ -1574,7 +1591,10 @@ ali1543_init(const device_t *info)
dev->smbus = device_add(&ali7101_smbus_device);
/* USB */
dev->usb = device_add(&usb_device);
dev->usb_params.parent_priv = dev;
dev->usb_params.smi_handle = NULL;
dev->usb_params.update_interrupt = ali5237_usb_update_interrupt;
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
dev->type = info->local & 0xff;
dev->offset = (info->local >> 8) & 0x7f;

View File

@@ -77,6 +77,7 @@ typedef struct _piix_ {
piix_io_trap_t io_traps[26];
port_92_t *port_92;
pc_timer_t fast_off_timer;
usb_params_t usb_params;
} piix_t;
#ifdef ENABLE_PIIX_LOG
@@ -1425,6 +1426,17 @@ piix_fast_off_count(void *priv)
dev->regs[0][0xaa] |= 0x20;
}
static void
piix_usb_update_interrupt(usb_t* usb, void *priv)
{
piix_t *dev = (piix_t *) priv;
if (usb->irq_level)
pci_set_irq(dev->pci_slot, PCI_INTD);
else
pci_clear_irq(dev->pci_slot, PCI_INTD);
}
static void
piix_reset(void *p)
{
@@ -1569,8 +1581,12 @@ piix_init(const device_t *info)
sff_set_irq_mode(dev->bm[1], 1, 2);
}
if (dev->type >= 3)
dev->usb = device_add(&usb_device);
if (dev->type >= 3) {
dev->usb_params.parent_priv = dev;
dev->usb_params.smi_handle = NULL;
dev->usb_params.update_interrupt = piix_usb_update_interrupt;
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
}
if (dev->type > 3) {
dev->nvr = device_add(&piix4_nvr_device);

View File

@@ -83,6 +83,8 @@ typedef struct sis_5571_t {
smram_t *smram;
usb_t *usb;
usb_params_t usb_params;
} sis_5571_t;
static void
@@ -638,6 +640,42 @@ pci_isa_bridge_read(int func, int addr, void *priv)
}
}
static void
sis_5571_usb_update_interrupt(usb_t* usb, void* priv)
{
sis_5571_t *dev = (sis_5571_t *) priv;
if (dev->pci_conf_sb[0][0x68] & 0x80) {
/* TODO: Is the normal PCI interrupt inhibited when USB IRQ remapping is enabled? */
switch (dev->pci_conf_sb[0][0x68] & 0x0F) {
case 0x00:
case 0x01:
case 0x02:
case 0x08:
case 0x0d:
break;
default:
if (usb->irq_level)
picint(1 << dev->pci_conf_sb[0][0x68] & 0x0f);
else
picintc(1 << dev->pci_conf_sb[0][0x68] & 0x0f);
break;
}
} else {
if (usb->irq_level)
pci_set_irq(dev->sb_pci_slot, PCI_INTA);
else
pci_clear_irq(dev->sb_pci_slot, PCI_INTA);
}
}
static uint8_t
sis_5571_usb_handle_smi(usb_t* usb, void* priv)
{
/* Left unimplemented for now. */
return 1;
}
static void
sis_5571_reset(void *priv)
{
@@ -722,7 +760,10 @@ sis_5571_init(const device_t *info)
dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2);
/* USB */
dev->usb = device_add(&usb_device);
dev->usb_params.parent_priv = dev;
dev->usb_params.update_interrupt = sis_5571_usb_update_interrupt;
dev->usb_params.smi_handle = sis_5571_usb_handle_smi;
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
sis_5571_reset(dev);

View File

@@ -65,7 +65,11 @@ typedef struct stpc_t {
smram_t *smram;
usb_t *usb;
int ide_slot;
int usb_slot;
sff8038i_t *bm[2];
/* Miscellaneous */
usb_params_t usb_params;
} stpc_t;
typedef struct stpc_serial_t {
@@ -870,6 +874,17 @@ stpc_setup(stpc_t *dev)
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
}
static void
stpc_usb_update_interrupt(usb_t* usb, void* priv)
{
stpc_t *dev = (stpc_t *) priv;
if (usb->irq_level)
pci_set_irq(dev->usb_slot, PCI_INTA);
else
pci_clear_irq(dev->usb_slot, PCI_INTA);
}
static void
stpc_close(void *priv)
{
@@ -895,9 +910,13 @@ stpc_init(const device_t *info)
pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev);
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev);
if (dev->local == STPC_ATLAS) {
dev->usb_params.smi_handle = NULL;
dev->usb_params.update_interrupt = stpc_usb_update_interrupt;
dev->usb_params.parent_priv = dev;
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_ide_read, stpc_ide_write, dev);
dev->usb = device_add(&usb_device);
pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_usb_read, stpc_usb_write, dev);
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_usb_read, stpc_usb_write, dev);
}
dev->bm[0] = device_add_inst(&sff8038i_device, 1);

View File

@@ -607,3 +607,51 @@ RecompOpFn recomp_opcodes_REPNE[512] = {
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
// clang-format on
};
RecompOpFn recomp_opcodes_NULL[512] = {
// clang-format off
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
// clang-format on
};

View File

@@ -17,6 +17,7 @@ extern RecompOpFn recomp_opcodes_de[512];
extern RecompOpFn recomp_opcodes_df[512];
extern RecompOpFn recomp_opcodes_REPE[512];
extern RecompOpFn recomp_opcodes_REPNE[512];
extern RecompOpFn recomp_opcodes_NULL[512];
#define REG_EAX 0
#define REG_ECX 1

View File

@@ -883,7 +883,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
case 0xd8:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
recomp_op_table = recomp_opcodes_d8;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_d8;
opcode_shift = 3;
opcode_mask = 0x1f;
over = 1;
@@ -893,7 +893,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xd9:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
recomp_op_table = recomp_opcodes_d9;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_d9;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -902,7 +902,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xda:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
recomp_op_table = recomp_opcodes_da;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_da;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -911,7 +911,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xdb:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
recomp_op_table = recomp_opcodes_db;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_db;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -920,7 +920,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xdc:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
recomp_op_table = recomp_opcodes_dc;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_dc;
opcode_shift = 3;
opcode_mask = 0x1f;
over = 1;
@@ -930,7 +930,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xdd:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
recomp_op_table = recomp_opcodes_dd;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_dd;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -939,7 +939,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xde:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
recomp_op_table = recomp_opcodes_de;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_de;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -948,7 +948,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xdf:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
recomp_op_table = recomp_opcodes_df;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_df;
opcode_mask = 0xff;
over = 1;
pc_off = -1;

View File

@@ -1921,7 +1921,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
case 0xd8:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
recomp_op_table = recomp_opcodes_d8;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_d8;
opcode_shift = 3;
opcode_mask = 0x1f;
over = 1;
@@ -1931,7 +1931,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xd9:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
recomp_op_table = recomp_opcodes_d9;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_d9;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -1940,7 +1940,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xda:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
recomp_op_table = recomp_opcodes_da;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_da;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -1949,7 +1949,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xdb:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
recomp_op_table = recomp_opcodes_db;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_db;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -1958,7 +1958,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xdc:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
recomp_op_table = recomp_opcodes_dc;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_dc;
opcode_shift = 3;
opcode_mask = 0x1f;
over = 1;
@@ -1968,7 +1968,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xdd:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
recomp_op_table = recomp_opcodes_dd;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_dd;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -1977,7 +1977,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xde:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
recomp_op_table = recomp_opcodes_de;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_de;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -1986,7 +1986,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xdf:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
recomp_op_table = recomp_opcodes_df;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_df;
opcode_mask = 0xff;
over = 1;
pc_off = -1;

View File

@@ -439,8 +439,8 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xd8;
#endif
op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_d8_a32 : (OpFn *) x86_dynarec_opcodes_d8_a16;
recomp_op_table = recomp_opcodes_d8;
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_d8;
opcode_shift = 3;
opcode_mask = 0x1f;
over = 1;
@@ -452,8 +452,8 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xd9;
#endif
op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_d9_a32 : (OpFn *) x86_dynarec_opcodes_d9_a16;
recomp_op_table = recomp_opcodes_d9;
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_d9;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -464,8 +464,8 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xda;
#endif
op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_da_a32 : (OpFn *) x86_dynarec_opcodes_da_a16;
recomp_op_table = recomp_opcodes_da;
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_da;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -476,8 +476,8 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xdb;
#endif
op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_db_a32 : (OpFn *) x86_dynarec_opcodes_db_a16;
recomp_op_table = recomp_opcodes_db;
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_db;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -488,8 +488,8 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xdc;
#endif
op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_dc_a32 : (OpFn *) x86_dynarec_opcodes_dc_a16;
recomp_op_table = recomp_opcodes_dc;
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_dc;
opcode_shift = 3;
opcode_mask = 0x1f;
over = 1;
@@ -501,8 +501,8 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xdd;
#endif
op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_dd_a32 : (OpFn *) x86_dynarec_opcodes_dd_a16;
recomp_op_table = recomp_opcodes_dd;
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_dd;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -513,8 +513,8 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xde;
#endif
op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_de_a32 : (OpFn *) x86_dynarec_opcodes_de_a16;
recomp_op_table = recomp_opcodes_de;
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_de;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -525,8 +525,8 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xdf;
#endif
op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_df_a32 : (OpFn *) x86_dynarec_opcodes_df_a16;
recomp_op_table = recomp_opcodes_df;
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
recomp_op_table = fpu_softfloat ? recomp_opcodes_NULL : recomp_opcodes_df;
opcode_mask = 0xff;
over = 1;
pc_off = -1;

View File

@@ -556,3 +556,52 @@ RecompOpFn recomp_opcodes_df[512] = {
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
// clang-format on
};
RecompOpFn recomp_opcodes_NULL[512] = {
// clang-format off
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
// clang-format on
};

View File

@@ -20,6 +20,7 @@ extern RecompOpFn recomp_opcodes_de[512];
extern RecompOpFn recomp_opcodes_df[512];
/*extern RecompOpFn recomp_opcodes_REPE[512];
extern RecompOpFn recomp_opcodes_REPNE[512];*/
extern RecompOpFn recomp_opcodes_NULL[512];
#define REG_EAX 0
#define REG_ECX 1

View File

@@ -783,6 +783,8 @@ load_network(void)
net_cards_conf[c].net_type = NET_TYPE_PCAP;
else if (!strcmp(p, "slirp") || !strcmp(p, "2"))
net_cards_conf[c].net_type = NET_TYPE_SLIRP;
else if (!strcmp(p, "vde") || !strcmp(p, "2"))
net_cards_conf[c].net_type = NET_TYPE_VDE;
else
net_cards_conf[c].net_type = NET_TYPE_NONE;
} else {
@@ -791,13 +793,17 @@ load_network(void)
p = ini_section_get_string(cat, "net_host_device", NULL);
if (p != NULL) {
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
if (network_ndev == 1) {
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130);
} else if (network_dev_to_id(p) == -1) {
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130);
if (net_cards_conf[c].net_type == NET_TYPE_PCAP) {
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
if (network_ndev == 1) {
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130);
} else if (network_dev_to_id(p) == -1) {
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130);
}
strcpy(net_cards_conf[c].host_dev_name, "none");
} else {
strncpy(net_cards_conf[c].host_dev_name, p, sizeof(net_cards_conf[c].host_dev_name) - 1);
}
strcpy(net_cards_conf[c].host_dev_name, "none");
} else {
strncpy(net_cards_conf[c].host_dev_name, p, sizeof(net_cards_conf[c].host_dev_name) - 1);
}
@@ -828,6 +834,8 @@ load_network(void)
net_cards_conf[c].net_type = NET_TYPE_PCAP;
} else if (!strcmp(p, "slirp") || !strcmp(p, "2")) {
net_cards_conf[c].net_type = NET_TYPE_SLIRP;
} else if (!strcmp(p, "vde") || !strcmp(p, "2")) {
net_cards_conf[c].net_type = NET_TYPE_VDE;
} else {
net_cards_conf[c].net_type = NET_TYPE_NONE;
}
@@ -838,13 +846,15 @@ load_network(void)
sprintf(temp, "net_%02i_host_device", c + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p != NULL) {
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
if (network_ndev == 1) {
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130);
} else if (network_dev_to_id(p) == -1) {
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130);
if (net_cards_conf[c].net_type == NET_TYPE_PCAP) {
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
if (network_ndev == 1) {
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130);
} else if (network_dev_to_id(p) == -1) {
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130);
}
strcpy(net_cards_conf[c].host_dev_name, "none");
}
strcpy(net_cards_conf[c].host_dev_name, "none");
} else {
strncpy(net_cards_conf[c].host_dev_name, p, sizeof(net_cards_conf[c].host_dev_name) - 1);
}
@@ -2469,11 +2479,19 @@ save_network(void)
}
sprintf(temp, "net_%02i_net_type", c + 1);
if (net_cards_conf[c].net_type == NET_TYPE_NONE) {
ini_section_delete_var(cat, temp);
} else {
ini_section_set_string(cat, temp,
(net_cards_conf[c].net_type == NET_TYPE_SLIRP) ? "slirp" : "pcap");
switch(net_cards_conf[c].net_type) {
case NET_TYPE_NONE:
ini_section_delete_var(cat, temp);
break;
case NET_TYPE_SLIRP:
ini_section_set_string(cat, temp, "slirp");
break;
case NET_TYPE_PCAP:
ini_section_set_string(cat, temp, "pcap");
break;
case NET_TYPE_VDE:
ini_section_set_string(cat, temp, "vde");
break;
}
sprintf(temp, "net_%02i_host_device", c + 1);

View File

@@ -208,7 +208,7 @@ void
cpu_set_edx(void)
{
EDX = cpu_s->edx_reset;
if (!cpu_use_dynarec && fpu_softfloat)
if (fpu_softfloat)
SF_FPU_reset();
}
@@ -463,22 +463,41 @@ cpu_set(void)
if (hasfpu) {
#ifdef USE_DYNAREC
x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16;
x86_dynarec_opcodes_d8_a32 = dynarec_ops_fpu_d8_a32;
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32;
if (fpu_softfloat) {
x86_dynarec_opcodes_d8_a16 = dynarec_ops_sf_fpu_d8_a16;
x86_dynarec_opcodes_d8_a32 = dynarec_ops_sf_fpu_d8_a32;
x86_dynarec_opcodes_d9_a16 = dynarec_ops_sf_fpu_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_sf_fpu_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_sf_fpu_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_sf_fpu_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_sf_fpu_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_sf_fpu_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_sf_fpu_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_sf_fpu_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_sf_fpu_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_sf_fpu_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_sf_fpu_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_sf_fpu_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_sf_fpu_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_sf_fpu_df_a32;
} else {
x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16;
x86_dynarec_opcodes_d8_a32 = dynarec_ops_fpu_d8_a32;
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32;
}
#endif
if (fpu_softfloat) {
x86_opcodes_d8_a16 = ops_sf_fpu_d8_a16;
@@ -587,20 +606,37 @@ cpu_set(void)
if (fpu_type == FPU_287) {
#ifdef USE_DYNAREC
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
if (fpu_softfloat) {
x86_dynarec_opcodes_d9_a16 = dynarec_ops_sf_fpu_287_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_sf_fpu_287_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_sf_fpu_287_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_sf_fpu_287_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_sf_fpu_287_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_sf_fpu_287_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_sf_fpu_287_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_sf_fpu_287_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_sf_fpu_287_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_sf_fpu_287_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_sf_fpu_287_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_sf_fpu_287_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_sf_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_sf_fpu_287_df_a32;
} else {
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
}
#endif
if (fpu_softfloat) {
x86_opcodes_d9_a16 = ops_sf_fpu_287_d9_a16;
@@ -680,20 +716,37 @@ cpu_set(void)
case CPU_386DX:
if (fpu_type == FPU_287) { /* In case we get Deskpro 386 emulation */
#ifdef USE_DYNAREC
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
if (fpu_softfloat) {
x86_dynarec_opcodes_d9_a16 = dynarec_ops_sf_fpu_287_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_sf_fpu_287_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_sf_fpu_287_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_sf_fpu_287_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_sf_fpu_287_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_sf_fpu_287_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_sf_fpu_287_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_sf_fpu_287_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_sf_fpu_287_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_sf_fpu_287_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_sf_fpu_287_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_sf_fpu_287_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_sf_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_sf_fpu_287_df_a32;
} else {
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
}
#endif
if (fpu_softfloat) {
x86_opcodes_d9_a16 = ops_sf_fpu_287_d9_a16;
@@ -1120,12 +1173,21 @@ cpu_set(void)
case CPU_Cx6x86MX:
if (cpu_s->cpu_type == CPU_Cx6x86MX) {
# ifdef USE_DYNAREC
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32;
if (fpu_softfloat) {
x86_dynarec_opcodes_da_a16 = dynarec_ops_sf_fpu_686_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_sf_fpu_686_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_sf_fpu_686_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_sf_fpu_686_db_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_sf_fpu_686_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_sf_fpu_686_df_a32;
} else {
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32;
}
# endif
if (fpu_softfloat) {
x86_opcodes_da_a16 = ops_sf_fpu_686_da_a16;
@@ -1158,7 +1220,8 @@ cpu_set(void)
else if (cpu_s->cpu_type == CPU_Cx6x86L)
x86_setopcodes(ops_386, ops_pentium_0f);
else
x86_setopcodes(ops_386, ops_c6x86_0f);
x86_setopcodes(ops_386, ops_c6x86mx_0f);
// x86_setopcodes(ops_386, ops_c6x86_0f);
# endif
timing_rr = 1; /* register dest - register src */
@@ -1332,12 +1395,21 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f);
else
x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f);
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32;
if (fpu_softfloat) {
x86_dynarec_opcodes_da_a16 = dynarec_ops_sf_fpu_686_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_sf_fpu_686_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_sf_fpu_686_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_sf_fpu_686_db_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_sf_fpu_686_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_sf_fpu_686_df_a32;
} else {
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32;
}
#else
if (cpu_s->cpu_type == CPU_PENTIUM2D)
x86_setopcodes(ops_386, ops_pentium2d_0f);

View File

@@ -102,6 +102,38 @@ extern const OpFn dynarec_ops_pentiumpro_0f[1024];
extern const OpFn dynarec_ops_pentium2_0f[1024];
extern const OpFn dynarec_ops_pentium2d_0f[1024];
extern const OpFn dynarec_ops_sf_fpu_287_d9_a16[256];
extern const OpFn dynarec_ops_sf_fpu_287_d9_a32[256];
extern const OpFn dynarec_ops_sf_fpu_287_da_a16[256];
extern const OpFn dynarec_ops_sf_fpu_287_da_a32[256];
extern const OpFn dynarec_ops_sf_fpu_287_db_a16[256];
extern const OpFn dynarec_ops_sf_fpu_287_db_a32[256];
extern const OpFn dynarec_ops_sf_fpu_287_dc_a16[32];
extern const OpFn dynarec_ops_sf_fpu_287_dc_a32[32];
extern const OpFn dynarec_ops_sf_fpu_287_dd_a16[256];
extern const OpFn dynarec_ops_sf_fpu_287_dd_a32[256];
extern const OpFn dynarec_ops_sf_fpu_287_de_a16[256];
extern const OpFn dynarec_ops_sf_fpu_287_de_a32[256];
extern const OpFn dynarec_ops_sf_fpu_287_df_a16[256];
extern const OpFn dynarec_ops_sf_fpu_287_df_a32[256];
extern const OpFn dynarec_ops_sf_fpu_d8_a16[32];
extern const OpFn dynarec_ops_sf_fpu_d8_a32[32];
extern const OpFn dynarec_ops_sf_fpu_d9_a16[256];
extern const OpFn dynarec_ops_sf_fpu_d9_a32[256];
extern const OpFn dynarec_ops_sf_fpu_da_a16[256];
extern const OpFn dynarec_ops_sf_fpu_da_a32[256];
extern const OpFn dynarec_ops_sf_fpu_db_a16[256];
extern const OpFn dynarec_ops_sf_fpu_db_a32[256];
extern const OpFn dynarec_ops_sf_fpu_dc_a16[32];
extern const OpFn dynarec_ops_sf_fpu_dc_a32[32];
extern const OpFn dynarec_ops_sf_fpu_dd_a16[256];
extern const OpFn dynarec_ops_sf_fpu_dd_a32[256];
extern const OpFn dynarec_ops_sf_fpu_de_a16[256];
extern const OpFn dynarec_ops_sf_fpu_de_a32[256];
extern const OpFn dynarec_ops_sf_fpu_df_a16[256];
extern const OpFn dynarec_ops_sf_fpu_df_a32[256];
extern const OpFn dynarec_ops_fpu_287_d9_a16[256];
extern const OpFn dynarec_ops_fpu_287_d9_a32[256];
extern const OpFn dynarec_ops_fpu_287_da_a16[256];
@@ -136,6 +168,13 @@ extern const OpFn dynarec_ops_fpu_df_a32[256];
extern const OpFn dynarec_ops_nofpu_a16[256];
extern const OpFn dynarec_ops_nofpu_a32[256];
extern const OpFn dynarec_ops_sf_fpu_686_da_a16[256];
extern const OpFn dynarec_ops_sf_fpu_686_da_a32[256];
extern const OpFn dynarec_ops_sf_fpu_686_db_a16[256];
extern const OpFn dynarec_ops_sf_fpu_686_db_a32[256];
extern const OpFn dynarec_ops_sf_fpu_686_df_a16[256];
extern const OpFn dynarec_ops_sf_fpu_686_df_a32[256];
extern const OpFn dynarec_ops_fpu_686_da_a16[256];
extern const OpFn dynarec_ops_fpu_686_da_a32[256];
extern const OpFn dynarec_ops_fpu_686_db_a16[256];

View File

@@ -97,7 +97,8 @@ opWAIT(uint32_t fetchdat)
return 1;
}
if (!cpu_use_dynarec && fpu_softfloat) {
// if (!cpu_use_dynarec && fpu_softfloat) {
if (fpu_softfloat) {
if (fpu_state.swd & FPU_SW_Summary) {
if (cr0 & 0x20) {
x86_int(16);

View File

@@ -165,7 +165,7 @@ typedef struct cdrom {
char *image_history[CD_IMAGE_HISTORY];
uint32_t sound_on, cdrom_capacity,
early, seek_pos,
seek_pos,
seek_diff, cd_end, type;
int host_drive, prev_host_drive,

View File

@@ -51,6 +51,7 @@
#define NET_TYPE_NONE 0 /* networking disabled */
#define NET_TYPE_SLIRP 1 /* use the SLiRP port forwarder */
#define NET_TYPE_PCAP 2 /* use the (Win)Pcap API */
#define NET_TYPE_VDE 3 /* use the VDE plug API */
#define NET_MAX_FRAME 1518
/* Queue size must be a power of 2 */
@@ -123,6 +124,7 @@ typedef struct netdrv_t {
extern const netdrv_t net_pcap_drv;
extern const netdrv_t net_slirp_drv;
extern const netdrv_t net_vde_drv;
struct _netcard_t {
const device_t *device;
@@ -147,15 +149,27 @@ typedef struct {
char description[128];
} netdev_t;
typedef struct {
int has_slirp: 1;
int has_pcap: 1;
int has_vde: 1;
} network_devmap_t;
#define HAS_NOSLIRP_NET(x) (x.has_pcap || x.has_vde)
#ifdef __cplusplus
extern "C" {
#endif
/* Global variables. */
extern int nic_do_log; /* config */
extern int network_ndev;
extern network_devmap_t network_devmap;
extern int network_ndev; // Number of pcap devices
extern network_devmap_t network_devmap; // Bitmap of available network types
extern netdev_t network_devs[NET_HOST_INTF_MAX];
/* Function prototypes. */
extern void network_init(void);
extern netcard_t *network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_link_state);
@@ -166,6 +180,8 @@ extern int network_available(void);
extern void network_tx(netcard_t *card, uint8_t *, int);
extern int net_pcap_prepare(netdev_t *);
extern int net_vde_prepare(void);
extern void network_connect(int id, int connect);
extern int network_is_connected(int id);

View File

@@ -142,26 +142,27 @@
#define IDT_CD_LUN 1766 /* LUN: */
#define IDT_CD_CHANNEL 1767 /* Channel: */
#define IDT_CD_SPEED 1768 /* Speed: */
#define IDT_CD_TYPE 1769 /* Type: */
/* DLG_CFG_OTHER_REMOVABLE_DEVICES */
#define IDT_MO_DRIVES 1769 /* MO drives: */
#define IDT_MO_BUS 1770 /* Bus: */
#define IDT_MO_ID 1771 /* ID: */
#define IDT_MO_CHANNEL 1772 /* Channel */
#define IDT_MO_TYPE 1773 /* Type: */
#define IDT_MO_DRIVES 1770 /* MO drives: */
#define IDT_MO_BUS 1771 /* Bus: */
#define IDT_MO_ID 1772 /* ID: */
#define IDT_MO_CHANNEL 1773 /* Channel */
#define IDT_MO_TYPE 1774 /* Type: */
#define IDT_ZIP_DRIVES 1774 /* ZIP drives: */
#define IDT_ZIP_BUS 1775 /* Bus: */
#define IDT_ZIP_ID 1776 /* ID: */
#define IDT_ZIP_LUN 1777 /* LUN: */
#define IDT_ZIP_CHANNEL 1778 /* Channel: */
#define IDT_ZIP_DRIVES 1775 /* ZIP drives: */
#define IDT_ZIP_BUS 1776 /* Bus: */
#define IDT_ZIP_ID 1777 /* ID: */
#define IDT_ZIP_LUN 1778 /* LUN: */
#define IDT_ZIP_CHANNEL 1779 /* Channel: */
/* DLG_CFG_PERIPHERALS */
#define IDT_ISARTC 1779 /* ISA RTC: */
#define IDT_ISAMEM_1 1780 /* ISAMEM Board #1: */
#define IDT_ISAMEM_2 1781 /* ISAMEM Board #2: */
#define IDT_ISAMEM_3 1782 /* ISAMEM Board #3: */
#define IDT_ISAMEM_4 1783 /* ISAMEM Board #4: */
#define IDT_ISARTC 1780 /* ISA RTC: */
#define IDT_ISAMEM_1 1781 /* ISAMEM Board #1: */
#define IDT_ISAMEM_2 1782 /* ISAMEM Board #2: */
#define IDT_ISAMEM_3 1783 /* ISAMEM Board #3: */
#define IDT_ISAMEM_4 1784 /* ISAMEM Board #4: */
/*
* To try to keep these organized, we now group the
@@ -302,7 +303,7 @@
#define IDC_COMBO_CD_ID 1157
#define IDC_COMBO_CD_LUN 1158
#define IDC_COMBO_CD_CHANNEL_IDE 1159
#define IDC_CHECKEARLY 1160
#define IDC_COMBO_CD_TYPE 1160
#define IDC_LIST_ZIP_DRIVES 1170 /* other removable devices config */
#define IDC_COMBO_ZIP_BUS 1171

View File

@@ -27,37 +27,92 @@ typedef struct usb_t usb_t;
/* USB device creation parameters struct */
typedef struct
{
void (*raise_interrupt)(usb_t*, void*);
void (*update_interrupt)(usb_t*, void*);
/* Handle (but do not raise) SMI. Returns 1 if SMI can be raised, 0 otherwise. */
uint8_t (*smi_handle)(usb_t*, void*);
void* parent_priv;
} usb_params_t;
typedef union
{
uint32_t l;
uint16_t w[2];
uint8_t b[4];
} ohci_mmio_t;
/* USB Host Controller device struct */
typedef struct usb_t
{
uint8_t uhci_io[32], ohci_mmio[4096];
uint8_t uhci_io[32];
ohci_mmio_t ohci_mmio[1024];
uint16_t uhci_io_base;
int uhci_enable, ohci_enable;
uint32_t ohci_mem_base;
uint32_t ohci_mem_base, irq_level;
mem_mapping_t ohci_mmio_mapping;
pc_timer_t ohci_frame_timer;
pc_timer_t ohci_port_reset_timer[2];
uint8_t ohci_interrupt_counter : 3;
usb_params_t* usb_params;
} usb_t;
#pragma pack(push, 1)
/* Base USB descriptor struct. */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
} usb_desc_base_t;
typedef struct
{
usb_desc_base_t base;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} usb_desc_conf_t;
#pragma pack(pop)
/* USB endpoint device struct. Incomplete and unused. */
typedef struct
{
uint16_t vendor_id;
uint16_t device_id;
/* Reads from endpoint. Non-zero value indicates error. */
uint8_t (*device_in)(void* priv, uint8_t* data, uint32_t len);
/* Writes to endpoint. Non-zero value indicates error. */
uint8_t (*device_out)(void* priv, uint8_t* data, uint32_t len);
/* Process setup packets. */
uint8_t (*device_setup)(void* priv, uint8_t* data);
/* Device reset */
void (*device_reset)(void* priv);
void* priv;
} usb_device_t;
enum usb_bus_types
{
USB_BUS_OHCI = 0,
USB_BUS_UHCI = 1
};
/* Global variables. */
extern const device_t usb_device;
/* Functions. */
extern void uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable);
extern void ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3, int enable);
/* Attach USB device to a port of a USB bus. Returns the port to which it got attached to. */
extern uint8_t usb_attach_device(usb_t *dev, usb_device_t* device, uint8_t bus_type);
/* Detach USB device from a port. */
extern void usb_detach_device(usb_t *dev, uint8_t port, uint8_t bus_type);
#ifdef __cplusplus
}

View File

@@ -83,6 +83,7 @@ typedef struct ibm8514_t {
} accel;
uint16_t test;
int ibm_mode;
int v_total, dispend, v_syncstart, split,
h_disp, h_disp_old, h_total, h_disp_time, rowoffset,
@@ -107,5 +108,6 @@ typedef struct ibm8514_t {
int blitter_busy;
uint64_t blitter_time;
uint64_t status_time;
int pitch;
} ibm8514_t;
#endif /*VIDEO_8514A_H*/

View File

@@ -184,6 +184,13 @@ extern int vga_on, ibm8514_on;
extern void ibm8514_poll(ibm8514_t *dev, svga_t *svga);
extern void ibm8514_recalctimings(svga_t *svga);
extern uint8_t ibm8514_ramdac_in(uint16_t port, void *p);
extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *p);
extern int ibm8514_cpu_src(svga_t *svga);
extern int ibm8514_cpu_dest(svga_t *svga);
extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint16_t val, int len);
extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len);
extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len);
extern void xga_poll(xga_t *xga, svga_t *svga);
extern void xga_recalctimings(svga_t *svga);

View File

@@ -12,8 +12,8 @@
#
# Copyright 2020-2021 David Hrdlička.
#
add_library(net OBJECT network.c net_pcap.c net_slirp.c net_dp8390.c net_3c501.c
set(net_sources)
list(APPEND net_sources network.c net_pcap.c net_slirp.c net_dp8390.c net_3c501.c
net_3c503.c net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c net_event.c)
option(SLIRP_EXTERNAL "Link against the system-provided libslirp library" OFF)
@@ -39,3 +39,13 @@ endif()
if(WIN32)
target_link_libraries(86Box ws2_32)
endif()
if (UNIX)
find_path(HAS_VDE "libvdeplug.h" PATHS ${VDE_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" )
if(HAS_VDE)
add_compile_definitions(HAS_VDE)
list(APPEND net_sources net_vde.c)
endif()
endif()
add_library(net OBJECT ${net_sources})

310
src/network/net_vde.c Normal file
View File

@@ -0,0 +1,310 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* VDE networking for 86box
* See https://wiki.virtualsquare.org/#!tutorials/vdebasics.md
* for basic information about VDE. You can browse the source
* code at https://github.com/virtualsquare/vde-2
*
* VDE support is only available in Linux and MacOS. It _should_
* be available in BSD*, and if someday there is a BSD version of
* 86box this _could_ work out of the box.
*
* Authors: jguillaumes <jguillaumes@gmail.com>
* Copyright 2023 jguillaumes.
*
* See the COPYING file at the top of the 86box for license details.
* TL;DR: GPL version 2.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#if !defined(_WIN32)
#include <poll.h>
#include <unistd.h>
#else
#error VDE is not supported under windows
#endif
#include <libvdeplug.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/plat.h>
#include <86box/plat_dynld.h>
#include <86box/thread.h>
#include <86box/timer.h>
#include <86box/network.h>
#include <86box/net_event.h>
#define VDE_PKT_BATCH NET_QUEUE_LEN
#define VDE_DESCRIPTION "86Box virtual card"
enum {
NET_EVENT_STOP = 0,
NET_EVENT_TX,
NET_EVENT_RX,
NET_EVENT_VDE,
NET_EVENT_MAX
};
static volatile void *libvde_handle = NULL;
//+
// VDE connection structure
//-
typedef struct {
void *vdeconn; // VDEPLUG Connection
netcard_t *card; // NIC linked to
thread_t *poll_tid; // Polling thread
net_evt_t tx_event; // Packets to transmit event
net_evt_t stop_event; // Stop thread event
netpkt_t pkt; // Packet read/sent
netpkt_t pktv[VDE_PKT_BATCH]; // Packet queue
uint8_t mac_addr[6]; // MAC Address
} net_vde_t;
//+
// VDE libvdeplug function pointers
//-
static VDECONN *(*f_vde_open)(char *, char *, int, struct vde_open_args *); // This is vde_open_real()
static void (*f_vde_close)(VDECONN *);
static int (*f_vde_datafd)(VDECONN *); // Get the data (read/write) handle
static int (*f_vde_ctlfd)(VDECONN *); // Get the control handle
static ssize_t (*f_vde_recv)(VDECONN *, void *, size_t, int); // Receive a packet
static ssize_t (*f_vde_send)(VDECONN *, const void *, size_t, int); // Send a packet
//+
// VDE libvdeplug function table (for import)
//-
static dllimp_t vde_imports[] = {
{"vde_open_real", &f_vde_open},
{"vde_close", &f_vde_close},
{"vde_datafd", &f_vde_datafd},
{"vde_ctlfd", &f_vde_ctlfd},
{"vde_recv", &f_vde_recv},
{"vde_send", &f_vde_send},
{ NULL, NULL}
};
#ifdef ENABLE_VDE_LOG
#include <stdarg.h>
int vde_do_log = ENABLE_VDE_LOG;
static void
vde_log(const char *fmt, ...) {
va_list ap;
if (vde_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define vde_log(fmt, ...)
#endif
#ifdef _WIN32
#error VDE networking is not supported under windows
#else
//+
// VDE thread
//-
static void net_vde_thread(void *priv) {
net_vde_t *vde = (net_vde_t *) priv;
vde_log("VDE: Polling started.\n");
struct pollfd pfd[NET_EVENT_MAX];
pfd[NET_EVENT_STOP].fd = net_event_get_fd(&vde->stop_event);
pfd[NET_EVENT_STOP].events = POLLIN | POLLPRI;
pfd[NET_EVENT_TX].fd = net_event_get_fd(&vde->tx_event);
pfd[NET_EVENT_TX].events = POLLIN | POLLPRI;
pfd[NET_EVENT_RX].fd = f_vde_datafd(vde->vdeconn);
pfd[NET_EVENT_RX].events = POLLIN;
pfd[NET_EVENT_VDE].fd = f_vde_ctlfd(vde->vdeconn);
pfd[NET_EVENT_VDE].events = POLLIN;
while(1) {
poll(pfd, NET_EVENT_MAX, -1);
// Acvity in the control handle means the link is closed
// We send ourselves a STOP event
if (pfd[NET_EVENT_VDE].revents & POLLIN) {
net_event_set(&vde->stop_event);
}
// There are packets queued to transmit
if (pfd[NET_EVENT_TX].revents & POLLIN) {
net_event_clear(&vde->tx_event);
int packets = network_tx_popv(vde->card, vde->pktv, VDE_PKT_BATCH);
for (int i=0; i<packets; i++) {
int nc = f_vde_send(vde->vdeconn, vde->pktv[i].data,vde->pktv[i].len, 0 );
if (nc == 0) {
vde_log("VDE: Problem, no bytes sent.\n");
}
}
}
// Packets are available for reading. Read packet and queue it
if (pfd[NET_EVENT_RX].revents & POLLIN) {
int nc = f_vde_recv(vde->vdeconn, vde->pkt.data, NET_MAX_FRAME, 0);
vde->pkt.len = nc;
network_rx_put_pkt(vde->card, &vde->pkt);
}
// We have been told to close
if (pfd[NET_EVENT_STOP].revents & POLLIN) {
net_event_clear(&vde->stop_event);
break;
}
}
vde_log("VDE: Polling stopped.\n");
}
#endif
//+
// Prepare the VDE libvdeplug interface.
// Load the dynamic library libvdeplug.
// Returns zero if the library has been loaded, -1 in case of error.
//-
int net_vde_prepare(void) {
#if defined(_WIN32)
#error VDE is not supported in Windows
#elif defined(__APPLE__)
libvde_handle = dynld_module("libvdeplug.dylib", vde_imports);
#else
libvde_handle = dynld_module("libvdeplug.so", vde_imports);
#endif
if (libvde_handle == NULL) {
vde_log("VDE: error loading VDEPLUG module\n");
return -1;
} else {
network_devmap.has_vde = 1;
}
return 0;
}
//+
// Close a VDE socket connection
//-
void net_vde_close(void *priv) {
int i;
if (!priv) return;
net_vde_t *vde = (net_vde_t *) priv;
vde_log("VDE: closing.\n");
net_event_set(&vde->stop_event); // Tell the thread to finish
vde_log("VDE: Waiting for the thread to finish...\n");
thread_wait(vde->poll_tid);
vde_log("VDE: Thread finished.\n");
// Free all the mallocs!
for(i=0;i<VDE_PKT_BATCH; i++) {
free(vde->pktv[i].data);
}
free(vde->pkt.data);
f_vde_close((void *) vde->vdeconn);
net_event_close(&vde->tx_event);
net_event_close(&vde->stop_event);
free(vde);
}
//+
// Signal packets are available to be transmitted
//-
void net_vde_in_available(void *priv) {
net_vde_t *vde = (net_vde_t *) priv;
net_event_set(&vde->tx_event);
}
//+
// Initialize VDE for use
// At this point the vdeplug library is already loaded
// card: network card we are attaching
// mac_addr: MAC address we are using
// priv: Name of the VDE contol socket directory
//-
void *net_vde_init(const netcard_t *card, const uint8_t *mac_addr, void *priv) {
struct vde_open_args vde_args;
int i;
char *socket_name = (char *) priv;
if (libvde_handle == NULL) {
vde_log("VDE: net_vde_init without library handle!\n");
return NULL;
}
if ((socket_name[0] == '\0') || !strcmp(socket_name, "none")) {
vde_log("VDE: No socket name configured!\n");
return NULL;
}
vde_log("VDE: Attaching to virtual switch at %s\n", socket_name);
net_vde_t *vde = calloc(1, sizeof(net_vde_t));
vde->card = (netcard_t *) card;
memcpy(vde->mac_addr, mac_addr, sizeof(vde->mac_addr));
vde_args.group = 0;
vde_args.port = 0;
vde_args.mode = 0;
// We are calling vde_open_real(), not the vde_open() macro...
if ((vde->vdeconn = f_vde_open(socket_name, VDE_DESCRIPTION,
LIBVDEPLUG_INTERFACE_VERSION, &vde_args)) == NULL) {
vde_log("VDE: Unable to open socket %s (%s)!\n", socket_name, strerror(errno));
free(vde);
//+
// There is a bug upstream that causes an uncontrolled crash if the network is not
// properly initialized.
// To avoid that crash, we tell the user we cannot continue and exit the program.
// TODO: Once there is a solution for the mentioned crash, this should be removed
// and/or replaced by proper error handling code.
//-
fatal("Could not open the specified VDE socket (%s). Please fix your networking configuration.", socket_name);
// It makes no sense to issue this warning since the program will crash anyway...
// ui_msgbox_header(MBX_WARNING, (wchar_t *) IDS_2167, (wchar_t *) IDS_2168);
return NULL;
}
vde_log("VDE: Socket opened (%s).\n", socket_name);
for(i=0; i < VDE_PKT_BATCH; i++) {
vde->pktv[i].data = calloc(1, NET_MAX_FRAME);
}
vde->pkt.data = calloc(1,NET_MAX_FRAME);
net_event_init(&vde->tx_event);
net_event_init(&vde->stop_event);
vde->poll_tid = thread_create(net_vde_thread, vde); // Fire up the read-write thread!
return vde;
}
//+
// VDE Driver structure
//-
const netdrv_t net_vde_drv = {
&net_vde_in_available,
&net_vde_init,
&net_vde_close,
NULL
};

View File

@@ -123,7 +123,8 @@ netcard_conf_t net_cards_conf[NET_CARD_MAX];
uint16_t net_card_current = 0;
/* Global variables. */
int network_ndev;
network_devmap_t network_devmap;
int network_ndev;
netdev_t network_devs[NET_HOST_INTF_MAX];
/* Local variables. */
@@ -214,9 +215,20 @@ network_init(void)
network_ndev = 1;
/* Initialize the Pcap system module, if present. */
network_devmap.has_slirp = 1;
i = net_pcap_prepare(&network_devs[network_ndev]);
if (i > 0)
if (i > 0) {
network_devmap.has_pcap = 1;
network_ndev += i;
}
#ifdef HAS_VDE
// Try to load the VDE plug library
if(net_vde_prepare()==0) {
network_devmap.has_vde = 1;
}
#endif
#if defined ENABLE_NETWORK_LOG && !defined(_WIN32)
/* Start packet dump. */
@@ -286,6 +298,17 @@ int
network_queue_put_swap(netqueue_t *queue, netpkt_t *src_pkt)
{
if (src_pkt->len == 0 || src_pkt->len > NET_MAX_FRAME || network_queue_full(queue)) {
#ifdef DEBUG
if (src_pkt->len == 0) {
network_log("Discarded zero length packet.\n");
} else if (src_pkt->len > NET_MAX_FRAME) {
network_log("Discarded oversized packet of len=%d.\n", src_pkt->len);
network_dump_packet(src_pkt);
} else {
network_log("Discarded %d bytes packet because the queue is full.\n", src_pkt->len);
network_dump_packet(src_pkt);
}
#endif
return 0;
}
@@ -434,6 +457,12 @@ network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_lin
card->host_drv = net_pcap_drv;
card->host_drv.priv = card->host_drv.init(card, mac, net_cards_conf[net_card_current].host_dev_name);
break;
#ifdef HAS_VDE
case NET_TYPE_VDE:
card->host_drv = net_vde_drv;
card->host_drv.priv = card->host_drv.init(card, mac, net_cards_conf[net_card_current].host_dev_name);
break;
#endif
}
if (!card->host_drv.priv) {
@@ -617,6 +646,8 @@ network_dev_available(int id)
if ((net_cards_conf[id].net_type == NET_TYPE_PCAP && (network_dev_to_id(net_cards_conf[id].host_dev_name) <= 0)))
available = 0;
// TODO: Handle VDE device
return available;
}

View File

@@ -570,6 +570,9 @@ pic_reset_hard(void)
{
pic_reset();
/* Explicitly reset the latches. */
kbd_latch = mouse_latch = 0;
/* The situation is as follows: There is a giant mess when it comes to these latches on real hardware,
to the point that there's even boards with board-level latched that get used in place of the latches
on the chipset, therefore, I'm just doing this here for the sake of simplicity. */

View File

@@ -857,6 +857,9 @@ MediaMenu::nicUpdateMenu(int i)
case NET_TYPE_PCAP:
netType = "PCAP";
break;
case NET_TYPE_VDE:
netType = "VDE";
break;
}
QString devName = DeviceConfig::DeviceName(network_card_getdevice(net_cards_conf[i].device_num), network_card_get_internal_name(net_cards_conf[i].device_num), 1);

View File

@@ -37,13 +37,17 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui)
auto *net_type_cbox = findChild<QComboBox *>(QString("comboBoxNet%1").arg(i + 1));
auto *intf_cbox = findChild<QComboBox *>(QString("comboBoxIntf%1").arg(i + 1));
auto *conf_btn = findChild<QPushButton *>(QString("pushButtonConf%1").arg(i + 1));
auto *socket_line = findChild<QLineEdit *>(QString("socketVDENIC%1").arg(i + 1));
int netType = net_type_cbox->currentData().toInt();
bool adaptersEnabled = netType == NET_TYPE_SLIRP || (netType == NET_TYPE_PCAP && intf_cbox->currentData().toInt() > 0);
bool adaptersEnabled = netType == NET_TYPE_SLIRP
|| NET_TYPE_VDE
|| (netType == NET_TYPE_PCAP && intf_cbox->currentData().toInt() > 0);
intf_cbox->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_PCAP);
nic_cbox->setEnabled(adaptersEnabled);
conf_btn->setEnabled(adaptersEnabled && network_card_has_config(nic_cbox->currentData().toInt()));
socket_line->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_VDE);
}
}
@@ -59,6 +63,7 @@ SettingsNetwork::SettingsNetwork(QWidget *parent)
auto *nic_cbox = findChild<QComboBox *>(QString("comboBoxNIC%1").arg(i + 1));
auto *net_type_cbox = findChild<QComboBox *>(QString("comboBoxNet%1").arg(i + 1));
auto *intf_cbox = findChild<QComboBox *>(QString("comboBoxIntf%1").arg(i + 1));
auto *socket_line = findChild<QLineEdit *>(QString("socketVDENIC%1").arg(i + 1));
connect(nic_cbox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged);
connect(net_type_cbox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged);
connect(intf_cbox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged);
@@ -75,12 +80,18 @@ SettingsNetwork::save()
{
for (int i = 0; i < NET_CARD_MAX; ++i) {
auto *cbox = findChild<QComboBox *>(QString("comboBoxNIC%1").arg(i + 1));
auto *socket_line = findChild<QLineEdit *>(QString("socketVDENIC%1").arg(i + 1));
net_cards_conf[i].device_num = cbox->currentData().toInt();
cbox = findChild<QComboBox *>(QString("comboBoxNet%1").arg(i + 1));
net_cards_conf[i].net_type = cbox->currentData().toInt();
cbox = findChild<QComboBox *>(QString("comboBoxIntf%1").arg(i + 1));
memset(net_cards_conf[i].host_dev_name, '\0', sizeof(net_cards_conf[i].host_dev_name));
strncpy(net_cards_conf[i].host_dev_name, network_devs[cbox->currentData().toInt()].device, sizeof(net_cards_conf[i].host_dev_name) - 1);
if (net_cards_conf[i].net_type == NET_TYPE_PCAP) {
strncpy(net_cards_conf[i].host_dev_name, network_devs[cbox->currentData().toInt()].device, sizeof(net_cards_conf[i].host_dev_name) - 1);
} else if (net_cards_conf[i].net_type == NET_TYPE_VDE) {
const char *str_socket = socket_line->text().toStdString().c_str();
strncpy(net_cards_conf[i].host_dev_name, str_socket, strlen(str_socket));
}
}
}
@@ -124,26 +135,38 @@ SettingsNetwork::onCurrentMachineChanged(int machineId)
removeRows = model->rowCount();
Models::AddEntry(model, tr("None"), NET_TYPE_NONE);
Models::AddEntry(model, "SLiRP", NET_TYPE_SLIRP);
if (network_ndev > 1) {
Models::AddEntry(model, "PCap", NET_TYPE_PCAP);
}
if (network_devmap.has_vde) {
Models::AddEntry(model, "VDE", NET_TYPE_VDE);
}
model->removeRows(0, removeRows);
cbox->setCurrentIndex(net_cards_conf[i].net_type);
selectedRow = 0;
QString currentPcapDevice = net_cards_conf[i].host_dev_name;
cbox = findChild<QComboBox *>(QString("comboBoxIntf%1").arg(i + 1));
model = cbox->model();
removeRows = model->rowCount();
for (int c = 0; c < network_ndev; c++) {
Models::AddEntry(model, tr(network_devs[c].description), c);
if (QString(network_devs[c].device) == currentPcapDevice) {
selectedRow = c;
if (network_ndev > 0) {
QString currentPcapDevice = net_cards_conf[i].host_dev_name;
cbox = findChild<QComboBox *>(QString("comboBoxIntf%1").arg(i + 1));
model = cbox->model();
removeRows = model->rowCount();
for (int c = 0; c < network_ndev; c++) {
Models::AddEntry(model, tr(network_devs[c].description), c);
if (QString(network_devs[c].device) == currentPcapDevice) {
selectedRow = c;
}
}
model->removeRows(0, removeRows);
cbox->setCurrentIndex(selectedRow);
}
if (net_cards_conf[i].net_type == NET_TYPE_VDE) {
QString currentVdeSocket = net_cards_conf[i].host_dev_name;
auto editline = findChild<QLineEdit *>(QString("socketVDENIC%1").arg(i+1));
editline->setText(currentVdeSocket);
}
model->removeRows(0, removeRows);
cbox->setCurrentIndex(selectedRow);
}
}

View File

@@ -36,19 +36,6 @@
<string>Network Card #1</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxNIC1">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
@@ -62,14 +49,17 @@
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxNet1">
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxNIC1">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="2" column="2">
@@ -98,17 +88,14 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxNet1">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Mode</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
@@ -121,7 +108,7 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -134,6 +121,33 @@
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Mode</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="socketVDENIC1">
<property name="maxLength">
<number>127</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>VDE Socket</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
@@ -141,6 +155,36 @@
<string>Network Card #2</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxIntf2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pushButtonConf2">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
@@ -154,19 +198,6 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Mode</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
@@ -193,6 +224,19 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Mode</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxNet2">
<property name="sizePolicy">
@@ -203,25 +247,28 @@
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxIntf2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pushButtonConf2">
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Configure</string>
<string>VDE Socket</string>
</property>
</widget>
</item>
<item row="3" column="1">
<spacer name="verticalSpacer">
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="socketVDENIC2"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Network Card #3</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="socketVDENIC3"/>
</item>
<item row="4" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
@@ -233,23 +280,6 @@
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Network Card #3</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxNet3">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_13">
<property name="sizePolicy">
@@ -263,17 +293,14 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_11">
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxNet3">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Mode</string>
</property>
</widget>
</item>
<item row="1" column="0">
@@ -299,19 +326,6 @@
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pushButtonConf3">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxNIC3">
<property name="sizePolicy">
@@ -325,41 +339,8 @@
</property>
</widget>
</item>
<item row="3" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Network Card #4</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxNIC4">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pushButtonConf4">
<widget class="QPushButton" name="pushButtonConf3">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -371,14 +352,44 @@
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxNet4">
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>VDE Socket </string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_11">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Mode</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Network Card #4</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="2" column="0">
<widget class="QLabel" name="label_16">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Adapter</string>
</property>
</widget>
</item>
<item row="1" column="0">
@@ -394,29 +405,6 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_16">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Adapter</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxIntf4">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_14">
<property name="sizePolicy">
@@ -430,7 +418,43 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxNIC4">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxNet4">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pushButtonConf4">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="4" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -443,6 +467,26 @@
</property>
</spacer>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxIntf4">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="socketVDENIC4"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>VDE Socket</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>

661
src/usb.c
View File

@@ -20,6 +20,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
@@ -28,6 +29,7 @@
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/usb.h>
#include <86box/dma.h>
#ifdef ENABLE_USB_LOG
int usb_do_log = ENABLE_USB_LOG;
@@ -50,42 +52,94 @@ usb_log(const char *fmt, ...)
/* OHCI registers */
enum
{
OHCI_HcRevision = 0x00,
OHCI_HcControl = 0x04,
OHCI_HcCommandStatus = 0x08,
OHCI_HcInterruptStatus = 0x0C,
OHCI_HcInterruptEnable = 0x10,
OHCI_HcInterruptDisable = 0x14,
OHCI_HcHCCA = 0x18,
OHCI_HcPeriodCurrentED = 0x1C,
OHCI_HcControlHeadED = 0x20,
OHCI_HcControlCurrentED = 0x24,
OHCI_HcBulkHeadED = 0x28,
OHCI_HcBulkCurrentED = 0x2C,
OHCI_HcDoneHead = 0x30,
OHCI_HcFMInterval = 0x34,
OHCI_HcFmRemaining = 0x38,
OHCI_HcFmNumber = 0x3C,
OHCI_HcPeriodicStart = 0x40,
OHCI_HcLSThreshold = 0x44,
OHCI_HcRhDescriptorA = 0x48,
OHCI_HcRhDescriptorB = 0x4C,
OHCI_HcRhStatus = 0x50,
OHCI_HcRhPortStatus1 = 0x54,
OHCI_HcRhPortStatus2 = 0x58,
OHCI_HcRhPortStatus3 = 0x5C
OHCI_HcRevision = 0x00 /* 0x00 */,
OHCI_HcControl = 0x01 /* 0x04 */,
OHCI_HcCommandStatus = 0x02 /* 0x08 */,
OHCI_HcInterruptStatus = 0x03 /* 0x0c */,
OHCI_HcInterruptEnable = 0x04 /* 0x10 */,
OHCI_HcInterruptDisable = 0x05 /* 0x14 */,
OHCI_HcHCCA = 0x06 /* 0x18 */,
OHCI_HcPeriodCurrentED = 0x07 /* 0x1c */,
OHCI_HcControlHeadED = 0x08 /* 0x20 */,
OHCI_HcControlCurrentED = 0x09 /* 0x24 */,
OHCI_HcBulkHeadED = 0x0a /* 0x28 */,
OHCI_HcBulkCurrentED = 0x0b /* 0x2c */,
OHCI_HcDoneHead = 0x0c /* 0x30 */,
OHCI_HcFmInterval = 0x0d /* 0x34 */,
OHCI_HcFmRemaining = 0x0e /* 0x38 */,
OHCI_HcFmNumber = 0x0f /* 0x3c */,
OHCI_HcPeriodicStart = 0x10 /* 0x40 */,
OHCI_HcLSThreshold = 0x11 /* 0x44 */,
OHCI_HcRhDescriptorA = 0x12 /* 0x48 */,
OHCI_HcRhDescriptorB = 0x13 /* 0x4c */,
OHCI_HcRhStatus = 0x14 /* 0x50 */,
OHCI_HcRhPortStatus1 = 0x15 /* 0x54 */,
OHCI_HcRhPortStatus2 = 0x16 /* 0x58 */,
OHCI_HcRhPortStatus3 = 0x17 /* 0x5c */
};
enum
{
OHCI_aHcRevision = 0x00,
OHCI_aHcControl = 0x04,
OHCI_aHcCommandStatus = 0x08,
OHCI_aHcInterruptStatus = 0x0c,
OHCI_aHcInterruptEnable = 0x10,
OHCI_aHcInterruptDisable = 0x14,
OHCI_aHcHCCA = 0x18,
OHCI_aHcPeriodCurrentED = 0x1c,
OHCI_aHcControlHeadED = 0x20,
OHCI_aHcControlCurrentED = 0x24,
OHCI_aHcBulkHeadED = 0x28,
OHCI_aHcBulkCurrentED = 0x2c,
OHCI_aHcDoneHead = 0x30,
OHCI_aHcFmInterval = 0x34,
OHCI_aHcFmRemaining = 0x38,
OHCI_aHcFmNumber = 0x3c,
OHCI_aHcPeriodicStart = 0x40,
OHCI_aHcLSThreshold = 0x44,
OHCI_aHcRhDescriptorA = 0x48,
OHCI_aHcRhDescriptorB = 0x4c,
OHCI_aHcRhStatus = 0x50,
OHCI_aHcRhPortStatus1 = 0x54,
OHCI_aHcRhPortStatus2 = 0x58,
OHCI_aHcRhPortStatus3 = 0x5c
};
/* OHCI HcInterruptEnable/Disable bits */
enum
{
OHCI_HcInterruptEnable_SO = 1 << 0,
OHCI_HcInterruptEnable_WDH = 1 << 1,
OHCI_HcInterruptEnable_SF = 1 << 2,
OHCI_HcInterruptEnable_RD = 1 << 3,
OHCI_HcInterruptEnable_UE = 1 << 4,
OHCI_HcInterruptEnable_HNO = 1 << 5,
OHCI_HcInterruptEnable_RHSC = 1 << 6,
};
/* OHCI HcControl bits */
enum
{
OHCI_HcControl_ControlBulkServiceRatio = 1 << 0,
OHCI_HcControl_PeriodicListEnable = 1 << 1,
OHCI_HcControl_IsochronousEnable = 1 << 2,
OHCI_HcControl_ControlListEnable = 1 << 3,
OHCI_HcControl_BulkListEnable = 1 << 4
};
static void
usb_interrupt_ohci(usb_t* usb)
usb_interrupt_ohci(usb_t *dev, uint32_t level)
{
if (usb->ohci_mmio[OHCI_HcControl + 1] & 1) {
smi_raise();
}
else if (usb->usb_params != NULL) {
if (usb->usb_params->parent_priv != NULL && usb->usb_params->raise_interrupt != NULL) {
usb->usb_params->raise_interrupt(usb, usb->usb_params->parent_priv);
}
if (dev->ohci_mmio[OHCI_HcControl].b[1] & 1) {
if (dev->usb_params && dev->usb_params->smi_handle && !dev->usb_params->smi_handle(dev, dev->usb_params->parent_priv))
return;
if (level)
smi_raise();
} else if (dev->usb_params != NULL) {
if ((dev->usb_params->parent_priv != NULL) && (dev->usb_params->update_interrupt != NULL))
dev->usb_params->update_interrupt(dev, dev->usb_params->parent_priv);
}
}
@@ -173,26 +227,235 @@ uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable)
io_sethandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, uhci_reg_writew, NULL, dev);
}
typedef struct
{
uint32_t HccaInterrruptTable[32];
uint16_t HccaFrameNumber;
uint16_t HccaPad1;
uint32_t HccaDoneHead;
} usb_hcca_t;
/* Transfer descriptors */
typedef struct
{
union
{
uint32_t Control;
struct
{
uint32_t Reserved : 18;
uint8_t bufferRounding : 1;
uint8_t Direction : 2;
uint8_t DelayInterrupt : 3;
uint8_t DataToggle : 2;
uint8_t ErrorCount : 2;
uint8_t ConditionCode : 4;
} flags;
};
uint32_t CBP;
uint32_t NextTD;
uint32_t BE;
} usb_td_t;
/* Endpoint descriptors */
typedef struct
{
union
{
uint32_t Control;
struct
{
uint8_t FunctionAddress : 7;
uint8_t EndpointNumber : 4;
uint8_t Direction : 2;
bool Speed : 1;
bool Skip : 1;
bool Format : 1;
uint16_t MaximumPacketSize : 11;
uint8_t Reserved : 5;
} flags;
};
uint32_t TailP;
union
{
uint32_t HeadP;
struct
{
bool Halted : 1;
bool toggleCarry : 1;
} flags_2;
};
uint32_t NextED;
} usb_ed_t;
#define ENDPOINT_DESC_LIMIT 32
static uint8_t
ohci_mmio_read(uint32_t addr, void *p)
{
usb_t *dev = (usb_t *) p;
uint8_t ret = 0x00;
#ifdef ENABLE_USB_LOG
uint32_t old_addr = addr;
#endif
addr &= 0x00000fff;
ret = dev->ohci_mmio[addr];
ret = dev->ohci_mmio[addr >> 2].b[addr & 3];
switch (addr) {
case 0x101:
ret = (ret & 0xfe) | (!!mem_a20_key);
break;
case OHCI_aHcRhPortStatus1 + 1:
case OHCI_aHcRhPortStatus2 + 1:
case OHCI_aHcRhPortStatus3 + 1:
ret |= 0x1;
break;
case OHCI_aHcInterruptDisable:
case OHCI_aHcInterruptDisable + 1:
case OHCI_aHcInterruptDisable + 2:
case OHCI_aHcInterruptDisable + 3:
ret = dev->ohci_mmio[OHCI_HcInterruptEnable].b[addr & 3];
default:
break;
}
if (addr == 0x101)
ret = (ret & 0xfe) | (!!mem_a20_key);
#ifdef ENABLE_USB_LOG
usb_log("[R] %08X = %04X\n", old_addr, ret);
#endif
return ret;
}
static uint16_t
ohci_mmio_readw(uint32_t addr, void *p)
{
return ohci_mmio_read(addr, p) | (ohci_mmio_read(addr + 1, p) << 8);
}
static uint32_t
ohci_mmio_readl(uint32_t addr, void *p)
{
return ohci_mmio_readw(addr, p) | (ohci_mmio_readw(addr + 2, p) << 16);
}
static void
ohci_update_irq(usb_t *dev)
{
uint32_t level = !!(dev->ohci_mmio[OHCI_HcInterruptStatus].l & dev->ohci_mmio[OHCI_HcInterruptEnable].l);
if (level != dev->irq_level) {
dev->irq_level = level;
usb_interrupt_ohci(dev, level);
}
}
void
ohci_set_interrupt(usb_t *dev, uint8_t bit)
{
if (!(dev->ohci_mmio[OHCI_HcInterruptEnable].b[3] & 0x80))
return;
if (!(dev->ohci_mmio[OHCI_HcInterruptEnable].b[0] & bit))
return;
if (dev->ohci_mmio[OHCI_HcInterruptDisable].b[0] & bit)
return;
dev->ohci_mmio[OHCI_HcInterruptStatus].b[0] |= bit;
ohci_update_irq(dev);
}
uint8_t
ohci_service_endpoint_desc(usb_t* dev, uint32_t head)
{
usb_ed_t endpoint_desc;
return 0;
}
void
ohci_end_of_frame(usb_t* dev)
{
usb_hcca_t hcca;
/* TODO: Put endpoint and transfer descriptor processing here. */
dma_bm_read(dev->ohci_mmio[OHCI_HcHCCA].l, (uint8_t*)&hcca, sizeof(usb_hcca_t), 4);
if (dev->ohci_mmio[OHCI_HcControl].l & OHCI_HcControl_PeriodicListEnable) {
ohci_service_endpoint_desc(dev, hcca.HccaInterrruptTable[dev->ohci_mmio[OHCI_HcFmNumber].l & 0x1f]);
}
if ((dev->ohci_mmio[OHCI_HcControl].l & OHCI_HcControl_ControlListEnable)
&& (dev->ohci_mmio[OHCI_HcCommandStatus].l & 0x2)) {
uint8_t result = ohci_service_endpoint_desc(dev, dev->ohci_mmio[OHCI_HcControlHeadED].l);
if (!result) {
dev->ohci_mmio[OHCI_HcControlHeadED].l = 0;
dev->ohci_mmio[OHCI_HcCommandStatus].l &= ~0x2;
}
}
if ((dev->ohci_mmio[OHCI_HcControl].l & OHCI_HcControl_BulkListEnable)
&& (dev->ohci_mmio[OHCI_HcCommandStatus].l & 0x4)) {
uint8_t result = ohci_service_endpoint_desc(dev, dev->ohci_mmio[OHCI_HcBulkHeadED].l);
if (!result) {
dev->ohci_mmio[OHCI_HcBulkHeadED].l = 0;
dev->ohci_mmio[OHCI_HcCommandStatus].l &= ~0x4;
}
}
if (dev->ohci_interrupt_counter == 0 && !(dev->ohci_mmio[OHCI_HcInterruptStatus].l & OHCI_HcInterruptEnable_WDH)) {
if (dev->ohci_mmio[OHCI_HcDoneHead].l == 0) {
fatal("OHCI: HcDoneHead is still NULL!");
}
if (dev->ohci_mmio[OHCI_HcInterruptStatus].l & dev->ohci_mmio[OHCI_HcInterruptEnable].l) {
dev->ohci_mmio[OHCI_HcDoneHead].l |= 1;
}
hcca.HccaDoneHead = dev->ohci_mmio[OHCI_HcDoneHead].l;
dev->ohci_mmio[OHCI_HcDoneHead].l = 0;
dev->ohci_interrupt_counter = 7;
ohci_set_interrupt(dev, OHCI_HcInterruptEnable_WDH);
}
if (dev->ohci_interrupt_counter != 0 && dev->ohci_interrupt_counter != 7) {
dev->ohci_interrupt_counter--;
}
dev->ohci_mmio[OHCI_HcFmNumber].w[0]++;
hcca.HccaFrameNumber = dev->ohci_mmio[OHCI_HcFmNumber].w[0];
dma_bm_write(dev->ohci_mmio[OHCI_HcHCCA].l, (uint8_t*)&hcca, sizeof(usb_hcca_t), 4);
}
void
ohci_start_of_frame(usb_t* dev)
{
ohci_set_interrupt(dev, OHCI_HcInterruptEnable_SO);
}
void
ohci_update_frame_counter(void* priv)
{
usb_t *dev = (usb_t *) priv;
dev->ohci_mmio[OHCI_HcFmRemaining].w[0] &= 0x3fff;
if (dev->ohci_mmio[OHCI_HcFmRemaining].w[0] == 0) {
ohci_end_of_frame(dev);
dev->ohci_mmio[OHCI_HcFmRemaining].w[0] = dev->ohci_mmio[OHCI_HcFmInterval].w[0] & 0x3fff;
dev->ohci_mmio[OHCI_HcFmRemaining].l &= ~(1 << 31);
dev->ohci_mmio[OHCI_HcFmRemaining].l |= dev->ohci_mmio[OHCI_HcFmInterval].l & (1 << 31);
ohci_start_of_frame(dev);
timer_on_auto(&dev->ohci_frame_timer, 1. / 12.);
return;
}
dev->ohci_mmio[OHCI_HcFmRemaining].w[0]--;
timer_on_auto(&dev->ohci_frame_timer, 1. / 12.);
}
void
@@ -200,7 +463,8 @@ ohci_port_reset_callback(void* priv)
{
usb_t *dev = (usb_t *) priv;
dev->ohci_mmio[OHCI_HcRhPortStatus1] &= ~0x10;
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x10;
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] |= 0x10;
}
void
@@ -208,7 +472,8 @@ ohci_port_reset_callback_2(void* priv)
{
usb_t *dev = (usb_t *) priv;
dev->ohci_mmio[OHCI_HcRhPortStatus2] &= ~0x10;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x10;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] |= 0x10;
}
static void
@@ -217,198 +482,250 @@ ohci_mmio_write(uint32_t addr, uint8_t val, void *p)
usb_t *dev = (usb_t *) p;
uint8_t old;
#ifdef ENABLE_USB_LOG
usb_log("[W] %08X = %04X\n", addr, val);
#endif
addr &= 0x00000fff;
switch (addr) {
case OHCI_HcControl:
case OHCI_aHcControl:
if ((val & 0xc0) == 0x00) {
/* UsbReset */
dev->ohci_mmio[OHCI_HcRhPortStatus1 + 2] = dev->ohci_mmio[OHCI_HcRhPortStatus2 + 2] = 0x16;
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] = dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] = 0x16;
}
break;
case OHCI_HcCommandStatus:
case OHCI_aHcCommandStatus:
/* bit OwnershipChangeRequest triggers an ownership change (SMM <-> OS) */
if (val & 0x08) {
dev->ohci_mmio[OHCI_HcInterruptStatus + 3] = 0x40;
if ((dev->ohci_mmio[OHCI_HcInterruptEnable + 3] & 0xc0) == 0xc0)
dev->ohci_mmio[OHCI_HcInterruptStatus].b[3] = 0x40;
if ((dev->ohci_mmio[OHCI_HcInterruptEnable].b[3] & 0xc0) == 0xc0)
smi_raise();
}
/* bit HostControllerReset must be cleared for the controller to be seen as initialized */
if (val & 0x01) {
memset(dev->ohci_mmio, 0x00, 4096);
dev->ohci_mmio[OHCI_HcRevision] = 0x10;
dev->ohci_mmio[OHCI_HcRevision + 1] = 0x01;
dev->ohci_mmio[OHCI_HcRhDescriptorA] = 0x02;
dev->ohci_mmio[OHCI_HcRevision].b[0] = 0x10;
dev->ohci_mmio[OHCI_HcRevision].b[1] = 0x01;
dev->ohci_mmio[OHCI_HcRhDescriptorA].b[0] = 0x02;
val &= ~0x01;
}
break;
case OHCI_HcHCCA:
case OHCI_aHcHCCA:
return;
case OHCI_HcInterruptStatus:
dev->ohci_mmio[addr] &= ~(val & 0x7f);
case OHCI_aHcInterruptEnable:
dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x7f);
dev->ohci_mmio[OHCI_HcInterruptDisable].b[0] &= ~(val & 0x7f);
ohci_update_irq(dev);
return;
case OHCI_HcInterruptStatus + 1:
case OHCI_HcInterruptStatus + 2:
case OHCI_aHcInterruptEnable + 1:
case OHCI_aHcInterruptEnable + 2:
return;
case OHCI_HcInterruptStatus + 3:
dev->ohci_mmio[addr] &= ~(val & 0x40);
case OHCI_aHcInterruptEnable + 3:
dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0xc0);
dev->ohci_mmio[OHCI_HcInterruptDisable].b[3] &= ~(val & 0xc0);
ohci_update_irq(dev);
return;
case OHCI_HcFmRemaining + 3:
dev->ohci_mmio[addr] = (val & 0x80);
case OHCI_aHcInterruptDisable:
dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x7f);
dev->ohci_mmio[OHCI_HcInterruptEnable].b[0] &= ~(val & 0x7f);
ohci_update_irq(dev);
return;
case OHCI_HcFmRemaining + 1:
case OHCI_HcPeriodicStart + 1:
dev->ohci_mmio[addr] = (val & 0x3f);
case OHCI_aHcInterruptDisable + 1:
case OHCI_aHcInterruptDisable + 2:
return;
case OHCI_HcLSThreshold + 1:
dev->ohci_mmio[addr] = (val & 0x0f);
case OHCI_aHcInterruptDisable + 3:
dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0xc0);
dev->ohci_mmio[OHCI_HcInterruptEnable].b[3] &= ~(val & 0xc0);
ohci_update_irq(dev);
return;
case OHCI_HcFmRemaining + 2:
case OHCI_HcFmNumber + 2:
case OHCI_HcFmNumber + 3:
case OHCI_HcPeriodicStart + 2:
case OHCI_HcPeriodicStart + 3:
case OHCI_HcLSThreshold + 2:
case OHCI_HcLSThreshold + 3:
case OHCI_HcRhDescriptorA:
case OHCI_HcRhDescriptorA + 2:
case OHCI_aHcInterruptStatus:
dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x7f);
return;
case OHCI_HcRhDescriptorA + 1:
dev->ohci_mmio[addr] = (val & 0x1b);
case OHCI_aHcInterruptStatus + 1:
case OHCI_aHcInterruptStatus + 2:
return;
case OHCI_aHcInterruptStatus + 3:
dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x40);
return;
case OHCI_aHcFmRemaining + 3:
dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x80);
return;
case OHCI_aHcFmRemaining + 1:
case OHCI_aHcPeriodicStart + 1:
dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x3f);
return;
case OHCI_aHcLSThreshold + 1:
dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x0f);
return;
case OHCI_aHcFmRemaining + 2:
case OHCI_aHcFmNumber + 2:
case OHCI_aHcFmNumber + 3:
case OHCI_aHcPeriodicStart + 2:
case OHCI_aHcPeriodicStart + 3:
case OHCI_aHcLSThreshold + 2:
case OHCI_aHcLSThreshold + 3:
case OHCI_aHcRhDescriptorA:
case OHCI_aHcRhDescriptorA + 2:
return;
case OHCI_aHcRhDescriptorA + 1:
dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x1b);
if (val & 0x02) {
dev->ohci_mmio[OHCI_HcRhPortStatus1 + 1] |= 0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2 + 1] |= 0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] |= 0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] |= 0x01;
}
return;
case OHCI_HcRhDescriptorA + 3:
dev->ohci_mmio[addr] = (val & 0x03);
case OHCI_aHcRhDescriptorA + 3:
dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x03);
return;
case OHCI_HcRhDescriptorB:
case OHCI_HcRhDescriptorB + 2:
dev->ohci_mmio[addr] = (val & 0x06);
case OHCI_aHcRhDescriptorB:
case OHCI_aHcRhDescriptorB + 2:
dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x06);
if ((addr == OHCI_HcRhDescriptorB) && !(val & 0x04)) {
if (!(dev->ohci_mmio[OHCI_HcRhPortStatus2] & 0x01))
dev->ohci_mmio[OHCI_HcRhPortStatus2 + 2] |= 0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2] |= 0x01;
if (!(dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] & 0x01))
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] |= 0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] |= 0x01;
}
if ((addr == OHCI_HcRhDescriptorB) && !(val & 0x02)) {
if (!(dev->ohci_mmio[OHCI_HcRhPortStatus1] & 0x01))
dev->ohci_mmio[OHCI_HcRhPortStatus1 + 2] |= 0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus1] |= 0x01;
if (!(dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] & 0x01))
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] |= 0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] |= 0x01;
}
return;
case OHCI_HcRhDescriptorB + 1:
case OHCI_HcRhDescriptorB + 3:
case OHCI_aHcRhDescriptorB + 1:
case OHCI_aHcRhDescriptorB + 3:
return;
case OHCI_HcRhStatus:
case OHCI_aHcRhStatus:
if (val & 0x01) {
if ((dev->ohci_mmio[OHCI_HcRhDescriptorA + 1] & 0x03) == 0x00) {
dev->ohci_mmio[OHCI_HcRhPortStatus1 + 1] &= ~0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus1] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus1 + 2] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus2 + 1] &= ~0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus2 + 2] &= ~0x17;
} else if ((dev->ohci_mmio[OHCI_HcRhDescriptorA + 1] & 0x03) == 0x01) {
if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB + 2] & 0x02)) {
dev->ohci_mmio[OHCI_HcRhPortStatus1 + 1] &= ~0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus1] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus1 + 2] &= ~0x17;
if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) {
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] &= ~0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] &= ~0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] &= ~0x17;
} else if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x01) {
if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02)) {
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] &= ~0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] &= ~0x17;
}
if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB + 2] & 0x04)) {
dev->ohci_mmio[OHCI_HcRhPortStatus2 + 1] &= ~0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus2 + 2] &= ~0x17;
if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04)) {
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] &= ~0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] &= ~0x17;
}
}
}
return;
case OHCI_HcRhStatus + 1:
case OHCI_aHcRhStatus + 1:
if (val & 0x80)
dev->ohci_mmio[addr] |= 0x80;
dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x80;
return;
case OHCI_HcRhStatus + 2:
dev->ohci_mmio[addr] &= ~(val & 0x02);
case OHCI_aHcRhStatus + 2:
dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x02);
if (val & 0x01) {
if ((dev->ohci_mmio[OHCI_HcRhDescriptorA + 1] & 0x03) == 0x00) {
dev->ohci_mmio[OHCI_HcRhPortStatus1 + 1] |= 0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2 + 1] |= 0x01;
} else if ((dev->ohci_mmio[OHCI_HcRhDescriptorA + 1] & 0x03) == 0x01) {
if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB + 2] & 0x02))
dev->ohci_mmio[OHCI_HcRhPortStatus1 + 1] |= 0x01;
if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB + 2] & 0x04))
dev->ohci_mmio[OHCI_HcRhPortStatus2 + 1] |= 0x01;
if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) {
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] |= 0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] |= 0x01;
} else if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x01) {
if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02))
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] |= 0x01;
if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04))
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] |= 0x01;
}
}
return;
case OHCI_HcRhStatus + 3:
case OHCI_aHcRhStatus + 3:
if (val & 0x80)
dev->ohci_mmio[OHCI_HcRhStatus + 1] &= ~0x80;
dev->ohci_mmio[OHCI_HcRhStatus].b[1] &= ~0x80;
return;
case OHCI_HcRhPortStatus1:
case OHCI_HcRhPortStatus2:
old = dev->ohci_mmio[addr];
case OHCI_aHcRhPortStatus1:
case OHCI_aHcRhPortStatus2:
old = dev->ohci_mmio[addr >> 2].b[addr & 3];
if (val & 0x10) {
if (old & 0x01) {
dev->ohci_mmio[addr] |= 0x10;
timer_on_auto(&dev->ohci_port_reset_timer[(addr - OHCI_HcRhPortStatus1) / 4], 10000.);
dev->ohci_mmio[addr + 2] |= 0x10;
dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x10;
timer_on_auto(&dev->ohci_port_reset_timer[(addr - OHCI_aHcRhPortStatus1) / 4], 10000.);
} else
dev->ohci_mmio[addr + 2] |= 0x01;
dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01;
}
if (val & 0x08)
dev->ohci_mmio[addr] &= ~0x04;
dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x04;
if (val & 0x04)
dev->ohci_mmio[addr] |= 0x04;
dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x04;
if (val & 0x02) {
if (old & 0x01)
dev->ohci_mmio[addr] |= 0x02;
dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x02;
else
dev->ohci_mmio[addr + 2] |= 0x01;
dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01;
}
if (val & 0x01) {
if (old & 0x01)
dev->ohci_mmio[addr] &= ~0x02;
dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x02;
else
dev->ohci_mmio[addr + 2] |= 0x01;
dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01;
}
if (!(dev->ohci_mmio[addr] & 0x04) && (old & 0x04))
dev->ohci_mmio[addr + 2] |= 0x04;
/* if (!(dev->ohci_mmio[addr] & 0x02))
dev->ohci_mmio[addr + 2] |= 0x02; */
if (!(dev->ohci_mmio[addr >> 2].b[addr & 3] & 0x04) && (old & 0x04))
dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x04;
/* if (!(dev->ohci_mmio[addr >> 2].b[addr & 3] & 0x02))
dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x02; */
return;
case OHCI_HcRhPortStatus1 + 1:
if ((val & 0x02) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA + 1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB + 2] & 0x02)) {
dev->ohci_mmio[addr] &= ~0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus1] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus1 + 2] &= ~0x17;
case OHCI_aHcRhPortStatus1 + 1:
if ((val & 0x02) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02)) {
dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] &= ~0x17;
}
if ((val & 0x01) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA + 1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB + 2] & 0x02)) {
dev->ohci_mmio[addr] |= 0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus2 + 2] &= ~0x17;
if ((val & 0x01) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02)) {
dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x01;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x17;
dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] &= ~0x17;
}
return;
case OHCI_HcRhPortStatus2 + 1:
if ((val & 0x02) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA + 1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB + 2] & 0x04))
dev->ohci_mmio[addr] &= ~0x01;
if ((val & 0x01) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA + 1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB + 2] & 0x04))
dev->ohci_mmio[addr] |= 0x01;
case OHCI_aHcRhPortStatus2 + 1:
if ((val & 0x02) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04))
dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x01;
if ((val & 0x01) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04))
dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x01;
return;
case OHCI_HcRhPortStatus1 + 2:
case OHCI_HcRhPortStatus2 + 2:
dev->ohci_mmio[addr] &= ~(val & 0x1f);
case OHCI_aHcRhPortStatus1 + 2:
case OHCI_aHcRhPortStatus2 + 2:
dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x1f);
return;
case OHCI_HcRhPortStatus1 + 3:
case OHCI_HcRhPortStatus2 + 3:
case OHCI_aHcRhPortStatus1 + 3:
case OHCI_aHcRhPortStatus2 + 3:
return;
case OHCI_aHcDoneHead:
case OHCI_aHcBulkCurrentED:
case OHCI_aHcBulkHeadED:
case OHCI_aHcControlCurrentED:
case OHCI_aHcControlHeadED:
case OHCI_aHcPeriodCurrentED:
dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0xf0);
return;
}
dev->ohci_mmio[addr] = val;
dev->ohci_mmio[addr >> 2].b[addr & 3] = val;
}
static void
ohci_mmio_writew(uint32_t addr, uint16_t val, void *p)
{
ohci_mmio_write(addr, val & 0xff, p);
ohci_mmio_write(addr + 1, val >> 8, p);
}
static void
ohci_mmio_writel(uint32_t addr, uint32_t val, void *p)
{
ohci_mmio_writew(addr, val & 0xffff, p);
ohci_mmio_writew(addr + 2, val >> 16, p);
}
void
ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3, int enable)
{
@@ -420,6 +737,20 @@ ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3,
if (dev->ohci_enable && (dev->ohci_mem_base != 0x00000000))
mem_mapping_set_addr(&dev->ohci_mmio_mapping, dev->ohci_mem_base, 0x1000);
usb_log("ohci_update_mem_mapping(): OHCI %sabled at %08X\n", dev->ohci_enable ? "en" : "dis", dev->ohci_mem_base);
}
uint8_t
usb_attach_device(usb_t *dev, usb_device_t* device, uint8_t bus_type)
{
return 255;
}
void
usb_detach_device(usb_t *dev, uint8_t port, uint8_t bus_type)
{
/* Unused. */
}
static void
@@ -427,20 +758,24 @@ usb_reset(void *priv)
{
usb_t *dev = (usb_t *) priv;
memset(dev->uhci_io, 0x00, 128);
memset(dev->uhci_io, 0x00, sizeof(dev->uhci_io));
dev->uhci_io[0x0c] = 0x40;
dev->uhci_io[0x10] = dev->uhci_io[0x12] = 0x80;
memset(dev->ohci_mmio, 0x00, 4096);
dev->ohci_mmio[OHCI_HcRevision] = 0x10;
dev->ohci_mmio[OHCI_HcRevision + 1] = 0x01;
dev->ohci_mmio[OHCI_HcRhDescriptorA] = 0x02;
memset(dev->ohci_mmio, 0x00, sizeof(dev->ohci_mmio));
dev->ohci_mmio[OHCI_HcRevision].b[0] = 0x10;
dev->ohci_mmio[OHCI_HcRevision].b[1] = 0x01;
dev->ohci_mmio[OHCI_HcRhDescriptorA].b[0] = 0x02;
dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] = 0x02;
io_removehandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, uhci_reg_writew, NULL, dev);
dev->uhci_enable = 0;
mem_mapping_disable(&dev->ohci_mmio_mapping);
dev->ohci_enable = 0;
usb_log("usb_reset(): OHCI %sabled at %08X\n", dev->ohci_enable ? "en" : "dis", dev->ohci_mem_base);
usb_log("usb_reset(): map = %08X\n", &dev->ohci_mmio_mapping);
}
static void
@@ -452,7 +787,7 @@ usb_close(void *priv)
}
static void *
usb_init_ext(const device_t *info, void* params)
usb_init_ext(const device_t *info, void *params)
{
usb_t *dev;
@@ -461,15 +796,19 @@ usb_init_ext(const device_t *info, void* params)
return (NULL);
memset(dev, 0x00, sizeof(usb_t));
dev->usb_params = (usb_params_t*)params;
dev->usb_params = (usb_params_t *) params;
mem_mapping_add(&dev->ohci_mmio_mapping, 0, 0,
ohci_mmio_read, NULL, NULL,
ohci_mmio_write, NULL, NULL,
mem_mapping_add(&dev->ohci_mmio_mapping, 0, 0x1000,
ohci_mmio_read, ohci_mmio_readw, ohci_mmio_readl,
ohci_mmio_write, ohci_mmio_writew, ohci_mmio_writel,
NULL, MEM_MAPPING_EXTERNAL, dev);
mem_mapping_disable(&dev->ohci_mmio_mapping);
timer_add(&dev->ohci_frame_timer, ohci_update_frame_counter, dev, 0); /* Unused for now, to be used for frame counting. */
timer_add(&dev->ohci_port_reset_timer[0], ohci_port_reset_callback, dev, 0);
timer_add(&dev->ohci_port_reset_timer[1], ohci_port_reset_callback_2, dev, 0);
usb_reset(dev);
return dev;

File diff suppressed because it is too large Load Diff

View File

@@ -199,15 +199,19 @@ svga_out(uint16_t addr, uint8_t val, void *p)
break;
}
break;
case 0x2ea:
case 0x3c6:
svga->dac_mask = val;
break;
case 0x2eb:
case 0x2ec:
case 0x3c7:
case 0x3c8:
svga->dac_pos = 0;
svga->dac_status = addr & 0x03;
svga->dac_addr = (val + (addr & 0x01)) & 255;
break;
case 0x2ed:
case 0x3c9:
if (svga->adv_flags & FLAG_RAMDAC_SHIFT)
val <<= 2;
@@ -311,15 +315,19 @@ svga_in(uint16_t addr, void *p)
case 0x3c5:
ret = svga->seqregs[svga->seqaddr & 0x0f];
break;
case 0x2ea:
case 0x3c6:
ret = svga->dac_mask;
break;
case 0x2eb:
case 0x3c7:
ret = svga->dac_status;
break;
case 0x2ec:
case 0x3c8:
ret = svga->dac_addr;
break;
case 0x2ed:
case 0x3c9:
index = (svga->dac_addr - 1) & 255;
switch (svga->dac_pos) {
@@ -572,7 +580,7 @@ svga_recalctimings(svga_t *svga)
svga->recalctimings_ex(svga);
}
} else {
if (ibm8514_on && ibm8514_enabled)
if (ibm8514_enabled)
ibm8514_recalctimings(svga);
if (xga_enabled)
xga_recalctimings(svga);
@@ -872,7 +880,7 @@ svga_poll(void *p)
svga->oddeven ^= 1;
svga->monitor->mon_changeframecount = svga->interlace ? 3 : 2;
svga->vslines = 0;
svga->vslines = 0;
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5);
@@ -893,22 +901,24 @@ svga_poll(void *p)
svga->dispon = 1;
svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0;
svga->scrollcache = (svga->attrregs[0x13] & 0x0f);
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 1)
if (!ibm8514_on) {
svga->scrollcache = (svga->attrregs[0x13] & 0x0f);
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 1)
svga->scrollcache &= 0x07;
else {
svga->scrollcache++;
if (svga->scrollcache > 8)
svga->scrollcache = 0;
}
} else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres))
svga->scrollcache &= 0x07;
else {
svga->scrollcache++;
if (svga->scrollcache > 8)
svga->scrollcache = 0;
}
} else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres))
svga->scrollcache &= 0x07;
else
svga->scrollcache = (svga->scrollcache & 0x06) >> 1;
else
svga->scrollcache = (svga->scrollcache & 0x06) >> 1;
if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres))
svga->scrollcache <<= 1;
if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres))
svga->scrollcache <<= 1;
}
svga->x_add = (svga->monitor->mon_overscan_x >> 1) - svga->scrollcache;
@@ -938,9 +948,9 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize,
{
int c, d, e;
svga->p = p;
svga->p = p;
svga->monitor_index = monitor_index_global;
svga->monitor = &monitors[svga->monitor_index];
svga->monitor = &monitors[svga->monitor_index];
for (c = 0; c < 256; c++) {
e = c;
@@ -954,10 +964,10 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize,
svga->attrregs[0x11] = 0;
svga->overscan_color = 0x000000;
svga->monitor->mon_overscan_x = 16;
svga->monitor->mon_overscan_y = 32;
svga->x_add = 8;
svga->y_add = 16;
svga->monitor->mon_overscan_x = 16;
svga->monitor->mon_overscan_y = 32;
svga->x_add = 8;
svga->y_add = 16;
svga->crtc[0] = 63;
svga->crtc[6] = 255;
@@ -1096,8 +1106,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
svga->xga.linear_endian_reverse = 1;
return;
}
} else
} else {
svga->xga.on = 0;
vga_on = !svga->xga.on;
}
}
addr = svga_decode_addr(svga, addr, 1);
@@ -1286,16 +1298,20 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) {
if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/
svga->xga.on = 1;
vga_on = !svga->xga.on;
return svga->xga.test;
} else if (svga->xga.test == 0x5a) {
svga->xga.on = 1;
vga_on = !svga->xga.on;
return svga->xga.test;
} else if (addr == 0xa0000 || addr == 0xa0010) {
addr += svga->xga.read_bank;
return svga->xga.vram[addr & svga->xga.vram_mask];
}
} else
} else {
svga->xga.on = 0;
vga_on = !svga->xga.on;
}
}
addr = svga_decode_addr(svga, addr, 0);

View File

@@ -1,18 +1,18 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
* This file is part of the 86Box distribution.
*
* IBM XGA emulation.
* IBM XGA emulation.
*
*
*
* Authors: TheCollector1995.
* Authors: TheCollector1995.
*
* Copyright 2022 TheCollector1995.
* Copyright 2022 TheCollector1995.
*/
#include <stdio.h>
#include <stdint.h>
@@ -38,16 +38,19 @@
#define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN"
#define XGA2_BIOS_PATH "roms/video/xga/xga2_v300.bin"
static video_timings_t timing_xga_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 };
static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 };
static void xga_ext_outb(uint16_t addr, uint8_t val, void *p);
static uint8_t xga_ext_inb(uint16_t addr, void *p);
static void
void
xga_updatemapping(svga_t *svga)
{
xga_t *xga = &svga->xga;
// pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, opmodereset1 = %d, access mode = %x, map = %x.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->op_mode_reset, xga->access_mode, svga->gdcreg[6] & 0x0c);
if ((xga->op_mode & 7) >= 4) {
//pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, opmodereset1 = %d, access mode = %x, map = %x.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->op_mode_reset, xga->access_mode, svga->gdcreg[6] & 0x0c);
if (((xga->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) {
if (xga->aperture_cntl == 1) {
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
@@ -56,25 +59,22 @@ xga_updatemapping(svga_t *svga)
if (!xga->linear_endian_reverse)
mem_mapping_disable(&xga->linear_mapping);
} else if (xga->aperture_cntl == 0) {
linear:
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
mem_mapping_enable(&xga->video_mapping);
xga->banked_mask = 0xffff;
if ((xga->pos_regs[4] & 1) && !xga->base_addr_1mb) {
xga->linear_size = 0x400000;
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, xga->linear_size);
} else {
if (xga->base_addr_1mb) {
xga->linear_size = 0x100000;
mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, xga->linear_size);
} else
mem_mapping_disable(&xga->linear_mapping);
}
xga->on = 0;
vga_on = 1;
if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test)
if (xga->pos_regs[4] & 1)
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000);
else if (xga->base_addr_1mb)
mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000);
else
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000);
if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && xga->on)
xga->linear_endian_reverse = 1;
else if (((xga->op_mode & 7) == 0) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && !xga->on)
xga->linear_endian_reverse = 1;
xga->on = 0;
vga_on = !xga->on;
} else {
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
@@ -83,23 +83,17 @@ linear:
mem_mapping_disable(&xga->linear_mapping);
}
} else {
if (!(xga->op_mode & 7)) {
goto linear;
}
if (xga->aperture_cntl == 2) {
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
mem_mapping_enable(&xga->video_mapping);
xga->banked_mask = 0xffff;
} else {
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
mem_mapping_enable(&xga->video_mapping);
xga->banked_mask = 0xffff;
}
mem_mapping_disable(&xga->linear_mapping);
xga->on = 0;
vga_on = 1;
vga_on = !xga->on;
mem_mapping_disable(&svga->mapping);
if (xga->aperture_cntl == 2)
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
else
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
mem_mapping_enable(&xga->video_mapping);
xga->banked_mask = 0xffff;
mem_mapping_disable(&xga->linear_mapping);
//pclog("XGA opmode (not extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7, xga->disp_cntl_2 & 7, xga->aperture_cntl);
}
}
@@ -147,8 +141,6 @@ xga_recalctimings(svga_t *svga)
svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0;
break;
}
} else {
vga_on = 1;
}
}
@@ -292,6 +284,8 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
case 0x51:
xga->disp_cntl_2 = val;
xga->on = ((val & 7) >= 3);
vga_on = !xga->on;
svga_recalctimings(svga);
break;
@@ -318,7 +312,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
else if (xga->sprite_pos >= 1)
xga->cursor_data_on = 1;
else if (xga->aperture_cntl == 0) {
if (xga->linear_endian_reverse)
if (xga->linear_endian_reverse && !(xga->access_mode & 8))
xga->cursor_data_on = 0;
}
}
@@ -351,7 +345,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
break;
case 0x65:
svga->fullchange = changeframecount;
svga->fullchange = svga->monitor->mon_changeframecount;
switch (svga->dac_pos) {
case 0:
svga->dac_r = val;
@@ -406,7 +400,7 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *p)
svga_t *svga = (svga_t *) p;
xga_t *xga = &svga->xga;
// pclog("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val);
//pclog("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val);
switch (addr & 0x0f) {
case 0:
xga->op_mode = val;
@@ -421,12 +415,10 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *p)
xga->aperture_cntl = 0;
break;
case 6:
vga_on = 0;
xga->on = 1;
break;
case 8:
xga->ap_idx = val;
// pclog("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, val, val & 0x3f);
//pclog("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, val, val & 0x3f);
if ((xga->op_mode & 7) < 4) {
xga->write_bank = xga->read_bank = 0;
} else {
@@ -586,10 +578,10 @@ xga_ext_inb(uint16_t addr, void *p)
ret = xga->disp_cntl_2;
break;
case 0x52:
ret = 0x0b;
ret = xga->type ? 0xfa : 0xea;
break;
case 0x53:
ret = 0x70;
ret = xga->type ? 0x53 : 0x30;
break;
case 0x54:
ret = xga->clk_sel_1;
@@ -667,7 +659,7 @@ xga_ext_inb(uint16_t addr, void *p)
break;
}
// pclog("[%04X:%08X]: EXT INB = %02x, ret = %02x\n", CS, cpu_state.pc, addr, ret);
//pclog("[%04X:%08X]: EXT INB = %02x, ret = %02x\n", CS, cpu_state.pc, addr, ret);
return ret;
}
@@ -676,7 +668,7 @@ xga_ext_inb(uint16_t addr, void *p)
#define WRITE(addr, dat) \
xga->vram[((addr)) & (xga->vram_mask)] = dat; \
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount;
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
#define READW(addr, dat) \
dat = *(uint16_t *) &xga->vram[(addr) & (xga->vram_mask)];
@@ -687,12 +679,12 @@ xga_ext_inb(uint16_t addr, void *p)
#define WRITEW(addr, dat) \
*(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount;
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
#define WRITEW_REVERSE(addr, dat) \
xga->vram[((addr + 1)) & (xga->vram_mask - 1)] = dat & 0xff; \
xga->vram[((addr)) & (xga->vram_mask - 1)] = dat >> 8; \
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount;
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
#define ROP(mix, d, s) \
{ \
@@ -908,12 +900,12 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
if (pixel & 1) {
if (!skip) {
xga->vram[((addr)) & (xga->vram_mask)] |= mask;
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount;
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
}
} else {
if (!skip) {
xga->vram[((addr)) & (xga->vram_mask)] &= ~mask;
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount;
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
}
}
mem_writeb_phys(addr, byte);
@@ -2198,7 +2190,7 @@ xga_write(uint32_t addr, uint8_t val, void *p)
cycles -= video_timing_write_b;
xga->changedvram[(addr & xga->vram_mask) >> 12] = changeframecount;
xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount;
xga->vram[addr & xga->vram_mask] = val;
}
@@ -2245,7 +2237,7 @@ xga_write_linear(uint32_t addr, uint8_t val, void *p)
cycles -= video_timing_write_b;
xga->changedvram[(addr & xga->vram_mask) >> 12] = changeframecount;
xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount;
xga->vram[addr & xga->vram_mask] = val;
}
@@ -2559,7 +2551,7 @@ xga_poll(xga_t *xga, svga_t *svga)
xga->oddeven ^= 1;
changeframecount = xga->interlace ? 3 : 2;
svga->monitor->mon_changeframecount = xga->interlace ? 3 : 2;
if (xga->interlace && xga->oddeven)
xga->ma = xga->maback = xga->ma_latch + (xga->rowoffset << 1);
@@ -2588,9 +2580,13 @@ xga_mca_read(int port, void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = &svga->xga;
uint8_t ret = xga->pos_regs[port & 7];
// pclog("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc, port & 7, xga->pos_regs[port & 7]);
return (xga->pos_regs[port & 7]);
if (((port & 7) == 3) && !(ret & 1)) /*Always enable the mapping.*/
ret |= 1;
//pclog("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc, port & 7, xga->pos_regs[port & 7]);
return (ret);
}
static void
@@ -2607,11 +2603,13 @@ xga_mca_write(int port, uint8_t val, void *priv)
mem_mapping_disable(&xga->bios_rom.mapping);
mem_mapping_disable(&xga->memio_mapping);
xga->on = 0;
vga_on = 1;
vga_on = !xga->on;
xga->linear_endian_reverse = 0;
xga->a5_test = 0;
/* Save the MCA register value. */
xga->pos_regs[port & 7] = val;
if (!(xga->pos_regs[4] & 1)) /*MCA 4MB addressing on systems with more than 16MB of memory*/
if (!(xga->pos_regs[4] & 1) && (mem_size >= 16384)) /*MCA 4MB addressing on systems with more than 16MB of memory*/
xga->pos_regs[4] |= 1;
if (xga->pos_regs[2] & 1) {
@@ -2622,13 +2620,12 @@ xga_mca_write(int port, uint8_t val, void *priv)
io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga);
if (xga->pos_regs[3] & 1) {
if (xga->pos_regs[3] & 1)
mem_mapping_set_addr(&xga->bios_rom.mapping, xga->rom_addr, 0x2000);
} else {
else
mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80);
}
}
// pclog("[%04X:%08X]: POS Write Port = %x, val = %02x, linear base = %08x, instance = %d, rom addr = %05x\n", CS, cpu_state.pc, port & 7, val, xga->linear_base, xga->instance, xga->rom_addr);
//pclog("[%04X:%08X]: POS Write Port = %x, val = %02x, linear base = %08x, instance = %d, rom addr = %05x\n", CS, cpu_state.pc, port & 7, val, xga->linear_base, xga->instance, xga->rom_addr);
}
static uint8_t
@@ -2644,10 +2641,27 @@ static void
xga_mca_reset(void *p)
{
svga_t *svga = (svga_t *) p;
xga_t *xga = &svga->xga;
xga->on = 0;
vga_on = !xga->on;
xga_mca_write(0x102, 0, svga);
}
static void
xga_reset(void *p)
{
svga_t *svga = (svga_t *) p;
xga_t *xga = &svga->xga;
mem_mapping_disable(&xga->bios_rom.mapping);
mem_mapping_disable(&xga->memio_mapping);
xga->on = 0;
vga_on = !xga->on;
xga->linear_endian_reverse = 0;
xga->a5_test = 0;
}
static uint8_t
xga_pos_in(uint16_t addr, void *priv)
{
@@ -2660,10 +2674,13 @@ static void
*
xga_init(const device_t *info)
{
if (svga_get_pri() == NULL)
return NULL;
svga_t *svga = svga_get_pri();
xga_t *xga = &svga->xga;
FILE *f;
uint32_t initial_bios_addr = device_get_config_hex20("init_bios_addr");
uint32_t temp;
uint8_t *rom = NULL;
xga->type = device_get_config_int("type");
@@ -2682,11 +2699,13 @@ static void
f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb");
(void) fseek(f, 0L, SEEK_END);
temp = ftell(f);
(void) fseek(f, 0L, SEEK_SET);
rom = malloc(xga->bios_rom.sz);
memset(rom, 0xff, xga->bios_rom.sz);
(void) !fread(rom, xga->bios_rom.sz, 1, f);
(void) fread(rom, xga->bios_rom.sz, 1, f);
temp -= xga->bios_rom.sz;
(void) fclose(f);
xga->bios_rom.rom = rom;
@@ -2697,11 +2716,13 @@ static void
xga->base_addr_1mb = 0;
if (info->flags & DEVICE_MCA) {
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_mca);
xga->linear_base = 0;
xga->instance = 0;
xga->rom_addr = 0;
rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, initial_bios_addr, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, 0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
} else {
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa);
xga->pos_regs[2] = 1 | 0x0c | 0xf0;
xga->instance = (xga->pos_regs[2] & 0x0e) >> 1;
xga->pos_regs[4] = 1 | 2;
@@ -2768,30 +2789,11 @@ xga_force_redraw(void *p)
{
svga_t *svga = (svga_t *) p;
svga->fullchange = changeframecount;
svga->fullchange = svga->monitor->mon_changeframecount;
}
static const device_config_t xga_configuration[] = {
// clang-format off
{
.name = "init_bios_addr",
.description = "Initial MCA BIOS Address (before POS configuration)",
.type = CONFIG_HEX20,
.default_string = "",
.default_int = 0xc0000,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "C000H", .value = 0xc0000 },
{ .description = "C800H", .value = 0xc8000 },
{ .description = "CC00H", .value = 0xcc000 },
{ .description = "D000H", .value = 0xd0000 },
{ .description = "D400H", .value = 0xd4000 },
{ .description = "D800H", .value = 0xd8000 },
{ .description = "DC00H", .value = 0xdc000 },
{ .description = "" }
},
},
{
.name = "type",
.description = "XGA type",
@@ -2813,7 +2815,7 @@ static const device_config_t xga_configuration[] = {
}
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
// clang-format on
};
const device_t xga_device = {
@@ -2823,7 +2825,7 @@ const device_t xga_device = {
.local = 0,
.init = xga_init,
.close = xga_close,
.reset = NULL,
.reset = xga_reset,
{ .available = xga_available },
.speed_changed = xga_speed_changed,
.force_redraw = xga_force_redraw,
@@ -2837,7 +2839,7 @@ const device_t xga_isa_device = {
.local = 0,
.init = xga_init,
.close = xga_close,
.reset = NULL,
.reset = xga_reset,
{ .available = xga_available },
.speed_changed = xga_speed_changed,
.force_redraw = xga_force_redraw,

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Kontrola BPB"
#define STR_CDROM_DRIVES "Mechaniky CD-ROM:"
#define STR_CD_SPEED "Rychlost:"
#define STR_EARLY "Časná mechanika"
#define STR_MO_DRIVES "Magnetooptické mechaniky:"
#define STR_ZIP_DRIVES "Mechaniky ZIP:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Resetovat"
IDS_2160 "Vypnout skrze rozhraní ACPI"
IDS_2161 "Nastavení"
IDS_2162 "Časná mechanika"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "BPB überprüfen"
#define STR_CDROM_DRIVES "CD-ROM-Laufwerke:"
#define STR_CD_SPEED "Geschwindigkeit:"
#define STR_EARLY "Früheres Laufwerk"
#define STR_MO_DRIVES "MO-Laufwerke:"
#define STR_ZIP_DRIVES "ZIP-Laufwerke:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Hard-Reset"
IDS_2160 "ACPI-basiertes Herunterfahren"
IDS_2161 "Optionen"
IDS_2162 "Früheres Laufwerk"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -402,23 +402,67 @@ FONT FONT_SIZE, FONT_NAME
BEGIN
LTEXT STR_NET_TYPE, IDT_NET_TYPE,
CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT
COMBOBOX IDC_COMBO_NET1_TYPE,
CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT STR_PCAP, IDT_PCAP,
CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT
COMBOBOX IDC_COMBO_PCAP1,
CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT,
CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT
LTEXT STR_NET, IDT_NET,
CFG_HMARGIN + (CFG_PANE_LTEXT_PRI_WIDTH * 2) + 20, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT
COMBOBOX IDC_COMBO_NET1_TYPE,
CFG_HMARGIN, 28, 32, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBO_PCAP1,
CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 28, 110, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT STR_NET, IDT_NET,
CFG_HMARGIN, 47, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT
COMBOBOX IDC_COMBO_NET1,
CFG_COMBO_BOX_LEFT, 45, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT,
CFG_HMARGIN + (CFG_PANE_LTEXT_PRI_WIDTH * 2) + 20, 28, 110, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET1,
CFG_COMBO_BTN_LEFT, 44, CFG_BTN_WIDTH, CFG_BTN_HEIGHT
CFG_HMARGIN + (CFG_PANE_LTEXT_PRI_WIDTH * 3) + 50, 27, CFG_BTN_WIDTH, CFG_BTN_HEIGHT
COMBOBOX IDC_COMBO_NET2_TYPE,
CFG_HMARGIN, 49, 32, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBO_PCAP2,
CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 49, 110, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBO_NET2,
CFG_HMARGIN + (CFG_PANE_LTEXT_PRI_WIDTH * 2) + 20, 49, 110, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET2,
CFG_HMARGIN + (CFG_PANE_LTEXT_PRI_WIDTH * 3) + 50, 48, CFG_BTN_WIDTH, CFG_BTN_HEIGHT
COMBOBOX IDC_COMBO_NET3_TYPE,
CFG_HMARGIN, 70, 32, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBO_PCAP3,
CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 70, 110, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBO_NET3,
CFG_HMARGIN + (CFG_PANE_LTEXT_PRI_WIDTH * 2) + 20, 70, 110, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET3,
CFG_HMARGIN + (CFG_PANE_LTEXT_PRI_WIDTH * 3) + 50, 69, CFG_BTN_WIDTH, CFG_BTN_HEIGHT
COMBOBOX IDC_COMBO_NET4_TYPE,
CFG_HMARGIN, 91, 32, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBO_PCAP4,
CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 91, 110, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBO_NET4,
CFG_HMARGIN + (CFG_PANE_LTEXT_PRI_WIDTH * 2) + 20, 91, 110, CFG_COMBO_HEIGHT,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET4,
CFG_HMARGIN + (CFG_PANE_LTEXT_PRI_WIDTH * 3) + 50, 90, CFG_BTN_WIDTH, CFG_BTN_HEIGHT
END
DLG_CFG_PORTS DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT
@@ -789,10 +833,13 @@ BEGIN
COMBOBOX IDC_COMBO_CD_SPEED,
33, 205, 140, 12,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL STR_EARLY, IDC_CHECKEARLY,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
186, 206, 84, CFG_CHECKBOX_HEIGHT
/*
LTEXT STR_TYPE, IDT_CD_TYPE,
CFG_HMARGIN, 233, 34, CFG_PANE_LTEXT_HEIGHT
COMBOBOX IDC_COMBO_CD_SPEED,
33, 231, 140, 12,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
*/
END
DLG_CFG_OTHER_REMOVABLE_DEVICES DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Check BPB"
#define STR_CDROM_DRIVES "CD-ROM drives:"
#define STR_CD_SPEED "Speed:"
#define STR_EARLY "Earlier drive"
#define STR_MO_DRIVES "MO drives:"
#define STR_ZIP_DRIVES "ZIP drives:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Hard reset"
IDS_2160 "ACPI shutdown"
IDS_2161 "Settings"
IDS_2162 "Earlier drive"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Check BPB"
#define STR_CDROM_DRIVES "CD-ROM drives:"
#define STR_CD_SPEED "Speed:"
#define STR_EARLY "Earlier drive"
#define STR_MO_DRIVES "MO drives:"
#define STR_ZIP_DRIVES "ZIP drives:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Hard reset"
IDS_2160 "ACPI shutdown"
IDS_2161 "Settings"
IDS_2162 "Earlier drive"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Chequear BPB"
#define STR_CDROM_DRIVES "Unidades de CD-ROM:"
#define STR_CD_SPEED "Velocidad:"
#define STR_EARLY "Unidad anterior"
#define STR_MO_DRIVES "Unidades MO:"
#define STR_ZIP_DRIVES "Unidades ZIP:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Hard reset"
IDS_2160 "ACPI shutdown"
IDS_2161 "Settings"
IDS_2162 "Unidad anterior"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Tarkista BPB"
#define STR_CDROM_DRIVES "CD-ROM-asemat:"
#define STR_CD_SPEED "Nopeus:"
#define STR_EARLY "Aiemmat asemat"
#define STR_MO_DRIVES "Magneettisoptiset asemat (MO):"
#define STR_ZIP_DRIVES "ZIP-asemat:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Kylmä uudelleenkäynnistys"
IDS_2160 "ACPI-sammutus"
IDS_2161 "Asetukset"
IDS_2162 "Aiemmat asemat"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Vérifier BPB"
#define STR_CDROM_DRIVES "Lecterus CD-ROM:"
#define STR_CD_SPEED "Vitesse:"
#define STR_EARLY "Lecteur plus tôt"
#define STR_MO_DRIVES "Lecteurs magnéto-optiques:"
#define STR_ZIP_DRIVES "Lecteurs ZIP:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Hard reset"
IDS_2160 "ACPI shutdown"
IDS_2161 "Settings"
IDS_2162 "Lecteur plus tôt"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Provjeraj BPB"
#define STR_CDROM_DRIVES "CD-ROM pogoni:"
#define STR_CD_SPEED "Brzina:"
#define STR_EARLY "Raniji pogon"
#define STR_MO_DRIVES "MO pogoni:"
#define STR_ZIP_DRIVES "ZIP pogoni:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Ponovno pokretanje"
IDS_2160 "ACPI bazirano gašenje"
IDS_2161 "Postavke"
IDS_2162 "Raniji pogon"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -373,7 +373,6 @@ END
#define STR_CHECKBPB "BPB ellenőrzés"
#define STR_CDROM_DRIVES "CD-ROM meghajtók:"
#define STR_CD_SPEED "Seb.:"
#define STR_EARLY "Korábbi meghajtó"
#define STR_MO_DRIVES "MO-meghajtók:"
#define STR_ZIP_DRIVES "ZIP-meghajtók:"
@@ -542,7 +541,7 @@ BEGIN
IDS_2159 "Hard reset"
IDS_2160 "ACPI shutdown"
IDS_2161 "Settings"
IDS_2162 "Korábbi meghajtó"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -369,7 +369,6 @@ END
#define STR_CHECKBPB "Verifica BPB"
#define STR_CDROM_DRIVES "Unità CD-ROM:"
#define STR_CD_SPEED "Veloc.:"
#define STR_EARLY "Unità anteriore"
#define STR_MO_DRIVES "Unità magneto-ottiche:"
#define STR_ZIP_DRIVES "Unità ZIP:"
@@ -539,7 +538,7 @@ BEGIN
IDS_2159 "Hard reset"
IDS_2160 "ACPI shutdown"
IDS_2161 "Settings"
IDS_2162 "Unità anteriore"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "BPBをチェック"
#define STR_CDROM_DRIVES "CD-ROMドライブ:"
#define STR_CD_SPEED "速度:"
#define STR_EARLY "アーリードライブ"
#define STR_MO_DRIVES "光磁気ドライブ:"
#define STR_ZIP_DRIVES "ZIPドライブ:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "ハードリセット"
IDS_2160 "ACPIシャットダウン"
IDS_2161 "設定"
IDS_2162 "アーリードライブ"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "BPB 확인"
#define STR_CDROM_DRIVES "CD-ROM 드라이브:"
#define STR_CD_SPEED "속도:"
#define STR_EARLY "이전 드라이브"
#define STR_MO_DRIVES "광자기 드라이브:"
#define STR_ZIP_DRIVES "ZIP 드라이브:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "재시작"
IDS_2160 "ACPI 종료"
IDS_2161 "설정"
IDS_2162 "이전 드라이브"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Sprawdzaj BPB"
#define STR_CDROM_DRIVES "Napędy CD-ROM:"
#define STR_CD_SPEED "Szybkość:"
#define STR_EARLY "Wcześniejszy napęd"
#define STR_MO_DRIVES "Napędy MO:"
#define STR_ZIP_DRIVES "Napędy ZIP:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Twardy reset"
IDS_2160 "Wyłączenie ACPI"
IDS_2161 "Ustawienia"
IDS_2162 "Wcześniejszy napęd"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -371,7 +371,6 @@ END
#define STR_CHECKBPB "Verificar BPB"
#define STR_CDROM_DRIVES "Unidades de CD-ROM:"
#define STR_CD_SPEED "Veloc.:"
#define STR_EARLY "Unidade anterior"
#define STR_MO_DRIVES "Unidades magneto-ópticas:"
#define STR_ZIP_DRIVES "Unidades ZIP:"
@@ -541,7 +540,7 @@ BEGIN
IDS_2159 "Reinicialização completa"
IDS_2160 "Desligamento por ACPI"
IDS_2161 "Configurações"
IDS_2162 "Unidade anterior"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Verificar BPB"
#define STR_CDROM_DRIVES "Unidades CD-ROM:"
#define STR_CD_SPEED "Velocidade:"
#define STR_EARLY "Unidade anterior"
#define STR_MO_DRIVES "Unidades magneto-ópticas:"
#define STR_ZIP_DRIVES "Unidades ZIP:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Reinicialização completa"
IDS_2160 "Encerramento ACPI"
IDS_2161 "Definições"
IDS_2162 "Unidade anterior"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Проверять BPB"
#define STR_CDROM_DRIVES "Дисководы CD-ROM:"
#define STR_CD_SPEED "Скорость:"
#define STR_EARLY "Предыдущий дисковод"
#define STR_MO_DRIVES "Магнитооптические дисководы:"
#define STR_ZIP_DRIVES "ZIP дисководы:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Холодная перезагрузка"
IDS_2160 "Сигнал завершения ACPI"
IDS_2161 "Настройки машины"
IDS_2162 "Предыдущий дисковод"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Preverjaj BPB"
#define STR_CDROM_DRIVES "Pogoni CD-ROM:"
#define STR_CD_SPEED "Hitrost:"
#define STR_EARLY "Zgodnejši pogon"
#define STR_MO_DRIVES "Magnetno-optični pogoni:"
#define STR_ZIP_DRIVES "Pogoni ZIP:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Ponovni zagon"
IDS_2160 "Zaustavitev ACPI"
IDS_2161 "Nastavitve"
IDS_2162 "Zgodnejši pogon"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "BPB'yi denetle"
#define STR_CDROM_DRIVES "CD-ROM sürücüleri:"
#define STR_CD_SPEED "Hız:"
#define STR_EARLY "Daha erken sürüş"
#define STR_MO_DRIVES "MO sürücüleri:"
#define STR_ZIP_DRIVES "ZIP sürücüleri:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Makineyi yeniden başlat"
IDS_2160 "ACPI kapatma"
IDS_2161 "Ayarlar"
IDS_2162 "Daha erken sürüş"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "Перевіряти BPB"
#define STR_CDROM_DRIVES "Дисководи CD-ROM:"
#define STR_CD_SPEED "Швидкість:"
#define STR_EARLY "Більш ранній дисковод"
#define STR_MO_DRIVES "Магнітооптичні дисководи:"
#define STR_ZIP_DRIVES "ZIP дисководи:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "Холодне перезавантаження"
IDS_2160 "Сигнал завершення ACPI"
IDS_2161 "Налаштування машини"
IDS_2162 "Більш ранній дисковод"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "检查 BPB"
#define STR_CDROM_DRIVES "光盘驱动器:"
#define STR_CD_SPEED "速度:"
#define STR_EARLY "早先的驱动器"
#define STR_MO_DRIVES "磁光盘驱动器:"
#define STR_ZIP_DRIVES "ZIP 驱动器:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "硬重置"
IDS_2160 "ACPI 关机"
IDS_2161 "设置"
IDS_2162 "早先的驱动器"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -368,7 +368,6 @@ END
#define STR_CHECKBPB "檢查 BPB"
#define STR_CDROM_DRIVES "光碟機:"
#define STR_CD_SPEED "速度:"
#define STR_EARLY "早先的光碟機"
#define STR_MO_DRIVES "磁光碟機:"
#define STR_ZIP_DRIVES "ZIP 磁碟機:"
@@ -538,7 +537,7 @@ BEGIN
IDS_2159 "硬重設"
IDS_2160 "ACPI 關機"
IDS_2161 "設定"
IDS_2162 "早先的光碟機"
IDS_2162 "Type"
IDS_2163 "No Dynarec"
IDS_2164 "Old Dynarec"
IDS_2165 "New Dynarec"

View File

@@ -2037,16 +2037,12 @@ network_recalc_combos(HWND hdlg)
{
ignore_change = 1;
#if 0
for (uint8_t i = 0; i < NET_CARD_MAX; i++) {
#endif
settings_enable_window(hdlg, IDC_COMBO_PCAP1, temp_net_type[0] == NET_TYPE_PCAP);
settings_enable_window(hdlg, IDC_COMBO_NET1,
(temp_net_type[0] == NET_TYPE_SLIRP) || ((temp_net_type[0] == NET_TYPE_PCAP) && (network_dev_to_id(temp_pcap_dev[0]) > 0)));
settings_enable_window(hdlg, IDC_CONFIGURE_NET1, network_card_has_config(temp_net_card[0]) && ((temp_net_type[0] == NET_TYPE_SLIRP) || ((temp_net_type[0] == NET_TYPE_PCAP) && (network_dev_to_id(temp_pcap_dev[0]) > 0))));
#if 0
settings_enable_window(hdlg, IDC_COMBO_PCAP1 + i, temp_net_type[i] == NET_TYPE_PCAP);
settings_enable_window(hdlg, IDC_COMBO_NET1 + i,
(temp_net_type[i] == NET_TYPE_SLIRP) || ((temp_net_type[i] == NET_TYPE_PCAP) && (network_dev_to_id(temp_pcap_dev[i]) > 0)));
settings_enable_window(hdlg, IDC_CONFIGURE_NET1 + i, network_card_has_config(temp_net_card[i]) && ((temp_net_type[i] == NET_TYPE_SLIRP) || ((temp_net_type[i] == NET_TYPE_PCAP) && (network_dev_to_id(temp_pcap_dev[i]) > 0))));
}
#endif
ignore_change = 0;
}
@@ -2065,73 +2061,80 @@ win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
case WM_INITDIALOG:
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
#if 0
for (uint8_t i = 0; i < NET_CARD_MAX; i++) {
#endif
settings_add_string(hdlg, IDC_COMBO_NET1_TYPE, (LPARAM) L"None");
settings_add_string(hdlg, IDC_COMBO_NET1_TYPE, (LPARAM) L"SLiRP");
settings_add_string(hdlg, IDC_COMBO_NET1_TYPE, (LPARAM) L"PCap");
settings_set_cur_sel(hdlg, IDC_COMBO_NET1_TYPE, temp_net_type[0]);
settings_enable_window(hdlg, IDC_COMBO_PCAP1, temp_net_type[0] == NET_TYPE_PCAP);
settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"None");
settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"SLiRP");
settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"PCap");
settings_set_cur_sel(hdlg, IDC_COMBO_NET1_TYPE + i, temp_net_type[i]);
settings_enable_window(hdlg, IDC_COMBO_PCAP1 + i, temp_net_type[i] == NET_TYPE_PCAP);
for (c = 0; c < network_ndev; c++) {
mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1);
settings_add_string(hdlg, IDC_COMBO_PCAP1, (LPARAM) lptsTemp);
}
settings_set_cur_sel(hdlg, IDC_COMBO_PCAP1, network_dev_to_id(temp_pcap_dev[0]));
for (c = 0; c < network_ndev; c++) {
mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1);
settings_add_string(hdlg, IDC_COMBO_PCAP1 + i, (LPARAM) lptsTemp);
}
settings_set_cur_sel(hdlg, IDC_COMBO_PCAP1 + i, network_dev_to_id(temp_pcap_dev[i]));
/* NIC config */
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_NET1);
while (1) {
generate_device_name(network_card_getdevice(c), network_card_get_internal_name(c), 1);
/* NIC config */
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_NET1 + i);
while (1) {
generate_device_name(network_card_getdevice(c), network_card_get_internal_name(c), 1);
if (device_name[0] == L'\0')
break;
if (device_name[0] == L'\0')
break;
if (network_card_available(c) && device_is_valid(network_card_getdevice(c), temp_machine)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_NET1, win_get_string(IDS_2104));
else
settings_add_string(hdlg, IDC_COMBO_NET1, (LPARAM) device_name);
settings_list_to_device[0][d] = c;
if ((c == 0) || (c == temp_net_card[0]))
settings_set_cur_sel(hdlg, IDC_COMBO_NET1, d);
d++;
if (network_card_available(c) && device_is_valid(network_card_getdevice(c), temp_machine)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_NET1 + i, win_get_string(IDS_2104));
else
settings_add_string(hdlg, IDC_COMBO_NET1 + i, (LPARAM) device_name);
settings_list_to_device[0][d] = c;
if ((c == 0) || (c == temp_net_card[i]))
settings_set_cur_sel(hdlg, IDC_COMBO_NET1 + i, d);
d++;
}
c++;
}
c++;
settings_enable_window(hdlg, IDC_COMBO_NET1 + i, d);
network_recalc_combos(hdlg);
}
settings_enable_window(hdlg, IDC_COMBO_NET1, d);
network_recalc_combos(hdlg);
free(lptsTemp);
#if 0
}
#endif
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_COMBO_NET1_TYPE:
#if 0
case IDC_COMBO_NET2_TYPE:
case IDC_COMBO_NET3_TYPE:
case IDC_COMBO_NET4_TYPE:
#endif
if (ignore_change)
return FALSE;
temp_net_type[0] = settings_get_cur_sel(hdlg, IDC_COMBO_NET1_TYPE);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET2_TYPE:
if (ignore_change)
return FALSE;
temp_net_type[1] = settings_get_cur_sel(hdlg, IDC_COMBO_NET2_TYPE);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET3_TYPE:
if (ignore_change)
return FALSE;
temp_net_type[2] = settings_get_cur_sel(hdlg, IDC_COMBO_NET3_TYPE);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET4_TYPE:
if (ignore_change)
return FALSE;
temp_net_type[3] = settings_get_cur_sel(hdlg, IDC_COMBO_NET4_TYPE);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_PCAP1:
#if 0
case IDC_COMBO_PCAP2:
case IDC_COMBO_PCAP3:
case IDC_COMBO_PCAP4:
#endif
if (ignore_change)
return FALSE;
@@ -2139,46 +2142,98 @@ win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
strcpy(temp_pcap_dev[0], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP1)].device);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_PCAP2:
if (ignore_change)
return FALSE;
memset(temp_pcap_dev[1], '\0', sizeof(temp_pcap_dev[1]));
strcpy(temp_pcap_dev[1], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP2)].device);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_PCAP3:
if (ignore_change)
return FALSE;
memset(temp_pcap_dev[2], '\0', sizeof(temp_pcap_dev[2]));
strcpy(temp_pcap_dev[2], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP3)].device);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_PCAP4:
if (ignore_change)
return FALSE;
memset(temp_pcap_dev[3], '\0', sizeof(temp_pcap_dev[3]));
strcpy(temp_pcap_dev[3], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP4)].device);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET1:
#if 0
case IDC_COMBO_NET2:
case IDC_COMBO_NET3:
case IDC_COMBO_NET4:
#endif
if (ignore_change)
return FALSE;
temp_net_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1)];
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET2:
if (ignore_change)
return FALSE;
temp_net_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET2)];
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET3:
if (ignore_change)
return FALSE;
temp_net_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET3)];
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET4:
if (ignore_change)
return FALSE;
temp_net_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET4)];
network_recalc_combos(hdlg);
break;
case IDC_CONFIGURE_NET1:
#if 0
case IDC_CONFIGURE_NET2:
case IDC_CONFIGURE_NET3:
case IDC_CONFIGURE_NET4:
#endif
if (ignore_change)
return FALSE;
temp_net_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[0]));
break;
case IDC_CONFIGURE_NET2:
if (ignore_change)
return FALSE;
temp_net_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET2)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[1]));
break;
case IDC_CONFIGURE_NET3:
if (ignore_change)
return FALSE;
temp_net_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET3)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[2]));
break;
case IDC_CONFIGURE_NET4:
if (ignore_change)
return FALSE;
temp_net_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET4)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[3]));
break;
}
return FALSE;
case WM_SAVESETTINGS:
#if 0
for (uint8_t i = 0; i < NET_CARD_MAX; i++) {
#endif
temp_net_type[0] = settings_get_cur_sel(hdlg, IDC_COMBO_NET1_TYPE);
memset(temp_pcap_dev[0], '\0', sizeof(temp_pcap_dev[0]));
strcpy(temp_pcap_dev[0], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP1)].device);
temp_net_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1)];
#if 0
temp_net_type[i] = settings_get_cur_sel(hdlg, IDC_COMBO_NET1_TYPE + i);
memset(temp_pcap_dev[i], '\0', sizeof(temp_pcap_dev[i]));
strcpy(temp_pcap_dev[i], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP1 + i)].device);
temp_net_card[i] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1 + i)];
}
#endif
default:
return FALSE;
}
@@ -3959,6 +4014,7 @@ win_settings_cdrom_drives_recalc_list(HWND hdlg)
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
/*
lvI.iSubItem = 2;
lvI.pszText = plat_get_string(temp_cdrom[i].early ? IDS_2060 : IDS_2061);
lvI.iItem = i;
@@ -3966,6 +4022,7 @@ win_settings_cdrom_drives_recalc_list(HWND hdlg)
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
*/
}
return TRUE;
@@ -4206,7 +4263,7 @@ win_settings_cdrom_drives_init_columns(HWND hdlg)
if (ListView_InsertColumn(hwndList, 1, &lvc) == -1)
return FALSE;
/* Earlier drive */
/* Type */
lvc.iSubItem = 2;
lvc.pszText = plat_get_string(IDS_2162);
@@ -4434,6 +4491,7 @@ win_settings_cdrom_drives_update_item(HWND hdlg, int i)
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
/*
lvI.iSubItem = 2;
lvI.pszText = plat_get_string(temp_cdrom[i].early ? IDS_2060 : IDS_2061);
lvI.iItem = i;
@@ -4441,6 +4499,7 @@ win_settings_cdrom_drives_update_item(HWND hdlg, int i)
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
*/
}
static void
@@ -4592,11 +4651,12 @@ cdrom_recalc_location_controls(HWND hdlg, int assign_id)
settings_show_window(hdlg, IDC_COMBO_CD_CHANNEL_IDE, FALSE);
settings_show_window(hdlg, IDC_COMBO_CD_SPEED, bus != CDROM_BUS_DISABLED);
settings_show_window(hdlg, IDT_CD_SPEED, bus != CDROM_BUS_DISABLED);
/*
settings_show_window(hdlg, IDC_CHECKEARLY, bus != CDROM_BUS_DISABLED);
*/
if (bus != CDROM_BUS_DISABLED) {
settings_set_cur_sel(hdlg, IDC_COMBO_CD_SPEED, temp_cdrom[lv2_current_sel].speed - 1);
settings_set_check(hdlg, IDC_CHECKEARLY, temp_cdrom[lv2_current_sel].early);
// settings_set_check(hdlg, IDC_CHECKEARLY, temp_cdrom[lv2_current_sel].early);
}
switch (bus) {
@@ -4987,10 +5047,12 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam
win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel);
break;
/*
case IDC_CHECKEARLY:
temp_cdrom[lv2_current_sel].early = settings_get_check(hdlg, IDC_CHECKEARLY);
win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel);
break;
*/
}
ignore_change = 0;