Merge branch '86Box:master' into machine_23

This commit is contained in:
BurnedPinguin
2023-07-05 15:49:47 +02:00
committed by GitHub
691 changed files with 58230 additions and 27517 deletions

View File

@@ -8,8 +8,6 @@
*
* Main emulator module where most things are controlled.
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -19,11 +17,14 @@
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2021 Laci bá'
* Copyright 2021 dob205
* Copyright 2021 Andreas J. Reichel.
* Copyright 2021-2022 Jasmine Iwanek.
*/
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
@@ -68,6 +69,7 @@
#include <86box/isartc.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/serial_passthrough.h>
#include <86box/keyboard.h>
#include <86box/mouse.h>
#include <86box/gameport.h>
@@ -146,46 +148,48 @@ uint64_t instru_run_ms = 0;
/* Configuration values. */
int window_remember;
int vid_resize; /* (C) allow resizing */
int invert_display = 0; /* (C) invert the display */
int suppress_overscan = 0; /* (C) suppress overscans */
int scale = 0; /* (C) screen scale factor */
int dpi_scale = 0; /* (C) DPI scaling of the emulated screen */
int vid_api = 0; /* (C) video renderer */
int vid_cga_contrast = 0; /* (C) video */
int video_fullscreen = 0; /* (C) video */
int video_fullscreen_scale = 0; /* (C) video */
int video_fullscreen_first = 0; /* (C) video */
int enable_overscan = 0; /* (C) video */
int force_43 = 0; /* (C) video */
int video_filter_method = 1; /* (C) video */
int video_vsync = 0; /* (C) video */
int video_framerate = -1; /* (C) video */
char video_shader[512] = { '\0' }; /* (C) video */
int bugger_enabled = 0; /* (C) enable ISAbugger */
int postcard_enabled = 0; /* (C) enable POST card */
int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */
int isartc_type = 0; /* (C) enable ISA RTC card */
int gfxcard[2] = { 0, 0 }; /* (C) graphics/video card */
int show_second_monitors = 1; /* (C) show non-primary monitors */
int sound_is_float = 1; /* (C) sound uses FP values */
int voodoo_enabled = 0; /* (C) video option */
int ibm8514_enabled = 0; /* (C) video option */
int xga_enabled = 0; /* (C) video option */
uint32_t mem_size = 0; /* (C) memory size (Installed on system board)*/
uint32_t isa_mem_size = 0; /* (C) memory size (ISA Memory Cards) */
int cpu_use_dynarec = 0; /* (C) cpu uses/needs Dyna */
int cpu = 0; /* (C) cpu type */
int fpu_type = 0; /* (C) fpu type */
int time_sync = 0; /* (C) enable time sync */
int confirm_reset = 1; /* (C) enable reset confirmation */
int confirm_exit = 1; /* (C) enable exit confirmation */
int confirm_save = 1; /* (C) enable save confirmation */
int enable_discord = 0; /* (C) enable Discord integration */
int pit_mode = -1; /* (C) force setting PIT mode */
int fm_driver = 0; /* (C) select FM sound driver */
int open_dir_usr_path = 0; /* default file open dialog directory of usr_path */
int video_fullscreen_scale_maximized = 0; /* (C) Whether fullscreen scaling settings also apply when maximized. */
int vid_resize; /* (C) allow resizing */
int invert_display = 0; /* (C) invert the display */
int suppress_overscan = 0; /* (C) suppress overscans */
int scale = 0; /* (C) screen scale factor */
int dpi_scale = 0; /* (C) DPI scaling of the emulated screen */
int vid_api = 0; /* (C) video renderer */
int vid_cga_contrast = 0; /* (C) video */
int video_fullscreen = 0; /* (C) video */
int video_fullscreen_scale = 0; /* (C) video */
int video_fullscreen_first = 0; /* (C) video */
int enable_overscan = 0; /* (C) video */
int force_43 = 0; /* (C) video */
int video_filter_method = 1; /* (C) video */
int video_vsync = 0; /* (C) video */
int video_framerate = -1; /* (C) video */
char video_shader[512] = { '\0' }; /* (C) video */
bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activation and kind of pass-through for serial ports */
int bugger_enabled = 0; /* (C) enable ISAbugger */
int postcard_enabled = 0; /* (C) enable POST card */
int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */
int isartc_type = 0; /* (C) enable ISA RTC card */
int gfxcard[2] = { 0, 0 }; /* (C) graphics/video card */
int show_second_monitors = 1; /* (C) show non-primary monitors */
int sound_is_float = 1; /* (C) sound uses FP values */
int voodoo_enabled = 0; /* (C) video option */
int ibm8514_enabled = 0; /* (C) video option */
int xga_enabled = 0; /* (C) video option */
uint32_t mem_size = 0; /* (C) memory size (Installed on system board)*/
uint32_t isa_mem_size = 0; /* (C) memory size (ISA Memory Cards) */
int cpu_use_dynarec = 0; /* (C) cpu uses/needs Dyna */
int cpu = 0; /* (C) cpu type */
int fpu_type = 0; /* (C) fpu type */
int fpu_softfloat = 0; /* (C) fpu uses softfloat */
int time_sync = 0; /* (C) enable time sync */
int confirm_reset = 1; /* (C) enable reset confirmation */
int confirm_exit = 1; /* (C) enable exit confirmation */
int confirm_save = 1; /* (C) enable save confirmation */
int enable_discord = 0; /* (C) enable Discord integration */
int pit_mode = -1; /* (C) force setting PIT mode */
int fm_driver = 0; /* (C) select FM sound driver */
int open_dir_usr_path = 0; /* default file open dialog directory of usr_path */
int video_fullscreen_scale_maximized = 0; /* (C) Whether fullscreen scaling settings also apply when maximized. */
/* Statistics. */
extern int mmuflush;
@@ -204,16 +208,20 @@ char exe_path[2048]; /* path (dir) of executable */
char usr_path[1024]; /* path (dir) of user data */
char cfg_path[1024]; /* full path of config file */
FILE *stdlog = NULL; /* file to log output to */
// int scrnsz_x = SCREEN_RES_X; /* current screen size, X */
// int scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */
#if 0
int scrnsz_x = SCREEN_RES_X; /* current screen size, X */
int scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */
#endif
int config_changed; /* config has changed */
int title_update;
int framecountx = 0;
int hard_reset_pending = 0;
// int unscaled_size_x = SCREEN_RES_X; /* current unscaled size X */
// int unscaled_size_y = SCREEN_RES_Y; /* current unscaled size Y */
// int efscrnsz_y = SCREEN_RES_Y;
#if 0
int unscaled_size_x = SCREEN_RES_X; /* current unscaled size X */
int unscaled_size_y = SCREEN_RES_Y; /* current unscaled size Y */
int efscrnsz_y = SCREEN_RES_Y;
#endif
static wchar_t mouse_msg[3][200];
@@ -400,19 +408,24 @@ pc_log(const char *fmt, ...)
int
pc_init(int argc, char *argv[])
{
char *ppath = NULL, *rpath = NULL;
char *cfg = NULL, *p;
char temp[2048], *fn[FDD_NUM] = { NULL };
char drive = 0, *temp2 = NULL;
char *ppath = NULL;
char *rpath = NULL;
char *cfg = NULL;
char *p;
char temp[2048];
char *fn[FDD_NUM] = { NULL };
char drive = 0;
char *temp2 = NULL;
struct tm *info;
time_t now;
int c, lvmp = 0;
int i;
int c;
int lvmp = 0;
#ifdef ENABLE_NG
int ng = 0;
#endif
#ifdef _WIN32
uint32_t *uid, *shwnd;
uint32_t *uid;
uint32_t *shwnd;
#endif
uint32_t lang_init = 0;
@@ -429,7 +442,7 @@ pc_init(int argc, char *argv[])
}
if (!strncmp(exe_path, "/private/var/folders/", 21)) {
ui_msgbox_header(MBX_FATAL, L"App Translocation", EMU_NAME_W L" cannot determine the emulated machine's location due to a macOS security feature. Please move the " EMU_NAME_W L" app to another folder (not /Applications), or make a copy of it and open that copy instead.");
return (0);
return 0;
}
#elif !defined(_WIN32)
/* Grab the actual path if we are an AppImage. */
@@ -457,7 +470,7 @@ pc_init(int argc, char *argv[])
if (!strcasecmp(argv[c], "--help") || !strcasecmp(argv[c], "-?")) {
usage:
for (i = 0; i < FDD_NUM; i++) {
for (uint8_t i = 0; i < FDD_NUM; i++) {
if (fn[i] != NULL) {
free(fn[i]);
fn[i] = NULL;
@@ -489,7 +502,7 @@ usage:
printf("-V or --vmname name - overrides the name of the running VM\n");
printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n");
printf("\nA config file can be specified. If none is, the default file will be used.\n");
return (0);
return 0;
} else if (!strcasecmp(argv[c], "--lastvmpath") || !strcasecmp(argv[c], "-Z")) {
lvmp = 1;
} else if (!strcasecmp(argv[c], "--dumpcfg") || !strcasecmp(argv[c], "-O")) {
@@ -581,7 +594,7 @@ usage:
/* some (undocumented) test function here.. */
/* .. and then exit. */
return (0);
return 0;
#ifdef USE_INSTRUMENT
} else if (!strcasecmp(argv[c], "--instrument")) {
if ((c + 1) == argc)
@@ -766,7 +779,7 @@ usage:
/* Load the configuration file. */
config_load();
for (i = 0; i < FDD_NUM; i++) {
for (uint8_t i = 0; i < FDD_NUM; i++) {
if (fn[i] != NULL) {
if (strlen(fn[i]) <= 511)
strncpy(floppyfns[i], fn[i], 511);
@@ -782,7 +795,7 @@ usage:
gdbstub_init();
/* All good! */
return (1);
return 1;
}
void
@@ -808,7 +821,8 @@ pc_full_speed(void)
int
pc_init_modules(void)
{
int c, m;
int c;
int m;
wchar_t temp[512];
char tempc[512];
@@ -842,13 +856,13 @@ pc_init_modules(void)
}
if (c == 0) {
/* No usable ROMs found, aborting. */
return (0);
return 0;
}
pc_log("A total of %d ROM sets have been loaded.\n", c);
/* Load the ROMs for the selected machine. */
if (!machine_available(machine)) {
swprintf(temp, sizeof(temp), plat_get_string(IDS_2063), machine_getname());
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2063), machine_getname());
c = 0;
machine = -1;
while (machine_get_internal_name_ex(c) != NULL) {
@@ -863,7 +877,6 @@ pc_init_modules(void)
if (machine == -1) {
fatal("No available machines\n");
exit(-1);
return (0);
}
}
@@ -871,7 +884,7 @@ pc_init_modules(void)
if (!video_card_available(gfxcard[0])) {
memset(tempc, 0, sizeof(tempc));
device_get_name(video_card_getdevice(gfxcard[0]), 0, tempc);
swprintf(temp, sizeof(temp), plat_get_string(IDS_2064), tempc);
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2064), tempc);
c = 0;
while (video_get_internal_name(c) != NULL) {
gfxcard[0] = -1;
@@ -886,14 +899,13 @@ pc_init_modules(void)
if (gfxcard[0] == -1) {
fatal("No available video cards\n");
exit(-1);
return (0);
}
}
if (!video_card_available(gfxcard[1])) {
char tempc[512] = { 0 };
device_get_name(video_card_getdevice(gfxcard[1]), 0, tempc);
swprintf(temp, sizeof(temp), (wchar_t *) "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.", tempc);
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2163), tempc);
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp);
gfxcard[1] = 0;
}
@@ -929,7 +941,7 @@ pc_init_modules(void)
machine_status_init();
return (1);
return 1;
}
void
@@ -1038,6 +1050,7 @@ pc_reset_hard_init(void)
/* Reset and reconfigure the serial ports. */
serial_standalone_init();
serial_passthrough_init();
/* Reset and reconfigure the Sound Card layer. */
sound_card_reset();
@@ -1124,12 +1137,17 @@ pc_reset_hard_init(void)
#endif
update_mouse_msg();
ui_hard_reset_completed();
}
void
update_mouse_msg(void)
{
wchar_t wcpufamily[2048], wcpu[2048], wmachine[2048], *wcp;
wchar_t wcpufamily[2048];
wchar_t wcpu[2048];
wchar_t wmachine[2048];
wchar_t *wcp;
mbstowcs(wmachine, machine_getname(), strlen(machine_getname()) + 1);
@@ -1169,8 +1187,6 @@ pc_reset_hard(void)
void
pc_close(thread_t *ptr)
{
int i;
/* Wait a while so things can shut down. */
plat_delay_ms(200);
@@ -1198,7 +1214,7 @@ pc_close(thread_t *ptr)
lpt_devices_close();
for (i = 0; i < FDD_NUM; i++)
for (uint8_t i = 0; i < FDD_NUM; i++)
fdd_close(i);
#ifdef ENABLE_808X_LOG
@@ -1257,9 +1273,11 @@ pc_run(void)
startblit();
cpu_exec(cpu_s->rspeed / 100);
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
if (gdbstub_step == GDBSTUB_EXEC)
// if (gdbstub_step == GDBSTUB_EXEC)
#endif
#if 0
mouse_process();
#endif
joystick_process();
endblit();
@@ -1271,7 +1289,7 @@ pc_run(void)
}
if (title_update) {
mouse_msg_idx = (mouse_type == MOUSE_TYPE_NONE) ? 2 : !!mouse_capture;
mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_mode >= 1)) ? 2 : !!mouse_capture;
swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps);
#ifdef __APPLE__
/* Needed due to modifying the UI on the non-main thread is a big no-no. */
@@ -1298,7 +1316,10 @@ set_screen_size_monitor(int x, int y, int monitor_index)
{
int temp_overscan_x = monitors[monitor_index].mon_overscan_x;
int temp_overscan_y = monitors[monitor_index].mon_overscan_y;
double dx, dy, dtx, dty;
double dx;
double dy;
double dtx;
double dty;
/* Make sure we keep usable values. */
#if 0
@@ -1397,6 +1418,9 @@ set_screen_size_monitor(int x, int y, int monitor_index)
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 3);
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 3);
break;
default:
break;
}
plat_resize_request(monitors[monitor_index].mon_scrnsz_x, monitors[monitor_index].mon_scrnsz_y, monitor_index);
@@ -1417,14 +1441,14 @@ reset_screen_size_monitor(int monitor_index)
void
reset_screen_size(void)
{
for (int i = 0; i < MONITORS_NUM; i++)
for (uint8_t i = 0; i < MONITORS_NUM; i++)
set_screen_size(monitors[i].mon_unscaled_size_x, monitors[i].mon_efscrnsz_y);
}
void
set_screen_size_natural(void)
{
for (int i = 0; i < MONITORS_NUM; i++)
for (uint8_t i = 0; i < MONITORS_NUM; i++)
set_screen_size(monitors[i].mon_unscaled_size_x, monitors[i].mon_unscaled_size_y);
}

View File

@@ -109,6 +109,9 @@ endif()
find_package(Freetype REQUIRED)
include_directories(${FREETYPE_INCLUDE_DIRS})
if(FREETYPE_INCLUDE_DIR_ft2build)
include_directories(${FREETYPE_INCLUDE_DIR_ft2build})
endif()
if(APPLE)
# Freetype is dynamically loaded by the emulator, however, we link it
# on macOS so it gets copied to the bundle by the installation process

View File

@@ -40,9 +40,9 @@
#include <86box/i2c.h>
#include <86box/video.h>
int acpi_rtc_status = 0;
int acpi_rtc_status = 0;
atomic_int acpi_pwrbut_pressed = 0;
int acpi_enabled = 0;
int acpi_enabled = 0;
static double cpu_to_acpi;
@@ -148,7 +148,7 @@ acpi_raise_smi(void *priv, int do_smi)
if (dev->regs.glbctl & 0x01) {
if ((dev->vendor == VEN_VIA) || (dev->vendor == VEN_VIA_596B)) {
if ((!dev->regs.smi_lock || !dev->regs.smi_active)) {
if (!dev->regs.smi_lock || !dev->regs.smi_active) {
if (do_smi)
smi_raise();
dev->regs.smi_active = 1;
@@ -169,11 +169,12 @@ acpi_raise_smi(void *priv, int do_smi)
}
static uint32_t
acpi_reg_read_common_regs(int size, uint16_t addr, void *p)
acpi_reg_read_common_regs(UNUSED(int size), uint16_t addr, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
uint32_t ret = 0x00000000;
int shift16, shift32;
int shift16;
int shift32;
addr &= 0x3f;
shift16 = (addr & 1) << 3;
@@ -210,6 +211,9 @@ acpi_reg_read_common_regs(int size, uint16_t addr, void *p)
update_tsc();
#endif
break;
default:
break;
}
#ifdef ENABLE_ACPI_LOG
@@ -220,11 +224,12 @@ acpi_reg_read_common_regs(int size, uint16_t addr, void *p)
}
static uint32_t
acpi_reg_read_ali(int size, uint16_t addr, void *p)
acpi_reg_read_ali(int size, uint16_t addr, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
uint32_t ret = 0x00000000;
int shift16, shift32;
int shift16;
int shift32;
addr &= 0x3f;
shift16 = (addr & 1) << 3;
@@ -275,7 +280,7 @@ acpi_reg_read_ali(int size, uint16_t addr, void *p)
ret = dev->regs.pmcntrl;
break;
default:
ret = acpi_reg_read_common_regs(size, addr, p);
ret = acpi_reg_read_common_regs(size, addr, priv);
break;
}
@@ -287,11 +292,12 @@ acpi_reg_read_ali(int size, uint16_t addr, void *p)
}
static uint32_t
acpi_reg_read_intel(int size, uint16_t addr, void *p)
acpi_reg_read_intel(int size, uint16_t addr, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
uint32_t ret = 0x00000000;
int shift16, shift32;
int shift16;
int shift32;
addr &= 0x3f;
shift16 = (addr & 1) << 3;
@@ -371,7 +377,7 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p)
ret = dev->regs.gporeg[addr & 3];
break;
default:
ret = acpi_reg_read_common_regs(size, addr, p);
ret = acpi_reg_read_common_regs(size, addr, priv);
break;
}
@@ -383,11 +389,12 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p)
}
static uint32_t
acpi_reg_read_via_common(int size, uint16_t addr, void *p)
acpi_reg_read_via_common(int size, uint16_t addr, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
uint32_t ret = 0x00000000;
int shift16, shift32;
int shift16;
int shift32;
addr &= 0xff;
shift16 = (addr & 1) << 3;
@@ -466,7 +473,7 @@ acpi_reg_read_via_common(int size, uint16_t addr, void *p)
ret = (dev->regs.gptren >> shift32) & 0xff;
break;
default:
ret = acpi_reg_read_common_regs(size, addr, p);
ret = acpi_reg_read_common_regs(size, addr, priv);
break;
}
@@ -478,9 +485,9 @@ acpi_reg_read_via_common(int size, uint16_t addr, void *p)
}
static uint32_t
acpi_reg_read_via(int size, uint16_t addr, void *p)
acpi_reg_read_via(int size, uint16_t addr, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
uint32_t ret = 0x00000000;
int shift16;
@@ -523,7 +530,7 @@ acpi_reg_read_via(int size, uint16_t addr, void *p)
ret = (dev->regs.gpi_val >> shift16) & 0xff;
break;
default:
ret = acpi_reg_read_via_common(size, addr, p);
ret = acpi_reg_read_via_common(size, addr, priv);
break;
}
@@ -535,11 +542,12 @@ acpi_reg_read_via(int size, uint16_t addr, void *p)
}
static uint32_t
acpi_reg_read_via_596b(int size, uint16_t addr, void *p)
acpi_reg_read_via_596b(int size, uint16_t addr, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
uint32_t ret = 0x00000000;
int shift16, shift32;
int shift16;
int shift32;
addr &= 0x7f;
shift16 = (addr & 1) << 3;
@@ -572,7 +580,7 @@ acpi_reg_read_via_596b(int size, uint16_t addr, void *p)
ret = (dev->regs.gpo_val >> shift32) & 0xff;
break;
default:
ret = acpi_reg_read_via_common(size, addr, p);
ret = acpi_reg_read_via_common(size, addr, priv);
break;
}
@@ -584,13 +592,13 @@ acpi_reg_read_via_596b(int size, uint16_t addr, void *p)
}
static uint32_t
acpi_reg_read_smc(int size, uint16_t addr, void *p)
acpi_reg_read_smc(int size, uint16_t addr, void *priv)
{
uint32_t ret = 0x00000000;
addr &= 0x0f;
ret = acpi_reg_read_common_regs(size, addr, p);
ret = acpi_reg_read_common_regs(size, addr, priv);
#ifdef ENABLE_ACPI_LOG
if (size != 1)
@@ -600,9 +608,9 @@ acpi_reg_read_smc(int size, uint16_t addr, void *p)
}
static uint32_t
acpi_aux_reg_read_smc(int size, uint16_t addr, void *p)
acpi_aux_reg_read_smc(UNUSED(int size), uint16_t addr, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
uint32_t ret = 0x00000000;
int shift16;
@@ -633,6 +641,9 @@ acpi_aux_reg_read_smc(int size, uint16_t addr, void *p)
/* Miscellaneous Control Register */
ret = dev->regs.glbctl & 0xff;
break;
default:
break;
}
acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret);
@@ -640,10 +651,11 @@ acpi_aux_reg_read_smc(int size, uint16_t addr, void *p)
}
static void
acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p)
acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *priv)
{
acpi_t *dev = (acpi_t *) p;
int shift16, sus_typ;
acpi_t *dev = (acpi_t *) priv;
int shift16;
int sus_typ;
addr &= 0x3f;
#ifdef ENABLE_ACPI_LOG
@@ -672,6 +684,7 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p)
/* PMCNTRL - Power Management Control Register (IO) */
if ((addr == 0x05) && (val & 0x20)) {
sus_typ = dev->suspend_types[(val >> 2) & 7];
acpi_log("ACPI suspend type %d flags %02X\n", (val >> 2) & 7, sus_typ);
if (sus_typ & SUS_POWER_OFF) {
/* Soft power off. */
@@ -686,14 +699,13 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p)
}
if (sus_typ & SUS_RESET_PCI)
device_reset_all_pci();
device_reset_all(DEVICE_PCI);
if (sus_typ & SUS_RESET_CPU)
cpu_alt_reset = 0;
if (sus_typ & SUS_RESET_PCI) {
pci_reset();
keyboard_at_reset();
mem_a20_alt = 0;
mem_a20_recalc();
@@ -713,14 +725,18 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p)
}
dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3f07 /* 0x3c07 */;
break;
default:
break;
}
}
static void
acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p)
acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *priv)
{
acpi_t *dev = (acpi_t *) p;
int shift16, shift32;
acpi_t *dev = (acpi_t *) priv;
int shift16;
int shift32;
addr &= 0x3f;
#ifdef ENABLE_ACPI_LOG
@@ -775,7 +791,7 @@ acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p)
dev->regs.pmcntrl = val & 1;
break;
default:
acpi_reg_write_common_regs(size, addr, val, p);
acpi_reg_write_common_regs(size, addr, val, priv);
/* Setting GBL_RLS also sets BIOS_STS and generates SMI. */
if ((addr == 0x00) && !(dev->regs.pmsts & 0x20))
dev->regs.gpcntrl &= ~0x0002;
@@ -788,10 +804,11 @@ acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p)
}
static void
acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p)
acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *priv)
{
acpi_t *dev = (acpi_t *) p;
int shift16, shift32;
acpi_t *dev = (acpi_t *) priv;
int shift16;
int shift32;
addr &= 0x3f;
#ifdef ENABLE_ACPI_LOG
@@ -870,7 +887,7 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p)
dev->regs.gporeg[addr & 3] = val;
break;
default:
acpi_reg_write_common_regs(size, addr, val, p);
acpi_reg_write_common_regs(size, addr, val, priv);
/* Setting GBL_RLS also sets BIOS_STS and generates SMI. */
if ((addr == 0x00) && !(dev->regs.pmsts & 0x20))
dev->regs.glbctl &= ~0x0002;
@@ -884,10 +901,11 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p)
}
static void
acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p)
acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *priv)
{
acpi_t *dev = (acpi_t *) p;
int shift16, shift32;
acpi_t *dev = (acpi_t *) priv;
int shift16;
int shift32;
addr &= 0xff;
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
@@ -956,7 +974,7 @@ acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p)
dev->regs.gptren = ((dev->regs.gptren & ~(0xff << shift32)) | (val << shift32)) & 0x000000d9;
break;
default:
acpi_reg_write_common_regs(size, addr, val, p);
acpi_reg_write_common_regs(size, addr, val, priv);
/* Setting GBL_RLS also sets BIOS_STS and generates SMI. */
if ((addr == 0x00) && !(dev->regs.pmsts & 0x20))
dev->regs.glbctl &= ~0x0002;
@@ -977,10 +995,11 @@ acpi_i2c_set(acpi_t *dev)
}
static void
acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p)
acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *priv)
{
acpi_t *dev = (acpi_t *) p;
int shift16, shift32;
acpi_t *dev = (acpi_t *) priv;
int shift16;
int shift32;
addr &= 0xff;
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
@@ -1034,16 +1053,17 @@ acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p)
dev->regs.gpo_val = ((dev->regs.gpo_val & ~(0xff << shift16)) | (val << shift16)) & 0xffff;
break;
default:
acpi_reg_write_via_common(size, addr, val, p);
acpi_reg_write_via_common(size, addr, val, priv);
break;
}
}
static void
acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *p)
acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *priv)
{
acpi_t *dev = (acpi_t *) p;
int shift16, shift32;
acpi_t *dev = (acpi_t *) priv;
int shift16;
int shift32;
addr &= 0x7f;
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
@@ -1091,20 +1111,20 @@ acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *p)
dev->regs.gpo_val = ((dev->regs.gpo_val & ~(0xff << shift32)) | (val << shift32)) & 0x7fffffff;
break;
default:
acpi_reg_write_via_common(size, addr, val, p);
acpi_reg_write_via_common(size, addr, val, priv);
break;
}
}
static void
acpi_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p)
acpi_reg_write_smc(int size, uint16_t addr, uint8_t val, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
addr &= 0x0f;
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
acpi_reg_write_common_regs(size, addr, val, p);
acpi_reg_write_common_regs(size, addr, val, priv);
/* Setting GBL_RLS also sets BIOS_STS and generates SMI. */
if ((addr == 0x00) && !(dev->regs.pmsts & 0x20))
dev->regs.glbctl &= ~0x0001;
@@ -1116,9 +1136,9 @@ acpi_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p)
}
static void
acpi_aux_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p)
acpi_aux_reg_write_smc(UNUSED(int size), uint16_t addr, uint8_t val, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
int shift16;
addr &= 0x07;
@@ -1160,76 +1180,79 @@ acpi_aux_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p)
acpi_update_irq(dev);
}
break;
default:
break;
}
}
static uint32_t
acpi_reg_read_common(int size, uint16_t addr, void *p)
acpi_reg_read_common(int size, uint16_t addr, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
uint8_t ret = 0xff;
if (dev->vendor == VEN_ALI)
ret = acpi_reg_read_ali(size, addr, p);
ret = acpi_reg_read_ali(size, addr, priv);
else if (dev->vendor == VEN_VIA)
ret = acpi_reg_read_via(size, addr, p);
ret = acpi_reg_read_via(size, addr, priv);
else if (dev->vendor == VEN_VIA_596B)
ret = acpi_reg_read_via_596b(size, addr, p);
ret = acpi_reg_read_via_596b(size, addr, priv);
else if (dev->vendor == VEN_INTEL)
ret = acpi_reg_read_intel(size, addr, p);
ret = acpi_reg_read_intel(size, addr, priv);
else if (dev->vendor == VEN_SMC)
ret = acpi_reg_read_smc(size, addr, p);
ret = acpi_reg_read_smc(size, addr, priv);
return ret;
}
static void
acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p)
acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
if (dev->vendor == VEN_ALI)
acpi_reg_write_ali(size, addr, val, p);
acpi_reg_write_ali(size, addr, val, priv);
else if (dev->vendor == VEN_VIA)
acpi_reg_write_via(size, addr, val, p);
acpi_reg_write_via(size, addr, val, priv);
else if (dev->vendor == VEN_VIA_596B)
acpi_reg_write_via_596b(size, addr, val, p);
acpi_reg_write_via_596b(size, addr, val, priv);
else if (dev->vendor == VEN_INTEL)
acpi_reg_write_intel(size, addr, val, p);
acpi_reg_write_intel(size, addr, val, priv);
else if (dev->vendor == VEN_SMC)
acpi_reg_write_smc(size, addr, val, p);
acpi_reg_write_smc(size, addr, val, priv);
}
static uint32_t
acpi_aux_reg_read_common(int size, uint16_t addr, void *p)
acpi_aux_reg_read_common(int size, uint16_t addr, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
uint8_t ret = 0xff;
if (dev->vendor == VEN_SMC)
ret = acpi_aux_reg_read_smc(size, addr, p);
ret = acpi_aux_reg_read_smc(size, addr, priv);
return ret;
}
static void
acpi_aux_reg_write_common(int size, uint16_t addr, uint8_t val, void *p)
acpi_aux_reg_write_common(int size, uint16_t addr, uint8_t val, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
if (dev->vendor == VEN_SMC)
acpi_aux_reg_write_smc(size, addr, val, p);
acpi_aux_reg_write_smc(size, addr, val, priv);
}
static uint32_t
acpi_reg_readl(uint16_t addr, void *p)
acpi_reg_readl(uint16_t addr, void *priv)
{
uint32_t ret = 0x00000000;
ret = acpi_reg_read_common(4, addr, p);
ret |= (acpi_reg_read_common(4, addr + 1, p) << 8);
ret |= (acpi_reg_read_common(4, addr + 2, p) << 16);
ret |= (acpi_reg_read_common(4, addr + 3, p) << 24);
ret = acpi_reg_read_common(4, addr, priv);
ret |= (acpi_reg_read_common(4, addr + 1, priv) << 8);
ret |= (acpi_reg_read_common(4, addr + 2, priv) << 16);
ret |= (acpi_reg_read_common(4, addr + 3, priv) << 24);
acpi_log("ACPI: Read L %08X from %04X\n", ret, addr);
@@ -1237,12 +1260,12 @@ acpi_reg_readl(uint16_t addr, void *p)
}
static uint16_t
acpi_reg_readw(uint16_t addr, void *p)
acpi_reg_readw(uint16_t addr, void *priv)
{
uint16_t ret = 0x0000;
ret = acpi_reg_read_common(2, addr, p);
ret |= (acpi_reg_read_common(2, addr + 1, p) << 8);
ret = acpi_reg_read_common(2, addr, priv);
ret |= (acpi_reg_read_common(2, addr + 1, priv) << 8);
acpi_log("ACPI: Read W %08X from %04X\n", ret, addr);
@@ -1250,11 +1273,11 @@ acpi_reg_readw(uint16_t addr, void *p)
}
static uint8_t
acpi_reg_read(uint16_t addr, void *p)
acpi_reg_read(uint16_t addr, void *priv)
{
uint8_t ret = 0x00;
ret = acpi_reg_read_common(1, addr, p);
ret = acpi_reg_read_common(1, addr, priv);
acpi_log("ACPI: Read B %02X from %04X\n", ret, addr);
@@ -1262,14 +1285,14 @@ acpi_reg_read(uint16_t addr, void *p)
}
static uint32_t
acpi_aux_reg_readl(uint16_t addr, void *p)
acpi_aux_reg_readl(uint16_t addr, void *priv)
{
uint32_t ret = 0x00000000;
ret = acpi_aux_reg_read_common(4, addr, p);
ret |= (acpi_aux_reg_read_common(4, addr + 1, p) << 8);
ret |= (acpi_aux_reg_read_common(4, addr + 2, p) << 16);
ret |= (acpi_aux_reg_read_common(4, addr + 3, p) << 24);
ret = acpi_aux_reg_read_common(4, addr, priv);
ret |= (acpi_aux_reg_read_common(4, addr + 1, priv) << 8);
ret |= (acpi_aux_reg_read_common(4, addr + 2, priv) << 16);
ret |= (acpi_aux_reg_read_common(4, addr + 3, priv) << 24);
acpi_log("ACPI: Read Aux L %08X from %04X\n", ret, addr);
@@ -1277,12 +1300,12 @@ acpi_aux_reg_readl(uint16_t addr, void *p)
}
static uint16_t
acpi_aux_reg_readw(uint16_t addr, void *p)
acpi_aux_reg_readw(uint16_t addr, void *priv)
{
uint16_t ret = 0x0000;
ret = acpi_aux_reg_read_common(2, addr, p);
ret |= (acpi_aux_reg_read_common(2, addr + 1, p) << 8);
ret = acpi_aux_reg_read_common(2, addr, priv);
ret |= (acpi_aux_reg_read_common(2, addr + 1, priv) << 8);
acpi_log("ACPI: Read Aux W %04X from %04X\n", ret, addr);
@@ -1290,11 +1313,11 @@ acpi_aux_reg_readw(uint16_t addr, void *p)
}
static uint8_t
acpi_aux_reg_read(uint16_t addr, void *p)
acpi_aux_reg_read(uint16_t addr, void *priv)
{
uint8_t ret = 0x00;
ret = acpi_aux_reg_read_common(1, addr, p);
ret = acpi_aux_reg_read_common(1, addr, priv);
acpi_log("ACPI: Read Aux B %02X from %04X\n", ret, addr);
@@ -1302,59 +1325,59 @@ acpi_aux_reg_read(uint16_t addr, void *p)
}
static void
acpi_reg_writel(uint16_t addr, uint32_t val, void *p)
acpi_reg_writel(uint16_t addr, uint32_t val, void *priv)
{
acpi_log("ACPI: Write L %08X to %04X\n", val, addr);
acpi_reg_write_common(4, addr, val & 0xff, p);
acpi_reg_write_common(4, addr + 1, (val >> 8) & 0xff, p);
acpi_reg_write_common(4, addr + 2, (val >> 16) & 0xff, p);
acpi_reg_write_common(4, addr + 3, (val >> 24) & 0xff, p);
acpi_reg_write_common(4, addr, val & 0xff, priv);
acpi_reg_write_common(4, addr + 1, (val >> 8) & 0xff, priv);
acpi_reg_write_common(4, addr + 2, (val >> 16) & 0xff, priv);
acpi_reg_write_common(4, addr + 3, (val >> 24) & 0xff, priv);
}
static void
acpi_reg_writew(uint16_t addr, uint16_t val, void *p)
acpi_reg_writew(uint16_t addr, uint16_t val, void *priv)
{
acpi_log("ACPI: Write W %04X to %04X\n", val, addr);
acpi_reg_write_common(2, addr, val & 0xff, p);
acpi_reg_write_common(2, addr + 1, (val >> 8) & 0xff, p);
acpi_reg_write_common(2, addr, val & 0xff, priv);
acpi_reg_write_common(2, addr + 1, (val >> 8) & 0xff, priv);
}
static void
acpi_reg_write(uint16_t addr, uint8_t val, void *p)
acpi_reg_write(uint16_t addr, uint8_t val, void *priv)
{
acpi_log("ACPI: Write B %02X to %04X\n", val, addr);
acpi_reg_write_common(1, addr, val, p);
acpi_reg_write_common(1, addr, val, priv);
}
static void
acpi_aux_reg_writel(uint16_t addr, uint32_t val, void *p)
acpi_aux_reg_writel(uint16_t addr, uint32_t val, void *priv)
{
acpi_log("ACPI: Write Aux L %08X to %04X\n", val, addr);
acpi_aux_reg_write_common(4, addr, val & 0xff, p);
acpi_aux_reg_write_common(4, addr + 1, (val >> 8) & 0xff, p);
acpi_aux_reg_write_common(4, addr + 2, (val >> 16) & 0xff, p);
acpi_aux_reg_write_common(4, addr + 3, (val >> 24) & 0xff, p);
acpi_aux_reg_write_common(4, addr, val & 0xff, priv);
acpi_aux_reg_write_common(4, addr + 1, (val >> 8) & 0xff, priv);
acpi_aux_reg_write_common(4, addr + 2, (val >> 16) & 0xff, priv);
acpi_aux_reg_write_common(4, addr + 3, (val >> 24) & 0xff, priv);
}
static void
acpi_aux_reg_writew(uint16_t addr, uint16_t val, void *p)
acpi_aux_reg_writew(uint16_t addr, uint16_t val, void *priv)
{
acpi_log("ACPI: Write Aux W %04X to %04X\n", val, addr);
acpi_aux_reg_write_common(2, addr, val & 0xff, p);
acpi_aux_reg_write_common(2, addr + 1, (val >> 8) & 0xff, p);
acpi_aux_reg_write_common(2, addr, val & 0xff, priv);
acpi_aux_reg_write_common(2, addr + 1, (val >> 8) & 0xff, priv);
}
static void
acpi_aux_reg_write(uint16_t addr, uint8_t val, void *p)
acpi_aux_reg_write(uint16_t addr, uint8_t val, void *priv)
{
acpi_log("ACPI: Write Aux B %02X to %04X\n", val, addr);
acpi_aux_reg_write_common(1, addr, val, p);
acpi_aux_reg_write_common(1, addr, val, priv);
}
void
@@ -1363,9 +1386,9 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en)
int size;
switch (dev->vendor) {
default:
case VEN_ALI:
case VEN_INTEL:
default:
size = 0x040;
break;
case VEN_SMC:
@@ -1519,7 +1542,7 @@ acpi_ali_soft_smi_status_write(acpi_t *dev, uint8_t soft_smi)
}
void
acpi_pwrbtn_timer(void* priv)
acpi_pwrbtn_timer(void *priv)
{
acpi_t *dev = (acpi_t *) priv;
@@ -1534,9 +1557,9 @@ acpi_pwrbtn_timer(void* priv)
}
static void
acpi_apm_out(uint16_t port, uint8_t val, void *p)
acpi_apm_out(uint16_t port, uint8_t val, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
acpi_log("[%04X:%08X] APM write: %04X = %02X (AX = %04X, BX = %04X, CX = %04X)\n", CS, cpu_state.pc, port, val, AX, BX, CX);
@@ -1546,7 +1569,9 @@ acpi_apm_out(uint16_t port, uint8_t val, void *p)
if (port == 0x0001) {
acpi_log("ALi SOFT SMI# status set (%i)\n", dev->apm->do_smi);
dev->apm->cmd = val;
// acpi_raise_smi(dev, dev->apm->do_smi);
#if 0
acpi_raise_smi(dev, dev->apm->do_smi);
#endif
if (dev->apm->do_smi)
smi_raise();
dev->regs.ali_soft_smi = 1;
@@ -1564,9 +1589,9 @@ acpi_apm_out(uint16_t port, uint8_t val, void *p)
}
static uint8_t
acpi_apm_in(uint16_t port, void *p)
acpi_apm_in(uint16_t port, void *priv)
{
acpi_t *dev = (acpi_t *) p;
acpi_t *dev = (acpi_t *) priv;
uint8_t ret = 0xff;
port &= 0x0001;
@@ -1592,7 +1617,6 @@ static void
acpi_reset(void *priv)
{
acpi_t *dev = (acpi_t *) priv;
int i;
memset(&dev->regs, 0x00, sizeof(acpi_regs_t));
dev->regs.gpireg[0] = 0xff;
@@ -1603,7 +1627,7 @@ acpi_reset(void *priv)
Gigabyte GA-686BX:
- Bit 1: CMOS battery low (active high) */
dev->regs.gpireg[2] = dev->gpireg2_default;
for (i = 0; i < 4; i++)
for (uint8_t i = 0; i < 4; i++)
dev->regs.gporeg[i] = dev->gporeg_default[i];
if (dev->vendor == VEN_VIA_596B) {
dev->regs.gpo_val = 0x7fffffff;
@@ -1698,6 +1722,7 @@ acpi_init(const device_t *info)
dev->suspend_types[1] = SUS_POWER_OFF;
dev->suspend_types[2] = SUS_SUSPEND | SUS_NVR | SUS_RESET_CPU | SUS_RESET_PCI;
dev->suspend_types[3] = SUS_SUSPEND;
dev->suspend_types[5] = SUS_POWER_OFF; /* undocumented, used for S4/S5 by ASUS P5A ACPI table */
break;
case VEN_VIA:
@@ -1720,6 +1745,9 @@ acpi_init(const device_t *info)
dev->suspend_types[3] = SUS_SUSPEND | SUS_RESET_CACHE;
dev->suspend_types[4] = SUS_SUSPEND;
break;
default:
break;
}
timer_add(&dev->timer, acpi_timer_overflow, dev, 0);

View File

@@ -52,9 +52,9 @@ apm_set_do_smi(apm_t *dev, uint8_t do_smi)
}
static void
apm_out(uint16_t port, uint8_t val, void *p)
apm_out(uint16_t port, uint8_t val, void *priv)
{
apm_t *dev = (apm_t *) p;
apm_t *dev = (apm_t *) priv;
apm_log("[%04X:%08X] APM write: %04X = %02X (BX = %04X, CX = %04X)\n", CS, cpu_state.pc, port, val, BX, CX);
@@ -69,9 +69,9 @@ apm_out(uint16_t port, uint8_t val, void *p)
}
static uint8_t
apm_in(uint16_t port, void *p)
apm_in(uint16_t port, void *priv)
{
apm_t *dev = (apm_t *) p;
apm_t *dev = (apm_t *) priv;
uint8_t ret = 0xff;
port &= 0x0001;
@@ -87,17 +87,17 @@ apm_in(uint16_t port, void *p)
}
static void
apm_reset(void *p)
apm_reset(void *priv)
{
apm_t *dev = (apm_t *) p;
apm_t *dev = (apm_t *) priv;
dev->cmd = dev->stat = 0x00;
}
static void
apm_close(void *p)
apm_close(void *priv)
{
apm_t *dev = (apm_t *) p;
apm_t *dev = (apm_t *) priv;
free(dev);
}

View File

@@ -183,12 +183,12 @@ cdrom_interface_has_config(int cdinterface)
const device_t *dev = cdrom_interface_get_device(cdinterface);
if (dev == NULL)
return (0);
return 0;
if (!device_has_config(dev))
return (0);
return 0;
return (1);
return 1;
}
int
@@ -257,7 +257,9 @@ int
cdrom_lba_to_msf_accurate(int lba)
{
int pos;
int m, s, f;
int m;
int s;
int f;
pos = lba + 150;
f = pos % 75;
@@ -401,7 +403,9 @@ cdrom_stop(cdrom_t *dev)
void
cdrom_seek(cdrom_t *dev, uint32_t pos, uint8_t vendor_type)
{
int m, s, f;
int m;
int s;
int f;
if (!dev)
return;
@@ -418,6 +422,8 @@ cdrom_seek(cdrom_t *dev, uint32_t pos, uint8_t vendor_type)
case 0x80:
pos = bcd2bin((pos >> 24) & 0xff);
break;
default:
break;
}
dev->seek_pos = pos;
@@ -498,7 +504,9 @@ uint8_t
cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
{
track_info_t ti;
int m = 0, s = 0, f = 0;
int m = 0;
int s = 0;
int f = 0;
if (dev->cd_status == CD_STATUS_DATA_ONLY)
return 0;
@@ -570,7 +578,9 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
uint8_t
cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit)
{
int m = 0, s = 0, f = 0;
int m = 0;
int s = 0;
int f = 0;
if (dev->cd_status == CD_STATUS_DATA_ONLY)
return 0;
@@ -603,6 +613,8 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit)
}
dev->seek_pos = (pos >> 24) & 0xff;
break;
default:
break;
}
/* Unlike standard commands, if there's a data track on an Audio CD (mixed mode)
@@ -615,7 +627,9 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit)
uint8_t
cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type)
{
int m = 0, s = 0, f = 0;
int m = 0;
int s = 0;
int f = 0;
if (dev->cd_status == CD_STATUS_DATA_ONLY)
return 0;
@@ -642,6 +656,8 @@ cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type)
}
dev->cd_end = pos;
break;
default:
break;
}
cdrom_log("Toshiba/NEC Play Audio: MSF = %06x, type = %02x, cdstatus = %02x\n", pos, type, dev->cd_status);
@@ -657,7 +673,9 @@ cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type)
uint8_t
cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type)
{
int m = 0, s = 0, f = 0;
int m = 0;
int s = 0;
int f = 0;
if (dev->cd_status == CD_STATUS_DATA_ONLY)
return 0;
@@ -686,6 +704,8 @@ cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type)
case 0x80:
dev->seek_pos = (pos >> 24) & 0xff;
break;
default:
break;
}
/* Do this at this point, since it's at this point that we know the
@@ -712,7 +732,10 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
{
uint8_t ret;
subchannel_t subc;
int pos = 1, m, s, f;
int pos = 1;
int m;
int s;
int f;
uint32_t dat;
dev->ops->get_subchannel(dev, dev->seek_pos, &subc);
@@ -895,9 +918,13 @@ static int
read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf)
{
track_info_t ti;
int i, len = 4;
int m, s, f;
int first_track, last_track;
int i;
int len = 4;
int m;
int s;
int f;
int first_track;
int last_track;
uint32_t temp;
cdrom_log("read_toc_normal(%08X, %08X, %02X, %i)\n", dev, b, start_track, msf);
@@ -978,7 +1005,10 @@ static int
read_toc_session(cdrom_t *dev, unsigned char *b, int msf)
{
track_info_t ti;
int len = 4, m, s, f;
int len = 4;
int m;
int s;
int f;
uint32_t temp;
cdrom_log("read_toc_session(%08X, %08X, %i)\n", dev, b, msf);
@@ -1027,8 +1057,9 @@ static int
read_toc_raw(cdrom_t *dev, unsigned char *b)
{
track_info_t ti;
int i, len = 4;
int first_track, last_track;
int len = 4;
int first_track;
int last_track;
cdrom_log("read_toc_raw(%08X, %08X)\n", dev, b);
@@ -1037,7 +1068,7 @@ read_toc_raw(cdrom_t *dev, unsigned char *b)
/* Bytes 2 and 3 = Number of first and last sessions */
b[2] = b[3] = 1;
for (i = 0; i <= last_track; i++) {
for (int i = 0; i <= last_track; i++) {
dev->ops->get_track_info(dev, i + 1, 0, &ti);
cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f);
@@ -1061,8 +1092,10 @@ static int
read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf)
{
track_info_t ti;
int i, len = 4;
int first_track, last_track;
int i;
int len = 4;
int first_track;
int last_track;
uint32_t temp;
cdrom_log("read_toc_sony(%08X, %08X, %02X, %i)\n", dev, b, start_track, msf);
@@ -1173,7 +1206,8 @@ void
cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf)
{
track_info_t ti;
int first_track, last_track;
int first_track;
int last_track;
if (dev != NULL) {
dev->ops->get_tracks(dev, &first_track, &last_track);
@@ -1196,7 +1230,8 @@ void
cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode)
{
track_info_t ti;
int first_track, last_track;
int first_track;
int last_track;
if (dev != NULL) {
dev->ops->get_tracks(dev, &first_track, &last_track);
@@ -1254,8 +1289,11 @@ uint8_t
cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type)
{
track_info_t ti;
int first_track, last_track;
int m = 0, s = 0, f = 0;
int first_track;
int last_track;
int m = 0;
int s = 0;
int f = 0;
dev->ops->get_tracks(dev, &first_track, &last_track);
@@ -1301,13 +1339,15 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in
b[2] = 0;
b[3] = 0;
break;
default:
break;
}
return 1;
}
static int
track_type_is_valid(uint8_t id, int type, int flags, int audio, int mode2)
track_type_is_valid(UNUSED(uint8_t id), int type, int flags, int audio, int mode2)
{
if (!(flags & 0x70) && (flags & 0xf8)) { /* 0x08/0x80/0x88 are illegal modes */
cdrom_log("CD-ROM %i: [Any Mode] 0x08/0x80/0x88 are illegal modes\n", id);
@@ -1583,10 +1623,15 @@ int
cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type,
int cdrom_sector_flags, int *len, uint8_t vendor_type)
{
uint8_t *b, *temp_b;
uint32_t msf, lba;
int audio = 0, mode2 = 0;
int m, s, f;
uint8_t *b;
uint8_t *temp_b;
uint32_t msf;
uint32_t lba;
int audio = 0;
int mode2 = 0;
int m;
int s;
int f;
if (dev->cd_status == CD_STATUS_EMPTY)
return 0;
@@ -1763,9 +1808,8 @@ void
cdrom_hard_reset(void)
{
cdrom_t *dev;
int i;
for (i = 0; i < CDROM_NUM; i++) {
for (uint8_t i = 0; i < CDROM_NUM; i++) {
dev = &cdrom[i];
if (dev->bus_type) {
cdrom_log("CD-ROM %i: Hard reset\n", i);
@@ -1798,9 +1842,8 @@ void
cdrom_close(void)
{
cdrom_t *dev;
int i;
for (i = 0; i < CDROM_NUM; i++) {
for (uint8_t i = 0; i < CDROM_NUM; i++) {
dev = &cdrom[i];
if (dev->bus_type == CDROM_BUS_SCSI)

View File

@@ -84,7 +84,8 @@ static void
image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc)
{
cd_img_t *img = (cd_img_t *) dev->image;
TMSF rel_pos, abs_pos;
TMSF rel_pos;
TMSF abs_pos;
cdi_get_audio_sub(img, lba, &subc->attr, &subc->track, &subc->index,
&rel_pos, &abs_pos);
@@ -102,17 +103,19 @@ static int
image_get_capacity(cdrom_t *dev)
{
cd_img_t *img = (cd_img_t *) dev->image;
int first_track, last_track;
int number, c;
int first_track;
int last_track;
int number;
unsigned char attr;
uint32_t address = 0, lb = 0;
uint32_t address = 0;
uint32_t lb = 0;
if (!img)
return 0;
cdi_get_audio_tracks_lba(img, &first_track, &last_track, &lb);
for (c = 0; c <= last_track; c++) {
for (int c = 0; c <= last_track; c++) {
cdi_get_audio_track_info_lba(img, 0, c + 1, &number, &address, &attr);
if (address > lb)
lb = address;
@@ -127,8 +130,11 @@ image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
cd_img_t *img = (cd_img_t *) dev->image;
uint8_t attr;
TMSF tmsf;
int m, s, f;
int number, track;
int m;
int s;
int f;
int number;
int track;
if (!img || (dev->cd_status == CD_STATUS_DATA_ONLY))
return 0;

View File

@@ -159,7 +159,15 @@ bin_init(const char *filename, int *error)
tf->get_length = bin_get_length;
tf->close = bin_close;
} else {
free(tf);
/* From the check above, error may still be non-zero if opening a directory.
* The error is set for viso to try and open the directory following this function.
* However, we need to make sure the descriptor is closed. */
if ((tf->file != NULL) && ((stats.st_mode & S_IFMT) == S_IFDIR)) {
/* tf is freed by bin_close */
bin_close(tf);
} else {
free(tf);
}
tf = NULL;
}
@@ -194,14 +202,13 @@ track_file_close(track_t *trk)
static void
cdi_clear_tracks(cd_img_t *cdi)
{
int i;
track_file_t *last = NULL;
track_t *cur = NULL;
if ((cdi->tracks == NULL) || (cdi->tracks_num == 0))
return;
for (i = 0; i < cdi->tracks_num; i++) {
for (int i = 0; i < cdi->tracks_num; i++) {
cur = &cdi->tracks[i];
/* Make sure we do not attempt to close a NULL file. */
@@ -276,7 +283,7 @@ cdi_get_audio_track_pre(cd_img_t *cdi, int track)
/* This replaces both Info and EndInfo, they are specified by a variable. */
int
cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF *start, uint8_t *attr)
cdi_get_audio_track_info(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
{
track_t *trk = &cdi->tracks[track - 1];
int pos = trk->start + 150;
@@ -295,7 +302,7 @@ cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF
}
int
cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, uint32_t *start, uint8_t *attr)
cdi_get_audio_track_info_lba(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, uint32_t *start, uint8_t *attr)
{
track_t *trk = &cdi->tracks[track - 1];
@@ -313,8 +320,8 @@ cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num,
int
cdi_get_track(cd_img_t *cdi, uint32_t sector)
{
int i;
track_t *cur, *next;
track_t *cur;
track_t *next;
/* There must be at least two tracks - data and lead out. */
if (cdi->tracks_num < 2)
@@ -322,7 +329,7 @@ cdi_get_track(cd_img_t *cdi, uint32_t sector)
/* This has a problem - the code skips the last track, which is
lead out - is that correct? */
for (i = 0; i < (cdi->tracks_num - 1); i++) {
for (int i = 0; i < (cdi->tracks_num - 1); i++) {
cur = &cdi->tracks[i];
next = &cdi->tracks[i + 1];
if ((cur->start <= sector) && (sector < next->start))
@@ -360,12 +367,17 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
{
size_t length;
int track = cdi_get_track(cdi, sector) - 1;
uint64_t sect = (uint64_t) sector, seek;
uint64_t sect = (uint64_t) sector;
uint64_t seek;
track_t *trk;
int track_is_raw, ret;
int raw_size, cooked_size;
int track_is_raw;
int ret;
int raw_size;
int cooked_size;
uint64_t offset = 0ULL;
int m = 0, s = 0, f = 0;
int m = 0;
int s = 0;
int f = 0;
if (track < 0)
return 0;
@@ -420,9 +432,10 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
int
cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num)
{
int sector_size, success = 1;
int sector_size;
int success = 1;
uint8_t *buf;
uint32_t buf_len, i;
uint32_t buf_len;
/* TODO: This fails to account for Mode 2. Shouldn't we have a function
to get sector size? */
@@ -430,7 +443,7 @@ cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint3
buf_len = num * sector_size;
buf = (uint8_t *) malloc(buf_len * sizeof(uint8_t));
for (i = 0; i < num; i++) {
for (uint32_t i = 0; i < num; i++) {
success = cdi_read_sector(cdi, &buf[i * sector_size], raw, sector + i);
if (!success)
break;
@@ -453,7 +466,8 @@ cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector)
{
int track = cdi_get_track(cdi, sector) - 1;
track_t *trk;
uint64_t s = (uint64_t) sector, seek;
uint64_t s = (uint64_t) sector;
uint64_t seek;
if (track < 0)
return 0;
@@ -542,7 +556,8 @@ cdi_track_push_back(cd_img_t *cdi, track_t *trk)
int
cdi_load_iso(cd_img_t *cdi, const char *filename)
{
int error, ret = 2;
int error;
int ret = 2;
track_t trk;
cdi->tracks = NULL;
@@ -690,7 +705,9 @@ static int
cdi_cue_get_frame(uint64_t *frames, char **line)
{
char temp[128];
int min, sec, fr;
int min;
int sec;
int fr;
int success;
success = cdi_cue_get_buffer(temp, line, 0);
@@ -709,7 +726,8 @@ cdi_cue_get_frame(uint64_t *frames, char **line)
static int
cdi_cue_get_flags(track_t *cur, char **line)
{
char temp[128], temp2[128];
char temp[128];
char temp2[128];
int success;
success = cdi_cue_get_buffer(temp, line, 0);
@@ -730,7 +748,8 @@ static int
cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, uint64_t *total_pregap, uint64_t cur_pregap)
{
/* Frames between index 0 (prestart) and 1 (current track start) must be skipped. */
uint64_t skip, temp;
uint64_t skip;
uint64_t temp;
track_t *prev = NULL;
/* Skip *MUST* be calculated even if prestart is 0. */
@@ -749,7 +768,7 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u
}
/* First track (track number must be 1). */
if (cdi->tracks_num == 0) {
if ((prev == NULL) || (cdi->tracks_num == 0)) {
/* I guess this makes sure the structure is not filled with invalid data. */
if (cur->number != 1)
return 0;
@@ -797,16 +816,23 @@ int
cdi_load_cue(cd_img_t *cdi, const char *cuefile)
{
track_t trk;
char pathname[MAX_FILENAME_LENGTH], filename[MAX_FILENAME_LENGTH];
char pathname[MAX_FILENAME_LENGTH];
char filename[MAX_FILENAME_LENGTH];
char temp[MAX_FILENAME_LENGTH];
uint64_t shift = 0ULL, prestart = 0ULL;
uint64_t cur_pregap = 0ULL, total_pregap = 0ULL;
uint64_t frame = 0ULL, index;
int i, success;
int error, can_add_track = 0;
uint64_t shift = 0ULL;
uint64_t prestart = 0ULL;
uint64_t cur_pregap = 0ULL;
uint64_t total_pregap = 0ULL;
uint64_t frame = 0ULL;
uint64_t index;
int success;
int error;
int can_add_track = 0;
FILE *fp;
char buf[MAX_LINE_LENGTH], ansi[MAX_FILENAME_LENGTH];
char *line, *command;
char buf[MAX_LINE_LENGTH];
char ansi[MAX_FILENAME_LENGTH];
char *line;
char *command;
char *type;
cdi->tracks = NULL;
@@ -834,7 +860,7 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
/* Do two iterations to make sure to nuke even if it's \r\n or \n\r,
but do checks to make sure we're not nuking other bytes. */
for (i = 0; i < 2; i++) {
for (uint8_t i = 0; i < 2; i++) {
if (strlen(buf) > 0) {
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
@@ -1027,13 +1053,11 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
int
cdi_has_data_track(cd_img_t *cdi)
{
int i;
if ((cdi == NULL) || (cdi->tracks == NULL))
return 0;
/* Data track has attribute 0x14. */
for (i = 0; i < cdi->tracks_num; i++) {
for (int i = 0; i < cdi->tracks_num; i++) {
if (cdi->tracks[i].attr == DATA_TRACK)
return 1;
}
@@ -1044,13 +1068,11 @@ cdi_has_data_track(cd_img_t *cdi)
int
cdi_has_audio_track(cd_img_t *cdi)
{
int i;
if ((cdi == NULL) || (cdi->tracks == NULL))
return 0;
/* Audio track has attribute 0x14. */
for (i = 0; i < cdi->tracks_num; i++) {
for (int i = 0; i < cdi->tracks_num; i++) {
if (cdi->tracks[i].attr == AUDIO_TRACK)
return 1;
}

View File

@@ -114,8 +114,10 @@ typedef struct _viso_entry_ {
} viso_entry_t;
typedef struct {
uint64_t vol_size_offsets[2], pt_meta_offsets[2];
int format, use_version_suffix : 1;
uint64_t vol_size_offsets[2];
uint64_t pt_meta_offsets[2];
int format;
uint8_t use_version_suffix : 1;
size_t metadata_sectors, all_sectors, entry_map_size, sector_size, file_fifo_pos;
uint8_t *metadata;
@@ -218,7 +220,7 @@ viso_convert_utf8(wchar_t *dest, const char *src, ssize_t buf_size)
return p - dest;
}
#define VISO_WRITE_STR_FUNC(func, dst_type, src_type, converter) \
#define VISO_WRITE_STR_FUNC(func, dst_type, src_type, converter, bounds_chk) \
static void \
func(dst_type *dest, const src_type *src, ssize_t buf_size, int charset) \
{ \
@@ -284,7 +286,7 @@ viso_convert_utf8(wchar_t *dest, const char *src, ssize_t buf_size)
\
default: \
/* Not valid for D or A, but valid for filenames. */ \
if ((charset < VISO_CHARSET_FN) || (c > 0xffff)) \
if ((charset < VISO_CHARSET_FN) || (bounds_chk)) \
c = '_'; \
break; \
} \
@@ -293,15 +295,16 @@ viso_convert_utf8(wchar_t *dest, const char *src, ssize_t buf_size)
*dest++ = converter(c); \
} \
}
VISO_WRITE_STR_FUNC(viso_write_string, uint8_t, char, )
VISO_WRITE_STR_FUNC(viso_write_wstring, uint16_t, wchar_t, cpu_to_be16)
VISO_WRITE_STR_FUNC(viso_write_string, uint8_t, char, , 0)
VISO_WRITE_STR_FUNC(viso_write_wstring, uint16_t, wchar_t, cpu_to_be16, c > 0xffff)
static int
viso_fill_fn_short(char *data, const viso_entry_t *entry, viso_entry_t **entries)
{
/* Get name and extension length. */
const char *ext_pos = strrchr(entry->basename, '.');
int name_len, ext_len;
int name_len;
int ext_len;
if (ext_pos) {
name_len = ext_pos - entry->basename;
ext_len = strlen(ext_pos);
@@ -472,7 +475,9 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform)
static int
viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, viso_t *viso, int type)
{
uint8_t *p = data, *q, *r;
uint8_t *p = data;
uint8_t *q;
uint8_t *r;
*p++ = 0; /* size (filled in later) */
*p++ = 0; /* extended attribute length */
@@ -626,10 +631,17 @@ pad_susp:
if (!(*q & 1)) /* padding for even file ID lengths */
*p++ = 0;
break;
default:
break;
}
if ((p - data) > 255)
fatal("VISO: Directory record overflow (%d) on entry %08X\n", p - data, entry);
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
fatal("VISO: Directory record overflow (%d) on entry %016" PRIX64 "\n", (uint32_t) (uintptr_t) (p - data), (uint64_t) (uintptr_t) entry);
#else
fatal("VISO: Directory record overflow (%d) on entry %08X\n", (uint32_t) (uintptr_t) (p - data), (uint32_t) (uintptr_t) entry);
#endif
data[0] = p - data; /* length */
return data[0];
@@ -650,9 +662,9 @@ viso_read(void *p, uint8_t *buffer, uint64_t seek, size_t count)
/* Handle reads in a sector by sector basis. */
while (count > 0) {
/* Determine the current sector, offset and remainder. */
uint32_t sector = seek / viso->sector_size,
sector_offset = seek % viso->sector_size,
sector_remain = MIN(count, viso->sector_size - sector_offset);
uint32_t sector = seek / viso->sector_size;
uint32_t sector_offset = seek % viso->sector_size;
uint32_t sector_remain = MIN(count, viso->sector_size - sector_offset);
/* Handle sector. */
if (sector < viso->metadata_sectors) {
@@ -736,7 +748,8 @@ viso_close(void *p)
remove(nvr_path(viso->tf.fn));
#endif
viso_entry_t *entry = viso->root_dir, *next_entry;
viso_entry_t *entry = viso->root_dir;
viso_entry_t *next_entry;
while (entry) {
if (entry->file)
fclose(entry->file);
@@ -760,7 +773,8 @@ viso_init(const char *dirname, int *error)
/* Initialize our data structure. */
viso_t *viso = (viso_t *) calloc(1, sizeof(viso_t));
uint8_t *data = NULL, *p;
uint8_t *data = NULL;
uint8_t *p;
*error = 1;
if (viso == NULL)
goto end;
@@ -785,9 +799,15 @@ viso_init(const char *dirname, int *error)
/* Set up directory traversal. */
cdrom_image_viso_log("VISO: Traversing directories:\n");
viso_entry_t *entry, *last_entry, *dir, *last_dir, *eltorito_dir = NULL, *eltorito_entry = NULL;
viso_entry_t *entry;
viso_entry_t *last_entry;
viso_entry_t *dir;
viso_entry_t *last_dir;
viso_entry_t *eltorito_dir = NULL;
viso_entry_t *eltorito_entry = NULL;
struct dirent *readdir_entry;
int len, eltorito_others_present = 0;
int len;
int eltorito_others_present = 0;
size_t dir_path_len;
uint64_t eltorito_offset = 0;
uint8_t eltorito_type = 0;
@@ -1445,8 +1465,8 @@ next_entry:
/* Go through files, assigning sectors to them. */
cdrom_image_viso_log("VISO: Assigning sectors to files:\n");
size_t base_factor = viso->sector_size / orig_sector_size;
viso_entry_t *prev_entry = viso->root_dir,
**entry_map_p = viso->entry_map;
viso_entry_t *prev_entry = viso->root_dir;
viso_entry_t **entry_map_p = viso->entry_map;
entry = prev_entry->next;
while (entry) {
/* Skip this entry if it corresponds to a directory. */
@@ -1512,7 +1532,8 @@ next_entry:
if (!viso->metadata)
goto end;
fseeko64(viso->tf.file, 0, SEEK_SET);
uint64_t metadata_size = viso->metadata_sectors * viso->sector_size, metadata_remain = metadata_size;
uint64_t metadata_size = viso->metadata_sectors * viso->sector_size;
uint64_t metadata_remain = metadata_size;
while (metadata_remain > 0)
metadata_remain -= fread(viso->metadata + (metadata_size - metadata_remain), 1, MIN(metadata_remain, viso->sector_size), viso->tf.file);

View File

@@ -116,7 +116,9 @@ typedef struct {
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
#ifdef MSFtoLBA
#undef MSFtoLBA
#endif
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
#define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4))
@@ -242,9 +244,11 @@ mitsumi_cdrom_in(uint16_t port, void *priv)
ret |= FLAG_NOSTAT;
pclog("Read port 1: ret = %02x\n", ret | FLAG_UNK);
return ret | FLAG_UNK;
default:
break;
}
return (0xff);
return 0xff;
}
static void
@@ -283,6 +287,8 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
case 0x10:
dev->enable_irq = val;
break;
default:
break;
}
dev->cmdbuf[1] = 0;
dev->cmdbuf_count = 2;
@@ -297,6 +303,8 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
if (dev->conf == 1)
dev->cmdrd_count++;
break;
default:
break;
}
break;
case CMD_READ1X:
@@ -320,8 +328,12 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
case 3:
dev->readmsf |= CD_DCB(val) << ((dev->cmdrd_count - 3) << 3);
break;
default:
break;
}
break;
default:
break;
}
if (!dev->cmdrd_count)
dev->stat = cdrom.host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
@@ -406,11 +418,13 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
case 1:
mitsumi_cdrom_reset(dev);
break;
default:
break;
}
}
static void *
mitsumi_cdrom_init(const device_t *info)
mitsumi_cdrom_init(UNUSED(const device_t *info))
{
mcd_t *dev;

View File

@@ -28,23 +28,24 @@
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/nmi.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/rom.h>
#include <86box/chipset.h>
typedef struct
{
typedef struct ems_page_t {
int enabled;
uint32_t virt, phys;
uint32_t virt;
uint32_t phys;
} ems_page_t;
typedef struct
{
uint8_t index, access;
uint16_t ems_io_base;
uint32_t ems_window_base;
uint8_t ems_page_regs[4],
regs[256];
typedef struct ct_82c100_t {
uint8_t index;
uint8_t access;
uint16_t ems_io_base;
uint32_t ems_window_base;
uint8_t ems_page_regs[4];
uint8_t regs[256];
ems_page_t ems_pages[4];
mem_mapping_t ems_mappings[4];
} ct_82c100_t;
@@ -70,10 +71,9 @@ ct_82c100_log(const char *fmt, ...)
static void
ct_82c100_ems_pages_recalc(ct_82c100_t *dev)
{
int i;
uint32_t page_base;
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
page_base = dev->ems_window_base + (i << 14);
if ((i == 1) || (i == 2))
page_base ^= 0xc000;
@@ -120,9 +120,7 @@ ct_82c100_ems_in(uint16_t port, void *priv)
static void
ct_82c100_ems_update(ct_82c100_t *dev)
{
int i;
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
ct_82c100_log("Disabling EMS I/O handler %i at %04X\n", i, dev->ems_io_base + (i << 14));
io_handler(0, dev->ems_io_base + (i << 14), 1,
ct_82c100_ems_in, NULL, NULL, ct_82c100_ems_out, NULL, NULL, dev);
@@ -130,7 +128,7 @@ ct_82c100_ems_update(ct_82c100_t *dev)
dev->ems_io_base = 0x0208 + (dev->regs[0x4c] & 0xf0);
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
ct_82c100_log("Enabling EMS I/O handler %i at %04X\n", i, dev->ems_io_base + (i << 14));
io_handler(1, dev->ems_io_base + (i << 14), 1,
ct_82c100_ems_in, NULL, NULL, ct_82c100_ems_out, NULL, NULL, dev);
@@ -222,6 +220,9 @@ ct_82c100_out(uint16_t port, uint8_t val, void *priv)
dev->regs[0x4c] = val;
ct_82c100_ems_update(dev);
break;
default:
break;
}
dev->access = 0;
}
@@ -258,6 +259,9 @@ ct_82c100_in(uint16_t port, void *priv)
case 0x4c:
ret = dev->regs[dev->index];
break;
default:
break;
}
dev->access = 0;
}
@@ -350,10 +354,9 @@ ct_82c100_close(void *priv)
}
static void *
ct_82c100_init(const device_t *info)
ct_82c100_init(UNUSED(const device_t *info))
{
ct_82c100_t *dev;
uint32_t i;
dev = (ct_82c100_t *) malloc(sizeof(ct_82c100_t));
memset(dev, 0x00, sizeof(ct_82c100_t));
@@ -367,7 +370,7 @@ ct_82c100_init(const device_t *info)
io_sethandler(0x007e, 2,
ct_82c100_in, NULL, NULL, ct_82c100_out, NULL, NULL, dev);
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
mem_mapping_add(&(dev->ems_mappings[i]), (i + 28) << 14, 0x04000,
mem_read_emsb, mem_read_emsw, NULL,
mem_write_emsb, mem_write_emsw, NULL,
@@ -379,7 +382,7 @@ ct_82c100_init(const device_t *info)
device_add(&port_92_device);
return (dev);
return dev;
}
const device_t ct_82c100_device = {

View File

@@ -30,6 +30,7 @@
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/port_92.h>
#include <86box/plat_unused.h>
#include <86box/chipset.h>
#define ENABLED_SHADOW (MEM_READ_INTERNAL | ((dev->regs[0x02] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL))
@@ -57,20 +58,21 @@ acc2168_log(const char *fmt, ...)
#endif
typedef struct acc2168_t {
uint8_t reg_idx, regs[256];
uint8_t reg_idx;
uint8_t regs[256];
} acc2168_t;
static void
acc2168_shadow_recalc(acc2168_t *dev)
{
for (uint32_t i = 0; i < 5; i++)
for (uint8_t i = 0; i < 5; i++)
mem_set_mem_state_both(SHADOW_ADDR, SHADOW_SIZE, SHADOW_RECALC);
}
static void
acc2168_write(uint16_t addr, uint8_t val, void *p)
acc2168_write(uint16_t addr, uint8_t val, void *priv)
{
acc2168_t *dev = (acc2168_t *) p;
acc2168_t *dev = (acc2168_t *) priv;
switch (addr) {
case 0xf2:
@@ -158,13 +160,15 @@ acc2168_write(uint16_t addr, uint8_t val, void *p)
break;
}
break;
default:
break;
}
}
static uint8_t
acc2168_read(uint16_t addr, void *p)
acc2168_read(uint16_t addr, void *priv)
{
acc2168_t *dev = (acc2168_t *) p;
acc2168_t *dev = (acc2168_t *) priv;
return (addr == 0xf3) ? dev->regs[dev->reg_idx] : dev->reg_idx;
}
@@ -178,7 +182,7 @@ acc2168_close(void *priv)
}
static void *
acc2168_init(const device_t *info)
acc2168_init(UNUSED(const device_t *info))
{
acc2168_t *dev = (acc2168_t *) malloc(sizeof(acc2168_t));
memset(dev, 0, sizeof(acc2168_t));

View File

@@ -1,21 +1,23 @@
/*
* 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.
*
* Implementation of the ALi M1429 chipset.
* Implementation of the ALi M1429 chipset.
*
* Note: This chipset has no datasheet, everything were done via
* reverse engineering the BIOS of various machines using it.
* Note: This chipset has no datasheet, everything were done via
* reverse engineering the BIOS of various machines using it.
*
* Authors: Tiseno100,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2020,2021 Tiseno100.
* Copyright 2021,2021 Miran Grca.
*
* Authors: Tiseno100,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2020-2021 Tiseno100.
* Copyright 2021 Miran Grca.
*/
/*
@@ -64,15 +66,14 @@
Register 20h:
Bits 2-1-0: Bus Clock Speed
0 0 0: 7.1519Mhz (ATCLK2)
0 0 1: CLK2IN/4
0 1 0: CLK2IN/5
0 1 1: CLK2IN/6
1 0 0: CLK2IN/8
1 0 1: CLK2IN/10
1 1 0: CLK2IN/12
0 0 1: CLK2IN/4
0 1 0: CLK2IN/5
0 1 1: CLK2IN/6
1 0 0: CLK2IN/8
1 0 1: CLK2IN/10
1 1 0: CLK2IN/12
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -94,13 +95,11 @@
#include <86box/smram.h>
#include <86box/chipset.h>
#define GREEN dev->is_g /* Is G Variant */
#define GREEN dev->is_g /* Is G Variant */
#ifdef ENABLE_ALI1429_LOG
int ali1429_do_log = ENABLE_ALI1429_LOG;
static void
ali1429_log(const char *fmt, ...)
{
@@ -113,29 +112,31 @@ ali1429_log(const char *fmt, ...)
}
}
#else
#define ali1429_log(fmt, ...)
# define ali1429_log(fmt, ...)
#endif
typedef struct
{
uint8_t is_g, index, cfg_locked, reg_57h,
regs[90];
typedef struct ali_1429_t {
uint8_t is_g;
uint8_t index;
uint8_t cfg_locked;
uint8_t reg_57h;
uint8_t regs[90];
} ali1429_t;
static void
ali1429_shadow_recalc(ali1429_t *dev)
{
uint32_t base, i, can_write, can_read;
uint32_t base;
uint32_t can_write;
uint32_t can_read;
shadowbios = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x01);
shadowbios = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x01);
shadowbios_write = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x02);
can_write = (dev->regs[0x14] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
can_read = (dev->regs[0x14] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
can_read = (dev->regs[0x14] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
for (i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
base = 0xc0000 + (i << 15);
if (dev->regs[0x13] & (1 << i))
@@ -147,149 +148,159 @@ ali1429_shadow_recalc(ali1429_t *dev)
flushmmucache_nopc();
}
static void
ali1429_write(uint16_t addr, uint8_t val, void *priv)
{
ali1429_t *dev = (ali1429_t *)priv;
ali1429_t *dev = (ali1429_t *) priv;
switch (addr) {
case 0x22:
dev->index = val;
break;
case 0x22:
dev->index = val;
break;
case 0x23:
case 0x23:
#ifdef ENABLE_ALI1429_LOG
if (dev->index != 0x03)
ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val);
if (dev->index != 0x03)
ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val);
#endif
if (dev->index == 0x03)
dev->cfg_locked = (val != 0xc5);
if (dev->index == 0x03)
dev->cfg_locked = (val != 0xc5);
if (!dev->cfg_locked) {
pclog("M1429: dev->regs[%02x] = %02x\n", dev->index, val);
if (!dev->cfg_locked) {
ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val);
/* Common M1429 Registers */
switch (dev->index) {
case 0x10: case 0x11:
dev->regs[dev->index] = val;
break;
/* Common M1429 Registers */
switch (dev->index) {
case 0x10:
case 0x11:
dev->regs[dev->index] = val;
break;
case 0x12:
dev->regs[dev->index] = val;
if(val & 4)
mem_remap_top(128);
else
mem_remap_top(0);
break;
case 0x12:
dev->regs[dev->index] = val;
if (val & 4)
mem_remap_top(128);
else
mem_remap_top(0);
break;
case 0x13: case 0x14:
dev->regs[dev->index] = val;
ali1429_shadow_recalc(dev);
break;
case 0x13:
case 0x14:
dev->regs[dev->index] = val;
ali1429_shadow_recalc(dev);
break;
case 0x15: case 0x16:
case 0x17:
dev->regs[dev->index] = val;
break;
case 0x15:
case 0x16:
case 0x17:
dev->regs[dev->index] = val;
break;
case 0x18:
dev->regs[dev->index] = (val & 0x8f) | 0x20;
cpu_cache_ext_enabled = !!(val & 2);
cpu_update_waitstates();
break;
case 0x18:
dev->regs[dev->index] = (val & 0x8f) | 0x20;
cpu_cache_ext_enabled = !!(val & 2);
cpu_update_waitstates();
break;
case 0x19: case 0x1a:
case 0x1e:
dev->regs[dev->index] = val;
break;
case 0x19:
case 0x1a:
case 0x1e:
dev->regs[dev->index] = val;
break;
case 0x20:
dev->regs[dev->index] = val;
case 0x20:
dev->regs[dev->index] = val;
switch(val & 7) {
case 0: case 7: /* Illegal */
cpu_set_isa_speed(7159091);
break;
switch (val & 7) {
case 0:
case 7: /* Illegal */
cpu_set_isa_speed(7159091);
break;
case 1:
cpu_set_isa_speed(cpu_busspeed / 4);
break;
case 1:
cpu_set_isa_speed(cpu_busspeed / 4);
break;
case 2:
cpu_set_isa_speed(cpu_busspeed / 5);
break;
case 2:
cpu_set_isa_speed(cpu_busspeed / 5);
break;
case 3:
cpu_set_isa_speed(cpu_busspeed / 6);
break;
case 3:
cpu_set_isa_speed(cpu_busspeed / 6);
break;
case 4:
cpu_set_isa_speed(cpu_busspeed / 8);
break;
case 4:
cpu_set_isa_speed(cpu_busspeed / 8);
break;
case 5:
cpu_set_isa_speed(cpu_busspeed / 10);
break;
case 5:
cpu_set_isa_speed(cpu_busspeed / 10);
break;
case 6:
cpu_set_isa_speed(cpu_busspeed / 12);
break;
}
break;
case 6:
cpu_set_isa_speed(cpu_busspeed / 12);
break;
default:
break;
}
break;
case 0x21 ... 0x27:
dev->regs[dev->index] = val;
break;
}
case 0x21 ... 0x27:
dev->regs[dev->index] = val;
break;
default:
break;
}
/* M1429G Only Registers */
if (GREEN) {
switch (dev->index) {
case 0x30 ... 0x41:
case 0x43: case 0x45:
case 0x4a:
dev->regs[dev->index] = val;
break;
/* M1429G Only Registers */
if (GREEN) {
switch (dev->index) {
case 0x30 ... 0x41:
case 0x43:
case 0x45:
case 0x4a:
dev->regs[dev->index] = val;
break;
case 0x57:
dev->reg_57h = val;
break;
}
}
}
break;
case 0x57:
dev->reg_57h = val;
break;
default:
break;
}
}
}
break;
default:
break;
}
}
static uint8_t
ali1429_read(uint16_t addr, void *priv)
{
ali1429_t *dev = (ali1429_t *)priv;
uint8_t ret = 0xff;
ali1429_t *dev = (ali1429_t *) priv;
uint8_t ret = 0xff;
if ((addr == 0x23) && (dev->index >= 0x10) && (dev->index <= 0x4a))
ret = dev->regs[dev->index];
ret = dev->regs[dev->index];
else if ((addr == 0x23) && (dev->index == 0x57))
ret = dev->reg_57h;
ret = dev->reg_57h;
else if (addr == 0x22)
ret = dev->index;
ret = dev->index;
return ret;
}
static void
ali1429_close(void *priv)
{
ali1429_t *dev = (ali1429_t *)priv;
ali1429_t *dev = (ali1429_t *) priv;
free(dev);
}
static void
ali1429_defaults(ali1429_t *dev)
{
@@ -308,28 +319,27 @@ ali1429_defaults(ali1429_t *dev)
/* M1429G Default Registers */
if (GREEN) {
dev->regs[0x31] = 0x88;
dev->regs[0x32] = 0xc0;
dev->regs[0x38] = 0xe5;
dev->regs[0x40] = 0xe3;
dev->regs[0x41] = 2;
dev->regs[0x45] = 0x80;
dev->regs[0x31] = 0x88;
dev->regs[0x32] = 0xc0;
dev->regs[0x38] = 0xe5;
dev->regs[0x40] = 0xe3;
dev->regs[0x41] = 2;
dev->regs[0x45] = 0x80;
}
}
static void *
ali1429_init(const device_t *info)
{
ali1429_t *dev = (ali1429_t *)malloc(sizeof(ali1429_t));
ali1429_t *dev = (ali1429_t *) malloc(sizeof(ali1429_t));
memset(dev, 0, sizeof(ali1429_t));
dev->cfg_locked = 1;
GREEN = info->local;
GREEN = info->local;
/* M1429 Ports:
22h Index Port
23h Data Port
22h Index Port
23h Data Port
*/
io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, dev);
@@ -341,29 +351,29 @@ ali1429_init(const device_t *info)
}
const device_t ali1429_device = {
.name = "ALi M1429",
.name = "ALi M1429",
.internal_name = "ali1429",
.flags = 0,
.local = 0,
.init = ali1429_init,
.close = ali1429_close,
.reset = NULL,
.flags = 0,
.local = 0,
.init = ali1429_init,
.close = ali1429_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t ali1429g_device = {
.name = "ALi M1429G",
.name = "ALi M1429G",
.internal_name = "ali1429g",
.flags = 0,
.local = 1,
.init = ali1429_init,
.close = ali1429_close,
.reset = NULL,
.flags = 0,
.local = 1,
.init = ali1429_init,
.close = ali1429_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};

View File

@@ -1,323 +1,327 @@
/*
* 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.
*
* Emulation of ALi M1435 chipset that acts as both the
* southbridge.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2020 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/apm.h>
#include <86box/dma.h>
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pci.h>
#include <86box/timer.h>
#include <86box/pic.h>
#include <86box/pit.h>
#include <86box/port_92.h>
#include <86box/hdc_ide.h>
#include <86box/hdc.h>
#include <86box/machine.h>
#include <86box/chipset.h>
#include <86box/spd.h>
#define MEM_STATE_SHADOW_R 0x01
#define MEM_STATE_SHADOW_W 0x02
#define MEM_STATE_SMRAM 0x04
typedef struct
{
uint8_t index, cfg_locked,
regs[16], pci_regs[256];
} ali1435_t;
#define ENABLE_ALI1435_LOG 1
#ifdef ENABLE_ALI1435_LOG
int ali1435_do_log = ENABLE_ALI1435_LOG;
static void
ali1435_log(const char *fmt, ...)
{
va_list ap;
if (ali1435_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define ali1435_log(fmt, ...)
#endif
/* NOTE: We cheat here. The real ALi M1435 uses a level to edge triggered IRQ converter
when the most siginificant bit is set. We work around that by manipulating the
emulated PIC's ELCR register. */
static void
ali1435_update_irqs(ali1435_t *dev, int set)
{
uint8_t val;
int i, reg;
int shift, irq;
int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
pic_t *temp_pic;
for (i = 0; i < 4; i++) {
reg = 0x80 + (i >> 1);
shift = (i & 1) << 2;
val = (dev->pci_regs[reg] >> shift) & 0x0f;
irq = irq_map[val & 0x07];
if (irq == -1)
continue;
temp_pic = (irq >= 8) ? &pic2 : &pic;
irq &= 7;
if (set && (val & 0x08))
temp_pic->elcr |= (1 << irq);
else
temp_pic->elcr &= ~(1 << irq);
}
}
static void
ali1435_pci_write(int func, int addr, uint8_t val, void *priv)
{
ali1435_t *dev = (ali1435_t *) priv;
int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
ali1435_log("ali1435_write(%02X, %02X, %02X)\n", func, addr, val);
if (func > 0)
return;
if ((addr < 0x04) || (addr == 0x06) || ((addr >= 0x08) && (addr <= 0x0b)))
return;
if ((addr >= 0x0f) && (addr < 0x30))
return;
if ((addr >= 0x34) && (addr < 0x40))
return;
switch (addr) {
/* Dummy PCI Config */
case 0x04:
dev->pci_regs[addr] = (val & 0x7f) | 0x07;
break;
case 0x05:
dev->pci_regs[addr] = (val & 0x01);
break;
/* Dummy PCI Status */
case 0x07:
dev->pci_regs[addr] &= ~(val & 0xb8);
break;
case 0x80: case 0x81:
dev->pci_regs[addr] = val;
ali1435_update_irqs(dev, 0);
irq = irq_map[val & 0x07];
if (irq >= 0) {
ali1435_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + ((addr & 0x01) << 1), irq);
pci_set_irq_routing(PCI_INTA + ((addr & 0x01) << 1), irq);
} else {
ali1435_log("Set IRQ routing: INT %c -> FF\n", 0x41 + ((addr & 0x01) << 1));
pci_set_irq_routing(PCI_INTA + ((addr & 0x01) << 1), PCI_IRQ_DISABLED);
}
irq = irq_map[(val >> 4) & 0x07];
if (irq >= 0) {
ali1435_log("Set IRQ routing: INT %c -> %02X\n", 0x42 + ((addr & 0x01) << 1), irq);
pci_set_irq_routing(PCI_INTB + ((addr & 0x01) << 1), irq);
} else {
ali1435_log("Set IRQ routing: INT %c -> FF\n", 0x42 + ((addr & 0x01) << 1));
pci_set_irq_routing(PCI_INTB + ((addr & 0x01) << 1), PCI_IRQ_DISABLED);
}
ali1435_update_irqs(dev, 1);
break;
default:
dev->pci_regs[addr] = val;
break;
}
}
static uint8_t
ali1435_pci_read(int func, int addr, void *priv)
{
ali1435_t *dev = (ali1435_t *) priv;
uint8_t ret;
ret = 0xff;
if (func == 0)
ret = dev->pci_regs[addr];
ali1435_log("ali1435_read(%02X, %02X) = %02X\n", func, addr, ret);
return ret;
}
static void
ali1435_write(uint16_t addr, uint8_t val, void *priv)
{
ali1435_t *dev = (ali1435_t *)priv;
switch (addr) {
case 0x22:
dev->index = val;
break;
case 0x23:
/* #ifdef ENABLE_ALI1435_LOG
if (dev->index != 0x03)
ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
#endif */
if (dev->index == 0x03)
dev->cfg_locked = (val != 0x69);
if (!dev->cfg_locked) {
pclog("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
switch (dev->index) {
/* PCI Mechanism select? */
case 0x00:
dev->regs[dev->index] = val;
pclog("PMC = %i\n", val != 0xc8);
pci_set_pmc(val != 0xc8);
break;
/* ???? */
case 0x06:
dev->regs[dev->index] = val;
break;
/* ???? */
case 0x07:
dev->regs[dev->index] = val;
break;
}
}
break;
}
}
static uint8_t
ali1435_read(uint16_t addr, void *priv)
{
ali1435_t *dev = (ali1435_t *)priv;
uint8_t ret = 0xff;
if ((addr == 0x23) && (dev->index < 0x10))
ret = dev->regs[dev->index];
else if (addr == 0x22)
ret = dev->index;
return ret;
}
static void
ali1435_reset(void *priv)
{
ali1435_t *dev = (ali1435_t *) priv;
memset(dev->regs, 0, 16);
dev->regs[0x00] = 0xff;
pci_set_pmc(0);
dev->cfg_locked = 1;
memset(dev->pci_regs, 0, 256);
dev->pci_regs[0x00] = 0x25; dev->pci_regs[0x01] = 0x10; /*ALi*/
dev->pci_regs[0x02] = 0x35; dev->pci_regs[0x03] = 0x14; /*M1435*/
dev->pci_regs[0x04] = 0x07;
dev->pci_regs[0x07] = 0x04;
dev->pci_regs[0x0b] = 0x06;
dev->pci_regs[0x80] = 0x80; dev->pci_regs[0x81] = 0x00;
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
}
static void
ali1435_close(void *p)
{
ali1435_t *dev = (ali1435_t *)p;
free(dev);
}
static void *
ali1435_init(const device_t *info)
{
ali1435_t *dev = (ali1435_t *) malloc(sizeof(ali1435_t));
memset(dev, 0, sizeof(ali1435_t));
dev->cfg_locked = 1;
/* M1435 Ports:
22h Index Port
23h Data Port
*/
io_sethandler(0x0022, 0x0002, ali1435_read, NULL, NULL, ali1435_write, NULL, NULL, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev);
ali1435_reset(dev);
/* pci_set_irq_level(PCI_INTA, 0);
pci_set_irq_level(PCI_INTB, 0);
pci_set_irq_level(PCI_INTC, 0);
pci_set_irq_level(PCI_INTD, 0); */
return dev;
}
const device_t ali1435_device = {
.name = "Intel ALi M1435",
.internal_name = "ali1435",
.flags = DEVICE_PCI,
.local = 0x00,
.init = ali1435_init,
.close = ali1435_close,
.reset = ali1435_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
/*
* 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.
*
* Emulation of ALi M1435 chipset that acts as both the
* southbridge.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2020 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/apm.h>
#include <86box/dma.h>
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pci.h>
#include <86box/timer.h>
#include <86box/pic.h>
#include <86box/pit.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/hdc_ide.h>
#include <86box/hdc.h>
#include <86box/machine.h>
#include <86box/chipset.h>
#include <86box/spd.h>
#define MEM_STATE_SHADOW_R 0x01
#define MEM_STATE_SHADOW_W 0x02
#define MEM_STATE_SMRAM 0x04
typedef struct ali_1435_t {
uint8_t index;
uint8_t cfg_locked;
uint8_t regs[16];
uint8_t pci_regs[256];
} ali1435_t;
#define ENABLE_ALI1435_LOG 1
#ifdef ENABLE_ALI1435_LOG
int ali1435_do_log = ENABLE_ALI1435_LOG;
static void
ali1435_log(const char *fmt, ...)
{
va_list ap;
if (ali1435_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define ali1435_log(fmt, ...)
#endif
/* NOTE: We cheat here. The real ALi M1435 uses a level to edge triggered IRQ converter
when the most siginificant bit is set. We work around that by manipulating the
emulated PIC's ELCR register. */
static void
ali1435_update_irqs(ali1435_t *dev, int set)
{
uint8_t val;
int reg;
int shift;
int irq;
int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
pic_t *temp_pic;
for (uint8_t i = 0; i < 4; i++) {
reg = 0x80 + (i >> 1);
shift = (i & 1) << 2;
val = (dev->pci_regs[reg] >> shift) & 0x0f;
irq = irq_map[val & 0x07];
if (irq == -1)
continue;
temp_pic = (irq >= 8) ? &pic2 : &pic;
irq &= 7;
if (set && (val & 0x08))
temp_pic->elcr |= (1 << irq);
else
temp_pic->elcr &= ~(1 << irq);
}
}
static void
ali1435_pci_write(int func, int addr, uint8_t val, void *priv)
{
ali1435_t *dev = (ali1435_t *) priv;
int irq;
int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
ali1435_log("ali1435_write(%02X, %02X, %02X)\n", func, addr, val);
if (func > 0)
return;
if ((addr < 0x04) || (addr == 0x06) || ((addr >= 0x08) && (addr <= 0x0b)))
return;
if ((addr >= 0x0f) && (addr < 0x30))
return;
if ((addr >= 0x34) && (addr < 0x40))
return;
switch (addr) {
/* Dummy PCI Config */
case 0x04:
dev->pci_regs[addr] = (val & 0x7f) | 0x07;
break;
case 0x05:
dev->pci_regs[addr] = (val & 0x01);
break;
/* Dummy PCI Status */
case 0x07:
dev->pci_regs[addr] &= ~(val & 0xb8);
break;
case 0x80:
case 0x81:
dev->pci_regs[addr] = val;
ali1435_update_irqs(dev, 0);
irq = irq_map[val & 0x07];
if (irq >= 0) {
ali1435_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + ((addr & 0x01) << 1), irq);
pci_set_irq_routing(PCI_INTA + ((addr & 0x01) << 1), irq);
} else {
ali1435_log("Set IRQ routing: INT %c -> FF\n", 0x41 + ((addr & 0x01) << 1));
pci_set_irq_routing(PCI_INTA + ((addr & 0x01) << 1), PCI_IRQ_DISABLED);
}
irq = irq_map[(val >> 4) & 0x07];
if (irq >= 0) {
ali1435_log("Set IRQ routing: INT %c -> %02X\n", 0x42 + ((addr & 0x01) << 1), irq);
pci_set_irq_routing(PCI_INTB + ((addr & 0x01) << 1), irq);
} else {
ali1435_log("Set IRQ routing: INT %c -> FF\n", 0x42 + ((addr & 0x01) << 1));
pci_set_irq_routing(PCI_INTB + ((addr & 0x01) << 1), PCI_IRQ_DISABLED);
}
ali1435_update_irqs(dev, 1);
break;
default:
dev->pci_regs[addr] = val;
break;
}
}
static uint8_t
ali1435_pci_read(int func, int addr, void *priv)
{
ali1435_t *dev = (ali1435_t *) priv;
uint8_t ret;
ret = 0xff;
if (func == 0)
ret = dev->pci_regs[addr];
ali1435_log("ali1435_read(%02X, %02X) = %02X\n", func, addr, ret);
return ret;
}
static void
ali1435_write(uint16_t addr, uint8_t val, void *priv)
{
ali1435_t *dev = (ali1435_t *) priv;
switch (addr) {
case 0x22:
dev->index = val;
break;
case 0x23:
#if 0
#ifdef ENABLE_ALI1435_LOG
if (dev->index != 0x03)
ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
#endif
#endif
if (dev->index == 0x03)
dev->cfg_locked = (val != 0x69);
if (!dev->cfg_locked) {
pclog("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
switch (dev->index) {
/* PCI Mechanism select? */
case 0x00:
dev->regs[dev->index] = val;
pclog("PMC = %i\n", val != 0xc8);
pci_set_pmc(val != 0xc8);
break;
/* ???? */
case 0x06:
dev->regs[dev->index] = val;
break;
/* ???? */
case 0x07:
dev->regs[dev->index] = val;
break;
default:
break;
}
}
break;
default:
break;
}
}
static uint8_t
ali1435_read(uint16_t addr, void *priv)
{
ali1435_t *dev = (ali1435_t *) priv;
uint8_t ret = 0xff;
if ((addr == 0x23) && (dev->index < 0x10))
ret = dev->regs[dev->index];
else if (addr == 0x22)
ret = dev->index;
return ret;
}
static void
ali1435_reset(void *priv)
{
ali1435_t *dev = (ali1435_t *) priv;
memset(dev->regs, 0, 16);
dev->regs[0x00] = 0xff;
pci_set_pmc(0);
dev->cfg_locked = 1;
memset(dev->pci_regs, 0, 256);
dev->pci_regs[0x00] = 0x25;
dev->pci_regs[0x01] = 0x10; /*ALi*/
dev->pci_regs[0x02] = 0x35;
dev->pci_regs[0x03] = 0x14; /*M1435*/
dev->pci_regs[0x04] = 0x07;
dev->pci_regs[0x07] = 0x04;
dev->pci_regs[0x0b] = 0x06;
dev->pci_regs[0x80] = 0x80;
dev->pci_regs[0x81] = 0x00;
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
}
static void
ali1435_close(void *priv)
{
ali1435_t *dev = (ali1435_t *) priv;
free(dev);
}
static void *
ali1435_init(UNUSED(const device_t *info))
{
ali1435_t *dev = (ali1435_t *) malloc(sizeof(ali1435_t));
memset(dev, 0, sizeof(ali1435_t));
dev->cfg_locked = 1;
/* M1435 Ports:
22h Index Port
23h Data Port
*/
io_sethandler(0x0022, 0x0002, ali1435_read, NULL, NULL, ali1435_write, NULL, NULL, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev);
ali1435_reset(dev);
#if 0
pci_set_irq_level(PCI_INTA, 0);
pci_set_irq_level(PCI_INTB, 0);
pci_set_irq_level(PCI_INTC, 0);
pci_set_irq_level(PCI_INTD, 0);
#endif
return dev;
}
const device_t ali1435_device = {
.name = "Intel ALi M1435",
.internal_name = "ali1435",
.flags = DEVICE_PCI,
.local = 0x00,
.init = ali1435_init,
.close = ali1435_close,
.reset = ali1435_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -35,6 +35,7 @@
#include <86box/nmi.h>
#include <86box/pic.h>
#include <86box/pci.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/smram.h>
@@ -61,10 +62,14 @@ ali1489_log(const char *fmt, ...)
# define ali1489_log(fmt, ...)
#endif
typedef struct
{
uint8_t index, ide_index, ide_chip_id, pci_slot,
regs[256], pci_conf[256], ide_regs[256];
typedef struct ali1489_t {
uint8_t index;
uint8_t ide_index;
uint8_t ide_chip_id;
uint8_t pci_slot;
uint8_t regs[256];
uint8_t pci_conf[256];
uint8_t ide_regs[256];
port_92_t *port_92;
smram_t *smram;
@@ -75,11 +80,9 @@ static void ali1489_ide_handler(ali1489_t *dev);
static void
ali1489_shadow_recalc(ali1489_t *dev)
{
uint32_t i;
shadowbios = shadowbios_write = 0;
for (i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
if (dev->regs[0x13] & (1 << i)) {
ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n",
0xc0000 + (i << 14), 0xc3fff + (i << 14), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
@@ -90,7 +93,7 @@ ali1489_shadow_recalc(ali1489_t *dev)
}
}
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
if (dev->regs[0x14] & (1 << i)) {
ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n",
0xe0000 + (i << 15), 0xe7fff + (i << 15), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
@@ -126,6 +129,8 @@ ali1489_smram_recalc(ali1489_t *dev)
else
smram_enable(dev->smram, 0x38000, 0xa8000, 0x08000, (dev->regs[0x19] & 0x08), 1);
break;
default:
break;
}
if ((dev->regs[0x19] & 0x31) == 0x11) {
@@ -206,7 +211,8 @@ static void
ali1489_write(uint16_t addr, uint8_t val, void *priv)
{
ali1489_t *dev = (ali1489_t *) priv;
uint8_t old, irq;
uint8_t old;
uint8_t irq;
const uint8_t irq_array[16] = { 0, 3, 4, 7, 0, 0, 0, 0, 9, 10, 5, 6, 11, 12, 14, 15 };
switch (addr) {
@@ -319,6 +325,8 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv)
case 0x30:
picint(1 << 10);
break;
default:
break;
}
dev->regs[0x35] |= 0x0e;
} else if (!(val & 0x10))
@@ -380,6 +388,8 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv)
/* TODO: When doing the IRQ and PCI IRQ rewrite, bits 0 to 3 toggle edge/level output. */
dev->regs[dev->index] = val;
break;
default:
break;
}
if (dev->index != 0x03) {
@@ -389,6 +399,9 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv)
dev->regs[dev->index] = val;
break;
default:
break;
}
}
@@ -408,6 +421,8 @@ ali1489_read(uint16_t addr, void *priv)
else
ret = dev->regs[dev->index];
break;
default:
break;
}
ali1489_log("M1489: dev->regs[%02x] (%02x)\n", dev->index, ret);
@@ -416,7 +431,7 @@ ali1489_read(uint16_t addr, void *priv)
}
static void
ali1489_pci_write(int func, int addr, uint8_t val, void *priv)
ali1489_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
{
ali1489_t *dev = (ali1489_t *) priv;
@@ -432,11 +447,14 @@ ali1489_pci_write(int func, int addr, uint8_t val, void *priv)
case 0x07:
dev->pci_conf[0x07] &= ~(val & 0xb8);
break;
default:
break;
}
}
static uint8_t
ali1489_pci_read(int func, int addr, void *priv)
ali1489_pci_read(UNUSED(int func), int addr, void *priv)
{
ali1489_t *dev = (ali1489_t *) priv;
uint8_t ret = 0xff;
@@ -528,8 +546,14 @@ ali1489_ide_write(uint16_t addr, uint8_t val, void *priv)
dev->ide_regs[dev->ide_index] = val;
ali1489_ide_handler(dev);
break;
default:
break;
}
break;
default:
break;
}
}
@@ -547,6 +571,9 @@ ali1489_ide_read(uint16_t addr, void *priv)
ret = dev->ide_regs[dev->ide_index];
ali1489_log("M1489-IDE: dev->regs[%02x] (%02x)\n", dev->ide_index, ret);
break;
default:
break;
}
return ret;
@@ -575,7 +602,7 @@ ali1489_close(void *priv)
}
static void *
ali1489_init(const device_t *info)
ali1489_init(UNUSED(const device_t *info))
{
ali1489_t *dev = (ali1489_t *) malloc(sizeof(ali1489_t));
memset(dev, 0, sizeof(ali1489_t));

View File

@@ -28,6 +28,7 @@
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/plat_unused.h>
#include <86box/smram.h>
#include <86box/spd.h>
@@ -82,6 +83,9 @@ ali1531_smram_recalc(uint8_t val, ali1531_t *dev)
if (val & 0x10)
mem_set_mem_state_smram_ex(1, 0x30000, 0x10000, 0x02);
break;
default:
break;
}
}
@@ -89,14 +93,17 @@ ali1531_smram_recalc(uint8_t val, ali1531_t *dev)
}
static void
ali1531_shadow_recalc(int cur_reg, ali1531_t *dev)
ali1531_shadow_recalc(UNUSED(int cur_reg), ali1531_t *dev)
{
int i, bit, r_reg, w_reg;
uint32_t base, flags = 0;
int bit;
int r_reg;
int w_reg;
uint32_t base;
uint32_t flags = 0;
shadowbios = shadowbios_write = 0;
for (i = 0; i < 16; i++) {
for (uint8_t i = 0; i < 16; i++) {
base = 0x000c0000 + (i << 14);
bit = i & 7;
r_reg = 0x4c + (i >> 3);
@@ -121,7 +128,7 @@ ali1531_shadow_recalc(int cur_reg, ali1531_t *dev)
}
static void
ali1531_write(int func, int addr, uint8_t val, void *priv)
ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv)
{
ali1531_t *dev = (ali1531_t *) priv;
@@ -225,8 +232,10 @@ ali1531_write(int func, int addr, uint8_t val, void *priv)
case 0x57: /* H2PO */
dev->pci_conf[addr] = val & 0x60;
/* Find where the Shut-down Special cycle is initiated. */
// if (!(val & 0x20))
// outb(0x92, 0x01);
#if 0
if (!(val & 0x20))
outb(0x92, 0x01);
#endif
break;
case 0x58:
@@ -285,11 +294,14 @@ ali1531_write(int func, int addr, uint8_t val, void *priv)
case 0x83:
dev->pci_conf[addr] = val & 0x10;
break;
default:
break;
}
}
static uint8_t
ali1531_read(int func, int addr, void *priv)
ali1531_read(UNUSED(int func), int addr, void *priv)
{
ali1531_t *dev = (ali1531_t *) priv;
uint8_t ret = 0xff;
@@ -303,7 +315,6 @@ static void
ali1531_reset(void *priv)
{
ali1531_t *dev = (ali1531_t *) priv;
int i;
/* Default Registers */
dev->pci_conf[0x00] = 0xb9;
@@ -339,10 +350,10 @@ ali1531_reset(void *priv)
ali1531_write(0, 0x47, 0x00, dev);
ali1531_write(0, 0x48, 0x00, dev);
for (i = 0; i < 4; i++)
for (uint8_t i = 0; i < 4; i++)
ali1531_write(0, 0x4c + i, 0x00, dev);
for (i = 0; i < 16; i += 2) {
for (uint8_t i = 0; i < 16; i += 2) {
ali1531_write(0, 0x60 + i, 0x08, dev);
ali1531_write(0, 0x61 + i, 0x40, dev);
}
@@ -358,7 +369,7 @@ ali1531_close(void *priv)
}
static void *
ali1531_init(const device_t *info)
ali1531_init(UNUSED(const device_t *info))
{
ali1531_t *dev = (ali1531_t *) malloc(sizeof(ali1531_t));
memset(dev, 0, sizeof(ali1531_t));

View File

@@ -28,6 +28,7 @@
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/plat_unused.h>
#include <86box/smram.h>
#include <86box/spd.h>
@@ -83,6 +84,8 @@ ali1541_smram_recalc(uint8_t val, ali1541_t *dev)
if (val & 0x10)
mem_set_mem_state_smram_ex(1, 0x30000, 0x10000, 0x02);
break;
default:
break;
}
}
@@ -90,14 +93,17 @@ ali1541_smram_recalc(uint8_t val, ali1541_t *dev)
}
static void
ali1541_shadow_recalc(int cur_reg, ali1541_t *dev)
ali1541_shadow_recalc(UNUSED(int cur_reg), ali1541_t *dev)
{
int i, bit, r_reg, w_reg;
uint32_t base, flags = 0;
int bit;
int r_reg;
int w_reg;
uint32_t base;
uint32_t flags = 0;
shadowbios = shadowbios_write = 0;
for (i = 0; i < 16; i++) {
for (uint8_t i = 0; i < 16; i++) {
base = 0x000c0000 + (i << 14);
bit = i & 7;
r_reg = 0x56 + (i >> 3);
@@ -124,11 +130,12 @@ ali1541_shadow_recalc(int cur_reg, ali1541_t *dev)
static void
ali1541_mask_bar(ali1541_t *dev)
{
uint32_t bar, mask;
uint32_t bar;
uint32_t mask;
switch (dev->pci_conf[0xbc] & 0x0f) {
case 0x00:
default:
case 0x00:
mask = 0x00000000;
break;
case 0x01:
@@ -166,7 +173,7 @@ ali1541_mask_bar(ali1541_t *dev)
}
static void
ali1541_write(int func, int addr, uint8_t val, void *priv)
ali1541_write(UNUSED(int func), int addr, uint8_t val, void *priv)
{
ali1541_t *dev = (ali1541_t *) priv;
@@ -363,8 +370,10 @@ ali1541_write(int func, int addr, uint8_t val, void *priv)
case 0x87: /* H2PO */
dev->pci_conf[addr] = val;
/* Find where the Shut-down Special cycle is initiated. */
// if (!(val & 0x20))
// outb(0x92, 0x01);
#if 0
if (!(val & 0x20))
outb(0x92, 0x01);
#endif
break;
case 0x88:
@@ -542,11 +551,14 @@ ali1541_write(int func, int addr, uint8_t val, void *priv)
case 0xf7:
dev->pci_conf[addr] = val & 0x43;
break;
default:
break;
}
}
static uint8_t
ali1541_read(int func, int addr, void *priv)
ali1541_read(UNUSED(int func), int addr, void *priv)
{
ali1541_t *dev = (ali1541_t *) priv;
uint8_t ret = 0xff;
@@ -560,7 +572,6 @@ static void
ali1541_reset(void *priv)
{
ali1541_t *dev = (ali1541_t *) priv;
int i;
/* Default Registers */
dev->pci_conf[0x00] = 0xb9;
@@ -603,12 +614,13 @@ ali1541_reset(void *priv)
ali1541_write(0, 0x54, 0x00, dev);
ali1541_write(0, 0x55, 0x00, dev);
for (i = 0; i < 4; i++)
for (uint8_t i = 0; i < 4; i++)
ali1541_write(0, 0x56 + i, 0x00, dev);
ali1541_write(0, 0x60 + i, 0x07, dev);
ali1541_write(0, 0x61 + i, 0x40, dev);
for (i = 0; i < 14; i += 2) {
ali1541_write(0, 0x60, 0x07, dev);
ali1541_write(0, 0x61, 0x40, dev);
for (uint8_t i = 0; i < 14; i += 2) {
ali1541_write(0, 0x62 + i, 0x00, dev);
ali1541_write(0, 0x63 + i, 0x00, dev);
}
@@ -624,7 +636,7 @@ ali1541_close(void *priv)
}
static void *
ali1541_init(const device_t *info)
ali1541_init(UNUSED(const device_t *info))
{
ali1541_t *dev = (ali1541_t *) malloc(sizeof(ali1541_t));
memset(dev, 0, sizeof(ali1541_t));

View File

@@ -36,6 +36,7 @@
#include <86box/nvr.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/sio.h>
#include <86box/smbus.h>
@@ -46,10 +47,19 @@
#include <86box/chipset.h>
typedef struct ali1543_t {
uint8_t pci_conf[256], pmu_conf[256], usb_conf[256], ide_conf[256],
pci_slot, ide_slot, usb_slot, pmu_slot, usb_dev_enable, ide_dev_enable,
pmu_dev_enable, type;
int offset;
uint8_t pci_conf[256];
uint8_t pmu_conf[256];
uint8_t usb_conf[256];
uint8_t ide_conf[256];
uint8_t pci_slot;
uint8_t ide_slot;
uint8_t usb_slot;
uint8_t pmu_slot;
uint8_t usb_dev_enable;
uint8_t ide_dev_enable;
uint8_t pmu_dev_enable;
uint8_t type;
int offset;
apm_t *apm;
acpi_t *acpi;
@@ -59,6 +69,7 @@ typedef struct ali1543_t {
sff8038i_t *ide_controller[2];
smbus_ali7101_t *smbus;
usb_t *usb;
usb_params_t usb_params;
} ali1543_t;
@@ -94,7 +105,7 @@ ali1543_log(const char *fmt, ...)
#endif
static void
ali1533_ddma_handler(ali1543_t *dev)
ali1533_ddma_handler(UNUSED(ali1543_t *dev))
{
/* TODO: Find any documentation that actually explains the ALi southbridge DDMA mapping. */
}
@@ -111,7 +122,6 @@ static void
ali1533_write(int func, int addr, uint8_t val, void *priv)
{
ali1543_t *dev = (ali1543_t *) priv;
int irq;
ali1543_log("M1533: dev->pci_conf[%02x] = %02x\n", addr, val);
if (func > 0)
@@ -151,10 +161,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x41:
/* TODO: Bit 7 selects keyboard controller type:
0 = AT, 1 = PS/2 */
keyboard_at_set_mouse_scan((val & 0x40) ? 1 : 0);
dev->pci_conf[addr] = val & 0xbf;
dev->pci_conf[addr] = val;
break;
case 0x42: /* ISA Bus Speed */
@@ -171,6 +178,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
case 6:
cpu_set_isa_pci_div((val & 7) + 1);
break;
default:
break;
}
break;
@@ -221,7 +230,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
case 0x4c: /* PCI INT to ISA Level to Edge transfer */
dev->pci_conf[addr] = val;
for (irq = 1; irq < 9; irq++)
for (uint8_t irq = 1; irq < 9; irq++)
pci_set_irq_level(irq, !(val & (1 << (irq - 1))));
break;
@@ -230,8 +239,10 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[addr] = val;
ali1543_log("SIRQI = IRQ %i; SIRQII = IRQ %i\n", ali1533_irq_routing[(val >> 4) & 0x0f], ali1533_irq_routing[val & 0x0f]);
// pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[(val >> 4) & 0x0f]);
// pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]);
#if 0
pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[(val >> 4) & 0x0f]);
pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]);
#endif
}
break;
@@ -296,6 +307,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
case 0x30:
dev->ide_slot = 0x0d; /* A24 = slot 13 */
break;
default:
break;
}
pci_relocate_slot(PCI_CARD_SOUTHBRIDGE_IDE, ((int) dev->ide_slot) + dev->offset);
ali1543_log("IDE slot = %02X (A%0i)\n", ((int) dev->ide_slot) + dev->offset, dev->ide_slot + 11);
@@ -367,6 +380,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
case 0x0c:
dev->pmu_slot = 0x04; /* A15 = slot 04 */
break;
default:
break;
}
pci_relocate_slot(PCI_CARD_SOUTHBRIDGE_PMU, ((int) dev->pmu_slot) + dev->offset);
ali1543_log("PMU slot = %02X (A%0i)\n", ((int) dev->pmu_slot) + dev->offset, dev->pmu_slot + 11);
@@ -383,6 +398,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
case 0x03:
dev->usb_slot = 0x01; /* A12 = slot 01 */
break;
default:
break;
}
pci_relocate_slot(PCI_CARD_SOUTHBRIDGE_USB, ((int) dev->usb_slot) + dev->offset);
ali1543_log("USB slot = %02X (A%0i)\n", ((int) dev->usb_slot) + dev->offset, dev->usb_slot + 11);
@@ -440,6 +457,9 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
dev->pmu_dev_enable = 0;
}
break;
default:
break;
}
}
@@ -454,9 +474,7 @@ ali1533_read(int func, int addr, void *priv)
ret = 0x00;
else {
ret = dev->pci_conf[addr];
if (addr == 0x41)
ret |= (keyboard_at_get_mouse_scan() << 2);
else if (addr == 0x58)
if (addr == 0x58)
ret = (ret & 0xbf) | (dev->ide_dev_enable ? 0x40 : 0x00);
else if ((dev->type == 1) && ((addr >= 0x7c) && (addr <= 0xff)) && !dev->pmu_dev_enable) {
dev->pmu_dev_enable = 1;
@@ -472,7 +490,8 @@ ali1533_read(int func, int addr, void *priv)
static void
ali5229_ide_irq_handler(ali1543_t *dev)
{
int ctl = 0, ch = 0;
int ctl = 0;
int ch = 0;
int bit = 0;
if (dev->ide_conf[0x52] & 0x10) {
@@ -513,6 +532,9 @@ ali5229_ide_irq_handler(ali1543_t *dev)
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 2);
break;
default:
break;
}
}
@@ -550,6 +572,9 @@ ali5229_ide_irq_handler(ali1543_t *dev)
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 2);
break;
default:
break;
}
}
}
@@ -559,17 +584,20 @@ ali5229_ide_handler(ali1543_t *dev)
{
uint32_t ch = 0;
uint16_t native_base_pri_addr = ((dev->ide_conf[0x11] | dev->ide_conf[0x10] << 8)) & 0xfffe;
uint16_t native_side_pri_addr = ((dev->ide_conf[0x15] | dev->ide_conf[0x14] << 8)) & 0xfffe;
uint16_t native_base_sec_addr = ((dev->ide_conf[0x19] | dev->ide_conf[0x18] << 8)) & 0xfffe;
uint16_t native_side_sec_addr = ((dev->ide_conf[0x1c] | dev->ide_conf[0x1b] << 8)) & 0xfffe;
uint16_t native_base_pri_addr = (dev->ide_conf[0x11] | dev->ide_conf[0x10] << 8) & 0xfffe;
uint16_t native_side_pri_addr = (dev->ide_conf[0x15] | dev->ide_conf[0x14] << 8) & 0xfffe;
uint16_t native_base_sec_addr = (dev->ide_conf[0x19] | dev->ide_conf[0x18] << 8) & 0xfffe;
uint16_t native_side_sec_addr = (dev->ide_conf[0x1c] | dev->ide_conf[0x1b] << 8) & 0xfffe;
uint16_t comp_base_pri_addr = 0x01f0;
uint16_t comp_side_pri_addr = 0x03f6;
uint16_t comp_base_sec_addr = 0x0170;
uint16_t comp_side_sec_addr = 0x0376;
uint16_t current_pri_base, current_pri_side, current_sec_base, current_sec_side;
uint16_t current_pri_base;
uint16_t current_pri_side;
uint16_t current_sec_base;
uint16_t current_sec_side;
/* Primary Channel Programming */
if (dev->ide_conf[0x52] & 0x10) {
@@ -622,7 +650,7 @@ ali5229_ide_handler(ali1543_t *dev)
ali1543_log("ali5229_ide_handler(): Enabling secondary IDE...\n");
ide_sec_enable();
sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, (((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8))) + (8 ^ ch));
sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (8 ^ ch));
ali1543_log("M5229 SEC: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side);
}
} else {
@@ -858,6 +886,9 @@ ali5229_write(int func, int addr, uint8_t val, void *priv)
case 0x5f:
dev->ide_conf[addr] = val & 0x7f;
break;
default:
break;
}
}
@@ -910,7 +941,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;
@@ -938,6 +974,9 @@ ali5237_write(int func, int addr, uint8_t val, void *priv)
if (!(dev->usb_conf[0x42] & 0x10))
dev->usb_conf[addr] = val;
break;
default:
break;
}
}
@@ -1422,6 +1461,9 @@ ali7101_read(int func, int addr, void *priv)
case 0x74:
dev->pmu_conf[addr] &= 0xcc;
break;
default:
break;
}
}
}
@@ -1429,6 +1471,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)
{
@@ -1510,7 +1563,8 @@ ali1543_reset(void *priv)
dev->pci_conf[0x0a] = 0x01;
dev->pci_conf[0x0b] = 0x06;
ali1533_write(0, 0x48, 0x00, dev); // Disables all IRQ's
ali1533_write(0, 0x41, 0x00, dev); /* Disables the keyboard and mouse IRQ latch. */
ali1533_write(0, 0x48, 0x00, dev); /* Disables all IRQ's. */
ali1533_write(0, 0x44, 0x00, dev);
ali1533_write(0, 0x4d, 0x00, dev);
ali1533_write(0, 0x53, 0x00, dev);
@@ -1520,6 +1574,8 @@ ali1543_reset(void *priv)
ali1533_write(0, 0x74, 0x00, dev);
ali1533_write(0, 0x75, 0x00, dev);
ali1533_write(0, 0x76, 0x00, dev);
if (dev->type == 1)
ali1533_write(0, 0x78, 0x00, dev);
unmask_a20_in_smm = 1;
}
@@ -1576,7 +1632,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

@@ -28,6 +28,7 @@
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/plat_unused.h>
#include <86box/smram.h>
#include <86box/spd.h>
@@ -94,7 +95,8 @@ ali1621_log(const char *fmt, ...)
static void
ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
{
uint16_t access_smm = 0x0000, access_normal = 0x0000;
uint16_t access_smm = 0x0000;
uint16_t access_normal = 0x0000;
smram_disable_all();
@@ -110,6 +112,8 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
case 0x30: /* Protect. */
access_smm |= ACCESS_SMRAM_R;
break;
default:
break;
}
}
@@ -121,6 +125,8 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
case 0x30: /* Protect. */
access_smm |= ACCESS_SMRAM_W;
break;
default:
break;
}
smram_enable(dev->smram[0], 0xa0000, 0xa0000, 0x20000, ((val & 0x30) == 0x10), (val & 0x30));
@@ -136,15 +142,18 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
}
static void
ali1621_shadow_recalc(int cur_reg, ali1621_t *dev)
ali1621_shadow_recalc(UNUSED(int cur_reg), ali1621_t *dev)
{
int i, r_bit, w_bit, reg;
uint32_t base, flags = 0;
int r_bit;
int w_bit;
int reg;
uint32_t base;
uint32_t flags = 0;
shadowbios = shadowbios_write = 0;
/* C0000-EFFFF */
for (i = 0; i < 12; i++) {
for (uint8_t i = 0; i < 12; i++) {
base = 0x000c0000 + (i << 14);
r_bit = (i << 1) + 4;
reg = 0x84;
@@ -199,11 +208,12 @@ ali1621_shadow_recalc(int cur_reg, ali1621_t *dev)
static void
ali1621_mask_bar(ali1621_t *dev)
{
uint32_t bar, mask;
uint32_t bar;
uint32_t mask;
switch (dev->pci_conf[0xbc] & 0x0f) {
case 0x00:
default:
case 0x00:
mask = 0x00000000;
break;
case 0x01:
@@ -241,7 +251,7 @@ ali1621_mask_bar(ali1621_t *dev)
}
static void
ali1621_write(int func, int addr, uint8_t val, void *priv)
ali1621_write(UNUSED(int func), int addr, uint8_t val, void *priv)
{
ali1621_t *dev = (ali1621_t *) priv;
@@ -560,11 +570,14 @@ ali1621_write(int func, int addr, uint8_t val, void *priv)
case 0xf0 ... 0xff:
dev->pci_conf[addr] = val;
break;
default:
break;
}
}
static uint8_t
ali1621_read(int func, int addr, void *priv)
ali1621_read(UNUSED(int func), int addr, void *priv)
{
ali1621_t *dev = (ali1621_t *) priv;
uint8_t ret = 0xff;
@@ -578,7 +591,6 @@ static void
ali1621_reset(void *priv)
{
ali1621_t *dev = (ali1621_t *) priv;
int i;
/* Default Registers */
dev->pci_conf[0x00] = 0xb9;
@@ -633,7 +645,7 @@ ali1621_reset(void *priv)
ali1621_write(0, 0x83, 0x08, dev);
for (i = 0; i < 4; i++)
for (uint8_t i = 0; i < 4; i++)
ali1621_write(0, 0x84 + i, 0x00, dev);
}
@@ -649,7 +661,7 @@ ali1621_close(void *priv)
}
static void *
ali1621_init(const device_t *info)
ali1621_init(UNUSED(const device_t *info))
{
ali1621_t *dev = (ali1621_t *) malloc(sizeof(ali1621_t));
memset(dev, 0, sizeof(ali1621_t));

View File

@@ -30,7 +30,6 @@
#include <86box/pit.h>
#include <86box/device.h>
#include <86box/port_92.h>
#include <86box/usb.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/chipset.h>
@@ -39,45 +38,48 @@ typedef struct ali6117_t {
uint32_t local;
/* Main registers (port 22h/23h) */
uint8_t unlocked, mode;
uint8_t unlocked;
uint8_t mode;
uint8_t reg_offset;
uint8_t regs[256];
} ali6117_t;
/* Total size, Bank 0 size, Bank 1 size, Bank 2 size, Bank 3 size. */
static uint32_t ali6117_modes[32][5] = {
{ 1024, 512, 512, 0, 0 },
{ 2048, 512, 512, 512, 512 },
{ 3072, 512, 512, 2048, 0 },
{ 5120, 512, 512, 2048, 2048 },
{ 9216, 512, 512, 8192, 0 },
{ 1024, 1024, 0, 0, 0 },
{ 2048, 1024, 1024, 0, 0 },
{ 4096, 1024, 1024, 2048, 0 },
{ 6144, 1024, 1024, 2048, 2048 },
{ 10240, 1024, 1024, 8192, 0 },
{ 18432, 1024, 1024, 8192, 8192 },
{ 3072, 1024, 2048, 0, 0 },
{ 5120, 1024, 2048, 2048, 0 },
{ 9216, 1024, 8192, 0, 0 },
{ 2048, 2048, 0, 0, 0 },
{ 4096, 2048, 2048, 0, 0 },
{ 6144, 2048, 2048, 2048, 0 },
{ 8192, 2048, 2048, 2048, 2048 },
{ 12288, 2048, 2048, 8192, 0 },
{ 20480, 2048, 2048, 8192, 8192 },
{ 10240, 2048, 8192, 0, 0 },
{ 18432, 2048, 8192, 8192, 0 },
{ 26624, 2048, 8192, 8192, 8192 },
{ 4096, 4096, 0, 0, 0 },
{ 8192, 4096, 4096, 0, 0 },
{ 24576, 4096, 4096, 8192, 8192 },
{ 12288, 4096, 8192, 0, 0 },
{ 8192, 8192, 0, 0, 0 },
{ 16384, 8192, 8192, 0, 0 },
{ 24576, 8192, 8192, 8192, 0 },
{ 32768, 8192, 8192, 8192, 8192 },
{ 65536, 32768, 32768, 0, 0 }
// clang-format off
{ 1024, 512, 512, 0, 0 },
{ 2048, 512, 512, 512, 512 },
{ 3072, 512, 512, 2048, 0 },
{ 5120, 512, 512, 2048, 2048 },
{ 9216, 512, 512, 8192, 0 },
{ 1024, 1024, 0, 0, 0 },
{ 2048, 1024, 1024, 0, 0 },
{ 4096, 1024, 1024, 2048, 0 },
{ 6144, 1024, 1024, 2048, 2048 },
{ 10240, 1024, 1024, 8192, 0 },
{ 18432, 1024, 1024, 8192, 8192 },
{ 3072, 1024, 2048, 0, 0 },
{ 5120, 1024, 2048, 2048, 0 },
{ 9216, 1024, 8192, 0, 0 },
{ 2048, 2048, 0, 0, 0 },
{ 4096, 2048, 2048, 0, 0 },
{ 6144, 2048, 2048, 2048, 0 },
{ 8192, 2048, 2048, 2048, 2048 },
{ 12288, 2048, 2048, 8192, 0 },
{ 20480, 2048, 2048, 8192, 8192 },
{ 10240, 2048, 8192, 0, 0 },
{ 18432, 2048, 8192, 8192, 0 },
{ 26624, 2048, 8192, 8192, 8192 },
{ 4096, 4096, 0, 0, 0 },
{ 8192, 4096, 4096, 0, 0 },
{ 24576, 4096, 4096, 8192, 8192 },
{ 12288, 4096, 8192, 0, 0 },
{ 8192, 8192, 0, 0, 0 },
{ 16384, 8192, 8192, 0, 0 },
{ 24576, 8192, 8192, 8192, 0 },
{ 32768, 8192, 8192, 8192, 8192 },
{ 65536, 32768, 32768, 0, 0 }
// clang-format on
};
#ifdef ENABLE_ALI6117_LOG
@@ -101,8 +103,8 @@ ali6117_log(const char *fmt, ...)
static void
ali6117_recalcmapping(ali6117_t *dev)
{
uint8_t reg, bitpair;
uint32_t base, size;
uint32_t base;
uint32_t size;
int state;
shadowbios = 0;
@@ -111,8 +113,8 @@ ali6117_recalcmapping(ali6117_t *dev)
ali6117_log("ALI6117: Shadowing for A0000-BFFFF (reg 12 bit 1) = %s\n", (dev->regs[0x12] & 0x02) ? "on" : "off");
mem_set_mem_state(0xa0000, 0x20000, (dev->regs[0x12] & 0x02) ? (MEM_WRITE_INTERNAL | MEM_READ_INTERNAL) : (MEM_WRITE_EXTANY | MEM_READ_EXTANY));
for (reg = 0; reg <= 1; reg++) {
for (bitpair = 0; bitpair <= 3; bitpair++) {
for (uint8_t reg = 0; reg <= 1; reg++) {
for (uint8_t bitpair = 0; bitpair <= 3; bitpair++) {
size = 0x8000;
base = 0xc0000 + (size * ((reg * 4) + bitpair));
ali6117_log("ALI6117: Shadowing for %05X-%05X (reg %02X bp %d wmask %02X rmask %02X) =", base, base + size - 1, 0x14 + reg, bitpair, 1 << ((bitpair * 2) + 1), 1 << (bitpair * 2));
@@ -147,10 +149,10 @@ ali6117_recalcmapping(ali6117_t *dev)
static void
ali6117_bank_recalc(ali6117_t *dev)
{
int i;
uint32_t bank, addr;
uint32_t bank;
uint32_t addr;
for (i = 0x00000000; i < (mem_size << 10); i += 4096) {
for (uint32_t i = 0x00000000; i < (mem_size << 10); i += 4096) {
if ((i >= 0x000a0000) && (i < 0x00100000))
continue;
@@ -276,6 +278,9 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv)
case 0x7:
cpu_set_isa_speed(cpu_busspeed / 6);
break;
default:
break;
}
break;
@@ -371,6 +376,9 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv)
case 0x71:
val &= 0x1f;
break;
default:
break;
}
dev->regs[dev->reg_offset] = val;
@@ -453,7 +461,7 @@ ali6117_close(void *priv)
static void *
ali6117_init(const device_t *info)
{
int i, last_match = 0;
int last_match = 0;
ali6117_log("ALI6117: init()\n");
@@ -466,7 +474,7 @@ ali6117_init(const device_t *info)
ali6117_setup(dev);
for (i = 31; i >= 0; i--) {
for (int8_t i = 31; i >= 0; i--) {
if ((mem_size >= ali6117_modes[i][0]) && (ali6117_modes[i][0] > last_match)) {
last_match = ali6117_modes[i][0];
dev->mode = i;

View File

@@ -48,16 +48,17 @@ contaq_82c59x_log(const char *fmt, ...)
# define contaq_82c59x_log(fmt, ...)
#endif
typedef struct
{
uint32_t phys, virt;
typedef struct mem_remapping_t {
uint32_t phys;
uint32_t virt;
} mem_remapping_t;
typedef struct
{
uint8_t index, green,
smi_status_set,
regs[256], smi_status[2];
typedef struct contaq_82c59x_t {
uint8_t index;
uint8_t green;
uint8_t smi_status_set;
uint8_t regs[256];
uint8_t smi_status[2];
smram_t *smram[2];
} contaq_82c59x_t;
@@ -82,6 +83,8 @@ contaq_82c59x_isa_speed_recalc(contaq_82c59x_t *dev)
case 0x03:
cpu_set_isa_speed(cpu_busspeed / 5);
break;
default:
break;
}
}
}
@@ -89,7 +92,8 @@ contaq_82c59x_isa_speed_recalc(contaq_82c59x_t *dev)
static void
contaq_82c59x_shadow_recalc(contaq_82c59x_t *dev)
{
uint32_t i, base;
uint32_t i;
uint32_t base;
uint8_t bit;
shadowbios = shadowbios_write = 0;
@@ -273,8 +277,14 @@ contaq_82c59x_write(uint16_t addr, uint8_t val, void *priv)
case 0x7c:
dev->regs[dev->index] = val;
break;
default:
break;
}
break;
default:
break;
}
}

View File

@@ -27,13 +27,13 @@
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t index,
regs[256];
typedef struct cs4031_t {
uint8_t index;
uint8_t regs[256];
port_92_t *port_92;
} cs4031_t;
@@ -134,8 +134,14 @@ cs4031_write(uint16_t addr, uint8_t val, void *priv)
dev->regs[dev->index] = val & 0xb3;
port_92_set_features(dev->port_92, val & 0x10, val & 0x20);
break;
default:
break;
}
break;
default:
break;
}
}
@@ -156,7 +162,7 @@ cs4031_close(void *priv)
}
static void *
cs4031_init(const device_t *info)
cs4031_init(UNUSED(const device_t *info))
{
cs4031_t *dev = (cs4031_t *) malloc(sizeof(cs4031_t));
memset(dev, 0, sizeof(cs4031_t));

View File

@@ -25,12 +25,12 @@
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/chipset.h>
typedef struct
{
typedef struct cs8230_t {
int idx;
uint8_t regs[256];
} cs8230_t;
@@ -51,6 +51,8 @@ shadow_control(uint32_t addr, uint32_t size, int state)
case 0x11:
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
break;
default:
break;
}
flushmmucache_nopc();
@@ -59,9 +61,7 @@ shadow_control(uint32_t addr, uint32_t size, int state)
static void
rethink_shadow_mappings(cs8230_t *cs8230)
{
int c;
for (c = 0; c < 32; c++) {
for (uint8_t c = 0; c < 32; c++) {
/* Addresses 40000-bffff in 16k blocks */
if (cs8230->regs[0xa + (c >> 3)] & (1 << (c & 7)))
mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /* I/O channel */
@@ -69,7 +69,7 @@ rethink_shadow_mappings(cs8230_t *cs8230)
mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); /* System board */
}
for (c = 0; c < 16; c++) {
for (uint8_t c = 0; c < 16; c++) {
/* Addresses c0000-fffff in 16k blocks. System board ROM can be mapped here */
if (cs8230->regs[0xe + (c >> 3)] & (1 << (c & 7)))
mem_set_mem_state(0xc0000 + (c << 14), 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); /* I/O channel */
@@ -79,9 +79,9 @@ rethink_shadow_mappings(cs8230_t *cs8230)
}
static uint8_t
cs8230_read(uint16_t port, void *p)
cs8230_read(uint16_t port, void *priv)
{
cs8230_t *cs8230 = (cs8230_t *) p;
cs8230_t *cs8230 = (cs8230_t *) priv;
uint8_t ret = 0xff;
if (port & 1) {
@@ -112,6 +112,9 @@ cs8230_read(uint16_t port, void *p)
case 0x2a:
ret = cs8230->regs[cs8230->idx];
break;
default:
break;
}
}
@@ -119,9 +122,9 @@ cs8230_read(uint16_t port, void *p)
}
static void
cs8230_write(uint16_t port, uint8_t val, void *p)
cs8230_write(uint16_t port, uint8_t val, void *priv)
{
cs8230_t *cs8230 = (cs8230_t *) p;
cs8230_t *cs8230 = (cs8230_t *) priv;
if (!(port & 1))
cs8230->idx = val;
@@ -137,6 +140,8 @@ cs8230_write(uint16_t port, uint8_t val, void *p)
case 0x0f: /* Address maps */
rethink_shadow_mappings(cs8230);
break;
default:
break;
}
}
}
@@ -149,9 +154,8 @@ cs8230_close(void *priv)
free(cs8230);
}
static void
*
cs8230_init(const device_t *info)
static void *
cs8230_init(UNUSED(const device_t *info))
{
cs8230_t *cs8230 = (cs8230_t *) malloc(sizeof(cs8230_t));
memset(cs8230, 0, sizeof(cs8230_t));

View File

@@ -28,14 +28,15 @@
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/pit.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
#define INDEX (dev->index - 0x10)
typedef struct
{
uint8_t index, regs[6];
typedef struct et6000_t {
uint8_t index;
uint8_t regs[256];
} et6000_t;
#ifdef ENABLE_ET6000_LOG
@@ -105,9 +106,15 @@ et6000_write(uint16_t addr, uint8_t val, void *priv)
et6000_shadow_control(0xe0000, 0x10000, val & 0x20, (val & 0x20) && (val & 0x10));
et6000_shadow_control(0xf0000, 0x10000, val & 0x40, !(val & 0x40));
break;
default:
break;
}
et6000_log("ET6000: dev->regs[%02x] = %02x\n", dev->index, dev->regs[dev->index]);
break;
default:
break;
}
}
@@ -128,7 +135,7 @@ et6000_close(void *priv)
}
static void *
et6000_init(const device_t *info)
et6000_init(UNUSED(const device_t *info))
{
et6000_t *dev = (et6000_t *) malloc(sizeof(et6000_t));
memset(dev, 0, sizeof(et6000_t));

View File

@@ -44,8 +44,7 @@
#include <86box/io.h>
#include <86box/video.h>
typedef struct
{
typedef struct gc100_t {
uint8_t reg[0x10];
} gc100_t;
@@ -70,9 +69,9 @@ gc100_log(const char *fmt, ...)
static uint8_t
get_fdd_switch_settings(void)
{
int i, fdd_count = 0;
uint8_t fdd_count = 0;
for (i = 0; i < FDD_NUM; i++) {
for (uint8_t i = 0; i < FDD_NUM; i++) {
if (fdd_get_flags(i))
fdd_count++;
}
@@ -135,6 +134,9 @@ gc100_write(uint16_t port, uint8_t val, void *priv)
/* addr 0x6 */
/* addr 0x7 */
default:
break;
}
gc100_log("GC100: Write %02x at %02x\n", val, port);
@@ -187,6 +189,9 @@ gc100_read(uint16_t port, void *priv)
/* addr 0x6 */
/* addr 0x7 */
default:
break;
}
return ret;

View File

@@ -34,6 +34,7 @@
#include <86box/device.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
@@ -52,8 +53,9 @@ enum {
#define HEADLAND_HAS_CRI 0x10
#define HEADLAND_HAS_SLEEP 0x20
typedef struct {
uint8_t valid, enabled;
typedef struct headland_mr_t {
uint8_t valid;
uint8_t enabled;
uint16_t mr;
uint32_t virt_base;
@@ -62,7 +64,8 @@ typedef struct {
typedef struct headland_t {
uint8_t revision;
uint8_t has_cri, has_sleep;
uint8_t has_cri;
uint8_t has_sleep;
uint8_t cri;
uint8_t cr[7];
@@ -72,8 +75,8 @@ typedef struct headland_t {
uint8_t ems_mar;
headland_mr_t null_mr,
ems_mr[64];
headland_mr_t null_mr;
headland_mr_t ems_mr[64];
mem_mapping_t low_mapping;
mem_mapping_t ems_mapping[64];
@@ -105,7 +108,11 @@ static const int mem_conf_cr1[41] = {
static uint32_t
get_addr(headland_t *dev, uint32_t addr, headland_mr_t *mr)
{
uint32_t bank_base[4], bank_shift[4], shift, other_shift, bank;
uint32_t bank_base[4];
uint32_t bank_shift[4];
uint32_t shift;
uint32_t other_shift;
uint32_t bank;
if ((addr >= 0x0e0000) && (addr <= 0x0fffff))
return addr;
@@ -173,7 +180,8 @@ hl_ems_disable(headland_t *dev, uint8_t mar, uint32_t base_addr, uint8_t indx)
static void
hl_ems_update(headland_t *dev, uint8_t mar)
{
uint32_t base_addr, virt_addr;
uint32_t base_addr;
uint32_t virt_addr;
uint8_t indx = mar & 0x1f;
base_addr = (indx + 16) << 14;
@@ -200,11 +208,9 @@ hl_ems_update(headland_t *dev, uint8_t mar)
}
static void
set_global_EMS_state(headland_t *dev, int state)
set_global_EMS_state(headland_t *dev, UNUSED(int state))
{
int i;
for (i = 0; i < 32; i++) {
for (uint8_t i = 0; i < 32; i++) {
hl_ems_update(dev, i | (((dev->cr[0] & 0x01) << 5) ^ 0x20));
hl_ems_update(dev, i | ((dev->cr[0] & 0x01) << 5));
}
@@ -229,7 +235,6 @@ static void
memmap_state_update(headland_t *dev)
{
uint32_t addr;
int i;
uint8_t ht_cr0 = dev->cr[0];
uint8_t ht_romcs = !(dev->cr[4] & 0x01);
if (dev->revision <= 1)
@@ -237,7 +242,7 @@ memmap_state_update(headland_t *dev)
if (!(dev->cr[0] & 0x04))
ht_cr0 &= ~0x18;
for (i = 0; i < 24; i++) {
for (uint8_t i = 0; i < 24; i++) {
addr = get_addr(dev, 0x40000 + (i << 14), NULL);
mem_mapping_set_exec(&dev->upper_mapping[i], addr < ((uint32_t) mem_size << 10) ? ram + addr : NULL);
}
@@ -588,7 +593,6 @@ headland_init(const device_t *info)
{
headland_t *dev;
int ht386 = 0;
uint32_t i;
dev = (headland_t *) malloc(sizeof(headland_t));
memset(dev, 0x00, sizeof(headland_t));
@@ -613,7 +617,7 @@ headland_init(const device_t *info)
dev->null_mr.mr = 0xff;
dev->null_mr.headland = dev;
for (i = 0; i < 64; i++) {
for (uint8_t i = 0; i < 64; i++) {
dev->ems_mr[i].valid = 1;
dev->ems_mr[i].mr = 0x00;
dev->ems_mr[i].headland = dev;
@@ -645,7 +649,7 @@ headland_init(const device_t *info)
mem_mapping_enable(&dev->high_mapping);
}
for (i = 0; i < 24; i++) {
for (uint8_t i = 0; i < 24; i++) {
mem_mapping_add(&dev->upper_mapping[i],
0x40000 + (i << 14), 0x4000,
mem_read_b, mem_read_w, mem_read_l,
@@ -671,7 +675,7 @@ headland_init(const device_t *info)
MEM_MAPPING_INTERNAL, &dev->null_mr);
mem_mapping_disable(&dev->shadow_mapping[1]);
for (i = 0; i < 64; i++) {
for (uint8_t i = 0; i < 64; i++) {
dev->ems_mr[i].mr = 0x00;
mem_mapping_add(&dev->ems_mapping[i],
((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14, 0x04000,
@@ -684,7 +688,7 @@ headland_init(const device_t *info)
memmap_state_update(dev);
return (dev);
return dev;
}
const device_t headland_gc10x_device = {

View File

@@ -30,6 +30,8 @@
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
@@ -117,10 +119,11 @@
Bit 0: HADS# Delay After LB. Cycle (1: Enabled / 0: Disable)
*/
typedef struct
{
uint8_t idx, access_data,
regs[256], pci_conf[256];
typedef struct ims8848_t {
uint8_t idx;
uint8_t access_data;
uint8_t regs[256];
uint8_t pci_conf[256];
smram_t *smram;
} ims8848_t;
@@ -147,7 +150,7 @@ ims8848_log(const char *fmt, ...)
static void
ims8848_recalc(ims8848_t *dev)
{
int i, state_on;
int state_on;
uint32_t base;
ims8848_log("SHADOW: 00 = %02X, 08 = %02X, 1B = %02X, 1C = %02X\n",
dev->regs[0x00], dev->regs[0x08], dev->regs[0x1b], dev->regs[0x1c]);
@@ -155,7 +158,7 @@ ims8848_recalc(ims8848_t *dev)
state_on = MEM_READ_INTERNAL;
state_on |= (dev->regs[0x08] & 0x04) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
for (i = 0; i < 2; i++) {
for (uint8_t i = 0; i < 2; i++) {
base = 0xe0000 + (i << 16);
if (dev->regs[0x00] & (1 << (i + 2)))
mem_set_mem_state_both(base, 0x10000, state_on);
@@ -163,7 +166,7 @@ ims8848_recalc(ims8848_t *dev)
mem_set_mem_state_both(base, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
}
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
base = 0xc0000 + (i << 14);
if (dev->regs[0x1c] & (1 << i))
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
@@ -242,10 +245,16 @@ ims8848_write(uint16_t addr, uint8_t val, void *priv)
/* Base Memory */
ims8848_base_memory(dev);
break;
default:
break;
}
dev->access_data = 0;
}
break;
default:
break;
}
}
@@ -274,6 +283,8 @@ ims8848_read(uint16_t addr, void *priv)
}
ims8848_log("[R] [%i] REG %02X = %02X\n", old_ad, dev->idx, ret);
break;
default:
break;
}
return ret;
@@ -307,6 +318,9 @@ ims8849_pci_write(int func, int addr, uint8_t val, void *priv)
case 0x52 ... 0x55:
dev->pci_conf[addr] = val;
break;
default:
break;
}
}
@@ -362,7 +376,7 @@ ims8848_close(void *priv)
}
static void *
ims8848_init(const device_t *info)
ims8848_init(UNUSED(const device_t *info))
{
ims8848_t *dev = (ims8848_t *) malloc(sizeof(ims8848_t));
memset(dev, 0, sizeof(ims8848_t));

View File

@@ -31,8 +31,10 @@
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/hdc_ide.h>
#include <86box/hdc.h>
@@ -44,19 +46,20 @@
#define MEM_STATE_SHADOW_W 0x02
#define MEM_STATE_SMRAM 0x04
typedef struct
{
uint8_t has_ide, smram_locked,
regs[256];
typedef struct i420ex_t {
uint8_t has_ide;
uint8_t smram_locked;
uint8_t regs[256];
uint16_t timer_base,
timer_latch;
uint16_t timer_base;
uint16_t timer_latch;
smram_t *smram;
double fast_off_period;
pc_timer_t timer, fast_off_timer;
pc_timer_t timer;
pc_timer_t fast_off_timer;
apm_t *apm;
port_92_t *port_92;
@@ -96,6 +99,8 @@ i420ex_map(uint32_t addr, uint32_t size, int state)
case 3:
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
default:
break;
}
flushmmucache_nopc();
}
@@ -112,13 +117,14 @@ i420ex_smram_handler_phase1(i420ex_t *dev)
{
uint8_t *regs = (uint8_t *) dev->regs;
uint32_t host_base = 0x000a0000, ram_base = 0x000a0000;
uint32_t size = 0x00010000;
uint32_t host_base = 0x000a0000;
uint32_t ram_base = 0x000a0000;
uint32_t size = 0x00010000;
switch (regs[0x70] & 0x07) {
default:
case 0:
case 1:
default:
host_base = ram_base = 0x00000000;
size = 0x00000000;
break;
@@ -193,6 +199,8 @@ i420ex_write(int func, int addr, uint8_t val, void *priv)
ide_set_side(0, 0x0376);
ide_pri_enable();
break;
default:
break;
}
}
break;
@@ -354,6 +362,8 @@ i420ex_write(int func, int addr, uint8_t val, void *priv)
cpu_fast_off_count = val + 1;
cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period);
break;
default:
break;
}
}
@@ -387,7 +397,7 @@ i420ex_reset_hard(void *priv)
dev->regs[0x4c] = 0x4d;
dev->regs[0x4e] = 0x03;
/* Bits 2:1 of register 50h are 00 is 25 MHz, and 01 if 33 MHz, 10 and 11 are reserved. */
/* Bits 2:1 of register 50h are 00 is 25 MHz, and 01 if 33 MHz, 10 and 11 are reserved. */
if (cpu_busspeed >= 33333333)
dev->regs[0x50] |= 0x02;
dev->regs[0x51] = 0x80;
@@ -409,9 +419,9 @@ i420ex_reset_hard(void *priv)
}
static void
i420ex_apm_out(uint16_t port, uint8_t val, void *p)
i420ex_apm_out(UNUSED(uint16_t port), UNUSED(uint8_t val), void *priv)
{
i420ex_t *dev = (i420ex_t *) p;
i420ex_t *dev = (i420ex_t *) priv;
if (dev->apm->do_smi)
dev->regs[0xaa] |= 0x80;
@@ -429,39 +439,41 @@ i420ex_fast_off_count(void *priv)
}
static void
i420ex_reset(void *p)
i420ex_reset(void *priv)
{
i420ex_t *dev = (i420ex_t *) p;
int i;
i420ex_t *dev = (i420ex_t *) priv;
i420ex_write(0, 0x48, 0x00, p);
i420ex_write(0, 0x48, 0x00, priv);
for (i = 0; i < 7; i++)
i420ex_write(0, 0x59 + i, 0x00, p);
/* Disable the PIC mouse latch. */
i420ex_write(0, 0x4e, 0x03, priv);
for (i = 0; i <= 4; i++)
i420ex_write(0, 0x60 + i, 0x01, p);
for (uint8_t i = 0; i < 7; i++)
i420ex_write(0, 0x59 + i, 0x00, priv);
for (uint8_t i = 0; i <= 4; i++)
i420ex_write(0, 0x60 + i, 0x01, priv);
dev->regs[0x70] &= 0xef; /* Forcibly unlock the SMRAM register. */
dev->smram_locked = 0;
i420ex_write(0, 0x70, 0x00, p);
i420ex_write(0, 0x70, 0x00, priv);
mem_set_mem_state(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
mem_set_mem_state_smm(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
i420ex_write(0, 0xa0, 0x08, p);
i420ex_write(0, 0xa2, 0x00, p);
i420ex_write(0, 0xa4, 0x00, p);
i420ex_write(0, 0xa5, 0x00, p);
i420ex_write(0, 0xa6, 0x00, p);
i420ex_write(0, 0xa7, 0x00, p);
i420ex_write(0, 0xa8, 0x0f, p);
i420ex_write(0, 0xa0, 0x08, priv);
i420ex_write(0, 0xa2, 0x00, priv);
i420ex_write(0, 0xa4, 0x00, priv);
i420ex_write(0, 0xa5, 0x00, priv);
i420ex_write(0, 0xa6, 0x00, priv);
i420ex_write(0, 0xa7, 0x00, priv);
i420ex_write(0, 0xa8, 0x0f, priv);
}
static void
i420ex_close(void *p)
i420ex_close(void *priv)
{
i420ex_t *dev = (i420ex_t *) p;
i420ex_t *dev = (i420ex_t *) priv;
smram_del(dev->smram);

View File

@@ -28,6 +28,7 @@
#include <86box/io.h>
#include <86box/device.h>
#include <86box/pci.h>
#include <86box/plat_unused.h>
#include <86box/chipset.h>
#include <86box/spd.h>
#include <86box/machine.h>
@@ -50,17 +51,20 @@ enum {
INTEL_440ZX
};
typedef struct
{
uint8_t pm2_cntrl,
smram_locked, max_drb,
drb_unit, drb_default;
uint8_t regs[256], regs_locked[256];
typedef struct i4x0_t {
uint8_t pm2_cntrl;
uint8_t smram_locked;
uint8_t max_drb;
uint8_t drb_unit;
uint8_t drb_default;
uint8_t regs[256];
uint8_t regs_locked[256];
uint8_t mem_state[256];
int type;
smram_t *smram_low, *smram_high;
smram_t *smram_low;
smram_t *smram_high;
agpgart_t *agpgart;
void (*write_drbs)(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit);
void (*write_drbs)(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit);
} i4x0_t;
#ifdef ENABLE_I4X0_LOG
@@ -119,7 +123,8 @@ i4x0_smram_handler_phase1(i4x0_t *dev)
uint8_t *reg = (dev->type >= INTEL_430LX) ? &(regs[0x72]) : &(regs[0x57]);
uint8_t *ext_reg = (dev->type >= INTEL_440BX) ? &(regs[0x73]) : &(regs[0x71]);
uint32_t s, base[2] = { 0x000a0000, 0x00000000 };
uint32_t s;
uint32_t base[2] = { 0x000a0000, 0x00000000 };
uint32_t size[2] = { 0x00010000, 0x00000000 };
if ((dev->type <= INTEL_420ZX) || (dev->type >= INTEL_430FX)) {
@@ -164,8 +169,8 @@ i4x0_smram_handler_phase1(i4x0_t *dev)
} else {
size[0] = 0x00010000;
switch (*reg & 0x03) {
case 0:
default:
case 0:
base[0] = (mem_size << 10) - size[0];
s = 1;
break;
@@ -221,17 +226,17 @@ i4x0_mask_bar(uint8_t *regs, void *agpgart)
}
static uint8_t
pm2_cntrl_read(uint16_t addr, void *p)
pm2_cntrl_read(UNUSED(uint16_t addr), void *priv)
{
i4x0_t *dev = (i4x0_t *) p;
i4x0_t *dev = (i4x0_t *) priv;
return dev->pm2_cntrl & 0x01;
}
static void
pm2_cntrl_write(uint16_t addr, uint8_t val, void *p)
pm2_cntrl_write(UNUSED(uint16_t addr), uint8_t val, void *priv)
{
i4x0_t *dev = (i4x0_t *) p;
i4x0_t *dev = (i4x0_t *) priv;
dev->pm2_cntrl = val & 0x01;
}
@@ -242,7 +247,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
i4x0_t *dev = (i4x0_t *) priv;
uint8_t *regs = (uint8_t *) dev->regs;
uint8_t *regs_l = (uint8_t *) dev->regs_locked;
int i;
if (func > 0)
return;
@@ -251,6 +255,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
switch (addr) {
case 0x04: /*Command register*/
switch (dev->type) {
default:
case INTEL_420TX:
case INTEL_420ZX:
case INTEL_430LX:
@@ -258,7 +263,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440BX:
case INTEL_440GX:
case INTEL_440ZX:
default:
regs[0x04] = (regs[0x04] & ~0x42) | (val & 0x42);
break;
case INTEL_430FX:
@@ -291,16 +295,18 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440EX:
regs[0x05] = val & 0x01;
break;
default:
break;
}
break;
case 0x07:
switch (dev->type) {
default:
case INTEL_420TX:
case INTEL_420ZX:
case INTEL_430LX:
case INTEL_430NX:
case INTEL_430HX:
default:
regs[0x07] &= ~(val & 0x70);
break;
case INTEL_430FX:
@@ -343,6 +349,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430TX:
regs[0x0f] = (val & 0x40);
break;
default:
break;
}
break;
case 0x12:
@@ -355,6 +363,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0x12] = (val & 0xc0);
i4x0_mask_bar(regs, dev->agpgart);
break;
default:
break;
}
break;
case 0x13:
@@ -367,6 +377,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0x13] = val;
i4x0_mask_bar(regs, dev->agpgart);
break;
default:
break;
}
break;
case 0x2c:
@@ -382,6 +394,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs_l[addr] = 1;
}
break;
default:
break;
}
break;
@@ -396,14 +410,16 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430TX:
regs[0x4f] = (val & 0x80);
break;
default:
break;
}
break;
case 0x50:
switch (dev->type) {
default:
case INTEL_420TX:
case INTEL_420ZX:
case INTEL_430LX:
default:
regs[0x50] = (val & 0xe5);
break;
case INTEL_430NX:
@@ -467,17 +483,19 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0x51] = (regs[0x51] & 0xb0) | (val & 0x4f);
i4x0_mask_bar(regs, dev->agpgart);
break;
default:
break;
}
break;
case 0x52: /* Cache Control Register */
switch (dev->type) {
default:
case INTEL_420TX:
case INTEL_420ZX:
case INTEL_430LX:
case INTEL_430FX:
case INTEL_430VX:
case INTEL_430TX:
default:
regs[0x52] = (val & 0xfb);
break;
case INTEL_430NX:
@@ -515,6 +533,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
/* Not applicable to 440ZX as that does not support ECC. */
regs[0x53] = val;
break;
default:
break;
}
break;
case 0x54:
@@ -534,6 +554,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440FX:
regs[0x54] = val & 0x82;
break;
default:
break;
}
break;
case 0x55:
@@ -553,6 +575,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440EX:
regs[0x55] = val;
break;
default:
break;
}
break;
case 0x56:
@@ -577,6 +601,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440EX:
regs[0x56] = val;
break;
default:
break;
}
break;
case 0x57:
@@ -628,10 +654,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x58:
switch (dev->type) {
default:
case INTEL_420TX:
case INTEL_420ZX:
case INTEL_430LX:
default:
regs[0x58] = val & 0x01;
break;
case INTEL_430NX:
@@ -720,6 +746,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
}
switch (dev->type) {
default:
case INTEL_420TX:
case INTEL_420ZX:
case INTEL_430LX:
@@ -731,7 +758,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440BX:
case INTEL_440ZX:
case INTEL_440GX:
default:
regs[addr] = val;
break;
case INTEL_430FX:
@@ -768,6 +794,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430TX:
regs[addr] = val & 0x7f;
break;
default:
break;
}
break;
case 0x66:
@@ -786,6 +814,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440ZX:
regs[addr] = val;
break;
default:
break;
}
break;
case 0x67:
@@ -810,6 +840,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430TX:
regs[addr] = val & 0xb7;
break;
default:
break;
}
break;
case 0x68:
@@ -838,6 +870,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440ZX:
regs[0x68] = (regs[0x68] & 0x3f) | (val & 0xc0);
break;
default:
break;
}
break;
case 0x69:
@@ -856,6 +890,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440ZX:
regs[0x69] = val & 0x3f;
break;
default:
break;
}
break;
case 0x6a:
@@ -880,6 +916,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
else
regs[addr] = val & 0x33;
break;
default:
break;
}
break;
case 0x6c:
@@ -899,6 +937,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
else if (addr == 0x6d)
regs[addr] = val & 0xcf;
break;
default:
break;
}
break;
case 0x6f:
@@ -909,6 +949,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440EX:
regs[addr] = val & 0xcf;
break;
default:
break;
}
break;
case 0x70:
@@ -930,6 +972,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440EX:
regs[addr] = val & 0xf8;
break;
default:
break;
}
break;
case 0x71:
@@ -953,6 +997,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440LX:
regs[addr] = val & 0x1f;
break;
default:
break;
}
break;
case 0x72: /* SMRAM */
@@ -998,6 +1044,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
i4x0_smram_handler_phase1(dev);
}
break;
default:
break;
}
break;
case 0x74:
@@ -1008,6 +1056,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[0x74] = val;
break;
default:
break;
}
break;
case 0x75:
@@ -1018,6 +1068,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440ZX:
case INTEL_440GX:
regs[addr] = val;
default:
break;
}
break;
case 0x77:
@@ -1025,6 +1077,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440BX:
case INTEL_440ZX:
regs[0x77] = val & 0x03;
default:
break;
}
break;
case 0x78:
@@ -1039,6 +1093,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[0x78] = val & 0x1f;
break;
default:
break;
}
break;
case 0x79:
@@ -1054,6 +1110,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[0x79] = val;
break;
default:
break;
}
break;
case 0x7a:
@@ -1066,6 +1124,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
if (val & 0x40)
io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev);
break;
default:
break;
}
break;
case 0x7c:
@@ -1081,6 +1141,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440ZX:
regs[0x7c] = val & 0x1f;
break;
default:
break;
}
break;
case 0x7d:
@@ -1091,6 +1153,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430NX:
regs[0x7d] = val & 0x32;
break;
default:
break;
}
break;
case 0x7e:
@@ -1102,6 +1166,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430NX:
regs[addr] = val;
break;
default:
break;
}
break;
case 0x80:
@@ -1111,6 +1177,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[0x80] &= ~(val & 0x03);
break;
default:
break;
}
break;
case 0x90:
@@ -1132,6 +1200,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[0x90] = val;
break;
default:
break;
}
break;
case 0x91:
@@ -1144,6 +1214,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
/* Not applicable on 82443EX and 82443ZX. */
regs[0x91] &= ~(val & 0x11);
break;
default:
break;
}
break;
case 0x92:
@@ -1157,6 +1229,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[0x92] &= ~(val & 0x1f);
break;
default:
break;
}
break;
case 0x93:
@@ -1170,6 +1244,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0x93] = (val & 0x0e);
trc_write(0x0093, val & 0x06, NULL);
break;
default:
break;
}
break;
case 0xa7:
@@ -1178,6 +1254,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440EX:
regs[0xa7] = val & 0x1f;
break;
default:
break;
}
break;
case 0xa8:
@@ -1190,6 +1268,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[addr] = (val & 0x03);
break;
default:
break;
}
break;
case 0xb0:
@@ -1201,6 +1281,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[0xb0] = (val & 0x80);
break;
default:
break;
}
break;
case 0xb1:
@@ -1214,6 +1296,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[0xb1] = (val & 0xa0);
break;
default:
break;
}
break;
case 0xb4:
@@ -1226,6 +1310,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0xb4] = (val & 0x3f);
i4x0_mask_bar(regs, dev->agpgart);
break;
default:
break;
}
break;
case 0xb9:
@@ -1238,6 +1324,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0xb9] = (val & 0xf0);
i4x0_mask_bar(regs, dev->agpgart);
break;
default:
break;
}
break;
@@ -1252,6 +1340,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[addr] = val;
i4x0_mask_bar(regs, dev->agpgart);
break;
default:
break;
}
break;
@@ -1261,6 +1351,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440EX:
regs[addr] = (val & 0xf8);
break;
default:
break;
}
break;
@@ -1270,6 +1362,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440EX:
regs[addr] = (val & 0xf8);
break;
default:
break;
}
break;
@@ -1287,6 +1381,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[addr] = val;
break;
default:
break;
}
break;
case 0xca:
@@ -1298,6 +1394,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440ZX:
regs[addr] = val & 0xe7;
break;
default:
break;
}
break;
case 0xcb:
@@ -1309,6 +1407,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440ZX:
regs[addr] = val & 0xa7;
break;
default:
break;
}
break;
case 0xcc:
@@ -1320,6 +1420,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440ZX:
regs[0xcc] = (val & 0x58);
break;
default:
break;
}
break;
case 0xe0:
@@ -1339,6 +1441,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
if (!regs_l[addr])
regs[addr] = val;
break;
default:
break;
}
break;
case 0xe5:
@@ -1350,6 +1454,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
if (!regs_l[addr])
regs[addr] = (val & 0x3f);
break;
default:
break;
}
break;
case 0xe7:
@@ -1358,12 +1464,14 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440ZX:
case INTEL_440GX:
regs[0xe7] = 0x80;
for (i = 0; i < 16; i++)
for (uint8_t i = 0; i < 16; i++)
regs_l[0xe0 + i] = !!(val & 0x80);
if (!regs_l[0xe7]) {
regs[0xe7] |= (val & 0x7f);
}
break;
default:
break;
}
break;
case 0xf0:
@@ -1373,6 +1481,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[0xf0] = (val & 0xc0);
break;
default:
break;
}
break;
case 0xf1:
@@ -1382,8 +1492,13 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440GX:
regs[0xf1] = (val & 0x03);
break;
default:
break;
}
break;
default:
break;
}
}
@@ -1409,7 +1524,6 @@ static void
i4x0_reset(void *priv)
{
i4x0_t *dev = (i4x0_t *) priv;
int i;
if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX))
memset(dev->regs_locked, 0x00, 256 * sizeof(uint8_t));
@@ -1419,10 +1533,10 @@ i4x0_reset(void *priv)
else
i4x0_write(0, 0x59, 0x0f, priv);
for (i = 0; i < 6; i++)
for (uint8_t i = 0; i < 6; i++)
i4x0_write(0, 0x5a + i, 0x00, priv);
for (i = 0; i <= dev->max_drb; i++)
for (uint8_t i = 0; i <= dev->max_drb; i++)
i4x0_write(0, 0x60 + i, dev->drb_default, priv);
if (dev->type >= INTEL_430FX) {
@@ -1443,9 +1557,9 @@ i4x0_reset(void *priv)
}
static void
i4x0_close(void *p)
i4x0_close(void *priv)
{
i4x0_t *dev = (i4x0_t *) p;
i4x0_t *dev = (i4x0_t *) priv;
smram_del(dev->smram_high);
smram_del(dev->smram_low);
@@ -1453,9 +1567,8 @@ i4x0_close(void *p)
free(dev);
}
static void
*
i4x0_init(const device_t *info)
static void *
i4x0_init(const device_t *info)
{
i4x0_t *dev = (i4x0_t *) malloc(sizeof(i4x0_t));
uint8_t *regs;
@@ -1484,9 +1597,9 @@ static void
regs[0x0d] = 0x20;
/* According to information from FreeBSD 3.x source code:
0x00 = 486DX, 0x20 = 486SX, 0x40 = 486DX2 or 486DX4, 0x80 = Pentium OverDrive. */
if (!(hasfpu) && (cpu_multi == 1))
if (!hasfpu && (cpu_multi == 1))
regs[0x50] = 0x20;
else if (!(hasfpu) && (cpu_multi == 2))
else if (!hasfpu && (cpu_multi == 2))
regs[0x50] = 0x60; /* Guess based on the SX, DX, and DX2 values. */
else if (hasfpu && (cpu_multi == 1))
regs[0x50] = 0x00;
@@ -1746,6 +1859,8 @@ static void
dev->drb_unit = 8;
dev->drb_default = 0x01;
break;
default:
break;
}
regs[0x04] = 0x06;

View File

@@ -28,6 +28,7 @@
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/chipset.h>
#include <86box/plat_unused.h>
/* Shadow capabilities */
#define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
@@ -56,12 +57,10 @@
#define DEFINE_RC1_REMAP_SIZE ((dev->regs[0x24] & 0x02) ? 128 : 256)
#define DEFINE_RC2_REMAP_SIZE ((dev->regs[0x26] & 0x02) ? 128 : 256)
typedef struct
{
typedef struct intel_82335_t {
uint16_t regs[256];
uint16_t regs[256],
cfg_locked;
uint16_t cfg_locked;
} intel_82335_t;
@@ -86,8 +85,11 @@ intel_82335_log(const char *fmt, ...)
static void
intel_82335_write(uint16_t addr, uint16_t val, void *priv)
{
intel_82335_t *dev = (intel_82335_t *) priv;
uint32_t romsize = 0, base = 0, i = 0, rc1_remap = 0, rc2_remap = 0;
intel_82335_t *dev = (intel_82335_t *) priv;
uint32_t romsize = 0;
uint32_t base = 0;
uint32_t rc1_remap = 0;
uint32_t rc2_remap = 0;
dev->regs[addr] = val;
@@ -106,7 +108,9 @@ intel_82335_write(uint16_t addr, uint16_t val, void *priv)
shadowbios_write = !!(dev->regs[0x22] & 0x01);
/* Base System 512/640KB set */
// mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x22] & 0x08) ? ENABLE_TOP_128KB : DISABLE_TOP_128KB);
#if 0
mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x22] & 0x08) ? ENABLE_TOP_128KB : DISABLE_TOP_128KB);
#endif
/* Video RAM shadow*/
mem_set_mem_state_both(0xa0000, 0x20000, (dev->regs[0x22] & (0x04 << 8)) ? DETERMINE_VIDEO_RAM_WRITE_ACCESS : DISABLED_SHADOW);
@@ -128,14 +132,17 @@ intel_82335_write(uint16_t addr, uint16_t val, void *priv)
case 0x2e: /* Extended Granularity (Enabled if Bit 0 in Register 2Ch is set) */
if (EXTENDED_GRANULARITY_ENABLED) {
for (i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
base = 0xc0000 + (i << 15);
shadowbios = (dev->regs[0x2e] & (1 << (i + 8))) && (base == romsize);
shadowbios_write = (dev->regs[0x2e] & (1 << i)) && (base == romsize);
mem_set_mem_state_both(base, 0x8000, GRANULARITY_RECALC);
}
break;
}
break;
default:
break;
}
}
@@ -162,7 +169,7 @@ intel_82335_close(void *priv)
}
static void *
intel_82335_init(const device_t *info)
intel_82335_init(UNUSED(const device_t *info))
{
intel_82335_t *dev = (intel_82335_t *) malloc(sizeof(intel_82335_t));
memset(dev, 0, sizeof(intel_82335_t));

View File

@@ -35,6 +35,7 @@ i450GX is way more popular of an option but needs more stuff.
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/plat_unused.h>
#include <86box/smram.h>
#include <86box/spd.h>
#include <86box/chipset.h>
@@ -61,7 +62,8 @@ i450kx_log(const char *fmt, ...)
typedef struct i450kx_t {
smram_t *smram[2];
uint8_t pb_pci_conf[256], mc_pci_conf[256];
uint8_t pb_pci_conf[256];
uint8_t mc_pci_conf[256];
uint8_t mem_state[2][256];
uint8_t bus_index;
@@ -89,7 +91,8 @@ static void
i450kx_smram_recalc(i450kx_t *dev, int bus)
{
uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf;
uint32_t addr, size;
uint32_t addr;
uint32_t size;
smram_disable(dev->smram[bus]);
@@ -111,7 +114,9 @@ i450kx_vid_buf_recalc(i450kx_t *dev, int bus)
{
uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf;
#if 0
// int state = (regs[0x58] & 0x02) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_DISABLED | MEM_WRITE_DISABLED);
#endif
int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
if (bus)
@@ -166,8 +171,10 @@ pb_write(int func, int addr, uint8_t val, void *priv)
case 0x4a:
case 0x4b:
dev->pb_pci_conf[addr] = val;
// if (addr == 0x4a)
// pci_remap_bus(dev->bus_index, val);
#if 0
if (addr == 0x4a)
pci_remap_bus(dev->bus_index, val);
#endif
break;
case 0x4c:
@@ -365,6 +372,9 @@ pb_write(int func, int addr, uint8_t val, void *priv)
case 0xcb:
dev->pb_pci_conf[addr] = val;
break;
default:
break;
}
}
@@ -386,10 +396,8 @@ pb_read(int func, int addr, void *priv)
static void
mc_fill_drbs(i450kx_t *dev)
{
int i;
spd_write_drbs_interleaved(dev->mc_pci_conf, 0x60, 0x6f, 4);
for (i = 0x60; i <= 0x6f; i++) {
for (uint8_t i = 0x60; i <= 0x6f; i++) {
if (i & 0x01)
dev->mc_pci_conf[i] = 0x00;
else
@@ -591,6 +599,9 @@ mc_write(int func, int addr, uint8_t val, void *priv)
case 0xcb:
dev->mc_pci_conf[addr] = val;
break;
default:
break;
}
}
@@ -614,7 +625,9 @@ i450kx_reset(void *priv)
i450kx_t *dev = (i450kx_t *) priv;
uint32_t i;
#if 0
// pclog("i450KX: i450kx_reset()\n");
#endif
/* Defaults PB */
dev->pb_pci_conf[0x00] = 0x86;
@@ -672,8 +685,10 @@ i450kx_reset(void *priv)
dev->pb_pci_conf[0xa6] = 0xfe;
dev->pb_pci_conf[0xa7] = 0x00;
/* Note: Do NOT reset these two registers on programmed (TRC) hard reset! */
// dev->pb_pci_conf[0xb0] = 0x00;
// dev->pb_pci_conf[0xb1] = 0x00;
#if 0
dev->pb_pci_conf[0xb0] = 0x00;
dev->pb_pci_conf[0xb1] = 0x00;
#endif
dev->pb_pci_conf[0xb4] = 0x00;
dev->pb_pci_conf[0xb5] = 0x00;
dev->pb_pci_conf[0xb8] = 0x05;
@@ -694,7 +709,9 @@ i450kx_reset(void *priv)
dev->pb_pci_conf[0xca] = 0x00;
dev->pb_pci_conf[0xcb] = 0x00;
// pci_remap_bus(dev->bus_index, 0x00);
#if 0
pci_remap_bus(dev->bus_index, 0x00);
#endif
i450kx_smram_recalc(dev, 1);
i450kx_vid_buf_recalc(dev, 1);
pb_write(0, 0x59, 0x30, dev);
@@ -787,7 +804,7 @@ i450kx_close(void *priv)
}
static void *
i450kx_init(const device_t *info)
i450kx_init(UNUSED(const device_t *info))
{
i450kx_t *dev = (i450kx_t *) malloc(sizeof(i450kx_t));
memset(dev, 0, sizeof(i450kx_t));

View File

@@ -40,6 +40,7 @@
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/pit.h>
#include <86box/plat.h>
#include <86box/port_92.h>
#include <86box/scsi_device.h>
#include <86box/hdc.h>
@@ -50,7 +51,7 @@
#include <86box/smbus.h>
#include <86box/chipset.h>
typedef struct {
typedef struct piix_io_trap_t {
struct _piix_ *dev;
void *trap;
uint8_t dev_id;
@@ -58,14 +59,20 @@ typedef struct {
} piix_io_trap_t;
typedef struct _piix_ {
uint8_t cur_readout_reg, rev,
type, func_shift,
max_func, pci_slot,
no_mirq0, pad,
regs[4][256],
readout_regs[256], board_config[2];
uint16_t func0_id, nvr_io_base,
acpi_io_base;
uint8_t cur_readout_reg;
uint8_t rev;
uint8_t type;
uint8_t func_shift;
uint8_t max_func;
uint8_t pci_slot;
uint8_t no_mirq0;
uint8_t pad;
uint8_t regs[4][256];
uint8_t readout_regs[256];
uint8_t board_config[2];
uint16_t func0_id;
uint16_t nvr_io_base;
uint16_t acpi_io_base;
double fast_off_period;
sff8038i_t *bm[2];
smbus_piix4_t *smbus;
@@ -77,6 +84,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
@@ -100,7 +108,8 @@ piix_log(const char *fmt, ...)
static void
smsc_ide_irqs(piix_t *dev)
{
int irq_line = 3, irq_mode[2] = { 0, 0 };
int irq_line = 3;
uint8_t irq_mode[2] = { 0, 0 };
if (dev->regs[1][0x09] & 0x01)
irq_mode[0] = (dev->regs[0][0xe1] & 0x01) ? 3 : 1;
@@ -133,6 +142,8 @@ smsc_ide_irqs(piix_t *dev)
case 0x07:
irq_line = 15;
break;
default:
break;
}
sff_set_irq_line(dev->bm[0], irq_line);
@@ -147,7 +158,8 @@ smsc_ide_irqs(piix_t *dev)
static void
piix_ide_handlers(piix_t *dev, int bus)
{
uint16_t main, side;
uint16_t main;
uint16_t side;
if (bus & 0x01) {
ide_pri_disable();
@@ -200,7 +212,7 @@ piix_ide_bm_handlers(piix_t *dev)
}
static uint8_t
kbc_alias_reg_read(uint16_t addr, void *p)
kbc_alias_reg_read(UNUSED(uint16_t addr), UNUSED(void *priv))
{
uint8_t ret = inb(0x61);
@@ -208,7 +220,7 @@ kbc_alias_reg_read(uint16_t addr, void *p)
}
static void
kbc_alias_reg_write(uint16_t addr, uint8_t val, void *p)
kbc_alias_reg_write(UNUSED(uint16_t addr), uint8_t val, UNUSED(void *priv))
{
outb(0x61, val);
}
@@ -264,7 +276,7 @@ nvr_update_io_mapping(piix_t *dev)
}
static void
piix_trap_io(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
piix_trap_io(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), void *priv)
{
piix_io_trap_t *trap = (piix_io_trap_t *) priv;
@@ -316,7 +328,8 @@ static void
piix_trap_update(void *priv)
{
piix_t *dev = (piix_t *) priv;
uint8_t trap_id = 0, *fregs = dev->regs[3];
uint8_t trap_id = 0;
uint8_t *fregs = dev->regs[3];
uint16_t temp;
piix_trap_update_devctl(dev, trap_id++, 0, 0x00000002, 1, 0x1f0, 8);
@@ -458,7 +471,6 @@ piix_write(int func, int addr, uint8_t val, void *priv)
piix_t *dev = (piix_t *) priv;
uint8_t *fregs;
uint16_t base;
int i;
/* Return on unsupported function. */
if (dev->max_func > 0) {
@@ -512,7 +524,6 @@ piix_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x4e:
fregs[0x4e] = val;
keyboard_at_set_mouse_scan((val & 0x10) ? 1 : 0);
if (dev->type >= 4)
kbc_alias_update_io_mapping(dev);
break;
@@ -553,8 +564,8 @@ piix_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x6a:
switch (dev->type) {
case 1:
default:
case 1:
fregs[0x6a] = (fregs[0x6a] & 0xfb) | (val & 0x04);
fregs[0x0e] = (val & 0x04) ? 0x80 : 0x00;
piix_log("PIIX: Write %02X\n", val);
@@ -639,7 +650,7 @@ piix_write(int func, int addr, uint8_t val, void *priv)
base = fregs[addr | 0x01] << 8;
base |= fregs[addr & 0xfe];
for (i = 0; i < 4; i++)
for (uint8_t i = 0; i < 4; i++)
ddma_update_io_mapping(dev->ddma, (addr & 4) + i, fregs[addr & 0xfe] + (i << 4), fregs[addr | 0x01], (base != 0x0000));
}
break;
@@ -789,6 +800,8 @@ piix_write(int func, int addr, uint8_t val, void *priv)
}
}
break;
default:
break;
}
else if (func == 1)
switch (addr) { /* IDE */
@@ -1010,6 +1023,8 @@ piix_write(int func, int addr, uint8_t val, void *priv)
nvr_read_addr_set(!!(val & 0x10), dev->nvr);
}
break;
default:
break;
}
else if (func == 3)
switch (addr) { /* Power Management */
@@ -1143,14 +1158,17 @@ piix_write(int func, int addr, uint8_t val, void *priv)
fregs[0x91] = val;
smbus_update_io_mapping(dev);
break;
default:
break;
}
}
static uint8_t
piix_read(int func, int addr, void *priv)
{
piix_t *dev = (piix_t *) priv;
uint8_t ret = 0xff, *fregs;
piix_t *dev = (piix_t *) priv;
uint8_t ret = 0xff;
uint8_t *fregs;
if ((dev->type == 3) && (func == 2) && (dev->max_func == 1) && (addr >= 0x40))
ret = 0x00;
@@ -1159,9 +1177,7 @@ piix_read(int func, int addr, void *priv)
if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) {
fregs = (uint8_t *) dev->regs[func];
ret = fregs[addr];
if ((func == 0) && (addr == 0x4e))
ret |= keyboard_at_get_mouse_scan();
else if ((func == 2) && (addr == 0xff))
if ((func == 2) && (addr == 0xff))
ret |= 0xef;
piix_log("PIIX function %i read: %02X from %02X\n", func, ret, addr);
@@ -1204,7 +1220,6 @@ board_read(uint16_t port, void *priv)
static void
piix_reset_hard(piix_t *dev)
{
int i;
uint8_t *fregs;
uint16_t old_base = (dev->regs[1][0x20] & 0xf0) | (dev->regs[1][0x21] << 8);
@@ -1241,7 +1256,7 @@ piix_reset_hard(piix_t *dev)
}
/* Clear all 4 functions' arrays and set their vendor and device ID's. */
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
memset(dev->regs[i], 0, 256);
if (dev->type == 5) {
dev->regs[i][0x00] = 0x55;
@@ -1293,7 +1308,7 @@ piix_reset_hard(piix_t *dev)
fregs[0xa0] = (dev->type < 4) ? 0x08 : 0x00;
fregs[0xa8] = (dev->type < 4) ? 0x0f : 0x00;
if (dev->type > 3)
fregs[0xb0] = (is_pentium) ? 0x00 : 0x04;
fregs[0xb0] = is_pentium ? 0x00 : 0x04;
fregs[0xcb] = (dev->type > 3) ? 0x21 : 0x00;
if (dev->type > 4) {
fregs[0xd4] = 0x70;
@@ -1409,9 +1424,9 @@ piix_reset_hard(piix_t *dev)
}
static void
piix_apm_out(uint16_t port, uint8_t val, void *p)
piix_apm_out(UNUSED(uint16_t port), UNUSED(uint8_t val), void *priv)
{
piix_t *dev = (piix_t *) p;
piix_t *dev = (piix_t *) priv;
if (dev->apm->do_smi) {
if (dev->type < 4)
@@ -1429,70 +1444,84 @@ piix_fast_off_count(void *priv)
}
static void
piix_reset(void *p)
piix_usb_update_interrupt(usb_t* usb, void *priv)
{
piix_t *dev = (piix_t *) p;
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 *priv)
{
piix_t *dev = (piix_t *) priv;
if (dev->type > 3) {
piix_write(3, 0x04, 0x00, p);
piix_write(3, 0x5b, 0x00, p);
piix_write(3, 0x04, 0x00, priv);
piix_write(3, 0x5b, 0x00, priv);
} else {
piix_write(0, 0xa0, 0x08, p);
piix_write(0, 0xa2, 0x00, p);
piix_write(0, 0xa4, 0x00, p);
piix_write(0, 0xa5, 0x00, p);
piix_write(0, 0xa6, 0x00, p);
piix_write(0, 0xa7, 0x00, p);
piix_write(0, 0xa8, 0x0f, p);
piix_write(0, 0xa0, 0x08, priv);
piix_write(0, 0xa2, 0x00, priv);
piix_write(0, 0xa4, 0x00, priv);
piix_write(0, 0xa5, 0x00, priv);
piix_write(0, 0xa6, 0x00, priv);
piix_write(0, 0xa7, 0x00, priv);
piix_write(0, 0xa8, 0x0f, priv);
}
/* Disable the PIC mouse latch. */
piix_write(0, 0x4e, 0x03, priv);
if (dev->type == 5)
piix_write(0, 0xe1, 0x40, p);
piix_write(1, 0x04, 0x00, p);
piix_write(0, 0xe1, 0x40, priv);
piix_write(1, 0x04, 0x00, priv);
if (dev->type == 5) {
piix_write(1, 0x09, 0x8a, p);
piix_write(1, 0x10, 0xf1, p);
piix_write(1, 0x11, 0x01, p);
piix_write(1, 0x14, 0xf5, p);
piix_write(1, 0x15, 0x03, p);
piix_write(1, 0x18, 0x71, p);
piix_write(1, 0x19, 0x01, p);
piix_write(1, 0x1c, 0x75, p);
piix_write(1, 0x1d, 0x03, p);
piix_write(1, 0x09, 0x8a, priv);
piix_write(1, 0x10, 0xf1, priv);
piix_write(1, 0x11, 0x01, priv);
piix_write(1, 0x14, 0xf5, priv);
piix_write(1, 0x15, 0x03, priv);
piix_write(1, 0x18, 0x71, priv);
piix_write(1, 0x19, 0x01, priv);
piix_write(1, 0x1c, 0x75, priv);
piix_write(1, 0x1d, 0x03, priv);
} else
piix_write(1, 0x09, 0x80, p);
piix_write(1, 0x20, 0x01, p);
piix_write(1, 0x21, 0x00, p);
piix_write(1, 0x41, 0x00, p);
piix_write(1, 0x43, 0x00, p);
piix_write(1, 0x09, 0x80, priv);
piix_write(1, 0x20, 0x01, priv);
piix_write(1, 0x21, 0x00, priv);
piix_write(1, 0x41, 0x00, priv);
piix_write(1, 0x43, 0x00, priv);
ide_pri_disable();
ide_sec_disable();
if (dev->type >= 3) {
piix_write(2, 0x04, 0x00, p);
piix_write(2, 0x04, 0x00, priv);
if (dev->type == 5) {
piix_write(2, 0x10, 0x00, p);
piix_write(2, 0x11, 0x00, p);
piix_write(2, 0x12, 0x00, p);
piix_write(2, 0x13, 0x00, p);
piix_write(2, 0x10, 0x00, priv);
piix_write(2, 0x11, 0x00, priv);
piix_write(2, 0x12, 0x00, priv);
piix_write(2, 0x13, 0x00, priv);
} else {
piix_write(2, 0x20, 0x01, p);
piix_write(2, 0x21, 0x00, p);
piix_write(2, 0x22, 0x00, p);
piix_write(2, 0x23, 0x00, p);
piix_write(2, 0x20, 0x01, priv);
piix_write(2, 0x21, 0x00, priv);
piix_write(2, 0x22, 0x00, priv);
piix_write(2, 0x23, 0x00, priv);
}
}
if (dev->type >= 4) {
piix_write(0, 0xb0, (is_pentium) ? 0x00 : 0x04, p);
piix_write(3, 0x40, 0x01, p);
piix_write(3, 0x41, 0x00, p);
piix_write(3, 0x5b, 0x00, p);
piix_write(3, 0x80, 0x00, p);
piix_write(3, 0x90, 0x01, p);
piix_write(3, 0x91, 0x00, p);
piix_write(3, 0xd2, 0x00, p);
piix_write(0, 0xb0, is_pentium ? 0x00 : 0x04, priv);
piix_write(3, 0x40, 0x01, priv);
piix_write(3, 0x41, 0x00, priv);
piix_write(3, 0x5b, 0x00, priv);
piix_write(3, 0x80, 0x00, priv);
piix_write(3, 0x90, 0x01, priv);
piix_write(3, 0x91, 0x00, priv);
piix_write(3, 0xd2, 0x00, priv);
}
sff_set_irq_mode(dev->bm[0], 0, 0);
@@ -1532,9 +1561,8 @@ piix_speed_changed(void *priv)
timer_on_auto(&dev->fast_off_timer, ((double) cpu_fast_off_val + 1) * dev->fast_off_period);
}
static void
*
piix_init(const device_t *info)
static void *
piix_init(const device_t *info)
{
piix_t *dev = (piix_t *) malloc(sizeof(piix_t));
memset(dev, 0, sizeof(piix_t));
@@ -1570,8 +1598,12 @@ static void
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);
@@ -1678,7 +1710,9 @@ static void
else
dev->board_config[1] |= 0x00;
// device_add(&i8254_sec_device);
#if 0
device_add(&i8254_sec_device);
#endif
return dev;
}

View File

@@ -27,23 +27,25 @@
#include <86box/dma.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/port_92.h>
#include <86box/machine.h>
#include <86box/chipset.h>
#include <86box/plat_unused.h>
typedef struct
{
uint8_t id,
regs[256];
typedef struct sio_t {
uint8_t id;
uint8_t regs[256];
uint16_t timer_base,
timer_latch;
uint16_t timer_base;
uint16_t timer_latch;
double fast_off_period;
pc_timer_t timer, fast_off_timer;
pc_timer_t timer;
pc_timer_t fast_off_timer;
apm_t *apm;
port_92_t *port_92;
@@ -199,6 +201,8 @@ sio_write(int func, int addr, uint8_t val, void *priv)
dev->regs[addr] = val;
break;
case 0x4c:
dev->regs[addr] = (val & 0x7f);
break;
case 0x4d:
dev->regs[addr] = (val & 0x7f);
break;
@@ -312,6 +316,8 @@ sio_write(int func, int addr, uint8_t val, void *priv)
cpu_fast_off_count = val + 1;
cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period);
break;
default:
break;
}
}
@@ -330,12 +336,13 @@ sio_read(int func, int addr, void *priv)
}
static void
sio_config_write(uint16_t addr, uint8_t val, void *priv)
sio_config_write(UNUSED(uint16_t addr), UNUSED(uint8_t val), UNUSED(void *priv))
{
//
}
static uint8_t
sio_config_read(uint16_t port, void *priv)
sio_config_read(uint16_t port, UNUSED(void *priv))
{
uint8_t ret = 0x00;
@@ -362,6 +369,9 @@ sio_config_read(uint16_t port, void *priv)
break;
}
break;
default:
break;
}
return ret;
@@ -422,9 +432,9 @@ sio_reset_hard(void *priv)
}
static void
sio_apm_out(uint16_t port, uint8_t val, void *p)
sio_apm_out(UNUSED(uint16_t port), UNUSED(uint8_t val), void *priv)
{
sio_t *dev = (sio_t *) p;
sio_t *dev = (sio_t *) priv;
if (dev->apm->do_smi)
dev->regs[0xaa] |= 0x80;
@@ -440,29 +450,32 @@ sio_fast_off_count(void *priv)
}
static void
sio_reset(void *p)
sio_reset(void *priv)
{
sio_t *dev = (sio_t *) p;
sio_t *dev = (sio_t *) priv;
sio_write(0, 0x57, 0x04, p);
/* Disable the PIC mouse latch. */
sio_write(0, 0x4d, 0x40, priv);
sio_write(0, 0x57, 0x04, priv);
dma_set_params(1, 0xffffffff);
if (dev->id == 0x03) {
sio_write(0, 0xa0, 0x08, p);
sio_write(0, 0xa2, 0x00, p);
sio_write(0, 0xa4, 0x00, p);
sio_write(0, 0xa5, 0x00, p);
sio_write(0, 0xa6, 0x00, p);
sio_write(0, 0xa7, 0x00, p);
sio_write(0, 0xa8, 0x0f, p);
sio_write(0, 0xa0, 0x08, priv);
sio_write(0, 0xa2, 0x00, priv);
sio_write(0, 0xa4, 0x00, priv);
sio_write(0, 0xa5, 0x00, priv);
sio_write(0, 0xa6, 0x00, priv);
sio_write(0, 0xa7, 0x00, priv);
sio_write(0, 0xa8, 0x0f, priv);
}
}
static void
sio_close(void *p)
sio_close(void *priv)
{
sio_t *dev = (sio_t *) p;
sio_t *dev = (sio_t *) priv;
free(dev);
}
@@ -536,7 +549,9 @@ sio_init(const device_t *info)
timer_add(&dev->timer, NULL, NULL, 0);
// device_add(&i8254_sec_device);
#if 0
device_add(&i8254_sec_device);
#endif
return dev;
}

View File

@@ -30,6 +30,7 @@
#include <86box/device.h>
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include <86box/chipset.h>
#define NEAT_DEBUG 0
@@ -200,7 +201,7 @@
#define RB11_EMSLEN 0xe0 /* EMS memory chunk size */
#define RB11_EMSLEN_SH 5
typedef struct {
typedef struct emspage_t {
int8_t enabled; /* 1=ENABLED */
char pad;
uint16_t page; /* selected page in EMS block */
@@ -209,18 +210,18 @@ typedef struct {
mem_mapping_t mapping; /* mapping entry for page */
} emspage_t;
typedef struct {
typedef struct neat_t {
uint8_t regs[128]; /* all the CS8221 registers */
uint8_t indx; /* programmed index into registers */
char pad;
uint16_t ems_base, /* configured base address */
ems_oldbase;
uint32_t ems_frame, /* configured frame address */
ems_oldframe;
uint16_t ems_size, /* EMS size in KB */
ems_pages; /* EMS size in pages */
uint16_t ems_base; /* configured base address */
uint16_t ems_oldbase;
uint32_t ems_frame; /* configured frame address */
uint32_t ems_oldframe;
uint16_t ems_size; /* EMS size in KB */
uint16_t ems_pages; /* EMS size in pages */
emspage_t ems[EMS_MAXPAGE]; /* EMS page registers */
} neat_t;
@@ -250,9 +251,9 @@ ems_readb(uint32_t addr, void *priv)
uint8_t ret = 0xff;
/* Grab the data. */
ret = *(uint8_t *) (dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff));
ret = *(uint8_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff));
return (ret);
return ret;
}
/* Read one word from paged RAM. */
@@ -263,9 +264,9 @@ ems_readw(uint32_t addr, void *priv)
uint16_t ret = 0xffff;
/* Grab the data. */
ret = *(uint16_t *) (dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff));
ret = *(uint16_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff));
return (ret);
return ret;
}
/* Write one byte to paged RAM. */
@@ -275,7 +276,7 @@ ems_writeb(uint32_t addr, uint8_t val, void *priv)
neat_t *dev = (neat_t *) priv;
/* Write the data. */
*(uint8_t *) (dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff)) = val;
*(uint8_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)) = val;
}
/* Write one word to paged RAM. */
@@ -285,7 +286,7 @@ ems_writew(uint32_t addr, uint16_t val, void *priv)
neat_t *dev = (neat_t *) priv;
/* Write the data. */
*(uint16_t *) (dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff)) = val;
*(uint16_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)) = val;
}
/* Re-calculate the active-page physical address. */
@@ -340,6 +341,8 @@ ems_write(uint16_t port, uint8_t val, void *priv)
ems->page |= (val & 0x7f); /* add new bits */
ems_recalc(dev, ems);
break;
default:
break;
}
}
@@ -359,25 +362,27 @@ ems_read(uint16_t port, void *priv)
if (dev->ems[vpage].enabled)
ret |= 0x80;
break;
default:
break;
}
#if NEAT_DEBUG > 1
neat_log("NEAT: ems_read(%04x) = %02x\n", port, ret);
#endif
return (ret);
return ret;
}
/* Initialize the EMS module. */
static void
ems_init(neat_t *dev, int en)
{
int i;
uint8_t j;
/* Remove if needed. */
if (!en) {
if (dev->ems_base > 0)
for (i = 0; i < EMS_MAXPAGE; i++) {
for (uint8_t i = 0; i < EMS_MAXPAGE; i++) {
/* Disable for now. */
mem_mapping_disable(&dev->ems[i].mapping);
@@ -394,19 +399,19 @@ ems_init(neat_t *dev, int en)
}
/* Get configured I/O address. */
i = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH;
dev->ems_base = 0x0208 + (0x10 * i);
j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH;
dev->ems_base = 0x0208 + (0x10 * j);
/* Get configured frame address. */
i = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH;
dev->ems_frame = 0xC0000 + (EMS_PGSIZE * i);
j = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH;
dev->ems_frame = 0xC0000 + (EMS_PGSIZE * j);
/*
* For each supported page (we can have a maximum of 4),
* create, initialize and disable the mappings, and set
* up the I/O control handler.
*/
for (i = 0; i < EMS_MAXPAGE; i++) {
for (uint8_t i = 0; i < EMS_MAXPAGE; i++) {
/* Create and initialize a page mapping. */
mem_mapping_add(&dev->ems[i].mapping,
dev->ems_frame + (EMS_PGSIZE * i), EMS_PGSIZE,
@@ -435,9 +440,10 @@ ems_init(neat_t *dev, int en)
static void
neat_write(uint16_t port, uint8_t val, void *priv)
{
neat_t *dev = (neat_t *) priv;
uint8_t xval, *reg;
int i;
neat_t *dev = (neat_t *) priv;
uint8_t xval;
uint8_t *reg;
int i;
#if NEAT_DEBUG > 2
neat_log("NEAT: write(%04x, %02x)\n", port, val);
@@ -607,6 +613,8 @@ neat_write(uint16_t port, uint8_t val, void *priv)
case 7: /* 7 MB */
dev->ems_size = i << 10;
break;
default:
break;
}
dev->ems_pages = (dev->ems_size << 10) / EMS_PGSIZE;
if (dev->regs[REG_RB7] & RB7_EMSEN) {
@@ -621,6 +629,8 @@ neat_write(uint16_t port, uint8_t val, void *priv)
break;
}
break;
default:
break;
}
}
@@ -647,7 +657,7 @@ neat_read(uint16_t port, void *priv)
neat_log("NEAT: read(%04x) = %02x\n", port, ret);
#endif
return (ret);
return ret;
}
static void
@@ -659,17 +669,17 @@ neat_close(void *priv)
}
static void *
neat_init(const device_t *info)
neat_init(UNUSED(const device_t *info))
{
neat_t *dev;
int i;
uint8_t dram_mode = 0;
/* Create an instance. */
dev = (neat_t *) malloc(sizeof(neat_t));
memset(dev, 0x00, sizeof(neat_t));
/* Initialize some of the registers to specific defaults. */
for (i = REG_RA0; i <= REG_RB11; i++) {
for (uint8_t i = REG_RA0; i <= REG_RB11; i++) {
dev->indx = i;
neat_write(0x0023, 0x00, dev);
}
@@ -681,7 +691,6 @@ neat_init(const device_t *info)
* TODO: We might also want to set 'valid' waitstate
* bits, based on our cpu speed.
*/
i = 0;
switch (mem_size) {
case 512: /* 512KB */
/* 256K, 0, 0, 0 */
@@ -689,7 +698,7 @@ neat_init(const device_t *info)
dev->regs[REG_RB6] |= (RTYPE_256K << RTYPE_SH); /* 256K */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_NONE << RTYPE_SH); /* NONE */
i = 2;
dram_mode = 2;
break;
case 640: /* 640KB */
@@ -698,7 +707,7 @@ neat_init(const device_t *info)
dev->regs[REG_RB6] |= (RTYPE_MIXED << RTYPE_SH); /* mixed */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_NONE << RTYPE_SH); /* NONE */
i = 4;
dram_mode = 4;
break;
case 1024: /* 1MB */
@@ -707,7 +716,7 @@ neat_init(const device_t *info)
dev->regs[REG_RB6] |= (RTYPE_256K << RTYPE_SH); /* 256K */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_NONE << RTYPE_SH); /* NONE */
i = 5;
dram_mode = 5;
break;
case 1536: /* 1.5MB */
@@ -716,7 +725,7 @@ neat_init(const device_t *info)
dev->regs[REG_RB6] |= (RTYPE_256K << RTYPE_SH); /* 256K */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_256K << RTYPE_SH); /* 256K */
i = 7;
dram_mode = 7;
break;
case 1664: /* 1.64MB */
@@ -725,7 +734,7 @@ neat_init(const device_t *info)
dev->regs[REG_RB6] |= (RTYPE_MIXED << RTYPE_SH); /* mixed */
dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */
dev->regs[REG_RB8] |= (RTYPE_256K << RTYPE_SH); /* 256K */
i = 10;
dram_mode = 10;
break;
case 2048: /* 2MB */
@@ -736,14 +745,14 @@ neat_init(const device_t *info)
dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */
dev->regs[REG_RB8] |= (RTYPE_256K << RTYPE_SH); /* 256K */
dev->regs[REG_RB8] |= RB8_4WAY; /* 4way intl */
i = 11;
dram_mode = 11;
#else
/* 1M, 0, 0, 0 */
dev->regs[REG_RB6] &= ~RB6_BANKS; /* one bank */
dev->regs[REG_RB6] |= (RTYPE_1M << RTYPE_SH); /* 1M */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_NONE << RTYPE_SH); /* NONE */
i = 3;
dram_mode = 3;
#endif
break;
@@ -753,7 +762,7 @@ neat_init(const device_t *info)
dev->regs[REG_RB6] |= (RTYPE_256K << RTYPE_SH); /* 256K */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_1M << RTYPE_SH); /* 1M */
i = 8;
dram_mode = 8;
break;
case 4096: /* 4MB */
@@ -762,7 +771,7 @@ neat_init(const device_t *info)
dev->regs[REG_RB6] |= (RTYPE_1M << RTYPE_SH); /* 1M */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_NONE << RTYPE_SH); /* NONE */
i = 6;
dram_mode = 6;
break;
case 4224: /* 4.64MB */
@@ -771,7 +780,7 @@ neat_init(const device_t *info)
dev->regs[REG_RB6] |= (RTYPE_MIXED << RTYPE_SH); /* mixed */
dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */
dev->regs[REG_RB8] |= (RTYPE_1M << RTYPE_SH); /* 1M */
i = 12;
dram_mode = 12;
break;
case 5120: /* 5MB */
@@ -780,7 +789,7 @@ neat_init(const device_t *info)
dev->regs[REG_RB6] |= (RTYPE_256K << RTYPE_SH); /* 256K */
dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */
dev->regs[REG_RB8] |= (RTYPE_1M << RTYPE_SH); /* 1M */
i = 13;
dram_mode = 13;
break;
case 6144: /* 6MB */
@@ -789,7 +798,7 @@ neat_init(const device_t *info)
dev->regs[REG_RB6] |= (RTYPE_1M << RTYPE_SH); /* 1M */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_1M << RTYPE_SH); /* 1M */
i = 9;
dram_mode = 9;
break;
case 8192: /* 8MB */
@@ -799,13 +808,13 @@ neat_init(const device_t *info)
dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */
dev->regs[REG_RB8] |= (RTYPE_1M << RTYPE_SH); /* 1M */
dev->regs[REG_RB8] |= RB8_4WAY; /* 4way intl */
i = 14;
dram_mode = 14;
break;
default:
neat_log("NEAT: **INVALID DRAM SIZE %iKB !**\n", mem_size);
}
if (i > 0) {
if (dram_mode > 0) {
neat_log("NEAT: using DRAM mode #%i (mem=%iKB)\n", i, mem_size);
}

View File

@@ -32,9 +32,9 @@
#include <86box/chipset.h>
#include <86box/video.h>
#include <86box/mem.h>
#include <86box/plat_unused.h>
typedef struct
{
typedef struct olivetti_eva_t {
uint8_t reg_065;
uint8_t reg_067;
uint8_t reg_069;
@@ -77,20 +77,24 @@ olivetti_eva_write(uint16_t addr, uint8_t val, void *priv)
* Unfortunately, if triggered, the BIOS remapping function fails causing
* a fatal error. Therefore, this code section is currently commented.
*/
// if (val & 1){
// /*
// * Set the register to 7 or above for the BIOS to trigger the
// * memory remapping function if shadowing is active.
// */
// dev->reg_069 = 0x7;
// }
// if (val & 8) {
// /*
// * Activate shadowing for region e0000-fffff
// */
// mem_remap_top(256);
// mem_set_mem_state_both(0xa0000, 0x60000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
// }
#if 0
if (val & 1) {
/*
* Set the register to 7 or above for the BIOS to trigger the
* memory remapping function if shadowing is active.
*/
dev->reg_069 = 0x7;
}
if (val & 8) {
/*
* Activate shadowing for region e0000-fffff
*/
mem_remap_top(256);
mem_set_mem_state_both(0xa0000, 0x60000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
}
#endif
break;
default:
break;
}
}
@@ -111,6 +115,8 @@ olivetti_eva_read(uint16_t addr, void *priv)
case 0x069:
ret = dev->reg_069;
break;
default:
break;
}
olivetti_eva_log("Olivetti EVA Gate Array: Read %02x at %02x\n", ret, addr);
return ret;
@@ -125,7 +131,7 @@ olivetti_eva_close(void *priv)
}
static void *
olivetti_eva_init(const device_t *info)
olivetti_eva_init(UNUSED(const device_t *info))
{
olivetti_eva_t *dev = (olivetti_eva_t *) malloc(sizeof(olivetti_eva_t));
memset(dev, 0, sizeof(olivetti_eva_t));

View File

@@ -29,6 +29,7 @@
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include <86box/chipset.h>
#ifdef ENABLE_OPTI283_LOG
@@ -49,15 +50,15 @@ opti283_log(const char *fmt, ...)
# define opti283_log(fmt, ...)
#endif
typedef struct
{
uint32_t phys, virt;
typedef struct mem_remapping_t {
uint32_t phys;
uint32_t virt;
} mem_remapping_t;
typedef struct
{
uint8_t index, shadow_high,
regs[256];
typedef struct opti283_t {
uint8_t index;
uint8_t shadow_high;
uint8_t regs[256];
mem_remapping_t mem_remappings[2];
mem_mapping_t mem_mappings[2];
} opti283_t;
@@ -113,10 +114,12 @@ opti283_write_remapped_raml(uint32_t addr, uint32_t val, void *priv)
static void
opti283_shadow_recalc(opti283_t *dev)
{
uint32_t i, base;
uint32_t base;
uint32_t rbase;
uint8_t sh_enable, sh_mode;
uint8_t rom, sh_copy;
uint8_t sh_enable;
uint8_t sh_mode;
uint8_t rom;
uint8_t sh_copy;
shadowbios = shadowbios_write = 0;
dev->shadow_high = 0;
@@ -143,7 +146,7 @@ opti283_shadow_recalc(opti283_t *dev)
}
sh_copy = dev->regs[0x11] & 0x08;
for (i = 0; i < 12; i++) {
for (uint8_t i = 0; i < 12; i++) {
base = 0xc0000 + (i << 14);
if (i >= 4)
sh_enable = dev->regs[0x12] & (1 << (i - 4));
@@ -232,8 +235,14 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
dev->regs[dev->index] = val;
opti283_shadow_recalc(dev);
break;
default:
break;
}
break;
default:
break;
}
}
@@ -258,7 +267,7 @@ opti283_close(void *priv)
}
static void *
opti283_init(const device_t *info)
opti283_init(UNUSED(const device_t *info))
{
opti283_t *dev = (opti283_t *) malloc(sizeof(opti283_t));
memset(dev, 0x00, sizeof(opti283_t));

View File

@@ -28,6 +28,7 @@
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
@@ -49,9 +50,9 @@ opti291_log(const char *fmt, ...)
# define opti291_log(fmt, ...)
#endif
typedef struct
{
uint8_t index, regs[256];
typedef struct opti291_t {
uint8_t index;
uint8_t regs[256];
port_92_t *port_92;
} opti291_t;
@@ -107,8 +108,14 @@ opti291_write(uint16_t addr, uint8_t val, void *priv)
case 0x2c:
dev->regs[dev->index] = val;
break;
default:
break;
}
break;
default:
break;
}
}
@@ -129,7 +136,7 @@ opti291_close(void *priv)
}
static void *
opti291_init(const device_t *info)
opti291_init(UNUSED(const device_t *info))
{
opti291_t *dev = (opti291_t *) malloc(sizeof(opti291_t));
memset(dev, 0, sizeof(opti291_t));

View File

@@ -27,6 +27,7 @@
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include <86box/chipset.h>
#ifdef ENABLE_OPTI391_LOG
@@ -47,22 +48,24 @@ opti391_log(const char *fmt, ...)
# define opti391_log(fmt, ...)
#endif
typedef struct
{
uint32_t phys, virt;
typedef struct mem_remapping_t {
uint32_t phys;
uint32_t virt;
} mem_remapping_t;
typedef struct
{
uint8_t index, regs[256];
typedef struct opti391_t {
uint8_t index;
uint8_t regs[256];
} opti391_t;
static void
opti391_shadow_recalc(opti391_t *dev)
{
uint32_t i, base;
uint8_t sh_enable, sh_master;
uint8_t sh_wp, sh_write_internal;
uint32_t base;
uint8_t sh_enable;
uint8_t sh_master;
uint8_t sh_wp;
uint8_t sh_write_internal;
shadowbios = shadowbios_write = 0;
@@ -75,7 +78,7 @@ opti391_shadow_recalc(opti391_t *dev)
sh_write_internal = (dev->regs[0x26] & 0x40);
/* D0000-EFFFF */
for (i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
base = 0xd0000 + (i << 14);
if (base >= 0xe0000) {
sh_master = (dev->regs[0x22] & 0x40);
@@ -105,7 +108,7 @@ opti391_shadow_recalc(opti391_t *dev)
/* C0000-CFFFF */
sh_master = !(dev->regs[0x26] & 0x10);
sh_wp = (dev->regs[0x26] & 0x20);
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
base = 0xc0000 + (i << 14);
sh_enable = dev->regs[0x26] & (1 << i);
@@ -161,8 +164,14 @@ opti391_write(uint16_t addr, uint8_t val, void *priv)
dev->regs[dev->index] = val;
opti391_shadow_recalc(dev);
break;
default:
break;
}
break;
default:
break;
}
}
@@ -187,7 +196,7 @@ opti391_close(void *priv)
}
static void *
opti391_init(const device_t *info)
opti391_init(UNUSED(const device_t *info))
{
opti391_t *dev = (opti391_t *) malloc(sizeof(opti391_t));
memset(dev, 0x00, sizeof(opti391_t));

View File

@@ -31,11 +31,10 @@
#include <86box/port_92.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t idx,
regs[256],
scratch[2];
typedef struct opti495_t {
uint8_t idx;
uint8_t regs[256];
uint8_t scratch[2];
} opti495_t;
#ifdef ENABLE_OPTI495_LOG
@@ -60,7 +59,7 @@ static void
opti495_recalc(opti495_t *dev)
{
uint32_t base;
uint32_t i, shflags = 0;
uint32_t shflags = 0;
shadowbios = 0;
shadowbios_write = 0;
@@ -77,7 +76,7 @@ opti495_recalc(opti495_t *dev)
mem_set_mem_state_both(0xf0000, 0x10000, shflags);
for (i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
base = 0xd0000 + (i << 14);
if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) && (dev->regs[0x23] & (1 << i))) {
@@ -94,7 +93,7 @@ opti495_recalc(opti495_t *dev)
mem_set_mem_state_both(base, 0x4000, shflags);
}
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
base = 0xc0000 + (i << 14);
if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) {
@@ -140,6 +139,8 @@ opti495_write(uint16_t addr, uint8_t val, void *priv)
case 0x26:
opti495_recalc(dev);
break;
default:
break;
}
}
break;
@@ -148,6 +149,8 @@ opti495_write(uint16_t addr, uint8_t val, void *priv)
case 0xe2:
dev->scratch[~addr & 0x01] = val;
break;
default:
break;
}
}
@@ -171,6 +174,8 @@ opti495_read(uint16_t addr, void *priv)
case 0xe2:
ret = dev->scratch[~addr & 0x01];
break;
default:
break;
}
return ret;

View File

@@ -29,12 +29,13 @@
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/port_92.h>
#include <86box/plat_unused.h>
#include <86box/chipset.h>
typedef struct
{
typedef struct opti499_t {
uint8_t idx,
regs[256], scratch[2];
uint8_t regs[256];
uint8_t scratch[2];
} opti499_t;
#ifdef ENABLE_OPTI499_LOG
@@ -59,7 +60,7 @@ static void
opti499_recalc(opti499_t *dev)
{
uint32_t base;
uint32_t i, shflags = 0;
uint32_t shflags = 0;
shadowbios = 0;
shadowbios_write = 0;
@@ -76,7 +77,7 @@ opti499_recalc(opti499_t *dev)
mem_set_mem_state_both(0xf0000, 0x10000, shflags);
for (i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
base = 0xd0000 + (i << 14);
if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) && (dev->regs[0x23] & (1 << i))) {
@@ -92,7 +93,7 @@ opti499_recalc(opti499_t *dev)
mem_set_mem_state_both(base, 0x4000, shflags);
}
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
base = 0xc0000 + (i << 14);
if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) {
@@ -153,6 +154,9 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
case 0x2d:
opti499_recalc(dev);
break;
default:
break;
}
}
break;
@@ -161,6 +165,9 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
case 0xe2:
dev->scratch[~addr & 0x01] = val;
break;
default:
break;
}
}
@@ -187,6 +194,9 @@ opti499_read(uint16_t addr, void *priv)
case 0xe2:
ret = dev->scratch[~addr & 0x01];
break;
default:
break;
}
return ret;
@@ -229,7 +239,7 @@ opti499_close(void *priv)
}
static void *
opti499_init(const device_t *info)
opti499_init(UNUSED(const device_t *info))
{
opti499_t *dev = (opti499_t *) malloc(sizeof(opti499_t));
memset(dev, 0, sizeof(opti499_t));

View File

@@ -32,10 +32,10 @@
#include <86box/port_92.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t idx, is_pci,
regs[16];
typedef struct opti5x7_t {
uint8_t idx;
uint8_t is_pci;
uint8_t regs[16];
} opti5x7_t;
#ifdef ENABLE_OPTI5X7_LOG
@@ -84,7 +84,7 @@ opti5x7_shadow_map(int cur_reg, opti5x7_t *dev)
mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
}
} else {
for (int i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
if (dev->is_pci)
mem_set_mem_state_cpu_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
else
@@ -143,9 +143,13 @@ opti5x7_write(uint16_t addr, uint8_t val, void *priv)
case 0x11: /* Master Cycle Control Register */
dev->regs[dev->idx] = val;
break;
default:
break;
}
opti5x7_log("OPTi 5x7: dev->regs[%02x] = %02x\n", dev->idx, dev->regs[dev->idx]);
break;
default:
break;
}
}

View File

@@ -33,6 +33,7 @@
#include <86box/timer.h>
#include <86box/pic.h>
#include <86box/pit.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/hdc_ide.h>
#include <86box/hdc.h>
@@ -40,10 +41,9 @@
#include <86box/chipset.h>
#include <86box/spd.h>
typedef struct
{
uint8_t irq_convert,
pci_regs[256];
typedef struct opti822_t {
uint8_t irq_convert;
uint8_t pci_regs[256];
} opti822_t;
// #define ENABLE_OPTI822_LOG 1
@@ -71,11 +71,13 @@ opti822_log(const char *fmt, ...)
static void
opti822_recalc(opti822_t *dev)
{
int i, reg, bit_r, bit_w;
int reg;
int bit_r;
int bit_w;
int state;
uint32_t base;
for (i = 0; i < 12; i++) {
for (uint8_t i = 0; i < 12; i++) {
base = 0x000c0000 + (i << 14);
reg = 0x44 + ((i >> 2) ^ 3);
bit_w = (i & 3);
@@ -99,15 +101,18 @@ static void
opti822_update_irqs(opti822_t *dev, int set)
{
uint8_t val;
int i, reg;
int shift, irq;
int reg;
int shift;
int irq;
int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
pic_t *temp_pic;
// dev->irq_convert = (dev->pci_regs[0x53] & 0x08);
#if 0
dev->irq_convert = (dev->pci_regs[0x53] & 0x08);
#endif
dev->irq_convert = 1;
for (i = 0; i < 16; i++) {
for (uint8_t i = 0; i < 16; i++) {
reg = 0x88 + (i >> 1);
shift = (i & 1) << 2;
val = (dev->pci_regs[reg] >> shift) & 0x0f;
@@ -127,8 +132,10 @@ static void
opti822_pci_write(int func, int addr, uint8_t val, void *priv)
{
opti822_t *dev = (opti822_t *) priv;
int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
int pin, slot;
int irq;
int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
int pin;
int slot;
opti822_log("opti822_write(%02X, %02X, %02X)\n", func, addr, val);
@@ -320,6 +327,9 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv)
}
opti822_update_irqs(dev, 1);
break;
default:
break;
}
}
@@ -343,7 +353,6 @@ static void
opti822_reset(void *priv)
{
opti822_t *dev = (opti822_t *) priv;
int i;
memset(dev->pci_regs, 0, 256);
@@ -366,7 +375,7 @@ opti822_reset(void *priv)
dev->irq_convert = 1 /*0*/;
for (i = 0; i < 16; i++)
for (uint8_t i = 0; i < 16; i++)
pci_set_irq_routing(PCI_INTA + i, PCI_IRQ_DISABLED);
}
@@ -379,7 +388,7 @@ opti822_close(void *p)
}
static void *
opti822_init(const device_t *info)
opti822_init(UNUSED(const device_t *info))
{
opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t));
memset(dev, 0, sizeof(opti822_t));

View File

@@ -32,12 +32,12 @@
#include <86box/port_92.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t idx, forced_green,
is_pci,
regs[256],
scratch[2];
typedef struct opti895_t {
uint8_t idx;
uint8_t forced_green;
uint8_t is_pci;
uint8_t regs[256];
uint8_t scratch[2];
smram_t *smram;
} opti895_t;
@@ -64,7 +64,7 @@ static void
opti895_recalc(opti895_t *dev)
{
uint32_t base;
uint32_t i, shflags = 0;
uint32_t shflags = 0;
shadowbios = 0;
shadowbios_write = 0;
@@ -84,7 +84,7 @@ opti895_recalc(opti895_t *dev)
else
mem_set_mem_state_both(0xf0000, 0x10000, shflags);
for (i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
base = 0xd0000 + (i << 14);
if (dev->regs[0x23] & (1 << i)) {
@@ -108,7 +108,7 @@ opti895_recalc(opti895_t *dev)
mem_set_mem_state_both(base, 0x4000, shflags);
}
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
base = 0xc0000 + (i << 14);
if (dev->regs[0x26] & (1 << i)) {
@@ -184,6 +184,9 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
break;
}
break;
default:
break;
}
}
break;
@@ -192,6 +195,9 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
case 0xe2:
dev->scratch[addr - 0xe1] = val;
break;
default:
break;
}
}
@@ -217,6 +223,9 @@ opti895_read(uint16_t addr, void *priv)
case 0xe2:
ret = dev->scratch[addr - 0xe1];
break;
default:
break;
}
return ret;

View File

@@ -31,6 +31,7 @@
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/nmi.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
@@ -66,20 +67,21 @@ enum {
BANK_4M_INTERLEAVED
};
typedef struct {
typedef struct ram_struct_t {
void *parent;
int bank;
} ram_struct_t;
typedef struct {
typedef struct ems_struct_t {
void *parent;
int segment;
} ems_struct_t;
typedef struct {
typedef struct scamp_t {
int cfg_index;
uint8_t cfg_regs[256];
int cfg_enable, ram_config;
int cfg_enable;
int ram_config;
int ems_index;
int ems_autoinc;
@@ -91,21 +93,23 @@ typedef struct {
ram_struct_t ram_struct[2];
ems_struct_t ems_struct[20];
uint32_t ram_virt_base[2], ram_phys_base[2];
uint32_t ram_virt_base[2];
uint32_t ram_phys_base[2];
uint32_t ram_mask[2];
int row_virt_shift[2], row_phys_shift[2];
int ram_interleaved[2], ibank_shift[2];
int row_virt_shift[2];
int row_phys_shift[2];
int ram_interleaved[2];
int ibank_shift[2];
port_92_t *port_92;
} scamp_t;
static const struct
{
static const struct {
int size_kb;
int rammap;
int bank[2];
} ram_configs[] = {
{512, 0x0, { BANK_256K, BANK_NONE } },
{ 512, 0x0, { BANK_256K, BANK_NONE } },
{ 1024, 0x1, { BANK_256K_INTERLEAVED, BANK_NONE } },
{ 1536, 0x2, { BANK_256K_INTERLEAVED, BANK_256K } },
{ 2048, 0x3, { BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED }},
@@ -118,12 +122,11 @@ static const struct
{ 16384, 0x9, { BANK_4M_INTERLEAVED, BANK_NONE } },
};
static const struct
{
static const struct {
int bank[2];
int remapped;
} rammap[16] = {
{{ BANK_256K, BANK_NONE }, 0},
{ { BANK_256K, BANK_NONE }, 0},
{ { BANK_256K_INTERLEAVED, BANK_NONE }, 0},
{ { BANK_256K_INTERLEAVED, BANK_256K }, 0},
{ { BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED }, 0},
@@ -151,8 +154,10 @@ ram_mirrored_256k_in_4mi_read(uint32_t addr, void *priv)
{
ram_struct_t *rs = (ram_struct_t *) priv;
scamp_t *dev = rs->parent;
int bank = rs->bank, byte;
int row, column;
int bank = rs->bank;
int byte;
int row;
int column;
addr -= dev->ram_virt_base[bank];
byte = addr & 1;
@@ -180,8 +185,10 @@ ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *priv)
{
ram_struct_t *rs = (ram_struct_t *) priv;
scamp_t *dev = rs->parent;
int bank = rs->bank, byte;
int row, column;
int bank = rs->bank;
int byte;
int row;
int column;
addr -= dev->ram_virt_base[bank];
byte = addr & 1;
@@ -211,8 +218,10 @@ ram_mirrored_interleaved_read(uint32_t addr, void *priv)
{
ram_struct_t *rs = (ram_struct_t *) priv;
scamp_t *dev = rs->parent;
int bank = rs->bank, byte;
int row, column;
int bank = rs->bank;
int byte;
int row;
int column;
addr -= dev->ram_virt_base[bank];
byte = addr & 1;
@@ -240,8 +249,10 @@ ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *priv)
{
ram_struct_t *rs = (ram_struct_t *) priv;
scamp_t *dev = rs->parent;
int bank = rs->bank, byte;
int row, column;
int bank = rs->bank;
int byte;
int row;
int column;
addr -= dev->ram_virt_base[bank];
byte = addr & 1;
@@ -269,8 +280,10 @@ ram_mirrored_read(uint32_t addr, void *priv)
{
ram_struct_t *rs = (ram_struct_t *) priv;
scamp_t *dev = rs->parent;
int bank = rs->bank, byte;
int row, column;
int bank = rs->bank;
int byte;
int row;
int column;
addr -= dev->ram_virt_base[bank];
byte = addr & 1;
@@ -286,8 +299,10 @@ ram_mirrored_write(uint32_t addr, uint8_t val, void *priv)
{
ram_struct_t *rs = (ram_struct_t *) priv;
scamp_t *dev = rs->parent;
int bank = rs->bank, byte;
int row, column;
int bank = rs->bank;
int byte;
int row;
int column;
addr -= dev->ram_virt_base[bank];
byte = addr & 1;
@@ -302,15 +317,16 @@ static void
recalc_mappings(void *priv)
{
scamp_t *dev = (scamp_t *) priv;
int c;
uint32_t virt_base = 0, old_virt_base;
uint32_t virt_base = 0;
uint32_t old_virt_base;
uint8_t cur_rammap = dev->cfg_regs[CFG_RAMMAP] & 0xf;
int bank_nr = 0, phys_bank;
int bank_nr = 0;
int phys_bank;
mem_set_mem_state_both((1 << 20), (16256 - 1024) * 1024, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
for (c = 0; c < 2; c++)
for (uint8_t c = 0; c < 2; c++)
mem_mapping_disable(&dev->ram_mapping[c]);
/* Once the BIOS programs the correct DRAM configuration, switch to regular
@@ -411,6 +427,9 @@ recalc_mappings(void *priv)
virt_base += (1 << 24);
dev->row_virt_shift[bank_nr] = 12;
break;
default:
break;
}
} else {
switch (rammap[cur_rammap].bank[bank_nr]) {
@@ -476,6 +495,9 @@ recalc_mappings(void *priv)
virt_base += (1 << 24);
dev->row_virt_shift[bank_nr] = 12;
break;
default:
break;
}
}
switch (rammap[cur_rammap].bank[bank_nr]) {
@@ -521,6 +543,9 @@ recalc_mappings(void *priv)
ram_mirrored_interleaved_write, NULL, NULL);
}
break;
default:
break;
}
}
}
@@ -571,7 +596,6 @@ scamp_ems_write(uint32_t addr, uint8_t val, void *priv)
static void
recalc_ems(scamp_t *dev)
{
int segment;
const uint32_t ems_base[12] = {
0xc0000, 0xc4000, 0xc8000, 0xcc000,
0xd0000, 0xd4000, 0xd8000, 0xdc000,
@@ -580,7 +604,7 @@ recalc_ems(scamp_t *dev)
uint32_t new_mappings[20];
uint16_t ems_enable;
for (segment = 0; segment < 20; segment++)
for (int segment = 0; segment < 20; segment++)
new_mappings[segment] = 0xa0000 + segment * 0x4000;
if (dev->cfg_regs[CFG_EMSEN1] & EMSEN1_EMSENAB)
@@ -588,7 +612,7 @@ recalc_ems(scamp_t *dev)
else
ems_enable = 0;
for (segment = 0; segment < 12; segment++) {
for (int segment = 0; segment < 12; segment++) {
if (ems_enable & (1 << segment)) {
uint32_t phys_addr = dev->ems[segment] << 14;
@@ -600,7 +624,7 @@ recalc_ems(scamp_t *dev)
}
}
for (segment = 0; segment < 20; segment++) {
for (int segment = 0; segment < 20; segment++) {
if (new_mappings[segment] != dev->mappings[segment]) {
dev->mappings[segment] = new_mappings[segment];
if (new_mappings[segment] < (mem_size * 1024)) {
@@ -631,6 +655,8 @@ shadow_control(uint32_t addr, uint32_t size, int state, int ems_enable)
case 3:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
default:
break;
}
flushmmucache_nopc();
@@ -743,6 +769,8 @@ scamp_write(uint16_t addr, uint8_t val, void *priv)
case CFG_FEAXS:
shadow_recalc(dev);
break;
default:
break;
}
}
break;
@@ -754,6 +782,9 @@ scamp_write(uint16_t addr, uint8_t val, void *priv)
mem_a20_recalc();
}
break;
default:
break;
}
}
@@ -796,6 +827,9 @@ scamp_read(uint16_t addr, void *priv)
softresetx86();
cpu_set_edx();
break;
default:
break;
}
return ret;
@@ -810,10 +844,9 @@ scamp_close(void *priv)
}
static void *
scamp_init(const device_t *info)
scamp_init(UNUSED(const device_t *info))
{
uint32_t addr;
int c;
scamp_t *dev = (scamp_t *) malloc(sizeof(scamp_t));
memset(dev, 0x00, sizeof(scamp_t));
@@ -834,7 +867,7 @@ scamp_init(const device_t *info)
dev->ram_config = 0;
/* Find best fit configuration for the requested memory size */
for (c = 0; c < NR_ELEMS(ram_configs); c++) {
for (uint8_t c = 0; c < NR_ELEMS(ram_configs); c++) {
if (mem_size < ram_configs[c].size_kb)
break;
@@ -850,7 +883,7 @@ scamp_init(const device_t *info)
mem_mapping_set_exec(&ram_mid_mapping, ram + 0xf0000);
addr = 0;
for (c = 0; c < 2; c++) {
for (uint8_t c = 0; c < 2; c++) {
dev->ram_struct[c].parent = dev;
dev->ram_struct[c].bank = c;
mem_mapping_add(&dev->ram_mapping[c], 0, 0,
@@ -911,12 +944,15 @@ scamp_init(const device_t *info)
dev->ibank_shift[c] = 23;
dev->ram_interleaved[c] = 1;
break;
default:
break;
}
}
mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
for (c = 0; c < 20; c++) {
for (uint8_t c = 0; c < 20; c++) {
dev->ems_struct[c].parent = dev;
dev->ems_struct[c].segment = c;
mem_mapping_add(&dev->ems_mappings[c],

View File

@@ -55,8 +55,9 @@
#define SCATSX_HIGH_PERFORMANCE_REFRESH 0x63
#define SCATSX_CAS_TIMING_FOR_DMA 0x64
typedef struct {
uint8_t valid, pad;
typedef struct ems_page_t {
uint8_t valid;
uint8_t pad;
uint8_t regs_2x8;
uint8_t regs_2x9;
@@ -75,7 +76,8 @@ typedef struct scat_t {
int external_is_RAS;
ems_page_t null_page, page[32];
ems_page_t null_page;
ems_page_t page[32];
mem_mapping_t low_mapping[32];
mem_mapping_t remap_mapping[6];
@@ -84,16 +86,20 @@ typedef struct scat_t {
} scat_t;
static const uint8_t max_map[32] = {
// clang-format off
0, 1, 1, 1, 2, 3, 4, 8,
4, 8, 12, 16, 20, 24, 28, 32,
0, 5, 9, 13, 6, 10, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
// clang-format om
};
static const uint8_t max_map_sx[32] = {
0, 1, 2, 1, 3, 4, 6, 10,
5, 9, 13, 4, 8, 12, 16, 14,
18, 22, 26, 20, 24, 28, 32, 18,
20, 32, 0, 0, 0, 0, 0, 0
// clang-format off
0, 1, 2, 1, 3, 4, 6, 10,
5, 9, 13, 4, 8, 12, 16, 14,
18, 22, 26, 20, 24, 28, 32, 18,
20, 32, 0, 0, 0, 0, 0, 0
// clang-format om
};
static const uint8_t scatsx_external_is_RAS[33] = {
0, 0, 0, 0, 0, 0, 0, 0,
@@ -109,13 +115,16 @@ static void scat_out(uint16_t port, uint8_t val, void *priv);
static void
shadow_state_update(scat_t *dev)
{
int i, val;
int val;
uint32_t base, bit, romcs, shflags = 0;
uint32_t base;
uint32_t bit;
uint32_t romcs;
uint32_t shflags = 0;
shadowbios = shadowbios_write = 0;
for (i = 0; i < 24; i++) {
for (uint8_t i = 0; i < 24; i++) {
if ((dev->regs[SCAT_DRAM_CONFIGURATION] & 0xf) < 4)
val = 0;
else
@@ -146,7 +155,6 @@ static void
set_xms_bound(scat_t *dev, uint8_t val)
{
uint32_t xms_max = ((dev->regs[SCAT_VERSION] & 0xf0) != 0 && ((val & 0x10) != 0)) || (dev->regs[SCAT_VERSION] >= 4) ? 0xfe0000 : 0xfc0000;
int i;
switch (val & 0x0f) {
case 1:
@@ -241,7 +249,7 @@ set_xms_bound(scat_t *dev, uint8_t val)
mem_mapping_set_addr(&dev->low_mapping[31], 0xf80000,
((dev->regs[SCAT_VERSION] & 0xf0) != 0 && ((val & 0x10) != 0)) || (dev->regs[SCAT_VERSION] >= 4) ? 0x60000 : 0x40000);
if (dev->regs[SCAT_VERSION] & 0xf0) {
for (i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
if (val & 0x10)
mem_mapping_disable(&bios_high_mapping);
else
@@ -254,7 +262,8 @@ static uint32_t
get_addr(scat_t *dev, uint32_t addr, ems_page_t *p)
{
#if 1
int nbanks_2048k, nbanks_512k;
int nbanks_2048k;
int nbanks_512k;
uint32_t addr2;
int nbank;
#else
@@ -878,10 +887,11 @@ get_addr(scat_t *dev, uint32_t addr, ems_page_t *p)
static void
set_global_EMS_state(scat_t *dev, int state)
{
uint32_t base_addr, virt_addr;
int i, conf;
uint32_t base_addr;
uint32_t virt_addr;
int conf;
for (i = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0 : 24; i < 32; i++) {
for (uint32_t i = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0 : 24; i < 32; i++) {
base_addr = (i + 16) << 14;
if (i >= 24)
@@ -923,9 +933,8 @@ static void
memmap_state_update(scat_t *dev)
{
uint32_t addr;
int i;
for (i = (((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0 : 16); i < 44; i++) {
for (uint8_t i = (((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0 : 16); i < 44; i++) {
addr = get_addr(dev, 0x40000 + (i << 14), &dev->null_page);
mem_mapping_set_exec(&dev->efff_mapping[i],
addr < ((uint32_t) mem_size << 10) ? ram + addr : NULL);
@@ -939,37 +948,40 @@ memmap_state_update(scat_t *dev)
mem_mapping_set_exec(&dev->low_mapping[1],
addr < ((uint32_t) mem_size << 10) ? ram + addr : NULL);
for (i = 2; i < 32; i++) {
for (uint8_t i = 2; i < 32; i++) {
addr = get_addr(dev, i << 19, &dev->null_page);
mem_mapping_set_exec(&dev->low_mapping[i],
addr < ((uint32_t) mem_size << 10) ? ram + addr : NULL);
}
if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) {
for (i = 0; i < max_map[(dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) | ((dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2)]; i++)
mem_mapping_enable(&dev->low_mapping[i]);
uint8_t j = 0;
for (; i < 32; i++)
mem_mapping_disable(&dev->low_mapping[i]);
for (j = 0; j < max_map[(dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) | ((dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2)]; j++)
mem_mapping_enable(&dev->low_mapping[j]);
for (i = 24; i < 36; i++) {
for (; j < 32; j++)
mem_mapping_disable(&dev->low_mapping[j]);
for (j = 24; j < 36; j++) {
if (((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) | (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40)) < 4)
mem_mapping_disable(&dev->efff_mapping[i]);
mem_mapping_disable(&dev->efff_mapping[j]);
else
mem_mapping_enable(&dev->efff_mapping[i]);
mem_mapping_enable(&dev->efff_mapping[j]);
}
} else {
for (i = 0; i < max_map_sx[dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f]; i++)
mem_mapping_enable(&dev->low_mapping[i]);
uint8_t j = 0;
for (j = 0; j < max_map_sx[dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f]; j++)
mem_mapping_enable(&dev->low_mapping[j]);
for (; i < 32; i++)
mem_mapping_disable(&dev->low_mapping[i]);
for (; j < 32; j++)
mem_mapping_disable(&dev->low_mapping[j]);
for (i = 24; i < 36; i++) {
for (j = 24; j < 36; j++) {
if ((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) < 2 || (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) == 3)
mem_mapping_disable(&dev->efff_mapping[i]);
mem_mapping_disable(&dev->efff_mapping[j]);
else
mem_mapping_enable(&dev->efff_mapping[i]);
mem_mapping_enable(&dev->efff_mapping[j]);
}
}
@@ -977,21 +989,21 @@ memmap_state_update(scat_t *dev)
if ((((dev->regs[SCAT_VERSION] & 0xf0) == 0) && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) == 3) || (((dev->regs[SCAT_VERSION] & 0xf0) != 0) && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) == 3)) {
mem_mapping_disable(&dev->low_mapping[2]);
for (i = 0; i < 6; i++) {
for (uint8_t i = 0; i < 6; i++) {
addr = get_addr(dev, 0x100000 + (i << 16), &dev->null_page);
mem_mapping_set_exec(&dev->remap_mapping[i],
addr < ((uint32_t) mem_size << 10) ? ram + addr : NULL);
mem_mapping_enable(&dev->remap_mapping[i]);
}
} else {
for (i = 0; i < 6; i++)
for (uint8_t i = 0; i < 6; i++)
mem_mapping_disable(&dev->remap_mapping[i]);
if ((((dev->regs[SCAT_VERSION] & 0xf0) == 0) && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) > 4) || (((dev->regs[SCAT_VERSION] & 0xf0) != 0) && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) > 3))
mem_mapping_enable(&dev->low_mapping[2]);
}
} else {
for (i = 0; i < 6; i++)
for (uint8_t i = 0; i < 6; i++)
mem_mapping_disable(&dev->remap_mapping[i]);
mem_mapping_enable(&dev->low_mapping[2]);
@@ -999,18 +1011,19 @@ memmap_state_update(scat_t *dev)
set_global_EMS_state(dev, dev->regs[SCAT_EMS_CONTROL] & 0x80);
flushmmucache_cr3();
flushmmucache_nopc();
}
static void
scat_out(uint16_t port, uint8_t val, void *priv)
{
scat_t *dev = (scat_t *) priv;
uint8_t reg_valid = 0,
shadow_update = 0,
map_update = 0,
indx;
uint32_t base_addr, virt_addr;
scat_t *dev = (scat_t *) priv;
uint8_t reg_valid = 0;
uint8_t shadow_update = 0;
uint8_t map_update = 0;
uint8_t indx;
uint32_t base_addr;
uint32_t virt_addr;
switch (port) {
case 0x22:
@@ -1182,6 +1195,9 @@ scat_out(uint16_t port, uint8_t val, void *priv)
if ((dev->regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4)))
dev->reg_2xA = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? val : val & 0xc3;
break;
default:
break;
}
}
@@ -1189,7 +1205,8 @@ static uint8_t
scat_in(uint16_t port, void *priv)
{
scat_t *dev = (scat_t *) priv;
uint8_t ret = 0xff, indx;
uint8_t ret = 0xff;
uint8_t indx;
switch (port) {
case 0x23:
@@ -1248,6 +1265,8 @@ scat_in(uint16_t port, void *priv)
if ((dev->regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4)))
ret = dev->reg_2xA;
break;
default:
break;
}
return ret;
@@ -1300,7 +1319,8 @@ mem_write_scatb(uint32_t addr, uint8_t val, void *priv)
{
ems_page_t *page = (ems_page_t *) priv;
scat_t *dev = (scat_t *) page->scat;
uint32_t oldaddr = addr, chkaddr;
uint32_t oldaddr = addr;
uint32_t chkaddr;
addr = get_addr(dev, addr, page);
chkaddr = page->valid ? addr : oldaddr;
@@ -1318,7 +1338,8 @@ mem_write_scatw(uint32_t addr, uint16_t val, void *priv)
{
ems_page_t *page = (ems_page_t *) priv;
scat_t *dev = (scat_t *) page->scat;
uint32_t oldaddr = addr, chkaddr;
uint32_t oldaddr = addr;
uint32_t chkaddr;
addr = get_addr(dev, addr, page);
chkaddr = page->valid ? addr : oldaddr;
@@ -1336,7 +1357,8 @@ mem_write_scatl(uint32_t addr, uint32_t val, void *priv)
{
ems_page_t *page = (ems_page_t *) priv;
scat_t *dev = (scat_t *) page->scat;
uint32_t oldaddr = addr, chkaddr;
uint32_t oldaddr = addr;
uint32_t chkaddr;
addr = get_addr(dev, addr, page);
chkaddr = page->valid ? addr : oldaddr;
@@ -1361,7 +1383,8 @@ static void *
scat_init(const device_t *info)
{
scat_t *dev;
uint32_t i, k;
uint32_t j;
uint32_t k;
int sx;
dev = (scat_t *) malloc(sizeof(scat_t));
@@ -1370,7 +1393,7 @@ scat_init(const device_t *info)
sx = (dev->type == 32) ? 1 : 0;
for (i = 0; i < sizeof(dev->regs); i++)
for (uint32_t i = 0; i < sizeof(dev->regs); i++)
dev->regs[i] = 0xff;
if (sx) {
@@ -1414,7 +1437,7 @@ scat_init(const device_t *info)
mem_mapping_disable(&ram_mid_mapping);
mem_mapping_disable(&ram_high_mapping);
k = (sx) ? 0x80000 : 0x40000;
k = sx ? 0x80000 : 0x40000;
dev->null_page.valid = 0;
dev->null_page.regs_2x8 = 0xff;
@@ -1431,7 +1454,7 @@ scat_init(const device_t *info)
mem_write_scatb, mem_write_scatw, mem_write_scatl,
ram + 0xf0000, MEM_MAPPING_INTERNAL, &dev->null_page);
for (i = 2; i < 32; i++) {
for (uint8_t i = 2; i < 32; i++) {
mem_mapping_add(&dev->low_mapping[i], (i << 19), 0x80000,
mem_read_scatb, mem_read_scatw, mem_read_scatl,
mem_write_scatb, mem_write_scatw, mem_write_scatl,
@@ -1439,27 +1462,27 @@ scat_init(const device_t *info)
}
if (sx) {
i = 16;
j = 16;
k = 0x40000;
} else {
i = 0;
j = 0;
k = (dev->regs[SCAT_VERSION] < 4) ? 0x40000 : 0x60000;
}
mem_mapping_set_addr(&dev->low_mapping[31], 0xf80000, k);
for (; i < 44; i++) {
mem_mapping_add(&dev->efff_mapping[i], 0x40000 + (i << 14), 0x4000,
for (; j < 44; j++) {
mem_mapping_add(&dev->efff_mapping[j], 0x40000 + (j << 14), 0x4000,
mem_read_scatb, mem_read_scatw, mem_read_scatl,
mem_write_scatb, mem_write_scatw, mem_write_scatl,
mem_size > (256 + (i << 4)) ? ram + 0x40000 + (i << 14) : NULL,
mem_size > (256 + (j << 4)) ? ram + 0x40000 + (j << 14) : NULL,
MEM_MAPPING_INTERNAL, &dev->null_page);
if (sx)
mem_mapping_enable(&dev->efff_mapping[i]);
mem_mapping_enable(&dev->efff_mapping[j]);
}
if (sx) {
for (i = 24; i < 32; i++) {
for (uint8_t i = 24; i < 32; i++) {
dev->page[i].valid = 1;
dev->page[i].regs_2x8 = 0xff;
dev->page[i].regs_2x9 = 0x03;
@@ -1471,7 +1494,7 @@ scat_init(const device_t *info)
mem_mapping_disable(&dev->ems_mapping[i]);
}
} else {
for (i = 0; i < 32; i++) {
for (uint8_t i = 0; i < 32; i++) {
dev->page[i].valid = 1;
dev->page[i].regs_2x8 = 0xff;
dev->page[i].regs_2x9 = 0x03;
@@ -1484,7 +1507,7 @@ scat_init(const device_t *info)
}
}
for (i = 0; i < 6; i++) {
for (uint8_t i = 0; i < 6; i++) {
mem_mapping_add(&dev->remap_mapping[i], 0x100000 + (i << 16), 0x10000,
mem_read_scatb, mem_read_scatw, mem_read_scatl,
mem_write_scatb, mem_write_scatw, mem_write_scatl,
@@ -1507,7 +1530,7 @@ scat_init(const device_t *info)
device_add(&port_92_device);
return (dev);
return dev;
}
const device_t scat_device = {

View File

@@ -32,6 +32,7 @@
#include <86box/hdc_ide.h>
#include <86box/hdc_ide_sff8038i.h>
#include <86box/pci.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/smram.h>
@@ -65,10 +66,13 @@ sis_5511_log(const char *fmt, ...)
#endif
typedef struct sis_5511_t {
uint8_t pci_conf[256], pci_conf_sb[2][256],
index, regs[16];
uint8_t pci_conf[256];
uint8_t pci_conf_sb[2][256];
uint8_t index;
uint8_t regs[16];
int nb_pci_slot, sb_pci_slot;
int nb_pci_slot;
int sb_pci_slot;
sff8038i_t *ide_drive[2];
smram_t *smram;
@@ -79,10 +83,10 @@ typedef struct sis_5511_t {
static void
sis_5511_shadow_recalc(sis_5511_t *dev)
{
int i, state;
int state;
uint32_t base;
for (i = 0x80; i <= 0x86; i++) {
for (uint8_t i = 0x80; i <= 0x86; i++) {
if (i == 0x86) {
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
@@ -121,6 +125,9 @@ sis_5511_smram_recalc(sis_5511_t *dev)
case 2:
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
break;
default:
break;
}
flushmmucache();
@@ -153,7 +160,7 @@ sis_5513_bm_handler(sis_5511_t *dev)
}
static void
sis_5511_write(int func, int addr, uint8_t val, void *priv)
sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv)
{
sis_5511_t *dev = (sis_5511_t *) priv;
@@ -331,12 +338,15 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
case 0x93: /* 5512 General Purpose Register Index */
dev->pci_conf[addr] = val;
break;
default:
break;
}
sis_5511_log("SiS 5511: dev->pci_conf[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80));
}
static uint8_t
sis_5511_read(int func, int addr, void *priv)
sis_5511_read(UNUSED(int func), int addr, void *priv)
{
sis_5511_t *dev = (sis_5511_t *) priv;
sis_5511_log("SiS 5511: dev->pci_conf[%02x] (%02x) POST %02x\n", addr, dev->pci_conf[addr], inb(0x80));
@@ -428,6 +438,9 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev)
case 0x6a: /* GPIO Status Register */
dev->pci_conf_sb[0][addr] &= val & 0x15;
break;
default:
break;
}
}
@@ -514,6 +527,9 @@ sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev)
case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */
dev->pci_conf_sb[1][addr] = val;
break;
default:
break;
}
}
@@ -528,6 +544,9 @@ sis_5513_write(int func, int addr, uint8_t val, void *priv)
case 1:
sis_5513_ide_write(addr, val, dev);
break;
default:
break;
}
sis_5511_log("SiS 5513: dev->pci_conf[%02x][%02x] = %02x POST: %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80));
}
@@ -567,6 +586,9 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv)
case 2:
cpu_set_isa_pci_div(3);
break;
default:
break;
}
break;
case 0x01:
@@ -587,9 +609,15 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv)
case 0x0b:
dev->regs[dev->index] = val;
break;
default:
break;
}
sis_5511_log("SiS 5513-ISA: dev->regs[%02x] = %02x POST: %02x\n", dev->index + 0x50, dev->regs[dev->index], inb(0x80));
break;
default:
break;
}
}
@@ -700,7 +728,7 @@ sis_5511_close(void *priv)
}
static void *
sis_5511_init(const device_t *info)
sis_5511_init(UNUSED(const device_t *info))
{
sis_5511_t *dev = (sis_5511_t *) malloc(sizeof(sis_5511_t));
memset(dev, 0, sizeof(sis_5511_t));

View File

@@ -29,6 +29,8 @@
#include <86box/dma.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/hdc_ide.h>
#include <86box/hdc_ide_sff8038i.h>
@@ -73,15 +75,19 @@ sis_5571_log(const char *fmt, ...)
#endif
typedef struct sis_5571_t {
uint8_t pci_conf[256], pci_conf_sb[3][256];
uint8_t pci_conf[256];
uint8_t pci_conf_sb[3][256];
int nb_pci_slot, sb_pci_slot;
int nb_pci_slot;
int sb_pci_slot;
port_92_t *port_92;
sff8038i_t *ide_drive[2];
smram_t *smram;
usb_t *usb;
usb_params_t usb_params;
} sis_5571_t;
static void
@@ -114,6 +120,9 @@ sis_5571_smm_recalc(sis_5571_t *dev)
case 0x03:
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0xa3] & 0x10), 1);
break;
default:
break;
}
flushmmucache();
@@ -146,7 +155,7 @@ sis_5571_bm_handler(sis_5571_t *dev)
}
static void
memory_pci_bridge_write(int func, int addr, uint8_t val, void *priv)
memory_pci_bridge_write(UNUSED(int func), int addr, uint8_t val, void *priv)
{
sis_5571_t *dev = (sis_5571_t *) priv;
@@ -321,12 +330,15 @@ memory_pci_bridge_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[addr] = val & 0xd0;
sis_5571_smm_recalc(dev);
break;
default:
break;
}
sis_5571_log("SiS5571: dev->pci_conf[%02x] = %02x\n", addr, val);
}
static uint8_t
memory_pci_bridge_read(int func, int addr, void *priv)
memory_pci_bridge_read(UNUSED(int func), int addr, void *priv)
{
sis_5571_t *dev = (sis_5571_t *) priv;
sis_5571_log("SiS5571: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]);
@@ -372,6 +384,9 @@ pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv)
case 2:
cpu_set_isa_pci_div(3);
break;
default:
break;
}
break;
@@ -495,6 +510,9 @@ pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv)
case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */
dev->pci_conf_sb[0][addr] = val;
break;
default:
break;
}
sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] = %02x\n", addr, val);
break;
@@ -574,6 +592,9 @@ pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv)
case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */
dev->pci_conf_sb[1][addr] = val;
break;
default:
break;
}
sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] = %02x\n", addr, val);
break;
@@ -612,8 +633,14 @@ pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv)
case 0x3c: /* Interrupt Line */
dev->pci_conf_sb[2][addr] = val;
break;
default:
break;
}
sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] = %02x\n", addr, val);
default:
break;
}
}
@@ -632,11 +659,49 @@ pci_isa_bridge_read(int func, int addr, void *priv)
case 2:
sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[2][addr]);
return dev->pci_conf_sb[2][addr];
default:
return 0xff;
}
}
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(UNUSED(usb_t* usb), UNUSED(void* priv))
{
/* Left unimplemented for now. */
return 1;
}
static void
sis_5571_reset(void *priv)
{
@@ -701,7 +766,7 @@ sis_5571_close(void *priv)
}
static void *
sis_5571_init(const device_t *info)
sis_5571_init(UNUSED(const device_t *info))
{
sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t));
memset(dev, 0x00, sizeof(sis_5571_t));
@@ -721,7 +786,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

@@ -10,18 +10,20 @@
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t cur_reg, tries,
regs[258];
typedef struct rabbit_t {
uint8_t cur_reg;
uint8_t tries;
uint8_t regs[258];
} rabbit_t;
static void
rabbit_recalcmapping(rabbit_t *dev)
{
uint32_t shread, shwrite;
uint32_t shread;
uint32_t shwrite;
uint32_t shflags = 0;
shread = !!(dev->regs[0x101] & 0x40);
@@ -63,6 +65,8 @@ rabbit_recalcmapping(rabbit_t *dev)
/* 128K at 0E0000-0FFFFF */
mem_set_mem_state(0x000e0000, 0x00020000, shflags);
break;
default:
break;
}
flushmmucache();
@@ -88,6 +92,8 @@ rabbit_write(uint16_t addr, uint8_t val, void *priv)
} else
dev->regs[dev->cur_reg] = val;
break;
default:
break;
}
}
@@ -105,6 +111,9 @@ rabbit_read(uint16_t addr, void *priv)
} else
ret = dev->regs[dev->cur_reg];
break;
default:
break;
}
return ret;
@@ -119,7 +128,7 @@ rabbit_close(void *priv)
}
static void *
rabbit_init(const device_t *info)
rabbit_init(UNUSED(const device_t *info))
{
rabbit_t *dev = (rabbit_t *) malloc(sizeof(rabbit_t));
memset(dev, 0, sizeof(rabbit_t));

View File

@@ -32,6 +32,7 @@
#include <86box/dma.h>
#include <86box/nvr.h>
#include <86box/pic.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/hdc_ide.h>
#include <86box/machine.h>
@@ -39,9 +40,10 @@
#include <86box/spd.h>
typedef struct sis_85c496_t {
uint8_t cur_reg, rmsmiblk_count,
regs[127],
pci_conf[256];
uint8_t cur_reg;
uint8_t rmsmiblk_count;
uint8_t regs[127];
uint8_t pci_conf[256];
smram_t *smram;
pc_timer_t rmsmiblk_timer;
port_92_t *port_92;
@@ -98,6 +100,8 @@ sis_85c497_isa_write(uint16_t port, uint8_t val, void *priv)
dev->regs[dev->cur_reg] = val & 0xfc;
dma_set_mask((val & 0x80) ? 0xffffffff : 0x00ffffff);
break;
default:
break;
}
}
@@ -121,12 +125,12 @@ static void
sis_85c496_recalcmapping(sis_85c496_t *dev)
{
uint32_t base;
uint32_t i, shflags = 0;
uint32_t shflags = 0;
shadowbios = 0;
shadowbios_write = 0;
for (i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
base = 0xc0000 + (i << 15);
if (dev->pci_conf[0x44] & (1 << i)) {
@@ -182,12 +186,15 @@ sis_85c496_ide_handler(sis_85c496_t *dev)
/* 00 - 3F = PCI Configuration, 40 - 7F = 85C496, 80 - FF = 85C497 */
static void
sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv)
sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
{
sis_85c496_t *dev = (sis_85c496_t *) priv;
uint8_t old, valxor;
uint8_t old;
uint8_t valxor;
uint8_t smm_irq[4] = { 10, 11, 12, 15 };
uint32_t host_base, ram_base, size;
uint32_t host_base;
uint32_t ram_base;
uint32_t size;
old = dev->pci_conf[addr];
valxor = (dev->pci_conf[addr]) ^ val;
@@ -252,7 +259,9 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv)
case 0x4d:
case 0x4e:
case 0x4f:
// dev->pci_conf[addr] = val;
#if 0
dev->pci_conf[addr] = val;
#endif
spd_write_drbs(dev->pci_conf, 0x48, 0x4f, 1);
break;
case 0x50:
@@ -318,6 +327,8 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv)
host_base = 0x000e0000;
ram_base = 0x000b0000;
break;
default:
break;
}
smram_enable(dev->smram, host_base, ram_base, size,
@@ -456,11 +467,14 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[addr] = val & 0x6e;
nvr_bank_set(0, !!(val & 0x40), dev->nvr);
break;
default:
break;
}
}
static uint8_t
sis_85c49x_pci_read(int func, int addr, void *priv)
sis_85c49x_pci_read(UNUSED(int func), int addr, void *priv)
{
sis_85c496_t *dev = (sis_85c496_t *) priv;
uint8_t ret = dev->pci_conf[addr];
@@ -478,6 +492,9 @@ sis_85c49x_pci_read(int func, int addr, void *priv)
case 0x83: /*Port 70h Mirror*/
ret = inb(0x70);
break;
default:
break;
}
sis_85c496_log("[%04X:%08X] PCI Read %02X from %02X:%02X\n", CS, cpu_state.pc, ret, func, addr);
@@ -526,7 +543,6 @@ static void
sis_85c496_reset(void *priv)
{
sis_85c496_t *dev = (sis_85c496_t *) priv;
int i;
sis_85c49x_pci_write(0, 0x44, 0x00, dev);
sis_85c49x_pci_write(0, 0x45, 0x00, dev);
@@ -535,7 +551,7 @@ sis_85c496_reset(void *priv)
sis_85c49x_pci_write(0, 0x5a, 0x00, dev);
// sis_85c49x_pci_write(0, 0x5a, 0x06, dev);
for (i = 0; i < 8; i++)
for (uint8_t i = 0; i < 8; i++)
sis_85c49x_pci_write(0, 0x48 + i, 0x00, dev);
sis_85c49x_pci_write(0, 0x80, 0x00, dev);
@@ -605,7 +621,9 @@ static void
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev);
// sis_85c497_isa_reset(dev);
#if 0
sis_85c497_isa_reset(dev);
#endif
dev->port_92 = device_add(&port_92_device);
port_92_set_period(dev->port_92, 2ULL * TIMER_USEC);

View File

@@ -28,6 +28,7 @@
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/mem.h>
#include <86box/smram.h>
@@ -35,14 +36,19 @@
#include <86box/machine.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t cur_reg, tries,
reg_base, reg_last,
reg_00, is_471,
force_flush, shadowed,
smram_enabled, pad,
regs[39], scratch[2];
typedef struct sis_85c4xx_t {
uint8_t cur_reg;
uint8_t tries;
uint8_t reg_base;
uint8_t reg_last;
uint8_t reg_00;
uint8_t is_471;
uint8_t force_flush;
uint8_t shadowed;
uint8_t smram_enabled;
uint8_t pad;
uint8_t regs[39];
uint8_t scratch[2];
uint32_t mem_state[8];
smram_t *smram;
port_92_t *port_92;
@@ -62,10 +68,13 @@ sis_85c4xx_recalcremap(sis_85c4xx_t *dev)
static void
sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
{
uint32_t base, n = 0;
uint32_t i, shflags = 0;
uint32_t readext, writeext;
uint8_t romcs = 0xc0, cur_romcs;
uint32_t base;
uint32_t n = 0;
uint32_t shflags = 0;
uint32_t readext;
uint32_t writeext;
uint8_t romcs = 0xc0;
uint8_t cur_romcs;
dev->shadowed = 0x00;
@@ -79,7 +88,7 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
if (dev->regs[0x08] & 0x04)
romcs |= 0x02;
for (i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
base = 0xc0000 + (i << 15);
cur_romcs = romcs & (1 << i);
readext = cur_romcs ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
@@ -121,7 +130,7 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
}
static void
sis_85c4xx_sw_smi_out(uint16_t port, uint8_t val, void *priv)
sis_85c4xx_sw_smi_out(UNUSED(uint16_t port), UNUSED(uint8_t val), void *priv)
{
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
@@ -155,7 +164,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
uint8_t rel_reg = dev->cur_reg - dev->reg_base;
uint8_t valxor = 0x00;
uint32_t host_base = 0x000e0000, ram_base = 0x000a0000;
uint32_t host_base = 0x000e0000;
uint32_t ram_base = 0x000a0000;
switch (port) {
case 0x22:
@@ -231,6 +241,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
port_92_add(dev->port_92);
}
break;
default:
break;
}
} else if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x00))
dev->reg_00 = val;
@@ -241,6 +253,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
case 0xe2:
dev->scratch[port - 0xe1] = val;
return;
default:
break;
}
}
@@ -269,6 +283,10 @@ sis_85c4xx_in(uint16_t port, void *priv)
case 0xe1:
case 0xe2:
ret = dev->scratch[port - 0xe1];
break;
default:
break;
}
return ret;

View File

@@ -29,6 +29,9 @@
#include <86box/timer.h>
#include <86box/apm.h>
#include <86box/machine.h>
#include <86box/pic.h>
#include <86box/plat_unused.h>
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pci.h>
@@ -55,9 +58,10 @@ sis_85c50x_log(const char *fmt, ...)
#endif
typedef struct sis_85c50x_t {
uint8_t index,
pci_conf[256], pci_conf_sb[256],
regs[256];
uint8_t index;
uint8_t pci_conf[256];
uint8_t pci_conf_sb[256];
uint8_t regs[256];
smram_t *smram[2];
port_92_t *port_92;
@@ -66,7 +70,9 @@ typedef struct sis_85c50x_t {
static void
sis_85c50x_shadow_recalc(sis_85c50x_t *dev)
{
uint32_t base, i, can_read, can_write;
uint32_t base;
uint32_t can_read;
uint32_t can_write;
can_read = (dev->pci_conf[0x53] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
can_write = (dev->pci_conf[0x53] & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
@@ -77,7 +83,7 @@ sis_85c50x_shadow_recalc(sis_85c50x_t *dev)
shadowbios = 1;
shadowbios_write = 1;
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
base = 0xe0000 + (i << 14);
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x54] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
base = 0xd0000 + (i << 14);
@@ -129,95 +135,101 @@ sis_85c50x_smm_recalc(sis_85c50x_t *dev)
smram_enable(dev->smram[0], host_base, 0xb0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
break;
default:
break;
}
}
static void
sis_85c50x_write(int func, int addr, uint8_t val, void *priv)
{
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
sis_85c50x_log("85C501: [W] (%02X, %02X) = %02X\n", func, addr, val);
if (func == 0x00) switch (addr) {
case 0x04: /* Command - low byte */
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xb4) | (val & 0x4b);
break;
case 0x07: /* Status - high byte */
dev->pci_conf[addr] = ((dev->pci_conf[addr] & 0xf9) & ~(val & 0xf8)) | (val & 0x06);
break;
case 0x50:
dev->pci_conf[addr] = val;
break;
case 0x51: /* Cache */
dev->pci_conf[addr] = val;
cpu_cache_ext_enabled = (val & 0x40);
cpu_update_waitstates();
break;
case 0x52:
dev->pci_conf[addr] = val;
break;
case 0x53: /* Shadow RAM */
case 0x54:
case 0x55:
case 0x56:
dev->pci_conf[addr] = val;
sis_85c50x_shadow_recalc(dev);
if (addr == 0x54)
if (func == 0x00)
switch (addr) {
case 0x04: /* Command - low byte */
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xb4) | (val & 0x4b);
break;
case 0x07: /* Status - high byte */
dev->pci_conf[addr] = ((dev->pci_conf[addr] & 0xf9) & ~(val & 0xf8)) | (val & 0x06);
break;
case 0x50:
dev->pci_conf[addr] = val;
break;
case 0x51: /* Cache */
dev->pci_conf[addr] = val;
cpu_cache_ext_enabled = (val & 0x40);
cpu_update_waitstates();
break;
case 0x52:
dev->pci_conf[addr] = val;
break;
case 0x53: /* Shadow RAM */
case 0x54:
case 0x55:
case 0x56:
dev->pci_conf[addr] = val;
sis_85c50x_shadow_recalc(dev);
if (addr == 0x54)
sis_85c50x_smm_recalc(dev);
break;
case 0x57:
case 0x58:
case 0x59:
case 0x5a:
case 0x5c:
case 0x5d:
case 0x5e:
case 0x61:
case 0x62:
case 0x63:
case 0x67:
case 0x68:
case 0x6a:
case 0x6b:
case 0x6c:
case 0x6d:
case 0x6e:
case 0x6f:
dev->pci_conf[addr] = val;
break;
case 0x5f:
dev->pci_conf[addr] = val & 0xfe;
break;
case 0x5b:
dev->pci_conf[addr] = val;
break;
case 0x60: /* SMI */
if ((dev->pci_conf[0x68] & 0x01) && !(dev->pci_conf[addr] & 0x02) && (val & 0x02)) {
dev->pci_conf[0x69] |= 0x01;
smi_raise();
}
dev->pci_conf[addr] = val & 0x3e;
break;
case 0x64: /* SMRAM */
case 0x65:
dev->pci_conf[addr] = val;
sis_85c50x_smm_recalc(dev);
break;
case 0x57:
case 0x58:
case 0x59:
case 0x5a:
case 0x5c:
case 0x5d:
case 0x5e:
case 0x61:
case 0x62:
case 0x63:
case 0x67:
case 0x68:
case 0x6a:
case 0x6b:
case 0x6c:
case 0x6d:
case 0x6e:
case 0x6f:
dev->pci_conf[addr] = val;
break;
case 0x5f:
dev->pci_conf[addr] = val & 0xfe;
break;
case 0x5b:
dev->pci_conf[addr] = val;
break;
case 0x60: /* SMI */
if ((dev->pci_conf[0x68] & 0x01) && !(dev->pci_conf[addr] & 0x02) && (val & 0x02)) {
dev->pci_conf[0x69] |= 0x01;
smi_raise();
}
dev->pci_conf[addr] = val & 0x3e;
break;
case 0x64: /* SMRAM */
case 0x65:
dev->pci_conf[addr] = val;
sis_85c50x_smm_recalc(dev);
break;
case 0x66:
dev->pci_conf[addr] = (val & 0x7f);
break;
case 0x69:
dev->pci_conf[addr] &= ~(val);
break;
}
break;
case 0x66:
dev->pci_conf[addr] = (val & 0x7f);
break;
case 0x69:
dev->pci_conf[addr] &= ~val;
break;
default:
break;
}
}
static uint8_t
sis_85c50x_read(int func, int addr, void *priv)
{
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
uint8_t ret = 0xff;
uint8_t ret = 0xff;
if (func == 0x00)
ret = dev->pci_conf[addr];
@@ -234,41 +246,45 @@ sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv)
sis_85c50x_log("85C503: [W] (%02X, %02X) = %02X\n", func, addr, val);
if (func == 0x00) switch (addr) {
case 0x04: /* Command */
dev->pci_conf_sb[addr] = val & 0x0f;
break;
case 0x07: /* Status */
dev->pci_conf_sb[addr] &= ~(val & 0x30);
break;
case 0x40: /* BIOS Control Register */
dev->pci_conf_sb[addr] = val & 0x3f;
break;
case 0x41:
case 0x42:
case 0x43:
case 0x44:
/* INTA/B/C/D# Remapping Control Register */
dev->pci_conf_sb[addr] = val & 0x8f;
if (val & 0x80)
pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf);
break;
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
dev->pci_conf_sb[addr] = val;
break;
}
if (func == 0x00)
switch (addr) {
case 0x04: /* Command */
dev->pci_conf_sb[addr] = val & 0x0f;
break;
case 0x07: /* Status */
dev->pci_conf_sb[addr] &= ~(val & 0x30);
break;
case 0x40: /* BIOS Control Register */
dev->pci_conf_sb[addr] = val & 0x3f;
break;
case 0x41:
case 0x42:
case 0x43:
case 0x44:
/* INTA/B/C/D# Remapping Control Register */
dev->pci_conf_sb[addr] = val & 0x8f;
if (val & 0x80)
pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf);
break;
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
dev->pci_conf_sb[addr] = val;
break;
default:
break;
}
}
static uint8_t
sis_85c50x_sb_read(int func, int addr, void *priv)
{
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
uint8_t ret = 0xff;
uint8_t ret = 0xff;
if (func == 0x00)
ret = dev->pci_conf_sb[addr];
@@ -308,8 +324,14 @@ sis_85c50x_isa_write(uint16_t addr, uint8_t val, void *priv)
case 0x85:
outb(0x70, val);
break;
default:
break;
}
break;
default:
break;
}
}
@@ -330,6 +352,9 @@ sis_85c50x_isa_read(uint16_t addr, void *priv)
else
ret = dev->regs[dev->index];
break;
default:
break;
}
sis_85c50x_log("85C503 ISA: [R] (%04X) = %02X\n", addr, ret);
@@ -395,7 +420,7 @@ sis_85c50x_close(void *priv)
}
static void *
sis_85c50x_init(const device_t *info)
sis_85c50x_init(UNUSED(const device_t *info))
{
sis_85c50x_t *dev = (sis_85c50x_t *) malloc(sizeof(sis_85c50x_t));
memset(dev, 0x00, sizeof(sis_85c50x_t));

View File

@@ -30,6 +30,7 @@
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/device.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/usb.h>
#include <86box/hdc_ide.h>
@@ -65,7 +66,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 {
@@ -100,15 +105,15 @@ stpc_log(const char *fmt, ...)
static void
stpc_recalcmapping(stpc_t *dev)
{
uint8_t reg, bitpair;
uint32_t base, size;
uint32_t base;
uint32_t size;
int state;
shadowbios = 0;
shadowbios_write = 0;
for (reg = 0; reg <= 3; reg++) {
for (bitpair = 0; bitpair <= ((reg == 3) ? 0 : 3); bitpair++) {
for (uint8_t reg = 0; reg <= 3; reg++) {
for (uint8_t bitpair = 0; bitpair <= ((reg == 3) ? 0 : 3); bitpair++) {
if (reg == 3) {
size = 0x10000;
base = 0xf0000;
@@ -244,6 +249,9 @@ stpc_nb_write(int func, int addr, uint8_t val, void *priv)
case 0x52:
val &= 0x70;
break;
default:
break;
}
dev->pci_conf[0][addr] = val;
@@ -267,7 +275,8 @@ stpc_nb_read(int func, int addr, void *priv)
static void
stpc_ide_handlers(stpc_t *dev, int bus)
{
uint16_t main, side;
uint16_t main;
uint16_t side;
if (bus & 0x01) {
ide_pri_disable();
@@ -427,6 +436,9 @@ stpc_ide_write(int func, int addr, uint8_t val, void *priv)
sff_bus_master_set_irq(0x00, dev->bm[1]);
}
break;
default:
break;
}
}
@@ -484,6 +496,9 @@ stpc_isab_write(int func, int addr, uint8_t val, void *priv)
case 0x05:
val &= 0x01;
break;
default:
break;
}
dev->pci_conf[1][addr] = val;
@@ -546,6 +561,8 @@ stpc_usb_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[3][addr] = val;
ohci_update_mem_mapping(dev->usb, dev->pci_conf[3][0x11], dev->pci_conf[3][0x12], dev->pci_conf[3][0x13], 1);
break;
default:
break;
}
dev->pci_conf[3][addr] = val;
@@ -603,8 +620,10 @@ stpc_serial_handlers(uint8_t val)
return 0;
}
uint16_t uart0_io = 0x3f8, uart1_io = 0x3f8;
uint8_t uart0_irq = 4, uart1_irq = 3;
uint16_t uart0_io = 0x3f8;
uint16_t uart1_io = 0x3f8;
uint8_t uart0_irq = 4;
uint8_t uart1_irq = 3;
if (val & 0x10)
uart1_io &= 0xfeff;
@@ -713,6 +732,9 @@ stpc_reg_write(uint16_t addr, uint8_t val, void *priv)
val &= 0xf1;
stpc_serial_handlers(val);
break;
default:
break;
}
dev->regs[dev->reg_offset] = val;
@@ -870,6 +892,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 +928,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);
@@ -935,7 +972,7 @@ stpc_serial_close(void *priv)
}
static void *
stpc_serial_init(const device_t *info)
stpc_serial_init(UNUSED(const device_t *info))
{
stpc_log("STPC: serial_init()\n");
@@ -953,7 +990,8 @@ stpc_serial_init(const device_t *info)
static void
stpc_lpt_handlers(stpc_lpt_t *dev, uint8_t val)
{
uint8_t old_addr = (dev->reg1 & 0x03), new_addr = (val & 0x03);
uint8_t old_addr = (dev->reg1 & 0x03);
uint8_t new_addr = (val & 0x03);
switch (old_addr) {
case 0x1:
@@ -967,6 +1005,8 @@ stpc_lpt_handlers(stpc_lpt_t *dev, uint8_t val)
case 0x3:
lpt2_remove();
break;
default:
break;
}
switch (new_addr) {
@@ -1045,7 +1085,7 @@ stpc_lpt_close(void *priv)
}
static void *
stpc_lpt_init(const device_t *info)
stpc_lpt_init(UNUSED(const device_t *info))
{
stpc_log("STPC: lpt_init()\n");

View File

@@ -121,10 +121,10 @@ umc_8886_log(const char *fmt, ...)
#define SB_ID dev->sb_id
typedef struct umc_8886_t {
uint8_t max_func, /* Last function number */
pci_conf_sb[2][256]; /* PCI Registers */
uint16_t sb_id; /* Southbridge Revision */
int has_ide; /* Check if Southbridge Revision is AF or F */
uint8_t max_func; /* Last function number */
uint8_t pci_conf_sb[2][256]; /* PCI Registers */
uint16_t sb_id; /* Southbridge Revision */
int has_ide; /* Check if Southbridge Revision is AF or F */
} umc_8886_t;
static void
@@ -212,6 +212,8 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
case 2:
cpu_set_isa_pci_div(2);
break;
default:
break;
}
break;
@@ -250,6 +252,9 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
case 0xa5 ... 0xa8:
dev->pci_conf_sb[func][addr] = val;
break;
default:
break;
}
break;
@@ -271,8 +276,13 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
case 0x41:
dev->pci_conf_sb[func][addr] = val;
break;
default:
break;
}
break;
default:
break;
}
}
@@ -339,7 +349,7 @@ umc_8886_reset(void *priv)
umc_8886_ide_handler(1);
}
for (int i = 1; i < 5; i++) /* Disable all IRQ interrupts */
for (uint8_t i = 1; i < 5; i++) /* Disable all IRQ interrupts */
pci_set_irq_routing(i, PCI_IRQ_DISABLED);
cpu_set_isa_pci_div(3);

View File

@@ -106,6 +106,7 @@
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/smram.h>
@@ -142,9 +143,10 @@ hb4_log(const char *fmt, ...)
#endif
typedef struct hb4_t {
uint8_t shadow,
shadow_read, shadow_write,
pci_conf[256]; /* PCI Registers */
uint8_t shadow;
uint8_t shadow_read;
uint8_t shadow_write;
uint8_t pci_conf[256]; /* PCI Registers */
int mem_state[9];
smram_t *smram[3]; /* SMRAM Handlers */
} hb4_t;
@@ -191,10 +193,10 @@ hb4_shadow_bios_low(hb4_t *dev)
int
hb4_shadow_main(hb4_t *dev)
{
int i, state;
int state;
int n = 0;
for (i = 0; i < 6; i++) {
for (uint8_t i = 0; i < 6; i++) {
state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> (i + 2)) & 0x01)] | shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
if (state != dev->mem_state[i + 1]) {
@@ -261,7 +263,7 @@ hb4_smram(hb4_t *dev)
}
static void
hb4_write(int func, int addr, uint8_t val, void *priv)
hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv)
{
hb4_t *dev = (hb4_t *) priv;
@@ -322,6 +324,9 @@ hb4_write(int func, int addr, uint8_t val, void *priv)
case 0x61:
dev->pci_conf[addr] = val;
break;
default:
break;
}
}
@@ -383,7 +388,7 @@ hb4_close(void *priv)
}
static void *
hb4_init(const device_t *info)
hb4_init(UNUSED(const device_t *info))
{
hb4_t *dev = (hb4_t *) malloc(sizeof(hb4_t));
memset(dev, 0, sizeof(hb4_t));

View File

@@ -69,6 +69,8 @@ apollo_map(uint32_t addr, uint32_t size, int state)
case 3:
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
default:
break;
}
flushmmucache_nopc();
@@ -392,8 +394,8 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
smram_disable_all();
if (dev->id >= VIA_691)
switch (val & 0x03) {
case 0x00:
default:
case 0x00:
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0); /* Non-SMM: Code PCI, Data PCI */
break;
@@ -412,8 +414,8 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
}
else if (dev->id >= VIA_597)
switch (val & 0x03) {
case 0x00:
default:
case 0x00:
/* Disable SMI Address Redirection (default) */
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 0);
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0);
@@ -458,6 +460,9 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 3);
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 3);
break;
default:
break;
}
break;
case 0x65:
@@ -532,7 +537,7 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x70:
if ((dev->id >= VIA_693A))
if (dev->id >= VIA_693A)
dev->pci_conf[0x70] = (dev->pci_conf[0x70] & ~0xdf) | (val & 0xdf);
else if (dev->id == VIA_597)
dev->pci_conf[0x70] = (dev->pci_conf[0x70] & ~0xf1) | (val & 0xf1);
@@ -673,6 +678,8 @@ via_apollo_read(int func, int addr, void *priv)
case 0:
ret = dev->pci_conf[addr];
break;
default:
break;
}
return ret;
@@ -685,6 +692,8 @@ via_apollo_write(int func, int addr, uint8_t val, void *priv)
case 0:
via_apollo_host_bridge_write(func, addr, val, priv);
break;
default:
break;
}
}
@@ -728,6 +737,9 @@ via_apollo_init(const device_t *info)
case VIA_694:
device_add(&via_mvp3_agp_device);
break;
default:
break;
}
if (dev->id >= VIA_597)

View File

@@ -41,6 +41,7 @@
#include <86box/ddma.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
@@ -59,13 +60,15 @@
/* Most revision numbers (PCI-ISA bridge or otherwise) were lifted from PCI device
listings on forums, as VIA's datasheets are not very helpful regarding those. */
#define VIA_PIPC_586A 0x05862500
#define VIA_PIPC_586B 0x05864700
#define VIA_PIPC_596A 0x05960900
#define VIA_PIPC_596B 0x05962300
#define VIA_PIPC_686A 0x06861400
#define VIA_PIPC_686B 0x06864000
#define VIA_PIPC_8231 0x82311000
#define VIA_PIPC_586A 0x05862500
#define VIA_PIPC_586B 0x05864700
#define VIA_PIPC_596A 0x05960900
#define VIA_PIPC_596B 0x05962300
#define VIA_PIPC_686A 0x06861400
#define VIA_PIPC_686B 0x06864000
#define VIA_PIPC_8231 0x82311000
#define VIA_PIPC_FM_EMULATION 1
enum {
TRAP_DRQ = 0,
@@ -107,22 +110,28 @@ enum {
typedef struct {
struct _pipc_ *dev;
void *trap;
uint32_t *sts_reg, *en_reg, mask;
uint32_t *sts_reg;
uint32_t *en_reg;
uint32_t mask;
} pipc_io_trap_t;
typedef struct _pipc_ {
uint32_t local;
uint8_t max_func, max_pcs;
uint8_t max_func;
uint8_t max_pcs;
uint8_t pci_isa_regs[256],
ide_regs[256],
usb_regs[2][256],
power_regs[256],
ac97_regs[2][256], fmnmi_regs[4];
uint8_t pci_isa_regs[256];
uint8_t ide_regs[256];
uint8_t usb_regs[2][256];
uint8_t power_regs[256];
uint8_t ac97_regs[2][256];
uint8_t fmnmi_regs[4];
uint8_t fmnmi_status;
sff8038i_t *bm[2];
nvr_t *nvr;
int nvr_enabled, slot;
int nvr_enabled;
int slot;
ddma_t *ddma;
smbus_piix4_t *smbus;
usb_t *usb[2];
@@ -130,9 +139,14 @@ typedef struct _pipc_ {
acpi_t *acpi;
pipc_io_trap_t io_traps[TRAP_MAX];
void *gameport, *ac97, *sio, *hwm;
void *gameport;
void *ac97;
void *sio;
void *hwm;
sb_t *sb;
uint16_t midigame_base, sb_base, fmnmi_base;
uint16_t midigame_base;
uint16_t sb_base;
uint16_t fmnmi_base;
} pipc_t;
#ifdef ENABLE_PIPC_LOG
@@ -160,7 +174,7 @@ static uint8_t pipc_read(int func, int addr, void *priv);
static void pipc_write(int func, int addr, uint8_t val, void *priv);
static void
pipc_io_trap_pact(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
pipc_io_trap_pact(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), void *priv)
{
pipc_io_trap_t *trap = (pipc_io_trap_t *) priv;
@@ -173,7 +187,7 @@ pipc_io_trap_pact(int size, uint16_t addr, uint8_t write, uint8_t val, void *pri
}
static void
pipc_io_trap_glb(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
pipc_io_trap_glb(UNUSED(int size), UNUSED(uint16_t addr), uint8_t write, UNUSED(uint8_t val), void *priv)
{
pipc_io_trap_t *trap = (pipc_io_trap_t *) priv;
@@ -330,6 +344,8 @@ pipc_reset_hard(void *priv)
case VIA_PIPC_8231:
dev->usb_regs[i][0x08] = 0x1e;
break;
default:
break;
}
dev->usb_regs[i][0x0a] = 0x03;
@@ -390,6 +406,9 @@ pipc_reset_hard(void *priv)
case VIA_PIPC_686B:
dev->power_regs[0x08] = 0x40;
break;
default:
break;
}
if (dev->local == VIA_PIPC_686B)
dev->power_regs[0x34] = 0x68;
@@ -451,6 +470,9 @@ pipc_reset_hard(void *priv)
case VIA_PIPC_8231:
dev->ac97_regs[i][0x08] = (i == 0) ? 0x40 : 0x20;
break;
default:
break;
}
if (i == 0) {
@@ -508,7 +530,8 @@ pipc_reset_hard(void *priv)
static void
pipc_ide_handlers(pipc_t *dev)
{
uint16_t main, side;
uint16_t main;
uint16_t side;
ide_pri_disable();
ide_sec_disable();
@@ -571,10 +594,14 @@ pipc_bus_master_handlers(pipc_t *dev)
static void
pipc_pcs_update(pipc_t *dev)
{
uint8_t i, io_base_reg, io_mask_reg, io_mask_shift, enable;
uint16_t io_base, io_mask;
uint8_t io_base_reg;
uint8_t io_mask_reg;
uint8_t io_mask_shift;
uint8_t enable;
uint16_t io_base;
uint16_t io_mask;
for (i = 0; i <= dev->max_pcs; i++) {
for (uint8_t i = 0; i <= dev->max_pcs; i++) {
if (i & 2) {
io_base_reg = 0x8c;
io_mask_reg = 0x8a;
@@ -648,7 +675,6 @@ static void
pipc_trap_update_596(void *priv)
{
pipc_t *dev = (pipc_t *) priv;
int i;
/* TRAP_DRQ (00000001) and TRAP_PIRQ (00000002) not implemented. */
@@ -679,7 +705,7 @@ pipc_trap_update_596(void *priv)
by the Positive Decoding Control registers. I couldn't probe this behavior on hardware.
It's better to be safe and cover all of them than to assume Intel-like behavior (one range). */
for (i = 0; i < 3; i++) {
for (uint8_t i = 0; i < 3; i++) {
pipc_trap_update_paden(dev, TRAP_AUD_MIDI_0 + i,
0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x01),
0x300 + (0x10 * i), 4);
@@ -760,10 +786,10 @@ pipc_fmnmi_handlers(pipc_t *dev, uint8_t modem)
static uint8_t
pipc_fm_read(uint16_t addr, void *priv)
{
#ifdef VIA_PIPC_FM_EMULATION
uint8_t ret = 0x00;
#else
pipc_t *dev = (pipc_t *) priv;
#ifdef VIA_PIPC_FM_EMULATION
uint8_t ret = ((addr & 0x03) == 0x00) ? dev->fmnmi_status : 0x00;
#else
uint8_t ret = dev->sb->opl.read(addr, dev->sb->opl.priv);
#endif
@@ -784,12 +810,26 @@ pipc_fm_write(uint16_t addr, uint8_t val, void *priv)
index port, and only fires NMI/SMI when writing to the data port. */
if (!(addr & 0x01)) {
dev->fmnmi_regs[0x00] = (addr & 0x02) ? 0x02 : 0x01;
dev->fmnmi_regs[0x01] = val;
} else {
dev->fmnmi_regs[0x02] = val;
} else {
dev->fmnmi_regs[0x01] = val;
/* TODO: Probe how real hardware handles OPL timers. This assumed implementation
just sets the relevant interrupt flags as soon as a timer is started. */
if (!(addr & 0x02) && (dev->fmnmi_regs[0x02] == 0x04)) {
if (val & 0x80)
dev->fmnmi_status = 0x00;
if ((val & 0x41) == 0x01)
dev->fmnmi_status |= 0x40;
if ((val & 0x22) == 0x02)
dev->fmnmi_status |= 0x20;
if (dev->fmnmi_status & 0x60)
dev->fmnmi_status |= 0x80;
}
/* Fire NMI/SMI if enabled. */
if (dev->ac97_regs[0][0x48] & 0x01) {
pipc_log("PIPC: Raising %s\n", (dev->ac97_regs[0][0x48] & 0x04) ? "SMI" : "NMI");
if (dev->ac97_regs[0][0x48] & 0x04)
smi_raise();
else
@@ -1047,6 +1087,10 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x44:
dev->pci_isa_regs[0x44] = val;
break;
case 0x47:
if (val & 0x01)
trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL);
@@ -1138,7 +1182,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
case 0x71:
case 0x72:
case 0x73:
dev->pci_isa_regs[(addr - 0x44)] = val;
dev->pci_isa_regs[addr - 0x44] = val;
break;
case 0x74:
@@ -1408,7 +1452,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
case 0x61:
case 0x62:
case 0x63:
dev->power_regs[(addr - 0x58)] = val;
dev->power_regs[addr - 0x58] = val;
break;
case 0x70:
@@ -1543,33 +1587,36 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
}
static void
pipc_reset(void *p)
pipc_reset(void *priv)
{
pipc_t *dev = (pipc_t *) p;
pipc_t *dev = (pipc_t *) priv;
uint8_t pm_func = dev->usb[1] ? 4 : 3;
pipc_write(pm_func, 0x41, 0x00, p);
pipc_write(pm_func, 0x48, 0x01, p);
pipc_write(pm_func, 0x49, 0x00, p);
pipc_write(pm_func, 0x41, 0x00, priv);
pipc_write(pm_func, 0x48, 0x01, priv);
pipc_write(pm_func, 0x49, 0x00, priv);
pipc_write(1, 0x04, 0x80, p);
pipc_write(1, 0x09, 0x85, p);
pipc_write(1, 0x10, 0xf1, p);
pipc_write(1, 0x11, 0x01, p);
pipc_write(1, 0x14, 0xf5, p);
pipc_write(1, 0x15, 0x03, p);
pipc_write(1, 0x18, 0x71, p);
pipc_write(1, 0x19, 0x01, p);
pipc_write(1, 0x1c, 0x75, p);
pipc_write(1, 0x1d, 0x03, p);
pipc_write(1, 0x20, 0x01, p);
pipc_write(1, 0x21, 0xcc, p);
pipc_write(1, 0x04, 0x80, priv);
pipc_write(1, 0x09, 0x85, priv);
pipc_write(1, 0x10, 0xf1, priv);
pipc_write(1, 0x11, 0x01, priv);
pipc_write(1, 0x14, 0xf5, priv);
pipc_write(1, 0x15, 0x03, priv);
pipc_write(1, 0x18, 0x71, priv);
pipc_write(1, 0x19, 0x01, priv);
pipc_write(1, 0x1c, 0x75, priv);
pipc_write(1, 0x1d, 0x03, priv);
pipc_write(1, 0x20, 0x01, priv);
pipc_write(1, 0x21, 0xcc, priv);
if (dev->local <= VIA_PIPC_586B)
pipc_write(1, 0x40, 0x04, p);
pipc_write(1, 0x40, 0x04, priv);
else
pipc_write(1, 0x40, 0x00, p);
pipc_write(1, 0x40, 0x00, priv);
pipc_write(0, 0x77, 0x00, p);
if (dev->local < VIA_PIPC_586B)
pipc_write(0, 0x44, 0x00, priv);
pipc_write(0, 0x77, 0x00, priv);
}
static void *
@@ -1655,13 +1702,13 @@ pipc_init(const device_t *info)
}
static void
pipc_close(void *p)
pipc_close(void *priv)
{
pipc_t *dev = (pipc_t *) p;
pipc_t *dev = (pipc_t *) priv;
pipc_log("PIPC: close()\n");
for (int i = 0; i < TRAP_MAX; i++)
for (uint8_t i = 0; i < TRAP_MAX; i++)
io_trap_remove(dev->io_traps[i].trap);
free(dev);

View File

@@ -35,13 +35,14 @@
#include <86box/port_92.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t has_ide, index,
regs[256];
typedef struct vt82c49x_t {
uint8_t has_ide;
uint8_t index;
uint8_t regs[256];
smram_t *smram_smm, *smram_low,
*smram_high;
smram_t *smram_smm;
smram_t *smram_low;
smram_t *smram_high;
} vt82c49x_t;
#ifdef ENABLE_VT82C49X_LOG
@@ -65,9 +66,11 @@ vt82c49x_log(const char *fmt, ...)
static void
vt82c49x_recalc(vt82c49x_t *dev)
{
int i, relocate;
uint8_t reg, bit;
uint32_t base, state;
int relocate;
uint8_t reg;
uint8_t bit;
uint32_t base;
uint32_t state;
uint32_t shadow_bitmap = 0x00000000;
relocate = (dev->regs[0x33] >> 2) & 0x03;
@@ -75,7 +78,7 @@ vt82c49x_recalc(vt82c49x_t *dev)
shadowbios = 0;
shadowbios_write = 0;
for (i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
base = 0xc0000 + (i << 14);
reg = 0x30 + (i >> 2);
bit = (i & 3) << 1;
@@ -120,7 +123,7 @@ vt82c49x_recalc(vt82c49x_t *dev)
mem_set_mem_state_both(base, 0x4000, state);
}
for (i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
base = 0xe0000 + (i << 15);
bit = 6 - (i & 2);
@@ -186,6 +189,8 @@ vt82c49x_recalc(vt82c49x_t *dev)
if (!shadow_bitmap)
mem_remap_top(384);
break;
default:
break;
}
}
@@ -277,8 +282,14 @@ vt82c49x_write(uint16_t addr, uint8_t val, void *priv)
(val & 0x40) ? "second" : "prim");
}
break;
default:
break;
}
break;
default:
break;
}
}
@@ -300,6 +311,9 @@ vt82c49x_read(uint16_t addr, void *priv)
else if (dev->index < 0x80)
ret = dev->regs[dev->index];
break;
default:
break;
}
return ret;
@@ -308,9 +322,7 @@ vt82c49x_read(uint16_t addr, void *priv)
static void
vt82c49x_reset(void *priv)
{
uint16_t i;
for (i = 0; i < 256; i++)
for (uint16_t i = 0; i < 256; i++)
vt82c49x_write(i, 0x00, priv);
}

View File

@@ -26,6 +26,7 @@
#include <86box/io.h>
#include <86box/pic.h>
#include <86box/pci.h>
#include <86box/plat_unused.h>
#include <86box/device.h>
#include <86box/chipset.h>
@@ -116,6 +117,9 @@ vt82c505_write(int func, int addr, uint8_t val, void *priv)
case 0x93:
dev->pci_conf[addr] = val & 0xe0;
break;
default:
break;
}
}
@@ -160,12 +164,11 @@ static void
vt82c505_reset(void *priv)
{
vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t));
int i;
dev->pci_conf[0x04] = 0x07;
dev->pci_conf[0x07] = 0x00;
for (i = 0x80; i <= 0x9f; i++) {
for (uint8_t i = 0x80; i <= 0x9f; i++) {
switch (i) {
case 0x81:
vt82c505_write(0, i, 0x01, priv);
@@ -195,7 +198,7 @@ vt82c505_close(void *priv)
}
static void *
vt82c505_init(const device_t *info)
vt82c505_init(UNUSED(const device_t *info))
{
vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t));
memset(dev, 0, sizeof(vt82c505_t));

View File

@@ -29,9 +29,9 @@
#include <86box/port_92.h>
#include <86box/chipset.h>
typedef struct {
uint8_t idx,
regs[256];
typedef struct vl82c480_t {
uint8_t idx;
uint8_t regs[256];
} vl82c480_t;
static int
@@ -40,8 +40,8 @@ vl82c480_shflags(uint8_t access)
int ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
switch (access) {
case 0x00:
default:
case 0x00:
ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
break;
case 0x01:
@@ -61,15 +61,14 @@ vl82c480_shflags(uint8_t access)
static void
vl82c480_recalc(vl82c480_t *dev)
{
int i, j;
uint32_t base;
uint8_t access;
shadowbios = 0;
shadowbios_write = 0;
for (i = 0; i < 6; i++) {
for (j = 0; j < 8; j += 2) {
for (uint8_t i = 0; i < 6; i++) {
for (uint8_t j = 0; j < 8; j += 2) {
base = 0x000a0000 + (i << 16) + (j << 13);
access = (dev->regs[0x0d + i] >> j) & 3;
mem_set_mem_state(base, 0x4000, vl82c480_shflags(access));
@@ -82,9 +81,9 @@ vl82c480_recalc(vl82c480_t *dev)
}
static void
vl82c480_write(uint16_t addr, uint8_t val, void *p)
vl82c480_write(uint16_t addr, uint8_t val, void *priv)
{
vl82c480_t *dev = (vl82c480_t *) p;
vl82c480_t *dev = (vl82c480_t *) priv;
switch (addr) {
case 0xec:
@@ -126,13 +125,16 @@ vl82c480_write(uint16_t addr, uint8_t val, void *p)
if (mem_a20_alt)
outb(0x92, inb(0x92) & ~2);
break;
default:
break;
}
}
static uint8_t
vl82c480_read(uint16_t addr, void *p)
vl82c480_read(uint16_t addr, void *priv)
{
vl82c480_t *dev = (vl82c480_t *) p;
vl82c480_t *dev = (vl82c480_t *) priv;
uint8_t ret = 0xff;
switch (addr) {
@@ -153,15 +155,18 @@ vl82c480_read(uint16_t addr, void *p)
softresetx86();
cpu_set_edx();
break;
default:
break;
}
return ret;
}
static void
vl82c480_close(void *p)
vl82c480_close(void *priv)
{
vl82c480_t *dev = (vl82c480_t *) p;
vl82c480_t *dev = (vl82c480_t *) priv;
free(dev);
}

View File

@@ -37,6 +37,7 @@
#include <86box/hdc_ide.h>
#include <86box/lpt.h>
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/serial.h>
#include <86box/chipset.h>
@@ -63,17 +64,33 @@ wd76c10_log(const char *fmt, ...)
# define wd76c10_log(fmt, ...)
#endif
typedef struct
{
uint16_t lock_reg, oscillator_40mhz, cache_flush, ems_page_reg,
ems_page_reg_pointer, port_shadow, pmc_interrupt,
high_mem_protect_boundry, delay_line, diagnostic,
nmi_status, pmc_input, pmc_timer,
pmc_output, ems_control_low_address_boundry, shadow_ram,
split_addr, bank32staddr, bank10staddr,
non_page_mode_dram_timing, mem_control,
refresh_control, disk_chip_select, prog_chip_sel_addr,
bus_timing_power_down_ctl, clk_control;
typedef struct wd76c10_t {
uint16_t lock_reg;
uint16_t oscillator_40mhz;
uint16_t cache_flush;
uint16_t ems_page_reg;
uint16_t ems_page_reg_pointer;
uint16_t port_shadow;
uint16_t pmc_interrupt;
uint16_t high_mem_protect_boundry;
uint16_t delay_line;
uint16_t diagnostic;
uint16_t nmi_status;
uint16_t pmc_input;
uint16_t pmc_timer;
uint16_t pmc_output;
uint16_t ems_control_low_address_boundry;
uint16_t shadow_ram;
uint16_t split_addr;
uint16_t bank32staddr;
uint16_t bank10staddr;
uint16_t non_page_mode_dram_timing;
uint16_t mem_control;
uint16_t refresh_control;
uint16_t disk_chip_select;
uint16_t prog_chip_sel_addr;
uint16_t bus_timing_power_down_ctl;
uint16_t clk_control;
int lock;
@@ -100,6 +117,8 @@ wd76c10_refresh_control(wd76c10_t *dev)
case 4:
serial_setup(dev->uart[1], 0x2e8, 3);
break;
default:
break;
}
serial_remove(dev->uart[0]);
@@ -117,6 +136,8 @@ wd76c10_refresh_control(wd76c10_t *dev)
case 4:
serial_setup(dev->uart[0], 0x2e8, 4);
break;
default:
break;
}
lpt1_remove();
@@ -134,6 +155,9 @@ wd76c10_refresh_control(wd76c10_t *dev)
lpt1_init(0x278);
lpt1_irq(7);
break;
default:
break;
}
}
@@ -153,6 +177,8 @@ wd76c10_split_addr(wd76c10_t *dev)
if (((dev->shadow_ram >> 8) & 3) == 3)
mem_remap_top(384);
break;
default:
break;
}
}
@@ -187,6 +213,8 @@ wd76c10_shadow_recalc(wd76c10_t *dev)
case 3:
mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | MEM_WRITE_DISABLED);
break;
default:
break;
}
switch ((dev->shadow_ram >> 8) & 3) {
@@ -203,6 +231,8 @@ wd76c10_shadow_recalc(wd76c10_t *dev)
case 3:
mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
break;
default:
break;
}
}
@@ -309,6 +339,9 @@ wd76c10_write(uint16_t addr, uint16_t val, void *priv)
dev->cache_flush = val;
flushmmucache();
break;
default:
break;
}
wd76c10_log("WD76C10: dev->regs[%04x] = %04x\n", addr, val);
}
@@ -326,6 +359,9 @@ wd76c10_write(uint16_t addr, uint16_t val, void *priv)
dev->lock_reg = val & 0x00ff;
LOCK = !(val & 0x00da);
break;
default:
break;
}
}
@@ -424,7 +460,7 @@ wd76c10_close(void *priv)
}
static void *
wd76c10_init(const device_t *info)
wd76c10_init(UNUSED(const device_t *info))
{
wd76c10_t *dev = (wd76c10_t *) malloc(sizeof(wd76c10_t));
memset(dev, 0, sizeof(wd76c10_t));

View File

@@ -212,7 +212,8 @@ codeblock_tree_delete(codeblock_t *block)
return;
} else {
/*Difficult case - node has two children. Walk right child to find lowest node*/
codeblock_t *lowest = block->right, *highest;
codeblock_t *lowest = block->right;
codeblock_t *highest;
codeblock_t *old_parent;
while (lowest->left)

View File

@@ -91,8 +91,8 @@ RecompOpFn recomp_opcodes_0f[512] = {
/*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, ropEMMS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_mm_l, ropMOVQ_mm_q,
/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, ropEMMS, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_l_mm, ropMOVQ_q_mm,
/*80*/ ropJO_w, ropJNO_w, ropJB_w, ropJNB_w, ropJE_w, ropJNE_w, ropJBE_w, ropJNBE_w, ropJS_w, ropJNS_w, ropJP_w, ropJNP_w, ropJL_w, ropJNL_w, ropJLE_w, ropJNLE_w,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -100,9 +100,9 @@ RecompOpFn recomp_opcodes_0f[512] = {
/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_w_b, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_w_b, 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,
/*d0*/ NULL, ropPSRLW, ropPSRLD, ropPSRLQ, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN,
/*e0*/ NULL, ropPSRAW, ropPSRAD, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR,
/*f0*/ NULL, ropPSLLW, ropPSLLD, ropPSLLQ, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/

View File

@@ -281,7 +281,8 @@ ROP_ARITH_RM(SUB, SUB, 1)
static uint32_t
ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
int src_reg;
int dst_reg;
if ((fetchdat & 0xc0) == 0xc0) {
src_reg = LOAD_REG_B(fetchdat & 7);
@@ -307,7 +308,8 @@ ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c
static uint32_t
ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
int src_reg;
int dst_reg;
if ((fetchdat & 0xc0) == 0xc0) {
src_reg = LOAD_REG_W(fetchdat & 7);
@@ -333,7 +335,8 @@ ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c
static uint32_t
ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
int src_reg;
int dst_reg;
if ((fetchdat & 0xc0) == 0xc0) {
src_reg = LOAD_REG_L(fetchdat & 7);
@@ -360,7 +363,8 @@ ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c
static uint32_t
ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
int src_reg;
int dst_reg;
if ((fetchdat & 0xc0) == 0xc0) {
dst_reg = LOAD_REG_B(fetchdat & 7);
@@ -386,7 +390,8 @@ ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc,
static uint32_t
ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
int src_reg;
int dst_reg;
if ((fetchdat & 0xc0) == 0xc0) {
dst_reg = LOAD_REG_W(fetchdat & 7);
@@ -412,7 +417,8 @@ ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc,
static uint32_t
ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
int src_reg;
int dst_reg;
if ((fetchdat & 0xc0) == 0xc0) {
dst_reg = LOAD_REG_L(fetchdat & 7);
@@ -744,7 +750,7 @@ rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb
host_reg = 0;
} else {
SAVE_EA();
MEM_CHECK_WRITE(target_seg);
MEM_CHECK_WRITE_L(target_seg);
host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg);
}
} else {

View File

@@ -156,7 +156,8 @@ static uint32_t
ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg1, host_reg2 = 0;
int host_reg1;
int host_reg2 = 0;
FP_ENTER();
op_pc--;
@@ -593,7 +594,8 @@ static uint32_t
ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg1, host_reg2;
int host_reg1;
int host_reg2;
FP_ENTER();
op_pc--;
@@ -679,7 +681,7 @@ opFLDimm(Z, 0.0)
static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull);
FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ULL);
return op_pc;
}

View File

@@ -175,7 +175,8 @@ ROP_LOGIC(XOR, XOR, 1)
static uint32_t
ropTEST_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
int src_reg;
int dst_reg;
if ((fetchdat & 0xc0) == 0xc0) {
src_reg = LOAD_REG_B(fetchdat & 7);
@@ -198,7 +199,8 @@ ropTEST_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc,
static uint32_t
ropTEST_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
int src_reg;
int dst_reg;
if ((fetchdat & 0xc0) == 0xc0) {
src_reg = LOAD_REG_W(fetchdat & 7);
@@ -221,7 +223,8 @@ ropTEST_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc,
static uint32_t
ropTEST_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
int src_reg;
int dst_reg;
if ((fetchdat & 0xc0) == 0xc0) {
src_reg = LOAD_REG_L(fetchdat & 7);

View File

@@ -1,7 +1,8 @@
static uint32_t
ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg1, host_reg2 = 0;
int host_reg1;
int host_reg2 = 0;
MMX_ENTER();
@@ -29,7 +30,8 @@ ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc,
MMX_ENTER();
if ((fetchdat & 0xc0) == 0xc0) {
int host_reg1, host_reg2;
int host_reg1;
int host_reg2;
LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2);
STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2);

View File

@@ -536,7 +536,8 @@ FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc)
addlong((fetchdat >> 8) & 0xffff);
(*op_pc) += 2;
} else {
int base_reg = 0, index_reg = 0;
int base_reg = 0;
int index_reg = 0;
switch (rm) {
case 0:
@@ -639,8 +640,9 @@ FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc,
uint32_t new_eaaddr;
if (rm == 4) {
uint8_t sib = fetchdat >> 8;
int base_reg = -1, index_reg = -1;
uint8_t sib = fetchdat >> 8;
int base_reg = -1;
int index_reg = -1;
(*op_pc)++;

View File

@@ -45,7 +45,9 @@ OP_XCHG_EAX_(EBP)
static uint32_t
ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg, temp_reg;
int src_reg;
int dst_reg;
int temp_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
@@ -61,7 +63,9 @@ ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod
static uint32_t
ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg, temp_reg;
int src_reg;
int dst_reg;
int temp_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
@@ -77,7 +81,9 @@ ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod
static uint32_t
ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg, temp_reg;
int src_reg;
int dst_reg;
int temp_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;

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 ? 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 ? 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 ? 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 ? 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 ? 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 ? 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 ? 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 ? NULL : recomp_opcodes_df;
opcode_mask = 0xff;
over = 1;
pc_off = -1;

View File

@@ -69,7 +69,8 @@
# include <windows.h>
# endif
int codegen_flat_ds, codegen_flat_ss;
int codegen_flat_ds;
int codegen_flat_ss;
int mmx_ebx_ecx_loaded;
int codegen_flags_changed = 0;
int codegen_fpu_entered = 0;
@@ -1921,7 +1922,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 ? NULL : recomp_opcodes_d8;
opcode_shift = 3;
opcode_mask = 0x1f;
over = 1;
@@ -1931,7 +1932,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 ? NULL : recomp_opcodes_d9;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -1940,7 +1941,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 ? NULL : recomp_opcodes_da;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -1949,7 +1950,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 ? NULL : recomp_opcodes_db;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -1958,7 +1959,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 ? NULL : recomp_opcodes_dc;
opcode_shift = 3;
opcode_mask = 0x1f;
over = 1;
@@ -1968,7 +1969,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 ? NULL : recomp_opcodes_dd;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -1977,7 +1978,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 ? NULL : recomp_opcodes_de;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -1986,7 +1987,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 ? NULL : recomp_opcodes_df;
opcode_mask = 0xff;
over = 1;
pc_off = -1;

View File

@@ -31,9 +31,7 @@ static struct
int
codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP)
{
int c;
for (c = 0; c <= block->ins; c++) {
for (uint8_t c = 0; c <= block->ins; c++) {
if (codegen_instructions[c].pc == pc) {
*first_instruction = c;
*TOP = codegen_instructions[c].TOP;
@@ -137,7 +135,9 @@ codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat,
uop_MOV_IMM(ir, IREG_eaaddr, addr);
(*op_pc) += 2;
} else {
int base_reg, index_reg, offset;
int base_reg;
int index_reg;
int offset;
switch (cpu_rm & 7) {
case 0:
@@ -374,7 +374,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
codeblock_t *block = &codeblock[block_current];
ir_data_t *ir = codegen_get_ir_data();
uint32_t op_pc = new_pc;
OpFn *op_table = (OpFn *) x86_dynarec_opcodes;
const OpFn *op_table = (OpFn *) x86_dynarec_opcodes;
RecompOpFn *recomp_op_table = recomp_opcodes;
int opcode_shift = 0;
int opcode_mask = 0x3ff;
@@ -398,7 +398,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0x0f;
#endif
op_table = (OpFn *) x86_dynarec_opcodes_0f;
op_table = x86_dynarec_opcodes_0f;
recomp_op_table = recomp_opcodes_0f;
over = 1;
break;
@@ -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 ? 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 ? 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 ? 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 ? 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 ? 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 ? 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 ? 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 ? NULL : recomp_opcodes_df;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
@@ -541,14 +541,14 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xf2;
#endif
op_table = (OpFn *) x86_dynarec_opcodes_REPNE;
op_table = x86_dynarec_opcodes_REPNE;
recomp_op_table = NULL; // recomp_opcodes_REPNE;
break;
case 0xf3: /*REPE*/
#ifdef DEBUG_EXTRA
last_prefix = 0xf3;
#endif
op_table = (OpFn *) x86_dynarec_opcodes_REPE;
op_table = x86_dynarec_opcodes_REPE;
recomp_op_table = NULL; // recomp_opcodes_REPE;
break;
@@ -713,6 +713,7 @@ generate_call:
uop_MOV_IMM(ir, IREG_ssegs, op_ssegs);
uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat);
uop_CALL_INSTRUCTION_FUNC(ir, op);
codegen_flags_changed = 0;
codegen_mark_code_present(block, cs + cpu_state.pc, 8);
last_op_32 = op_32;

View File

@@ -140,12 +140,16 @@ codeblock_tree_add(codeblock_t *new_block)
block = block->right ? &codeblock[block->right] : NULL;
}
if (a < old_block_cmp)
old_block->left = get_block_nr(new_block);
else
old_block->right = get_block_nr(new_block);
if (old_block != NULL) {
if (a < old_block_cmp)
old_block->left = get_block_nr(new_block);
else
old_block->right = get_block_nr(new_block);
new_block->parent = get_block_nr(old_block);
} else
new_block->parent = BLOCK_INVALID;
new_block->parent = get_block_nr(old_block);
new_block->left = new_block->right = BLOCK_INVALID;
}
}
@@ -212,7 +216,8 @@ codeblock_tree_delete(codeblock_t *block)
return;
} else {
/*Difficult case - node has two children. Walk right child to find lowest node*/
codeblock_t *lowest = &codeblock[block->right], *highest;
codeblock_t *lowest = &codeblock[block->right];
codeblock_t *highest;
codeblock_t *old_parent;
uint16_t lowest_nr;

View File

@@ -32,8 +32,6 @@ int codegen_allocator_usage = 0;
void
codegen_allocator_init(void)
{
int c;
#if defined WIN32 || defined _WIN32 || defined _WIN32
mem_block_alloc = VirtualAlloc(NULL, MEM_BLOCK_NR * MEM_BLOCK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
/* TODO: check deployment target: older Intel-based versions of macOS don't play
@@ -44,7 +42,7 @@ codegen_allocator_init(void)
mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
#endif
for (c = 0; c < MEM_BLOCK_NR; c++) {
for (uint32_t c = 0; c < MEM_BLOCK_NR; c++) {
mem_blocks[c].offset = c * MEM_BLOCK_SIZE;
mem_blocks[c].code_block = BLOCK_INVALID;
if (c < MEM_BLOCK_NR - 1)

View File

@@ -1313,7 +1313,8 @@ static uint32_t imm_table[][2] = {
uint32_t
host_arm64_find_imm(uint32_t data)
{
int l = 0, r = IMM_NR - 1;
int l = 0;
int r = IMM_NR - 1;
while (l <= r) {
int m = (l + r) >> 1;

View File

@@ -263,7 +263,6 @@ void
codegen_backend_init(void)
{
codeblock_t *block;
int c;
codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t));
codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *));
@@ -271,7 +270,7 @@ codegen_backend_init(void)
memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t));
memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *));
for (c = 0; c < BLOCK_SIZE; c++)
for (uint32_t c = 0; c < BLOCK_SIZE; c++)
codeblock[c].pc = BLOCK_PC_INVALID;
block_current = 0;

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,8 @@
uint8_t *block_write_data = NULL;
int codegen_flat_ds, codegen_flat_ss;
int codegen_flat_ds;
int codegen_flat_ss;
int mmx_ebx_ecx_loaded;
int codegen_flags_changed = 0;
int codegen_fpu_entered = 0;
@@ -61,7 +62,8 @@ static void delete_dirty_block(codeblock_t *block);
The size of this list is limited to DIRTY_LIST_MAX_SIZE blocks. When this is
exceeded the oldest entry will be moved to the free list.*/
static uint16_t block_dirty_list_head, block_dirty_list_tail;
static uint16_t block_dirty_list_head;
static uint16_t block_dirty_list_tail;
static int dirty_list_size = 0;
#define DIRTY_LIST_MAX_SIZE 64
@@ -210,13 +212,11 @@ block_free_list_get(void)
void
codegen_init(void)
{
int c;
codegen_allocator_init();
codegen_backend_init();
block_free_list = 0;
for (c = 0; c < BLOCK_SIZE; c++)
for (uint32_t c = 0; c < BLOCK_SIZE; c++)
block_free_list_add(&codeblock[c]);
block_dirty_list_head = block_dirty_list_tail = 0;
dirty_list_size = 0;
@@ -472,7 +472,6 @@ codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
{
uint16_t block_nr = page->block;
int remove_from_evict_list = 0;
int c;
while (block_nr) {
codeblock_t *block = &codeblock[block_nr];
@@ -509,7 +508,7 @@ codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
page->code_present_mask &= ~page->dirty_mask;
page->dirty_mask = 0;
for (c = 0; c < 64; c++) {
for (uint8_t c = 0; c < 64; c++) {
if (page->byte_code_present_mask[c] & page->byte_dirty_mask[c])
remove_from_evict_list = 0;
page->byte_code_present_mask[c] &= ~page->byte_dirty_mask[c];

View File

@@ -12,7 +12,8 @@
extern int has_ea;
static ir_data_t ir_block;
static int codegen_unroll_start, codegen_unroll_count;
static int codegen_unroll_start;
static int codegen_unroll_count;
static int codegen_unroll_first_instruction;
ir_data_t *
@@ -64,13 +65,12 @@ codegen_ir_compile(ir_data_t *ir, codeblock_t *block)
int c;
if (codegen_unroll_count) {
int unroll_count;
int unroll_end;
codegen_set_loop_start(ir, codegen_unroll_first_instruction);
unroll_end = ir->wr_pos;
for (unroll_count = 1; unroll_count < codegen_unroll_count; unroll_count++) {
for (int unroll_count = 1; unroll_count < codegen_unroll_count; unroll_count++) {
int offset = ir->wr_pos - codegen_unroll_start;
// pclog("Unroll from %i to %i, offset %i - iteration %i\n", codegen_unroll_start, ir->wr_pos, offset, unroll_count);
for (c = codegen_unroll_start; c < unroll_end; c++) {

View File

@@ -556,3 +556,4 @@ 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
};

View File

@@ -264,7 +264,8 @@ ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t ne
static int
ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc)
{
int jump_uop, jump_uop2 = -1;
int jump_uop;
int jump_uop2 = -1;
int do_unroll = ((CF_SET() || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr));
switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) {
@@ -331,7 +332,8 @@ ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t ne
static int
ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc)
{
int jump_uop, jump_uop2 = -1;
int jump_uop;
int jump_uop2 = -1;
int do_unroll = ((!CF_SET() && !ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr));
switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) {
@@ -686,7 +688,8 @@ ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t ne
static int
ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc)
{
int jump_uop, jump_uop2 = -1;
int jump_uop;
int jump_uop2 = -1;
int do_unroll = (((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr));
switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) {
@@ -748,7 +751,8 @@ ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t ne
static int
ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc)
{
int jump_uop, jump_uop2 = -1;
int jump_uop;
int jump_uop2 = -1;
int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && !ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr));
switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) {
@@ -928,7 +932,8 @@ ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u
{
uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc);
uint32_t dest_addr = op_pc + 1 + offset;
int jump_uop, jump_uop2;
int jump_uop;
int jump_uop2;
if (!(op_32 & 0x100))
dest_addr &= 0xffff;
@@ -960,7 +965,8 @@ ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat,
{
uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc);
uint32_t dest_addr = op_pc + 1 + offset;
int jump_uop, jump_uop2;
int jump_uop;
int jump_uop2;
if (!(op_32 & 0x100))
dest_addr &= 0xffff;

View File

@@ -269,7 +269,8 @@ uint32_t
ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
x86seg *target_seg = NULL;
int src_reg, sp_reg;
int src_reg;
int sp_reg;
if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30)
return 0;
@@ -367,7 +368,8 @@ uint32_t
ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
x86seg *target_seg = NULL;
int src_reg, sp_reg;
int src_reg;
int sp_reg;
if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30)
return 0;

View File

@@ -30,7 +30,8 @@ typedef struct host_reg_set_t {
int nr_regs;
} host_reg_set_t;
static host_reg_set_t host_reg_set, host_fp_reg_set;
static host_reg_set_t host_reg_set;
static host_reg_set_t host_fp_reg_set;
enum {
REG_BYTE,
@@ -182,9 +183,7 @@ struct
void
codegen_reg_mark_as_required(void)
{
int reg;
for (reg = 0; reg < IREG_COUNT; reg++) {
for (uint8_t reg = 0; reg < IREG_COUNT; reg++) {
int last_version = reg_last_version[reg];
if (last_version > 0 && ireg_data[reg].is_volatile == REG_PERMANENT)
@@ -533,9 +532,8 @@ alloc_reg(ir_reg_t ir_reg)
{
host_reg_set_t *reg_set = get_reg_set(ir_reg);
int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS;
int c;
for (c = 0; c < nr_regs; c++) {
for (int c = 0; c < nr_regs; c++) {
if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) {
#ifndef RELEASE_BUILD
if (reg_set->regs[c].version != ir_reg.version)
@@ -552,9 +550,8 @@ alloc_dest_reg(ir_reg_t ir_reg, int dest_reference)
{
host_reg_set_t *reg_set = get_reg_set(ir_reg);
int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS;
int c;
for (c = 0; c < nr_regs; c++) {
for (int c = 0; c < nr_regs; c++) {
if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) {
if (reg_set->regs[c].version == ir_reg.version) {
reg_set->locked |= (1 << c);
@@ -737,10 +734,9 @@ int
codegen_reg_is_loaded(ir_reg_t ir_reg)
{
host_reg_set_t *reg_set = get_reg_set(ir_reg);
int c;
/*Search for previous version in host register*/
for (c = 0; c < reg_set->nr_regs; c++) {
for (int c = 0; c < reg_set->nr_regs; c++) {
if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) {
if (reg_set->regs[c].version <= ir_reg.version - 1) {
# ifndef RELEASE_BUILD

View File

@@ -20,6 +20,8 @@
* Copyright 2016-2019 Miran Grca.
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2018-2019 David Hrdlička.
* Copyright 2021 Andreas J. Reichel.
* Copyright 2021-2022 Jasmine Iwanek.
*
* NOTE: Forcing config files to be in Unicode encoding breaks
* it on Windows XP, and possibly also Vista. Use the
@@ -54,6 +56,8 @@
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/gameport.h>
#include <86box/serial.h>
#include <86box/serial_passthrough.h>
#include <86box/machine.h>
#include <86box/mouse.h>
#include <86box/thread.h>
@@ -74,13 +78,17 @@
#include <86box/ui.h>
#include <86box/snd_opl.h>
static int cx, cy, cw, ch;
static int cx;
static int cy;
static int cw;
static int ch;
static ini_t config;
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */
static int backwards_compat = 0;
static int backwards_compat2 = 0;
#define ENABLE_CONFIG_LOG 1
#ifdef ENABLE_CONFIG_LOG
int config_do_log = ENABLE_CONFIG_LOG;
@@ -218,7 +226,8 @@ static void
load_monitor(int monitor_index)
{
ini_section_t cat;
char name[512], temp[512];
char name[512];
char temp[512];
char *p = NULL;
sprintf(name, "Monitor #%i", monitor_index + 1);
@@ -246,8 +255,14 @@ static void
load_machine(void)
{
ini_section_t cat = ini_find_section(config, "Machine");
char *p, *migrate_from = NULL;
int c, i, j, speed, legacy_mfg, legacy_cpu;
char *p;
char *migrate_from = NULL;
int c;
int i;
int j;
int speed;
int legacy_mfg;
int legacy_cpu;
double multi;
p = ini_section_get_string(cat, "machine", NULL);
@@ -499,6 +514,9 @@ load_machine(void)
mem_size = machine_get_max_ram(machine);
cpu_use_dynarec = !!ini_section_get_int(cat, "cpu_use_dynarec", 0);
fpu_softfloat = !!ini_section_get_int(cat, "fpu_softfloat", 0);
if (machine_has_flags(machine, MACHINE_SOFTFLOAT_ONLY))
fpu_softfloat = 1;
p = ini_section_get_string(cat, "time_sync", NULL);
if (p != NULL) {
@@ -569,7 +587,8 @@ load_input_devices(void)
{
ini_section_t cat = ini_find_section(config, "Input devices");
char temp[512];
int c, d;
int c;
int d;
char *p;
p = ini_section_get_string(cat, "mouse_type", NULL);
@@ -651,6 +670,8 @@ load_input_devices(void)
}
}
}
tablet_tool_type = !!ini_section_get_int(cat, "tablet_tool_type", 1);
}
/* Load "Sound" section. */
@@ -711,6 +732,24 @@ load_sound(void)
mpu401_standalone_enable = !!ini_section_get_int(cat, "mpu401_standalone", 0);
/* Backwards compatibility for standalone SSI-2001, CMS and GUS from v3.11 and older. */
const char *legacy_cards[][2] = {
{"ssi2001", "ssi2001"},
{ "gameblaster", "cms" },
{ "gus", "gus" }
};
for (int i = 0, j = 0; i < (sizeof(legacy_cards) / sizeof(legacy_cards[0])); i++) {
if (ini_section_get_int(cat, legacy_cards[i][0], 0) == 1) {
/* Migrate to the first available sound card slot. */
for (; j < (sizeof(sound_card_current) / sizeof(sound_card_current[0])); j++) {
if (!sound_card_current[j]) {
sound_card_current[j] = sound_card_get_from_internal_name(legacy_cards[i][1]);
break;
}
}
}
}
memset(temp, '\0', sizeof(temp));
p = ini_section_get_string(cat, "sound_type", "float");
if (strlen(p) > 511)
@@ -737,7 +776,8 @@ load_network(void)
ini_section_t cat = ini_find_section(config, "Network");
char *p;
char temp[512];
uint16_t c = 0, min = 0;
uint16_t c = 0;
uint16_t min = 0;
/* Handle legacy configuration which supported only one NIC */
p = ini_section_get_string(cat, "net_card", NULL);
@@ -750,6 +790,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 {
@@ -758,13 +800,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);
}
@@ -795,6 +841,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;
}
@@ -805,13 +853,17 @@ 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");
} 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);
}
@@ -832,17 +884,26 @@ load_ports(void)
ini_section_t cat = ini_find_section(config, "Ports (COM & LPT)");
char *p;
char temp[512];
int c, d;
int c;
int d;
memset(temp, 0, sizeof(temp));
for (c = 0; c < SERIAL_MAX; c++) {
sprintf(temp, "serial%d_enabled", c + 1);
com_ports[c].enabled = !!ini_section_get_int(cat, temp, (c >= 2) ? 0 : 1);
/*
#if 0
sprintf(temp, "serial%d_device", c + 1);
p = (char *) ini_section_get_string(cat, temp, "none");
com_ports[c].device = com_device_get_from_internal_name(p);
*/
#endif
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
serial_passthrough_enabled[c] = !!ini_section_get_int(cat, temp, 0);
if (serial_passthrough_enabled[c])
config_log("Serial Port %d: passthrough enabled.\n\n", c + 1);
}
for (c = 0; c < PARALLEL_MAX; c++) {
@@ -868,8 +929,10 @@ static void
load_storage_controllers(void)
{
ini_section_t cat = ini_find_section(config, "Storage controllers");
char *p, temp[512];
int c, min = 0;
char *p;
char temp[512];
int c;
int min = 0;
int free_p = 0;
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */
@@ -940,9 +1003,11 @@ load_storage_controllers(void)
ide_ter_enabled = !!ini_section_get_int(cat, "ide_ter", 0);
ide_qua_enabled = !!ini_section_get_int(cat, "ide_qua", 0);
/* TODO: Re-enable by default after we actually have a proper machine flag for this. */
cassette_enable = !!ini_section_get_int(cat, "cassette_enabled", 0);
p = ini_section_get_string(cat, "cassette_file", "");
if (machine_has_bus(machine, MACHINE_BUS_CASSETTE))
cassette_enable = !!ini_section_get_int(cat, "cassette_enabled", 0);
else
cassette_enable = 0;
p = ini_section_get_string(cat, "cassette_file", "");
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511\n");
else
@@ -991,15 +1056,18 @@ static void
load_hard_disks(void)
{
ini_section_t cat = ini_find_section(config, "Hard disks");
char temp[512], tmp2[512];
char temp[512];
char tmp2[512];
char s[512];
int c;
char *p;
uint32_t max_spt, max_hpc, max_tracks;
uint32_t board = 0, dev = 0;
uint32_t max_spt;
uint32_t max_hpc;
uint32_t max_tracks;
uint32_t board = 0;
uint32_t dev = 0;
memset(temp, '\0', sizeof(temp));
for (c = 0; c < HDD_NUM; c++) {
for (uint8_t c = 0; c < HDD_NUM; c++) {
sprintf(temp, "hdd_%02i_parameters", c + 1);
p = ini_section_get_string(cat, temp, "0, 0, 0, 0, none");
sscanf(p, "%u, %u, %u, %i, %s",
@@ -1007,8 +1075,8 @@ load_hard_disks(void)
hdd[c].bus = hdd_string_to_bus(s, 0);
switch (hdd[c].bus) {
case HDD_BUS_DISABLED:
default:
case HDD_BUS_DISABLED:
max_spt = max_hpc = max_tracks = 0;
break;
@@ -1127,7 +1195,6 @@ load_hard_disks(void)
ini_section_delete_var(cat, temp);
memset(hdd[c].fn, 0x00, sizeof(hdd[c].fn));
memset(hdd[c].prev_fn, 0x00, sizeof(hdd[c].prev_fn));
sprintf(temp, "hdd_%02i_fn", c + 1);
p = ini_section_get_string(cat, temp, "");
@@ -1160,6 +1227,13 @@ load_hard_disks(void)
}
path_normalize(hdd[c].fn);
sprintf(temp, "hdd_%02i_vhd_blocksize", c + 1);
hdd[c].vhd_blocksize = ini_section_get_int(cat, temp, 0);
sprintf(temp, "hdd_%02i_vhd_parent", c + 1);
p = ini_section_get_string(cat, temp, "");
strncpy(hdd[c].vhd_parent, p, sizeof(hdd[c].vhd_parent) - 1);
/* If disk is empty or invalid, mark it for deletion. */
if (!hdd_is_valid(c)) {
sprintf(temp, "hdd_%02i_parameters", c + 1);
@@ -1192,13 +1266,13 @@ static void
load_floppy_drives(void)
{
ini_section_t cat = ini_find_section(config, "Floppy drives");
char temp[512], *p;
int c;
char temp[512];
char *p;
if (!backwards_compat)
return;
for (c = 0; c < FDD_NUM; c++) {
for (uint8_t c = 0; c < FDD_NUM; c++) {
sprintf(temp, "fdd_%02i_type", c + 1);
p = ini_section_get_string(cat, temp, (c < 2) ? "525_2dd" : "none");
fdd_set_type(c, fdd_get_from_internal_name(p));
@@ -1232,8 +1306,10 @@ load_floppy_drives(void)
else
strncpy(floppyfns[c], p, 511);
/* if (*wp != L'\0')
config_log("Floppy%d: %ls\n", c, floppyfns[c]); */
#if 0
if (*wp != L'\0')
config_log("Floppy%d: %ls\n", c, floppyfns[c]);
#endif
sprintf(temp, "fdd_%02i_writeprot", c + 1);
ui_writeprot[c] = !!ini_section_get_int(cat, temp, 0);
ini_section_delete_var(cat, temp);
@@ -1253,10 +1329,14 @@ static void
load_floppy_and_cdrom_drives(void)
{
ini_section_t cat = ini_find_section(config, "Floppy and CD-ROM drives");
char temp[512], tmp2[512], *p;
char temp[512];
char tmp2[512];
char *p;
char s[512];
unsigned int board = 0, dev = 0;
int c, d = 0;
unsigned int board = 0;
unsigned int dev = 0;
int c;
int d = 0;
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */
backwards_compat = (cat == NULL);
@@ -1294,8 +1374,10 @@ load_floppy_and_cdrom_drives(void)
else
strncpy(floppyfns[c], p, 511);
/* if (*wp != L'\0')
config_log("Floppy%d: %ls\n", c, floppyfns[c]); */
#if 0
if (*wp != L'\0')
config_log("Floppy%d: %ls\n", c, floppyfns[c]);
#endif
sprintf(temp, "fdd_%02i_writeprot", c + 1);
ui_writeprot[c] = !!ini_section_get_int(cat, temp, 0);
sprintf(temp, "fdd_%02i_turbo", c + 1);
@@ -1473,10 +1555,14 @@ static void
load_other_removable_devices(void)
{
ini_section_t cat = ini_find_section(config, "Other removable devices");
char temp[512], tmp2[512], *p;
char temp[512];
char tmp2[512];
char *p;
char s[512];
unsigned int board = 0, dev = 0;
int c, d = 0;
unsigned int board = 0;
unsigned int dev = 0;
int c;
int d = 0;
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */
if (backwards_compat) {
@@ -1751,7 +1837,7 @@ load_other_peripherals(void)
ini_section_t cat = ini_find_section(config, "Other peripherals");
char *p;
char temp[512];
int c, free_p = 0;
int free_p = 0;
if (backwards_compat2) {
p = ini_section_get_string(cat, "scsicard", NULL);
@@ -1808,7 +1894,7 @@ load_other_peripherals(void)
bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0);
postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0);
for (c = 0; c < ISAMEM_MAX; c++) {
for (uint8_t c = 0; c < ISAMEM_MAX; c++) {
sprintf(temp, "isamem%d_type", c);
p = ini_section_get_string(cat, temp, "none");
@@ -1886,8 +1972,7 @@ config_load(void)
for (i = 0; i < ISAMEM_MAX; i++)
isamem_type[i] = 0;
/* TODO: Re-enable by default when we have a proper machine flag for this. */
cassette_enable = 0;
cassette_enable = 1;
memset(cassette_fname, 0x00, sizeof(cassette_fname));
memcpy(cassette_mode, "load", strlen("load") + 1);
cassette_pos = 0;
@@ -1929,7 +2014,8 @@ static void
save_general(void)
{
ini_section_t cat = ini_find_or_create_section(config, "General");
char temp[512], buffer[512] = { 0 };
char temp[512];
char buffer[512] = { 0 };
char *va_name;
@@ -2131,7 +2217,11 @@ save_machine(void)
{
ini_section_t cat = ini_find_or_create_section(config, "Machine");
char *p;
int c, i = 0, legacy_mfg, legacy_cpu = -1, closest_legacy_cpu = -1;
int c;
int i = 0;
int legacy_mfg;
int legacy_cpu = -1;
int closest_legacy_cpu = -1;
p = machine_get_internal_name();
ini_section_set_string(cat, "machine", p);
@@ -2144,7 +2234,7 @@ save_machine(void)
else
ini_section_delete_var(cat, "cpu_override");
/* Forwards compatibility with the previous CPU model system. */
/* Downgrade compatibility with the previous CPU model system. */
ini_section_delete_var(cat, "cpu_manufacturer");
ini_section_delete_var(cat, "cpu");
@@ -2211,6 +2301,7 @@ save_machine(void)
ini_section_set_int(cat, "mem_size", mem_size);
ini_section_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec);
ini_section_set_int(cat, "fpu_softfloat", fpu_softfloat);
if (time_sync & TIME_SYNC_ENABLED)
if (time_sync & TIME_SYNC_UTC)
@@ -2275,8 +2366,10 @@ static void
save_input_devices(void)
{
ini_section_t cat = ini_find_or_create_section(config, "Input devices");
char temp[512], tmp2[512];
int c, d;
char temp[512];
char tmp2[512];
int c;
int d;
ini_section_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type));
@@ -2325,6 +2418,12 @@ save_input_devices(void)
}
}
if (tablet_tool_type != 1) {
ini_section_set_int(cat, "tablet_tool_type", tablet_tool_type);
} else {
ini_section_delete_var(cat, "tablet_tool_type");
}
ini_delete_section_if_empty(config, cat);
}
@@ -2369,6 +2468,27 @@ save_sound(void)
else
ini_section_set_int(cat, "mpu401_standalone", mpu401_standalone_enable);
/* Downgrade compatibility for standalone SSI-2001, CMS and GUS from v3.11 and older. */
const char *legacy_cards[][2] = {
{"ssi2001", "ssi2001"},
{ "gameblaster", "cms" },
{ "gus", "gus" }
};
for (int i = 0; i < (sizeof(legacy_cards) / sizeof(legacy_cards[0])); i++) {
int card_id = sound_card_get_from_internal_name(legacy_cards[i][1]);
for (int j = 0; j < (sizeof(sound_card_current) / sizeof(sound_card_current[0])); j++) {
if (sound_card_current[j] == card_id) {
/* A special value of 2 still enables the cards on older versions,
but lets newer versions know that they've already been migrated. */
ini_section_set_int(cat, legacy_cards[i][0], 2);
card_id = 0; /* mark as found */
break;
}
}
if (card_id > 0) /* not found */
ini_section_delete_var(cat, legacy_cards[i][0]);
}
if (sound_is_float == 1)
ini_section_delete_var(cat, "sound_type");
else
@@ -2383,7 +2503,6 @@ save_sound(void)
static void
save_network(void)
{
int c = 0;
char temp[512];
ini_section_t cat = ini_find_or_create_section(config, "Network");
@@ -2391,7 +2510,7 @@ save_network(void)
ini_section_delete_var(cat, "net_host_device");
ini_section_delete_var(cat, "net_card");
for (c = 0; c < NET_CARD_MAX; c++) {
for (uint8_t c = 0; c < NET_CARD_MAX; c++) {
sprintf(temp, "net_%02i_card", c + 1);
if (net_cards_conf[c].device_num == 0) {
ini_section_delete_var(cat, temp);
@@ -2400,11 +2519,22 @@ 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;
default:
break;
}
sprintf(temp, "net_%02i_host_device", c + 1);
@@ -2414,7 +2544,9 @@ save_network(void)
else
ini_section_set_string(cat, temp, net_cards_conf[c].host_dev_name);
} else {
/* ini_section_set_string(cat, temp, "none"); */
#if 0
ini_section_set_string(cat, temp, "none");
#endif
ini_section_delete_var(cat, temp);
}
@@ -2435,7 +2567,8 @@ save_ports(void)
{
ini_section_t cat = ini_find_or_create_section(config, "Ports (COM & LPT)");
char temp[512];
int c, d;
int c;
int d;
for (c = 0; c < SERIAL_MAX; c++) {
sprintf(temp, "serial%d_enabled", c + 1);
@@ -2444,7 +2577,7 @@ save_ports(void)
else
ini_section_set_int(cat, temp, com_ports[c].enabled);
/*
#if 0
sprintf(temp, "serial%d_type", c + 1);
if (!com_ports[c].enabled))
ini_section_delete_var(cat, temp);
@@ -2457,7 +2590,14 @@ save_ports(void)
else
ini_section_set_string(cat, temp,
(char *) com_device_get_internal_name(com_ports[c].device));
*/
#endif
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
if (serial_passthrough_enabled[c]) {
ini_section_set_int(cat, temp, 1);
} else {
ini_section_delete_var(cat, temp);
}
}
for (c = 0; c < PARALLEL_MAX; c++) {
@@ -2512,7 +2652,7 @@ save_storage_controllers(void)
ini_section_delete_var(cat, "cdrom_interface");
else
ini_section_set_string(cat, "cdrom_interface",
cdrom_interface_get_internal_name(cdrom_interface_current));
cdrom_interface_get_internal_name(cdrom_interface_current));
if (ide_ter_enabled == 0)
ini_section_delete_var(cat, "ide_ter");
@@ -2581,7 +2721,6 @@ save_other_peripherals(void)
{
ini_section_t cat = ini_find_or_create_section(config, "Other peripherals");
char temp[512];
int c;
if (bugger_enabled == 0)
ini_section_delete_var(cat, "bugger_enabled");
@@ -2593,7 +2732,7 @@ save_other_peripherals(void)
else
ini_section_set_int(cat, "postcard_enabled", postcard_enabled);
for (c = 0; c < ISAMEM_MAX; c++) {
for (uint8_t c = 0; c < ISAMEM_MAX; c++) {
sprintf(temp, "isamem%d_type", c);
if (isamem_type[c] == 0)
ini_section_delete_var(cat, temp);
@@ -2616,12 +2755,12 @@ static void
save_hard_disks(void)
{
ini_section_t cat = ini_find_or_create_section(config, "Hard disks");
char temp[32], tmp2[512];
char temp[32];
char tmp2[512];
char *p;
int c;
memset(temp, 0x00, sizeof(temp));
for (c = 0; c < HDD_NUM; c++) {
for (uint8_t c = 0; c < HDD_NUM; c++) {
sprintf(temp, "hdd_%02i_parameters", c + 1);
if (hdd_is_valid(c)) {
p = hdd_bus_to_string(hdd[c].bus, 0);
@@ -2680,6 +2819,19 @@ save_hard_disks(void)
} else
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_vhd_blocksize", c + 1);
if (hdd_is_valid(c) && (hdd[c].vhd_blocksize > 0))
ini_section_set_int(cat, temp, hdd[c].vhd_blocksize);
else
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_vhd_parent", c + 1);
if (hdd_is_valid(c) && hdd[c].vhd_parent[0]) {
path_normalize(hdd[c].vhd_parent);
ini_section_set_string(cat, temp, hdd[c].vhd_parent);
} else
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_speed", c + 1);
if (!hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_IDE && hdd[c].bus != HDD_BUS_ESDI))
ini_section_delete_var(cat, temp);
@@ -2695,7 +2847,8 @@ static void
save_floppy_and_cdrom_drives(void)
{
ini_section_t cat = ini_find_or_create_section(config, "Floppy and CD-ROM drives");
char temp[512], tmp2[512];
char temp[512];
char tmp2[512];
int c;
for (c = 0; c < FDD_NUM; c++) {
@@ -2831,7 +2984,8 @@ static void
save_other_removable_devices(void)
{
ini_section_t cat = ini_find_or_create_section(config, "Other removable devices");
char temp[512], tmp2[512];
char temp[512];
char tmp2[512];
int c;
for (c = 0; c < ZIP_NUM; c++) {
@@ -2918,10 +3072,8 @@ save_other_removable_devices(void)
void
config_save(void)
{
int i;
save_general(); /* General */
for (i = 0; i < MONITORS_NUM; i++)
for (uint8_t i = 0; i < MONITORS_NUM; i++)
save_monitor(i);
save_machine(); /* Machine */
save_video(); /* Video */

View File

@@ -46,6 +46,42 @@ uint32_t backupregs[16];
x86seg _oldds;
#if 1
int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x3x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */
1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */
3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */
3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */
3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */
1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */
#else
int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */
3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, /* 0x2x */
3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, /* 0x3x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */
1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */
3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */
3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */
3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */
3, 1, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */
#endif
#ifdef ENABLE_386_LOG
int x386_do_log = ENABLE_386_LOG;
@@ -143,7 +179,7 @@ exec386(int cycs)
cpu_state.ea_seg = &cpu_state.seg_ds;
cpu_state.ssegs = 0;
fetchdat = fastreadl(cs + cpu_state.pc);
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
if (!cpu_state.abrt) {
#ifdef ENABLE_386_LOG

View File

@@ -780,8 +780,8 @@ smram_restore_state_p6(uint32_t *saved_state)
cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 24) & 0xff;
smm_seg_load(&cpu_state.seg_gs);
mem_a20_alt = 0;
keyboard_at_set_a20_key(!saved_state[SMRAM_FIELD_P6_A20M]);
mem_a20_alt = 0x00;
mem_a20_key = saved_state[SMRAM_FIELD_P6_A20M] ? 0x00 : 0x02;
mem_a20_recalc();
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
@@ -1053,13 +1053,13 @@ enter_smm(int in_hlt)
memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t));
if (is_cxsmm) /* Cx6x86 */
if (is_cxsmm) /* Cx6x86 */
smram_save_state_cyrix(saved_state, in_hlt);
else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */
smram_save_state_p5(saved_state, in_hlt);
else if (is_k5 || is_k6) /* AMD K5 and K6 */
else if (is_k5 || is_k6) /* AMD K5 and K6 */
smram_save_state_amd_k(saved_state, in_hlt);
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
smram_save_state_p6(saved_state, in_hlt);
cr0 &= ~0x8000000d;
@@ -1224,13 +1224,13 @@ leave_smm(void)
}
x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]);
if (is_cxsmm) /* Cx6x86 */
if (is_cxsmm) /* Cx6x86 */
smram_restore_state_cyrix(saved_state);
else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */
smram_restore_state_p5(saved_state);
else if (is_k5 || is_k6) /* AMD K5 and K6 */
else if (is_k5 || is_k6) /* AMD K5 and K6 */
smram_restore_state_amd_k(saved_state);
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
smram_restore_state_p6(saved_state);
in_smm = 0;
@@ -1427,25 +1427,29 @@ x86illegal(void)
}
int
checkio(uint32_t port)
checkio(uint32_t port, int mask)
{
uint16_t t;
uint8_t d;
uint32_t t;
cpl_override = 1;
t = readmemw(tr.base, 0x66);
cpl_override = 0;
if (cpu_state.abrt)
if (UNLIKELY(cpu_state.abrt)) {
cpl_override = 0;
return 0;
}
if ((t + (port >> 3UL)) > tr.limit)
return 1;
cpl_override = 1;
d = readmembl(tr.base + t + (port >> 3));
t += (port >> 3UL);
mask <<= (port & 7);
if (UNLIKELY(mask & 0xff00)) {
if (LIKELY(t < tr.limit))
mask &= readmemwl(tr.base + t);
} else {
if (LIKELY(t <= tr.limit))
mask &= readmembl(tr.base + t);
}
cpl_override = 0;
return d & (1 << (port & 7));
return mask;
}
#ifdef OLD_DIVEXCP
@@ -1679,7 +1683,7 @@ sysexit(uint32_t fetchdat)
cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS /* | CPU_STATUS_V86*/);
cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE);
flushmmucache_cr3();
flushmmucache_nopc();
set_use32(1);
set_stack32(1);
@@ -1800,7 +1804,7 @@ sysret(uint32_t fetchdat)
cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS /* | CPU_STATUS_V86*/);
cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE);
flushmmucache_cr3();
flushmmucache_nopc();
set_use32(1);
set_stack32(1);

View File

@@ -20,6 +20,7 @@
#define _386_COMMON_H_
#include <stddef.h>
#include <inttypes.h>
#define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
#define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
@@ -97,11 +98,11 @@
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
do_mmutranslate((s) + (a), b, 4, 1)
int checkio(uint32_t port);
int checkio(uint32_t port, int mask);
#define check_io_perm(port) \
#define check_io_perm(port, size) \
if (msw & 1 && ((CPL > IOPL) || (cpu_state.eflags & VM_FLAG))) { \
int tempi = checkio(port); \
int tempi = checkio(port, (1 << size) - 1); \
if (cpu_state.abrt) \
return 1; \
if (tempi) { \
@@ -196,13 +197,21 @@ fastreadb(uint32_t a)
uint8_t *t;
if ((a >> 12) == pccache)
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
return *((uint8_t *) &pccache2[a]);
#endif
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache = a >> 12;
pccache2 = t;
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
return *((uint8_t *) &pccache2[a]);
#endif
}
static __inline uint16_t
@@ -216,14 +225,22 @@ fastreadw(uint32_t a)
return val;
}
if ((a >> 12) == pccache)
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
return *((uint16_t *) &pccache2[a]);
#endif
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache = a >> 12;
pccache2 = t;
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
return *((uint16_t *) &pccache2[a]);
#endif
}
static __inline uint32_t
@@ -239,7 +256,11 @@ fastreadl(uint32_t a)
pccache2 = t;
pccache = a >> 12;
}
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint32_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
return *((uint32_t *) &pccache2[a]);
#endif
}
val = fastreadw(a);
val |= (fastreadw(a + 2) << 16);
@@ -250,13 +271,78 @@ static __inline void *
get_ram_ptr(uint32_t a)
{
if ((a >> 12) == pccache)
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return (void *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL));
#else
return &pccache2[a];
#endif
else {
uint8_t *t = getpccache(a);
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return (void *) (((uintptr_t) &t[a] & 0x00000000ffffffffULL) | ((uintptr_t) &t[0] & 0xffffffff00000000ULL));
#else
return &t[a];
#endif
}
}
extern int opcode_length[256];
static __inline uint16_t
fastreadw_fetch(uint32_t a)
{
uint8_t *t;
uint16_t val;
if ((a & 0xFFF) > 0xFFE) {
val = fastreadb(a);
if (opcode_length[val & 0xff] > 1)
val |= (fastreadb(a + 1) << 8);
return val;
}
if ((a >> 12) == pccache)
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
return *((uint16_t *) &pccache2[a]);
#endif
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache = a >> 12;
pccache2 = t;
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
return *((uint16_t *) &pccache2[a]);
#endif
}
static __inline uint32_t
fastreadl_fetch(uint32_t a)
{
uint8_t *t;
uint32_t val;
if ((a & 0xFFF) < 0xFFD) {
if ((a >> 12) != pccache) {
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache2 = t;
pccache = a >> 12;
}
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint32_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
return *((uint32_t *) &pccache2[a]);
#endif
}
val = fastreadw_fetch(a);
if (opcode_length[val & 0xff] > 2)
val |= (fastreadw(a + 2) << 16);
return val;
}
static __inline uint8_t
getbyte(void)
{

View File

@@ -348,7 +348,7 @@ exec386_dynarec_int(void)
cpu_state.ea_seg = &cpu_state.seg_ds;
cpu_state.ssegs = 0;
fetchdat = fastreadl(cs + cpu_state.pc);
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
# ifdef ENABLE_386_DYNAREC_LOG
if (in_smm)
x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat);
@@ -431,7 +431,7 @@ exec386_dynarec_dyn(void)
uint64_t mask = (uint64_t) 1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
# ifdef USE_NEW_DYNAREC
int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK;
uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f);
uint64_t byte_mask = 1ULL << (PAGE_BYTE_MASK_MASK & 0x3f);
if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask))
# else
@@ -572,7 +572,7 @@ exec386_dynarec_dyn(void)
cpu_state.ea_seg = &cpu_state.seg_ds;
cpu_state.ssegs = 0;
fetchdat = fastreadl(cs + cpu_state.pc);
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
# ifdef ENABLE_386_DYNAREC_LOG
if (in_smm)
x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat);
@@ -668,7 +668,7 @@ exec386_dynarec_dyn(void)
cpu_state.ssegs = 0;
codegen_endpc = (cs + cpu_state.pc) + 8;
fetchdat = fastreadl(cs + cpu_state.pc);
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
# ifdef ENABLE_386_DYNAREC_LOG
if (in_smm)

View File

@@ -426,13 +426,13 @@ pfq_write(void)
free in the queue. */
tempw = readmemwf(pfq_ip);
*(uint16_t *) &(pfq[pfq_pos]) = tempw;
pfq_ip += 2;
pfq_ip = (pfq_ip + 2) & 0xffff;
pfq_pos += 2;
} else if (!is8086 && (pfq_pos < pfq_size)) {
/* The 8088 fetches 1 byte at a time, and only if there's at least 1 byte
free in the queue. */
pfq[pfq_pos] = readmembf(pfq_ip);
pfq_ip++;
pfq_ip = (pfq_ip + 1) & 0xffff;
pfq_pos++;
}
}
@@ -440,10 +440,10 @@ pfq_write(void)
static uint8_t
pfq_read(void)
{
uint8_t temp, i;
uint8_t temp;
temp = pfq[0];
for (i = 0; i < (pfq_size - 1); i++)
for (int i = 0; i < (pfq_size - 1); i++)
pfq[i] = pfq[i + 1];
pfq_pos--;
cpu_state.pc = (cpu_state.pc + 1) & 0xffff;
@@ -2248,7 +2248,7 @@ execx86(int cycs)
default:
opcode = orig_opcode;
cpu_state.pc--;
cpu_state.pc = (cpu_state.pc - 1) & 0xffff;
break;
}
} else
@@ -3178,33 +3178,63 @@ execx86(int cycs)
tempw = cpu_state.pc;
if (!hasfpu)
geteaw();
else
switch (opcode) {
case 0xD8:
ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
break;
case 0xD9:
ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDA:
ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDB:
ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDC:
ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
break;
case 0xDD:
ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDE:
ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDF:
ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat);
break;
else {
if (fpu_softfloat) {
switch (opcode) {
case 0xD8:
ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
break;
case 0xD9:
ops_sf_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDA:
ops_sf_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDB:
ops_sf_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDC:
ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
break;
case 0xDD:
ops_sf_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDE:
ops_sf_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDF:
ops_sf_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat);
break;
}
} else {
switch (opcode) {
case 0xD8:
ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
break;
case 0xD9:
ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDA:
ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDB:
ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDC:
ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
break;
case 0xDD:
ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDE:
ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat);
break;
case 0xDF:
ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat);
break;
}
}
}
cpu_state.pc = tempw; /* Do this as the x87 code advances it, which is needed on
the 286+ core, but not here. */
wait(1, 0);

View File

@@ -32,3 +32,6 @@ if(DYNAREC)
codegen_timing_pentium.c codegen_timing_p6.c
codegen_timing_winchip.c codegen_timing_winchip2.c)
endif()
add_subdirectory(softfloat)
target_link_libraries(86Box softfloat)

View File

@@ -74,71 +74,153 @@ enum {
/* Make sure this is as low as possible. */
cpu_state_t cpu_state;
fpu_state_t fpu_state;
/* Place this immediately after. */
uint32_t abrt_error;
#ifdef USE_DYNAREC
const OpFn *x86_dynarec_opcodes, *x86_dynarec_opcodes_0f,
*x86_dynarec_opcodes_d8_a16, *x86_dynarec_opcodes_d8_a32,
*x86_dynarec_opcodes_d9_a16, *x86_dynarec_opcodes_d9_a32,
*x86_dynarec_opcodes_da_a16, *x86_dynarec_opcodes_da_a32,
*x86_dynarec_opcodes_db_a16, *x86_dynarec_opcodes_db_a32,
*x86_dynarec_opcodes_dc_a16, *x86_dynarec_opcodes_dc_a32,
*x86_dynarec_opcodes_dd_a16, *x86_dynarec_opcodes_dd_a32,
*x86_dynarec_opcodes_de_a16, *x86_dynarec_opcodes_de_a32,
*x86_dynarec_opcodes_df_a16, *x86_dynarec_opcodes_df_a32,
*x86_dynarec_opcodes_REPE, *x86_dynarec_opcodes_REPNE,
*x86_dynarec_opcodes_3DNOW;
const OpFn *x86_dynarec_opcodes;
const OpFn *x86_dynarec_opcodes_0f;
const OpFn *x86_dynarec_opcodes_d8_a16;
const OpFn *x86_dynarec_opcodes_d8_a32;
const OpFn *x86_dynarec_opcodes_d9_a16;
const OpFn *x86_dynarec_opcodes_d9_a32;
const OpFn *x86_dynarec_opcodes_da_a16;
const OpFn *x86_dynarec_opcodes_da_a32;
const OpFn *x86_dynarec_opcodes_db_a16;
const OpFn *x86_dynarec_opcodes_db_a32;
const OpFn *x86_dynarec_opcodes_dc_a16;
const OpFn *x86_dynarec_opcodes_dc_a32;
const OpFn *x86_dynarec_opcodes_dd_a16;
const OpFn *x86_dynarec_opcodes_dd_a32;
const OpFn *x86_dynarec_opcodes_de_a16;
const OpFn *x86_dynarec_opcodes_de_a32;
const OpFn *x86_dynarec_opcodes_df_a16;
const OpFn *x86_dynarec_opcodes_df_a32;
const OpFn *x86_dynarec_opcodes_REPE;
const OpFn *x86_dynarec_opcodes_REPNE;
const OpFn *x86_dynarec_opcodes_3DNOW;
#endif
const OpFn *x86_opcodes, *x86_opcodes_0f,
*x86_opcodes_d8_a16, *x86_opcodes_d8_a32,
*x86_opcodes_d9_a16, *x86_opcodes_d9_a32,
*x86_opcodes_da_a16, *x86_opcodes_da_a32,
*x86_opcodes_db_a16, *x86_opcodes_db_a32,
*x86_opcodes_dc_a16, *x86_opcodes_dc_a32,
*x86_opcodes_dd_a16, *x86_opcodes_dd_a32,
*x86_opcodes_de_a16, *x86_opcodes_de_a32,
*x86_opcodes_df_a16, *x86_opcodes_df_a32,
*x86_opcodes_REPE, *x86_opcodes_REPNE,
*x86_opcodes_3DNOW;
const OpFn *x86_opcodes;
const OpFn *x86_opcodes_0f;
const OpFn *x86_opcodes_d8_a16;
const OpFn *x86_opcodes_d8_a32;
const OpFn *x86_opcodes_d9_a16;
const OpFn *x86_opcodes_d9_a32;
const OpFn *x86_opcodes_da_a16;
const OpFn *x86_opcodes_da_a32;
const OpFn *x86_opcodes_db_a16;
const OpFn *x86_opcodes_db_a32;
const OpFn *x86_opcodes_dc_a16;
const OpFn *x86_opcodes_dc_a32;
const OpFn *x86_opcodes_dd_a16;
const OpFn *x86_opcodes_dd_a32;
const OpFn *x86_opcodes_de_a16;
const OpFn *x86_opcodes_de_a32;
const OpFn *x86_opcodes_df_a16;
const OpFn *x86_opcodes_df_a32;
const OpFn *x86_opcodes_REPE;
const OpFn *x86_opcodes_REPNE;
const OpFn *x86_opcodes_3DNOW;
uint16_t cpu_fast_off_count, cpu_fast_off_val;
uint16_t cpu_fast_off_count;
uint16_t cpu_fast_off_val;
uint16_t temp_seg_data[4] = { 0, 0, 0, 0 };
int isa_cycles, cpu_inited,
int isa_cycles;
int cpu_inited;
cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l,
cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles,
cpu_waitstates, cpu_cache_int_enabled, cpu_cache_ext_enabled,
cpu_isa_speed, cpu_pci_speed, cpu_isa_pci_div, cpu_agp_speed, cpu_alt_reset,
int cpu_cycles_read;
int cpu_cycles_read_l;
int cpu_cycles_write;
int cpu_cycles_write_l;
int cpu_prefetch_cycles;
int cpu_prefetch_width;
int cpu_mem_prefetch_cycles;
int cpu_rom_prefetch_cycles;
int cpu_waitstates;
int cpu_cache_int_enabled;
int cpu_cache_ext_enabled;
int cpu_isa_speed;
int cpu_pci_speed;
int cpu_isa_pci_div;
int cpu_agp_speed;
int cpu_alt_reset;
cpu_override, cpu_effective, cpu_multi, cpu_16bitbus, cpu_64bitbus, cpu_busspeed,
cpu_cyrix_alignment, CPUID,
int cpu_override;
int cpu_effective;
int cpu_multi;
int cpu_16bitbus;
int cpu_64bitbus;
int cpu_cyrix_alignment;
int CPUID;
is186, is_nec,
is286, is386, is6117, is486 = 1,
cpu_isintel, cpu_iscyrix, hascache, isibm486, israpidcad, is_vpc,
is_am486, is_am486dxl, is_pentium, is_k5, is_k6, is_p6, is_cxsmm, hasfpu,
int is186;
int is_nec;
int is286;
int is386;
int is6117;
int is486 = 1;
int cpu_isintel;
int cpu_iscyrix;
int hascache;
int isibm486;
int israpidcad;
int is_vpc;
int is_am486;
int is_am486dxl;
int is_pentium;
int is_k5;
int is_k6;
int is_p6;
int is_cxsmm;
int hasfpu;
timing_rr, timing_mr, timing_mrl, timing_rm, timing_rml,
timing_mm, timing_mml, timing_bt, timing_bnt,
timing_int, timing_int_rm, timing_int_v86, timing_int_pm,
timing_int_pm_outer, timing_iret_rm, timing_iret_v86, timing_iret_pm,
timing_iret_pm_outer, timing_call_rm, timing_call_pm, timing_call_pm_gate,
timing_call_pm_gate_inner, timing_retf_rm, timing_retf_pm, timing_retf_pm_outer,
timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate, timing_misaligned;
uint32_t cpu_features, cpu_fast_off_flags;
int timing_rr;
int timing_mr;
int timing_mrl;
int timing_rm;
int timing_rml;
int timing_mm;
int timing_mml;
int timing_bt;
int timing_bnt;
int timing_int;
int timing_int_rm;
int timing_int_v86;
int timing_int_pm;
int timing_int_pm_outer;
int timing_iret_rm;
int timing_iret_v86;
int timing_iret_pm;
int timing_iret_pm_outer;
int timing_call_rm;
int timing_call_pm;
int timing_call_pm_gate;
int timing_call_pm_gate_inner;
int timing_retf_rm;
int timing_retf_pm;
int timing_retf_pm_outer;
int timing_jmp_rm;
int timing_jmp_pm;
int timing_jmp_pm_gate;
int timing_misaligned;
uint32_t cpu_features;
uint32_t cpu_fast_off_flags;
uint32_t _tr[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
uint32_t cache_index = 0;
uint8_t _cache[2048];
uint64_t cpu_CR4_mask, tsc = 0;
uint64_t cpu_CR4_mask;
uint64_t tsc = 0;
uint64_t pmc[2] = { 0, 0 };
double cpu_dmulti;
double cpu_busspeed;
msr_t msr;
@@ -147,11 +229,18 @@ cyrix_t cyrix;
cpu_family_t *cpu_f;
CPU *cpu_s;
uint8_t do_translate = 0, do_translate2 = 0;
uint8_t do_translate = 0;
uint8_t do_translate2 = 0;
void (*cpu_exec)(int cycs);
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
static uint8_t ccr0;
static uint8_t ccr1;
static uint8_t ccr2;
static uint8_t ccr3;
static uint8_t ccr4;
static uint8_t ccr5;
static uint8_t ccr6;
static int cyrix_addr;
@@ -201,6 +290,8 @@ void
cpu_set_edx(void)
{
EDX = cpu_s->edx_reset;
if (fpu_softfloat)
SF_FPU_reset();
}
cpu_family_t *
@@ -222,7 +313,8 @@ cpu_is_eligible(const cpu_family_t *cpu_family, int cpu, int machine)
{
const machine_t *machine_s = &machines[machine];
const CPU *cpu_s = &cpu_family->cpus[cpu];
uint32_t packages, bus_speed;
uint32_t packages;
uint32_t bus_speed;
uint8_t i;
double multi;
@@ -344,6 +436,23 @@ cpu_family_is_eligible(const cpu_family_t *cpu_family, int machine)
return 0;
}
void
SF_FPU_reset(void)
{
if (fpu_type != FPU_NONE) {
fpu_state.cwd = 0x0040;
fpu_state.swd = 0;
fpu_state.tos = 0;
fpu_state.tag = 0x5555;
fpu_state.foo = 0;
fpu_state.fip = 0;
fpu_state.fcs = 0;
fpu_state.fds = 0;
fpu_state.fdp = 0;
memset(fpu_state.st_space, 0, sizeof(floatx80)*8);
}
}
void
cpu_set(void)
{
@@ -437,39 +546,77 @@ 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
x86_opcodes_d8_a16 = ops_fpu_d8_a16;
x86_opcodes_d8_a32 = ops_fpu_d8_a32;
x86_opcodes_d9_a16 = ops_fpu_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_d9_a32;
x86_opcodes_da_a16 = ops_fpu_da_a16;
x86_opcodes_da_a32 = ops_fpu_da_a32;
x86_opcodes_db_a16 = ops_fpu_db_a16;
x86_opcodes_db_a32 = ops_fpu_db_a32;
x86_opcodes_dc_a16 = ops_fpu_dc_a16;
x86_opcodes_dc_a32 = ops_fpu_dc_a32;
x86_opcodes_dd_a16 = ops_fpu_dd_a16;
x86_opcodes_dd_a32 = ops_fpu_dd_a32;
x86_opcodes_de_a16 = ops_fpu_de_a16;
x86_opcodes_de_a32 = ops_fpu_de_a32;
x86_opcodes_df_a16 = ops_fpu_df_a16;
x86_opcodes_df_a32 = ops_fpu_df_a32;
if (fpu_softfloat) {
x86_opcodes_d8_a16 = ops_sf_fpu_d8_a16;
x86_opcodes_d8_a32 = ops_sf_fpu_d8_a32;
x86_opcodes_d9_a16 = ops_sf_fpu_d9_a16;
x86_opcodes_d9_a32 = ops_sf_fpu_d9_a32;
x86_opcodes_da_a16 = ops_sf_fpu_da_a16;
x86_opcodes_da_a32 = ops_sf_fpu_da_a32;
x86_opcodes_db_a16 = ops_sf_fpu_db_a16;
x86_opcodes_db_a32 = ops_sf_fpu_db_a32;
x86_opcodes_dc_a16 = ops_sf_fpu_dc_a16;
x86_opcodes_dc_a32 = ops_sf_fpu_dc_a32;
x86_opcodes_dd_a16 = ops_sf_fpu_dd_a16;
x86_opcodes_dd_a32 = ops_sf_fpu_dd_a32;
x86_opcodes_de_a16 = ops_sf_fpu_de_a16;
x86_opcodes_de_a32 = ops_sf_fpu_de_a32;
x86_opcodes_df_a16 = ops_sf_fpu_df_a16;
x86_opcodes_df_a32 = ops_sf_fpu_df_a32;
} else {
x86_opcodes_d8_a16 = ops_fpu_d8_a16;
x86_opcodes_d8_a32 = ops_fpu_d8_a32;
x86_opcodes_d9_a16 = ops_fpu_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_d9_a32;
x86_opcodes_da_a16 = ops_fpu_da_a16;
x86_opcodes_da_a32 = ops_fpu_da_a32;
x86_opcodes_db_a16 = ops_fpu_db_a16;
x86_opcodes_db_a32 = ops_fpu_db_a32;
x86_opcodes_dc_a16 = ops_fpu_dc_a16;
x86_opcodes_dc_a32 = ops_fpu_dc_a32;
x86_opcodes_dd_a16 = ops_fpu_dd_a16;
x86_opcodes_dd_a32 = ops_fpu_dd_a32;
x86_opcodes_de_a16 = ops_fpu_de_a16;
x86_opcodes_de_a32 = ops_fpu_de_a32;
x86_opcodes_df_a16 = ops_fpu_df_a16;
x86_opcodes_df_a32 = ops_fpu_df_a32;
}
} else {
#ifdef USE_DYNAREC
x86_dynarec_opcodes_d8_a16 = dynarec_ops_nofpu_a16;
@@ -542,35 +689,69 @@ 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
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
x86_opcodes_da_a16 = ops_fpu_287_da_a16;
x86_opcodes_da_a32 = ops_fpu_287_da_a32;
x86_opcodes_db_a16 = ops_fpu_287_db_a16;
x86_opcodes_db_a32 = ops_fpu_287_db_a32;
x86_opcodes_dc_a16 = ops_fpu_287_dc_a16;
x86_opcodes_dc_a32 = ops_fpu_287_dc_a32;
x86_opcodes_dd_a16 = ops_fpu_287_dd_a16;
x86_opcodes_dd_a32 = ops_fpu_287_dd_a32;
x86_opcodes_de_a16 = ops_fpu_287_de_a16;
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
if (fpu_softfloat) {
x86_opcodes_d9_a16 = ops_sf_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_sf_fpu_287_d9_a32;
x86_opcodes_da_a16 = ops_sf_fpu_287_da_a16;
x86_opcodes_da_a32 = ops_sf_fpu_287_da_a32;
x86_opcodes_db_a16 = ops_sf_fpu_287_db_a16;
x86_opcodes_db_a32 = ops_sf_fpu_287_db_a32;
x86_opcodes_dc_a16 = ops_sf_fpu_287_dc_a16;
x86_opcodes_dc_a32 = ops_sf_fpu_287_dc_a32;
x86_opcodes_dd_a16 = ops_sf_fpu_287_dd_a16;
x86_opcodes_dd_a32 = ops_sf_fpu_287_dd_a32;
x86_opcodes_de_a16 = ops_sf_fpu_287_de_a16;
x86_opcodes_de_a32 = ops_sf_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_sf_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_sf_fpu_287_df_a32;
} else {
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
x86_opcodes_da_a16 = ops_fpu_287_da_a16;
x86_opcodes_da_a32 = ops_fpu_287_da_a32;
x86_opcodes_db_a16 = ops_fpu_287_db_a16;
x86_opcodes_db_a32 = ops_fpu_287_db_a32;
x86_opcodes_dc_a16 = ops_fpu_287_dc_a16;
x86_opcodes_dc_a32 = ops_fpu_287_dc_a32;
x86_opcodes_dd_a16 = ops_fpu_287_dd_a16;
x86_opcodes_dd_a32 = ops_fpu_287_dd_a32;
x86_opcodes_de_a16 = ops_fpu_287_de_a16;
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
}
}
timing_rr = 2; /* register dest - register src */
@@ -618,35 +799,69 @@ 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
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
x86_opcodes_da_a16 = ops_fpu_287_da_a16;
x86_opcodes_da_a32 = ops_fpu_287_da_a32;
x86_opcodes_db_a16 = ops_fpu_287_db_a16;
x86_opcodes_db_a32 = ops_fpu_287_db_a32;
x86_opcodes_dc_a16 = ops_fpu_287_dc_a16;
x86_opcodes_dc_a32 = ops_fpu_287_dc_a32;
x86_opcodes_dd_a16 = ops_fpu_287_dd_a16;
x86_opcodes_dd_a32 = ops_fpu_287_dd_a32;
x86_opcodes_de_a16 = ops_fpu_287_de_a16;
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
if (fpu_softfloat) {
x86_opcodes_d9_a16 = ops_sf_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_sf_fpu_287_d9_a32;
x86_opcodes_da_a16 = ops_sf_fpu_287_da_a16;
x86_opcodes_da_a32 = ops_sf_fpu_287_da_a32;
x86_opcodes_db_a16 = ops_sf_fpu_287_db_a16;
x86_opcodes_db_a32 = ops_sf_fpu_287_db_a32;
x86_opcodes_dc_a16 = ops_sf_fpu_287_dc_a16;
x86_opcodes_dc_a32 = ops_sf_fpu_287_dc_a32;
x86_opcodes_dd_a16 = ops_sf_fpu_287_dd_a16;
x86_opcodes_dd_a32 = ops_sf_fpu_287_dd_a32;
x86_opcodes_de_a16 = ops_sf_fpu_287_de_a16;
x86_opcodes_de_a32 = ops_sf_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_sf_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_sf_fpu_287_df_a32;
} else {
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
x86_opcodes_da_a16 = ops_fpu_287_da_a16;
x86_opcodes_da_a32 = ops_fpu_287_da_a32;
x86_opcodes_db_a16 = ops_fpu_287_db_a16;
x86_opcodes_db_a32 = ops_fpu_287_db_a32;
x86_opcodes_dc_a16 = ops_fpu_287_dc_a16;
x86_opcodes_dc_a32 = ops_fpu_287_dc_a32;
x86_opcodes_dd_a16 = ops_fpu_287_dd_a16;
x86_opcodes_dd_a32 = ops_fpu_287_dd_a32;
x86_opcodes_de_a16 = ops_fpu_287_de_a16;
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
}
}
timing_rr = 2; /* register dest - register src */
@@ -1041,19 +1256,37 @@ 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
x86_opcodes_da_a16 = ops_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_fpu_686_da_a32;
x86_opcodes_db_a16 = ops_fpu_686_db_a16;
x86_opcodes_db_a32 = ops_fpu_686_db_a32;
x86_opcodes_df_a16 = ops_fpu_686_df_a16;
x86_opcodes_df_a32 = ops_fpu_686_df_a32;
if (fpu_softfloat) {
x86_opcodes_da_a16 = ops_sf_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_sf_fpu_686_da_a32;
x86_opcodes_db_a16 = ops_sf_fpu_686_db_a16;
x86_opcodes_db_a32 = ops_sf_fpu_686_db_a32;
x86_opcodes_df_a16 = ops_sf_fpu_686_df_a16;
x86_opcodes_df_a32 = ops_sf_fpu_686_df_a32;
} else {
x86_opcodes_da_a16 = ops_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_fpu_686_da_a32;
x86_opcodes_db_a16 = ops_fpu_686_db_a16;
x86_opcodes_db_a32 = ops_fpu_686_db_a32;
x86_opcodes_df_a16 = ops_fpu_686_df_a16;
x86_opcodes_df_a32 = ops_fpu_686_df_a32;
}
}
# ifdef USE_DYNAREC
@@ -1070,7 +1303,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 */
@@ -1244,24 +1478,42 @@ 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);
else
x86_setopcodes(ops_386, ops_pentium2_0f);
#endif
x86_opcodes_da_a16 = ops_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_fpu_686_da_a32;
x86_opcodes_db_a16 = ops_fpu_686_db_a16;
x86_opcodes_db_a32 = ops_fpu_686_db_a32;
x86_opcodes_df_a16 = ops_fpu_686_df_a16;
x86_opcodes_df_a32 = ops_fpu_686_df_a32;
if (fpu_softfloat) {
x86_opcodes_da_a16 = ops_sf_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_sf_fpu_686_da_a32;
x86_opcodes_db_a16 = ops_sf_fpu_686_db_a16;
x86_opcodes_db_a32 = ops_sf_fpu_686_db_a32;
x86_opcodes_df_a16 = ops_sf_fpu_686_df_a16;
x86_opcodes_df_a32 = ops_sf_fpu_686_df_a32;
} else {
x86_opcodes_da_a16 = ops_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_fpu_686_da_a32;
x86_opcodes_db_a16 = ops_fpu_686_db_a16;
x86_opcodes_db_a32 = ops_fpu_686_db_a32;
x86_opcodes_df_a16 = ops_fpu_686_df_a16;
x86_opcodes_df_a32 = ops_fpu_686_df_a32;
}
timing_rr = 1; /* register dest - register src */
timing_rm = 2; /* register dest - memory src */
@@ -1357,7 +1609,7 @@ cpu_set(void)
break;
default:
fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type);
fatal("cpu_set : unknown CPU type %llu\n", cpu_s->cpu_type);
}
switch (fpu_type) {
@@ -1484,7 +1736,7 @@ cpu_current_pc(char *bufp)
sprintf(bufp, "%04X:%04X", CS, cpu_state.pc);
return (bufp);
return bufp;
}
void
@@ -3062,7 +3314,7 @@ cpu_write(uint16_t addr, uint8_t val, void *priv)
if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) {
cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8);
if ((val & 0xf) == 0xf)
cyrix.arr[3].size = 1ull << 32; /* 4 GB */
cyrix.arr[3].size = 1ULL << 32; /* 4 GB */
else if (val & 0xf)
cyrix.arr[3].size = 2048 << (val & 0xf);
else
@@ -3124,6 +3376,9 @@ cpu_read(uint16_t addr, void *priv)
return cpu_s->cyrix_id & 0xff;
case 0xff:
return cpu_s->cyrix_id >> 8;
default:
break;
}
if ((cyrix_addr & 0xf0) == 0xc0)

View File

@@ -21,6 +21,8 @@
#ifndef EMU_CPU_H
#define EMU_CPU_H
#include "softfloat/softfloat.h"
enum {
FPU_NONE,
FPU_8087,
@@ -148,8 +150,10 @@ typedef struct {
uint32_t cpuid_model;
uint16_t cyrix_id;
uint8_t cpu_flags;
int8_t mem_read_cycles, mem_write_cycles;
int8_t cache_read_cycles, cache_write_cycles;
int8_t mem_read_cycles;
int8_t mem_write_cycles;
int8_t cache_read_cycles;
int8_t cache_write_cycles;
int8_t atclk_div;
} CPU;
@@ -213,17 +217,19 @@ typedef union {
uint32_t l;
uint16_t w;
struct {
uint8_t l,
h;
uint8_t l;
uint8_t h;
} b;
} x86reg;
typedef struct {
uint32_t base;
uint32_t limit;
uint8_t access, ar_high;
uint8_t access;
uint8_t ar_high;
uint16_t seg;
uint32_t limit_low, limit_high;
uint32_t limit_low;
uint32_t limit_high;
int checked; /*Non-zero if selector is known to be valid*/
} x86seg;
@@ -241,8 +247,9 @@ typedef union {
typedef struct {
/* IDT WinChip and WinChip 2 MSR's */
uint32_t tr1, tr12; /* 0x00000002, 0x0000000e */
uint32_t cesr; /* 0x00000011 */
uint32_t tr1; /* 0x00000002, 0x0000000e */
uint32_t tr12; /* 0x00000002, 0x0000000e */
uint32_t cesr; /* 0x00000011 */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */
@@ -257,8 +264,9 @@ typedef struct {
uint64_t mtrr_cap; /* 0x000000fe */
/* IDT WinChip and WinChip 2 MSR's that are also on the VIA Cyrix III */
uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */
uint64_t fcr2, fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */
uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */
uint64_t fcr2; /* 0x00000108 (IDT), 0x00001108 (VIA) */
uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t ecx116; /* 0x00000116 */
@@ -274,8 +282,9 @@ typedef struct {
uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t ecx186, ecx187; /* 0x00000186, 0x00000187 */
uint64_t ecx1e0; /* 0x000001e0 */
uint64_t ecx186; /* 0x00000186, 0x00000187 */
uint64_t ecx187; /* 0x00000186, 0x00000187 */
uint64_t ecx1e0; /* 0x000001e0 */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also
on the VIA Cyrix III */
@@ -323,7 +332,8 @@ typedef struct {
uint64_t amd_epmr; /* 0xc0000086 */
/* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */
uint64_t amd_psor, amd_pfir; /* 0xc0000087, 0xc0000088 */
uint64_t amd_psor; /* 0xc0000087, 0xc0000088 */
uint64_t amd_pfir; /* 0xc0000087, 0xc0000088 */
/* K6-3, K6-2P, and K6-3P MSR's */
uint64_t amd_l2aar; /* 0xc0000089 */
@@ -343,33 +353,38 @@ typedef struct {
uint32_t eaaddr;
int flags_op;
uint32_t flags_res,
flags_op1, flags_op2;
uint32_t flags_res;
uint32_t flags_op1;
uint32_t flags_op2;
uint32_t pc,
oldpc, op32;
uint32_t pc;
uint32_t oldpc;
uint32_t op32;
int TOP;
union {
struct {
int8_t rm,
mod,
reg;
int8_t rm;
int8_t mod;
int8_t reg;
} rm_mod_reg;
int32_t rm_mod_reg_data;
} rm_data;
uint8_t ssegs, ismmx,
abrt, _smi_line;
uint8_t ssegs;
uint8_t ismmx;
uint8_t abrt;
uint8_t _smi_line;
int _cycles;
#ifdef FPU_CYCLES
int _cycles, _fpu_cycles, _in_smm;
#else
int _cycles, _in_smm;
int _fpu_cycles;
#endif
int _in_smm;
uint16_t npxs, npxc;
uint16_t npxs;
uint16_t npxc;
double ST[8];
@@ -378,36 +393,58 @@ typedef struct {
MMX_REG MM[8];
#ifdef USE_NEW_DYNAREC
uint32_t old_fp_control, new_fp_control;
uint32_t old_fp_control;
uint32_t new_fp_control;
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
uint16_t old_fp_control2, new_fp_control2;
uint16_t old_fp_control2;
uint16_t new_fp_control2;
# endif
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined __amd64__ || defined _M_X64
uint32_t trunc_fp_control;
uint32_t trunc_fp_control;
# endif
#else
uint16_t old_npxc, new_npxc;
uint16_t old_npxc;
uint16_t new_npxc;
#endif
x86seg seg_cs, seg_ds, seg_es, seg_ss,
seg_fs, seg_gs;
x86seg seg_cs;
x86seg seg_ds;
x86seg seg_es;
x86seg seg_ss;
x86seg seg_fs;
x86seg seg_gs;
union {
uint32_t l;
uint16_t w;
} CR0;
uint16_t flags, eflags;
uint16_t flags;
uint16_t eflags;
uint32_t _smbase;
uint8_t inside_emulation_mode;
} cpu_state_t;
typedef struct {
uint16_t cwd;
uint16_t swd;
uint16_t tag;
uint16_t foo;
uint32_t fip;
uint32_t fdp;
uint16_t fcs;
uint16_t fds;
floatx80 st_space[8];
unsigned char tos;
unsigned char align1;
unsigned char align2;
unsigned char align3;
} fpu_state_t;
#define in_smm cpu_state._in_smm
#define smi_line cpu_state._smi_line
#define smbase cpu_state._smbase
#define smbase cpu_state._smbase
/*The cpu_state.flags below must match in both cpu_cur_status and block->status for a block
to be valid*/
@@ -416,7 +453,11 @@ typedef struct {
#define CPU_STATUS_PMODE (1 << 2)
#define CPU_STATUS_V86 (1 << 3)
#define CPU_STATUS_SMM (1 << 4)
#ifdef USE_NEW_DYNAREC
#define CPU_STATUS_FLAGS 0xff
#else
#define CPU_STATUS_FLAGS 0xffff
#endif
/*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status.
Otherwise they are ignored*/
@@ -480,6 +521,7 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state_t) <= 128)
/* Global variables. */
extern cpu_state_t cpu_state;
extern fpu_state_t fpu_state;
extern const cpu_family_t cpu_families[];
extern const cpu_legacy_machine_t cpu_legacy_table[];
@@ -489,16 +531,29 @@ extern int cpu_override;
extern int cpu_isintel;
extern int cpu_iscyrix;
extern int cpu_16bitbus, cpu_64bitbus;
extern int cpu_busspeed, cpu_pci_speed;
extern int cpu_16bitbus;
extern int cpu_64bitbus;
extern int cpu_pci_speed;
extern int cpu_multi;
extern double cpu_dmulti;
extern double fpu_multi;
extern double cpu_busspeed;
extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment
penalties when crossing 8-byte boundaries*/
extern int is8086, is186, is286, is386, is6117, is486;
extern int is_am486, is_am486dxl, is_pentium, is_k5, is_k6, is_p6, is_cxsmm;
extern int is8086;
extern int is186;
extern int is286;
extern int is386;
extern int is6117;
extern int is486;
extern int is_am486;
extern int is_am486dxl;
extern int is_pentium;
extern int is_k5;
extern int is_k6;
extern int is_p6;
extern int is_cxsmm;
extern int hascache;
extern int isibm486;
extern int is_nec;
@@ -516,7 +571,8 @@ extern int hasfpu;
extern uint32_t cpu_features;
extern int smi_latched, smm_in_hlt;
extern int smi_latched;
extern int smm_in_hlt;
extern int smi_block;
#ifdef USE_NEW_DYNAREC
@@ -532,12 +588,21 @@ extern int cgate16;
extern int cpl_override;
extern int CPUID;
extern uint64_t xt_cpu_multi;
extern int isa_cycles, cpu_inited;
extern uint32_t oldds, oldss, olddslimit, oldsslimit, olddslimitw, oldsslimitw;
extern int isa_cycles;
extern int cpu_inited;
extern uint32_t oldds;
extern uint32_t oldss;
extern uint32_t olddslimit;
extern uint32_t oldsslimit;
extern uint32_t olddslimitw;
extern uint32_t oldsslimitw;
extern uint32_t pccache;
extern uint8_t *pccache2;
extern double bus_timing, isa_timing, pci_timing, agp_timing;
extern double bus_timing;
extern double isa_timing;
extern double pci_timing;
extern double agp_timing;
extern uint64_t pmc[2];
extern uint16_t temp_seg_data[4];
extern uint16_t cs_msr;
@@ -545,13 +610,16 @@ extern uint32_t esp_msr;
extern uint32_t eip_msr;
/* For the AMD K6. */
extern uint64_t amd_efer, star;
extern uint64_t amd_efer;
extern uint64_t star;
#define FPU_CW_Reserved_Bits (0xe0c0)
#define cr0 cpu_state.CR0.l
#define msw cpu_state.CR0.w
extern uint32_t cr2, cr3, cr4;
#define cr0 cpu_state.CR0.l
#define msw cpu_state.CR0.w
extern uint32_t cr2;
extern uint32_t cr3;
extern uint32_t cr4;
extern uint32_t dr[8];
extern uint32_t _tr[8];
extern uint32_t cache_index;
@@ -561,7 +629,10 @@ extern uint8_t _cache[2048];
_cs,_ds,_es,_ss are the segment structures
CS,DS,ES,SS is the 16-bit data
cs,ds,es,ss are defines to the bases*/
extern x86seg gdt, ldt, idt, tr;
extern x86seg gdt;
extern x86seg ldt;
extern x86seg idt;
extern x86seg tr;
extern x86seg _oldds;
#define CS cpu_state.seg_cs.seg
#define DS cpu_state.seg_ds.seg
@@ -578,37 +649,67 @@ extern x86seg _oldds;
#define ISA_CYCLES(x) (x * isa_cycles)
extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l;
extern int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles;
extern int cpu_cycles_read;
extern int cpu_cycles_read_l;
extern int cpu_cycles_write;
extern int cpu_cycles_write_l;
extern int cpu_prefetch_cycles;
extern int cpu_prefetch_width;
extern int cpu_mem_prefetch_cycles;
extern int cpu_rom_prefetch_cycles;
extern int cpu_waitstates;
extern int cpu_cache_int_enabled, cpu_cache_ext_enabled;
extern int cpu_isa_speed, cpu_pci_speed, cpu_agp_speed;
extern int cpu_cache_int_enabled;
extern int cpu_cache_ext_enabled;
extern int cpu_isa_speed;
extern int cpu_pci_speed;
extern int cpu_agp_speed;
extern int timing_rr;
extern int timing_mr, timing_mrl;
extern int timing_rm, timing_rml;
extern int timing_mm, timing_mml;
extern int timing_bt, timing_bnt;
extern int timing_int, timing_int_rm, timing_int_v86, timing_int_pm;
extern int timing_int_pm_outer, timing_iret_rm, timing_iret_v86, timing_iret_pm;
extern int timing_iret_pm_outer, timing_call_rm, timing_call_pm;
extern int timing_call_pm_gate, timing_call_pm_gate_inner;
extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
extern int timing_mr;
extern int timing_mrl;
extern int timing_rm;
extern int timing_rml;
extern int timing_mm;
extern int timing_mml;
extern int timing_bt;
extern int timing_bnt;
extern int timing_int;
extern int timing_int_rm;
extern int timing_int_v86;
extern int timing_int_pm;
extern int timing_int_pm_outer;
extern int timing_iret_rm;
extern int timing_iret_v86;
extern int timing_iret_pm;
extern int timing_iret_pm_outer;
extern int timing_call_rm;
extern int timing_call_pm;
extern int timing_call_pm_gate;
extern int timing_call_pm_gate_inner;
extern int timing_retf_rm;
extern int timing_retf_pm;
extern int timing_retf_pm_outer;
extern int timing_jmp_rm;
extern int timing_jmp_pm;
extern int timing_jmp_pm_gate;
extern int timing_misaligned;
extern int in_sys, unmask_a20_in_smm;
extern int in_sys;
extern int unmask_a20_in_smm;
extern int cycles_main;
extern uint32_t old_rammask;
#ifdef USE_ACYCS
extern int acycs;
#endif
extern int pic_pending, is_vpc;
extern int soft_reset_mask, alt_access;
extern int pic_pending;
extern int is_vpc;
extern int soft_reset_mask;
extern int alt_access;
extern int cpu_end_block_after_ins;
extern uint16_t cpu_fast_off_count, cpu_fast_off_val;
extern uint16_t cpu_fast_off_count;
extern uint16_t cpu_fast_off_val;
extern uint32_t cpu_fast_off_flags;
/* Functions. */
@@ -637,7 +738,7 @@ extern void cpu_CPUID(void);
extern void cpu_RDMSR(void);
extern void cpu_WRMSR(void);
extern int checkio(uint32_t port);
extern int checkio(uint32_t port, int mask);
extern void codegen_block_end(void);
extern void codegen_reset(void);
extern void cpu_set_edx(void);
@@ -683,7 +784,8 @@ extern void x87_dumpregs(void);
extern void x87_reset(void);
#endif
extern int cpu_effective, cpu_alt_reset;
extern int cpu_effective;
extern int cpu_alt_reset;
extern void cpu_dynamic_switch(int new_cpu);
extern void cpu_ven_reset(void);
@@ -708,22 +810,23 @@ void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg);
#define SMHR_VALID (1 << 0)
#define SMHR_ADDR_MASK (0xfffffffc)
typedef struct
{
struct
{
typedef struct {
struct {
uint32_t base;
uint64_t size;
} arr[8];
uint32_t smhr;
} cyrix_t;
extern uint32_t addr64, addr64_2;
extern uint32_t addr64a[8], addr64a_2[8];
extern uint32_t addr64;
extern uint32_t addr64_2;
extern uint32_t addr64a[8];
extern uint32_t addr64a_2[8];
extern int soft_reset_pci;
extern int reset_on_hlt, hlt_reset_pending;
extern int reset_on_hlt;
extern int hlt_reset_pending;
extern cyrix_t cyrix;
@@ -731,7 +834,10 @@ extern uint8_t use_custom_nmi_vector;
extern uint32_t custom_nmi_vector;
extern void (*cpu_exec)(int cycs);
extern uint8_t do_translate, do_translate2;
extern uint8_t do_translate;
extern uint8_t do_translate2;
extern void SF_FPU_reset(void);
extern void reset_808x(int hard);
extern void interrupt_808x(uint16_t addr);

View File

@@ -0,0 +1,17 @@
#
# 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.
#
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
#
# Copyright 2020-2021 David Hrdlička.
#
add_library(softfloat OBJECT f2xm1.cc fpatan.cc fprem.cc fsincos.cc fyl2x.cc softfloat_poly.cc softfloat.cc softfloat16.cc
softfloat-muladd.cc softfloat-round-pack.cc softfloat-specialize.cc softfloatx80.cc)

View File

@@ -0,0 +1,46 @@
#include <stdint.h>
typedef int8_t flag;
typedef uint8_t uint8;
typedef int8_t int8;
typedef uint16_t uint16;
typedef int16_t int16;
typedef uint32_t uint32;
typedef int32_t int32;
typedef uint64_t uint64;
typedef int64_t int64;
/*----------------------------------------------------------------------------
| Each of the following `typedef's defines a type that holds integers
| of _exactly_ the number of bits specified. For instance, for most
| implementation of C, `bits16' and `sbits16' should be `typedef'ed to
| `unsigned short int' and `signed short int' (or `short int'), respectively.
*----------------------------------------------------------------------------*/
typedef uint8_t bits8;
typedef int8_t sbits8;
typedef uint16_t bits16;
typedef int16_t sbits16;
typedef uint32_t bits32;
typedef int32_t sbits32;
typedef uint64_t bits64;
typedef int64_t sbits64;
typedef uint8_t Bit8u;
typedef int8_t Bit8s;
typedef uint16_t Bit16u;
typedef int16_t Bit16s;
typedef uint32_t Bit32u;
typedef int32_t Bit32s;
typedef uint64_t Bit64u;
typedef int64_t Bit64s;
/*----------------------------------------------------------------------------
| The `LIT64' macro takes as its argument a textual integer literal and
| if necessary ``marks'' the literal as having a 64-bit integer type.
| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
| appended with the letters `LL' standing for `long long', which is `gcc's
| name for the 64-bit integer type. Some compilers may allow `LIT64' to be
| defined as the identity macro: `#define LIT64( a ) a'.
*----------------------------------------------------------------------------*/
#define BX_CONST64(a) a##LL
#define BX_CPP_INLINE static __inline

182
src/cpu/softfloat/f2xm1.cc Normal file
View File

@@ -0,0 +1,182 @@
/*============================================================================
This source file is an extension to the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
floating point emulation.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/
/*============================================================================
* Written for Bochs (x86 achitecture simulator) by
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
#define FLOAT128
#include "softfloatx80.h"
#include "softfloat-round-pack.h"
static const floatx80 floatx80_negone = packFloatx80(1, 0x3fff, BX_CONST64(0x8000000000000000));
static const floatx80 floatx80_neghalf = packFloatx80(1, 0x3ffe, BX_CONST64(0x8000000000000000));
static const float128 float128_ln2 =
packFloat128(BX_CONST64(0x3ffe62e42fefa39e), BX_CONST64(0xf35793c7673007e6));
#ifdef BETTER_THAN_PENTIUM
#define LN2_SIG_HI BX_CONST64(0xb17217f7d1cf79ab)
#define LN2_SIG_LO BX_CONST64(0xc9e3b39800000000) /* 96 bit precision */
#else
#define LN2_SIG_HI BX_CONST64(0xb17217f7d1cf79ab)
#define LN2_SIG_LO BX_CONST64(0xc000000000000000) /* 67-bit precision */
#endif
#define EXP_ARR_SIZE 15
static float128 exp_arr[EXP_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0x3ffe000000000000, 0x0000000000000000), /* 2 */
PACK_FLOAT_128(0x3ffc555555555555, 0x5555555555555555), /* 3 */
PACK_FLOAT_128(0x3ffa555555555555, 0x5555555555555555), /* 4 */
PACK_FLOAT_128(0x3ff8111111111111, 0x1111111111111111), /* 5 */
PACK_FLOAT_128(0x3ff56c16c16c16c1, 0x6c16c16c16c16c17), /* 6 */
PACK_FLOAT_128(0x3ff2a01a01a01a01, 0xa01a01a01a01a01a), /* 7 */
PACK_FLOAT_128(0x3fefa01a01a01a01, 0xa01a01a01a01a01a), /* 8 */
PACK_FLOAT_128(0x3fec71de3a556c73, 0x38faac1c88e50017), /* 9 */
PACK_FLOAT_128(0x3fe927e4fb7789f5, 0xc72ef016d3ea6679), /* 10 */
PACK_FLOAT_128(0x3fe5ae64567f544e, 0x38fe747e4b837dc7), /* 11 */
PACK_FLOAT_128(0x3fe21eed8eff8d89, 0x7b544da987acfe85), /* 12 */
PACK_FLOAT_128(0x3fde6124613a86d0, 0x97ca38331d23af68), /* 13 */
PACK_FLOAT_128(0x3fda93974a8c07c9, 0xd20badf145dfa3e5), /* 14 */
PACK_FLOAT_128(0x3fd6ae7f3e733b81, 0xf11d8656b0ee8cb0) /* 15 */
};
extern float128 EvalPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
/* required -1 < x < 1 */
static float128 poly_exp(float128 x, struct float_status_t *status)
{
/*
// 2 3 4 5 6 7 8 9
// x x x x x x x x x
// e - 1 ~ x + --- + --- + --- + --- + --- + --- + --- + --- + ...
// 2! 3! 4! 5! 6! 7! 8! 9!
//
// 2 3 4 5 6 7 8
// x x x x x x x x
// = x [ 1 + --- + --- + --- + --- + --- + --- + --- + --- + ... ]
// 2! 3! 4! 5! 6! 7! 8! 9!
//
// 8 8
// -- 2k -- 2k+1
// p(x) = > C * x q(x) = > C * x
// -- 2k -- 2k+1
// k=0 k=0
//
// x
// e - 1 ~ x * [ p(x) + x * q(x) ]
//
*/
float128 t = EvalPoly(x, exp_arr, EXP_ARR_SIZE, status);
return float128_mul(t, x, status);
}
// =================================================
// x
// FX2M1 Compute 2 - 1
// =================================================
//
// Uses the following identities:
//
// 1. ----------------------------------------------------------
// x x*ln(2)
// 2 = e
//
// 2. ----------------------------------------------------------
// 2 3 4 5 n
// x x x x x x x
// e = 1 + --- + --- + --- + --- + --- + ... + --- + ...
// 1! 2! 3! 4! 5! n!
//
floatx80 f2xm1(floatx80 a, struct float_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
Bit64u zSig0, zSig1, zSig2;
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a))
{
float_raise(status, float_flag_invalid);
return floatx80_default_nan;
}
Bit64u aSig = extractFloatx80Frac(a);
Bit32s aExp = extractFloatx80Exp(a);
int aSign = extractFloatx80Sign(a);
if (aExp == 0x7FFF) {
if ((Bit64u) (aSig<<1))
return propagateFloatx80NaNOne(a, status);
return (aSign) ? floatx80_negone : a;
}
if (aExp == 0) {
if (aSig == 0) return a;
float_raise(status, float_flag_denormal | float_flag_inexact);
normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
tiny_argument:
mul128By64To192(LN2_SIG_HI, LN2_SIG_LO, aSig, &zSig0, &zSig1, &zSig2);
if (0 < (Bit64s) zSig0) {
shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
--aExp;
}
return
roundAndPackFloatx80(80, aSign, aExp, zSig0, zSig1, status);
}
float_raise(status, float_flag_inexact);
if (aExp < 0x3FFF)
{
if (aExp < FLOATX80_EXP_BIAS-68)
goto tiny_argument;
/* ******************************** */
/* using float128 for approximation */
/* ******************************** */
float128 x = floatx80_to_float128(a, status);
x = float128_mul(x, float128_ln2, status);
x = poly_exp(x, status);
return float128_to_floatx80(x, status);
}
else
{
if (a.exp == 0xBFFF && ! (aSig<<1))
return floatx80_neghalf;
return a;
}
}

288
src/cpu/softfloat/fpatan.cc Normal file
View File

@@ -0,0 +1,288 @@
/*============================================================================
This source file is an extension to the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
floating point emulation.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/
/*============================================================================
* Written for Bochs (x86 achitecture simulator) by
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
#define FLOAT128
#include "softfloatx80.h"
#include "softfloat-round-pack.h"
#include "fpu_constant.h"
#define FPATAN_ARR_SIZE 11
static const float128 float128_one =
packFloat128(BX_CONST64(0x3fff000000000000), BX_CONST64(0x0000000000000000));
static const float128 float128_sqrt3 =
packFloat128(BX_CONST64(0x3fffbb67ae8584ca), BX_CONST64(0xa73b25742d7078b8));
static const floatx80 floatx80_pi =
packFloatx80(0, 0x4000, BX_CONST64(0xc90fdaa22168c235));
static const float128 float128_pi2 =
packFloat128(BX_CONST64(0x3fff921fb54442d1), BX_CONST64(0x8469898CC5170416));
static const float128 float128_pi4 =
packFloat128(BX_CONST64(0x3ffe921fb54442d1), BX_CONST64(0x8469898CC5170416));
static const float128 float128_pi6 =
packFloat128(BX_CONST64(0x3ffe0c152382d736), BX_CONST64(0x58465BB32E0F580F));
static float128 atan_arr[FPATAN_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0xbffd555555555555, 0x5555555555555555), /* 3 */
PACK_FLOAT_128(0x3ffc999999999999, 0x999999999999999a), /* 5 */
PACK_FLOAT_128(0xbffc249249249249, 0x2492492492492492), /* 7 */
PACK_FLOAT_128(0x3ffbc71c71c71c71, 0xc71c71c71c71c71c), /* 9 */
PACK_FLOAT_128(0xbffb745d1745d174, 0x5d1745d1745d1746), /* 11 */
PACK_FLOAT_128(0x3ffb3b13b13b13b1, 0x3b13b13b13b13b14), /* 13 */
PACK_FLOAT_128(0xbffb111111111111, 0x1111111111111111), /* 15 */
PACK_FLOAT_128(0x3ffae1e1e1e1e1e1, 0xe1e1e1e1e1e1e1e2), /* 17 */
PACK_FLOAT_128(0xbffaaf286bca1af2, 0x86bca1af286bca1b), /* 19 */
PACK_FLOAT_128(0x3ffa861861861861, 0x8618618618618618) /* 21 */
};
extern float128 OddPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
/* |x| < 1/4 */
static float128 poly_atan(float128 x1, struct float_status_t *status)
{
/*
// 3 5 7 9 11 13 15 17
// x x x x x x x x
// atan(x) ~ x - --- + --- - --- + --- - ---- + ---- - ---- + ----
// 3 5 7 9 11 13 15 17
//
// 2 4 6 8 10 12 14 16
// x x x x x x x x
// = x * [ 1 - --- + --- - --- + --- - ---- + ---- - ---- + ---- ]
// 3 5 7 9 11 13 15 17
//
// 5 5
// -- 4k -- 4k+2
// p(x) = > C * x q(x) = > C * x
// -- 2k -- 2k+1
// k=0 k=0
//
// 2
// atan(x) ~ x * [ p(x) + x * q(x) ]
//
*/
return OddPoly(x1, atan_arr, FPATAN_ARR_SIZE, status);
}
// =================================================
// FPATAN Compute y * log (x)
// 2
// =================================================
//
// Uses the following identities:
//
// 1. ----------------------------------------------------------
//
// atan(-x) = -atan(x)
//
// 2. ----------------------------------------------------------
//
// x + y
// atan(x) + atan(y) = atan -------, xy < 1
// 1-xy
//
// x + y
// atan(x) + atan(y) = atan ------- + PI, x > 0, xy > 1
// 1-xy
//
// x + y
// atan(x) + atan(y) = atan ------- - PI, x < 0, xy > 1
// 1-xy
//
// 3. ----------------------------------------------------------
//
// atan(x) = atan(INF) + atan(- 1/x)
//
// x-1
// atan(x) = PI/4 + atan( ----- )
// x+1
//
// x * sqrt(3) - 1
// atan(x) = PI/6 + atan( ----------------- )
// x + sqrt(3)
//
// 4. ----------------------------------------------------------
// 3 5 7 9 2n+1
// x x x x n x
// atan(x) = x - --- + --- - --- + --- - ... + (-1) ------ + ...
// 3 5 7 9 2n+1
//
floatx80 fpatan(floatx80 a, floatx80 b, struct float_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
float_raise(status, float_flag_invalid);
return floatx80_default_nan;
}
Bit64u aSig = extractFloatx80Frac(a);
Bit32s aExp = extractFloatx80Exp(a);
int aSign = extractFloatx80Sign(a);
Bit64u bSig = extractFloatx80Frac(b);
Bit32s bExp = extractFloatx80Exp(b);
int bSign = extractFloatx80Sign(b);
int zSign = aSign ^ bSign;
if (bExp == 0x7FFF)
{
if ((Bit64u) (bSig<<1))
return propagateFloatx80NaN(a, b, status);
if (aExp == 0x7FFF) {
if ((Bit64u) (aSig<<1))
return propagateFloatx80NaN(a, b, status);
if (aSign) { /* return 3PI/4 */
return roundAndPackFloatx80(80, bSign,
FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, status);
}
else { /* return PI/4 */
return roundAndPackFloatx80(80, bSign,
FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
}
}
if (aSig && (aExp == 0))
float_raise(status, float_flag_denormal);
/* return PI/2 */
return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
}
if (aExp == 0x7FFF)
{
if ((Bit64u) (aSig<<1))
return propagateFloatx80NaN(a, b, status);
if (bSig && (bExp == 0))
float_raise(status, float_flag_denormal);
return_PI_or_ZERO:
if (aSign) { /* return PI */
return roundAndPackFloatx80(80, bSign, FLOATX80_PI_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
} else { /* return 0 */
return packFloatx80(bSign, 0, 0);
}
}
if (bExp == 0)
{
if (bSig == 0) {
if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
goto return_PI_or_ZERO;
}
float_raise(status, float_flag_denormal);
normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
}
if (aExp == 0)
{
if (aSig == 0) /* return PI/2 */
return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
float_raise(status, float_flag_denormal);
normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
}
float_raise(status, float_flag_inexact);
/* |a| = |b| ==> return PI/4 */
if (aSig == bSig && aExp == bExp)
return roundAndPackFloatx80(80, bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
/* ******************************** */
/* using float128 for approximation */
/* ******************************** */
float128 a128 = normalizeRoundAndPackFloat128(0, aExp-0x10, aSig, 0, status);
float128 b128 = normalizeRoundAndPackFloat128(0, bExp-0x10, bSig, 0, status);
float128 x;
int swap = 0, add_pi6 = 0, add_pi4 = 0;
if (aExp > bExp || (aExp == bExp && aSig > bSig))
{
x = float128_div(b128, a128, status);
}
else {
x = float128_div(a128, b128, status);
swap = 1;
}
Bit32s xExp = extractFloat128Exp(x);
if (xExp <= FLOATX80_EXP_BIAS-40)
goto approximation_completed;
if (x.hi >= BX_CONST64(0x3ffe800000000000)) // 3/4 < x < 1
{
/*
arctan(x) = arctan((x-1)/(x+1)) + pi/4
*/
float128 t1 = float128_sub(x, float128_one, status);
float128 t2 = float128_add(x, float128_one, status);
x = float128_div(t1, t2, status);
add_pi4 = 1;
}
else
{
/* argument correction */
if (xExp >= 0x3FFD) // 1/4 < x < 3/4
{
/*
arctan(x) = arctan((x*sqrt(3)-1)/(x+sqrt(3))) + pi/6
*/
float128 t1 = float128_mul(x, float128_sqrt3, status);
float128 t2 = float128_add(x, float128_sqrt3, status);
x = float128_sub(t1, float128_one, status);
x = float128_div(x, t2, status);
add_pi6 = 1;
}
}
x = poly_atan(x, status);
if (add_pi6) x = float128_add(x, float128_pi6, status);
if (add_pi4) x = float128_add(x, float128_pi4, status);
approximation_completed:
if (swap) x = float128_sub(float128_pi2, x, status);
floatx80 result = float128_to_floatx80(x, status);
if (zSign) floatx80_chs(result);
int rSign = extractFloatx80Sign(result);
if (!bSign && rSign)
return floatx80_add(result, floatx80_pi, status);
if (bSign && !rSign)
return floatx80_sub(result, floatx80_pi, status);
return result;
}

196
src/cpu/softfloat/fprem.cc Normal file
View File

@@ -0,0 +1,196 @@
/*============================================================================
This source file is an extension to the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
floating point emulation.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/
/*============================================================================
* Written for Bochs (x86 achitecture simulator) by
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
#include "softfloatx80.h"
#include "softfloat-round-pack.h"
#define USE_estimateDiv128To64
#include "softfloat-macros.h"
/* executes single exponent reduction cycle */
static Bit64u remainder_kernel(Bit64u aSig0, Bit64u bSig, int expDiff, Bit64u *zSig0, Bit64u *zSig1)
{
Bit64u term0, term1;
Bit64u aSig1 = 0;
shortShift128Left(aSig1, aSig0, expDiff, &aSig1, &aSig0);
Bit64u q = estimateDiv128To64(aSig1, aSig0, bSig);
mul64To128(bSig, q, &term0, &term1);
sub128(aSig1, aSig0, term0, term1, zSig1, zSig0);
while ((Bit64s)(*zSig1) < 0) {
--q;
add128(*zSig1, *zSig0, 0, bSig, zSig1, zSig0);
}
return q;
}
static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding_mode, struct float_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
Bit32s aExp, bExp, zExp, expDiff;
Bit64u aSig0, aSig1, bSig;
int aSign;
*q = 0;
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
{
float_raise(status, float_flag_invalid);
*r = floatx80_default_nan;
return -1;
}
aSig0 = extractFloatx80Frac(a);
aExp = extractFloatx80Exp(a);
aSign = extractFloatx80Sign(a);
bSig = extractFloatx80Frac(b);
bExp = extractFloatx80Exp(b);
if (aExp == 0x7FFF) {
if ((Bit64u) (aSig0<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) {
*r = propagateFloatx80NaN(a, b, status);
return -1;
}
float_raise(status, float_flag_invalid);
*r = floatx80_default_nan;
return -1;
}
if (bExp == 0x7FFF) {
if ((Bit64u) (bSig<<1)) {
*r = propagateFloatx80NaN(a, b, status);
return -1;
}
if (aExp == 0 && aSig0) {
float_raise(status, float_flag_denormal);
normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
*r = (a.fraction & BX_CONST64(0x8000000000000000)) ?
packFloatx80(aSign, aExp, aSig0) : a;
return 0;
}
*r = a;
return 0;
}
if (bExp == 0) {
if (bSig == 0) {
float_raise(status, float_flag_invalid);
*r = floatx80_default_nan;
return -1;
}
float_raise(status, float_flag_denormal);
normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
}
if (aExp == 0) {
if (aSig0 == 0) {
*r = a;
return 0;
}
float_raise(status, float_flag_denormal);
normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
}
expDiff = aExp - bExp;
aSig1 = 0;
Bit32u overflow = 0;
if (expDiff >= 64) {
int n = (expDiff & 0x1f) | 0x20;
remainder_kernel(aSig0, bSig, n, &aSig0, &aSig1);
zExp = aExp - n;
overflow = 1;
}
else {
zExp = bExp;
if (expDiff < 0) {
if (expDiff < -1) {
*r = (a.fraction & BX_CONST64(0x8000000000000000)) ?
packFloatx80(aSign, aExp, aSig0) : a;
return 0;
}
shift128Right(aSig0, 0, 1, &aSig0, &aSig1);
expDiff = 0;
}
if (expDiff > 0) {
*q = remainder_kernel(aSig0, bSig, expDiff, &aSig0, &aSig1);
}
else {
if (bSig <= aSig0) {
aSig0 -= bSig;
*q = 1;
}
}
if (rounding_mode == float_round_nearest_even)
{
Bit64u term0, term1;
shift128Right(bSig, 0, 1, &term0, &term1);
if (! lt128(aSig0, aSig1, term0, term1))
{
int lt = lt128(term0, term1, aSig0, aSig1);
int eq = eq128(aSig0, aSig1, term0, term1);
if ((eq && ((*q) & 1)) || lt) {
aSign = !aSign;
++(*q);
}
if (lt) sub128(bSig, 0, aSig0, aSig1, &aSig0, &aSig1);
}
}
}
*r = normalizeRoundAndPackFloatx80(80, aSign, zExp, aSig0, aSig1, status);
return overflow;
}
/*----------------------------------------------------------------------------
| Returns the remainder of the extended double-precision floating-point value
| `a' with respect to the corresponding value `b'. The operation is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status)
{
return do_fprem(a, b, r, q, float_round_nearest_even, status);
}
/*----------------------------------------------------------------------------
| Returns the remainder of the extended double-precision floating-point value
| `a' with respect to the corresponding value `b'. Unlike previous function
| the function does not compute the remainder specified in the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic. This function operates
| differently from the previous function in the way that it rounds the
| quotient of 'a' divided by 'b' to an integer.
*----------------------------------------------------------------------------*/
int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status)
{
return do_fprem(a, b, r, q, float_round_to_zero, status);
}

View File

@@ -0,0 +1,82 @@
/*============================================================================
This source file is an extension to the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
floating point emulation.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/
#ifndef _FPU_CONSTANTS_H_
#define _FPU_CONSTANTS_H_
#include "config.h"
// Pentium CPU uses only 68-bit precision M_PI approximation
//#define BETTER_THAN_PENTIUM
/*============================================================================
* Written for Bochs (x86 achitecture simulator) by
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
//////////////////////////////
// PI, PI/2, PI/4 constants
//////////////////////////////
#define FLOATX80_PI_EXP (0x4000)
// 128-bit PI fraction
#ifdef BETTER_THAN_PENTIUM
#define FLOAT_PI_HI (BX_CONST64(0xc90fdaa22168c234))
#define FLOAT_PI_LO (BX_CONST64(0xc4c6628b80dc1cd1))
#else
#define FLOAT_PI_HI (BX_CONST64(0xc90fdaa22168c234))
#define FLOAT_PI_LO (BX_CONST64(0xC000000000000000))
#endif
#define FLOATX80_PI2_EXP (0x3FFF)
#define FLOATX80_PI4_EXP (0x3FFE)
//////////////////////////////
// 3PI/4 constant
//////////////////////////////
#define FLOATX80_3PI4_EXP (0x4000)
// 128-bit 3PI/4 fraction
#ifdef BETTER_THAN_PENTIUM
#define FLOAT_3PI4_HI (BX_CONST64(0x96cbe3f9990e91a7))
#define FLOAT_3PI4_LO (BX_CONST64(0x9394c9e8a0a5159c))
#else
#define FLOAT_3PI4_HI (BX_CONST64(0x96cbe3f9990e91a7))
#define FLOAT_3PI4_LO (BX_CONST64(0x9000000000000000))
#endif
//////////////////////////////
// 1/LN2 constant
//////////////////////////////
#define FLOAT_LN2INV_EXP (0x3FFF)
// 128-bit 1/LN2 fraction
#ifdef BETTER_THAN_PENTIUM
#define FLOAT_LN2INV_HI (BX_CONST64(0xb8aa3b295c17f0bb))
#define FLOAT_LN2INV_LO (BX_CONST64(0xbe87fed0691d3e89))
#else
#define FLOAT_LN2INV_HI (BX_CONST64(0xb8aa3b295c17f0bb))
#define FLOAT_LN2INV_LO (BX_CONST64(0xC000000000000000))
#endif
#endif

View File

@@ -0,0 +1,441 @@
/*============================================================================
This source file is an extension to the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
floating point emulation.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/
/*============================================================================
* Written for Bochs (x86 achitecture simulator) by
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
#define FLOAT128
#define USE_estimateDiv128To64
#include "softfloatx80.h"
#include "softfloat-round-pack.h"
#include "fpu_constant.h"
static const floatx80 floatx80_one = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
/* reduce trigonometric function argument using 128-bit precision
M_PI approximation */
static Bit64u argument_reduction_kernel(Bit64u aSig0, int Exp, Bit64u *zSig0, Bit64u *zSig1)
{
Bit64u term0, term1, term2;
Bit64u aSig1 = 0;
shortShift128Left(aSig1, aSig0, Exp, &aSig1, &aSig0);
Bit64u q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI);
mul128By64To192(FLOAT_PI_HI, FLOAT_PI_LO, q, &term0, &term1, &term2);
sub128(aSig1, aSig0, term0, term1, zSig1, zSig0);
while ((Bit64s)(*zSig1) < 0) {
--q;
add192(*zSig1, *zSig0, term2, 0, FLOAT_PI_HI, FLOAT_PI_LO, zSig1, zSig0, &term2);
}
*zSig1 = term2;
return q;
}
static int reduce_trig_arg(int expDiff, int *zSign, Bit64u *aSig0, Bit64u *aSig1)
{
Bit64u term0, term1, q = 0;
if (expDiff < 0) {
shift128Right(*aSig0, 0, 1, aSig0, aSig1);
expDiff = 0;
}
if (expDiff > 0) {
q = argument_reduction_kernel(*aSig0, expDiff, aSig0, aSig1);
}
else {
if (FLOAT_PI_HI <= *aSig0) {
*aSig0 -= FLOAT_PI_HI;
q = 1;
}
}
shift128Right(FLOAT_PI_HI, FLOAT_PI_LO, 1, &term0, &term1);
if (! lt128(*aSig0, *aSig1, term0, term1))
{
int lt = lt128(term0, term1, *aSig0, *aSig1);
int eq = eq128(*aSig0, *aSig1, term0, term1);
if ((eq && (q & 1)) || lt) {
*zSign = !(*zSign);
++q;
}
if (lt) sub128(FLOAT_PI_HI, FLOAT_PI_LO, *aSig0, *aSig1, aSig0, aSig1);
}
return (int)(q & 3);
}
#define SIN_ARR_SIZE 11
#define COS_ARR_SIZE 11
static float128 sin_arr[SIN_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0xbffc555555555555, 0x5555555555555555), /* 3 */
PACK_FLOAT_128(0x3ff8111111111111, 0x1111111111111111), /* 5 */
PACK_FLOAT_128(0xbff2a01a01a01a01, 0xa01a01a01a01a01a), /* 7 */
PACK_FLOAT_128(0x3fec71de3a556c73, 0x38faac1c88e50017), /* 9 */
PACK_FLOAT_128(0xbfe5ae64567f544e, 0x38fe747e4b837dc7), /* 11 */
PACK_FLOAT_128(0x3fde6124613a86d0, 0x97ca38331d23af68), /* 13 */
PACK_FLOAT_128(0xbfd6ae7f3e733b81, 0xf11d8656b0ee8cb0), /* 15 */
PACK_FLOAT_128(0x3fce952c77030ad4, 0xa6b2605197771b00), /* 17 */
PACK_FLOAT_128(0xbfc62f49b4681415, 0x724ca1ec3b7b9675), /* 19 */
PACK_FLOAT_128(0x3fbd71b8ef6dcf57, 0x18bef146fcee6e45) /* 21 */
};
static float128 cos_arr[COS_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 0 */
PACK_FLOAT_128(0xbffe000000000000, 0x0000000000000000), /* 2 */
PACK_FLOAT_128(0x3ffa555555555555, 0x5555555555555555), /* 4 */
PACK_FLOAT_128(0xbff56c16c16c16c1, 0x6c16c16c16c16c17), /* 6 */
PACK_FLOAT_128(0x3fefa01a01a01a01, 0xa01a01a01a01a01a), /* 8 */
PACK_FLOAT_128(0xbfe927e4fb7789f5, 0xc72ef016d3ea6679), /* 10 */
PACK_FLOAT_128(0x3fe21eed8eff8d89, 0x7b544da987acfe85), /* 12 */
PACK_FLOAT_128(0xbfda93974a8c07c9, 0xd20badf145dfa3e5), /* 14 */
PACK_FLOAT_128(0x3fd2ae7f3e733b81, 0xf11d8656b0ee8cb0), /* 16 */
PACK_FLOAT_128(0xbfca6827863b97d9, 0x77bb004886a2c2ab), /* 18 */
PACK_FLOAT_128(0x3fc1e542ba402022, 0x507a9cad2bf8f0bb) /* 20 */
};
extern float128 OddPoly (float128 x, float128 *arr, int n, struct float_status_t *status);
/* 0 <= x <= pi/4 */
BX_CPP_INLINE float128 poly_sin(float128 x, struct float_status_t *status)
{
// 3 5 7 9 11 13 15
// x x x x x x x
// sin (x) ~ x - --- + --- - --- + --- - ---- + ---- - ---- =
// 3! 5! 7! 9! 11! 13! 15!
//
// 2 4 6 8 10 12 14
// x x x x x x x
// = x * [ 1 - --- + --- - --- + --- - ---- + ---- - ---- ] =
// 3! 5! 7! 9! 11! 13! 15!
//
// 3 3
// -- 4k -- 4k+2
// p(x) = > C * x > 0 q(x) = > C * x < 0
// -- 2k -- 2k+1
// k=0 k=0
//
// 2
// sin(x) ~ x * [ p(x) + x * q(x) ]
//
return OddPoly(x, sin_arr, SIN_ARR_SIZE, status);
}
extern float128 EvenPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
/* 0 <= x <= pi/4 */
BX_CPP_INLINE float128 poly_cos(float128 x, struct float_status_t *status)
{
// 2 4 6 8 10 12 14
// x x x x x x x
// cos (x) ~ 1 - --- + --- - --- + --- - ---- + ---- - ----
// 2! 4! 6! 8! 10! 12! 14!
//
// 3 3
// -- 4k -- 4k+2
// p(x) = > C * x > 0 q(x) = > C * x < 0
// -- 2k -- 2k+1
// k=0 k=0
//
// 2
// cos(x) ~ [ p(x) + x * q(x) ]
//
return EvenPoly(x, cos_arr, COS_ARR_SIZE, status);
}
BX_CPP_INLINE void sincos_invalid(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
{
if (sin_a) *sin_a = a;
if (cos_a) *cos_a = a;
}
BX_CPP_INLINE void sincos_tiny_argument(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
{
if (sin_a) *sin_a = a;
if (cos_a) *cos_a = floatx80_one;
}
static floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient, struct float_status_t *status)
{
if (quotient & 0x1) {
r = poly_cos(r, status);
neg = 0;
} else {
r = poly_sin(r, status);
}
floatx80 result = float128_to_floatx80(r, status);
if (quotient & 0x2)
neg = ! neg;
if (neg)
floatx80_chs(result);
return result;
}
// =================================================
// FSINCOS Compute sin(x) and cos(x)
// =================================================
//
// Uses the following identities:
// ----------------------------------------------------------
//
// sin(-x) = -sin(x)
// cos(-x) = cos(x)
//
// sin(x+y) = sin(x)*cos(y)+cos(x)*sin(y)
// cos(x+y) = sin(x)*sin(y)+cos(x)*cos(y)
//
// sin(x+ pi/2) = cos(x)
// sin(x+ pi) = -sin(x)
// sin(x+3pi/2) = -cos(x)
// sin(x+2pi) = sin(x)
//
int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
Bit64u aSig0, aSig1 = 0;
Bit32s aExp, zExp, expDiff;
int aSign, zSign;
int q = 0;
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a)) {
goto invalid;
}
aSig0 = extractFloatx80Frac(a);
aExp = extractFloatx80Exp(a);
aSign = extractFloatx80Sign(a);
/* invalid argument */
if (aExp == 0x7FFF) {
if ((Bit64u) (aSig0<<1)) {
sincos_invalid(sin_a, cos_a, propagateFloatx80NaNOne(a, status));
return 0;
}
invalid:
float_raise(status, float_flag_invalid);
sincos_invalid(sin_a, cos_a, floatx80_default_nan);
return 0;
}
if (aExp == 0) {
if (aSig0 == 0) {
sincos_tiny_argument(sin_a, cos_a, a);
return 0;
}
float_raise(status, float_flag_denormal);
/* handle pseudo denormals */
if (! (aSig0 & BX_CONST64(0x8000000000000000)))
{
float_raise(status, float_flag_inexact);
if (sin_a)
float_raise(status, float_flag_underflow);
sincos_tiny_argument(sin_a, cos_a, a);
return 0;
}
normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
}
zSign = aSign;
zExp = FLOATX80_EXP_BIAS;
expDiff = aExp - zExp;
/* argument is out-of-range */
if (expDiff >= 63)
return -1;
float_raise(status, float_flag_inexact);
if (expDiff < -1) { // doesn't require reduction
if (expDiff <= -68) {
a = packFloatx80(aSign, aExp, aSig0);
sincos_tiny_argument(sin_a, cos_a, a);
return 0;
}
zExp = aExp;
}
else {
q = reduce_trig_arg(expDiff, &zSign, &aSig0, &aSig1);
}
/* **************************** */
/* argument reduction completed */
/* **************************** */
/* using float128 for approximation */
float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1, status);
if (aSign) q = -q;
if (sin_a) *sin_a = sincos_approximation(zSign, r, q, status);
if (cos_a) *cos_a = sincos_approximation(zSign, r, q+1, status);
return 0;
}
int fsin(floatx80 *a, struct float_status_t *status)
{
return fsincos(*a, a, 0, status);
}
int fcos(floatx80 *a, struct float_status_t *status)
{
return fsincos(*a, 0, a, status);
}
// =================================================
// FPTAN Compute tan(x)
// =================================================
//
// Uses the following identities:
//
// 1. ----------------------------------------------------------
//
// sin(-x) = -sin(x)
// cos(-x) = cos(x)
//
// sin(x+y) = sin(x)*cos(y)+cos(x)*sin(y)
// cos(x+y) = sin(x)*sin(y)+cos(x)*cos(y)
//
// sin(x+ pi/2) = cos(x)
// sin(x+ pi) = -sin(x)
// sin(x+3pi/2) = -cos(x)
// sin(x+2pi) = sin(x)
//
// 2. ----------------------------------------------------------
//
// sin(x)
// tan(x) = ------
// cos(x)
//
int ftan(floatx80 *a, struct float_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
Bit64u aSig0, aSig1 = 0;
Bit32s aExp, zExp, expDiff;
int aSign, zSign;
int q = 0;
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(*a)) {
goto invalid;
}
aSig0 = extractFloatx80Frac(*a);
aExp = extractFloatx80Exp(*a);
aSign = extractFloatx80Sign(*a);
/* invalid argument */
if (aExp == 0x7FFF) {
if ((Bit64u) (aSig0<<1))
{
*a = propagateFloatx80NaNOne(*a, status);
return 0;
}
invalid:
float_raise(status, float_flag_invalid);
*a = floatx80_default_nan;
return 0;
}
if (aExp == 0) {
if (aSig0 == 0) return 0;
float_raise(status, float_flag_denormal);
/* handle pseudo denormals */
if (! (aSig0 & BX_CONST64(0x8000000000000000)))
{
float_raise(status, float_flag_inexact | float_flag_underflow);
return 0;
}
normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
}
zSign = aSign;
zExp = FLOATX80_EXP_BIAS;
expDiff = aExp - zExp;
/* argument is out-of-range */
if (expDiff >= 63)
return -1;
float_raise(status, float_flag_inexact);
if (expDiff < -1) { // doesn't require reduction
if (expDiff <= -68) {
*a = packFloatx80(aSign, aExp, aSig0);
return 0;
}
zExp = aExp;
}
else {
q = reduce_trig_arg(expDiff, &zSign, &aSig0, &aSig1);
}
/* **************************** */
/* argument reduction completed */
/* **************************** */
/* using float128 for approximation */
float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1, status);
float128 sin_r = poly_sin(r, status);
float128 cos_r = poly_cos(r, status);
if (q & 0x1) {
r = float128_div(cos_r, sin_r, status);
zSign = ! zSign;
} else {
r = float128_div(sin_r, cos_r, status);
}
*a = float128_to_floatx80(r, status);
if (zSign)
floatx80_chs(*a);
return 0;
}

363
src/cpu/softfloat/fyl2x.cc Normal file
View File

@@ -0,0 +1,363 @@
/*============================================================================
This source file is an extension to the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
floating point emulation.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/
/*============================================================================
* Written for Bochs (x86 achitecture simulator) by
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
#define FLOAT128
#include "softfloatx80.h"
#include "softfloat-round-pack.h"
#include "fpu_constant.h"
static const floatx80 floatx80_one =
packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
static const float128 float128_one =
packFloat128(BX_CONST64(0x3fff000000000000), BX_CONST64(0x0000000000000000));
static const float128 float128_two =
packFloat128(BX_CONST64(0x4000000000000000), BX_CONST64(0x0000000000000000));
static const float128 float128_ln2inv2 =
packFloat128(BX_CONST64(0x400071547652b82f), BX_CONST64(0xe1777d0ffda0d23a));
#define SQRT2_HALF_SIG BX_CONST64(0xb504f333f9de6484)
extern float128 OddPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
#define L2_ARR_SIZE 9
static float128 ln_arr[L2_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0x3ffd555555555555, 0x5555555555555555), /* 3 */
PACK_FLOAT_128(0x3ffc999999999999, 0x999999999999999a), /* 5 */
PACK_FLOAT_128(0x3ffc249249249249, 0x2492492492492492), /* 7 */
PACK_FLOAT_128(0x3ffbc71c71c71c71, 0xc71c71c71c71c71c), /* 9 */
PACK_FLOAT_128(0x3ffb745d1745d174, 0x5d1745d1745d1746), /* 11 */
PACK_FLOAT_128(0x3ffb3b13b13b13b1, 0x3b13b13b13b13b14), /* 13 */
PACK_FLOAT_128(0x3ffb111111111111, 0x1111111111111111), /* 15 */
PACK_FLOAT_128(0x3ffae1e1e1e1e1e1, 0xe1e1e1e1e1e1e1e2) /* 17 */
};
static float128 poly_ln(float128 x1, struct float_status_t *status)
{
/*
//
// 3 5 7 9 11 13 15
// 1+u u u u u u u u
// 1/2 ln --- ~ u + --- + --- + --- + --- + ---- + ---- + ---- =
// 1-u 3 5 7 9 11 13 15
//
// 2 4 6 8 10 12 14
// u u u u u u u
// = u * [ 1 + --- + --- + --- + --- + ---- + ---- + ---- ] =
// 3 5 7 9 11 13 15
//
// 3 3
// -- 4k -- 4k+2
// p(u) = > C * u q(u) = > C * u
// -- 2k -- 2k+1
// k=0 k=0
//
// 1+u 2
// 1/2 ln --- ~ u * [ p(u) + u * q(u) ]
// 1-u
//
*/
return OddPoly(x1, ln_arr, L2_ARR_SIZE, status);
}
/* required sqrt(2)/2 < x < sqrt(2) */
static float128 poly_l2(float128 x, struct float_status_t *status)
{
/* using float128 for approximation */
float128 x_p1 = float128_add(x, float128_one, status);
float128 x_m1 = float128_sub(x, float128_one, status);
x = float128_div(x_m1, x_p1, status);
x = poly_ln(x, status);
x = float128_mul(x, float128_ln2inv2, status);
return x;
}
static float128 poly_l2p1(float128 x, struct float_status_t *status)
{
/* using float128 for approximation */
float128 x_p2 = float128_add(x, float128_two, status);
x = float128_div(x, x_p2, status);
x = poly_ln(x, status);
x = float128_mul(x, float128_ln2inv2, status);
return x;
}
// =================================================
// FYL2X Compute y * log (x)
// 2
// =================================================
//
// Uses the following identities:
//
// 1. ----------------------------------------------------------
// ln(x)
// log (x) = -------, ln (x*y) = ln(x) + ln(y)
// 2 ln(2)
//
// 2. ----------------------------------------------------------
// 1+u x-1
// ln (x) = ln -----, when u = -----
// 1-u x+1
//
// 3. ----------------------------------------------------------
// 3 5 7 2n+1
// 1+u u u u u
// ln ----- = 2 [ u + --- + --- + --- + ... + ------ + ... ]
// 1-u 3 5 7 2n+1
//
floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
invalid:
float_raise(status, float_flag_invalid);
return floatx80_default_nan;
}
Bit64u aSig = extractFloatx80Frac(a);
Bit32s aExp = extractFloatx80Exp(a);
int aSign = extractFloatx80Sign(a);
Bit64u bSig = extractFloatx80Frac(b);
Bit32s bExp = extractFloatx80Exp(b);
int bSign = extractFloatx80Sign(b);
int zSign = bSign ^ 1;
if (aExp == 0x7FFF) {
if ((Bit64u) (aSig<<1)
|| ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
{
return propagateFloatx80NaN(a, b, status);
}
if (aSign) goto invalid;
else {
if (bExp == 0) {
if (bSig == 0) goto invalid;
float_raise(status, float_flag_denormal);
}
return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
}
if (bExp == 0x7FFF)
{
if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
if (aSign && (Bit64u)(aExp | aSig)) goto invalid;
if (aSig && (aExp == 0))
float_raise(status, float_flag_denormal);
if (aExp < 0x3FFF) {
return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
if (aExp == 0x3FFF && ((Bit64u) (aSig<<1) == 0)) goto invalid;
return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
if (aExp == 0) {
if (aSig == 0) {
if ((bExp | bSig) == 0) goto invalid;
float_raise(status, float_flag_divbyzero);
return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
if (aSign) goto invalid;
float_raise(status, float_flag_denormal);
normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
}
if (aSign) goto invalid;
if (bExp == 0) {
if (bSig == 0) {
if (aExp < 0x3FFF) return packFloatx80(zSign, 0, 0);
return packFloatx80(bSign, 0, 0);
}
float_raise(status, float_flag_denormal);
normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
}
if (aExp == 0x3FFF && ((Bit64u) (aSig<<1) == 0))
return packFloatx80(bSign, 0, 0);
float_raise(status, float_flag_inexact);
int ExpDiff = aExp - 0x3FFF;
aExp = 0;
if (aSig >= SQRT2_HALF_SIG) {
ExpDiff++;
aExp--;
}
/* ******************************** */
/* using float128 for approximation */
/* ******************************** */
Bit64u zSig0, zSig1;
shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
float128 x = packFloat128Four(0, aExp+0x3FFF, zSig0, zSig1);
x = poly_l2(x, status);
x = float128_add(x, int64_to_float128((Bit64s) ExpDiff), status);
return floatx80_128_mul(b, x, status);
}
// =================================================
// FYL2XP1 Compute y * log (x + 1)
// 2
// =================================================
//
// Uses the following identities:
//
// 1. ----------------------------------------------------------
// ln(x)
// log (x) = -------
// 2 ln(2)
//
// 2. ----------------------------------------------------------
// 1+u x
// ln (x+1) = ln -----, when u = -----
// 1-u x+2
//
// 3. ----------------------------------------------------------
// 3 5 7 2n+1
// 1+u u u u u
// ln ----- = 2 [ u + --- + --- + --- + ... + ------ + ... ]
// 1-u 3 5 7 2n+1
//
floatx80 fyl2xp1(floatx80 a, floatx80 b, struct float_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
Bit32s aExp, bExp;
Bit64u aSig, bSig, zSig0, zSig1, zSig2;
int aSign, bSign;
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
invalid:
float_raise(status, float_flag_invalid);
return floatx80_default_nan;
}
aSig = extractFloatx80Frac(a);
aExp = extractFloatx80Exp(a);
aSign = extractFloatx80Sign(a);
bSig = extractFloatx80Frac(b);
bExp = extractFloatx80Exp(b);
bSign = extractFloatx80Sign(b);
int zSign = aSign ^ bSign;
if (aExp == 0x7FFF) {
if ((Bit64u) (aSig<<1)
|| ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
{
return propagateFloatx80NaN(a, b, status);
}
if (aSign) goto invalid;
else {
if (bExp == 0) {
if (bSig == 0) goto invalid;
float_raise(status, float_flag_denormal);
}
return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
}
if (bExp == 0x7FFF)
{
if ((Bit64u) (bSig<<1))
return propagateFloatx80NaN(a, b, status);
if (aExp == 0) {
if (aSig == 0) goto invalid;
float_raise(status, float_flag_denormal);
}
return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
if (aExp == 0) {
if (aSig == 0) {
if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
return packFloatx80(zSign, 0, 0);
}
float_raise(status, float_flag_denormal);
normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
}
if (bExp == 0) {
if (bSig == 0) return packFloatx80(zSign, 0, 0);
float_raise(status, float_flag_denormal);
normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
}
float_raise(status, float_flag_inexact);
if (aSign && aExp >= 0x3FFF)
return a;
if (aExp >= 0x3FFC) // big argument
{
return fyl2x(floatx80_add(a, floatx80_one, status), b, status);
}
// handle tiny argument
if (aExp < FLOATX80_EXP_BIAS-70)
{
// first order approximation, return (a*b)/ln(2)
Bit32s zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE;
mul128By64To192(FLOAT_LN2INV_HI, FLOAT_LN2INV_LO, aSig, &zSig0, &zSig1, &zSig2);
if (0 < (Bit64s) zSig0) {
shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
--zExp;
}
zExp = zExp + bExp - 0x3FFE;
mul128By64To192(zSig0, zSig1, bSig, &zSig0, &zSig1, &zSig2);
if (0 < (Bit64s) zSig0) {
shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
--zExp;
}
return
roundAndPackFloatx80(80, aSign ^ bSign, zExp, zSig0, zSig1, status);
}
/* ******************************** */
/* using float128 for approximation */
/* ******************************** */
shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
float128 x = packFloat128Four(aSign, aExp, zSig0, zSig1);
x = poly_l2p1(x, status);
return floatx80_128_mul(b, x, status);
}

View File

@@ -0,0 +1,496 @@
/*============================================================================
This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
Package, Release 2b.
Written by John R. Hauser. This work was made possible in part by the
International Computer Science Institute, located at Suite 600, 1947 Center
Street, Berkeley, California 94704. Funding was partially provided by the
National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
arithmetic/SoftFloat.html'.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/
/*============================================================================
* Adapted for Bochs (x86 achitecture simulator) by
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
#ifndef _SOFTFLOAT_COMPARE_H_
#define _SOFTFLOAT_COMPARE_H_
#include "softfloat.h"
// ======= float32 ======= //
typedef int (*float32_compare_method)(float32, float32, struct float_status_t *status);
// 0x00
BX_CPP_INLINE int float32_eq_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_equal);
}
// 0x01
BX_CPP_INLINE int float32_lt_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation == float_relation_less);
}
// 0x02
BX_CPP_INLINE int float32_le_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_equal);
}
// 0x03
BX_CPP_INLINE int float32_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_unordered);
}
// 0x04
BX_CPP_INLINE int float32_neq_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_equal);
}
// 0x05
BX_CPP_INLINE int float32_nlt_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation != float_relation_less);
}
// 0x06
BX_CPP_INLINE int float32_nle_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation != float_relation_less) && (relation != float_relation_equal);
}
// 0x07
BX_CPP_INLINE int float32_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_unordered);
}
// 0x08
BX_CPP_INLINE int float32_eq_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_equal) || (relation == float_relation_unordered);
}
// 0x09
BX_CPP_INLINE int float32_nge_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_unordered);
}
// 0x0a
BX_CPP_INLINE int float32_ngt_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation != float_relation_greater);
}
// 0x0b
BX_CPP_INLINE int float32_false_quiet(float32 a, float32 b, struct float_status_t *status)
{
float32_compare_quiet(a, b, status);
return 0;
}
// 0x0c
BX_CPP_INLINE int float32_neq_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_equal) && (relation != float_relation_unordered);
}
// 0x0d
BX_CPP_INLINE int float32_ge_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation == float_relation_greater) || (relation == float_relation_equal);
}
// 0x0e
BX_CPP_INLINE int float32_gt_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation == float_relation_greater);
}
// 0x0f
BX_CPP_INLINE int float32_true_quiet(float32 a, float32 b, struct float_status_t *status)
{
float32_compare_quiet(a, b, status);
return 1;
}
// 0x10
BX_CPP_INLINE int float32_eq_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation == float_relation_equal);
}
// 0x11
BX_CPP_INLINE int float32_lt_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_less);
}
// 0x12
BX_CPP_INLINE int float32_le_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_equal);
}
// 0x13
BX_CPP_INLINE int float32_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation == float_relation_unordered);
}
// 0x14
BX_CPP_INLINE int float32_neq_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation != float_relation_equal);
}
// 0x15
BX_CPP_INLINE int float32_nlt_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_less);
}
// 0x16
BX_CPP_INLINE int float32_nle_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_less) && (relation != float_relation_equal);
}
// 0x17
BX_CPP_INLINE int float32_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation != float_relation_unordered);
}
// 0x18
BX_CPP_INLINE int float32_eq_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation == float_relation_equal) || (relation == float_relation_unordered);
}
// 0x19
BX_CPP_INLINE int float32_nge_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_unordered);
}
// 0x1a
BX_CPP_INLINE int float32_ngt_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_greater);
}
// 0x1b
BX_CPP_INLINE int float32_false_signalling(float32 a, float32 b, struct float_status_t *status)
{
float32_compare_two(a, b, status);
return 0;
}
// 0x1c
BX_CPP_INLINE int float32_neq_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_two(a, b, status);
return (relation != float_relation_equal) && (relation != float_relation_unordered);
}
// 0x1d
BX_CPP_INLINE int float32_ge_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_greater) || (relation == float_relation_equal);
}
// 0x1e
BX_CPP_INLINE int float32_gt_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_greater);
}
// 0x1f
BX_CPP_INLINE int float32_true_signalling(float32 a, float32 b, struct float_status_t *status)
{
float32_compare_two(a, b, status);
return 1;
}
// ======= float64 ======= //
typedef int (*float64_compare_method)(float64, float64, struct float_status_t *status);
// 0x00
BX_CPP_INLINE int float64_eq_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_equal);
}
// 0x01
BX_CPP_INLINE int float64_lt_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation == float_relation_less);
}
// 0x02
BX_CPP_INLINE int float64_le_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_equal);
}
// 0x03
BX_CPP_INLINE int float64_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_unordered);
}
// 0x04
BX_CPP_INLINE int float64_neq_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_equal);
}
// 0x05
BX_CPP_INLINE int float64_nlt_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation != float_relation_less);
}
// 0x06
BX_CPP_INLINE int float64_nle_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation != float_relation_less) && (relation != float_relation_equal);
}
// 0x07
BX_CPP_INLINE int float64_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_unordered);
}
// 0x08
BX_CPP_INLINE int float64_eq_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_equal) || (relation == float_relation_unordered);
}
// 0x09
BX_CPP_INLINE int float64_nge_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_unordered);
}
// 0x0a
BX_CPP_INLINE int float64_ngt_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation != float_relation_greater);
}
// 0x0b
BX_CPP_INLINE int float64_false_quiet(float64 a, float64 b, struct float_status_t *status)
{
float64_compare_quiet(a, b, status);
return 0;
}
// 0x0c
BX_CPP_INLINE int float64_neq_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_equal) && (relation != float_relation_unordered);
}
// 0x0d
BX_CPP_INLINE int float64_ge_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation == float_relation_greater) || (relation == float_relation_equal);
}
// 0x0e
BX_CPP_INLINE int float64_gt_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation == float_relation_greater);
}
// 0x0f
BX_CPP_INLINE int float64_true_quiet(float64 a, float64 b, struct float_status_t *status)
{
float64_compare_quiet(a, b, status);
return 1;
}
// 0x10
BX_CPP_INLINE int float64_eq_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation == float_relation_equal);
}
// 0x11
BX_CPP_INLINE int float64_lt_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_less);
}
// 0x12
BX_CPP_INLINE int float64_le_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_equal);
}
// 0x13
BX_CPP_INLINE int float64_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation == float_relation_unordered);
}
// 0x14
BX_CPP_INLINE int float64_neq_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation != float_relation_equal);
}
// 0x15
BX_CPP_INLINE int float64_nlt_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_less);
}
// 0x16
BX_CPP_INLINE int float64_nle_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_less) && (relation != float_relation_equal);
}
// 0x17
BX_CPP_INLINE int float64_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation != float_relation_unordered);
}
// 0x18
BX_CPP_INLINE int float64_eq_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation == float_relation_equal) || (relation == float_relation_unordered);
}
// 0x19
BX_CPP_INLINE int float64_nge_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_unordered);
}
// 0x1a
BX_CPP_INLINE int float64_ngt_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_greater);
}
// 0x1b
BX_CPP_INLINE int float64_false_signalling(float64 a, float64 b, struct float_status_t *status)
{
float64_compare_two(a, b, status);
return 0;
}
// 0x1c
BX_CPP_INLINE int float64_neq_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_two(a, b, status);
return (relation != float_relation_equal) && (relation != float_relation_unordered);
}
// 0x1d
BX_CPP_INLINE int float64_ge_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_greater) || (relation == float_relation_equal);
}
// 0x1e
BX_CPP_INLINE int float64_gt_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_greater);
}
// 0x1f
BX_CPP_INLINE int float64_true_signalling(float64 a, float64 b, struct float_status_t *status)
{
float64_compare_two(a, b, status);
return 1;
}
#endif

View File

@@ -0,0 +1,686 @@
/*============================================================================
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b.
Written by John R. Hauser. This work was made possible in part by the
International Computer Science Institute, located at Suite 600, 1947 Center
Street, Berkeley, California 94704. Funding was partially provided by the
National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
arithmetic/SoftFloat.html'.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/
/*============================================================================
* Adapted for Bochs (x86 achitecture simulator) by
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
#ifndef _SOFTFLOAT_MACROS_H_
#define _SOFTFLOAT_MACROS_H_
/*----------------------------------------------------------------------------
| Shifts `a' right by the number of bits given in `count'. If any nonzero
| bits are shifted off, they are ``jammed'' into the least significant bit of
| the result by setting the least significant bit to 1. The value of `count'
| can be arbitrarily large; in particular, if `count' is greater than 16, the
| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE Bit16u shift16RightJamming(Bit16u a, int count)
{
Bit16u z;
if (count == 0) {
z = a;
}
else if (count < 16) {
z = (a>>count) | ((a<<((-count) & 15)) != 0);
}
else {
z = (a != 0);
}
return z;
}
/*----------------------------------------------------------------------------
| Shifts `a' right by the number of bits given in `count'. If any nonzero
| bits are shifted off, they are ``jammed'' into the least significant bit of
| the result by setting the least significant bit to 1. The value of `count'
| can be arbitrarily large; in particular, if `count' is greater than 32, the
| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE Bit32u shift32RightJamming(Bit32u a, int count)
{
Bit32u z;
if (count == 0) {
z = a;
}
else if (count < 32) {
z = (a>>count) | ((a<<((-count) & 31)) != 0);
}
else {
z = (a != 0);
}
return z;
}
/*----------------------------------------------------------------------------
| Shifts `a' right by the number of bits given in `count'. If any nonzero
| bits are shifted off, they are ``jammed'' into the least significant bit of
| the result by setting the least significant bit to 1. The value of `count'
| can be arbitrarily large; in particular, if `count' is greater than 64, the
| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE Bit64u shift64RightJamming(Bit64u a, int count)
{
Bit64u z;
if (count == 0) {
z = a;
}
else if (count < 64) {
z = (a>>count) | ((a << ((-count) & 63)) != 0);
}
else {
z = (a != 0);
}
return z;
}
/*----------------------------------------------------------------------------
| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
| _plus_ the number of bits given in `count'. The shifted result is at most
| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The
| bits shifted off form a second 64-bit result as follows: The _last_ bit
| shifted off is the most-significant bit of the extra result, and the other
| 63 bits of the extra result are all zero if and only if _all_but_the_last_
| bits shifted off were all zero. This extra result is stored in the location
| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large.
| (This routine makes more sense if `a0' and `a1' are considered to form
| a fixed-point value with binary point between `a0' and `a1'. This fixed-
| point value is shifted right by the number of bits given in `count', and
| the integer part of the result is returned at the location pointed to by
| `z0Ptr'. The fractional part of the result may be slightly corrupted as
| described above, and is returned at the location pointed to by `z1Ptr'.)
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void shift64ExtraRightJamming(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr)
{
Bit64u z0, z1;
int negCount = (-count) & 63;
if (count == 0) {
z1 = a1;
z0 = a0;
}
else if (count < 64) {
z1 = (a0<<negCount) | (a1 != 0);
z0 = a0>>count;
}
else {
if (count == 64) {
z1 = a0 | (a1 != 0);
}
else {
z1 = ((a0 | a1) != 0);
}
z0 = 0;
}
*z1Ptr = z1;
*z0Ptr = z0;
}
/*----------------------------------------------------------------------------
| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so
| any carry out is lost. The result is broken into two 64-bit pieces which
| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void add128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1, Bit64u *z0Ptr, Bit64u *z1Ptr)
{
Bit64u z1 = a1 + b1;
*z1Ptr = z1;
*z0Ptr = a0 + b0 + (z1 < a1);
}
/*----------------------------------------------------------------------------
| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo
| 2^128, so any borrow out (carry out) is lost. The result is broken into two
| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
| `z1Ptr'.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void
sub128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1, Bit64u *z0Ptr, Bit64u *z1Ptr)
{
*z1Ptr = a1 - b1;
*z0Ptr = a0 - b0 - (a1 < b1);
}
/*----------------------------------------------------------------------------
| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken
| into two 64-bit pieces which are stored at the locations pointed to by
| `z0Ptr' and `z1Ptr'.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void mul64To128(Bit64u a, Bit64u b, Bit64u *z0Ptr, Bit64u *z1Ptr)
{
Bit32u aHigh, aLow, bHigh, bLow;
Bit64u z0, zMiddleA, zMiddleB, z1;
aLow = (Bit32u) a;
aHigh = (Bit32u)(a>>32);
bLow = (Bit32u) b;
bHigh = (Bit32u)(b>>32);
z1 = ((Bit64u) aLow) * bLow;
zMiddleA = ((Bit64u) aLow) * bHigh;
zMiddleB = ((Bit64u) aHigh) * bLow;
z0 = ((Bit64u) aHigh) * bHigh;
zMiddleA += zMiddleB;
z0 += (((Bit64u) (zMiddleA < zMiddleB))<<32) + (zMiddleA>>32);
zMiddleA <<= 32;
z1 += zMiddleA;
z0 += (z1 < zMiddleA);
*z1Ptr = z1;
*z0Ptr = z0;
}
/*----------------------------------------------------------------------------
| Returns an approximation to the 64-bit integer quotient obtained by dividing
| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The
| divisor `b' must be at least 2^63. If q is the exact quotient truncated
| toward zero, the approximation returned lies between q and q + 2 inclusive.
| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
| unsigned integer is returned.
*----------------------------------------------------------------------------*/
#ifdef USE_estimateDiv128To64
static Bit64u estimateDiv128To64(Bit64u a0, Bit64u a1, Bit64u b)
{
Bit64u b0, b1;
Bit64u rem0, rem1, term0, term1;
Bit64u z;
if (b <= a0) return BX_CONST64(0xFFFFFFFFFFFFFFFF);
b0 = b>>32;
z = (b0<<32 <= a0) ? BX_CONST64(0xFFFFFFFF00000000) : (a0 / b0)<<32;
mul64To128(b, z, &term0, &term1);
sub128(a0, a1, term0, term1, &rem0, &rem1);
while (((Bit64s) rem0) < 0) {
z -= BX_CONST64(0x100000000);
b1 = b<<32;
add128(rem0, rem1, b0, b1, &rem0, &rem1);
}
rem0 = (rem0<<32) | (rem1>>32);
z |= (b0<<32 <= rem0) ? 0xFFFFFFFF : rem0 / b0;
return z;
}
#endif
/*----------------------------------------------------------------------------
| Returns an approximation to the square root of the 32-bit significand given
| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of
| `aExp' (the least significant bit) is 1, the integer returned approximates
| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp'
| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either
| case, the approximation returned lies strictly within +/-2 of the exact
| value.
*----------------------------------------------------------------------------*/
#ifdef USE_estimateSqrt32
static Bit32u estimateSqrt32(Bit16s aExp, Bit32u a)
{
static const Bit16u sqrtOddAdjustments[] = {
0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
};
static const Bit16u sqrtEvenAdjustments[] = {
0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
};
Bit32u z;
int index = (a>>27) & 15;
if (aExp & 1) {
z = 0x4000 + (a>>17) - sqrtOddAdjustments[index];
z = ((a / z)<<14) + (z<<15);
a >>= 1;
}
else {
z = 0x8000 + (a>>17) - sqrtEvenAdjustments[index];
z = a / z + z;
z = (0x20000 <= z) ? 0xFFFF8000 : (z<<15);
if (z <= a) return (Bit32u) (((Bit32s) a)>>1);
}
return ((Bit32u) ((((Bit64u) a)<<31) / z)) + (z>>1);
}
#endif
static const int countLeadingZeros8[] = {
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#ifdef FLOAT16
/*----------------------------------------------------------------------------
| Returns the number of leading 0 bits before the most-significant 1 bit of
| `a'. If `a' is zero, 16 is returned.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE int countLeadingZeros16(Bit16u a)
{
int shiftCount = 0;
if (a < 0x100) {
shiftCount += 8;
a <<= 8;
}
shiftCount += countLeadingZeros8[a>>8];
return shiftCount;
}
#endif
/*----------------------------------------------------------------------------
| Returns the number of leading 0 bits before the most-significant 1 bit of
| `a'. If `a' is zero, 32 is returned.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE int countLeadingZeros32(Bit32u a)
{
int shiftCount = 0;
if (a < 0x10000) {
shiftCount += 16;
a <<= 16;
}
if (a < 0x1000000) {
shiftCount += 8;
a <<= 8;
}
shiftCount += countLeadingZeros8[a>>24];
return shiftCount;
}
/*----------------------------------------------------------------------------
| Returns the number of leading 0 bits before the most-significant 1 bit of
| `a'. If `a' is zero, 64 is returned.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE int countLeadingZeros64(Bit64u a)
{
int shiftCount = 0;
if (a < BX_CONST64(0x100000000)) {
shiftCount += 32;
}
else {
a >>= 32;
}
shiftCount += countLeadingZeros32((Bit32u)(a));
return shiftCount;
}
#ifdef FLOATX80
/*----------------------------------------------------------------------------
| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
| number of bits given in `count'. Any bits shifted off are lost. The value
| of `count' can be arbitrarily large; in particular, if `count' is greater
| than 128, the result will be 0. The result is broken into two 64-bit pieces
| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void shift128Right(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr)
{
Bit64u z0, z1;
int negCount = (-count) & 63;
if (count == 0) {
z1 = a1;
z0 = a0;
}
else if (count < 64) {
z1 = (a0<<negCount) | (a1>>count);
z0 = a0>>count;
}
else {
z1 = (count < 128) ? (a0>>(count & 63)) : 0;
z0 = 0;
}
*z1Ptr = z1;
*z0Ptr = z0;
}
/*----------------------------------------------------------------------------
| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
| number of bits given in `count'. If any nonzero bits are shifted off, they
| are ``jammed'' into the least significant bit of the result by setting the
| least significant bit to 1. The value of `count' can be arbitrarily large;
| in particular, if `count' is greater than 128, the result will be either
| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
| nonzero. The result is broken into two 64-bit pieces which are stored at
| the locations pointed to by `z0Ptr' and `z1Ptr'.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void shift128RightJamming(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr)
{
Bit64u z0, z1;
int negCount = (-count) & 63;
if (count == 0) {
z1 = a1;
z0 = a0;
}
else if (count < 64) {
z1 = (a0<<negCount) | (a1>>count) | ((a1<<negCount) != 0);
z0 = a0>>count;
}
else {
if (count == 64) {
z1 = a0 | (a1 != 0);
}
else if (count < 128) {
z1 = (a0>>(count & 63)) | (((a0<<negCount) | a1) != 0);
}
else {
z1 = ((a0 | a1) != 0);
}
z0 = 0;
}
*z1Ptr = z1;
*z0Ptr = z0;
}
/*----------------------------------------------------------------------------
| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
| number of bits given in `count'. Any bits shifted off are lost. The value
| of `count' must be less than 64. The result is broken into two 64-bit
| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void shortShift128Left(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr)
{
*z1Ptr = a1<<count;
*z0Ptr = (count == 0) ? a0 : (a0<<count) | (a1>>((-count) & 63));
}
/*----------------------------------------------------------------------------
| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is
| modulo 2^192, so any carry out is lost. The result is broken into three
| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
| `z1Ptr', and `z2Ptr'.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void add192(
Bit64u a0,
Bit64u a1,
Bit64u a2,
Bit64u b0,
Bit64u b1,
Bit64u b2,
Bit64u *z0Ptr,
Bit64u *z1Ptr,
Bit64u *z2Ptr
)
{
Bit64u z0, z1, z2;
unsigned carry0, carry1;
z2 = a2 + b2;
carry1 = (z2 < a2);
z1 = a1 + b1;
carry0 = (z1 < a1);
z0 = a0 + b0;
z1 += carry1;
z0 += (z1 < carry1);
z0 += carry0;
*z2Ptr = z2;
*z1Ptr = z1;
*z0Ptr = z0;
}
/*----------------------------------------------------------------------------
| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
| from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The
| result is broken into three 64-bit pieces which are stored at the locations
| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void sub192(
Bit64u a0,
Bit64u a1,
Bit64u a2,
Bit64u b0,
Bit64u b1,
Bit64u b2,
Bit64u *z0Ptr,
Bit64u *z1Ptr,
Bit64u *z2Ptr
)
{
Bit64u z0, z1, z2;
unsigned borrow0, borrow1;
z2 = a2 - b2;
borrow1 = (a2 < b2);
z1 = a1 - b1;
borrow0 = (a1 < b1);
z0 = a0 - b0;
z0 -= (z1 < borrow1);
z1 -= borrow1;
z0 -= borrow0;
*z2Ptr = z2;
*z1Ptr = z1;
*z0Ptr = z0;
}
/*----------------------------------------------------------------------------
| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
| is equal to the 128-bit value formed by concatenating `b0' and `b1'.
| Otherwise, returns 0.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE int eq128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1)
{
return (a0 == b0) && (a1 == b1);
}
/*----------------------------------------------------------------------------
| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
| than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
| Otherwise, returns 0.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE int le128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1)
{
return (a0 < b0) || ((a0 == b0) && (a1 <= b1));
}
/*----------------------------------------------------------------------------
| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise,
| returns 0.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE int lt128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1)
{
return (a0 < b0) || ((a0 == b0) && (a1 < b1));
}
#endif /* FLOATX80 */
/*----------------------------------------------------------------------------
| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by
| `b' to obtain a 192-bit product. The product is broken into three 64-bit
| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
| `z2Ptr'.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void mul128By64To192(
Bit64u a0,
Bit64u a1,
Bit64u b,
Bit64u *z0Ptr,
Bit64u *z1Ptr,
Bit64u *z2Ptr
)
{
Bit64u z0, z1, z2, more1;
mul64To128(a1, b, &z1, &z2);
mul64To128(a0, b, &z0, &more1);
add128(z0, more1, 0, z1, &z0, &z1);
*z2Ptr = z2;
*z1Ptr = z1;
*z0Ptr = z0;
}
#ifdef FLOAT128
/*----------------------------------------------------------------------------
| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
| product. The product is broken into four 64-bit pieces which are stored at
| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void mul128To256(
Bit64u a0,
Bit64u a1,
Bit64u b0,
Bit64u b1,
Bit64u *z0Ptr,
Bit64u *z1Ptr,
Bit64u *z2Ptr,
Bit64u *z3Ptr
)
{
Bit64u z0, z1, z2, z3;
Bit64u more1, more2;
mul64To128(a1, b1, &z2, &z3);
mul64To128(a1, b0, &z1, &more2);
add128(z1, more2, 0, z2, &z1, &z2);
mul64To128(a0, b0, &z0, &more1);
add128(z0, more1, 0, z1, &z0, &z1);
mul64To128(a0, b1, &more1, &more2);
add128(more1, more2, 0, z2, &more1, &z2);
add128(z0, z1, 0, more1, &z0, &z1);
*z3Ptr = z3;
*z2Ptr = z2;
*z1Ptr = z1;
*z0Ptr = z0;
}
/*----------------------------------------------------------------------------
| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
| by 64 _plus_ the number of bits given in `count'. The shifted result is
| at most 128 nonzero bits; these are broken into two 64-bit pieces which are
| stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted
| off form a third 64-bit result as follows: The _last_ bit shifted off is
| the most-significant bit of the extra result, and the other 63 bits of the
| extra result are all zero if and only if _all_but_the_last_ bits shifted off
| were all zero. This extra result is stored in the location pointed to by
| `z2Ptr'. The value of `count' can be arbitrarily large.
| (This routine makes more sense if `a0', `a1', and `a2' are considered
| to form a fixed-point value with binary point between `a1' and `a2'. This
| fixed-point value is shifted right by the number of bits given in `count',
| and the integer part of the result is returned at the locations pointed to
| by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly
| corrupted as described above, and is returned at the location pointed to by
| `z2Ptr'.)
*----------------------------------------------------------------------------*/
BX_CPP_INLINE void shift128ExtraRightJamming(
Bit64u a0,
Bit64u a1,
Bit64u a2,
int count,
Bit64u *z0Ptr,
Bit64u *z1Ptr,
Bit64u *z2Ptr
)
{
Bit64u z0, z1, z2;
int negCount = (-count) & 63;
if (count == 0) {
z2 = a2;
z1 = a1;
z0 = a0;
}
else {
if (count < 64) {
z2 = a1<<negCount;
z1 = (a0<<negCount) | (a1>>count);
z0 = a0>>count;
}
else {
if (count == 64) {
z2 = a1;
z1 = a0;
}
else {
a2 |= a1;
if (count < 128) {
z2 = a0<<negCount;
z1 = a0>>(count & 63);
}
else {
z2 = (count == 128) ? a0 : (a0 != 0);
z1 = 0;
}
}
z0 = 0;
}
z2 |= (a2 != 0);
}
*z2Ptr = z2;
*z1Ptr = z1;
*z0Ptr = z0;
}
#endif /* FLOAT128 */
#endif

Some files were not shown because too many files have changed in this diff Show More