diff --git a/.gitignore b/.gitignore index bac8fe436..cc9da153b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ src/*.o src/*.exe src/*.res +src/*.d src/NUL diff --git a/src/386.txt b/src/386.txt new file mode 100644 index 000000000..18686e42d --- /dev/null +++ b/src/386.txt @@ -0,0 +1,3 @@ +Comparing files CPU\386.c and CPU_NEW\386.C +FC: no differences encountered + diff --git a/src/386_common.txt b/src/386_common.txt new file mode 100644 index 000000000..09472e03d --- /dev/null +++ b/src/386_common.txt @@ -0,0 +1,3 @@ +Comparing files CPU\386_common.h and CPU_NEW\386_COMMON.H +FC: no differences encountered + diff --git a/src/386_dynarec.txt b/src/386_dynarec.txt new file mode 100644 index 000000000..0ceb013df --- /dev/null +++ b/src/386_dynarec.txt @@ -0,0 +1,3 @@ +Comparing files CPU\386_dynarec.c and CPU_NEW\386_DYNAREC.C +FC: no differences encountered + diff --git a/src/386_dynarec_ops.txt b/src/386_dynarec_ops.txt new file mode 100644 index 000000000..47a24c719 --- /dev/null +++ b/src/386_dynarec_ops.txt @@ -0,0 +1,3 @@ +Comparing files CPU\386_dynarec_ops.c and CPU_NEW\386_DYNAREC_OPS.C +FC: no differences encountered + diff --git a/src/386_ops.txt b/src/386_ops.txt new file mode 100644 index 000000000..b16faec06 --- /dev/null +++ b/src/386_ops.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops.h and CPU_NEW\X86_OPS.H +FC: no differences encountered + diff --git a/src/808x.txt b/src/808x.txt new file mode 100644 index 000000000..78b95f4ac --- /dev/null +++ b/src/808x.txt @@ -0,0 +1,205 @@ +Comparing files CPU\808x.c and CPU_NEW\808X.C +***** CPU\808x.c + * + * Version: @(#)808x.c 1.0.11 2019/10/21 + * +***** CPU_NEW\808X.C + * + * Version: @(#)808x.c 1.0.9 2019/02/13 + * +***** + +***** CPU\808x.c +#include + +#define HAVE_STDARG_H +***** CPU_NEW\808X.C +#include +#define HAVE_STDARG_H +***** + +***** CPU\808x.c +int nmi = 0, nmi_auto_clear = 0; +int nmi_enable = 1; + +***** CPU_NEW\808X.C +int nmi = 0, nmi_auto_clear = 0; + +***** + +***** CPU\808x.c + + /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ + tsc += (uint64_t)diff * ((uint64_t)xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then +***** CPU_NEW\808X.C + + /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ + tsc += (uint64_t)diff * ((uint64_t)xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then +***** + +***** CPU\808x.c + pfq_add(c, !bus); + if (bus < 2) { + // clock_end(); + // clock_start(); + } +} +***** CPU_NEW\808X.C + pfq_add(c, !bus); + clock_end(); + clock_start(); +} +***** + +***** CPU\808x.c +{ + if (c <= 0) + return; + + cycles -= c; +***** CPU_NEW\808X.C +{ + cycles -= c; +***** + +***** CPU\808x.c + if (!is286) + fetch_and_bus(c, 2); +} +***** CPU_NEW\808X.C + if (!is286) + fetch_and_bus(c, 1); +} +***** + +***** CPU\808x.c + +static uint32_t +sign_extend32(uint16_t data) +{ + return data + (data < 0x8000 ? 0 : 0xffff0000); +} + + +/* Fetches the effective address from the prefetch queue according to MOD and R/M. */ +***** CPU_NEW\808X.C + +/* Fetches the effective address from the prefetch queue according to MOD and R/M. */ +***** + +***** CPU\808x.c + cpu_state.pc = 0xFFF0; + cpu_state.seg_cs.base = 0xFFFF0000; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; +***** CPU_NEW\808X.C + cpu_state.pc = 0xFFF0; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; +***** + +***** CPU\808x.c + resetmcr(); + cpu_set_edx(); +***** CPU_NEW\808X.C + resetmcr(); + pfq_clear(); + cpu_set_edx(); +***** + +***** CPU\808x.c +#endif + if (!hard) + flushmmucache(); + x86_was_reset = 1; +***** CPU_NEW\808X.C +#endif + if (!hard) + flushmmucache(); + x86_was_reset = 1; +***** + +***** CPU\808x.c + + pfq_clear(); + prefetching = 1; + + takeint = 0; +***** CPU_NEW\808X.C + + prefetching = 1; + takeint = 0; +***** + +***** CPU\808x.c + cpu_ven_reset(); + + cpu_alu_op = 0; +} +***** CPU_NEW\808X.C + cpu_ven_reset(); +} +***** + +***** CPU\808x.c + + /* This has to be done so that the special case of ADD does not kick in. */ + size_mask = (1 << bit_count) - 1; +***** CPU_NEW\808X.C + + size_mask = (1 << bit_count) - 1; +***** + +***** CPU\808x.c + uint16_t new_cs, new_ip; + uint32_t result; + int bits; +***** CPU_NEW\808X.C + uint16_t new_cs, new_ip; + int bits; +***** + +***** CPU\808x.c + if (opcode & 1) { + result = cpu_data; + mul(AX, cpu_data); +***** CPU_NEW\808X.C + if (opcode & 1) { + mul(AX, cpu_data); +***** + +***** CPU\808x.c + cpu_data |= DX; + result = ((uint32_t) DX << 16) | AX; + if ((rmdat & 0x38) == 0x20) + set_co_mul(DX != 0x0000); + else + set_co_mul(result != sign_extend32(AX)); + } else { +***** CPU_NEW\808X.C + cpu_data |= DX; + set_co_mul(DX != ((AX & 0x8000) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xffff)); + } else { +***** + +***** CPU\808x.c + cpu_data |= AH; + if ((rmdat & 0x38) == 0x20) + set_co_mul(AH != 0x00); + else + set_co_mul(AX != sign_extend(AL)); + } +***** CPU_NEW\808X.C + cpu_data |= AH; + set_co_mul(AH != ((AL & 0x80) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xff)); + } +***** + +***** CPU\808x.c + noint = 0; + + cpu_alu_op = 0; + } +***** CPU_NEW\808X.C + noint = 0; + } +***** + diff --git a/src/86box.h b/src/86box.h index 7df924036..30a5088e1 100644 --- a/src/86box.h +++ b/src/86box.h @@ -99,6 +99,7 @@ extern int vid_cga_contrast, /* (C) video */ gfxcard; /* (C) graphics/video card */ extern int serial_enabled[], /* (C) enable serial ports */ bugger_enabled, /* (C) enable ISAbugger */ + postcard_enabled, /* (C) enable POST card */ isamem_type[], /* (C) enable ISA mem cards */ isartc_type; /* (C) enable ISA RTC card */ extern int sound_is_float, /* (C) sound uses FP values */ diff --git a/src/io.h b/src/86box_io.h similarity index 100% rename from src/io.h rename to src/86box_io.h diff --git a/src/apm.c b/src/apm.c index 1ec2fb6de..27c33474e 100644 --- a/src/apm.c +++ b/src/apm.c @@ -21,9 +21,9 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu/cpu.h" +#include "cpu.h" #include "device.h" -#include "io.h" +#include "86box_io.h" typedef struct diff --git a/src/apm_new.c b/src/apm_new.c index a0963cade..2ae56d82e 100644 --- a/src/apm_new.c +++ b/src/apm_new.c @@ -21,9 +21,9 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu_new/cpu.h" +#include "cpu.h" #include "device.h" -#include "io.h" +#include "86box_io.h" typedef struct diff --git a/src/bugger.c b/src/bugger.c index cd2d843d9..7205ea25d 100644 --- a/src/bugger.c +++ b/src/bugger.c @@ -56,7 +56,7 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "device.h" #include "plat.h" #include "ui.h" diff --git a/src/cassette/cassette.c b/src/cassette/cassette.c deleted file mode 100644 index b9ba8a7ca..000000000 --- a/src/cassette/cassette.c +++ /dev/null @@ -1,203 +0,0 @@ -/************************************************************************ - - PCEM: IBM 5150 Cassette support - - Copyright (C) 2019 John Elliott - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*************************************************************************/ - -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../ppi.h" -#include "../ui.h" -#include "../plat.h" -#include "pzx.h" -#include "cassette.h" - -typedef struct cassette_t -{ - uint8_t motor; /* Motor status */ - pzxfile_t pzx; - int cycles_last; /* Cycle count at last cassette poll */ - -} cassette_t; - -wchar_t cassettefn[256]; - -static cassette_t *st_cas; - - -#ifdef ENABLE_CASSETTE_LOG -int cassette_do_log = ENABLE_CASSETTE_LOG; - - -static void -cassette_log(const char *fmt, ...) -{ - va_list ap; - - if (cassette_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define cassette_log(fmt, ...) -#endif - - -/* The PCEM CPU uses IBM cycles (4.77MHz). PZX uses Spectrum cycles (3.5MHz) - * so scale accordingly. */ -static int32_t -pzx_cycles(int32_t pc) -{ - double d = pc; - - return (int32_t)(((d * 3.5) / 4.772728) + 0.5); -} - -void -cassette_eject(void) -{ - if (st_cas->pzx.input) { - pzx_close(&st_cas->pzx); - } - cassettefn[0] = 0; -} - -void -cassette_load(wchar_t *fn) -{ - FILE *fp; - unsigned char magic[8]; - - if (!fn) - return; - - fp = plat_fopen(fn, L"rb"); - if (!fp) { - /* Warn user? */ - cassette_log("Failed to open cassette input %s\n", fn); - return; - } - memset(magic, 0, sizeof(magic)); - fread(magic, 1, sizeof(magic), fp); - - /* Check for PZX signature. In due course support could be added for - * other formats like TZX */ - if (!memcmp(magic, "PZXT", 4)) { - wchar_t *result; - - result = pzx_open(&st_cas->pzx, fp); - - if (result) { - cassette_log("Failed to open %s as PZX: %s\n", - fn, result); - fclose(fp); - return; - } - wcscpy(cassettefn, fn); - } -} - - -uint8_t -cassette_input(void) -{ - int ticks; - - /* While motor is off, result is loopback */ - if (!st_cas->motor) - return ppispeakon; - /* If there is no tapefile open don't try to extract data */ - if (st_cas->pzx.input == NULL) - return 0; - /* Otherwise see how many ticks there have been since the last input */ - if (st_cas->cycles_last == -1) - st_cas->cycles_last = cycles; - if (cycles <= st_cas->cycles_last) - ticks = (st_cas->cycles_last - cycles); - else - ticks = (st_cas->cycles_last + (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed / 100) - cycles); - st_cas->cycles_last = cycles; - - return pzx_advance(&st_cas->pzx, pzx_cycles(ticks)); -} - - - -void -cassette_set_motor(uint8_t on) -{ - if (on && !st_cas->motor) { - cassette_log("Start cassette motor\n"); - st_cas->cycles_last = -1; - } - if (st_cas->motor && !on) { - cassette_log("Stop cassette motor\n"); - st_cas->cycles_last = -1; - } - st_cas->motor = on; -} - - -static void -*cassette_init(const device_t *info) -{ - cassette_t *cas = (cassette_t *)malloc(sizeof(cassette_t)); - memset(cas, 0, sizeof(cassette_t)); - pzx_init(&cas->pzx); - - st_cas = cas; - return cas; -} - - -static void -cassette_close(void *p) -{ - cassette_t *cas = (cassette_t *)p; - - pzx_close(&cas->pzx); - - free(cas); -} - - -const device_t cassette_device = { - "IBM PC 5150 Cassette", - 0, - 0, - cassette_init, - cassette_close, - NULL, - NULL, - NULL, - NULL -}; - diff --git a/src/cassette/cassette.h b/src/cassette/cassette.h deleted file mode 100644 index cf7712811..000000000 --- a/src/cassette/cassette.h +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************ - - PCEM: IBM 5150 cassette support - - Copyright (C) 2019 John Elliott - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*************************************************************************/ - -extern wchar_t cassettefn[256]; - -extern const device_t cassette_device; - -uint8_t cassette_input(void); -void cassette_set_motor(uint8_t on); -void cassette_eject(void); -void cassette_load(wchar_t *filename); diff --git a/src/cassette/pzx.c b/src/cassette/pzx.c deleted file mode 100644 index c7d16d36e..000000000 --- a/src/cassette/pzx.c +++ /dev/null @@ -1,414 +0,0 @@ -/************************************************************************ - - PCEM: IBM 5150 Cassette support - - Copyright (C) 2019 John Elliott - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*************************************************************************/ - -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../ui.h" -#include "pzx.h" - -/* This module is intended to abstract all the details of a PZX file and - * emit its contents as a bitstream in a form suitable for PCEM. Similar - * modules could be written to add support for other tape formats such as TZX, - * TAP or CSW. */ - - -#ifdef ENABLE_PZX_LOG -int pzx_do_log = ENABLE_PZX_LOG; - - -static void -pzx_log(const char *fmt, ...) -{ - va_list ap; - - if (pzx_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define pzx_log(fmt, ...) -#endif - -static uint32_t -peek2(uint8_t *data) -{ - return (((uint32_t)data[1]) << 8) | data[0]; -} - -static uint32_t -peek4(uint8_t *data) -{ - return (((uint32_t)data[3]) << 24) | - (((uint32_t)data[2]) << 16) | - (((uint32_t)data[1]) << 8) | data[0]; -} - -/* Cue up the next pulse definition from the current PULS block. */ -static void -pzx_parse_pulse(pzxfile_t *pzx) -{ - pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr); - pzx->puls_ptr += 2; - if (pzx->puls_duration > 0x8000) { - pzx->puls_count = pzx->puls_duration & 0x7FFF; - pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr); - pzx->puls_ptr += 2; - } - if (pzx->puls_duration >= 0x8000) { - pzx->puls_duration &= 0x7FFF; - pzx->puls_duration <<= 16; - pzx->puls_duration |= peek2(pzx->curblock + pzx->puls_ptr); - pzx->puls_ptr += 2; - } - if (!pzx->puls_count) pzx->puls_count = 1; -} - - -void -pzx_init(pzxfile_t *pzx) -{ - memset(pzx, 0, sizeof(pzxfile_t)); - pzx->state = PZX_CLOSED; -} - -/* Load the next block from a PZX-format file. - * - * Returns block if successful, NULL if end of file or error - * Caller must free the block with free(). */ -uint8_t -*pzx_load_block(FILE *fp) -{ - uint8_t block_header[8]; - uint8_t *block_data; - uint32_t block_len; - - /* The first 8 bytes of a PZX block are fixed: the first 4 give - * the ID, the second 4 the length (excluding the header itself) */ - if (fread(block_header, 1, 8, fp) < 8) - return NULL; /* EoF */ - - block_len = peek4(block_header + 4); - block_data = malloc(8 + block_len); - if (!block_data) return NULL; - memcpy(block_data, block_header, 8); - if (!block_len) { /* Block is only the header */ -/* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */ - return block_data; - } - if (fread(block_data + 8, 1, block_len, fp) < block_len) { - free(block_data); /* Unexpected EoF */ - return NULL; - } -/* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */ - return block_data; -} - - -/* Search the current file for PZX version headers and check they're all 1.x */ -static wchar_t -*pzx_check_version(FILE *fp) -{ - uint8_t *block; - static wchar_t message[80]; - - rewind(fp); - while ((block = pzx_load_block(fp))) { - if (!memcmp(block, "PZXT", 4)) { - pzx_log("PZX version %d.%d\n", block[8], block[9]); - if (block[8] != 1) { - swprintf(message, 80, L"Unsupported PZX version %d.%d\n", block[8], block[9]); - free(block); - return message; - } - } - free(block); - } - rewind(fp); - return NULL; -} - - -wchar_t -*pzx_open(pzxfile_t *pzx, FILE *fp) -{ - wchar_t *result; - - rewind(fp); - /* Check that this file is compatible */ - result = pzx_check_version(fp); - if (result) - return result; - - pzx->level = 0; - pzx->state = PZX_IDLE; - pzx->input = fp; - return NULL; -} - -void -pzx_close(pzxfile_t *pzx) -{ - if (pzx->input) { - fclose(pzx->input); - pzx->input = NULL; - } - if (pzx->curblock) { - free(pzx->curblock); - pzx->curblock = NULL; - } - pzx->state = PZX_CLOSED; -} - -/* Read the next block of type DATA, PAUS or PULS */ -int -pzx_next_block(pzxfile_t *pzx) -{ - long pos; - - pos = ftell(pzx->input); - while (pzx->state == PZX_IDLE) { - uint8_t *blk; - - /* In idle state there should be no current block. But - * make sure of that */ - if (pzx->curblock) { - free(pzx->curblock); - pzx->curblock = NULL; - } - - /* Load the next block */ - blk = pzx_load_block(pzx->input); - - /* If that didn't load we've reached the end of file; wrap to - * beginning. */ - if (!blk) { - rewind(pzx->input); - blk = pzx_load_block(pzx->input); - if (!blk) { /* Couldn't even load first block */ - pzx_close(pzx); - return 0; - } - /* Have we read the whole file and come back to where - * we were? */ - if (ftell(pzx->input) == pos) { - free(blk); - pzx_close(pzx); - return 0; - } - } - /* We have loaded the next block. What is it? */ - if (!memcmp(blk, "PULS", 4)) { - pzx->state = PZX_IN_PULS; - pzx->curblock = blk; - pzx->puls_len = 8 + peek4(blk + 4); - pzx->puls_ptr = 8; - pzx->puls_count = 0; - pzx->puls_remain = 0; - pzx->puls_duration = 0; - pzx->level = 0; - pzx_log("Beginning PULS block\n"); - } - else if (!memcmp(blk, "PAUS", 4)) { - pzx->state = PZX_IN_PAUS; - pzx->curblock = blk; - pzx->paus_remain = peek4(blk + 8); - pzx->level = (pzx->paus_remain >> 31); - pzx->paus_remain &= 0x7FFFFFFF; - pzx_log("Beginning PAUS block, duration=%d\n", - pzx->paus_remain); - } - else if (!memcmp(blk, "DATA", 4)) { - pzx->state = PZX_IN_DATA; - pzx->curblock = blk; - pzx->data_bits = peek4(blk + 8); - pzx->level = (pzx->data_bits >> 31); - pzx->data_bits &= 0x7FFFFFFF; - pzx->data_tail = peek2(blk + 12); - pzx->data_p0 = blk[14]; - pzx->data_p1 = blk[15]; - pzx->data_p = 0; - pzx->data_w = 16; - pzx->data_remain = 0; - pzx->data_ptr = 16 + 2 * (pzx->data_p0 + pzx->data_p1); - pzx->data_mask = 0x80; - pzx_log("Beginning DATA block, length=%d p0=%d p1=%d" - " data_ptr=%d\n", - pzx->data_bits, - pzx->data_p0, pzx->data_p1, - pzx->data_ptr); - } - } - return 1; -} - -static void -pzx_endblock(pzxfile_t *pzx) -{ - if (pzx->curblock) - free(pzx->curblock); - pzx->curblock = NULL; - pzx->state = PZX_IDLE; -} - -/* PAUS is easy - just run the timer down */ -static int -pzx_advance_paus(pzxfile_t *pzx, int time) -{ - if (pzx->paus_remain > time) { - pzx->paus_remain -= time; - return 0; - } - time -= pzx->paus_remain; - pzx_endblock(pzx); - return time; -} - -static int -pzx_advance_puls(pzxfile_t *pzx, int time) -{ - /* At the start of a pulse sequence? */ - if (pzx->puls_count == 0) { - pzx_parse_pulse(pzx); - pzx->puls_remain = pzx->puls_duration; - } - /* Does sample trigger a pulse change? If not, that's easy. */ - if (time < pzx->puls_remain) { - pzx->puls_remain -= time; - return 0; - } - /* Sample does trigger a pulse change */ - time -= pzx->puls_remain; - /* If there's another pulse in the current sequence, that's - * straightforward; just flip the level and continue */ - --pzx->puls_count; - pzx->level = !pzx->level; - if (pzx->puls_count) { - pzx->puls_remain = pzx->puls_duration; - return time; - } - /* If we've reached the end of the pulse sequence, there may be - * another one */ - if (pzx->puls_ptr < pzx->puls_len) { - return time; - } - /* If there isn't another one, it's the end of the block */ - pzx_endblock(pzx); - return time; -} - -/* Decode a DATA block */ -static int -pzx_advance_data(pzxfile_t *pzx, int time) -{ - uint8_t bit; - - /* Reached end of data? */ - if (pzx->data_bits == 0) { - /* Time interval is covered by the tail bit */ - if (pzx->data_tail > time) { - pzx->data_tail -= time; - return 0; - } - /* Have run out of block */ - time -= pzx->data_tail; - pzx_endblock(pzx); - return time; - } - /* No more time remaining on the current bit? */ - if (pzx->data_p < 1 && !pzx->data_remain) { - bit = pzx->curblock[pzx->data_ptr] & pzx->data_mask; - pzx->data_mask >>= 1; - if (!pzx->data_mask) { - pzx->data_mask = 0x80; - ++pzx->data_ptr; - } - --pzx->data_bits; - - if (bit) { - pzx->data_p = pzx->data_p1; - pzx->data_w = 16 + 2 * pzx->data_p0; - pzx->data_remain = 0; - } else { - pzx->data_p = pzx->data_p0; - pzx->data_w = 16; - pzx->data_remain = 0; - } - } - /* See if we've started processing the current waveform. If not, - * load its first element (assuming that there is one) */ - if (!pzx->data_remain) { - if (pzx->data_p) { - pzx->data_remain = peek2(pzx->curblock + pzx->data_w); - pzx->data_w += 2; - pzx->data_p--; - } - } - if (pzx->data_remain > time) { - /* Time advance is contained within current wave */ - pzx->data_remain -= time; - return 0; - } else { /* Move on to next element of wave / next bit / next block */ - time -= pzx->data_remain; - pzx->data_remain = 0; - pzx->level = !pzx->level; - } - - return time; -} - -int -pzx_advance(pzxfile_t *pzx, int time) -{ - if (pzx->state == PZX_CLOSED) - return 0; /* No tape loaded */ - - while (time) { - switch (pzx->state) - { - case PZX_IDLE: - if (!pzx_next_block(pzx)) return 0; - break; - case PZX_IN_PULS: - time = pzx_advance_puls(pzx, time); - break; - case PZX_IN_PAUS: - time = pzx_advance_paus(pzx, time); - break; - case PZX_IN_DATA: - time = pzx_advance_data(pzx, time); - break; - } - } - return pzx->level; -} - - - diff --git a/src/cassette/pzx.h b/src/cassette/pzx.h deleted file mode 100644 index a642a0688..000000000 --- a/src/cassette/pzx.h +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************ - - PCEM: IBM 5150 cassette support - - Copyright (C) 2019 John Elliott - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*************************************************************************/ - -typedef enum -{ - PZX_CLOSED, /* File is not open */ - PZX_IDLE, /* File is open, no block loaded */ - PZX_IN_PULS, /* File is open, current block is a PULS block */ - PZX_IN_DATA, /* File is open, current block is a DATA block */ - PZX_IN_PAUS, /* File is open, current block is a PAUS block */ -} PZX_STATE; - - -typedef struct pzxfile_t -{ - FILE *input; /* Input PZX file */ - uint8_t *curblock; /* Currently-loaded block, if any */ - int level; /* Current signal level */ - PZX_STATE state; /* State machine current status */ -/* State variables for PULS */ - uint32_t puls_ptr; /* Pointer within PULS block */ - uint32_t puls_len; /* Length of PULS block */ - uint32_t puls_count; /* Count of pulses */ - uint32_t puls_duration; /* Duration of each pulse */ - uint32_t puls_remain; /* Time remaining in this pulse */ -/* State variables for PAUS */ - uint32_t paus_remain; /* Time remaining in this pause */ -/* State variables for DATA */ - uint32_t data_ptr; /* Pointer within DATA block */ - uint32_t data_bits; /* Count of bits */ - uint16_t data_tail; /* Length of pulse after last bit */ - uint8_t data_mask; /* Mask for current bit */ - uint8_t data_p0; /* Length of 0 encoding */ - uint8_t data_p1; /* Length of 1 encoding */ - int data_p; /* Current sequence being emitted */ - uint32_t data_w; /* Current waveform */ - uint32_t data_remain; /* Current data pulse time remaining */ -} pzxfile_t; - -uint8_t *pzx_load_block(FILE *fp); - -/* Initialise structure */ -void pzx_init(pzxfile_t *pzx); - -/* Open file for input */ -wchar_t *pzx_open(pzxfile_t *pzx, FILE *fp); - -/* Close file */ -void pzx_close(pzxfile_t *pzx); - -/* Advance by 'time' samples (3.5MHz sample rate) and return current state */ -int pzx_advance(pzxfile_t *pzx, int time); diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 6c19233a7..2b68ff09f 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -8,7 +8,7 @@ * * Generic CD-ROM drive core. * - * Version: @(#)cdrom.c 1.0.9 2019/12/13 + * Version: @(#)cdrom.c 1.0.10 2020/03/23 * * Author: Miran Grca, * @@ -22,12 +22,12 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" +#include "86box.h" +#include "config.h" #include "cdrom.h" #include "cdrom_image.h" -#include "../plat.h" -#include "../sound/sound.h" +#include "plat.h" +#include "sound.h" /* 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: @@ -41,6 +41,8 @@ #define MIN_SEEK 2000 #define MAX_SEEK 333333 +#define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4)) +#define CD_DCB(x) ((((x) & 0xf0) >> 4) * 10 + ((x) & 0x0f)) #pragma pack(push,1) typedef struct { @@ -345,6 +347,72 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf) return 1; } +uint8_t +cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit) +{ + int m = 0, s = 0, f = 0; + + if (dev->cd_status == CD_STATUS_DATA_ONLY) + return 0; + + switch (type) { + case 0x40: + cdrom_log("Audio Track Search: MSF = %06x, type = %02x\n", pos, type); + m = CD_DCB((pos >> 24) & 0xff); + s = CD_DCB((pos >> 16) & 0xff); + f = CD_DCB((pos >> 8) & 0xff); + pos = MSFtoLBA(m, s, f) - 150; + break; + } + + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); + cdrom_stop(dev); + return 0; + } + + dev->seek_pos = pos; + dev->noplay = !playbit; + dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; + return 1; +} + +uint8_t +cdrom_toshiba_audio_play(cdrom_t *dev, uint32_t pos, int type) +{ + int m = 0, s = 0, f = 0; + + if (dev->cd_status == CD_STATUS_DATA_ONLY) + return 0; + + if (dev->cd_status == CD_STATUS_STOPPED || dev->cd_status == CD_STATUS_PAUSED) + dev->cd_status = CD_STATUS_PLAYING; + + /*Preliminary support, revert if too incomplete*/ + switch (type) { + case 0x40: + cdrom_log("Toshiba Play Audio: MSF = %06x, type = %02x\n", pos, type); + m = CD_DCB((pos >> 24) & 0xff); + s = CD_DCB((pos >> 16) & 0xff); + f = CD_DCB((pos >> 8) & 0xff); + pos = MSFtoLBA(m, s, f) - 150; + break; + } + + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); + cdrom_stop(dev); + return 0; + } + + dev->cd_end = pos; + dev->cd_buflen = 0; + return 1; +} void cdrom_audio_pause_resume(cdrom_t *dev, uint8_t resume) @@ -409,6 +477,38 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) return ret; } +uint8_t +cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) +{ + uint8_t ret; + subchannel_t subc; + + dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + + if (dev->cd_status == CD_STATUS_PLAYING) + ret = 0x00; + else if (dev->cd_status == CD_STATUS_PAUSED) { + if (dev->noplay) + ret = 0x02; + else + ret = 0x01; + } + else + ret = 0x03; + + b[0] = subc.attr; + b[1] = CD_BCD(subc.track); + b[2] = CD_BCD(subc.index); + b[3] = CD_BCD(subc.rel_m); + b[4] = CD_BCD(subc.rel_s); + b[5] = CD_BCD(subc.rel_f); + b[6] = CD_BCD(subc.abs_m); + b[7] = CD_BCD(subc.abs_s); + b[8] = CD_BCD(subc.abs_f); + cdrom_log("CD-ROM %i: Returned subcode-q at %02i:%02i.%02i, track=%02x\n", dev->id, b[3], b[4], b[5], b[1]); + + return ret; +} static int read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf) @@ -557,6 +657,44 @@ cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_tra return len; } +void +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; + + dev->ops->get_tracks(dev, &first_track, &last_track); + + switch (type) { + case 0: + b[0] = CD_BCD(first_track); + b[1] = CD_BCD(last_track); + b[2] = 0; + b[3] = 0; + break; + case 1: + dev->ops->get_track_info(dev, 0xAA, 0, &ti); + b[0] = CD_BCD(ti.m); + b[1] = CD_BCD(ti.s); + b[2] = CD_BCD(ti.f); + b[3] = 0; + break; + case 2: + dev->ops->get_track_info(dev, CD_DCB(track), 0, &ti); + b[0] = CD_BCD(ti.m); + b[1] = CD_BCD(ti.s); + b[2] = CD_BCD(ti.f); + b[3] = ti.attr; + cdrom_log("CD-ROM %i: Returned Toshiba disc information at %02i:%02i.%02i, track=%d\n", dev->id, b[0], b[1], b[2], CD_DCB(track)); + break; + case 3: + b[0] = 0x00; /*TODO: correct it further, mark it as CD-Audio/CD-ROM disc for now*/ + b[1] = 0; + b[2] = 0; + b[3] = 0; + break; + } +} static int track_type_is_valid(uint8_t id, int type, int flags, int audio, int mode2) diff --git a/src/cdrom/cdrom.h b/src/cdrom/cdrom.h index ec141a5f9..e5b3a948f 100644 --- a/src/cdrom/cdrom.h +++ b/src/cdrom/cdrom.h @@ -112,7 +112,7 @@ typedef struct cdrom { seek_diff, cd_end; int host_drive, prev_host_drive, - cd_buflen; + cd_buflen, noplay; const cdrom_ops_t *ops; @@ -134,12 +134,17 @@ extern double cdrom_seek_time(cdrom_t *dev); extern void cdrom_stop(cdrom_t *dev); extern int cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len); extern uint8_t cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf); +extern uint8_t cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit); +extern uint8_t cdrom_toshiba_audio_play(cdrom_t *dev, uint32_t pos, int type); extern void cdrom_audio_pause_resume(cdrom_t *dev, uint8_t resume); extern uint8_t cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf); +extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b); extern int cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_track, int msf, int max_len); extern int cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len); +extern void cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type); + extern void cdrom_seek(cdrom_t *dev, uint32_t pos); extern void cdrom_close_handler(uint8_t id); diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 84dff1f98..2a4c7b30c 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -29,10 +29,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../plat.h" -#include "../scsi/scsi_device.h" +#include "86box.h" +#include "config.h" +#include "plat.h" +#include "scsi_device.h" #include "cdrom_image_backend.h" #include "cdrom.h" #include "cdrom_image.h" diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 556c0e954..c85739b6c 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -35,8 +35,8 @@ #endif #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" #include "cdrom_image_backend.h" @@ -190,6 +190,9 @@ track_file_close(track_t *trk) if (trk->file == NULL) return; + if (trk->file->close == NULL) + return; + trk->file->close(trk->file); trk->file = NULL; } @@ -209,10 +212,12 @@ cdi_clear_tracks(cd_img_t *cdi) for (i = 0; i < cdi->tracks_num; i++) { cur = &cdi->tracks[i]; + /* Make sure we do not attempt to close a NULL file. */ if (cur->file != last) { - track_file_close(cur); last = cur->file; - } + track_file_close(cur); + } else + cur->file = NULL; } /* Now free the array. */ diff --git a/src/chipset/acc2168.c b/src/chipset/acc2168.c index 1df0fec34..686301c24 100644 --- a/src/chipset/acc2168.c +++ b/src/chipset/acc2168.c @@ -20,19 +20,18 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../device.h" -#include "../keyboard.h" -#include "../io.h" -#include "../mem.h" -#include "../mouse.h" -#include "../port_92.h" -#include "../sio.h" -#include "../disk/hdc.h" -#include "../video/video.h" -#include "../video/vid_ht216.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "device.h" +#include "keyboard.h" +#include "86box_io.h" +#include "mem.h" +#include "mouse.h" +#include "port_92.h" +#include "sio.h" +#include "hdc.h" +#include "video.h" #include "chipset.h" diff --git a/src/chipset/acer_m3a.c b/src/chipset/acer_m3a.c index 0d8ab2052..43c19d6f1 100644 --- a/src/chipset/acer_m3a.c +++ b/src/chipset/acer_m3a.c @@ -20,13 +20,13 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" +#include "86box.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "keyboard.h" #include "chipset.h" diff --git a/src/chipset/ali1429.c b/src/chipset/ali1429.c index 5d5b4bd83..2f6b8cad1 100644 --- a/src/chipset/ali1429.c +++ b/src/chipset/ali1429.c @@ -21,19 +21,19 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../mem.h" -#include "../device.h" -#include "../keyboard.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../timer.h" -#include "../port_92.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "mem.h" +#include "device.h" +#include "keyboard.h" +#include "fdd.h" +#include "fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "timer.h" +#include "port_92.h" #include "chipset.h" diff --git a/src/chipset/chipset.h b/src/chipset/chipset.h index b78f177c5..9c9b96a2c 100644 --- a/src/chipset/chipset.h +++ b/src/chipset/chipset.h @@ -8,7 +8,7 @@ * * Handling of the emulated chipsets. * - * Version: @(#)machine.h 1.0.1 2020/01/14 + * Version: @(#)machine.h 1.0.2 2020/01/24 * * Authors: Miran Grca, * @@ -33,15 +33,19 @@ extern const device_t headland_386_device; /* Intel 4x0xX */ extern const device_t i420tx_device; +extern const device_t i420zx_device; extern const device_t i430lx_device; extern const device_t i430nx_device; extern const device_t i430fx_device; extern const device_t i430fx_pb640_device; extern const device_t i430hx_device; extern const device_t i430vx_device; +extern const device_t i430tx_device; #if defined(DEV_BRANCH) && defined(USE_I686) extern const device_t i440fx_device; #endif +extern const device_t i440bx_device; +extern const device_t i440zx_device; /* NEAT */ extern const device_t neat_device; diff --git a/src/chipset/headland.c b/src/chipset/headland.c index cbd52cfb1..d3f1f4081 100644 --- a/src/chipset/headland.c +++ b/src/chipset/headland.c @@ -25,18 +25,18 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../cpu/x86.h" -#include "../timer.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../keyboard.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../port_92.h" +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "timer.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "keyboard.h" +#include "fdd.h" +#include "fdc.h" +#include "port_92.h" #include "chipset.h" diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index cf2901146..3a711ba3d 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -8,48 +8,55 @@ * * Implementation of the Intel PCISet chips from 420TX to 440FX. * - * Version: @(#)intel_4x0.c 1.0.2 2019/10/21 + * Version: @(#)intel_4x0.c 1.0.3 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2019 Miran Grca. + * Copyright 2019,2020 Miran Grca. */ #include #include #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" +#include "86box.h" +#include "cpu.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "keyboard.h" #include "chipset.h" enum { INTEL_420TX, + INTEL_420ZX, INTEL_430LX, INTEL_430NX, INTEL_430FX, INTEL_430FX_PB640, INTEL_430HX, - INTEL_430VX + INTEL_430VX, + INTEL_430TX, #if defined(DEV_BRANCH) && defined(USE_I686) - ,INTEL_440FX -#endif + INTEL_440FX, +#endif + INTEL_440BX, + INTEL_440ZX }; typedef struct { - uint8_t regs[256]; + uint8_t pm2_cntrl, max_func; + uint8_t regs[2][256], regs_locked[2][256]; int type; } i4x0_t; + + static void i4x0_map(uint32_t addr, uint32_t size, int state) { @@ -71,116 +78,884 @@ i4x0_map(uint32_t addr, uint32_t size, int state) } +static void +i4x0_mask_bar(uint8_t *regs) +{ + uint32_t bar; + + bar = (regs[0x13] << 24) | (regs[0x12] << 16); + bar &= (((uint32_t) regs[0xb4] << 22) | 0xf0000000); + regs[0x12] = (bar >> 16) & 0xff; + regs[0x13] = (bar >> 24) & 0xff; +} + + +static uint8_t +pm2_cntrl_read(uint16_t addr, void *p) +{ + i4x0_t *dev = (i4x0_t *) p; + + return dev->pm2_cntrl & 0x01; +} + + +static void +pm2_cntrl_write(uint16_t addr, uint8_t val, void *p) +{ + i4x0_t *dev = (i4x0_t *) p; + + dev->pm2_cntrl = val & 0x01; +} + + static void i4x0_write(int func, int addr, uint8_t val, void *priv) { i4x0_t *dev = (i4x0_t *) priv; + uint8_t *regs = (uint8_t *) dev->regs[func]; + uint8_t *regs_l = (uint8_t *) dev->regs_locked[func]; + int i; - if (func) - return; + if (func > dev->max_func) + return; if ((addr >= 0x10) && (addr < 0x4f)) return; - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0e: - return; - + if (func == 0) switch (addr) { case 0x04: /*Command register*/ - if (dev->type >= INTEL_430FX) { - if (dev->type == INTEL_430FX_PB640) - val &= 0x06; - else - val &= 0x02; - } else - val &= 0x42; - val |= 0x04; + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: + case INTEL_440BX: case INTEL_440ZX: + default: + regs[0x04] = (regs[0x04] & ~0x42) | (val & 0x42); + break; + case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + regs[0x04] = (regs[0x04] & ~0x02) | (val & 0x02); + break; + } break; case 0x05: - if (dev->type >= INTEL_430FX) - val = 0; - else - val &= 0x01; - break; - - case 0x06: /*Status*/ - val = 0; + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + case INTEL_440BX: case INTEL_440ZX: + regs[0x05] = (regs[0x05] & ~0x01) | (val & 0x01); + break; + } break; case 0x07: - if (dev->type >= INTEL_430HX) { - val &= 0x80; - val |= 0x02; - } else { - val = 0x02; - if (dev->type == INTEL_430FX_PB640) - val |= 0x20; + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX: + default: + regs[0x07] &= ~(val & 0x70); + break; + case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430VX: case INTEL_430TX: + regs[0x07] &= ~(val & 0x30); + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x07] &= ~(val & 0xf9); + break; +#endif + case INTEL_440BX: case INTEL_440ZX: + regs[0x07] &= ~(val & 0xf0); + break; } break; - - case 0x52: /*Cache Control Register*/ -#if defined(DEV_BRANCH) && defined(USE_I686) - if (dev->type < INTEL_440FX) { -#endif - cpu_cache_ext_enabled = (val & 0x01); - cpu_update_waitstates(); -#if defined(DEV_BRANCH) && defined(USE_I686) + case 0x0d: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: + regs[0x0d] = (val & 0xf0); + break; + default: + regs[0x0d] = (val & 0xf8); + break; } -#endif break; + case 0x0f: + switch (dev->type) { + case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: + regs[0x0f] = (val & 0x40); + break; + } + break; + case 0x12: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0x12] = (val & 0xc0); + i4x0_mask_bar(regs); + break; + } + break; + case 0x13: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0x13] = val; + i4x0_mask_bar(regs); + break; + } + break; + case 0x2c: case 0x2d: case 0x2e: case 0x2f: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + if (!regs_l[addr]) { + regs[addr] = val; + regs_l[addr] = 1; + } + break; + } + break; + case 0x4f: + switch (dev->type) { + case INTEL_430HX: + regs[0x4f] = (val & 0x84); + break; + case INTEL_430VX: + regs[0x4f] = (val & 0x94); + break; + case INTEL_430TX: + regs[0x4f] = (val & 0x80); + break; + } + break; + case 0x50: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: default: + regs[0x50] = (val & 0xe5); + break; + case INTEL_430NX: + regs[0x50] = (val & 0xe7); + break; + case INTEL_430FX: case INTEL_430FX_PB640: + regs[0x50] = (val & 0xef); + break; + case INTEL_430HX: + regs[0x50] = (val & 0xf7); + break; + case INTEL_430VX: case INTEL_430TX: + regs[0x50] = (val & 0x08); + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x50] = (val & 0xf4); + break; +#endif + case INTEL_440BX: + regs[0x50] = (regs[0x50] & 0x14) | (val & 0xeb); + break; + case INTEL_440ZX: + regs[0x50] = (regs[0x50] & 0x34) | (val & 0xcb); + break; - case 0x59: /*PAM0*/ - if ((dev->regs[0x59] ^ val) & 0xf0) { + } + break; + case 0x51: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: + regs[0x51] = (val & 0xc0); + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x51] = (val & 0xc3); + break; +#endif + case INTEL_440BX: case INTEL_440ZX: + regs[0x51] = (regs[0x50] & 0x70) | (val & 0x8f); + break; + } + break; + case 0x52: /* Cache Control Register */ + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: + case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430VX: case INTEL_430TX: + default: + regs[0x52] = (val & 0xfb); + break; + case INTEL_430NX: case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + regs[0x52] = val; + break; + case INTEL_440BX: case INTEL_440ZX: + regs[0x52] = val & 0x07; + break; + } + break; + case 0x53: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: + regs[0x53] = val & 0x0b; + break; + case INTEL_430NX: + regs[0x53] = val & 0x0a; + break; + case INTEL_430VX: case INTEL_430TX: + regs[0x53] = val & 0x3f; + break; + case INTEL_440BX: + /* Not applicable to 440ZX as that does not support ECC. */ + regs[0x53] = val; + break; + } + break; + case 0x54: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + regs[0x54] = val & 0x07; + break; + case INTEL_430VX: + regs[0x54] = val & 0xd8; + break; + case INTEL_430TX: + regs[0x54] = val & 0xfa; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x54] = val & 0x82; + break; +#endif + } + break; + case 0x55: + switch (dev->type) { + case INTEL_430VX: case INTEL_430TX: + regs[0x55] = val & 0x01; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x55] = val; + break; +#endif + } + break; + case 0x56: + switch (dev->type) { + case INTEL_430HX: + regs[0x56] = val & 0x1f; + break; + case INTEL_430VX: + regs[0x56] = val & 0x77; + break; + case INTEL_430TX: + regs[0x56] = val & 0x76; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x56] = val; + break; +#endif + } + break; + case 0x57: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: default: + regs[0x57] = val & 0x3f; + break; + case INTEL_430NX: + regs[0x57] = val; + break; + case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430HX: case INTEL_430VX: + regs[0x57] = val & 0xcf; + break; + case INTEL_430TX: + regs[0x57] = val & 0xdf; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x57] = val & 0x77; + break; +#endif + case INTEL_440BX: + regs[0x57] = val & 0x3f; + break; + case INTEL_440ZX: + regs[0x57] = val & 0x2f; + break; + } + break; + case 0x58: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: default: + regs[0x58] = val & 0x01; + break; + case INTEL_430NX: + case INTEL_440BX: case INTEL_440ZX: + regs[0x58] = val & 0x03; + break; + case INTEL_430FX: case INTEL_430FX_PB640: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + regs[0x58] = val & 0x7f; + break; + case INTEL_430HX: case INTEL_430VX: + regs[0x57] = val; + break; + case INTEL_430TX: + regs[0x57] = val & 0x7b; + break; + } + break; + case 0x59: /* PAM0 */ + if (dev->type <= INTEL_430NX) { + if ((regs[0x59] ^ val) & 0x0f) + i4x0_map(0x80000, 0x20000, val & 0x0f); + } + if ((regs[0x59] ^ val) & 0xf0) { i4x0_map(0xf0000, 0x10000, val >> 4); shadowbios = (val & 0x10); } + if (dev->type > INTEL_430NX) + regs[0x59] = val & 0x70; + else + regs[0x59] = val & 0x77; break; - case 0x5a: /*PAM1*/ - if ((dev->regs[0x5a] ^ val) & 0x0f) + case 0x5a: /* PAM1 */ + if ((regs[0x5a] ^ val) & 0x0f) i4x0_map(0xc0000, 0x04000, val & 0xf); - if ((dev->regs[0x5a] ^ val) & 0xf0) + if ((regs[0x5a] ^ val) & 0xf0) i4x0_map(0xc4000, 0x04000, val >> 4); + regs[0x5a] = val & 0x77; break; - case 0x5b: /*PAM2*/ - if ((dev->regs[0x5b] ^ val) & 0x0f) + case 0x5b: /*PAM2 */ + if ((regs[0x5b] ^ val) & 0x0f) i4x0_map(0xc8000, 0x04000, val & 0xf); - if ((dev->regs[0x5b] ^ val) & 0xf0) + if ((regs[0x5b] ^ val) & 0xf0) i4x0_map(0xcc000, 0x04000, val >> 4); + regs[0x5b] = val & 0x77; break; - case 0x5c: /*PAM3*/ - if ((dev->regs[0x5c] ^ val) & 0x0f) + case 0x5c: /*PAM3 */ + if ((regs[0x5c] ^ val) & 0x0f) i4x0_map(0xd0000, 0x04000, val & 0xf); - if ((dev->regs[0x5c] ^ val) & 0xf0) + if ((regs[0x5c] ^ val) & 0xf0) i4x0_map(0xd4000, 0x04000, val >> 4); + regs[0x5c] = val & 0x77; break; - case 0x5d: /*PAM4*/ - if ((dev->regs[0x5d] ^ val) & 0x0f) + case 0x5d: /* PAM4 */ + if ((regs[0x5d] ^ val) & 0x0f) i4x0_map(0xd8000, 0x04000, val & 0xf); - if ((dev->regs[0x5d] ^ val) & 0xf0) + if ((regs[0x5d] ^ val) & 0xf0) i4x0_map(0xdc000, 0x04000, val >> 4); + regs[0x5d] = val & 0x77; break; - case 0x5e: /*PAM5*/ - if ((dev->regs[0x5e] ^ val) & 0x0f) + case 0x5e: /* PAM5 */ + if ((regs[0x5e] ^ val) & 0x0f) i4x0_map(0xe0000, 0x04000, val & 0xf); - if ((dev->regs[0x5e] ^ val) & 0xf0) + if ((regs[0x5e] ^ val) & 0xf0) i4x0_map(0xe4000, 0x04000, val >> 4); + regs[0x5e] = val & 0x77; break; - case 0x5f: /*PAM6*/ - if ((dev->regs[0x5f] ^ val) & 0x0f) + case 0x5f: /* PAM6 */ + if ((regs[0x5f] ^ val) & 0x0f) i4x0_map(0xe8000, 0x04000, val & 0xf); - if ((dev->regs[0x5f] ^ val) & 0xf0) + if ((regs[0x5f] ^ val) & 0xf0) i4x0_map(0xec000, 0x04000, val >> 4); + regs[0x5f] = val & 0x77; break; - case 0x72: /*SMRAM*/ - if ((dev->type >= INTEL_430FX) && ((dev->regs[0x72] ^ val) & 0x48)) - i4x0_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0); - else if ((dev->type < INTEL_430FX) && ((dev->regs[0x72] ^ val) & 0x20)) - i4x0_map(0xa0000, 0x20000, ((val & 0x20) == 0x20) ? 3 : 0); + case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + case INTEL_440BX: case INTEL_440ZX: + default: + regs[addr] = val; + break; + case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430VX: + regs[addr] = val/* & 0x3f*/; + break; + case INTEL_430TX: + regs[addr] = val & 0x7f; + break; + } + break; + case 0x65: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + case INTEL_440BX: case INTEL_440ZX: + regs[addr] = val; + break; + case INTEL_430VX: + regs[addr] = val & 0x3f; + break; + case INTEL_430TX: + regs[addr] = val & 0x7f; + break; + } + break; + case 0x66: + switch (dev->type) { + case INTEL_430NX: case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + case INTEL_440BX: case INTEL_440ZX: + regs[addr] = val; + break; + } + break; + case 0x67: + switch (dev->type) { + case INTEL_430NX: case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + case INTEL_440BX: case INTEL_440ZX: + regs[addr] = val; + break; + case INTEL_430VX: + regs[addr] = val & 0x11; + break; + case INTEL_430TX: + regs[addr] = val & 0xb7; + break; + } + break; + case 0x68: + switch (dev->type) { + case INTEL_430NX: case INTEL_430HX: + case INTEL_430VX: case INTEL_430TX: + regs[0x68] = val; + break; + case INTEL_430FX: case INTEL_430FX_PB640: + regs[0x68] = val & 0x1f; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x68] = val & 0xc0; + break; +#endif + case INTEL_440BX: + regs[0x68] = (regs[0x68] & 0x38) | (val & 0xc7); + break; + case INTEL_440ZX: + regs[0x68] = (regs[0x68] & 0x3f) | (val & 0xc0); + break; + } + break; + case 0x69: + switch (dev->type) { + case INTEL_430NX: + case INTEL_440BX: + regs[0x69] = val; + break; + case INTEL_430VX: + regs[0x69] = val & 0x07; + break; + case INTEL_440ZX: + regs[0x69] = val & 0x3f; + break; + } + break; + case 0x6a: case 0x6b: + switch (dev->type) { + case INTEL_430NX: + case INTEL_440BX: + regs[addr] = val; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440ZX: + if (addr == 0x6a) + regs[addr] = val & 0xfc; + else + regs[addr] = val & 0x33; + break; +#endif + } + break; + case 0x6c: case 0x6d: case 0x6e: + switch (dev->type) { + case INTEL_440BX: + regs[addr] = val; + break; + case INTEL_440ZX: + if (addr == 0x6c) + regs[addr] = val & 0x03; + else if (addr == 0x6d) + regs[addr] = val & 0xcf; + break; + } + break; + case 0x70: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: + regs[addr] = val & 0xc7; + break; + case INTEL_430NX: + regs[addr] = val; + break; + case INTEL_430VX: case INTEL_430TX: + regs[addr] = val & 0xfc; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[addr] = val & 0xf8; + break; +#endif + } + break; + case 0x71: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: + regs[addr] = val & 0x4d; + break; + case INTEL_430TX: + regs[addr] = val; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[addr] = val & 0x1f; + break; +#endif + } + break; + case 0x72: /* SMRAM */ + if (dev->type >= INTEL_430FX) { + if ((regs[0x72] ^ val) & 0x48) + i4x0_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0); + regs[0x72] = val & 0x7f; + } else { + if ((regs[0x72] ^ val) & 0x20) + i4x0_map(0xa0000, 0x20000, ((val & 0x20) == 0x20) ? 3 : 0); + regs[0x72] = val & 0x3f; + } + break; + case 0x73: + switch (dev->type) { + case INTEL_430VX: + regs[0x73] = val & 0x03; + break; + case INTEL_440BX: case INTEL_440ZX: + regs[0x73] = val; + break; + } + break; + case 0x74: + switch (dev->type) { + case INTEL_430VX: + case INTEL_440BX: case INTEL_440ZX: + regs[0x74] = val; + break; + } + break; + case 0x75: case 0x76: + case 0x7b: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[addr] = val; + } + break; + case 0x77: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0x77] = val & 0x03; + } + break; + case 0x78: + switch (dev->type) { + case INTEL_430VX: + regs[0x78] = val & 0xcf; + break; + case INTEL_440BX: case INTEL_440ZX: + regs[0x78] = val & 0x0f; + break; + } + break; + case 0x79: + switch (dev->type) { + case INTEL_430TX: + regs[0x79] = val & 0x74; + io_removehandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); + if (val & 0x40) + io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); + break; + case INTEL_440BX: case INTEL_440ZX: + regs[0x79] = val; + break; + } + break; + case 0x7a: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0x7a] = (regs[0x7a] & 0x0a) | (val & 0xf5); + io_removehandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); + if (val & 0x40) + io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); + break; + } + break; + case 0x7c: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + regs[0x7c] = val & 0x8f; + break; + case INTEL_440BX: case INTEL_440ZX: + regs[0x7c] = val & 0x1f; + break; + } + case 0x7d: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + regs[0x7c] = val & 0x32; + break; + } + case 0x7e: case 0x7f: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + regs[addr] = val; + break; + } + case 0x80: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0x80] &= ~(val & 0x03); + break; + } + break; + case 0x90: + switch (dev->type) { + case INTEL_430HX: + regs[0x80] = val & 0x87; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x80] = val & 0x1b; + break; +#endif + case INTEL_440BX: case INTEL_440ZX: + regs[0x7c] = val; + break; + } + break; + case 0x91: + switch (dev->type) { + case INTEL_430HX: case INTEL_440BX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + /* Not applicable on 82443ZX. */ + regs[0x91] &= ~(val & 0x11); + break; + } + break; + case 0x92: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0x92] &= ~(val & 0x1f); + break; + } + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case 0x93: + switch (dev->type) { + case INTEL_440FX: + regs[0x93] = (val & 0x0f); + trc_write(0x0093, val & 0x06, NULL); + break; + } + break; +#endif + case 0xa8: case 0xa9: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[addr] = (val & 0x03); + break; + } + break; + case 0xb0: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0xb0] = (val & 0x80); + break; + } + break; + case 0xb1: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0xb1] = (val & 0xa0); + break; + } + break; + case 0xb4: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0xb4] = (val & 0x3f); + i4x0_mask_bar(regs); + break; + } + break; + case 0xb9: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0xb9] = (val & 0xf0); + break; + } + break; + case 0xba: case 0xbb: + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[addr] = val; + break; + } + break; + case 0xca: + switch (dev->type) { + case INTEL_440BX: + regs[addr] = val; + break; + case INTEL_440ZX: + regs[addr] = val & 0xe7; + break; + } + break; + case 0xcb: + switch (dev->type) { + case INTEL_440BX: + regs[addr] = val; + break; + case INTEL_440ZX: + regs[addr] = val & 0xa7; + break; + } + break; + case 0xcc: + switch (dev->type) { + case INTEL_440BX: + regs[0xcc] = (val & 0x7f); + break; + case INTEL_440ZX: + regs[0xcc] = (val & 0x58); + break; + } + break; + case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: + case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + if (!regs_l[addr]) + regs[addr] = val; + break; + } + break; + case 0xe5: case 0xed: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + if (!regs_l[addr]) + regs[addr] = (val & 0x3f); + break; + } + break; + case 0xe7: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0xe7] = 0x80; + for (i = 0; i < 16; i++) + regs_l[0xe0 + i] = !!(val & 0x80); + if (!regs_l[0xe7]) { + regs[0xe7] |= (val & 0x7f); + } + break; + } + break; + case 0xf0: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0xf0] = (val & 0xc0); + break; + } + break; + case 0xf1: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0xf1] = (val & 0x03); + break; + } + break; + } else if (func == 1) switch (addr) { + case 0x04: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0x04] = (val & 0x1f); + break; + } + break; + case 0x05: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0x05] = (val & 0x01); + break; + } + break; + case 0x0d: case 0x1b: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[addr] = (val & 0xf8); + break; + } + break; + case 0x19: case 0x1a: + case 0x21: case 0x23: + case 0x25: case 0x27: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[addr] = val; + break; + } + break; + case 0x1c: case 0x1d: + case 0x20: case 0x22: + case 0x24: case 0x26: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[addr] = (val & 0xf0); + break; + } + break; + case 0x1f: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0x1f] &= ~(val & 0xf0); + break; + } + break; + case 0x3e: + switch (dev->type) { + case INTEL_440BX: case INTEL_440ZX: + regs[0x3e] = (val & 0xed); + break; + } break; } - - dev->regs[addr] = val; } @@ -188,22 +963,50 @@ static uint8_t i4x0_read(int func, int addr, void *priv) { i4x0_t *dev = (i4x0_t *) priv; + uint8_t ret = 0xff; + uint8_t *regs = (uint8_t *) dev->regs[func]; - if (func) - return 0xff; + if (func > dev->max_func) + ret = 0xff; + else { + ret = regs[addr]; +#if defined(DEV_BRANCH) && defined(USE_I686) + /* Special behavior for 440FX register 0x93 which is basically TRC in PCI space + with the addition of bits 3 and 0. */ + if ((func == 0) && (addr == 0x93) && (dev->type == INTEL_440FX)) + ret = (ret & 0xf9) | (trc_read(0x0093, NULL) & 0x06); +#endif + } - return dev->regs[addr]; + return ret; } static void i4x0_reset(void *priv) { - i4x0_t *i4x0 = (i4x0_t *)priv; + i4x0_t *dev = (i4x0_t *)priv; + int i; - i4x0_write(0, 0x59, 0x00, priv); - if (i4x0->type >= INTEL_430FX) + if (dev->type >= INTEL_430FX) + i4x0_write(0, 0x59, 0x00, priv); + else + i4x0_write(0, 0x59, 0x0f, priv); + + for (i = 0; i < 6; i++) + i4x0_write(0, 0x5a + i, 0x00, priv); + + if (dev->type >= INTEL_430FX) i4x0_write(0, 0x72, 0x02, priv); + else + i4x0_write(0, 0x72, 0x00, priv); + + if ((dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) { + for (i = 0; i <= dev->max_func; i++) + memset(dev->regs_locked[i], 0x00, 256 * sizeof(uint8_t)); + } + + smbase = 0xa0000; } @@ -219,114 +1022,227 @@ i4x0_close(void *p) static void *i4x0_init(const device_t *info) { - i4x0_t *i4x0 = (i4x0_t *) malloc(sizeof(i4x0_t)); - memset(i4x0, 0, sizeof(i4x0_t)); + i4x0_t *dev = (i4x0_t *) malloc(sizeof(i4x0_t)); + uint8_t *regs; - i4x0->type = info->local; + memset(dev, 0, sizeof(i4x0_t)); - i4x0->regs[0x00] = 0x86; i4x0->regs[0x01] = 0x80; /*Intel*/ - switch(i4x0->type) { + dev->type = info->local & 0xff; + + regs = (uint8_t *) dev->regs[0]; + + // This is off by default and has to be moved to the appropriate register handling. + // io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); + + regs[0x00] = 0x86; regs[0x01] = 0x80; /*Intel*/ + + switch (dev->type) { case INTEL_420TX: - i4x0->regs[0x02] = 0x83; i4x0->regs[0x03] = 0x04; /*82424TX/ZX*/ - i4x0->regs[0x08] = 0x03; /*A3 stepping*/ - i4x0->regs[0x50] = 0x80; - i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/ + case INTEL_420ZX: + regs[0x02] = 0x83; regs[0x03] = 0x04; /* 82424TX/ZX */ + regs[0x06] = 0x40; + regs[0x08] = (dev->type == INTEL_420ZX) ? 0x01 : 0x00; + regs[0x0d] = 0x20; + if (is486sx) + regs[0x50] = 0x20; + else if (is486sx2) + regs[0x50] = 0x60; /* Guess based on the SX, DX, and DX2 values. */ + else if (is486dx || isdx4) + regs[0x50] = 0x00; + else if (is486dx2) + regs[0x50] = 0x40; + else + regs[0x50] = 0x80; /* Pentium OverDrive. */ + if (cpu_busspeed <= 25000000) + regs[0x50] |= 0x01; + else if ((cpu_busspeed > 25000000) && (cpu_busspeed <= 30000000)) + regs[0x50] |= 0x02; + else if ((cpu_busspeed > 30000000) && (cpu_busspeed <= 33333333)) + regs[0x50] |= 0x03; + regs[0x51] = 0x80; + regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */ + regs[0x57] = 0x31; + regs[0x59] = 0x0f; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; break; case INTEL_430LX: - i4x0->regs[0x02] = 0xa3; i4x0->regs[0x03] = 0x04; /*82434LX/NX*/ - i4x0->regs[0x08] = 0x03; /*A3 stepping*/ - i4x0->regs[0x50] = 0x80; - i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/ + regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */ + regs[0x06] = 0x40; + regs[0x08] = 0x03; + regs[0x0d] = 0x20; + regs[0x50] = 0x82; + if (cpu_busspeed <= 60000000) + regs[0x50] |= 0x00; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x50] |= 0x01; + regs[0x51] = 0x80; + regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */ + regs[0x57] = 0x31; + regs[0x59] = 0x0f; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; break; case INTEL_430NX: - i4x0->regs[0x02] = 0xa3; i4x0->regs[0x03] = 0x04; /*82434LX/NX*/ - i4x0->regs[0x08] = 0x10; /*A0 stepping*/ - i4x0->regs[0x50] = 0xA0; - i4x0->regs[0x52] = 0x44; /*256kb PLB cache*/ - i4x0->regs[0x66] = i4x0->regs[0x67] = 0x02; + regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */ + regs[0x06] = 0x40; + regs[0x08] = 0x11; + regs[0x0d] = 0x20; + regs[0x50] = 0x80; + if (cpu_busspeed <= 50000000) + regs[0x50] |= 0x01; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + regs[0x50] |= 0x02; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x50] |= 0x03; + regs[0x51] = 0x80; + regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */ + regs[0x57] = 0x31; + regs[0x59] = 0x0f; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; break; - case INTEL_430FX: case INTEL_430FX_PB640: - i4x0->regs[0x02] = 0x2d; i4x0->regs[0x03] = 0x12; /*SB82437FX-66*/ - if (i4x0->type == INTEL_430FX_PB640) - i4x0->regs[0x08] = 0x02; /*???? stepping*/ - else - i4x0->regs[0x08] = 0x00; /*A0 stepping*/ - i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/ + regs[0x08] = 0x02; + /* FALLTHROUGH */ + case INTEL_430FX: + regs[0x02] = 0x2d; regs[0x03] = 0x12; /* SB82437FX-66 */ + regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */ + if (cpu_busspeed <= 50000000) + regs[0x57] |= 0x01; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + regs[0x57] |= 0x02; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x57] |= 0x03; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = 0x02; + regs[0x72] = 0x02; break; case INTEL_430HX: - i4x0->regs[0x02] = 0x50; i4x0->regs[0x03] = 0x12; /*82439HX*/ - i4x0->regs[0x08] = 0x00; /*A0 stepping*/ - i4x0->regs[0x51] = 0x20; - i4x0->regs[0x52] = 0xB5; /*512kb cache*/ - i4x0->regs[0x56] = 0x52; /*DRAM control*/ - i4x0->regs[0x59] = 0x40; - i4x0->regs[0x5A] = i4x0->regs[0x5B] = i4x0->regs[0x5C] = i4x0->regs[0x5D] = 0x44; - i4x0->regs[0x5E] = i4x0->regs[0x5F] = 0x44; - i4x0->regs[0x65] = i4x0->regs[0x66] = i4x0->regs[0x67] = 0x02; - i4x0->regs[0x68] = 0x11; + regs[0x02] = 0x50; regs[0x03] = 0x12; /* 82439HX */ + regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */ + if (cpu_busspeed <= 50000000) + regs[0x57] |= 0x01; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + regs[0x57] |= 0x02; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x57] |= 0x03; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + regs[0x72] = 0x02; break; case INTEL_430VX: - i4x0->regs[0x02] = 0x30; i4x0->regs[0x03] = 0x70; /*82437VX*/ - i4x0->regs[0x08] = 0x00; /*A0 stepping*/ - i4x0->regs[0x52] = 0x42; /*256kb PLB cache*/ - i4x0->regs[0x53] = 0x14; - i4x0->regs[0x56] = 0x52; /*DRAM control*/ - i4x0->regs[0x67] = 0x11; - i4x0->regs[0x69] = 0x03; - i4x0->regs[0x70] = 0x20; - i4x0->regs[0x74] = 0x0e; - i4x0->regs[0x78] = 0x23; + regs[0x02] = 0x30; regs[0x03] = 0x70; /* 82437VX */ + regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */ + regs[0x53] = 0x14; + regs[0x56] = 0x52; + if (cpu_busspeed <= 50000000) + regs[0x57] |= 0x01; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + regs[0x57] |= 0x02; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x57] |= 0x03; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = 0x02; + regs[0x67] = 0x11; + regs[0x69] = 0x03; + regs[0x70] = 0x20; + regs[0x72] = 0x02; + regs[0x74] = 0x0e; + regs[0x78] = 0x23; + break; + case INTEL_430TX: + regs[0x02] = 0x00; regs[0x03] = 0x71; /* 82439TX */ + regs[0x08] = 0x01; + regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */ + regs[0x53] = 0x14; + regs[0x56] = 0x52; + regs[0x57] = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; + if (cpu_busspeed <= 60000000) + regs[0x67] |= 0x00; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x67] |= 0x80; + regs[0x70] = 0x20; + regs[0x72] = 0x02; break; #if defined(DEV_BRANCH) && defined(USE_I686) case INTEL_440FX: - i4x0->regs[0x02] = 0x37; i4x0->regs[0x03] = 0x12; /*82441FX*/ - i4x0->regs[0x08] = 0x02; /*A0 stepping*/ - i4x0->regs[0x2c] = 0xf4; - i4x0->regs[0x2d] = 0x1a; - i4x0->regs[0x2f] = 0x11; - i4x0->regs[0x51] = 0x01; - i4x0->regs[0x53] = 0x80; - i4x0->regs[0x58] = 0x10; - i4x0->regs[0x5a] = i4x0->regs[0x5b] = i4x0->regs[0x5c] = i4x0->regs[0x5d] = 0x11; - i4x0->regs[0x5e] = 0x11; - i4x0->regs[0x5f] = 0x31; + regs[0x02] = 0x37; regs[0x03] = 0x12; /* 82441FX */ + regs[0x08] = 0x02; + if (cpu_busspeed <= 60000000) + regs[0x51] |= 0x01; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x51] |= 0x02; + regs[0x53] = 0x80; + regs[0x57] = 0x01; + regs[0x58] = 0x10; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + regs[0x71] = 0x10; + regs[0x72] = 0x02; + break; +#endif + case INTEL_440BX: case INTEL_440ZX: + regs[0x7a] = (info->local >> 8) & 0xff; + dev->max_func = (regs[0x7a] & 0x02) ? 0 : 1; + + regs[0x02] = (regs[0x7a] & 0x02) ? 0x92 : 0x90; regs[0x03] = 0x71; /* 82443BX */ + regs[0x06] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; + regs[0x08] = 0x02; + regs[0x10] = 0x08; + regs[0x34] = (regs[0x7a] & 0x02) ? 0x00 : 0xa0; + if (cpu_busspeed <= 66666667) + regs[0x51] |= 0x00; + else if ((cpu_busspeed > 66666667) && (cpu_busspeed <= 100000000)) + regs[0x51] |= 0x20; + regs[0x57] = 0x28; /* 4 DIMMs, SDRAM */ + regs[0x58] = 0x03; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x72] = 0x02; + regs[0x73] = 0x38; + regs[0x7b] = 0x38; + regs[0x90] = 0x80; + regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; + regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; + regs[0xa4] = 0x03; + regs[0xa5] = 0x02; + regs[0xa7] = 0x1f; break; -#endif } - i4x0->regs[0x04] = 0x06; i4x0->regs[0x05] = 0x00; -#if defined(DEV_BRANCH) && defined(USE_I686) - if (i4x0->type == INTEL_440FX) - i4x0->regs[0x06] = 0x80; -#endif - if (i4x0->type == INTEL_430FX) - i4x0->regs[0x07] = 0x82; -#if defined(DEV_BRANCH) && defined(USE_I686) - else if (i4x0->type != INTEL_440FX) -#else - else -#endif - i4x0->regs[0x07] = 0x02; - i4x0->regs[0x0b] = 0x06; - if (i4x0->type >= INTEL_430FX) - i4x0->regs[0x57] = 0x01; - else - i4x0->regs[0x57] = 0x31; - i4x0->regs[0x60] = i4x0->regs[0x61] = i4x0->regs[0x62] = i4x0->regs[0x63] = 0x02; - i4x0->regs[0x64] = 0x02; - if (i4x0->type >= INTEL_430FX) - i4x0->regs[0x72] = 0x02; + + regs[0x04] = 0x06; regs[0x07] = 0x02; + regs[0x0b] = 0x06; #if defined(DEV_BRANCH) && defined(USE_I686) - if (i4x0->type == INTEL_440FX) { + if (dev->type >= INTEL_440FX) { cpu_cache_ext_enabled = 1; cpu_update_waitstates(); } #endif - pci_add_card(0, i4x0_read, i4x0_write, i4x0); + i4x0_write(regs[0x59], 0x59, 0x00, dev); + i4x0_write(regs[0x5a], 0x5a, 0x00, dev); + i4x0_write(regs[0x5b], 0x5b, 0x00, dev); + i4x0_write(regs[0x5c], 0x5c, 0x00, dev); + i4x0_write(regs[0x5d], 0x5d, 0x00, dev); + i4x0_write(regs[0x5e], 0x5e, 0x00, dev); + i4x0_write(regs[0x5f], 0x5f, 0x00, dev); - return i4x0; + smbase = 0xa0000; + + if (((dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) && (dev->max_func == 1)) { + regs = (uint8_t *) dev->regs[1]; + + regs[0x00] = 0x86; regs[0x01] = 0x80; /* Intel */ + regs[0x02] = 0x91; regs[0x03] = 0x71; /* 82443BX */ + regs[0x06] = 0x20; regs[0x07] = 0x02; + regs[0x08] = 0x02; + regs[0x0a] = 0x04; regs[0x0b] = 0x06; + regs[0x0e] = 0x01; + regs[0x1c] = 0xf0; + regs[0x1e] = 0xa0; regs[0x1f] = 0x02; + regs[0x20] = 0xf0; regs[0x21] = 0xff; + regs[0x24] = 0xf0; regs[0x25] = 0xff; + regs[0x3e] = 0x80; + } + + pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev); + + return dev; } @@ -345,6 +1261,21 @@ const device_t i420tx_device = }; +const device_t i420zx_device = +{ + "Intel 82424ZX", + DEVICE_PCI, + INTEL_420ZX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + const device_t i430lx_device = { "Intel 82434LX", @@ -435,6 +1366,21 @@ const device_t i430vx_device = }; +const device_t i430tx_device = +{ + "Intel 82439TX", + DEVICE_PCI, + INTEL_430TX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + #if defined(DEV_BRANCH) && defined(USE_I686) const device_t i440fx_device = { @@ -449,4 +1395,33 @@ const device_t i440fx_device = NULL, NULL }; + #endif +const device_t i440bx_device = +{ + "Intel 82443BX", + DEVICE_PCI, + 0x8000 | INTEL_440BX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + +const device_t i440zx_device = +{ + "Intel 82443ZX", + DEVICE_PCI, + 0x8000 | INTEL_440ZX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/chipset/neat.c b/src/chipset/neat.c index cc641c0d5..dc2798813 100644 --- a/src/chipset/neat.c +++ b/src/chipset/neat.c @@ -24,15 +24,15 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../keyboard.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#include "keyboard.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" #include "chipset.h" #define NEAT_DEBUG 0 diff --git a/src/chipset/opti495.c b/src/chipset/opti495.c index b6ffb0ff8..21fa9f048 100644 --- a/src/chipset/opti495.c +++ b/src/chipset/opti495.c @@ -258,15 +258,15 @@ SeeAlso: #P0178,#P0187 #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../device.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "device.h" +#include "keyboard.h" +#include "mem.h" +#include "fdd.h" +#include "fdc.h" #include "chipset.h" diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c index 093b3863a..c6f3619c3 100644 --- a/src/chipset/scamp.c +++ b/src/chipset/scamp.c @@ -13,7 +13,7 @@ * 8MB of DRAM chips', because it works fine with bus-based * memory expansion. * - * Version: @(#)scamp.c 1.0.0 2020/01/21 + * Version: @(#)scamp.c 1.0.1 2020/01/22 * * Authors: Sarah Walker, * @@ -24,16 +24,21 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../port_92.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "port_92.h" #include "chipset.h" +typedef struct { + void *parent; + int bank; +} ram_struct_t; + typedef struct { int cfg_index; uint8_t cfg_regs[256]; @@ -42,6 +47,9 @@ typedef struct { int ram_config; mem_mapping_t ram_mapping[2]; + + ram_struct_t ram_struct[3]; + uint32_t ram_virt_base[2], ram_phys_base[2]; uint32_t ram_mask[2]; int row_virt_shift[2], row_phys_shift[2]; @@ -129,8 +137,9 @@ static const struct static uint8_t ram_mirrored_256k_in_4mi_read(uint32_t addr, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -156,8 +165,9 @@ ram_mirrored_256k_in_4mi_read(uint32_t addr, void *priv) static void ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -186,8 +196,9 @@ ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *priv) static uint8_t ram_mirrored_interleaved_read(uint32_t addr, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -213,8 +224,9 @@ ram_mirrored_interleaved_read(uint32_t addr, void *priv) static void ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -242,8 +254,9 @@ ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *priv) static uint8_t ram_mirrored_read(uint32_t addr, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -257,8 +270,9 @@ ram_mirrored_read(uint32_t addr, void *priv) static void ram_mirrored_write(uint32_t addr, uint8_t val, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -674,14 +688,19 @@ scamp_init(const device_t *info) mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL); + dev->ram_struct[2].parent = dev; + dev->ram_struct[2].bank = 0; + mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[2]); mem_mapping_disable(&ram_high_mapping); addr = 0; for (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, ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL, - &ram[addr], MEM_MAPPING_INTERNAL, (void *)c); + &ram[addr], MEM_MAPPING_INTERNAL, (void *) &dev->ram_struct[c]); mem_mapping_disable(&dev->ram_mapping[c]); dev->ram_phys_base[c] = addr; diff --git a/src/chipset/scat.c b/src/chipset/scat.c index d5712a98c..a9b668141 100644 --- a/src/chipset/scat.c +++ b/src/chipset/scat.c @@ -23,24 +23,19 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#ifdef USE_NEW_DYNAREC -#include "../cpu_new/cpu.h" -#include "../cpu_new/x86.h" -#else -#include "../cpu/cpu.h" -#include "../cpu/x86.h" -#endif -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../keyboard.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../port_92.h" -#include "../rom.h" +#include "86box.h" +#include "device.h" +#include "cpu.h" +#include "x86.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#include "keyboard.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "port_92.h" +#include "rom.h" #include "chipset.h" diff --git a/src/chipset/sis_85c471.c b/src/chipset/sis_85c471.c index 934e84c55..d28d824c1 100644 --- a/src/chipset/sis_85c471.c +++ b/src/chipset/sis_85c471.c @@ -22,20 +22,20 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../io.h" -#include "../lpt.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../disk/hdc_ide.h" -#include "../keyboard.h" -#include "../timer.h" -#include "../port_92.h" -#include "../serial.h" -#include "../machine/machine.h" +#include "86box.h" +#include "cpu.h" +#include "mem.h" +#include "86box_io.h" +#include "lpt.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "hdc_ide.h" +#include "keyboard.h" +#include "timer.h" +#include "port_92.h" +#include "serial.h" +#include "machine.h" #include "chipset.h" diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index cddb74b9d..607178fb9 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -21,18 +21,18 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" -#include "../timer.h" -#include "../port_92.h" -#include "../disk/hdc_ide.h" -#include "../machine/machine.h" +#include "86box.h" +#include "cpu.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "keyboard.h" +#include "timer.h" +#include "port_92.h" +#include "hdc_ide.h" +#include "machine.h" #include "chipset.h" @@ -142,7 +142,6 @@ sis_85c496_write(int func, int addr, uint8_t val, void *priv) port_92_remove(dev->port_92); if (val & 0x02) port_92_add(dev->port_92); - pclog("Port 92: %sabled\n", (val & 0x02) ? "En" : "Dis"); } break; @@ -197,10 +196,8 @@ sis_85c496_write(int func, int addr, uint8_t val, void *priv) break; case 0x67: - if (valxor & 0x60) { + if (valxor & 0x60) port_92_set_features(dev->port_92, !!(val & 0x20), !!(val & 0x40)); - pclog("[Port 92] Set features: %sreset, %sA20\n", !!(val & 0x20) ? "" : "no ", !!(val & 0x40) ? "" : "no "); - } break; case 0x82: @@ -239,15 +236,18 @@ static uint8_t sis_85c496_read(int func, int addr, void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; + uint8_t ret = dev->pci_conf[addr]; switch (addr) { case 0x82: /*Port 22h Mirror*/ - return inb(0x22); + ret = inb(0x22); + break; case 0x70: /*Port 70h Mirror*/ - return inb(0x70); + ret = inb(0x70); + break; } - return dev->pci_conf[addr]; + return ret; } @@ -313,7 +313,7 @@ static void dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */ dev->pci_conf[0xd1] = 0xff; - pci_add_card(5, sis_85c496_read, sis_85c496_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c496_read, sis_85c496_write, dev); sis_85c497_reset(dev); diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index f5a67198d..605799e17 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -20,14 +20,14 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" -#include "../port_92.h" +#include "86box.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "keyboard.h" +#include "port_92.h" #include "chipset.h" diff --git a/src/chipset/via_mvp3.c b/src/chipset/via_mvp3.c index d9ffc01a6..cdbcc17d1 100644 --- a/src/chipset/via_mvp3.c +++ b/src/chipset/via_mvp3.c @@ -21,13 +21,13 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" +#include "86box.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "keyboard.h" #include "chipset.h" @@ -292,7 +292,7 @@ via_mvp3_init(const device_t *info) { via_mvp3_t *dev = (via_mvp3_t *) malloc(sizeof(via_mvp3_t)); - pci_add_card(0, via_mvp3_read, via_mvp3_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, via_mvp3_read, via_mvp3_write, dev); via_mvp3_setup(dev); diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index e469f6672..f01290e65 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -23,17 +23,17 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../io.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../port_92.h" -#include "../serial.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../video/vid_paradise.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "86box_io.h" +#include "keyboard.h" +#include "mem.h" +#include "port_92.h" +#include "serial.h" +#include "fdd.h" +#include "fdc.h" +#include "video.h" #include "chipset.h" diff --git a/src/config.c b/src/config.c index f2b6076c1..6daa573aa 100644 --- a/src/config.c +++ b/src/config.c @@ -34,7 +34,7 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu/cpu.h" +#include "cpu.h" #include "device.h" #include "timer.h" #include "nvr.h" @@ -42,24 +42,23 @@ #include "isamem.h" #include "isartc.h" #include "lpt.h" -#include "disk/hdd.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" -#include "game/gameport.h" -#include "machine/machine.h" +#include "hdd.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "machine.h" #include "mouse.h" -#include "network/network.h" -#include "scsi/scsi.h" -#include "scsi/scsi_device.h" -#include "cdrom/cdrom.h" -#include "disk/zip.h" -#include "sound/sound.h" -#include "sound/midi.h" -#include "sound/snd_mpu401.h" -#include "sound/sound.h" -#include "video/video.h" +#include "network.h" +#include "scsi.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "zip.h" +#include "sound.h" +#include "midi.h" +#include "snd_mpu401.h" +#include "video.h" #include "plat.h" #include "plat_midi.h" #include "ui.h" @@ -309,7 +308,7 @@ config_read(wchar_t *fn) /* Create a new section and insert it. */ ns = malloc(sizeof(section_t)); memset(ns, 0x00, sizeof(section_t)); - strncpy(ns->name, sname, sizeof(ns->name) - 1); + memcpy(ns->name, sname, 128); list_add(&ns->list, &config_head); /* New section is now the current one. */ @@ -339,7 +338,7 @@ config_read(wchar_t *fn) /* Allocate a new variable entry.. */ ne = malloc(sizeof(entry_t)); memset(ne, 0x00, sizeof(entry_t)); - strncpy(ne->name, ename, sizeof(ne->name) - 1); + memcpy(ne->name, ename, 128); wcsncpy(ne->wdata, &buff[d], sizeof_w(ne->wdata)-1); ne->wdata[sizeof_w(ne->wdata)-1] = L'\0'; wcstombs(ne->data, ne->wdata, sizeof(ne->data)); @@ -807,6 +806,7 @@ load_other_peripherals(void) ide_qua_enabled = !!config_get_int(cat, "ide_qua", 0); bugger_enabled = !!config_get_int(cat, "bugger_enabled", 0); + postcard_enabled = !!config_get_int(cat, "postcard_enabled", 0); for (c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); @@ -1687,6 +1687,11 @@ save_other_peripherals(void) else config_set_int(cat, "bugger_enabled", bugger_enabled); + if (postcard_enabled == 0) + config_delete_var(cat, "postcard_enabled"); + else + config_set_int(cat, "postcard_enabled", postcard_enabled); + for (c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); if (isamem_type[c] == 0) diff --git a/src/cpu.txt b/src/cpu.txt new file mode 100644 index 000000000..670721fd5 --- /dev/null +++ b/src/cpu.txt @@ -0,0 +1,3 @@ +Comparing files CPU\cpu.c and CPU_NEW\CPU.C +FC: no differences encountered + diff --git a/src/cpu/386.c b/src/cpu/386.c deleted file mode 100644 index e4d011bc9..000000000 --- a/src/cpu/386.c +++ /dev/null @@ -1,256 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#ifndef INFINITY -# define INFINITY (__builtin_inff()) -#endif -#define HAVE_STDARG_H -#include "../86box.h" -#include "cpu.h" -#include "../timer.h" -#include "x86.h" -#include "x87.h" -#include "../nmi.h" -#include "../mem.h" -#include "../pic.h" -#include "../pit.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "386_common.h" - - -#define CPU_BLOCK_END() - -extern int codegen_flags_changed; - -int cpl_override = 0, fpucount = 0; -int tempc, oldcpl, optype, inttype, oddeven = 0; -int stack32, timetolive; - -uint16_t oldcs; - -uint32_t use32; -uint32_t oldds, oldss, olddslimit, oldsslimit, - olddslimitw, oldsslimitw; -uint32_t *eal_r, *eal_w; -uint32_t oxpc, cr2, cr3, cr4; -uint32_t dr[8]; -uint32_t rmdat32; -uint32_t backupregs[16]; - -x86seg gdt,ldt,idt,tr; -x86seg _oldds; - -uint32_t rmdat; - -#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; } -#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0 - - -#include "x86_flags.h" - -#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ -#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 -#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ -#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 -extern int xout; - -int oldi; - -uint32_t testr[9]; -extern int dontprint; - -#undef NOTRM -#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\ - { \ - x86_int(6); \ - return 0; \ - } - -#define OP_TABLE(name) ops_ ## name - -#define CLOCK_CYCLES(c) cycles -= (c) -#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) - -#include "x86_ops.h" - -#undef NOTRM -#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\ - { \ - x86_int(6); \ - break; \ - } - - -#ifdef ENABLE_386_LOG -int x386_do_log = ENABLE_386_LOG; - - -static void -x386_log(const char *fmt, ...) -{ - va_list ap; - - if (x386_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define x386_log(fmt, ...) -#endif - - -void exec386(int cycs) -{ - int vector, tempi, cycdiff, oldcyc; - int ins_cycles; - uint32_t addr; - - cycles+=cycs; - while (cycles>0) - { - int cycle_period = (timer_target - (uint32_t)tsc) + 1; - - x86_was_reset = 0; - cycdiff=0; - oldcyc=cycles; - while (cycdiff < cycle_period) - { - ins_cycles = cycles; - - oldcs=CS; - cpu_state.oldpc = cpu_state.pc; - oldcpl=CPL; - cpu_state.op32 = use32; - - x86_was_reset = 0; - -dontprint=0; - - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; - - fetchdat = fastreadl(cs + cpu_state.pc); - - if (!cpu_state.abrt) - { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; - - cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if(x86_was_reset) - break; - } - - if (!use32) cpu_state.pc &= 0xffff; - - if (cpu_state.abrt) - { - flags_rebuild(); - tempi = cpu_state.abrt; - cpu_state.abrt = 0; - x86_doabrt(tempi); - if (cpu_state.abrt) - { - cpu_state.abrt = 0; - CS = oldcs; - cpu_state.pc = cpu_state.oldpc; - x386_log("Double fault %i\n", ins); - pmodeint(8, 0); - if (cpu_state.abrt) - { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); - x386_log("Triple fault - reset\n"); - } - } - } - - ins_cycles -= cycles; - tsc += ins_cycles; - - cycdiff=oldcyc-cycles; - - if (trap) - { - flags_rebuild(); - /* oldpc=pc; */ - /* oldcs=CS; */ - if (msw&1) - { - pmodeint(1,0); - } - else - { - writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr = (1 << 2) + idt.base; - cpu_state.flags&=~I_FLAG; - cpu_state.flags&=~T_FLAG; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - } - } - else if (nmi && nmi_enable) - { - cpu_state.oldpc = cpu_state.pc; - oldcs = CS; - x86_int(2); - nmi_enable = 0; - if (nmi_auto_clear) - { - nmi_auto_clear = 0; - nmi = 0; - } - } - else if ((cpu_state.flags & I_FLAG) && pic_intpending) - { - vector = picinterrupt(); - if (vector != -1) - { - flags_rebuild(); - if (msw&1) - { - pmodeint(vector,0); - } - else - { - writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr = (vector << 2) + idt.base; - cpu_state.flags&=~I_FLAG; - cpu_state.flags&=~T_FLAG; - oxpc = cpu_state.pc; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - } - } - } - - ins++; - - if (timetolive) - { - timetolive--; - if (!timetolive) - fatal("Life expired\n"); - } - - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process(); - } - } -} diff --git a/src/cpu/codegen.c b/src/cpu/codegen.c index d951f650c..44b1c502d 100644 --- a/src/cpu/codegen.c +++ b/src/cpu/codegen.c @@ -2,8 +2,9 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" + +#include "86box.h" +#include "mem.h" #include "cpu.h" #include "x86_ops.h" #include "codegen.h" diff --git a/src/cpu/codegen.h b/src/cpu/codegen.h index 38847f78b..f7c41f849 100644 --- a/src/cpu/codegen.h +++ b/src/cpu/codegen.h @@ -38,7 +38,7 @@ #define _CODEGEN_H_ #include "../mem.h" -#include "x86_ops.h" +#include "../cpu_common/x86_ops.h" #ifdef __amd64__ #include "codegen_x86-64.h" @@ -315,9 +315,6 @@ extern int cpu_recomp_evicted, cpu_recomp_evicted_latched; extern int cpu_recomp_reuse, cpu_recomp_reuse_latched; extern int cpu_recomp_removed, cpu_recomp_removed_latched; -extern int cpu_reps, cpu_reps_latched; -extern int cpu_notreps, cpu_notreps_latched; - extern int codegen_block_cycles; extern void (*codegen_timing_start)(); diff --git a/src/cpu/codegen_ops.c b/src/cpu/codegen_ops.c index a577d3b6e..229fa1882 100644 --- a/src/cpu/codegen_ops.c +++ b/src/cpu/codegen_ops.c @@ -2,8 +2,9 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" + +#include "86box.h" +#include "mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu/codegen_ops_x86-64.h b/src/cpu/codegen_ops_x86-64.h index de6763561..9508a83bd 100644 --- a/src/cpu/codegen_ops_x86-64.h +++ b/src/cpu/codegen_ops_x86-64.h @@ -4663,11 +4663,6 @@ static inline void FP_OP_IL(int op) FP_OP_MEM(op); } -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) - static inline void FP_COMPARE_REG(int dst, int src) { addbyte(0x8b); /*MOV EAX, [TOP]*/ diff --git a/src/cpu/codegen_ops_x86.h b/src/cpu/codegen_ops_x86.h index 225490cd3..13ca37c4c 100644 --- a/src/cpu/codegen_ops_x86.h +++ b/src/cpu/codegen_ops_x86.h @@ -2951,10 +2951,6 @@ static inline void FP_OP_IQ(int op) } } #endif -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) static inline void FP_COMPARE_S() { diff --git a/src/cpu/codegen_timing_486.c b/src/cpu/codegen_timing_486.c index 3f45d117e..912bfc16b 100644 --- a/src/cpu/codegen_timing_486.c +++ b/src/cpu/codegen_timing_486.c @@ -2,8 +2,8 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" +#include "86box.h" +#include "mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu/codegen_timing_686.c b/src/cpu/codegen_timing_686.c index fc818d7f1..dc901dddc 100644 --- a/src/cpu/codegen_timing_686.c +++ b/src/cpu/codegen_timing_686.c @@ -12,8 +12,8 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" +#include "86box.h" +#include "mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu/codegen_timing_common.c b/src/cpu/codegen_timing_common.c index f53a8fc4d..c9ac19766 100644 --- a/src/cpu/codegen_timing_common.c +++ b/src/cpu/codegen_timing_common.c @@ -2,7 +2,7 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "codegen_timing_common.h" diff --git a/src/cpu/codegen_timing_pentium.c b/src/cpu/codegen_timing_pentium.c index 88c4e9544..3a625ed6d 100644 --- a/src/cpu/codegen_timing_pentium.c +++ b/src/cpu/codegen_timing_pentium.c @@ -13,8 +13,8 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" +#include "86box.h" +#include "mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu/codegen_timing_winchip.c b/src/cpu/codegen_timing_winchip.c index 93717c4a6..7074307ef 100644 --- a/src/cpu/codegen_timing_winchip.c +++ b/src/cpu/codegen_timing_winchip.c @@ -2,7 +2,7 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu/codegen_x86-64.c b/src/cpu/codegen_x86-64.c index 42136207c..c0ece0ce0 100644 --- a/src/cpu/codegen_x86-64.c +++ b/src/cpu/codegen_x86-64.c @@ -5,13 +5,13 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" #include "x87.h" -#include "../mem.h" +#include "mem.h" #include "386_common.h" diff --git a/src/cpu/codegen_x86.c b/src/cpu/codegen_x86.c index a3352943f..b6fd2a49b 100644 --- a/src/cpu/codegen_x86.c +++ b/src/cpu/codegen_x86.c @@ -43,12 +43,12 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" -#include "x86_ops.h" +#include "../cpu_common/x86_ops.h" #include "x87.h" #include "386_common.h" diff --git a/src/cpu/x86_ops_arith_ex.h b/src/cpu/x86_ops_arith_ex.h deleted file mode 100644 index cc4fcd7c3..000000000 --- a/src/cpu/x86_ops_arith_ex.h +++ /dev/null @@ -1,752 +0,0 @@ -#define OP_ARITH(name, operation, setflags, flagops, gettempc) \ - static int op ## name ## _b_rmw_a16(uint32_t fetchdat) \ - { \ - uint8_t dst; \ - uint8_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = getr8(cpu_rm); \ - src = getr8(cpu_reg); \ - setflags ## 8 flagops; \ - setr8(cpu_rm, operation); \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - src = getr8(cpu_reg); \ - seteab(operation); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _b_rmw_a32(uint32_t fetchdat) \ - { \ - uint8_t dst; \ - uint8_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = getr8(cpu_rm); \ - src = getr8(cpu_reg); \ - setflags ## 8 flagops; \ - setr8(cpu_rm, operation); \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - src = getr8(cpu_reg); \ - seteab(operation); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _w_rmw_a16(uint32_t fetchdat) \ - { \ - uint16_t dst; \ - uint16_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].w; \ - src = cpu_state.regs[cpu_reg].w; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_rm].w = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].w; \ - seteaw(operation); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _w_rmw_a32(uint32_t fetchdat) \ - { \ - uint16_t dst; \ - uint16_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].w; \ - src = cpu_state.regs[cpu_reg].w; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_rm].w = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].w; \ - seteaw(operation); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _l_rmw_a16(uint32_t fetchdat) \ - { \ - uint32_t dst; \ - uint32_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].l; \ - src = cpu_state.regs[cpu_reg].l; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_rm].l = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].l; \ - seteal(operation); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _l_rmw_a32(uint32_t fetchdat) \ - { \ - uint32_t dst; \ - uint32_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].l; \ - src = cpu_state.regs[cpu_reg].l; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_rm].l = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].l; \ - seteal(operation); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _b_rm_a16(uint32_t fetchdat) \ - { \ - uint8_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - dst = getr8(cpu_reg); \ - src = geteab(); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - setr8(cpu_reg, operation); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _b_rm_a32(uint32_t fetchdat) \ - { \ - uint8_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - dst = getr8(cpu_reg); \ - src = geteab(); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - setr8(cpu_reg, operation); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _w_rm_a16(uint32_t fetchdat) \ - { \ - uint16_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - dst = cpu_state.regs[cpu_reg].w; \ - src = geteaw(); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_reg].w = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _w_rm_a32(uint32_t fetchdat) \ - { \ - uint16_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - dst = cpu_state.regs[cpu_reg].w; \ - src = geteaw(); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_reg].w = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _l_rm_a16(uint32_t fetchdat) \ - { \ - uint32_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - dst = cpu_state.regs[cpu_reg].l; \ - src = geteal(); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_reg].l = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _l_rm_a32(uint32_t fetchdat) \ - { \ - uint32_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - dst = cpu_state.regs[cpu_reg].l; \ - src = geteal(); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_reg].l = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _AL_imm(uint32_t fetchdat) \ - { \ - uint8_t dst = AL; \ - uint8_t src = getbytef(); \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 8 flagops; \ - AL = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int op ## name ## _AX_imm(uint32_t fetchdat) \ - { \ - uint16_t dst = AX; \ - uint16_t src = getwordf(); \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 16 flagops; \ - AX = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int op ## name ## _EAX_imm(uint32_t fetchdat) \ - { \ - uint32_t dst = EAX; \ - uint32_t src = getlong(); if (cpu_state.abrt) return 1; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 32 flagops; \ - EAX = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); \ - return 0; \ - } - -OP_ARITH(ADD, dst + src, setadd, (dst, src), 0) -OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src), 1) -OP_ARITH(SUB, dst - src, setsub, (dst, src), 0) -OP_ARITH(SBB, dst - (src + tempc), setsbc, (dst, src), 1) -OP_ARITH(OR, dst | src, setznp, (dst | src), 0) -OP_ARITH(AND, dst & src, setznp, (dst & src), 0) -OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src), 0) - -static int opCMP_b_rmw_a16(uint32_t fetchdat) -{ - uint8_t dst; - fetch_ea_16(fetchdat); - dst = geteab(); if (cpu_state.abrt) return 1; - setsub8(dst, getr8(cpu_reg)); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opCMP_b_rmw_a32(uint32_t fetchdat) -{ - uint8_t dst; - fetch_ea_32(fetchdat); - dst = geteab(); if (cpu_state.abrt) return 1; - setsub8(dst, getr8(cpu_reg)); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opCMP_w_rmw_a16(uint32_t fetchdat) -{ - uint16_t dst; - fetch_ea_16(fetchdat); - dst = geteaw(); if (cpu_state.abrt) return 1; - setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opCMP_w_rmw_a32(uint32_t fetchdat) -{ - uint16_t dst; - fetch_ea_32(fetchdat); - dst = geteaw(); if (cpu_state.abrt) return 1; - setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opCMP_l_rmw_a16(uint32_t fetchdat) -{ - uint32_t dst; - fetch_ea_16(fetchdat); - dst = geteal(); if (cpu_state.abrt) return 1; - setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; -} -static int opCMP_l_rmw_a32(uint32_t fetchdat) -{ - uint32_t dst; - fetch_ea_32(fetchdat); - dst = geteal(); if (cpu_state.abrt) return 1; - setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; -} - -static int opCMP_b_rm_a16(uint32_t fetchdat) -{ - uint8_t src; - fetch_ea_16(fetchdat); - src = geteab(); if (cpu_state.abrt) return 1; - setsub8(getr8(cpu_reg), src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opCMP_b_rm_a32(uint32_t fetchdat) -{ - uint8_t src; - fetch_ea_32(fetchdat); - src = geteab(); if (cpu_state.abrt) return 1; - setsub8(getr8(cpu_reg), src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opCMP_w_rm_a16(uint32_t fetchdat) -{ - uint16_t src; - fetch_ea_16(fetchdat); - src = geteaw(); if (cpu_state.abrt) return 1; - setsub16(cpu_state.regs[cpu_reg].w, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opCMP_w_rm_a32(uint32_t fetchdat) -{ - uint16_t src; - fetch_ea_32(fetchdat); - src = geteaw(); if (cpu_state.abrt) return 1; - setsub16(cpu_state.regs[cpu_reg].w, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opCMP_l_rm_a16(uint32_t fetchdat) -{ - uint32_t src; - fetch_ea_16(fetchdat); - src = geteal(); if (cpu_state.abrt) return 1; - setsub32(cpu_state.regs[cpu_reg].l, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; -} -static int opCMP_l_rm_a32(uint32_t fetchdat) -{ - uint32_t src; - fetch_ea_32(fetchdat); - src = geteal(); if (cpu_state.abrt) return 1; - setsub32(cpu_state.regs[cpu_reg].l, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; -} - -static int opCMP_AL_imm(uint32_t fetchdat) -{ - uint8_t src = getbytef(); - setsub8(AL, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} - -static int opCMP_AX_imm(uint32_t fetchdat) -{ - uint16_t src = getwordf(); - setsub16(AX, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} - -static int opCMP_EAX_imm(uint32_t fetchdat) -{ - uint32_t src = getlong(); if (cpu_state.abrt) return 1; - setsub32(EAX, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} - -static int opTEST_b_a16(uint32_t fetchdat) -{ - uint8_t temp, temp2; - fetch_ea_16(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - temp2 = getr8(cpu_reg); - setznp8(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opTEST_b_a32(uint32_t fetchdat) -{ - uint8_t temp, temp2; - fetch_ea_32(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - temp2 = getr8(cpu_reg); - setznp8(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opTEST_w_a16(uint32_t fetchdat) -{ - uint16_t temp, temp2; - fetch_ea_16(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].w; - setznp16(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opTEST_w_a32(uint32_t fetchdat) -{ - uint16_t temp, temp2; - fetch_ea_32(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].w; - setznp16(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opTEST_l_a16(uint32_t fetchdat) -{ - uint32_t temp, temp2; - fetch_ea_16(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].l; - setznp32(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; -} -static int opTEST_l_a32(uint32_t fetchdat) -{ - uint32_t temp, temp2; - fetch_ea_32(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].l; - setznp32(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; -} - -static int opTEST_AL(uint32_t fetchdat) -{ - uint8_t temp = getbytef(); - setznp8(AL & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opTEST_AX(uint32_t fetchdat) -{ - uint16_t temp = getwordf(); - setznp16(AX & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} -static int opTEST_EAX(uint32_t fetchdat) -{ - uint32_t temp = getlong(); if (cpu_state.abrt) return 1; - setznp32(EAX & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} - - -#define ARITH_MULTI(ea_width, flag_width, is32) \ - dst = read ## ea_width(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \ - switch ((rmdat >> 3) & 7) \ - { \ - case 0x00: /*ADD ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - write ## ea_width(easeg, cpu_state.eaaddr, dst + src); if (cpu_state.abrt) return 1; \ - setadd ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x01: /*OR ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - dst |= src; \ - write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x02: /*ADC ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - tempc = CF_SET() ? 1 : 0; \ - write ## ea_width(easeg, cpu_state.eaaddr, dst + src + tempc); if (cpu_state.abrt) return 1; \ - setadc ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x03: /*SBB ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - tempc = CF_SET() ? 1 : 0; \ - write ## ea_width(easeg, cpu_state.eaaddr, dst - (src + tempc)); if (cpu_state.abrt) return 1; \ - setsbc ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x04: /*AND ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - dst &= src; \ - write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x05: /*SUB ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - write ## ea_width(easeg, cpu_state.eaaddr, dst - src); if (cpu_state.abrt) return 1; \ - setsub ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x06: /*XOR ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - dst ^= src; \ - write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x07: /*CMP ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 0, is32) \ - setsub ## flag_width(dst, src); \ - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); \ - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); \ - break; \ - } - - -static int op80_a16(uint32_t fetchdat) -{ - uint8_t src, dst; - - fetch_ea_16(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - ARITH_MULTI(8, 8, 0); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - - return 0; -} -static int op80_a32(uint32_t fetchdat) -{ - uint8_t src, dst; - - fetch_ea_32(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - ARITH_MULTI(8, 8, 1); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - - return 0; -} -static int op81_w_a16(uint32_t fetchdat) -{ - uint16_t src, dst; - - fetch_ea_16(fetchdat); - src = getword(); if (cpu_state.abrt) return 1; - ARITH_MULTI(16, 16, 0); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - - return 0; -} -static int op81_w_a32(uint32_t fetchdat) -{ - uint16_t src, dst; - - fetch_ea_32(fetchdat); - src = getword(); if (cpu_state.abrt) return 1; - ARITH_MULTI(16, 16, 1); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - - return 0; -} -static int op81_l_a16(uint32_t fetchdat) -{ - uint32_t src, dst; - - fetch_ea_16(fetchdat); - src = getlong(); if (cpu_state.abrt) return 1; - ARITH_MULTI(32, 32, 0); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - - return 0; -} -static int op81_l_a32(uint32_t fetchdat) -{ - uint32_t src, dst; - - fetch_ea_32(fetchdat); - src = getlong(); if (cpu_state.abrt) return 1; - ARITH_MULTI(32, 32, 1); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - - return 0; -} - -static int op83_w_a16(uint32_t fetchdat) -{ - uint16_t src, dst; - - fetch_ea_16(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xff00; - ARITH_MULTI(16, 16, 0); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - - return 0; -} -static int op83_w_a32(uint32_t fetchdat) -{ - uint16_t src, dst; - - fetch_ea_32(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xff00; - ARITH_MULTI(16, 16, 1); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - - return 0; -} - -static int op83_l_a16(uint32_t fetchdat) -{ - uint32_t src, dst; - - fetch_ea_16(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xffffff00; - ARITH_MULTI(32, 32, 0); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - - return 0; -} -static int op83_l_a32(uint32_t fetchdat) -{ - uint32_t src, dst; - - fetch_ea_32(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xffffff00; - ARITH_MULTI(32, 32, 1); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - - return 0; -} - diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 036dfcfe4..ced052ea0 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -24,13 +24,13 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../device.h" -#include "../timer.h" -#include "../machine/machine.h" -#include "../mem.h" -#include "../nvr.h" +#include "device.h" +#include "timer.h" +#include "machine.h" +#include "mem.h" +#include "nvr.h" #include "x86.h" #include "x86_flags.h" #include "386_common.h" @@ -108,8 +108,8 @@ static void seg_reset(x86seg *s) if(s == &cpu_state.seg_cs) { // TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below. - //s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0; - s->base = AT ? 0xF0000 : 0xFFFF0; + s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0; + // s->base = AT ? 0xF0000 : 0xFFFF0; s->seg = AT ? 0xF000 : 0xFFFF; } else diff --git a/src/cpu/x87.h b/src/cpu/x87.h deleted file mode 100644 index 6d2cb3ca9..000000000 --- a/src/cpu/x87.h +++ /dev/null @@ -1,26 +0,0 @@ -uint32_t x87_pc_off,x87_op_off; -uint16_t x87_pc_seg,x87_op_seg; - -static __inline void x87_set_mmx() -{ - uint64_t *p; - cpu_state.TOP = 0; - p = (uint64_t *)cpu_state.tag; - *p = 0; - cpu_state.ismmx = 1; -} - -static __inline void x87_emms() -{ - uint64_t *p; - p = (uint64_t *)cpu_state.tag; - *p = 0; - cpu_state.ismmx = 0; -} - - -uint16_t x87_gettag(); -void x87_settag(uint16_t new_tag); - -/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ -#define TAG_UINT64 (1 << 2) diff --git a/src/cpu_common.bak/386.c b/src/cpu_common.bak/386.c new file mode 100644 index 000000000..416f9577e --- /dev/null +++ b/src/cpu_common.bak/386.c @@ -0,0 +1,335 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "x86.h" +#include "x87.h" +#include "nmi.h" +#include "mem.h" +#include "pic.h" +#include "pit.h" +#include "fdd.h" +#include "fdc.h" +#include "386_common.h" +#ifdef USE_NEW_DYNAREC +#include "codegen.h" +#endif + + +#undef CPU_BLOCK_END +#define CPU_BLOCK_END() + + +extern int codegen_flags_changed; + +int tempc, oldcpl, optype, inttype, oddeven = 0; +int timetolive; + +uint16_t oldcs; + +uint32_t oldds, oldss, olddslimit, oldsslimit, + olddslimitw, oldsslimitw; +uint32_t oxpc; +uint32_t rmdat32; +uint32_t backupregs[16]; + +x86seg _oldds; + + +#ifdef ENABLE_386_LOG +int x386_do_log = ENABLE_386_LOG; + + +void +x386_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_log(fmt, ...) +#endif + + +#undef CPU_BLOCK_END +#define CPU_BLOCK_END() + +static inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; +// pc++; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } +} + +static inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0 + +#include "x86_flags.h" + +#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ +#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 +#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ +#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 + + +#define OP_TABLE(name) ops_ ## name + +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "x86_ops.h" + +void +exec386(int cycs) +{ + // uint8_t opcode; + int vector, tempi, cycdiff, oldcyc; + int cycle_period, ins_cycles; + uint32_t addr; + + cycles += cycs; + + while (cycles > 0) { + cycle_period = (timer_target - (uint32_t)tsc) + 1; + + x86_was_reset = 0; + cycdiff = 0; + oldcyc = cycles; + while (cycdiff < cycle_period) { + ins_cycles = cycles; + +#ifndef USE_NEW_DYNAREC + oldcs=CS; + oldcpl=CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + +#ifndef USE_NEW_DYNAREC + x86_was_reset = 0; +#endif + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + if (cpu_state.abrt) { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + cpu_state.pc = cpu_state.oldpc; + x386_log("Double fault %i\n", ins); + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_LOG + x386_log("Triple fault - reset\n"); +#endif + } + } + } + + ins_cycles -= cycles; + tsc += ins_cycles; + + cycdiff = oldcyc - cycles; + + if (trap) { + flags_rebuild(); + if (msw&1) + pmodeint(1,0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } else if (nmi && nmi_enable && nmi_mask) { + cpu_state.oldpc = cpu_state.pc; + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } + } else if ((cpu_state.flags & I_FLAG) && pic_intpending) { + vector = picinterrupt(); + if (vector != -1) { + flags_rebuild(); + if (msw & 1) + pmodeint(vector, 0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (vector << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } + } + + ins++; + + if (timetolive) { + timetolive--; + if (!timetolive) + fatal("Life expired\n"); + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process(); + } + } +} diff --git a/src/cpu_new/386_common.c b/src/cpu_common.bak/386_common.c similarity index 93% rename from src/cpu_new/386_common.c rename to src/cpu_common.bak/386_common.c index 32b65e0bf..cb140c41a 100644 --- a/src/cpu_new/386_common.c +++ b/src/cpu_common.bak/386_common.c @@ -9,17 +9,17 @@ # define INFINITY (__builtin_inff()) #endif #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../timer.h" +#include "timer.h" #include "x86.h" #include "x87.h" -#include "../nmi.h" -#include "../mem.h" -#include "../pic.h" -#include "../pit.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "nmi.h" +#include "mem.h" +#include "pic.h" +#include "pit.h" +#include "fdd.h" +#include "fdc.h" #include "386_common.h" #include "x86_flags.h" #include "codegen.h" @@ -45,7 +45,11 @@ int cpl_override=0; int fpucount=0; +#ifdef USE_NEW_DYNAREC uint16_t cpu_cur_status = 0; +#else +uint32_t cpu_cur_status = 0; +#endif uint32_t pccache; uint8_t *pccache2; @@ -117,6 +121,9 @@ void x86_int(int num) cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); } @@ -161,6 +168,9 @@ void x86_int_sw(int num) cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); cycles -= timing_int_rm; @@ -197,6 +207,9 @@ int x86_int_sw_rm(int num) cpu_state.flags &= ~T_FLAG; cpu_state.pc = new_pc; loadcs(new_cs); +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif cycles -= timing_int_rm; trap = 0; @@ -220,7 +233,11 @@ int checkio(int port) if (cpu_state.abrt) return 0; if ((t+(port>>3))>tr.limit) return 1; cpl_override = 1; +#ifdef USE_NEW_DYNAREC d = readmembl(tr.base + t + (port >> 3)); +#else + d = readmemb386l(0, tr.base + t + (port >> 3)); +#endif cpl_override = 0; return d&(1<<(port&7)); } diff --git a/src/cpu_new/386_common.h b/src/cpu_common.bak/386_common.h similarity index 100% rename from src/cpu_new/386_common.h rename to src/cpu_common.bak/386_common.h diff --git a/src/cpu/386_dynarec.c b/src/cpu_common.bak/386_dynarec - Cópia (2).c similarity index 85% rename from src/cpu/386_dynarec.c rename to src/cpu_common.bak/386_dynarec - Cópia (2).c index 67594c786..421381dd3 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu_common.bak/386_dynarec - Cópia (2).c @@ -8,31 +8,31 @@ #ifndef INFINITY # define INFINITY (__builtin_inff()) #endif + #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../pic.h" -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" #ifdef USE_DYNAREC #include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif #endif #include "386_common.h" #define CPU_BLOCK_END() cpu_block_end = 1 -uint32_t cpu_cur_status = 0; - -int cpu_reps, cpu_reps_latched; -int cpu_notreps, cpu_notreps_latched; int inrecomp = 0, cpu_block_end = 0; int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; @@ -55,7 +55,7 @@ x386_dynarec_log(const char *fmt, ...) } } #else -#define x86_dynarec_log (fmt, ...) +#define x386_dynarec_log(fmt, ...) #endif @@ -175,155 +175,6 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) #include "x86_flags.h" -void x86_int(int num) -{ - uint32_t addr; - flags_rebuild(); - cpu_state.pc=cpu_state.oldpc; - if (msw&1) - { - pmodeint(num,0); - } - else - { - addr = (num << 2) + idt.base; - - if ((num << 2) + 3 > idt.limit) - { - if (idt.limit < 35) - { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); -#ifdef ENABLE_386_DYNAREC_LOG - x386_dynarec_log("Triple fault in real mode - reset\n"); -#endif - } - else - x86_int(8); - } - else - { - if (stack32) - { - writememw(ss,ESP-2,cpu_state.flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; - } - else - { - writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - - cpu_state.flags&=~I_FLAG; - cpu_state.flags&=~T_FLAG; - oxpc=cpu_state.pc; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - } - } - cycles-=70; - CPU_BLOCK_END(); -} - -void x86_int_sw(int num) -{ - uint32_t addr; - flags_rebuild(); - cycles -= timing_int; - if (msw&1) - { - pmodeint(num,1); - } - else - { - addr = (num << 2) + idt.base; - - if ((num << 2) + 3 > idt.limit) - { - x86_int(13); - } - else - { - if (stack32) - { - writememw(ss,ESP-2,cpu_state.flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; - } - else - { - writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - - cpu_state.flags&=~I_FLAG; - cpu_state.flags&=~T_FLAG; - oxpc=cpu_state.pc; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - cycles -= timing_int_rm; - } - } - trap = 0; - CPU_BLOCK_END(); -} - -int x86_int_sw_rm(int num) -{ - uint32_t addr; - uint16_t new_pc, new_cs; - - flags_rebuild(); - cycles -= timing_int; - - addr = num << 2; - new_pc = readmemw(0, addr); - new_cs = readmemw(0, addr + 2); - - if (cpu_state.abrt) return 1; - - writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); - if (cpu_state.abrt) { -#ifdef ENABLE_386_DYNAREC_LOG - x386_dynarec_log("abrt5\n"); -#endif - return 1; - } - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - if (cpu_state.abrt) { -#ifdef ENABLE_386_DYNAREC_LOG - x386_dynarec_log("abrt6\n"); -#endif - return 1; - } - SP-=6; - - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = new_pc; - loadcs(new_cs); - oxpc=cpu_state.pc; - - cycles -= timing_int_rm; - trap = 0; - CPU_BLOCK_END(); - - return 0; -} - -void x86illegal() -{ - x86_int(6); -} /*Prefetch emulation is a fairly simplistic model: - All instruction bytes must be fetched before it starts. @@ -411,94 +262,6 @@ static void prefetch_flush() #define PREFETCH_FLUSH() prefetch_flush() -int checkio(int port) -{ - uint16_t t; - uint8_t d; - cpl_override = 1; - t = readmemw(tr.base, 0x66); - cpl_override = 0; - if (cpu_state.abrt) return 0; - if ((t+(port>>3))>tr.limit) return 1; - cpl_override = 1; - d = readmemb386l(0, tr.base + t + (port >> 3)); - cpl_override = 0; - return d&(1<<(port&7)); -} - -int xout=0; - - -#define divexcp() { \ - x86_int(0); \ -} - -int divl(uint32_t val) -{ - uint64_t num, quo; - uint32_t rem, quo32; - - if (val==0) - { - divexcp(); - return 1; - } - - num=(((uint64_t)EDX)<<32)|EAX; - quo=num/val; - rem=num%val; - quo32=(uint32_t)(quo&0xFFFFFFFF); - - if (quo!=(uint64_t)quo32) - { - divexcp(); - return 1; - } - EDX=rem; - EAX=quo32; - return 0; -} -int idivl(int32_t val) -{ - int64_t num, quo; - int32_t rem, quo32; - - if (val==0) - { - divexcp(); - return 1; - } - - num=(((uint64_t)EDX)<<32)|EAX; - quo=num/val; - rem=num%val; - quo32=(int32_t)(quo&0xFFFFFFFF); - - if (quo!=(int64_t)quo32) - { - divexcp(); - return 1; - } - EDX=rem; - EAX=quo32; - return 0; -} - - -void cpu_386_flags_extract() -{ - flags_extract(); -} -void cpu_386_flags_rebuild() -{ - flags_rebuild(); -} - -int oldi; - -uint32_t testr[9]; -int dontprint=0; - void enter_smm() { uint32_t smram_state = smbase + 0xfe00; @@ -510,6 +273,7 @@ void enter_smm() cpu_state.eflags = 0; in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); smi_latched = 1; mem_writel_phys(smram_state + 0xf8, smbase); @@ -704,6 +468,7 @@ void leave_smm() = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; } + mem_restore_mem_state(smbase, 131072); in_smm = 0; nmi_mask = 1; @@ -716,11 +481,12 @@ void leave_smm() #include "386_ops.h" -#define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(cpu_state.flags & T_FLAG)) +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) #ifdef USE_DYNAREC static int cycles_main = 0; + void exec386_dynarec(int cycs) { int vector; @@ -1134,10 +900,10 @@ inrecomp=0; } } } - - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process(); } + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + cycles_main -= (cycles_start - cycles); } } diff --git a/src/cpu_common.bak/386_dynarec - Cópia.c b/src/cpu_common.bak/386_dynarec - Cópia.c new file mode 100644 index 000000000..75219e86a --- /dev/null +++ b/src/cpu_common.bak/386_dynarec - Cópia.c @@ -0,0 +1,1008 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cycdiff=0; +#endif + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); +#ifdef USE_NEW_DYNAREC + codeblock_t *block = &codeblock[codeblock_hash[hash]]; +#else + codeblock_t *block = codeblock_hash[hash]; +#endif + int valid_block = 0; +#ifdef USE_NEW_DYNAREC + + if (!cpu_state.abrt) +#else + trap = 0; + + if (block && !cpu_state.abrt) +#endif + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + 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); + + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) +#else + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) +#endif + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + { + block = new_block; +#ifdef USE_NEW_DYNAREC + codeblock_hash[hash] = get_block_nr(block); +#endif + } + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { +#ifdef USE_NEW_DYNAREC + codegen_check_flush(page, page->dirty_mask, phys_addr); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +#else + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +#endif + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ +#ifdef USE_NEW_DYNAREC + uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); +#else + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); +#endif + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; +#ifdef USE_NEW_DYNAREC + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + } +#else + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } +#endif + } +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) + { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) +#else + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) +#endif + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ +#ifdef USE_NEW_DYNAREC + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); +#else + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; +#endif + } + } + +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) +#else + if (valid_block && block->was_recompiled) +#endif + { + void (*code)() = (void *)&block->data[BLOCK_START]; + +#ifndef USE_NEW_DYNAREC + codeblock_hash[hash] = block; +#endif + + inrecomp=1; + code(); + inrecomp=0; + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { +#ifdef USE_NEW_DYNAREC + start_pc = cs+cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#else + start_pc = cpu_state.pc; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + start_pc = cs+cpu_state.pc; +#ifdef USE_NEW_DYNAREC + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs=CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } +#ifdef USE_NEW_DYNAREC + else + cpu_state.oldpc = cpu_state.pc; +#endif + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); +#endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + else if (trap) + { +#ifdef USE_NEW_DYNAREC + trap = 0; +#endif + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags & I_FLAG) && pic_intpending) + { + vector = picinterrupt(); + if (vector != -1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu_new/386_dynarec.c b/src/cpu_common.bak/386_dynarec.c similarity index 99% rename from src/cpu_new/386_dynarec.c rename to src/cpu_common.bak/386_dynarec.c index 0081aceb8..4ca6b4493 100644 --- a/src/cpu_new/386_dynarec.c +++ b/src/cpu_common.bak/386_dynarec.c @@ -9,18 +9,18 @@ # define INFINITY (__builtin_inff()) #endif #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../pic.h" -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" #ifdef USE_DYNAREC #include "codegen.h" #include "codegen_backend.h" @@ -874,10 +874,11 @@ void exec386_dynarec(int cycs) } } } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); } - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process(); cycles_main -= (cycles_start - cycles); } } diff --git a/src/cpu_common.bak/386_dynarec.c.temp b/src/cpu_common.bak/386_dynarec.c.temp new file mode 100644 index 000000000..78130f3c0 --- /dev/null +++ b/src/cpu_common.bak/386_dynarec.c.temp @@ -0,0 +1,900 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cycdiff=0; + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { + oldcs = CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + + if (!use32) cpu_state.pc &= 0xffff; + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); + codeblock_t *block = codeblock_hash[hash]; + int valid_block = 0; + trap = 0; + + if (block && !cpu_state.abrt) + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + block = new_block; + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + } + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; + } + } + + if (valid_block && block->was_recompiled) + { + void (*code)() = (void *)&block->data[BLOCK_START]; + + codeblock_hash[hash] = block; + + inrecomp=1; + code(); + inrecomp=0; + if (!use32) cpu_state.pc &= 0xffff; + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { + oldcs = CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { + oldcs=CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; + CS = oldcs; +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Double fault %i\n", ins); +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); + #ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); + #endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + else if (trap) + { + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; + oldcs = CS; + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags&I_FLAG) && pic_intpending) + { + vector = picinterrupt(); + if (vector != -1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + oxpc=cpu_state.pc; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu_new/386_dynarec_ops.c b/src/cpu_common.bak/386_dynarec_ops.c similarity index 95% rename from src/cpu_new/386_dynarec_ops.c rename to src/cpu_common.bak/386_dynarec_ops.c index 1996b5824..80b72d33b 100644 --- a/src/cpu_new/386_dynarec_ops.c +++ b/src/cpu_common.bak/386_dynarec_ops.c @@ -9,15 +9,14 @@ #endif #include "../86box.h" #include "cpu.h" -#include "../timer.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" #include "x86_flags.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../pic.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" #include "codegen.h" #define CPU_BLOCK_END() cpu_block_end = 1 diff --git a/src/cpu/386_ops.h b/src/cpu_common.bak/386_ops.h similarity index 82% rename from src/cpu/386_ops.h rename to src/cpu_common.bak/386_ops.h index c66b3d0b4..a8213d116 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu_common.bak/386_ops.h @@ -167,7 +167,7 @@ static int ILLEGAL(uint32_t fetchdat) return 0; } -#if defined(DEV_BRANCH) && (defined(USE_AMD_K) || defined(USE_I686)) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_AMD_K) || defined(USE_I686))) static int internal_illegal(char *s) { cpu_state.pc = cpu_state.oldpc; @@ -184,13 +184,11 @@ extern void x386_dynarec_log(const char *fmt, ...); #endif #endif -#include "x86seg.h" #include "x86_ops_arith.h" #include "x86_ops_atomic.h" #include "x86_ops_bcd.h" #include "x86_ops_bit.h" #include "x86_ops_bitscan.h" -#include "x86_ops_call.h" #include "x86_ops_flag.h" #include "x86_ops_fpu.h" #include "x86_ops_inc_dec.h" @@ -220,10 +218,16 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_rep.h" #include "x86_ops_ret.h" #include "x86_ops_set.h" -#include "x86_ops_shift.h" #include "x86_ops_stack.h" #include "x86_ops_string.h" #include "x86_ops_xchg.h" +#include "x86seg.h" +#include "x86_ops_call.h" +#include "x86_ops_shift.h" +#ifdef USE_NEW_DYNAREC +#include "x86_ops_amd.h" +#include "x86_ops_3dnow.h" +#endif static int op0F_w_a16(uint32_t fetchdat) @@ -454,7 +458,7 @@ const OpFn OP_TABLE(486_0f)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -632,6 +636,99 @@ const OpFn OP_TABLE(winchip_0f)[1024] = /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; +#ifdef USE_NEW_DYNAREC +const OpFn OP_TABLE(winchip2_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +}; +#endif + const OpFn OP_TABLE(pentium_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -814,7 +911,191 @@ const OpFn OP_TABLE(pentiummmx_0f)[1024] = /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#ifdef USE_NEW_DYNAREC +const OpFn OP_TABLE(k6_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +}; + +const OpFn OP_TABLE(k62_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +}; +#endif + +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) const OpFn OP_TABLE(c6x86mx_0f)[1024] = { /*16-bit data, 16-bit addr*/ diff --git a/src/cpu_new/808x.c b/src/cpu_common.bak/808x.c similarity index 98% rename from src/cpu_new/808x.c rename to src/cpu_common.bak/808x.c index 686ea9e0c..1904d7322 100644 --- a/src/cpu_new/808x.c +++ b/src/cpu_common.bak/808x.c @@ -9,7 +9,7 @@ * 808x CPU emulation, mostly ported from reenigne's XTCE, which * is cycle-accurate. * - * Version: @(#)808x.c 1.0.9 2019/02/13 + * Version: @(#)808x.c 1.0.11 2019/10/21 * * Authors: Andrew Jenner, * Miran Grca, @@ -23,17 +23,18 @@ #include #include #include + #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../nmi.h" -#include "../pic.h" -#include "../timer.h" +#include "machine.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" /* The opcode of the instruction currently being executed. */ uint8_t opcode; @@ -235,7 +236,7 @@ clock_end(void) { int diff = cycdiff - cycles; - /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ + /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ tsc += (uint64_t)diff * ((uint64_t)xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) timer_process(); @@ -257,8 +258,10 @@ fetch_and_bus(int c, int bus) } pfq_add(c, !bus); - clock_end(); - clock_start(); + if (bus < 2) { + clock_end(); + clock_start(); + } } @@ -275,10 +278,13 @@ wait(int c, int bus) void sub_cycles(int c) { + if (c <= 0) + return; + cycles -= c; if (!is286) - fetch_and_bus(c, 1); + fetch_and_bus(c, 2); } @@ -647,6 +653,13 @@ sign_extend(uint8_t data) } +static uint32_t +sign_extend32(uint16_t data) +{ + return data + (data < 0x8000 ? 0 : 0xffff0000); +} + + /* Fetches the effective address from the prefetch queue according to MOD and R/M. */ static void do_mod_rm(void) @@ -912,7 +925,7 @@ reset_common(int hard) if (isibmcpu) cpu_cache_int_enabled = 1; else - cpu_cache_int_enabled = 0; + cpu_cache_int_enabled = 0; cpu_update_waitstates(); cr4 = 0; cpu_state.eflags = 0; @@ -920,6 +933,7 @@ reset_common(int hard) if (AT) { loadcs(0xF000); cpu_state.pc = 0xFFF0; + cpu_state.seg_cs.base = 0xFFFF0000; rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; } else { loadcs(0xFFFF); @@ -950,8 +964,8 @@ reset_common(int hard) if (hard) codegen_reset(); #endif - if (!hard) - flushmmucache(); + if (!hard) + flushmmucache(); x86_was_reset = 1; cpu_alt_reset = 0; @@ -959,6 +973,8 @@ reset_common(int hard) takeint = 0; cpu_ven_reset(); + + cpu_alu_op = 0; } @@ -1754,6 +1770,7 @@ execx86(int cycs) uint8_t temp = 0, temp2; uint16_t addr, tempw; uint16_t new_cs, new_ip; + uint32_t result; int bits; cycles += cycs; @@ -2736,17 +2753,25 @@ execx86(int cycs) case 0x28: /* IMUL */ wait(1, 0); if (opcode & 1) { + result = cpu_data; mul(AX, cpu_data); AX = cpu_data; DX = cpu_dest; cpu_data |= DX; - set_co_mul(DX != ((AX & 0x8000) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xffff)); + result = ((uint32_t) DX << 16) | AX; + if ((rmdat & 0x38) == 0x20) + set_co_mul(DX != 0x0000); + else + set_co_mul(result != sign_extend32(AX)); } else { mul(AL, cpu_data); AL = (uint8_t) cpu_data; AH = (uint8_t) cpu_dest; cpu_data |= AH; - set_co_mul(AH != ((AL & 0x80) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xff)); + if ((rmdat & 0x38) == 0x20) + set_co_mul(AH != 0x00); + else + set_co_mul(AX != sign_extend(AL)); } /* NOTE: When implementing the V20, care should be taken to not change the zero flag. */ @@ -2881,6 +2906,8 @@ execx86(int cycs) if (noint) noint = 0; + + cpu_alu_op = 0; } ins++; diff --git a/src/cpu_common.bak/codegen_public.h b/src/cpu_common.bak/codegen_public.h new file mode 100644 index 000000000..c1f16d893 --- /dev/null +++ b/src/cpu_common.bak/codegen_public.h @@ -0,0 +1,62 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the code generator. + * + * Version: @(#)codegen_public.h 1.0.0 2020/01/27 + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ +#ifndef _CODEGEN_PUBLIC_H_ +#define _CODEGEN_PUBLIC_H_ + +#ifndef USE_NEW_DYNAREC +#define PAGE_MASK_INDEX_MASK 3 +#define PAGE_MASK_INDEX_SHIFT 10 +#endif +#define PAGE_MASK_MASK 63 +#define PAGE_MASK_SHIFT 4 + +#ifdef USE_NEW_DYNAREC +#define BLOCK_PC_INVALID 0xffffffff +#define BLOCK_INVALID 0 +#endif + + +extern void codegen_init(); +#ifdef USE_NEW_DYNAREC +extern void codegen_close(); +#endif +extern void codegen_flush(); + + +/*Current physical page of block being recompiled. -1 if no recompilation taking place */ +extern uint32_t recomp_page; +extern int codegen_in_recompile; + +#endif diff --git a/src/cpu_new/cpu.c b/src/cpu_common.bak/cpu.c similarity index 97% rename from src/cpu_new/cpu.c rename to src/cpu_common.bak/cpu.c index 6b277275c..3ade0e879 100644 --- a/src/cpu_new/cpu.c +++ b/src/cpu_common.bak/cpu.c @@ -42,16 +42,16 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../device.h" -#include "../machine/machine.h" -#include "../io.h" +#include "device.h" +#include "machine.h" +#include "86box_io.h" #include "x86_ops.h" -#include "../mem.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pci.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "pci.h" #ifdef USE_DYNAREC # include "codegen.h" #endif @@ -75,11 +75,13 @@ enum { CPUID_FXSR = (1 << 24) }; +#ifdef USE_NEW_DYNAREC /*Addition flags returned by CPUID function 0x80000001*/ enum { CPUID_3DNOW = (1 << 31) }; +#endif #ifdef USE_DYNAREC @@ -103,8 +105,10 @@ 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; +#ifdef USE_NEW_DYNAREC const OpFn *x86_dynarec_opcodes_3DNOW; #endif +#endif const OpFn *x86_opcodes; const OpFn *x86_opcodes_0f; @@ -126,7 +130,9 @@ const OpFn *x86_opcodes_df_a16; const OpFn *x86_opcodes_df_a32; const OpFn *x86_opcodes_REPE; const OpFn *x86_opcodes_REPNE; +#ifdef USE_NEW_DYNAREC const OpFn *x86_opcodes_3DNOW; +#endif int in_smm = 0, smi_line = 0, smi_latched = 0; uint32_t smbase = 0x30000; @@ -195,13 +201,21 @@ uint64_t ecx1e0_msr = 0; uint64_t ecx570_msr = 0; #endif +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) uint64_t ecx83_msr = 0; /* AMD K5 and K6 MSR's. */ +#ifdef USE_NEW_DYNAREC uint64_t star = 0; /* AMD K6-2+. */ +#endif -uint64_t amd_efer = 0, amd_whcr = 0, /* AMD K6-2+ registers. */ - amd_uwccr = 0, amd_epmr = 0, +#ifdef USE_NEW_DYNAREC +uint64_t amd_efer = 0, amd_whcr = 0, + amd_uwccr = 0, amd_epmr = 0, /* AMD K6-2+ registers. */ amd_psor = 0, amd_pfir = 0, amd_l2aar = 0; +#else +uint64_t amd_efer = 0, amd_whcr = 0; +#endif +#endif int timing_rr; int timing_mr, timing_mrl; @@ -257,7 +271,7 @@ cpu_set(void) cpu_manufacturer = 0; cpu = 0; } - + cpu_effective = cpu; cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective]; @@ -272,8 +286,14 @@ cpu_set(void) is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL ); is_pentium = (cpu_s->cpu_type >= CPU_WINCHIP); hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD); +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); +#else + cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86); +#endif + cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC ); + if (cpu_s->multi) { cpu_busspeed = cpu_s->rspeed / cpu_s->multi; } @@ -315,7 +335,7 @@ cpu_set(void) io_sethandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); else io_removehandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - + #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); #else @@ -323,12 +343,16 @@ cpu_set(void) #endif x86_opcodes_REPE = ops_REPE; x86_opcodes_REPNE = ops_REPNE; +#ifdef USE_NEW_DYNAREC x86_opcodes_3DNOW = ops_3DNOW; +#endif #ifdef USE_DYNAREC x86_dynarec_opcodes_REPE = dynarec_ops_REPE; x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; +#ifdef USE_NEW_DYNAREC x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; #endif +#endif #ifdef USE_DYNAREC if (hasfpu) @@ -490,7 +514,7 @@ cpu_set(void) timing_jmp_pm = 23; timing_jmp_pm_gate = 38; break; - + case CPU_IBM386SLC: case CPU_386SX: timing_rr = 2; /*register dest - register src*/ @@ -553,7 +577,7 @@ cpu_set(void) timing_jmp_pm = 27; timing_jmp_pm_gate = 45; break; - + case CPU_IBM486SLC: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); @@ -590,6 +614,7 @@ cpu_set(void) timing_jmp_pm_gate = 32; timing_misaligned = 3; break; + case CPU_IBM486BL: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); @@ -941,6 +966,7 @@ cpu_set(void) cpu_cyrix_alignment = 1; break; +#ifdef USE_NEW_DYNAREC case CPU_WINCHIP2: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); @@ -982,6 +1008,7 @@ cpu_set(void) cpu_cyrix_alignment = 1; codegen_timing_set(&codegen_timing_winchip2); break; +#endif case CPU_PENTIUM: #ifdef USE_DYNAREC @@ -1069,6 +1096,7 @@ cpu_set(void) #endif break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); @@ -1237,13 +1265,15 @@ cpu_set(void) #endif ccr4 = 0x80; break; +#endif +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); #else - x86_setopcodes(ops_386, ops_k6_0f); + x86_setopcodes(ops_386, ops_pentiummmx_0f); #endif timing_rr = 1; /*register dest - register src*/ timing_rm = 2; /*register dest - memory src*/ @@ -1277,7 +1307,7 @@ cpu_set(void) cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC +#if defined(USE_NEW_DYNAREC) && defined(USE_DYNAREC) codegen_timing_set(&codegen_timing_k6); #endif break; @@ -1321,10 +1351,16 @@ cpu_set(void) msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC codegen_timing_set(&codegen_timing_k6); +#else + codegen_timing_set(&codegen_timing_pentium); +#endif #endif break; +#endif +#ifdef USE_NEW_DYNAREC case CPU_K6_2: case CPU_K6_2C: case CPU_K6_3: @@ -1369,6 +1405,7 @@ cpu_set(void) cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; codegen_timing_set(&codegen_timing_k6); break; +#endif #if defined(DEV_BRANCH) && defined(USE_I686) case CPU_PENTIUMPRO: @@ -1422,7 +1459,11 @@ cpu_set(void) msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC codegen_timing_set(&codegen_timing_k6); +#else + codegen_timing_set(&codegen_timing_686); +#endif #endif break; @@ -1478,7 +1519,11 @@ cpu_set(void) msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC codegen_timing_set(&codegen_timing_k6); +#else + codegen_timing_set(&codegen_timing_686); +#endif #endif break; #endif @@ -1534,7 +1579,11 @@ cpu_set(void) msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE | CR4_OSFXSR; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC codegen_timing_set(&codegen_timing_k6); +#else + codegen_timing_set(&codegen_timing_686); +#endif #endif break; #endif @@ -1667,6 +1716,7 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; +#ifdef USE_NEW_DYNAREC case CPU_WINCHIP2: switch (EAX) { @@ -1726,6 +1776,7 @@ cpu_CPUID(void) break; } break; +#endif case CPU_PENTIUM: if (!EAX) @@ -1745,6 +1796,7 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: if (!EAX) { @@ -1876,7 +1928,9 @@ cpu_CPUID(void) else EAX = EBX = ECX = EDX = 0; break; +#endif +#ifdef USE_NEW_DYNAREC case CPU_K6_2: case CPU_K6_2C: switch (EAX) @@ -2037,6 +2091,7 @@ cpu_CPUID(void) break; } break; +#endif case CPU_PENTIUMMMX: if (!EAX) @@ -2057,6 +2112,7 @@ cpu_CPUID(void) break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: if (!EAX) { @@ -2132,6 +2188,7 @@ cpu_CPUID(void) else EAX = EBX = ECX = EDX = 0; break; +#endif #ifdef DEV_BRANCH #ifdef USE_I686 @@ -2211,6 +2268,7 @@ cpu_CPUID(void) void cpu_ven_reset(void) { +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_K5: @@ -2222,6 +2280,7 @@ void cpu_ven_reset(void) amd_efer = amd_whcr = 0ULL; star = 0ULL; break; +#ifdef USE_NEW_DYNAREC case CPU_K6_2C: amd_efer = 2ULL; amd_whcr = star = 0ULL; @@ -2244,7 +2303,9 @@ void cpu_ven_reset(void) amd_pfir = amd_l2aar = 0ULL; amd_epmr = 0ULL; break; +#endif } +#endif } void cpu_RDMSR() @@ -2252,7 +2313,9 @@ void cpu_RDMSR() switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_WINCHIP: +#ifdef USE_NEW_DYNAREC case CPU_WINCHIP2: +#endif EAX = EDX = 0; switch (ECX) { @@ -2282,6 +2345,7 @@ void cpu_RDMSR() } break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: case CPU_K6: @@ -2312,7 +2376,9 @@ void cpu_RDMSR() break; } break; +#endif +#ifdef USE_NEW_DYNAREC case CPU_K6_2: EAX = EDX = 0; switch (ECX) @@ -2493,6 +2559,7 @@ void cpu_RDMSR() break; } break; +#endif case CPU_PENTIUM: case CPU_PENTIUMMMX: @@ -2505,6 +2572,7 @@ void cpu_RDMSR() break; } break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: @@ -2517,6 +2585,7 @@ void cpu_RDMSR() break; } break; +#endif #ifdef DEV_BRANCH #ifdef USE_I686 @@ -2649,12 +2718,16 @@ i686_invalid_rdmsr: void cpu_WRMSR() { +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) uint64_t temp; +#endif switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_WINCHIP: +#ifdef USE_NEW_DYNAREC case CPU_WINCHIP2: +#endif switch (ECX) { case 0x02: @@ -2679,10 +2752,12 @@ void cpu_WRMSR() cpu_features |= CPU_FEATURE_CX8; else cpu_features &= ~CPU_FEATURE_CX8; +#ifdef USE_NEW_DYNAREC if ((EAX & (1 << 20)) && machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_WINCHIP2) cpu_features |= CPU_FEATURE_3DNOW; else cpu_features &= ~CPU_FEATURE_3DNOW; +#endif if (EAX & (1 << 29)) CPUID = 0; else @@ -2697,6 +2772,7 @@ void cpu_WRMSR() } break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: case CPU_K6: @@ -2726,7 +2802,9 @@ void cpu_WRMSR() break; } break; +#endif +#ifdef USE_NEW_DYNAREC case CPU_K6_2: switch (ECX) { @@ -2887,6 +2965,7 @@ void cpu_WRMSR() break; } break; +#endif case CPU_PENTIUM: case CPU_PENTIUMMMX: @@ -2897,6 +2976,7 @@ void cpu_WRMSR() break; } break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: @@ -2908,6 +2988,7 @@ void cpu_WRMSR() break; } break; +#endif #ifdef DEV_BRANCH #ifdef USE_I686 @@ -3040,6 +3121,7 @@ static void cpu_write(uint16_t addr, uint8_t val, void *priv) if ((ccr3 & 0xf0) == 0x10) { ccr4 = val; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_Cx6x86) { if (val & 0x80) @@ -3047,6 +3129,7 @@ static void cpu_write(uint16_t addr, uint8_t val, void *priv) else CPUID = 0; } +#endif } break; case 0xe9: /*CCR5*/ diff --git a/src/cpu/cpu.h b/src/cpu_common.bak/cpu.h similarity index 80% rename from src/cpu/cpu.h rename to src/cpu_common.bak/cpu.h index 12a50473b..38086347a 100644 --- a/src/cpu/cpu.h +++ b/src/cpu_common.bak/cpu.h @@ -18,63 +18,72 @@ * Copyright 2016-2018 leilei. * Copyright 2016,2018 Miran Grca. */ -#ifdef USE_NEW_DYNAREC -#include "../cpu_new/cpu.h" -#else - #ifndef EMU_CPU_H # define EMU_CPU_H +enum { + CPU_8088, /* 808x class CPUs */ + CPU_8086, +#ifdef USE_NEC_808X + CPU_V20, /* NEC 808x class CPUs - future proofing */ + CPU_V30, +#endif + CPU_286, /* 286 class CPUs */ + CPU_386SX, /* 386 class CPUs */ + CPU_386DX, + CPU_IBM386SLC, + CPU_IBM486SLC, + CPU_IBM486BL, + CPU_RAPIDCAD, + CPU_486SLC, + CPU_486DLC, + CPU_i486SX, /* 486 class CPUs */ + CPU_Am486SX, + CPU_Cx486S, + CPU_i486DX, + CPU_Am486DX, + CPU_Cx486DX, + CPU_iDX4, + CPU_Cx5x86, + CPU_WINCHIP, /* 586 class CPUs */ +#ifdef USE_NEW_DYNAREC + CPU_WINCHIP2, +#endif + CPU_PENTIUM, + CPU_PENTIUMMMX, +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) + CPU_Cx6x86, + CPU_Cx6x86MX, + CPU_Cx6x86L, + CPU_CxGX1, +#endif +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))) + CPU_K5, + CPU_5K86, + CPU_K6, +#endif +#ifdef USE_NEW_DYNAREC + CPU_K6_2, + CPU_K6_2C, + CPU_K6_3, + CPU_K6_2P, + CPU_K6_3P, +#endif +#if defined(DEV_BRANCH) && defined(USE_I686) + CPU_PENTIUMPRO, /* 686 class CPUs */ +#ifdef USE_PENTIUM2 + CPU_PENTIUM2, +#endif + CPU_PENTIUM2D, +#endif + CPU_MAX /* Only really needed to close the enum in a way independent of the #ifdef's. */ +}; -#define CPU_8088 0 /* 808x class CPUs */ -#define CPU_8086 1 -#define CPU_286 2 /* 286 class CPUs */ -#define CPU_386SX 3 /* 386 class CPUs */ -#define CPU_386DX 4 -#define CPU_IBM386SLC 5 -#define CPU_IBM486SLC 6 -#define CPU_IBM486BL 7 -#define CPU_RAPIDCAD 8 -#define CPU_486SLC 9 -#define CPU_486DLC 10 -#define CPU_i486SX 11 /* 486 class CPUs */ -#define CPU_Am486SX 12 -#define CPU_Cx486S 13 -#define CPU_i486DX 14 -#define CPU_Am486DX 15 -#define CPU_Cx486DX 16 -#define CPU_iDX4 17 -#define CPU_Cx5x86 18 -#define CPU_WINCHIP 19 /* 586 class CPUs */ -#define CPU_PENTIUM 20 -#define CPU_PENTIUMMMX 21 -#define CPU_Cx6x86 22 -#define CPU_Cx6x86MX 23 -#define CPU_Cx6x86L 24 -#define CPU_CxGX1 25 -#ifdef DEV_BRANCH -#ifdef USE_AMD_K -#define CPU_K5 26 -#define CPU_5K86 27 -#define CPU_K6 28 -#endif -#endif -#ifdef DEV_BRANCH -#ifdef USE_I686 -#define CPU_PENTIUMPRO 29 /* 686 class CPUs */ -#if 0 -# define CPU_PENTIUM2 30 -# define CPU_PENTIUM2D 31 -#else -# define CPU_PENTIUM2D 30 -#endif -#endif -#endif - #define MANU_INTEL 0 #define MANU_AMD 1 #define MANU_CYRIX 2 #define MANU_IDT 3 +#define MANU_NEC 4 #define CPU_SUPPORTS_DYNAREC 1 #define CPU_REQUIRES_DYNAREC 2 @@ -96,6 +105,7 @@ typedef struct { int8_t atclk_div; } CPU; + extern CPU cpus_8088[]; extern CPU cpus_8086[]; extern CPU cpus_286[]; @@ -115,30 +125,33 @@ extern CPU cpus_i486[]; extern CPU cpus_Am486[]; extern CPU cpus_Cx486[]; extern CPU cpus_WinChip[]; +#ifdef USE_NEW_DYNAREC +extern CPU cpus_WinChip_SS7[]; +#endif extern CPU cpus_Pentium5V[]; extern CPU cpus_Pentium5V50[]; extern CPU cpus_PentiumS5[]; extern CPU cpus_Pentium3V[]; extern CPU cpus_Pentium[]; -#ifdef DEV_BRANCH -#ifdef USE_AMD_K +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))) extern CPU cpus_K5[]; extern CPU cpus_K56[]; #endif +#ifdef USE_NEW_DYNAREC +extern CPU cpus_K56_SS7[]; #endif -#ifdef DEV_BRANCH -#ifdef USE_CYRIX_6X86 +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) extern CPU cpus_6x863V[]; extern CPU cpus_6x86[]; #endif +#ifdef USE_NEW_DYNAREC +extern CPU cpus_6x86SS7[]; #endif -#ifdef DEV_BRANCH -#ifdef USE_I686 +#if defined(DEV_BRANCH) && defined(USE_I686) extern CPU cpus_PentiumPro[]; extern CPU cpus_Pentium2[]; extern CPU cpus_Pentium2D[]; #endif -#endif #define C_FLAG 0x0001 @@ -196,6 +209,9 @@ typedef union { int16_t sw[4]; uint8_t b[8]; int8_t sb[8]; +#ifdef USE_NEW_DYNAREC + float f[2]; +#endif } MMX_REG; typedef struct { @@ -259,6 +275,16 @@ struct _cpustate_ { new_npxc; uint32_t last_ea; +#ifdef USE_NEW_DYNAREC + uint32_t old_fp_control, new_fp_control; +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ + uint16_t old_fp_control2, new_fp_control2; +#endif +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ + uint32_t trunc_fp_control; +#endif +#endif + x86seg seg_cs, seg_ds, seg_es, @@ -279,9 +305,15 @@ struct _cpustate_ { /*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status. Otherwise they are ignored*/ +#ifdef USE_NEW_DYNAREC +#define CPU_STATUS_NOTFLATDS (1 << 8) +#define CPU_STATUS_NOTFLATSS (1 << 9) +#define CPU_STATUS_MASK 0xff00 +#else #define CPU_STATUS_NOTFLATDS (1 << 16) #define CPU_STATUS_NOTFLATSS (1 << 17) #define CPU_STATUS_MASK 0xffff0000 +#endif #ifdef __MSC__ # define COMPILE_TIME_ASSERT(expr) /*nada*/ @@ -355,12 +387,16 @@ extern int hasfpu; #define CPU_FEATURE_CX8 (1 << 5) #define CPU_FEATURE_3DNOW (1 << 6) -extern uint32_t cpu_features; +extern uint32_t cpu_features; -extern int in_smm, smi_line, smi_latched; -extern uint32_t smbase; +extern int in_smm, smi_line, smi_latched; +extern uint32_t smbase; +#ifdef USE_NEW_DYNAREC +extern uint16_t cpu_cur_status; +#else extern uint32_t cpu_cur_status; +#endif extern uint64_t cpu_CR4_mask; extern uint64_t tsc; extern msr_t msr; @@ -455,8 +491,14 @@ extern CPU cpus_acer[]; // FIXME: should be in machine file! /* Functions. */ extern int cpu_has_feature(int feature); +#ifdef USE_NEW_DYNAREC +extern void loadseg_dynarec(uint16_t seg, x86seg *s); +extern int loadseg(uint16_t seg, x86seg *s); +extern void loadcs(uint16_t seg); +#else extern void loadseg(uint16_t seg, x86seg *s); extern void loadcs(uint16_t seg); +#endif extern char *cpu_current_pc(char *bufp); @@ -473,16 +515,24 @@ extern void codegen_reset(void); extern void cpu_set_edx(void); extern int divl(uint32_t val); extern void execx86(int cycs); -extern void enter_smm(); -extern void leave_smm(); +extern void enter_smm(); +extern void leave_smm(); extern void exec386(int cycs); extern void exec386_dynarec(int cycs); extern int idivl(int32_t val); +#ifdef USE_NEW_DYNAREC +extern void loadcscall(uint16_t seg, uint32_t old_pc); +extern void loadcsjmp(uint16_t seg, uint32_t old_pc); +extern void pmodeint(int num, int soft); +extern void pmoderetf(int is32, uint16_t off); +extern void pmodeiret(int is32); +#else extern void loadcscall(uint16_t seg); extern void loadcsjmp(uint16_t seg, uint32_t old_pc); extern void pmodeint(int num, int soft); extern void pmoderetf(int is32, uint16_t off); extern void pmodeiret(int is32); +#endif extern void resetmcr(void); extern void resetx86(void); extern void refreshread(void); @@ -509,4 +559,3 @@ extern void cpu_ven_reset(void); #endif /*EMU_CPU_H*/ -#endif diff --git a/src/cpu_new/cpu_table.c b/src/cpu_common.bak/cpu_table.c similarity index 98% rename from src/cpu_new/cpu_table.c rename to src/cpu_common.bak/cpu_table.c index 34767b870..1e7a3ffba 100644 --- a/src/cpu_new/cpu_table.c +++ b/src/cpu_common.bak/cpu_table.c @@ -45,9 +45,9 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../machine/machine.h" +#include "machine.h" CPU cpus_8088[] = { @@ -55,10 +55,10 @@ CPU cpus_8088[] = { {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8088/8", CPU_8088, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/16", CPU_8088, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} + {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/16", CPU_8088, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; CPU cpus_pcjr[] = { @@ -153,7 +153,6 @@ CPU cpus_i386DX[] = { {"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, {"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, {"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"i486DX/33", CPU_i486DX, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; @@ -226,6 +225,7 @@ CPU cpus_486DLC[] = { {"Cx486DRx2/66", CPU_486DLC, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 8}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} }; + CPU cpus_i486S1[] = { /*i486*/ {"i486SX/16", CPU_i486SX, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2}, @@ -249,7 +249,7 @@ CPU cpus_Am486S1[] = { {"Am486SX/33", CPU_Am486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, {"Am486SX/40", CPU_Am486SX, 40000000, 1, 40000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, {"Am486SX2/50", CPU_Am486SX, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ - {"Am486SX2/66", CPU_Am486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486SX2/66", CPU_Am486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ {"Am486DX/33", CPU_Am486DX, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, {"Am486DX/40", CPU_Am486DX, 40000000, 1, 40000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, {"Am486DX2/50", CPU_Am486DX, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, @@ -284,8 +284,8 @@ CPU cpus_i486[] = { {"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, /*CPUID available on DX2, DX4, P24T, >= 40 MHz*/ {"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, {"i486DX2/66", CPU_i486DX, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, - {"iDX4/75", CPU_iDX4, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, - {"iDX4/100", CPU_iDX4, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, + {"iDX4/75", CPU_iDX4, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/ + {"iDX4/100", CPU_iDX4, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 25000000, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 33333333, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, {"Pentium OverDrive 63", CPU_PENTIUM, 62500000, 5/2, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, @@ -328,13 +328,14 @@ CPU cpus_Cx486[] = { {"Cx486DX4/100", CPU_Cx486DX, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, /*Cyrix 5x86*/ - {"Cx5x86/80", CPU_Cx5x86, 80000000, 2, 40000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"Cx5x86/80", CPU_Cx5x86, 80000000, 2, 40000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, /*If we're including the Pentium 50, might as well include this*/ {"Cx5x86/100", CPU_Cx5x86, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, {"Cx5x86/120", CPU_Cx5x86, 120000000, 3, 40000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15}, {"Cx5x86/133", CPU_Cx5x86, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) CPU cpus_6x863V[] = { /*Cyrix 6x86*/ {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, @@ -370,7 +371,9 @@ CPU cpus_6x86[] = { {"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 41666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#endif +#ifdef USE_NEW_DYNAREC CPU cpus_6x86SS7[] = { /*Cyrix 6x86*/ {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, @@ -398,6 +401,7 @@ CPU cpus_6x86[] = { {"MII/PR433", CPU_Cx6x86MX, 300000000, 3, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#endif CPU cpus_WinChip[] = { /*IDT WinChip*/ @@ -412,15 +416,18 @@ CPU cpus_WinChip[] = { {"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, {"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, {"WinChip 240", CPU_WINCHIP, 240000000, 4, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, +#ifdef USE_NEW_DYNAREC {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, (7*8)/2}, +#endif {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#ifdef USE_NEW_DYNAREC CPU cpus_WinChip_SS7[] = { /*IDT WinChip*/ {"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, @@ -444,6 +451,7 @@ CPU cpus_WinChip_SS7[] = { {"WinChip 2A/300", CPU_WINCHIP2, 250000000, 5/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 8, 8, 30}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#endif CPU cpus_Pentium5V[] = { /*Intel Pentium (5V, socket 4)*/ @@ -528,6 +536,8 @@ CPU cpus_Pentium[] = { {"Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, {"Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, {"Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + + /*Mobile Pentium*/ {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 150000000, 5/2, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, @@ -548,6 +558,8 @@ CPU cpus_Pentium[] = { {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) CPU cpus_K5[] = { /*AMD K5 (Socket 5)*/ {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, @@ -586,13 +598,17 @@ CPU cpus_K56[] = { {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, +#ifdef USE_NEW_DYNAREC {"K6-2/233", CPU_K6_2, 233333333, 7/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, {"K6-2/266", CPU_K6_2, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, {"K6-2/300 AFR-66", CPU_K6_2, 300000000, 9/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, {"K6-2/366", CPU_K6_2, 366666666, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33, 17, 17, 44}, +#endif {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#endif +#ifdef USE_NEW_DYNAREC CPU cpus_K56_SS7[] = { /*AMD K5 (Socket 7)*/ {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, @@ -645,6 +661,7 @@ CPU cpus_K56_SS7[] = { {"K6-III+/500", CPU_K6_3P, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#endif #ifdef DEV_BRANCH #ifdef USE_I686 diff --git a/src/cpu_new/x86.h b/src/cpu_common.bak/x86.h similarity index 100% rename from src/cpu_new/x86.h rename to src/cpu_common.bak/x86.h diff --git a/src/cpu/x86_ops.h b/src/cpu_common.bak/x86_ops.h similarity index 90% rename from src/cpu/x86_ops.h rename to src/cpu_common.bak/x86_ops.h index 2c4a2f3e5..652bdd29f 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu_common.bak/x86_ops.h @@ -70,6 +70,9 @@ extern const OpFn *x86_dynarec_opcodes_df_a16; extern const OpFn *x86_dynarec_opcodes_df_a32; extern const OpFn *x86_dynarec_opcodes_REPE; extern const OpFn *x86_dynarec_opcodes_REPNE; +#ifdef USE_NEW_DYNAREC +extern const OpFn *x86_dynarec_opcodes_3DNOW; +#endif extern const OpFn dynarec_ops_286[1024]; extern const OpFn dynarec_ops_286_0f[1024]; @@ -80,13 +83,22 @@ extern const OpFn dynarec_ops_386_0f[1024]; extern const OpFn dynarec_ops_486_0f[1024]; extern const OpFn dynarec_ops_winchip_0f[1024]; +#ifdef USE_NEW_DYNAREC +extern const OpFn dynarec_ops_winchip2_0f[1024]; +#endif extern const OpFn dynarec_ops_pentium_0f[1024]; extern const OpFn dynarec_ops_pentiummmx_0f[1024]; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) extern const OpFn dynarec_ops_c6x86mx_0f[1024]; #endif +#ifdef USE_NEW_DYNAREC +extern const OpFn dynarec_ops_k6_0f[1024]; +extern const OpFn dynarec_ops_k62_0f[1024]; +#endif + #if defined(DEV_BRANCH) && defined(USE_I686) extern const OpFn dynarec_ops_pentiumpro_0f[1024]; extern const OpFn dynarec_ops_pentium2d_0f[1024]; @@ -135,6 +147,9 @@ extern const OpFn dynarec_ops_fpu_686_df_a32[256]; extern const OpFn dynarec_ops_REPE[1024]; extern const OpFn dynarec_ops_REPNE[1024]; +#ifdef USE_NEW_DYNAREC +extern const OpFn dynarec_ops_3DNOW[256]; +#endif #else void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f); #endif @@ -159,6 +174,9 @@ extern const OpFn *x86_opcodes_df_a16; extern const OpFn *x86_opcodes_df_a32; extern const OpFn *x86_opcodes_REPE; extern const OpFn *x86_opcodes_REPNE; +#ifdef USE_NEW_DYNAREC +extern const OpFn *x86_opcodes_3DNOW; +#endif extern const OpFn ops_286[1024]; extern const OpFn ops_286_0f[1024]; @@ -169,14 +187,22 @@ extern const OpFn ops_386_0f[1024]; extern const OpFn ops_486_0f[1024]; extern const OpFn ops_winchip_0f[1024]; +#ifdef USE_NEW_DYNAREC +extern const OpFn ops_winchip2_0f[1024]; +#endif extern const OpFn ops_pentium_0f[1024]; extern const OpFn ops_pentiummmx_0f[1024]; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) extern const OpFn ops_c6x86mx_0f[1024]; #endif +#ifdef USE_NEW_DYNAREC +extern const OpFn ops_k6_0f[1024]; +extern const OpFn ops_k62_0f[1024]; +#endif + #if defined(DEV_BRANCH) && defined(USE_I686) extern const OpFn ops_pentiumpro_0f[1024]; extern const OpFn ops_pentium2d_0f[1024]; @@ -225,5 +251,13 @@ extern const OpFn ops_fpu_686_df_a32[256]; extern const OpFn ops_REPE[1024]; extern const OpFn ops_REPNE[1024]; +#ifdef USE_NEW_DYNAREC +extern const OpFn ops_3DNOW[256]; +#endif + +#define C0 (1<<8) +#define C1 (1<<9) +#define C2 (1<<10) +#define C3 (1<<14) #endif /*_X86_OPS_H*/ diff --git a/src/cpu_new/x86_ops_3dnow.h b/src/cpu_common.bak/x86_ops_3dnow.h similarity index 100% rename from src/cpu_new/x86_ops_3dnow.h rename to src/cpu_common.bak/x86_ops_3dnow.h diff --git a/src/cpu_new/x86_ops_amd.h b/src/cpu_common.bak/x86_ops_amd.h similarity index 100% rename from src/cpu_new/x86_ops_amd.h rename to src/cpu_common.bak/x86_ops_amd.h diff --git a/src/cpu_new/x86_ops_arith.h b/src/cpu_common.bak/x86_ops_arith.h similarity index 100% rename from src/cpu_new/x86_ops_arith.h rename to src/cpu_common.bak/x86_ops_arith.h diff --git a/src/cpu_new/x86_ops_atomic.h b/src/cpu_common.bak/x86_ops_atomic.h similarity index 100% rename from src/cpu_new/x86_ops_atomic.h rename to src/cpu_common.bak/x86_ops_atomic.h diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu_common.bak/x86_ops_bcd.h similarity index 100% rename from src/cpu/x86_ops_bcd.h rename to src/cpu_common.bak/x86_ops_bcd.h diff --git a/src/cpu_new/x86_ops_bit.h b/src/cpu_common.bak/x86_ops_bit.h similarity index 100% rename from src/cpu_new/x86_ops_bit.h rename to src/cpu_common.bak/x86_ops_bit.h diff --git a/src/cpu/x86_ops_bitscan.h b/src/cpu_common.bak/x86_ops_bitscan.h similarity index 100% rename from src/cpu/x86_ops_bitscan.h rename to src/cpu_common.bak/x86_ops_bitscan.h diff --git a/src/cpu_new/x86_ops_flag.h b/src/cpu_common.bak/x86_ops_flag.h similarity index 100% rename from src/cpu_new/x86_ops_flag.h rename to src/cpu_common.bak/x86_ops_flag.h diff --git a/src/cpu/x86_ops_fpu.h b/src/cpu_common.bak/x86_ops_fpu.h similarity index 100% rename from src/cpu/x86_ops_fpu.h rename to src/cpu_common.bak/x86_ops_fpu.h diff --git a/src/cpu_new/x86_ops_i686.h b/src/cpu_common.bak/x86_ops_i686.h similarity index 98% rename from src/cpu_new/x86_ops_i686.h rename to src/cpu_common.bak/x86_ops_i686.h index b4c1ed7ff..2b34e0822 100644 --- a/src/cpu_new/x86_ops_i686.h +++ b/src/cpu_common.bak/x86_ops_i686.h @@ -8,10 +8,10 @@ * * x86 i686 (Pentium Pro/Pentium II) CPU Instructions. * - * Version: @(#)x86_ops_i686.h 1.0.5 2018/10/17 + * Version: @(#)x86_ops_i686.h 1.0.6 2020/01/27 * * Author: Miran Grca, - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2020 Miran Grca. */ /* 0 = Limit 0-15 @@ -190,10 +190,14 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) { /* FXRSTOR */ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif fpus = readmemw(easeg, cpu_state.eaaddr + 2); cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.TOP = (fpus >> 11) & 7; cpu_state.npxs &= fpus & ~0x3800; @@ -316,7 +320,9 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) cpu_state.eaaddr = old_eaaddr; cpu_state.npxc = 0x37F; +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; @@ -371,10 +377,14 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) { /* FXRSTOR */ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif fpus = readmemw(easeg, cpu_state.eaaddr + 2); cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.TOP = (fpus >> 11) & 7; cpu_state.npxs &= fpus & ~0x3800; @@ -497,7 +507,9 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) cpu_state.eaaddr = old_eaaddr; cpu_state.npxc = 0x37F; +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; diff --git a/src/cpu/x86_ops_inc_dec.h b/src/cpu_common.bak/x86_ops_inc_dec.h similarity index 100% rename from src/cpu/x86_ops_inc_dec.h rename to src/cpu_common.bak/x86_ops_inc_dec.h diff --git a/src/cpu/x86_ops_int.h b/src/cpu_common.bak/x86_ops_int.h similarity index 100% rename from src/cpu/x86_ops_int.h rename to src/cpu_common.bak/x86_ops_int.h diff --git a/src/cpu/x86_ops_io.h b/src/cpu_common.bak/x86_ops_io.h similarity index 100% rename from src/cpu/x86_ops_io.h rename to src/cpu_common.bak/x86_ops_io.h diff --git a/src/cpu_new/x86_ops_jump.h b/src/cpu_common.bak/x86_ops_jump.h similarity index 100% rename from src/cpu_new/x86_ops_jump.h rename to src/cpu_common.bak/x86_ops_jump.h diff --git a/src/cpu/x86_ops_misc.h b/src/cpu_common.bak/x86_ops_misc.h similarity index 100% rename from src/cpu/x86_ops_misc.h rename to src/cpu_common.bak/x86_ops_misc.h diff --git a/src/cpu_new/x86_ops_mmx.h b/src/cpu_common.bak/x86_ops_mmx.h similarity index 100% rename from src/cpu_new/x86_ops_mmx.h rename to src/cpu_common.bak/x86_ops_mmx.h diff --git a/src/cpu_new/x86_ops_mmx_arith.h b/src/cpu_common.bak/x86_ops_mmx_arith.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_arith.h rename to src/cpu_common.bak/x86_ops_mmx_arith.h diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu_common.bak/x86_ops_mmx_cmp.h similarity index 100% rename from src/cpu/x86_ops_mmx_cmp.h rename to src/cpu_common.bak/x86_ops_mmx_cmp.h diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu_common.bak/x86_ops_mmx_logic.h similarity index 100% rename from src/cpu/x86_ops_mmx_logic.h rename to src/cpu_common.bak/x86_ops_mmx_logic.h diff --git a/src/cpu_new/x86_ops_mmx_mov.h b/src/cpu_common.bak/x86_ops_mmx_mov.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_mov.h rename to src/cpu_common.bak/x86_ops_mmx_mov.h diff --git a/src/cpu_new/x86_ops_mmx_pack.h b/src/cpu_common.bak/x86_ops_mmx_pack.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_pack.h rename to src/cpu_common.bak/x86_ops_mmx_pack.h diff --git a/src/cpu_new/x86_ops_mmx_shift.h b/src/cpu_common.bak/x86_ops_mmx_shift.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_shift.h rename to src/cpu_common.bak/x86_ops_mmx_shift.h diff --git a/src/cpu_new/x86_ops_mov.h b/src/cpu_common.bak/x86_ops_mov.h similarity index 100% rename from src/cpu_new/x86_ops_mov.h rename to src/cpu_common.bak/x86_ops_mov.h diff --git a/src/cpu_new/x86_ops_mov_ctrl.h b/src/cpu_common.bak/x86_ops_mov_ctrl.h similarity index 100% rename from src/cpu_new/x86_ops_mov_ctrl.h rename to src/cpu_common.bak/x86_ops_mov_ctrl.h diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu_common.bak/x86_ops_mov_seg.h similarity index 100% rename from src/cpu/x86_ops_mov_seg.h rename to src/cpu_common.bak/x86_ops_mov_seg.h diff --git a/src/cpu/x86_ops_movx.h b/src/cpu_common.bak/x86_ops_movx.h similarity index 100% rename from src/cpu/x86_ops_movx.h rename to src/cpu_common.bak/x86_ops_movx.h diff --git a/src/cpu/x86_ops_msr.h b/src/cpu_common.bak/x86_ops_msr.h similarity index 100% rename from src/cpu/x86_ops_msr.h rename to src/cpu_common.bak/x86_ops_msr.h diff --git a/src/cpu/x86_ops_mul.h b/src/cpu_common.bak/x86_ops_mul.h similarity index 100% rename from src/cpu/x86_ops_mul.h rename to src/cpu_common.bak/x86_ops_mul.h diff --git a/src/cpu_new/x86_ops_pmode.h b/src/cpu_common.bak/x86_ops_pmode.h similarity index 100% rename from src/cpu_new/x86_ops_pmode.h rename to src/cpu_common.bak/x86_ops_pmode.h diff --git a/src/cpu/x86_ops_prefix.h b/src/cpu_common.bak/x86_ops_prefix.h similarity index 100% rename from src/cpu/x86_ops_prefix.h rename to src/cpu_common.bak/x86_ops_prefix.h diff --git a/src/cpu/x86_ops_rep.h b/src/cpu_common.bak/x86_ops_rep.h similarity index 100% rename from src/cpu/x86_ops_rep.h rename to src/cpu_common.bak/x86_ops_rep.h diff --git a/src/cpu/x86_ops_ret.h b/src/cpu_common.bak/x86_ops_ret.h similarity index 96% rename from src/cpu/x86_ops_ret.h rename to src/cpu_common.bak/x86_ops_ret.h index 75419e6d8..1ebe67b9c 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu_common.bak/x86_ops_ret.h @@ -1,10 +1,16 @@ +#ifdef USE_NEW_DYNAREC +#define CPU_SET_OXPC +#else +#define CPU_SET_OXPC oxpc = cpu_state.pc; +#endif + #define RETF_a16(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ { \ pmoderetf(0, stack_offset); \ return 1; \ } \ - oxpc = cpu_state.pc; \ + CPU_SET_OXPC \ if (stack32) \ { \ cpu_state.pc = readmemw(ss, ESP); \ @@ -15,18 +21,18 @@ cpu_state.pc = readmemw(ss, SP); \ loadcs(readmemw(ss, SP + 2)); \ } \ - if (cpu_state.abrt) return 1; \ + if (cpu_state.abrt) return 1; \ if (stack32) ESP += 4 + stack_offset; \ else SP += 4 + stack_offset; \ cycles -= timing_retf_rm; #define RETF_a32(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ { \ pmoderetf(1, stack_offset); \ return 1; \ } \ - oxpc = cpu_state.pc; \ + CPU_SET_OXPC \ if (stack32) \ { \ cpu_state.pc = readmeml(ss, ESP); \ @@ -108,7 +114,7 @@ static int opIRET_286(uint32_t fetchdat) else { uint16_t new_cs; - oxpc = cpu_state.pc; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmemw(ss, ESP); @@ -184,7 +190,7 @@ static int opIRET(uint32_t fetchdat) else { uint16_t new_cs; - oxpc = cpu_state.pc; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmemw(ss, ESP); @@ -230,7 +236,7 @@ static int opIRETD(uint32_t fetchdat) else { uint16_t new_cs; - oxpc = cpu_state.pc; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmeml(ss, ESP); diff --git a/src/cpu/x86_ops_set.h b/src/cpu_common.bak/x86_ops_set.h similarity index 100% rename from src/cpu/x86_ops_set.h rename to src/cpu_common.bak/x86_ops_set.h diff --git a/src/cpu_new/x86_ops_stack.h b/src/cpu_common.bak/x86_ops_stack.h similarity index 100% rename from src/cpu_new/x86_ops_stack.h rename to src/cpu_common.bak/x86_ops_stack.h diff --git a/src/cpu_new/x86_ops_string.h b/src/cpu_common.bak/x86_ops_string.h similarity index 100% rename from src/cpu_new/x86_ops_string.h rename to src/cpu_common.bak/x86_ops_string.h diff --git a/src/cpu_new/x86_ops_xchg.h b/src/cpu_common.bak/x86_ops_xchg.h similarity index 100% rename from src/cpu_new/x86_ops_xchg.h rename to src/cpu_common.bak/x86_ops_xchg.h diff --git a/src/cpu/x86seg.h b/src/cpu_common.bak/x86seg.h similarity index 100% rename from src/cpu/x86seg.h rename to src/cpu_common.bak/x86seg.h diff --git a/src/cpu_new/x87.c b/src/cpu_common.bak/x87.c similarity index 98% rename from src/cpu_new/x87.c rename to src/cpu_common.bak/x87.c index 7d27e29f3..367948656 100644 --- a/src/cpu_new/x87.c +++ b/src/cpu_common.bak/x87.c @@ -21,12 +21,12 @@ int fpu_do_log = ENABLE_FPU_LOG; -void +static void fpu_log(const char *fmt, ...) { va_list ap; - if (fpu_do_log) { + if (fpu_log) { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); diff --git a/src/cpu_new/x87.h b/src/cpu_common.bak/x87.h similarity index 100% rename from src/cpu_new/x87.h rename to src/cpu_common.bak/x87.h diff --git a/src/cpu_new/x87_ops.h b/src/cpu_common.bak/x87_ops.h similarity index 100% rename from src/cpu_new/x87_ops.h rename to src/cpu_common.bak/x87_ops.h diff --git a/src/cpu_new/x87_ops_arith.h b/src/cpu_common.bak/x87_ops_arith.h similarity index 100% rename from src/cpu_new/x87_ops_arith.h rename to src/cpu_common.bak/x87_ops_arith.h diff --git a/src/cpu_new/x87_ops_loadstore.h b/src/cpu_common.bak/x87_ops_loadstore.h similarity index 100% rename from src/cpu_new/x87_ops_loadstore.h rename to src/cpu_common.bak/x87_ops_loadstore.h diff --git a/src/cpu_new/x87_ops_misc.h b/src/cpu_common.bak/x87_ops_misc.h similarity index 100% rename from src/cpu_new/x87_ops_misc.h rename to src/cpu_common.bak/x87_ops_misc.h diff --git a/src/cpu_common/386.c b/src/cpu_common/386.c new file mode 100644 index 000000000..416f9577e --- /dev/null +++ b/src/cpu_common/386.c @@ -0,0 +1,335 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "x86.h" +#include "x87.h" +#include "nmi.h" +#include "mem.h" +#include "pic.h" +#include "pit.h" +#include "fdd.h" +#include "fdc.h" +#include "386_common.h" +#ifdef USE_NEW_DYNAREC +#include "codegen.h" +#endif + + +#undef CPU_BLOCK_END +#define CPU_BLOCK_END() + + +extern int codegen_flags_changed; + +int tempc, oldcpl, optype, inttype, oddeven = 0; +int timetolive; + +uint16_t oldcs; + +uint32_t oldds, oldss, olddslimit, oldsslimit, + olddslimitw, oldsslimitw; +uint32_t oxpc; +uint32_t rmdat32; +uint32_t backupregs[16]; + +x86seg _oldds; + + +#ifdef ENABLE_386_LOG +int x386_do_log = ENABLE_386_LOG; + + +void +x386_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_log(fmt, ...) +#endif + + +#undef CPU_BLOCK_END +#define CPU_BLOCK_END() + +static inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; +// pc++; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } +} + +static inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0 + +#include "x86_flags.h" + +#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ +#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 +#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ +#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 + + +#define OP_TABLE(name) ops_ ## name + +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "x86_ops.h" + +void +exec386(int cycs) +{ + // uint8_t opcode; + int vector, tempi, cycdiff, oldcyc; + int cycle_period, ins_cycles; + uint32_t addr; + + cycles += cycs; + + while (cycles > 0) { + cycle_period = (timer_target - (uint32_t)tsc) + 1; + + x86_was_reset = 0; + cycdiff = 0; + oldcyc = cycles; + while (cycdiff < cycle_period) { + ins_cycles = cycles; + +#ifndef USE_NEW_DYNAREC + oldcs=CS; + oldcpl=CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + +#ifndef USE_NEW_DYNAREC + x86_was_reset = 0; +#endif + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + if (cpu_state.abrt) { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + cpu_state.pc = cpu_state.oldpc; + x386_log("Double fault %i\n", ins); + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_LOG + x386_log("Triple fault - reset\n"); +#endif + } + } + } + + ins_cycles -= cycles; + tsc += ins_cycles; + + cycdiff = oldcyc - cycles; + + if (trap) { + flags_rebuild(); + if (msw&1) + pmodeint(1,0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } else if (nmi && nmi_enable && nmi_mask) { + cpu_state.oldpc = cpu_state.pc; + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } + } else if ((cpu_state.flags & I_FLAG) && pic_intpending) { + vector = picinterrupt(); + if (vector != -1) { + flags_rebuild(); + if (msw & 1) + pmodeint(vector, 0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (vector << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } + } + + ins++; + + if (timetolive) { + timetolive--; + if (!timetolive) + fatal("Life expired\n"); + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process(); + } + } +} diff --git a/src/cpu_common/386_common.c b/src/cpu_common/386_common.c new file mode 100644 index 000000000..cb140c41a --- /dev/null +++ b/src/cpu_common/386_common.c @@ -0,0 +1,309 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "x86.h" +#include "x87.h" +#include "nmi.h" +#include "mem.h" +#include "pic.h" +#include "pit.h" +#include "fdd.h" +#include "fdc.h" +#include "386_common.h" +#include "x86_flags.h" +#include "codegen.h" + +x86seg gdt, ldt, idt, tr; + +uint32_t cr2, cr3, cr4; +uint32_t dr[8]; + +uint32_t use32; +int stack32; +int optype; + +int trap; + +uint32_t rmdat; + +uint32_t *eal_r, *eal_w; + +int nmi_enable = 1; + +int cpl_override=0; + +int fpucount=0; + +#ifdef USE_NEW_DYNAREC +uint16_t cpu_cur_status = 0; +#else +uint32_t cpu_cur_status = 0; +#endif + +uint32_t pccache; +uint8_t *pccache2; + + +#ifdef ENABLE_386_COMMON_LOG +int x386_common_do_log = ENABLE_386_COMMON_LOG; + + +void +x386_common_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_common_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_common_log(fmt, ...) +#endif + + +void x86_int(int num) +{ + uint32_t addr; + flags_rebuild(); + cpu_state.pc=cpu_state.oldpc; + if (msw&1) + { + pmodeint(num,0); + } + else + { + addr = (num << 2) + idt.base; + + if ((num << 2) + 3 > idt.limit) + { + if (idt.limit < 35) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_COMMON_LOG + x386_log("Triple fault in real mode - reset\n"); +#endif + } + else + x86_int(8); + } + else + { + if (stack32) + { + writememw(ss,ESP-2,cpu_state.flags); + writememw(ss,ESP-4,CS); + writememw(ss,ESP-6,cpu_state.pc); + ESP-=6; + } + else + { + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); + SP-=6; + } + + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + cycles-=70; + CPU_BLOCK_END(); +} + +void x86_int_sw(int num) +{ + uint32_t addr; + flags_rebuild(); + cycles -= timing_int; + if (msw&1) + { + pmodeint(num,1); + } + else + { + addr = (num << 2) + idt.base; + + if ((num << 2) + 3 > idt.limit) + { + x86_int(13); + } + else + { + if (stack32) + { + writememw(ss,ESP-2,cpu_state.flags); + writememw(ss,ESP-4,CS); + writememw(ss,ESP-6,cpu_state.pc); + ESP-=6; + } + else + { + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); + SP-=6; + } + + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + cycles -= timing_int_rm; + } + } + trap = 0; + CPU_BLOCK_END(); +} + +int x86_int_sw_rm(int num) +{ + uint32_t addr; + uint16_t new_pc, new_cs; + + flags_rebuild(); + cycles -= timing_int; + + addr = num << 2; + new_pc = readmemw(0, addr); + new_cs = readmemw(0, addr + 2); + + if (cpu_state.abrt) return 1; + + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); + if (cpu_state.abrt) + return 1; + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); + if (cpu_state.abrt) + return 1; + SP-=6; + + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = new_pc; + loadcs(new_cs); +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + + cycles -= timing_int_rm; + trap = 0; + CPU_BLOCK_END(); + + return 0; +} + +void x86illegal() +{ + x86_int(6); +} + +int checkio(int port) +{ + uint16_t t; + uint8_t d; + cpl_override = 1; + t = readmemw(tr.base, 0x66); + cpl_override = 0; + if (cpu_state.abrt) return 0; + if ((t+(port>>3))>tr.limit) return 1; + cpl_override = 1; +#ifdef USE_NEW_DYNAREC + d = readmembl(tr.base + t + (port >> 3)); +#else + d = readmemb386l(0, tr.base + t + (port >> 3)); +#endif + cpl_override = 0; + return d&(1<<(port&7)); +} + +#define divexcp() { \ + x386_common_log("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \ + x86_int(0); \ +} + +int divl(uint32_t val) +{ + uint64_t num, quo; + uint32_t rem, quo32; + + if (val==0) + { + divexcp(); + return 1; + } + + num=(((uint64_t)EDX)<<32)|EAX; + quo=num/val; + rem=num%val; + quo32=(uint32_t)(quo&0xFFFFFFFF); + + if (quo!=(uint64_t)quo32) + { + divexcp(); + return 1; + } + EDX=rem; + EAX=quo32; + return 0; +} +int idivl(int32_t val) +{ + int64_t num, quo; + int32_t rem, quo32; + + if (val==0) + { + divexcp(); + return 1; + } + + num=(((uint64_t)EDX)<<32)|EAX; + quo=num/val; + rem=num%val; + quo32=(int32_t)(quo&0xFFFFFFFF); + + if (quo!=(int64_t)quo32) + { + divexcp(); + return 1; + } + EDX=rem; + EAX=quo32; + return 0; +} + + +void cpu_386_flags_extract() +{ + flags_extract(); +} +void cpu_386_flags_rebuild() +{ + flags_rebuild(); +} diff --git a/src/cpu/386_common.h b/src/cpu_common/386_common.h similarity index 77% rename from src/cpu/386_common.h rename to src/cpu_common/386_common.h index 428bf3118..2ab8157a2 100644 --- a/src/cpu/386_common.h +++ b/src/cpu_common/386_common.h @@ -16,6 +16,20 @@ * Copyright 2016-2019 Miran Grca. */ +#ifndef _386_COMMON_H_ +#define _386_COMMON_H_ + +#ifdef USE_NEW_DYNAREC +#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) ) +#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) + +#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#else #undef readmemb #undef writememb @@ -28,8 +42,24 @@ #define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl(s,a,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v #define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll(s,a,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v #define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql(s,a,v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#endif +int checkio(int port); + + +#ifdef USE_NEW_DYNAREC +#define check_io_perm(port) if (!IOPLp || (cpu_state.eflags&VM_FLAG)) \ + { \ + int tempi = checkio(port); \ + if (cpu_state.abrt) return 1; \ + if (tempi) \ + { \ + x86gpf("check_io_perm(): no permission",0); \ + return 1; \ + } \ + } +#else #define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (cpu_state.eflags&VM_FLAG))) \ { \ int tempi = checkio(port); \ @@ -40,6 +70,7 @@ return 1; \ } \ } +#endif #define SEG_CHECK_READ(seg) \ do \ @@ -205,7 +236,6 @@ static __inline uint32_t fastreadl(uint32_t a) return 0; pccache2 = t; pccache=a>>12; - /* return *((uint32_t *)&pccache2[a]); */ } return *((uint32_t *)&pccache2[a]); } @@ -309,19 +339,36 @@ static __inline void seteaq(uint64_t v) { if (seteaq_cwc()) return; +#ifdef USE_NEW_DYNAREC + writememql(easeg + cpu_state.eaaddr, v); +#else writememql(easeg, cpu_state.eaaddr, v); +#endif } +#ifdef USE_NEW_DYNAREC +#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v +#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v +#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v +#else #define seteab(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else { writememb386l(easeg,cpu_state.eaaddr,v); } } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v #define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else { writememwl(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].w=v #define seteal(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else { writememll(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].l=v +#endif - +#ifdef USE_NEW_DYNAREC +#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); +#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); +#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); +#else #define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,cpu_state.eaaddr,v); #define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,cpu_state.eaaddr,v); #define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg,cpu_state.eaaddr,v); - +#endif + #define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ #define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 #define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ #define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 + +#endif diff --git a/src/cpu_common/386_dynarec - Cópia (2).c b/src/cpu_common/386_dynarec - Cópia (2).c new file mode 100644 index 000000000..421381dd3 --- /dev/null +++ b/src/cpu_common/386_dynarec - Cópia (2).c @@ -0,0 +1,910 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + + cycdiff=0; + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { + oldcs=CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + + if (!use32) cpu_state.pc &= 0xffff; + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + +/* if (ssegs) + { + ds=oldds; + ss=oldss; + ssegs=0; + }*/ + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + +/* if ((cs + pc) == 4) + fatal("4\n");*/ +/* if (ins >= 141400000) + output = 3;*/ + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); + codeblock_t *block = codeblock_hash[hash]; + int valid_block = 0; + trap = 0; + + if (block && !cpu_state.abrt) + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + block = new_block; + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + } + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; + } + } + + if (valid_block && block->was_recompiled) + { + void (*code)() = (void *)&block->data[BLOCK_START]; + + codeblock_hash[hash] = block; + +inrecomp=1; + code(); +inrecomp=0; + if (!use32) cpu_state.pc &= 0xffff; + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { + oldcs=CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { + oldcs=CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + CS = oldcs; + cpu_state.pc = cpu_state.oldpc; +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Double fault %i\n", ins); +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); +#endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + if (trap) + { + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags&=~I_FLAG; + cpu_state.flags&=~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; + oldcs = CS; + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags&I_FLAG) && pic_intpending) + { + vector=picinterrupt(); + if (vector!=-1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags&=~I_FLAG; + cpu_state.flags&=~T_FLAG; + oxpc=cpu_state.pc; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + } + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu_common/386_dynarec - Cópia.c b/src/cpu_common/386_dynarec - Cópia.c new file mode 100644 index 000000000..75219e86a --- /dev/null +++ b/src/cpu_common/386_dynarec - Cópia.c @@ -0,0 +1,1008 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cycdiff=0; +#endif + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); +#ifdef USE_NEW_DYNAREC + codeblock_t *block = &codeblock[codeblock_hash[hash]]; +#else + codeblock_t *block = codeblock_hash[hash]; +#endif + int valid_block = 0; +#ifdef USE_NEW_DYNAREC + + if (!cpu_state.abrt) +#else + trap = 0; + + if (block && !cpu_state.abrt) +#endif + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + 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); + + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) +#else + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) +#endif + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + { + block = new_block; +#ifdef USE_NEW_DYNAREC + codeblock_hash[hash] = get_block_nr(block); +#endif + } + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { +#ifdef USE_NEW_DYNAREC + codegen_check_flush(page, page->dirty_mask, phys_addr); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +#else + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +#endif + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ +#ifdef USE_NEW_DYNAREC + uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); +#else + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); +#endif + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; +#ifdef USE_NEW_DYNAREC + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + } +#else + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } +#endif + } +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) + { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) +#else + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) +#endif + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ +#ifdef USE_NEW_DYNAREC + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); +#else + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; +#endif + } + } + +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) +#else + if (valid_block && block->was_recompiled) +#endif + { + void (*code)() = (void *)&block->data[BLOCK_START]; + +#ifndef USE_NEW_DYNAREC + codeblock_hash[hash] = block; +#endif + + inrecomp=1; + code(); + inrecomp=0; + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { +#ifdef USE_NEW_DYNAREC + start_pc = cs+cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#else + start_pc = cpu_state.pc; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + start_pc = cs+cpu_state.pc; +#ifdef USE_NEW_DYNAREC + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs=CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } +#ifdef USE_NEW_DYNAREC + else + cpu_state.oldpc = cpu_state.pc; +#endif + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); +#endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + else if (trap) + { +#ifdef USE_NEW_DYNAREC + trap = 0; +#endif + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags & I_FLAG) && pic_intpending) + { + vector = picinterrupt(); + if (vector != -1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu_common/386_dynarec.c b/src/cpu_common/386_dynarec.c new file mode 100644 index 000000000..b03f723c1 --- /dev/null +++ b/src/cpu_common/386_dynarec.c @@ -0,0 +1,1007 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cycdiff=0; +#endif + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); +#ifdef USE_NEW_DYNAREC + codeblock_t *block = &codeblock[codeblock_hash[hash]]; +#else + codeblock_t *block = codeblock_hash[hash]; +#endif + int valid_block = 0; +#ifdef USE_NEW_DYNAREC + + if (!cpu_state.abrt) +#else + trap = 0; + + if (block && !cpu_state.abrt) +#endif + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + 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); + + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) +#else + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) +#endif + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + { + block = new_block; +#ifdef USE_NEW_DYNAREC + codeblock_hash[hash] = get_block_nr(block); +#endif + } + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { +#ifdef USE_NEW_DYNAREC + codegen_check_flush(page, page->dirty_mask, phys_addr); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +#else + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +#endif + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ +#ifdef USE_NEW_DYNAREC + uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); +#else + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); +#endif + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; + else if (block->page_mask2 & *block->dirty_mask2) + { +#ifdef USE_NEW_DYNAREC + codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +#else + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +#endif + } + } +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) + { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) +#else + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) +#endif + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ +#ifdef USE_NEW_DYNAREC + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); +#else + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; +#endif + } + } + +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) +#else + if (valid_block && block->was_recompiled) +#endif + { + void (*code)() = (void *)&block->data[BLOCK_START]; + +#ifndef USE_NEW_DYNAREC + codeblock_hash[hash] = block; +#endif + + inrecomp=1; + code(); + inrecomp=0; + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { +#ifdef USE_NEW_DYNAREC + start_pc = cs+cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#else + start_pc = cpu_state.pc; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ +#ifdef USE_NEW_DYNAREC + start_pc = cs+cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#else + start_pc = cpu_state.pc; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs=CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } +#ifdef USE_NEW_DYNAREC + else + cpu_state.oldpc = cpu_state.pc; +#endif + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); +#endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + else if (trap) + { +#ifdef USE_NEW_DYNAREC + trap = 0; +#endif + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags & I_FLAG) && pic_intpending) + { + vector = picinterrupt(); + if (vector != -1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + } + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu_common/386_dynarec.c.temp b/src/cpu_common/386_dynarec.c.temp new file mode 100644 index 000000000..78130f3c0 --- /dev/null +++ b/src/cpu_common/386_dynarec.c.temp @@ -0,0 +1,900 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cycdiff=0; + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { + oldcs = CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + + if (!use32) cpu_state.pc &= 0xffff; + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); + codeblock_t *block = codeblock_hash[hash]; + int valid_block = 0; + trap = 0; + + if (block && !cpu_state.abrt) + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + block = new_block; + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + } + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; + } + } + + if (valid_block && block->was_recompiled) + { + void (*code)() = (void *)&block->data[BLOCK_START]; + + codeblock_hash[hash] = block; + + inrecomp=1; + code(); + inrecomp=0; + if (!use32) cpu_state.pc &= 0xffff; + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { + oldcs = CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { + oldcs=CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; + CS = oldcs; +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Double fault %i\n", ins); +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); + #ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); + #endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + else if (trap) + { + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; + oldcs = CS; + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags&I_FLAG) && pic_intpending) + { + vector = picinterrupt(); + if (vector != -1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + oxpc=cpu_state.pc; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu_common/386_dynarec_ops.c similarity index 90% rename from src/cpu/386_dynarec_ops.c rename to src/cpu_common/386_dynarec_ops.c index 7585a305b..42edfbef5 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu_common/386_dynarec_ops.c @@ -7,18 +7,19 @@ #ifndef INFINITY # define INFINITY (__builtin_inff()) #endif -#include "../86box.h" + +#include "86box.h" #include "cpu.h" -#include "../timer.h" +#include "timer.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" #include "x86_flags.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" #include "codegen.h" -#include "../pic.h" #define CPU_BLOCK_END() cpu_block_end = 1 @@ -55,8 +56,8 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) cpu_state.last_ea = cpu_state.eaaddr; } -#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat); -#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat); +#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat); +#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat); #define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32) @@ -64,6 +65,8 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) #define PREFETCH_FLUSH() #define OP_TABLE(name) dynarec_ops_ ## name + #define CLOCK_CYCLES(c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + #include "386_ops.h" diff --git a/src/cpu_new/386_ops.h b/src/cpu_common/386_ops.h similarity index 99% rename from src/cpu_new/386_ops.h rename to src/cpu_common/386_ops.h index b3d331423..8459607ff 100644 --- a/src/cpu_new/386_ops.h +++ b/src/cpu_common/386_ops.h @@ -167,12 +167,14 @@ static int ILLEGAL(uint32_t fetchdat) return 0; } +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_AMD_K) || defined(USE_I686))) static int internal_illegal(char *s) { cpu_state.pc = cpu_state.oldpc; x86gpf(s, 0); return cpu_state.abrt; } +#endif #ifdef ENABLE_386_DYNAREC_LOG extern void x386_dynarec_log(const char *fmt, ...); @@ -183,13 +185,11 @@ extern void x386_dynarec_log(const char *fmt, ...); #endif #include "x86seg.h" -# include "x86_ops_amd.h" #include "x86_ops_arith.h" #include "x86_ops_atomic.h" #include "x86_ops_bcd.h" #include "x86_ops_bit.h" #include "x86_ops_bitscan.h" -#include "x86_ops_call.h" #include "x86_ops_flag.h" #include "x86_ops_fpu.h" #include "x86_ops_inc_dec.h" @@ -202,7 +202,6 @@ extern void x386_dynarec_log(const char *fmt, ...); # include "x86_ops_i686.h" #endif #include "x86_ops_mmx.h" -#include "x86_ops_3dnow.h" #include "x86_ops_mmx_arith.h" #include "x86_ops_mmx_cmp.h" #include "x86_ops_mmx_logic.h" @@ -220,10 +219,15 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_rep.h" #include "x86_ops_ret.h" #include "x86_ops_set.h" -#include "x86_ops_shift.h" #include "x86_ops_stack.h" #include "x86_ops_string.h" #include "x86_ops_xchg.h" +#include "x86_ops_call.h" +#include "x86_ops_shift.h" +#ifdef USE_NEW_DYNAREC +#include "x86_ops_amd.h" +#endif +#include "x86_ops_3dnow.h" static int op0F_w_a16(uint32_t fetchdat) @@ -905,6 +909,7 @@ const OpFn OP_TABLE(pentiummmx_0f)[1024] = /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; +#ifdef USE_NEW_DYNAREC const OpFn OP_TABLE(k6_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -1086,7 +1091,9 @@ const OpFn OP_TABLE(k62_0f)[1024] = /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; +#endif +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) const OpFn OP_TABLE(c6x86mx_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -1177,6 +1184,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; +#endif #ifdef DEV_BRANCH #ifdef USE_I686 @@ -1271,7 +1279,6 @@ const OpFn OP_TABLE(pentiumpro_0f)[1024] = /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; -#if 0 const OpFn OP_TABLE(pentium2_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -1362,7 +1369,6 @@ const OpFn OP_TABLE(pentium2_0f)[1024] = /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; -#endif const OpFn OP_TABLE(pentium2d_0f)[1024] = { diff --git a/src/cpu/808x.c b/src/cpu_common/808x.c similarity index 98% rename from src/cpu/808x.c rename to src/cpu_common/808x.c index 929d08bb6..ede1412cd 100644 --- a/src/cpu/808x.c +++ b/src/cpu_common/808x.c @@ -23,17 +23,18 @@ #include #include #include + #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../nmi.h" -#include "../pic.h" -#include "../timer.h" +#include "machine.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" /* The opcode of the instruction currently being executed. */ uint8_t opcode; @@ -58,7 +59,6 @@ int is8086 = 0; /* Variables for handling the non-maskable interrupts. */ int nmi = 0, nmi_auto_clear = 0; -int nmi_enable = 1; /* Was the CPU ever reset? */ int x86_was_reset = 0; @@ -653,6 +653,13 @@ sign_extend(uint8_t data) } +static uint32_t +sign_extend32(uint16_t data) +{ + return data + (data < 0x8000 ? 0 : 0xffff0000); +} + + /* Fetches the effective address from the prefetch queue according to MOD and R/M. */ static void do_mod_rm(void) @@ -937,7 +944,6 @@ reset_common(int hard) cpu_state.flags = 2; trap = 0; ovr_seg = NULL; - in_lock = 0; EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; @@ -946,6 +952,7 @@ reset_common(int hard) resetreadlookup(); makemod1table(); resetmcr(); + pfq_clear(); cpu_set_edx(); mmu_perm = 4; pfq_size = (is8086) ? 6 : 4; @@ -960,12 +967,12 @@ reset_common(int hard) x86_was_reset = 1; cpu_alt_reset = 0; - pfq_clear(); prefetching = 1; - takeint = 0; cpu_ven_reset(); + + cpu_alu_op = 0; } @@ -1761,6 +1768,7 @@ execx86(int cycs) uint8_t temp = 0, temp2; uint16_t addr, tempw; uint16_t new_cs, new_ip; + uint32_t result; int bits; cycles += cycs; @@ -2743,17 +2751,25 @@ execx86(int cycs) case 0x28: /* IMUL */ wait(1, 0); if (opcode & 1) { + result = cpu_data; mul(AX, cpu_data); AX = cpu_data; DX = cpu_dest; cpu_data |= DX; - set_co_mul(DX != ((AX & 0x8000) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xffff)); + result = ((uint32_t) DX << 16) | AX; + if ((rmdat & 0x38) == 0x20) + set_co_mul(DX != 0x0000); + else + set_co_mul(result != sign_extend32(AX)); } else { mul(AL, cpu_data); AL = (uint8_t) cpu_data; AH = (uint8_t) cpu_dest; cpu_data |= AH; - set_co_mul(AH != ((AL & 0x80) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xff)); + if ((rmdat & 0x38) == 0x20) + set_co_mul(AH != 0x00); + else + set_co_mul(AX != sign_extend(AL)); } /* NOTE: When implementing the V20, care should be taken to not change the zero flag. */ @@ -2888,6 +2904,8 @@ execx86(int cycs) if (noint) noint = 0; + + cpu_alu_op = 0; } ins++; diff --git a/src/cpu_common/codegen_public.h b/src/cpu_common/codegen_public.h new file mode 100644 index 000000000..e5ca4b33e --- /dev/null +++ b/src/cpu_common/codegen_public.h @@ -0,0 +1,64 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the code generator. + * + * Version: @(#)codegen_public.h 1.0.0 2020/01/27 + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ +#ifndef _CODEGEN_PUBLIC_H_ +#define _CODEGEN_PUBLIC_H_ + +#ifndef USE_NEW_DYNAREC +#define PAGE_MASK_INDEX_MASK 3 +#define PAGE_MASK_INDEX_SHIFT 10 +#define PAGE_MASK_SHIFT 4 +#else +#define PAGE_MASK_SHIFT 6 +#endif +#define PAGE_MASK_MASK 63 + +#ifdef USE_NEW_DYNAREC +#define BLOCK_PC_INVALID 0xffffffff +#define BLOCK_INVALID 0 +#endif + + +extern void codegen_init(); +#ifdef USE_NEW_DYNAREC +extern void codegen_close(); +#endif +extern void codegen_flush(); + + +/*Current physical page of block being recompiled. -1 if no recompilation taking place */ +extern uint32_t recomp_page; +extern int codegen_in_recompile; + +#endif diff --git a/src/cpu/cpu.c b/src/cpu_common/cpu.c similarity index 65% rename from src/cpu/cpu.c rename to src/cpu_common/cpu.c index 599c90e6e..43e8a7adb 100644 --- a/src/cpu/cpu.c +++ b/src/cpu_common/cpu.c @@ -38,29 +38,28 @@ * Boston, MA 02111-1307 * USA. */ +#include #include #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../device.h" -#include "../machine/machine.h" -#include "../io.h" +#include "device.h" +#include "machine.h" +#include "86box_io.h" #include "x86_ops.h" -#include "../mem.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pci.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "pci.h" #ifdef USE_DYNAREC # include "codegen.h" #endif -#if 1 static void cpu_write(uint16_t addr, uint8_t val, void *priv); static uint8_t cpu_read(uint16_t addr, void *priv); -#endif enum { @@ -77,6 +76,12 @@ enum { CPUID_FXSR = (1 << 24) }; +/*Addition flags returned by CPUID function 0x80000001*/ +enum +{ + CPUID_3DNOW = (1 << 31) +}; + #ifdef USE_DYNAREC const OpFn *x86_dynarec_opcodes; @@ -99,6 +104,9 @@ 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; +#ifdef USE_NEW_DYNAREC +const OpFn *x86_dynarec_opcodes_3DNOW; +#endif #endif const OpFn *x86_opcodes; @@ -121,6 +129,7 @@ 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; int in_smm = 0, smi_line = 0, smi_latched = 0; uint32_t smbase = 0x30000; @@ -128,6 +137,7 @@ uint32_t smbase = 0x30000; CPU *cpu_s; int cpu_effective; int cpu_multi; +double cpu_dmulti; int cpu_16bitbus; int cpu_busspeed; int cpu_cyrix_alignment; @@ -146,7 +156,8 @@ uint32_t cpu_features; int is286, is386, - is486, + is486 = 1, + is486sx, is486dx, is486sx2, is486dx2, isdx4, cpu_iscyrix, isibmcpu, israpidcad, @@ -162,11 +173,6 @@ uint64_t pmc[2] = {0, 0}; uint16_t temp_seg_data[4] = {0, 0, 0, 0}; -#if defined(DEV_BRANCH) && defined(USE_I686) -uint16_t cs_msr = 0; -uint32_t esp_msr = 0; -uint32_t eip_msr = 0; -uint64_t apic_base_msr = 0; uint64_t mtrr_cap_msr = 0; uint64_t mtrr_physbase_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint64_t mtrr_physmask_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -174,8 +180,14 @@ uint64_t mtrr_fix64k_8000_msr = 0; uint64_t mtrr_fix16k_8000_msr = 0; uint64_t mtrr_fix16k_a000_msr = 0; uint64_t mtrr_fix4k_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t pat_msr = 0; uint64_t mtrr_deftype_msr = 0; + +#if defined(DEV_BRANCH) && defined(USE_I686) +uint16_t cs_msr = 0; +uint32_t esp_msr = 0; +uint32_t eip_msr = 0; +uint64_t apic_base_msr = 0; +uint64_t pat_msr = 0; uint64_t msr_ia32_pmc[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint64_t ecx17_msr = 0; uint64_t ecx79_msr = 0; @@ -189,10 +201,21 @@ uint64_t ecx1e0_msr = 0; uint64_t ecx570_msr = 0; #endif -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) uint64_t ecx83_msr = 0; /* AMD K5 and K6 MSR's. */ +#ifdef USE_NEW_DYNAREC +uint64_t star = 0; /* AMD K6-2+. */ +#endif + +#ifdef USE_NEW_DYNAREC +uint64_t amd_efer = 0, amd_whcr = 0, + amd_uwccr = 0, amd_epmr = 0, /* AMD K6-2+ registers. */ + amd_psor = 0, amd_pfir = 0, + amd_l2aar = 0; +#else uint64_t amd_efer = 0, amd_whcr = 0; #endif +#endif int timing_rr; int timing_mr, timing_mrl; @@ -254,27 +277,34 @@ cpu_set(void) cpu_alt_reset = 0; - CPUID = cpu_s->cpuid_model; - is8086 = (cpu_s->cpu_type > CPU_8088); - is286 = (cpu_s->cpu_type >= CPU_286); - is386 = (cpu_s->cpu_type >= CPU_386SX); - isibmcpu = (cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL); - israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); - is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL ); - is_pentium = (cpu_s->cpu_type >= CPU_WINCHIP); - hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD); -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); + CPUID = cpu_s->cpuid_model; + is8086 = (cpu_s->cpu_type > CPU_8088); + is286 = (cpu_s->cpu_type >= CPU_286); + is386 = (cpu_s->cpu_type >= CPU_386SX); + isibmcpu = (cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL); + israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); + is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL ); + is486sx = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type < CPU_i486SX2); + is486sx2 = (cpu_s->cpu_type >= CPU_i486SX2) && (cpu_s->cpu_type < CPU_i486DX); + is486dx = (cpu_s->cpu_type >= CPU_i486DX) && (cpu_s->cpu_type < CPU_i486DX2); + is486dx2 = (cpu_s->cpu_type >= CPU_iDX4) && (cpu_s->cpu_type < CPU_WINCHIP); + isdx4 = (cpu_s->cpu_type >= CPU_i486DX2) && (cpu_s->cpu_type < CPU_iDX4); + is_pentium = (cpu_s->cpu_type >= CPU_WINCHIP); + hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD); +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) + cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); #else - cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86); + cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86); #endif cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC ); - if (cpu_s->multi) { - cpu_busspeed = cpu_s->rspeed / cpu_s->multi; - } - cpu_multi = cpu_s->multi; + if (cpu_s->multi) + cpu_busspeed = cpu_s->rspeed / cpu_s->multi; + else + cpu_busspeed = cpu_s->rspeed; + cpu_multi = (int) ceil(cpu_s->multi); + cpu_dmulti = cpu_s->multi; ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; if ((cpu_s->cpu_type == CPU_8088) || (cpu_s->cpu_type == CPU_8086) || @@ -292,16 +322,15 @@ cpu_set(void) else cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; - if (cpu_s->pci_speed) - { - pci_nonburst_time = 4*cpu_s->rspeed / cpu_s->pci_speed; - pci_burst_time = cpu_s->rspeed / cpu_s->pci_speed; - } - else - { - pci_nonburst_time = 4; - pci_burst_time = 1; - } + if (cpu_busspeed < 42500000) + cpu_pci_speed = cpu_busspeed; + else if ((cpu_busspeed > 42500000) && (cpu_busspeed < 84000000)) + cpu_pci_speed = cpu_busspeed / 2; + else + cpu_pci_speed = cpu_busspeed / 3; + + pci_burst_time = cpu_s->rspeed / cpu_pci_speed; + pci_nonburst_time = 4 * pci_burst_time; if (cpu_iscyrix) io_sethandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); @@ -320,9 +349,13 @@ cpu_set(void) #endif x86_opcodes_REPE = ops_REPE; x86_opcodes_REPNE = ops_REPNE; + x86_opcodes_3DNOW = ops_3DNOW; #ifdef USE_DYNAREC x86_dynarec_opcodes_REPE = dynarec_ops_REPE; x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; +#ifdef USE_NEW_DYNAREC + x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; +#endif #endif #ifdef USE_DYNAREC @@ -622,8 +655,13 @@ cpu_set(void) timing_jmp_pm_gate = 32; timing_misaligned = 3; break; - + case CPU_RAPIDCAD: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); +#else + x86_setopcodes(ops_386, ops_486_0f); +#endif timing_rr = 1; /*register dest - register src*/ timing_rm = 2; /*register dest - memory src*/ timing_mr = 3; /*memory dest - register src*/ @@ -652,6 +690,7 @@ cpu_set(void) timing_jmp_rm = 17; timing_jmp_pm = 19; timing_jmp_pm_gate = 32; + timing_misaligned = 3; break; case CPU_486SLC: @@ -735,7 +774,9 @@ cpu_set(void) cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; /*FALLTHROUGH*/ case CPU_i486SX: + case CPU_i486SX2: case CPU_i486DX: + case CPU_i486DX2: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else @@ -773,7 +814,11 @@ cpu_set(void) break; case CPU_Am486SX: + case CPU_Am486SX2: case CPU_Am486DX: + case CPU_Am486DX2: + case CPU_Am486DX4: + case CPU_Am5x86: /*AMD timing identical to Intel*/ #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); @@ -813,6 +858,7 @@ cpu_set(void) case CPU_Cx486S: case CPU_Cx486DX: + case CPU_Cx486DX2: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else @@ -931,6 +977,52 @@ cpu_set(void) cpu_cyrix_alignment = 1; break; +#ifdef USE_NEW_DYNAREC + case CPU_WINCHIP2: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); +#else + x86_setopcodes(ops_386, ops_winchip2_0f); +#endif + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 2; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 2; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 3-1; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + /*unknown*/ + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_winchip2); +#endif + break; +#endif + case CPU_PENTIUM: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); @@ -1017,7 +1109,7 @@ cpu_set(void) #endif break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); @@ -1188,7 +1280,7 @@ cpu_set(void) break; #endif -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: #ifdef USE_DYNAREC @@ -1205,10 +1297,32 @@ cpu_set(void) timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; timing_misaligned = 3; cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; +#if defined(USE_NEW_DYNAREC) && defined(USE_DYNAREC) + codegen_timing_set(&codegen_timing_k6); +#endif break; case CPU_K6: @@ -1226,13 +1340,83 @@ cpu_set(void) timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; timing_misaligned = 3; cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC + codegen_timing_set(&codegen_timing_k6); +#else codegen_timing_set(&codegen_timing_pentium); #endif +#endif + break; +#endif + +#ifdef USE_NEW_DYNAREC + case CPU_K6_2: + case CPU_K6_2C: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f); +#else + x86_setopcodes(ops_386, ops_k62_0f); +#endif + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 0; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + timing_misaligned = 3; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX | CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; + codegen_timing_set(&codegen_timing_k6); break; #endif @@ -1256,24 +1440,46 @@ cpu_set(void) 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 = 1; /*register dest - memory src*/ - timing_mr = 1; /*memory dest - register src*/ - timing_mm = 1; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 1; /*memory dest - register src long*/ - timing_mml = 1; + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; timing_misaligned = 3; cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC + codegen_timing_set(&codegen_timing_k6); +#else codegen_timing_set(&codegen_timing_686); +#endif #endif break; -#if 0 case CPU_PENTIUM2: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); @@ -1293,23 +1499,45 @@ cpu_set(void) 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 = 1; /*register dest - memory src*/ - timing_mr = 1; /*memory dest - register src*/ - timing_mm = 1; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 1; /*memory dest - register src long*/ - timing_mml = 1; + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; timing_misaligned = 3; cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC + codegen_timing_set(&codegen_timing_k6); +#else codegen_timing_set(&codegen_timing_686); #endif - break; #endif + break; case CPU_PENTIUM2D: #ifdef USE_DYNAREC @@ -1330,23 +1558,89 @@ cpu_set(void) 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 = 1; /*register dest - memory src*/ - timing_mr = 1; /*memory dest - register src*/ - timing_mm = 1; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 1; /*memory dest - register src long*/ - timing_mml = 1; + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; timing_misaligned = 3; cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE | CR4_OSFXSR; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC + codegen_timing_set(&codegen_timing_k6); +#else codegen_timing_set(&codegen_timing_686); +#endif #endif break; #endif + case CPU_CYRIX3S: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); +#else + x86_setopcodes(ops_386, ops_winchip2_0f); +#endif + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 2; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 2; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 3-1; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + /*unknown*/ + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_winchip); +#endif + break; default: fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); @@ -1373,7 +1667,9 @@ cpu_CPUID(void) { switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { + case CPU_RAPIDCAD: case CPU_i486DX: + case CPU_i486DX2: if (!EAX) { EAX = 0x00000001; @@ -1410,6 +1706,7 @@ cpu_CPUID(void) break; case CPU_Am486SX: + case CPU_Am486SX2: if (!EAX) { EAX = 1; @@ -1427,6 +1724,9 @@ cpu_CPUID(void) break; case CPU_Am486DX: + case CPU_Am486DX2: + case CPU_Am486DX4: + case CPU_Am5x86: if (!EAX) { EAX = 1; @@ -1475,6 +1775,68 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; +#ifdef USE_NEW_DYNAREC + case CPU_WINCHIP2: + switch (EAX) + { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) + { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } + else + { + EBX = 0x746e6543; /*CentaurHauls*/ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + if (cpu_has_feature(CPU_FEATURE_3DNOW)) + EDX |= CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x20544449; /*IDT WinChip 2-3D*/ + EBX = 0x436e6957; + ECX = 0x20706968; + EDX = 0x44332d32; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x08800880; /*TLBs*/ + ECX = 0x20040120; /*L1 data cache*/ + EDX = 0x20020120; /*L1 instruction cache*/ + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; +#endif + case CPU_PENTIUM: if (!EAX) { @@ -1493,7 +1855,7 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: if (!EAX) { @@ -1576,7 +1938,7 @@ cpu_CPUID(void) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; } else if (EAX == 0x80000000) { @@ -1587,7 +1949,7 @@ cpu_CPUID(void) { EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; } else if (EAX == 0x80000002) { @@ -1627,6 +1989,169 @@ cpu_CPUID(void) break; #endif +#ifdef USE_NEW_DYNAREC + case CPU_K6_2: + case CPU_K6_2C: + switch (EAX) + { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID+0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm) 3D pr*/ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x72702044; + break; + + case 0x80000003: /*Processor name string*/ + EAX = 0x7365636f; /*ocessor*/ + EBX = 0x00726f73; + ECX = 0x00000000; + EDX = 0x00000000; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + + case CPU_K6_3: + switch (EAX) + { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000006; + break; + case 0x80000001: + EAX = CPUID+0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm) 3D+ P*/ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x50202b44; + break; + + case 0x80000003: /*Processor name string*/ + EAX = 0x65636f72; /*rocessor*/ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + + case 0x80000006: /*L2 Cache information*/ + ECX = 0x01004220; + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + + case CPU_K6_2P: + case CPU_K6_3P: + switch (EAX) + { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000007; + break; + case 0x80000001: + EAX = CPUID+0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm)-III P*/ + EBX = 0x7428364b; + ECX = 0x492d296d; + EDX = 0x50204949; + break; + + case 0x80000003: /*Processor name string*/ + EAX = 0x65636f72; /*rocessor*/ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + + case 0x80000006: /*L2 Cache information*/ + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_K6_3P) + ECX = 0x01004220; + else + ECX = 0x00804220; + break; + + case 0x80000007: /*PowerNow information*/ + EDX = 7; + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; +#endif + case CPU_PENTIUMMMX: if (!EAX) { @@ -1646,7 +2171,7 @@ cpu_CPUID(void) break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: if (!EAX) { @@ -1747,7 +2272,7 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; - /* case CPU_PENTIUM2: + case CPU_PENTIUM2: if (!EAX) { EAX = 0x00000002; @@ -1769,7 +2294,7 @@ cpu_CPUID(void) } else EAX = EBX = ECX = EDX = 0; - break; */ + break; case CPU_PENTIUM2D: if (!EAX) @@ -1796,13 +2321,71 @@ cpu_CPUID(void) break; #endif #endif - + case CPU_CYRIX3S: + switch (EAX) + { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) + { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } + else + { + EBX = 0x746e6543; /*CentaurHauls*/ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + if (cpu_has_feature(CPU_FEATURE_3DNOW)) + EDX |= CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x20414956; /*VIA Samuel*/ + EBX = 0x756d6153; + ECX = 0x00006c65; + EDX = 0x00000000; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x08800880; /*TLBs*/ + ECX = 0x40040120; /*L1 data cache*/ + EDX = 0x40020120; /*L1 instruction cache*/ + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; } } void cpu_ven_reset(void) { -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_K5: @@ -1810,6 +2393,34 @@ void cpu_ven_reset(void) case CPU_K6: amd_efer = amd_whcr = 0ULL; break; +#ifdef USE_NEW_DYNAREC + case CPU_K6_2: + amd_efer = amd_whcr = 0ULL; + star = 0ULL; + break; + case CPU_K6_2C: + amd_efer = 2ULL; + amd_whcr = star = 0ULL; + amd_psor = 0x018cULL; + amd_uwccr = 0ULL; + break; + case CPU_K6_3: + amd_efer = 2ULL; + amd_whcr = star = 0ULL; + amd_psor = 0x008cULL; + amd_uwccr = 0ULL; + amd_pfir = amd_l2aar = 0ULL; + break; + case CPU_K6_2P: + case CPU_K6_3P: + amd_efer = 2ULL; + amd_whcr = star = 0ULL; + amd_psor = 0x008cULL; + amd_uwccr = 0ULL; + amd_pfir = amd_l2aar = 0ULL; + amd_epmr = 0ULL; + break; +#endif } #endif } @@ -1819,6 +2430,9 @@ void cpu_RDMSR() switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_WINCHIP: +#ifdef USE_NEW_DYNAREC + case CPU_WINCHIP2: +#endif EAX = EDX = 0; switch (ECX) { @@ -1847,8 +2461,81 @@ void cpu_RDMSR() break; } break; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K) + + case CPU_CYRIX3S: + EAX = EDX = 0; + switch (ECX) + { + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x2a: + if (cpu_dmulti == 3) + EAX = ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 3.5) + EAX = ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 4) + EAX = ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 4.5) + EAX = ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 5) + EAX = 0; + else if (cpu_dmulti == 5.5) + EAX = ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); + else if (cpu_dmulti == 6) + EAX = ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 6.5) + EAX = ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 7) + EAX = ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else + EAX = ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + break; + case 0x1107: + EAX = msr.fcr; + break; + case 0x1108: + EAX = msr.fcr2 & 0xffffffff; + EDX = msr.fcr2 >> 32; + break; + case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: + if (ECX & 1) + { + EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = mtrr_physmask_msr[(ECX - 0x200) >> 1] >> 32; + } + else + { + EAX = mtrr_physbase_msr[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = mtrr_physbase_msr[(ECX - 0x200) >> 1] >> 32; + } + break; + case 0x250: + EAX = mtrr_fix64k_8000_msr & 0xffffffff; + EDX = mtrr_fix64k_8000_msr >> 32; + break; + case 0x258: + EAX = mtrr_fix16k_8000_msr & 0xffffffff; + EDX = mtrr_fix16k_8000_msr >> 32; + break; + case 0x259: + EAX = mtrr_fix16k_a000_msr & 0xffffffff; + EDX = mtrr_fix16k_a000_msr >> 32; + break; + case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: + EAX = mtrr_fix4k_msr[ECX - 0x268] & 0xffffffff; + EDX = mtrr_fix4k_msr[ECX - 0x268] >> 32; + break; + case 0x2FF: + EAX = mtrr_deftype_msr & 0xffffffff; + EDX = mtrr_deftype_msr >> 32; + break; + } + break; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: case CPU_K6: @@ -1881,6 +2568,189 @@ void cpu_RDMSR() break; #endif +#ifdef USE_NEW_DYNAREC + case CPU_K6_2: + EAX = EDX = 0; + switch (ECX) + { + case 0x0000000e: + EAX = msr.tr12; + break; + case 0x00000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x00000083: + EAX = ecx83_msr & 0xffffffff; + EDX = ecx83_msr >> 32; + break; + case 0xC0000080: + EAX = amd_efer & 0xffffffff; + EDX = amd_efer >> 32; + break; + case 0xC0000081: + EAX = star & 0xffffffff; + EDX = star >> 32; + break; + case 0xC0000082: + EAX = amd_whcr & 0xffffffff; + EDX = amd_whcr >> 32; + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_2C: + EAX = EDX = 0; + switch (ECX) + { + case 0x0000000e: + EAX = msr.tr12; + break; + case 0x00000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x00000083: + EAX = ecx83_msr & 0xffffffff; + EDX = ecx83_msr >> 32; + break; + case 0xC0000080: + EAX = amd_efer & 0xffffffff; + EDX = amd_efer >> 32; + break; + case 0xC0000081: + EAX = star & 0xffffffff; + EDX = star >> 32; + break; + case 0xC0000082: + EAX = amd_whcr & 0xffffffff; + EDX = amd_whcr >> 32; + break; + case 0xC0000085: + EAX = amd_uwccr & 0xffffffff; + EDX = amd_uwccr >> 32; + break; + case 0xC0000087: + EAX = amd_psor & 0xffffffff; + EDX = amd_psor >> 32; + break; + case 0xC0000088: + EAX = amd_pfir & 0xffffffff; + EDX = amd_pfir >> 32; + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_3: + EAX = EDX = 0; + switch (ECX) + { + case 0x0000000e: + EAX = msr.tr12; + break; + case 0x00000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x00000083: + EAX = ecx83_msr & 0xffffffff; + EDX = ecx83_msr >> 32; + break; + case 0xC0000080: + EAX = amd_efer & 0xffffffff; + EDX = amd_efer >> 32; + break; + case 0xC0000081: + EAX = star & 0xffffffff; + EDX = star >> 32; + break; + case 0xC0000082: + EAX = amd_whcr & 0xffffffff; + EDX = amd_whcr >> 32; + break; + case 0xC0000085: + EAX = amd_uwccr & 0xffffffff; + EDX = amd_uwccr >> 32; + break; + case 0xC0000087: + EAX = amd_psor & 0xffffffff; + EDX = amd_psor >> 32; + break; + case 0xC0000088: + EAX = amd_pfir & 0xffffffff; + EDX = amd_pfir >> 32; + break; + case 0xC0000089: + EAX = amd_l2aar & 0xffffffff; + EDX = amd_l2aar >> 32; + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_2P: + case CPU_K6_3P: + EAX = EDX = 0; + switch (ECX) + { + case 0x0000000e: + EAX = msr.tr12; + break; + case 0x00000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x00000083: + EAX = ecx83_msr & 0xffffffff; + EDX = ecx83_msr >> 32; + break; + case 0xC0000080: + EAX = amd_efer & 0xffffffff; + EDX = amd_efer >> 32; + break; + case 0xC0000081: + EAX = star & 0xffffffff; + EDX = star >> 32; + break; + case 0xC0000082: + EAX = amd_whcr & 0xffffffff; + EDX = amd_whcr >> 32; + break; + case 0xC0000085: + EAX = amd_uwccr & 0xffffffff; + EDX = amd_uwccr >> 32; + break; + case 0xC0000086: + EAX = amd_epmr & 0xffffffff; + EDX = amd_epmr >> 32; + break; + case 0xC0000087: + EAX = amd_psor & 0xffffffff; + EDX = amd_psor >> 32; + break; + case 0xC0000088: + EAX = amd_pfir & 0xffffffff; + EDX = amd_pfir >> 32; + break; + case 0xC0000089: + EAX = amd_l2aar & 0xffffffff; + EDX = amd_l2aar >> 32; + break; + default: + x86gpf(NULL, 0); + break; + } + break; +#endif + case CPU_PENTIUM: case CPU_PENTIUMMMX: EAX = EDX = 0; @@ -1892,7 +2762,7 @@ void cpu_RDMSR() break; } break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: @@ -1910,6 +2780,7 @@ void cpu_RDMSR() #ifdef DEV_BRANCH #ifdef USE_I686 case CPU_PENTIUMPRO: + case CPU_PENTIUM2: case CPU_PENTIUM2D: EAX = EDX = 0; switch (ECX) @@ -2027,7 +2898,7 @@ void cpu_RDMSR() break; default: i686_invalid_rdmsr: - pclog("Invalid MSR read %08X\n", ECX); + // pclog("RDMSR: Invalid MSR: %08X\n", ECX); x86gpf(NULL, 0); break; } @@ -2039,13 +2910,16 @@ i686_invalid_rdmsr: void cpu_WRMSR() { -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) uint64_t temp; #endif switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_WINCHIP: +#ifdef USE_NEW_DYNAREC + case CPU_WINCHIP2: +#endif switch (ECX) { case 0x02: @@ -2066,10 +2940,16 @@ void cpu_WRMSR() cpu_features |= CPU_FEATURE_MMX; else cpu_features &= ~CPU_FEATURE_MMX; - if (EAX & (1 << 1)) - cpu_features |= CPU_FEATURE_CX8; - else - cpu_features &= ~CPU_FEATURE_CX8; + if (EAX & (1 << 1)) + cpu_features |= CPU_FEATURE_CX8; + else + cpu_features &= ~CPU_FEATURE_CX8; +#ifdef USE_NEW_DYNAREC + if ((EAX & (1 << 20)) && machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_WINCHIP2) + cpu_features |= CPU_FEATURE_3DNOW; + else + cpu_features &= ~CPU_FEATURE_3DNOW; +#endif if (EAX & (1 << 29)) CPUID = 0; else @@ -2082,9 +2962,52 @@ void cpu_WRMSR() msr.fcr3 = EAX | ((uint64_t)EDX << 32); break; } + break; + case CPU_CYRIX3S: + switch (ECX) + { + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x1107: + msr.fcr = EAX; + if (EAX & (1 << 1)) + cpu_features |= CPU_FEATURE_CX8; + else + cpu_features &= ~CPU_FEATURE_CX8; + break; + case 0x1108: + msr.fcr2 = EAX | ((uint64_t)EDX << 32); + break; + case 0x1109: + msr.fcr3 = EAX | ((uint64_t)EDX << 32); + break; + case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: + if (ECX & 1) + mtrr_physmask_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); + else + mtrr_physbase_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); + break; + case 0x250: + mtrr_fix64k_8000_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0x258: + mtrr_fix16k_8000_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0x259: + mtrr_fix16k_a000_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: + mtrr_fix4k_msr[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); + break; + case 0x2FF: + mtrr_deftype_msr = EAX | ((uint64_t)EDX << 32); + break; + } break; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K) + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: case CPU_K6: @@ -2116,6 +3039,169 @@ void cpu_WRMSR() break; #endif +#ifdef USE_NEW_DYNAREC + case CPU_K6_2: + switch (ECX) + { + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x83: + ecx83_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000080: + temp = EAX | ((uint64_t)EDX << 32); + if (temp & ~1ULL) + x86gpf(NULL, 0); + else + amd_efer = temp; + break; + case 0xC0000081: + star = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000082: + amd_whcr = EAX | ((uint64_t)EDX << 32); + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_2C: + switch (ECX) + { + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x83: + ecx83_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000080: + temp = EAX | ((uint64_t)EDX << 32); + if (temp & ~0xfULL) + x86gpf(NULL, 0); + else + amd_efer = temp; + break; + case 0xC0000081: + star = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000082: + amd_whcr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000085: + amd_uwccr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000087: + amd_psor = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000088: + amd_pfir = EAX | ((uint64_t)EDX << 32); + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_3: + switch (ECX) + { + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x83: + ecx83_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000080: + temp = EAX | ((uint64_t)EDX << 32); + if (temp & ~0x1fULL) + x86gpf(NULL, 0); + else + amd_efer = temp; + break; + case 0xC0000081: + star = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000082: + amd_whcr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000085: + amd_uwccr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000087: + amd_psor = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000088: + amd_pfir = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000089: + amd_l2aar = EAX | ((uint64_t)EDX << 32); + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_2P: + case CPU_K6_3P: + switch (ECX) + { + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x83: + ecx83_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000080: + temp = EAX | ((uint64_t)EDX << 32); + if (temp & ~0x1fULL) + x86gpf(NULL, 0); + else + amd_efer = temp; + break; + case 0xC0000081: + star = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000082: + amd_whcr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000085: + amd_uwccr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000086: + amd_epmr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000087: + amd_psor = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000088: + amd_pfir = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000089: + amd_l2aar = EAX | ((uint64_t)EDX << 32); + break; + default: + x86gpf(NULL, 0); + break; + } + break; +#endif + case CPU_PENTIUM: case CPU_PENTIUMMMX: switch (ECX) @@ -2125,7 +3211,7 @@ void cpu_WRMSR() break; } break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: @@ -2142,6 +3228,7 @@ void cpu_WRMSR() #ifdef DEV_BRANCH #ifdef USE_I686 case CPU_PENTIUMPRO: + case CPU_PENTIUM2: case CPU_PENTIUM2D: switch (ECX) { @@ -2227,7 +3314,7 @@ void cpu_WRMSR() break; default: i686_invalid_wrmsr: - pclog("Invalid MSR write %08X: %08X%08X\n", ECX, EDX, EAX); + // pclog("WRMSR: Invalid MSR: %08X\n", ECX); x86gpf(NULL, 0); break; } @@ -2271,7 +3358,7 @@ static void cpu_write(uint16_t addr, uint8_t val, void *priv) if ((ccr3 & 0xf0) == 0x10) { ccr4 = val; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_Cx6x86) { if (val & 0x80) diff --git a/src/cpu_new/cpu.h b/src/cpu_common/cpu.h similarity index 75% rename from src/cpu_new/cpu.h rename to src/cpu_common/cpu.h index 185250319..3672486f5 100644 --- a/src/cpu_new/cpu.h +++ b/src/cpu_common/cpu.h @@ -20,50 +20,77 @@ */ #ifndef EMU_CPU_H # define EMU_CPU_H +enum { + CPU_8088, /* 808x class CPUs */ + CPU_8086, +#ifdef USE_NEC_808X + CPU_V20, /* NEC 808x class CPUs - future proofing */ + CPU_V30, +#endif + CPU_286, /* 286 class CPUs */ + CPU_386SX, /* 386 class CPUs */ + CPU_386DX, + CPU_IBM386SLC, + CPU_IBM486SLC, + CPU_IBM486BL, + CPU_RAPIDCAD, + CPU_486SLC, + CPU_486DLC, + CPU_i486SX, /* 486 class CPUs */ + CPU_Am486SX, + CPU_Cx486S, + CPU_i486SX2, + CPU_Am486SX2, + CPU_i486DX, + CPU_i486DX2, + CPU_Am486DX, + CPU_Am486DX2, + CPU_Cx486DX, + CPU_Cx486DX2, + CPU_iDX4, + CPU_Am486DX4, + CPU_Cx486DX4, + CPU_Am5x86, + CPU_Cx5x86, + CPU_WINCHIP, /* 586 class CPUs */ +#ifdef USE_NEW_DYNAREC + CPU_WINCHIP2, +#endif + CPU_PENTIUM, + CPU_PENTIUMMMX, +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) + CPU_Cx6x86, + CPU_Cx6x86MX, + CPU_Cx6x86L, + CPU_CxGX1, +#endif +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))) + CPU_K5, + CPU_5K86, + CPU_K6, +#endif +#ifdef USE_NEW_DYNAREC + CPU_K6_2, + CPU_K6_2C, + CPU_K6_3, + CPU_K6_2P, + CPU_K6_3P, +#endif + CPU_CYRIX3S, +#if defined(DEV_BRANCH) && defined(USE_I686) + CPU_PENTIUMPRO, /* 686 class CPUs */ + CPU_PENTIUM2, + CPU_PENTIUM2D, +#endif + CPU_MAX /* Only really needed to close the enum in a way independent of the #ifdef's. */ +}; -#define CPU_8088 0 /* 808x class CPUs */ -#define CPU_8086 1 -#define CPU_286 2 /* 286 class CPUs */ -#define CPU_386SX 3 /* 386 class CPUs */ -#define CPU_386DX 4 -#define CPU_IBM386SLC 5 -#define CPU_IBM486SLC 6 -#define CPU_IBM486BL 7 -#define CPU_RAPIDCAD 8 -#define CPU_486SLC 9 -#define CPU_486DLC 10 -#define CPU_i486SX 11 /* 486 class CPUs */ -#define CPU_Am486SX 12 -#define CPU_Cx486S 13 -#define CPU_i486DX 14 -#define CPU_Am486DX 15 -#define CPU_Cx486DX 16 -#define CPU_iDX4 17 -#define CPU_Cx5x86 18 -#define CPU_WINCHIP 19 /* 586 class CPUs */ -#define CPU_WINCHIP2 20 -#define CPU_PENTIUM 21 -#define CPU_PENTIUMMMX 22 -#define CPU_Cx6x86 23 -#define CPU_Cx6x86MX 24 -#define CPU_Cx6x86L 25 -#define CPU_CxGX1 26 -#define CPU_K5 27 -#define CPU_5K86 28 -#define CPU_K6 29 -#define CPU_K6_2 30 -#define CPU_K6_2C 31 -#define CPU_K6_3 32 -#define CPU_K6_2P 33 -#define CPU_K6_3P 34 -#define CPU_PENTIUMPRO 35 /* 686 class CPUs */ -#define CPU_PENTIUM2D 36 - #define MANU_INTEL 0 #define MANU_AMD 1 #define MANU_CYRIX 2 #define MANU_IDT 3 +#define MANU_NEC 4 #define CPU_SUPPORTS_DYNAREC 1 #define CPU_REQUIRES_DYNAREC 2 @@ -71,20 +98,20 @@ typedef struct { - const char*name; - int cpu_type; - int rspeed; - double multi; - int pci_speed; - uint32_t edx_reset; - 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 atclk_div; + const char *name; + int cpu_type; + int rspeed; + double multi; + uint32_t edx_reset; + 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 atclk_div; } CPU; + extern CPU cpus_8088[]; extern CPU cpus_8086[]; extern CPU cpus_286[]; @@ -104,24 +131,33 @@ extern CPU cpus_i486[]; extern CPU cpus_Am486[]; extern CPU cpus_Cx486[]; extern CPU cpus_WinChip[]; +#ifdef USE_NEW_DYNAREC extern CPU cpus_WinChip_SS7[]; +#endif extern CPU cpus_Pentium5V[]; extern CPU cpus_Pentium5V50[]; extern CPU cpus_PentiumS5[]; extern CPU cpus_Pentium3V[]; +extern CPU cpus_Pentium[]; +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))) extern CPU cpus_K5[]; extern CPU cpus_K56[]; +#endif +#ifdef USE_NEW_DYNAREC extern CPU cpus_K56_SS7[]; -extern CPU cpus_Pentium[]; +#endif +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) extern CPU cpus_6x863V[]; extern CPU cpus_6x86[]; -extern CPU cpus_6x86SS7[]; -#ifdef DEV_BRANCH -#ifdef USE_I686 -extern CPU cpus_PentiumPro[]; -extern CPU cpus_Pentium2[]; -extern CPU cpus_Pentium2D[]; #endif +#ifdef USE_NEW_DYNAREC +extern CPU cpus_6x86SS7[]; +#endif +extern CPU cpus_Cyrix3[]; +#if defined(DEV_BRANCH) && defined(USE_I686) +extern CPU cpus_PentiumPro[]; +extern CPU cpus_PentiumII[]; +extern CPU cpus_PGA370[]; #endif @@ -244,12 +280,14 @@ struct _cpustate_ { new_npxc; uint32_t last_ea; +#ifdef USE_NEW_DYNAREC uint32_t old_fp_control, new_fp_control; #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ uint16_t old_fp_control2, new_fp_control2; #endif #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ uint32_t trunc_fp_control; +#endif #endif x86seg seg_cs, @@ -272,9 +310,15 @@ struct _cpustate_ { /*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status. Otherwise they are ignored*/ +#ifdef USE_NEW_DYNAREC #define CPU_STATUS_NOTFLATDS (1 << 8) #define CPU_STATUS_NOTFLATSS (1 << 9) #define CPU_STATUS_MASK 0xff00 +#else +#define CPU_STATUS_NOTFLATDS (1 << 16) +#define CPU_STATUS_NOTFLATSS (1 << 17) +#define CPU_STATUS_MASK 0xffff0000 +#endif #ifdef __MSC__ # define COMPILE_TIME_ASSERT(expr) /*nada*/ @@ -331,12 +375,13 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128) /* Global variables. */ extern int cpu_iscyrix; extern int cpu_16bitbus; -extern int cpu_busspeed; +extern int cpu_busspeed, cpu_pci_speed; extern int cpu_multi; +extern double cpu_dmulti; extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/ -extern int is8086, is286, is386, is486; +extern int is8086, is286, is386, is486, is486sx, is486dx, is486sx2, is486dx2, isdx4; extern int isibmcpu; extern int is_rapidcad; extern int hasfpu; @@ -348,12 +393,16 @@ extern int hasfpu; #define CPU_FEATURE_CX8 (1 << 5) #define CPU_FEATURE_3DNOW (1 << 6) -extern uint32_t cpu_features; +extern uint32_t cpu_features; -extern int in_smm, smi_line, smi_latched; -extern uint32_t smbase; +extern int in_smm, smi_line, smi_latched; +extern uint32_t smbase; +#ifdef USE_NEW_DYNAREC extern uint16_t cpu_cur_status; +#else +extern uint32_t cpu_cur_status; +#endif extern uint64_t cpu_CR4_mask; extern uint64_t tsc; extern msr_t msr; @@ -372,7 +421,7 @@ extern int ins,output; extern uint32_t pccache; extern uint8_t *pccache2; -extern double bus_timing; +extern double bus_timing, pci_timing; extern uint64_t pmc[2]; extern uint16_t temp_seg_data[4]; extern uint16_t cs_msr; @@ -448,9 +497,14 @@ extern CPU cpus_acer[]; // FIXME: should be in machine file! /* Functions. */ extern int cpu_has_feature(int feature); -int loadseg(uint16_t seg, x86seg *s); -void loadseg_dynarec(uint16_t seg, x86seg *s); -void loadcs(uint16_t seg); +#ifdef USE_NEW_DYNAREC +extern void loadseg_dynarec(uint16_t seg, x86seg *s); +extern int loadseg(uint16_t seg, x86seg *s); +extern void loadcs(uint16_t seg); +#else +extern void loadseg(uint16_t seg, x86seg *s); +extern void loadcs(uint16_t seg); +#endif extern char *cpu_current_pc(char *bufp); @@ -467,18 +521,24 @@ extern void codegen_reset(void); extern void cpu_set_edx(void); extern int divl(uint32_t val); extern void execx86(int cycs); -extern void enter_smm(); -extern void leave_smm(); +extern void enter_smm(); +extern void leave_smm(); extern void exec386(int cycs); extern void exec386_dynarec(int cycs); extern int idivl(int32_t val); -void pmodeint(int num, int soft); -int loadseg(uint16_t seg, x86seg *s); -void loadcs(uint16_t seg); -void loadcscall(uint16_t seg, uint32_t old_pc); -void loadcsjmp(uint16_t seg, uint32_t old_pc); -void pmoderetf(int is32, uint16_t off); -void pmodeiret(int is32); +#ifdef USE_NEW_DYNAREC +extern void loadcscall(uint16_t seg, uint32_t old_pc); +extern void loadcsjmp(uint16_t seg, uint32_t old_pc); +extern void pmodeint(int num, int soft); +extern void pmoderetf(int is32, uint16_t off); +extern void pmodeiret(int is32); +#else +extern void loadcscall(uint16_t seg); +extern void loadcsjmp(uint16_t seg, uint32_t old_pc); +extern void pmodeint(int num, int soft); +extern void pmoderetf(int is32, uint16_t off); +extern void pmodeiret(int is32); +#endif extern void resetmcr(void); extern void resetx86(void); extern void refreshread(void); diff --git a/src/cpu/cpu_table.c b/src/cpu_common/cpu_table - Cópia.c similarity index 75% rename from src/cpu/cpu_table.c rename to src/cpu_common/cpu_table - Cópia.c index a0e77f414..2c5676023 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu_common/cpu_table - Cópia.c @@ -45,9 +45,9 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../machine/machine.h" +#include "machine.h" CPU cpus_8088[] = { @@ -55,10 +55,10 @@ CPU cpus_8088[] = { {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8088/8", CPU_8088, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/16", CPU_8088, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} + {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/16", CPU_8088, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; CPU cpus_pcjr[] = { @@ -80,9 +80,9 @@ CPU cpus_8086[] = { {"8086/7.16", CPU_8086, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, {"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8086/9.54", CPU_8086, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8086/10", CPU_8086, 10000000, 2, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/12", CPU_8086, 12000000, 3, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/16", CPU_8086, 16000000, 4, 0, 0, 0, 0, 0, 0,0,0,0, 2}, + {"8086/10", CPU_8086, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/12", CPU_8086, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/16", CPU_8086, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; @@ -144,20 +144,20 @@ CPU cpus_i386SX[] = { }; CPU cpus_i386DX[] = { - /*i386DX*/ + /*i386DX/RapidCAD*/ {"i386DX/16", CPU_386DX, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2}, {"i386DX/20", CPU_386DX, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, {"i386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, {"i386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, {"i386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5}, - {"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0, 0x0430, 0, 0, 0, 4,4,3,3, 3}, - {"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0, 0x0430, 0, 0, 0, 6,6,3,3, 4}, - {"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0, 0x0430, 0, 0, 0, 7,7,3,3, 5}, + {"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; CPU cpus_Am386SX[] = { - /*Am386*/ + /*Am386SX*/ {"Am386SX/16", CPU_386SX, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, {"Am386SX/20", CPU_386SX, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, {"Am386SX/25", CPU_386SX, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, @@ -167,12 +167,24 @@ CPU cpus_Am386SX[] = { }; CPU cpus_Am386DX[] = { - /*Am386*/ + /*Am386DX*/ {"Am386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, {"Am386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, {"Am386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; + +CPU cpus_486SLC[] = { + /*Cx486SLC*/ + {"Cx486SLC/20", CPU_486SLC, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/25", CPU_486SLC, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/33", CPU_486SLC, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, + {"Cx486SRx2/32", CPU_486SLC, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 4}, + {"Cx486SRx2/40", CPU_486SLC, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, + {"Cx486SRx2/50", CPU_486SLC, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + CPU cpus_IBM386SLC[] = { /*IBM 386SLC*/ {"386SLC/16", CPU_IBM386SLC, 16000000, 1, 0, 0x300, 0, 0, 0, 3,3,3,3, 2}, @@ -182,13 +194,13 @@ CPU cpus_IBM386SLC[] = { }; CPU cpus_IBM486SLC[] = { - /*IBM 486SLC*/ - {"486SLC/33", CPU_IBM486SLC, 33333333, 1, 0, 0x400, 0, 0, 0, 6,6,3,3, 4}, + /*IBM 486SLC*/ + {"486SLC/33", CPU_IBM486SLC, 33333333, 1, 0, 0x400, 0, 0, 0, 6,6,3,3, 4}, {"486SLC2/40", CPU_IBM486SLC, 40000000, 2, 0, 0x400, 0, 0, 0, 7,7,6,6, 5}, - {"486SLC2/50", CPU_IBM486SLC, 50000000, 2, 0, 0x400, 0, 0, 0, 8,8,6,6, 6}, - {"486SLC2/66", CPU_IBM486SLC, 66666666, 2, 0, 0x400, 0, 0, 0, 12,12,6,6, 8}, - {"486SLC3/60", CPU_IBM486SLC, 60000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 7}, - {"486SLC3/75", CPU_IBM486SLC, 75000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 9}, + {"486SLC2/50", CPU_IBM486SLC, 50000000, 2, 0, 0x400, 0, 0, 0, 8,8,6,6, 6}, + {"486SLC2/66", CPU_IBM486SLC, 66666666, 2, 0, 0x400, 0, 0, 0, 12,12,6,6, 8}, + {"486SLC3/60", CPU_IBM486SLC, 60000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 7}, + {"486SLC3/75", CPU_IBM486SLC, 75000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 9}, {"486SLC3/100", CPU_IBM486SLC, 100000000, 3, 0, 0x400, 0, 0, 0, 18,18,9,9, 12}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; @@ -201,16 +213,6 @@ CPU cpus_IBM486BL[] = { {"486BL3/100", CPU_IBM486BL, 100000000, 3, 0, 0x400, 0, 0, 0, 18,18,9,9, 12}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; -CPU cpus_486SLC[] = { - /*Cx486SLC*/ - {"Cx486SLC/20", CPU_486SLC, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/25", CPU_486SLC, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/33", CPU_486SLC, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, - {"Cx486SRx2/32", CPU_486SLC, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 4}, - {"Cx486SRx2/40", CPU_486SLC, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, - {"Cx486SRx2/50", CPU_486SLC, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; CPU cpus_486DLC[] = { /*Cx486DLC*/ @@ -279,17 +281,18 @@ CPU cpus_i486[] = { {"i486DX/25", CPU_i486DX, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, {"i486DX/33", CPU_i486DX, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, {"i486DX/50", CPU_i486DX, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6}, - {"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, - {"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, /*CPUID available on DX2, DX4, P24T, >= 40 MHz*/ + {"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, {"i486DX2/66", CPU_i486DX, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, {"iDX4/75", CPU_iDX4, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/ {"iDX4/100", CPU_iDX4, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ - {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 25000000, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, + {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 25000000, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 33333333, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, {"Pentium OverDrive 63", CPU_PENTIUM, 62500000, 5/2, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, {"Pentium OverDrive 83", CPU_PENTIUM, 83333333, 5/2, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} }; + CPU cpus_Am486[] = { /*Am486/5x86*/ {"Am486SX/33", CPU_Am486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, @@ -332,8 +335,7 @@ CPU cpus_Cx486[] = { {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; -#ifdef DEV_BRANCH -#ifdef USE_CYRIX_6X86 +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) CPU cpus_6x863V[] = { /*Cyrix 6x86*/ {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, @@ -370,6 +372,35 @@ CPU cpus_6x86[] = { {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; #endif + +#ifdef USE_NEW_DYNAREC + CPU cpus_6x86SS7[] = { + /*Cyrix 6x86*/ + {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86L*/ + {"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86MX/MII*/ + {"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 5/2, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 5/2, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, + {"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 5/2, 41666666, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"MII/PR300", CPU_Cx6x86MX, 233333333, 7/2, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, + {"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 41666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, + {"MII/PR366", CPU_Cx6x86MX, 250000000, 5/2, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, + {"MII/PR400", CPU_Cx6x86MX, 285000000, 3, 31666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, + {"MII/PR433", CPU_Cx6x86MX, 300000000, 3, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }; #endif CPU cpus_WinChip[] = { @@ -385,9 +416,43 @@ CPU cpus_WinChip[] = { {"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, {"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, {"WinChip 240", CPU_WINCHIP, 240000000, 4, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#ifdef USE_NEW_DYNAREC + {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, (7*8)/2}, +#endif + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#ifdef USE_NEW_DYNAREC +CPU cpus_WinChip_SS7[] = { + /*IDT WinChip*/ + {"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, + {"WinChip 90", CPU_WINCHIP, 90000000, 3/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2}, + {"WinChip 100", CPU_WINCHIP, 100000000, 3/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12}, + {"WinChip 120", CPU_WINCHIP, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14}, + {"WinChip 133", CPU_WINCHIP, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16}, + {"WinChip 150", CPU_WINCHIP, 150000000, 5/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2}, + {"WinChip 166", CPU_WINCHIP, 166666666, 5/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40}, + {"WinChip 180", CPU_WINCHIP, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21}, + {"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 240", CPU_WINCHIP, 240000000, 4, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, + {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, + {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*9}, + {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, + {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, (7*8)/2}, + {"WinChip 2A/266", CPU_WINCHIP2, 233333333, 7/3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 7, 7, 28}, + {"WinChip 2A/300", CPU_WINCHIP2, 250000000, 5/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 8, 8, 30}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif + CPU cpus_Pentium5V[] = { /*Intel Pentium (5V, socket 4)*/ {"Pentium 60", CPU_PENTIUM, 60000000, 1, 30000000, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7}, @@ -466,6 +531,8 @@ CPU cpus_Pentium[] = { {"Pentium 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, {"Pentium 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, {"Pentium 200", CPU_PENTIUM, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*Intel Pentium MMX*/ {"Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, {"Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, {"Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, @@ -492,8 +559,7 @@ CPU cpus_Pentium[] = { {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; -#ifdef DEV_BRANCH -#ifdef USE_AMD_K +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) CPU cpus_K5[] = { /*AMD K5 (Socket 5)*/ {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, @@ -532,9 +598,69 @@ CPU cpus_K56[] = { {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} -}; +#ifdef USE_NEW_DYNAREC + {"K6-2/233", CPU_K6_2, 233333333, 7/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, + {"K6-2/300 AFR-66", CPU_K6_2, 300000000, 9/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, + {"K6-2/366", CPU_K6_2, 366666666, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33, 17, 17, 44}, #endif + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif + +#ifdef USE_NEW_DYNAREC +CPU cpus_K56_SS7[] = { + /*AMD K5 (Socket 7)*/ + {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*AMD K6 (Socket 7)*/ + {"K6 (Model 6) 166", CPU_K6, 166666666, 5/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K6 (Model 6) 200", CPU_K6, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 6) 233", CPU_K6, 233333333, 7/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6 (Model 7) 200", CPU_K6, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + + /*AMD K6-2 (Socket 7/Super Socket 7)*/ + {"K6-2/233", CPU_K6_2, 233333333, 7/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, + {"K6-2/300", CPU_K6_2, 300000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36}, + {"K6-2/333", CPU_K6_2, 332500000, 7/2, 31666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40}, + {"K6-2/350", CPU_K6_2C, 350000000, 7/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42}, + {"K6-2/366", CPU_K6_2C, 366666666, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44}, + {"K6-2/380", CPU_K6_2C, 380000000, 4, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46}, + {"K6-2/400", CPU_K6_2C, 400000000, 4, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-2/450", CPU_K6_2C, 450000000, 9/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-2/475", CPU_K6_2C, 475000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-2/500", CPU_K6_2C, 500000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"K6-2/533", CPU_K6_2C, 533333333, 11/2, 32323232, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, + {"K6-2/550", CPU_K6_2C, 550000000, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, + + /*AMD K6-2+/K6-3/K6-3+ (Super Socket 7)*/ + {"K6-2+/450", CPU_K6_2P, 450000000, 9/2, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-2+/475", CPU_K6_2P, 475000000, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-2+/500", CPU_K6_2P, 500000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"K6-2+/533", CPU_K6_2P, 533333333, 11/2, 32323232, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, + {"K6-2+/550", CPU_K6_2P, 550000000, 11/2, 32333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, + {"K6-III/400", CPU_K6_3, 400000000, 4, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-III/450", CPU_K6_3, 450000000, 9/2, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-III+/400", CPU_K6_3P, 400000000, 4, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-III+/450", CPU_K6_3P, 450000000, 9/2, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-III+/475", CPU_K6_3P, 475000000, 5, 31666667, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-III+/500", CPU_K6_3P, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; #endif #ifdef DEV_BRANCH diff --git a/src/cpu_common/cpu_table.c b/src/cpu_common/cpu_table.c new file mode 100644 index 000000000..f8422126b --- /dev/null +++ b/src/cpu_common/cpu_table.c @@ -0,0 +1,743 @@ +/* + * 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. + * + * Define all known processor types. + * + * Available cpuspeeds: + * + * 0 = 16 MHz + * 1 = 20 MHz + * 2 = 25 MHz + * 3 = 33 MHz + * 4 = 40 MHz + * 5 = 50 MHz + * 6 = 66 MHz + * 7 = 75 MHz + * 8 = 80 MHz + * 9 = 90 MHz + * 10 = 100 MHz + * 11 = 120 MHz + * 12 = 133 MHz + * 13 = 150 MHz + * 14 = 160 MHz + * 15 = 166 MHz + * 16 = 180 MHz + * 17 = 200 MHz + * + * Version: @(#)cpu_table.c 1.0.7 2019/10/21 + * + * Authors: Sarah Walker, + * leilei, + * Miran Grca, + * Fred N. van Kempen, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 leilei. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + */ +#include +#include +#include +#include +#include "86box.h" +#include "cpu.h" +#include "machine.h" + + +CPU cpus_8088[] = { + /*8088 standard*/ + {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/8", CPU_8088, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/16", CPU_8088, 16000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_pcjr[] = { + /*8088 PCjr*/ + {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_europc[] = { + /*8088 EuroPC*/ + {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8088/9.54", CPU_8088, 9545456, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_8086[] = { + /*8086 standard*/ + {"8086/7.16", CPU_8086, 7159092, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/9.54", CPU_8086, 9545456, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8086/10", CPU_8086, 10000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/12", CPU_8086, 12000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/16", CPU_8086, 16000000, 1, 0, 0, 0, 0, 0,0,0,0, 2}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_pc1512[] = { + /*8086 Amstrad*/ + {"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_286[] = { + /*286*/ + {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/12", CPU_286, 12500000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_ibmat[] = { + /*286*/ + {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 3,3,3,3, 1}, + {"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 3,3,3,3, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_ibmxt286[] = { + /*286*/ + {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_ps1_m2011[] = { + /*286*/ + {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 9} +}; + +CPU cpus_ps2_m30_286[] = { + /*286*/ + {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/12", CPU_286, 12500000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_i386SX[] = { + /*i386SX*/ + {"i386SX/16", CPU_386SX, 16000000, 1, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"i386SX/20", CPU_386SX, 20000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/25", CPU_386SX, 25000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/33", CPU_386SX, 33333333, 1, 0x2308, 0, 0, 0, 6,6,3,3, 4}, + {"i386SX/40", CPU_386SX, 40000000, 1, 0x2308, 0, 0, 0, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_i386DX[] = { + /*i386DX/RapidCAD*/ + {"i386DX/16", CPU_386DX, 16000000, 1, 0x0308, 0, 0, 0, 3,3,3,3, 2}, + {"i386DX/20", CPU_386DX, 20000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/25", CPU_386DX, 25000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/33", CPU_386DX, 33333333, 1, 0x0308, 0, 0, 0, 6,6,3,3, 4}, + {"i386DX/40", CPU_386DX, 40000000, 1, 0x0308, 0, 0, 0, 7,7,3,3, 5}, + {"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_Am386SX[] = { + /*Am386SX*/ + {"Am386SX/16", CPU_386SX, 16000000, 1, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"Am386SX/20", CPU_386SX, 20000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/25", CPU_386SX, 25000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/33", CPU_386SX, 33333333, 1, 0x2308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386SX/40", CPU_386SX, 40000000, 1, 0x2308, 0, 0, 0, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_Am386DX[] = { + /*Am386DX*/ + {"Am386DX/25", CPU_386DX, 25000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386DX/33", CPU_386DX, 33333333, 1, 0x0308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386DX/40", CPU_386DX, 40000000, 1, 0x0308, 0, 0, 0, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_486SLC[] = { + /*Cx486SLC*/ + {"Cx486SLC/20", CPU_486SLC, 20000000, 1, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/25", CPU_486SLC, 25000000, 1, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/33", CPU_486SLC, 33333333, 1, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, + {"Cx486SRx2/32", CPU_486SLC, 32000000, 2, 0x406, 0, 0x0006, 0, 6,6,6,6, 4}, + {"Cx486SRx2/40", CPU_486SLC, 40000000, 2, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, + {"Cx486SRx2/50", CPU_486SLC, 50000000, 2, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_IBM386SLC[] = { + /*IBM 386SLC*/ + {"386SLC/16", CPU_IBM386SLC, 16000000, 1, 0x300, 0, 0, 0, 3,3,3,3, 2}, + {"386SLC/20", CPU_IBM386SLC, 20000000, 1, 0x300, 0, 0, 0, 4,4,3,3, 3}, + {"386SLC/25", CPU_IBM386SLC, 25000000, 1, 0x300, 0, 0, 0, 4,4,3,3, 3}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_IBM486SLC[] = { + /*IBM 486SLC*/ + {"486SLC/33", CPU_IBM486SLC, 33333333, 1, 0x400, 0, 0, 0, 6,6,3,3, 4}, + {"486SLC2/40", CPU_IBM486SLC, 40000000, 2, 0x400, 0, 0, 0, 7,7,6,6, 5}, + {"486SLC2/50", CPU_IBM486SLC, 50000000, 2, 0x400, 0, 0, 0, 8,8,6,6, 6}, + {"486SLC2/66", CPU_IBM486SLC, 66666666, 2, 0x400, 0, 0, 0, 12,12,6,6, 8}, + {"486SLC3/60", CPU_IBM486SLC, 60000000, 3, 0x400, 0, 0, 0, 12,12,9,9, 7}, + {"486SLC3/75", CPU_IBM486SLC, 75000000, 3, 0x400, 0, 0, 0, 12,12,9,9, 9}, + {"486SLC3/100", CPU_IBM486SLC, 100000000, 3, 0x400, 0, 0, 0, 18,18,9,9, 12}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_IBM486BL[] = { + /*IBM Blue Lightning*/ + {"486BL2/50", CPU_IBM486BL, 50000000, 2, 0x400, 0, 0, 0, 8,8,6,6, 6}, + {"486BL2/66", CPU_IBM486BL, 66666666, 2, 0x400, 0, 0, 0, 12,12,6,6, 8}, + {"486BL3/75", CPU_IBM486BL, 75000000, 3, 0x400, 0, 0, 0, 12,12,9,9, 9}, + {"486BL3/100", CPU_IBM486BL, 100000000, 3, 0x400, 0, 0, 0, 18,18,9,9, 12}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_486DLC[] = { + /*Cx486DLC*/ + {"Cx486DLC/25", CPU_486DLC, 25000000, 1, 0x401, 0, 0x0001, 0, 4, 4,3,3, 3}, + {"Cx486DLC/33", CPU_486DLC, 33333333, 1, 0x401, 0, 0x0001, 0, 6, 6,3,3, 4}, + {"Cx486DLC/40", CPU_486DLC, 40000000, 1, 0x401, 0, 0x0001, 0, 7, 7,3,3, 5}, + {"Cx486DRx2/32", CPU_486DLC, 32000000, 2, 0x407, 0, 0x0007, 0, 6, 6,6,6, 4}, + {"Cx486DRx2/40", CPU_486DLC, 40000000, 2, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, + {"Cx486DRx2/50", CPU_486DLC, 50000000, 2, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, + {"Cx486DRx2/66", CPU_486DLC, 66666666, 2, 0x407, 0, 0x0007, 0, 12,12,6,6, 8}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} +}; + +CPU cpus_i486S1[] = { + /*i486*/ + {"i486SX/16", CPU_i486SX, 16000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2}, + {"i486SX/20", CPU_i486SX, 20000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/25", CPU_i486SX, 25000000, 1, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/33", CPU_i486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, + {"i486SX2/50", CPU_i486SX, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8}, + {"i486DX/25", CPU_i486DX, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486DX/33", CPU_i486DX, 33333333, 1, 0x414, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, + {"i486DX/50", CPU_i486DX, 50000000, 1, 0x411, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6}, + {"i486DX2/40", CPU_i486DX, 40000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, + {"i486DX2/50", CPU_i486DX, 50000000, 2, 0x433, 0x433, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486DX2/66", CPU_i486DX, 66666666, 2, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, + {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*Only added the DX4 OverDrive as the others would be redundant*/ + {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} +}; +CPU cpus_Am486S1[] = { + /*Am486*/ + {"Am486SX/33", CPU_Am486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486SX/40", CPU_Am486SX, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486SX2/50", CPU_Am486SX2, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX2, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ + {"Am486DX/33", CPU_Am486DX, 33333333, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486DX/40", CPU_Am486DX, 40000000, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486DX2/50", CPU_Am486DX2, 50000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Am486DX2/66", CPU_Am486DX2, 66666666, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486DX2/80", CPU_Am486DX2, 80000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +CPU cpus_Cx486S1[] = { + /*Cyrix 486*/ + {"Cx486S/25", CPU_Cx486S, 25000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"Cx486S/33", CPU_Cx486S, 33333333, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486S/40", CPU_Cx486S, 40000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX/33", CPU_Cx486DX, 33333333, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486DX/40", CPU_Cx486DX, 40000000, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX2/50", CPU_Cx486DX2, 50000000, 2, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Cx486DX2/66", CPU_Cx486DX2, 66666666, 2, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Cx486DX2/80", CPU_Cx486DX2, 80000000, 2, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_i486[] = { + /*i486/P24T*/ + {"i486SX/16", CPU_i486SX, 16000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2}, + {"i486SX/20", CPU_i486SX, 20000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/25", CPU_i486SX, 25000000, 1, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/33", CPU_i486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, + {"i486SX2/50", CPU_i486SX, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8}, + {"i486DX/25", CPU_i486DX, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486DX/33", CPU_i486DX, 33333333, 1, 0x414, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, + {"i486DX/50", CPU_i486DX, 50000000, 1, 0x411, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6}, + {"i486DX2/40", CPU_i486DX, 40000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, + {"i486DX2/50", CPU_i486DX, 50000000, 2, 0x433, 0x433, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486DX2/66", CPU_i486DX, 66666666, 2, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, + {"iDX4/75", CPU_iDX4, 75000000, 3, 0x480, 0x480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/ + {"iDX4/100", CPU_iDX4, 100000000, 3, 0x483, 0x483, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ + {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, + {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, + {"Pentium OverDrive 63", CPU_PENTIUM, 62500000, 5/2, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, + {"Pentium OverDrive 83", CPU_PENTIUM, 83333333, 5/2, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} +}; + +CPU cpus_Am486[] = { + /*Am486/5x86*/ + {"Am486SX/33", CPU_Am486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486SX/40", CPU_Am486SX, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486SX2/50", CPU_Am486SX2, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX2, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486DX/33", CPU_Am486DX, 33333333, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486DX/40", CPU_Am486DX, 40000000, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486DX2/50", CPU_Am486DX2, 50000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Am486DX2/66", CPU_Am486DX2, 66666666, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486DX2/80", CPU_Am486DX2, 80000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"Am486DX4/75", CPU_Am486DX4, 75000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, + {"Am486DX4/90", CPU_Am486DX4, 90000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + {"Am486DX4/100", CPU_Am486DX4, 100000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + {"Am486DX4/120", CPU_Am486DX4, 120000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15}, + {"Am5x86/P75", CPU_Am5x86, 133333333, 4, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, + {"Am5x86/P75+", CPU_Am5x86, 150000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/ + {"Am5x86/P90", CPU_Am5x86, 160000000, 4, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/ + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Cx486[] = { + /*Cyrix 486*/ + {"Cx486S/25", CPU_Cx486S, 25000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"Cx486S/33", CPU_Cx486S, 33333333, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486S/40", CPU_Cx486S, 40000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX/33", CPU_Cx486DX, 33333333, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486DX/40", CPU_Cx486DX, 40000000, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX2/50", CPU_Cx486DX2, 50000000, 2, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Cx486DX2/66", CPU_Cx486DX2, 66666666, 2, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Cx486DX2/80", CPU_Cx486DX2, 80000000, 2, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"Cx486DX4/75", CPU_Cx486DX4, 75000000, 3, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, + {"Cx486DX4/100", CPU_Cx486DX4, 100000000, 3, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + + /*Cyrix 5x86*/ + {"Cx5x86/80", CPU_Cx5x86, 80000000, 2, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, /*If we're including the Pentium 50, might as well include this*/ + {"Cx5x86/100", CPU_Cx5x86, 100000000, 3, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + {"Cx5x86/120", CPU_Cx5x86, 120000000, 3, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15}, + {"Cx5x86/133", CPU_Cx5x86, 133333333, 4, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) +CPU cpus_6x863V[] = { + /*Cyrix 6x86*/ + {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_6x86[] = { + /*Cyrix 6x86*/ + {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86L*/ + {"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86MX/MII*/ + {"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, + {"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"MII/PR300", CPU_Cx6x86MX, 233333333, 7/2, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, + {"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }; +#endif + +#ifdef USE_NEW_DYNAREC + CPU cpus_6x86SS7[] = { + /*Cyrix 6x86*/ + {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86L*/ + {"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86MX/MII*/ + {"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, + {"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"MII/PR300", CPU_Cx6x86MX, 233333333, 7/2, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, + {"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, + {"MII/PR366", CPU_Cx6x86MX, 250000000, 5/2, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, + {"MII/PR400", CPU_Cx6x86MX, 285000000, 3, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, + {"MII/PR433", CPU_Cx6x86MX, 300000000, 3, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }; +#endif + +CPU cpus_WinChip[] = { + /*IDT WinChip*/ + {"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, + {"WinChip 90", CPU_WINCHIP, 90000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2}, + {"WinChip 100", CPU_WINCHIP, 100000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12}, + {"WinChip 120", CPU_WINCHIP, 120000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14}, + {"WinChip 133", CPU_WINCHIP, 133333333, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16}, + {"WinChip 150", CPU_WINCHIP, 150000000, 5/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2}, + {"WinChip 166", CPU_WINCHIP, 166666666, 5/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40}, + {"WinChip 180", CPU_WINCHIP, 180000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21}, + {"WinChip 200", CPU_WINCHIP, 200000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 225", CPU_WINCHIP, 225000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 240", CPU_WINCHIP, 240000000, 4, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, +#ifdef USE_NEW_DYNAREC + {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, (7*8)/2}, +#endif + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +#ifdef USE_NEW_DYNAREC +CPU cpus_WinChip_SS7[] = { + /*IDT WinChip*/ + {"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, + {"WinChip 90", CPU_WINCHIP, 90000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2}, + {"WinChip 100", CPU_WINCHIP, 100000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12}, + {"WinChip 120", CPU_WINCHIP, 120000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14}, + {"WinChip 133", CPU_WINCHIP, 133333333, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16}, + {"WinChip 150", CPU_WINCHIP, 150000000, 5/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2}, + {"WinChip 166", CPU_WINCHIP, 166666666, 5/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40}, + {"WinChip 180", CPU_WINCHIP, 180000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21}, + {"WinChip 200", CPU_WINCHIP, 200000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 225", CPU_WINCHIP, 225000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 240", CPU_WINCHIP, 240000000, 4, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, + {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, + {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*9}, + {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, + {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, (7*8)/2}, + {"WinChip 2A/266", CPU_WINCHIP2, 233333333, 7/3, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 7, 7, 28}, + {"WinChip 2A/300", CPU_WINCHIP2, 250000000, 5/2, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 8, 8, 30}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif + +CPU cpus_Pentium5V[] = { + /*Intel Pentium (5V, socket 4)*/ + {"Pentium 60", CPU_PENTIUM, 60000000, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7}, + {"Pentium 66", CPU_PENTIUM, 66666666, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8}, + {"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Pentium5V50[] = { + /*Intel Pentium (5V, socket 4, including 50 MHz FSB)*/ + {"Pentium 50 (Q0399)", CPU_PENTIUM, 50000000, 1, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4,3,3, 6}, + {"Pentium 60", CPU_PENTIUM, 60000000, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7}, + {"Pentium 66", CPU_PENTIUM, 66666666, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8}, + {"Pentium OverDrive 100", CPU_PENTIUM, 100000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8,6,6, 12}, + {"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_PentiumS5[] = { + /*Intel Pentium (Socket 5)*/ + {"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, + {"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12}, + {"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, + {"Pentium 120", CPU_PENTIUM, 120000000, 2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + + /*Intel Pentium OverDrive*/ + {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 16}, + {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 40}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Pentium3V[] = { + /*Intel Pentium*/ + {"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"Pentium 120", CPU_PENTIUM, 120000000, 2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Pentium 133", CPU_PENTIUM, 133333333, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Pentium 150", CPU_PENTIUM, 150000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium 166", CPU_PENTIUM, 166666666, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium 200", CPU_PENTIUM, 200000000, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*Intel Pentium OverDrive*/ + {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Pentium[] = { + /*Intel Pentium*/ + {"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"Pentium 120", CPU_PENTIUM, 120000000, 2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Pentium 133", CPU_PENTIUM, 133333333, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Pentium 150", CPU_PENTIUM, 150000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium 166", CPU_PENTIUM, 166666666, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium 200", CPU_PENTIUM, 200000000, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*Intel Pentium MMX*/ + {"Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + + /*Mobile Pentium*/ + {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 120000000, 2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 133333333, 2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 150000000, 5/2, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 266666666, 4, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 300000000, 9/2, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + + /*Intel Pentium OverDrive*/ + {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) +CPU cpus_K5[] = { + /*AMD K5 (Socket 5)*/ + {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, + {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, + {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, + {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, + {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_K56[] = { + /*AMD K5 (Socket 7)*/ + {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*AMD K6 (Socket 7*/ + {"K6 (Model 6) 166", CPU_K6, 166666666, 5/2, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K6 (Model 6) 200", CPU_K6, 200000000, 3, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 6) 233", CPU_K6, 233333333, 7/2, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, + {"K6 (Model 7) 200", CPU_K6, 200000000, 3, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, + {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, + {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, +#ifdef USE_NEW_DYNAREC + {"K6-2/233", CPU_K6_2, 233333333, 7/2, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, 266666666, 4, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, + {"K6-2/300 AFR-66", CPU_K6_2, 300000000, 9/2, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, + {"K6-2/366", CPU_K6_2, 366666666, 11/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33, 17, 17, 44}, +#endif + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif + +#ifdef USE_NEW_DYNAREC +CPU cpus_K56_SS7[] = { + /*AMD K5 (Socket 7)*/ + {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*AMD K6 (Socket 7)*/ + {"K6 (Model 6) 166", CPU_K6, 166666666, 5/2, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K6 (Model 6) 200", CPU_K6, 200000000, 3, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 6) 233", CPU_K6, 233333333, 7/2, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6 (Model 7) 200", CPU_K6, 200000000, 3, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + + /*AMD K6-2 (Socket 7/Super Socket 7)*/ + {"K6-2/233", CPU_K6_2, 233333333, 7/2, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, 266666666, 4, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, + {"K6-2/300", CPU_K6_2, 300000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36}, + {"K6-2/333", CPU_K6_2, 332500000, 7/2, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40}, + {"K6-2/350", CPU_K6_2C, 350000000, 7/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42}, + {"K6-2/366", CPU_K6_2C, 366666666, 11/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44}, + {"K6-2/380", CPU_K6_2C, 380000000, 4, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46}, + {"K6-2/400", CPU_K6_2C, 400000000, 4, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-2/450", CPU_K6_2C, 450000000, 9/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-2/475", CPU_K6_2C, 475000000, 5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-2/500", CPU_K6_2C, 500000000, 5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"K6-2/533", CPU_K6_2C, 533333333, 11/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, + {"K6-2/550", CPU_K6_2C, 550000000, 11/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, + + /*AMD K6-2+/K6-3/K6-3+ (Super Socket 7)*/ + {"K6-2+/450", CPU_K6_2P, 450000000, 9/2, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-2+/475", CPU_K6_2P, 475000000, 5, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-2+/500", CPU_K6_2P, 500000000, 5, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"K6-2+/533", CPU_K6_2P, 533333333, 11/2, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, + {"K6-2+/550", CPU_K6_2P, 550000000, 11/2, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, + {"K6-III/400", CPU_K6_3, 400000000, 4, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-III/450", CPU_K6_3, 450000000, 9/2, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-III+/400", CPU_K6_3P, 400000000, 4, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-III+/450", CPU_K6_3P, 450000000, 9/2, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-III+/475", CPU_K6_3P, 475000000, 5, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-III+/500", CPU_K6_3P, 500000000, 5, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif + +#ifdef DEV_BRANCH +#ifdef USE_I686 +CPU cpus_PentiumPro[] = { + /*Intel Pentium Pro*/ + {"Pentium Pro 50", CPU_PENTIUMPRO, 50000000, 1, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium Pro 60" , CPU_PENTIUMPRO, 60000000, 1, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium Pro 66" , CPU_PENTIUMPRO, 66666666, 1, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium Pro 75", CPU_PENTIUMPRO, 75000000, 3/2, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium Pro 150", CPU_PENTIUMPRO, 150000000, 5/2, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium Pro 166", CPU_PENTIUMPRO, 166666666, 5/2, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium Pro 180", CPU_PENTIUMPRO, 180000000, 3, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, + {"Pentium Pro 200", CPU_PENTIUMPRO, 200000000, 3, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*Intel Pentium II OverDrive*/ + {"Pentium II Overdrive 50", CPU_PENTIUM2D, 50000000, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium II Overdrive 60", CPU_PENTIUM2D, 60000000, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium II Overdrive 66", CPU_PENTIUM2D, 66666666, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium II Overdrive 75", CPU_PENTIUM2D, 75000000, 3/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Overdrive 210", CPU_PENTIUM2D, 210000000, 7/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"Pentium II Overdrive 233", CPU_PENTIUM2D, 233333333, 7/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"Pentium II Overdrive 240", CPU_PENTIUM2D, 240000000, 4, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29}, + {"Pentium II Overdrive 266", CPU_PENTIUM2D, 266666666, 4, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"Pentium II Overdrive 270", CPU_PENTIUM2D, 270000000, 9/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 33}, + {"Pentium II Overdrive 300/66", CPU_PENTIUM2D, 300000000, 9/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + {"Pentium II Overdrive 300/60", CPU_PENTIUM2D, 300000000, 5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"Pentium II Overdrive 333", CPU_PENTIUM2D, 333333333, 5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_PentiumII[] = { + /*Intel Pentium II Klamath*/ + {"Pentium II Klamath 50", CPU_PENTIUM2, 50000000, 1, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium II Klamath 60", CPU_PENTIUM2, 60000000, 1, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium II Klamath 66", CPU_PENTIUM2, 66666666, 1, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium II Klamath 75", CPU_PENTIUM2, 75000000, 3/2, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Klamath 233", CPU_PENTIUM2, 233333333, 7/2, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"Pentium II Klamath 266", CPU_PENTIUM2, 266666666, 4, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29}, + {"Pentium II Klamath 300/66", CPU_PENTIUM2, 300000000, 9/2, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + + /*Intel Pentium II Deschutes*/ + {"Pentium II Deschutes 50", CPU_PENTIUM2D, 50000000, 1, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium II Deschutes 60", CPU_PENTIUM2D, 60000000, 1, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium II Deschutes 66", CPU_PENTIUM2D, 66666666, 1, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium II Deschutes 75", CPU_PENTIUM2D, 75000000, 3/2, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Deschutes 266", CPU_PENTIUM2D, 266666666, 4, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29}, + {"Pentium II Deschutes 300/66", CPU_PENTIUM2D, 300000000, 9/2, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + {"Pentium II Deschutes 333", CPU_PENTIUM2D, 333333333, 5, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"Pentium II Deschutes 350", CPU_PENTIUM2D, 350000000, 7/2, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32,32,11,11, 42}, + {"Pentium II Deschutes 400", CPU_PENTIUM2D, 400000000, 4, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48}, + {"Pentium II Deschutes 450", CPU_PENTIUM2D, 450000000, 9/2, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41,41,14,14, 54}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +}; + +CPU cpus_PGA370[] = { + {"Celeron Mendocino 100", CPU_PENTIUM2D, 100000000, 3/2, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Celeron Mendocino 333", CPU_PENTIUM2D, 333333333, 5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif +#endif +CPU cpus_Cyrix3[] = { + /*VIA Cyrix III (Samuel)*/ + {"Cyrix III 66", CPU_CYRIX3S, 66666666, 1, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 8}, /*66 MHz version*/ + {"Cyrix III 233", CPU_CYRIX3S, 233333333, 3.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, 28}, + {"Cyrix III 266", CPU_CYRIX3S, 266666666, 4, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 32}, + {"Cyrix III 300", CPU_CYRIX3S, 300000000, 4.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 27, 27, 13, 13, 36}, + {"Cyrix III 333", CPU_CYRIX3S, 333333333, 5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 30, 30, 15, 15, 40}, + {"Cyrix III 350", CPU_CYRIX3S, 350000000, 3.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 32, 32, 11, 11, 42}, + {"Cyrix III 400", CPU_CYRIX3S, 400000000, 4, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 36, 36, 12, 12, 48}, + {"Cyrix III 450", CPU_CYRIX3S, 450000000, 4.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 41, 41, 14, 14, 54}, /*^ is lower P2 speeds to allow emulation below 466 mhz*/ + {"Cyrix III 500", CPU_CYRIX3S, 500000000, 5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 45, 45, 15, 15, 60}, + {"Cyrix III 550", CPU_CYRIX3S, 550000000, 5.5, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 50, 50, 17, 17, 66}, + {"Cyrix III 600", CPU_CYRIX3S, 600000000, 6, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 54, 54, 18, 18, 72}, + {"Cyrix III 650", CPU_CYRIX3S, 650000000, 6.5, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 58, 58, 20, 20, 78}, + {"Cyrix III 700", CPU_CYRIX3S, 700000000, 7, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 62, 62, 21, 21, 84}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; \ No newline at end of file diff --git a/src/cpu/x86.h b/src/cpu_common/x86.h similarity index 96% rename from src/cpu/x86.h rename to src/cpu_common/x86.h index cf664a8b1..e3505a2e2 100644 --- a/src/cpu/x86.h +++ b/src/cpu_common/x86.h @@ -1,7 +1,3 @@ -#ifdef USE_NEW_DYNAREC -#include "../cpu_new/x86.h" -#else - extern uint8_t opcode, opcode2; extern uint8_t flags_p; extern uint8_t znptable8[256]; @@ -72,4 +68,3 @@ extern void x86_doabrt(int x86_abrt); extern void x86illegal(); extern void x86seg_reset(); extern void x86gpf(char *s, uint16_t error); -#endif diff --git a/src/cpu_new/x86_ops.h b/src/cpu_common/x86_ops.h similarity index 96% rename from src/cpu_new/x86_ops.h rename to src/cpu_common/x86_ops.h index 0de3b3252..34d1bcb24 100644 --- a/src/cpu_new/x86_ops.h +++ b/src/cpu_common/x86_ops.h @@ -85,13 +85,19 @@ extern const OpFn dynarec_ops_winchip2_0f[1024]; extern const OpFn dynarec_ops_pentium_0f[1024]; extern const OpFn dynarec_ops_pentiummmx_0f[1024]; -extern const OpFn dynarec_ops_c6x86mx_0f[1024]; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) +extern const OpFn dynarec_ops_c6x86mx_0f[1024]; +#endif + +#ifdef USE_NEW_DYNAREC extern const OpFn dynarec_ops_k6_0f[1024]; extern const OpFn dynarec_ops_k62_0f[1024]; +#endif #if defined(DEV_BRANCH) && defined(USE_I686) extern const OpFn dynarec_ops_pentiumpro_0f[1024]; +extern const OpFn dynarec_ops_pentium2_0f[1024]; extern const OpFn dynarec_ops_pentium2d_0f[1024]; #endif @@ -179,13 +185,18 @@ extern const OpFn ops_winchip2_0f[1024]; extern const OpFn ops_pentium_0f[1024]; extern const OpFn ops_pentiummmx_0f[1024]; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) extern const OpFn ops_c6x86mx_0f[1024]; +#endif +#ifdef USE_NEW_DYNAREC extern const OpFn ops_k6_0f[1024]; extern const OpFn ops_k62_0f[1024]; +#endif #if defined(DEV_BRANCH) && defined(USE_I686) extern const OpFn ops_pentiumpro_0f[1024]; +extern const OpFn ops_pentium2_0f[1024]; extern const OpFn ops_pentium2d_0f[1024]; #endif diff --git a/src/cpu_common/x86_ops_3dnow.h b/src/cpu_common/x86_ops_3dnow.h new file mode 100644 index 000000000..c578c400a --- /dev/null +++ b/src/cpu_common/x86_ops_3dnow.h @@ -0,0 +1,346 @@ +#include + +static int opPREFETCH_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + + CLOCK_CYCLES(1); + return 0; +} +static int opPREFETCH_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + + CLOCK_CYCLES(1); + return 0; +} + +static int opFEMMS(uint32_t fetchdat) +{ + ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); + if (cr0 & 0xc) + { + x86_int(7); + return 1; + } + x87_emms(); + CLOCK_CYCLES(1); + return 0; +} + +static int opPAVGUSB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; + + return 0; +} +static int opPF2ID(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sl[0] = (int32_t)src.f[0]; + cpu_state.MM[cpu_reg].sl[1] = (int32_t)src.f[1]; + + return 0; +} +static int opPFACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int opPFADD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] += src.f[0]; + cpu_state.MM[cpu_reg].f[1] += src.f[1]; + + return 0; +} +static int opPFCMPEQ(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int opPFCMPGE(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int opPFCMPGT(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int opPFMAX(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFMIN(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFMUL(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] *= src.f[0]; + cpu_state.MM[cpu_reg].f[1] *= src.f[1]; + + return 0; +} +static int opPFRCP(uint32_t fetchdat) +{ + union + { + uint32_t i; + float f; + } src; + + if (cpu_mod == 3) + { + src.f = cpu_state.MM[cpu_rm].f[0]; + CLOCK_CYCLES(1); + } + else + { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); + } + + cpu_state.MM[cpu_reg].f[0] = 1.0/src.f; + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + + return 0; +} +/*Since opPFRCP() calculates a full precision reciprocal, treat the followup iterations as MOVs*/ +static int opPFRCPIT1(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFRCPIT2(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFRSQRT(uint32_t fetchdat) +{ + union + { + uint32_t i; + float f; + } src; + + if (cpu_mod == 3) + { + src.f = cpu_state.MM[cpu_rm].f[0]; + CLOCK_CYCLES(1); + } + else + { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); + } + + cpu_state.MM[cpu_reg].f[0] = 1.0/sqrt(src.f); + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + + return 0; +} +/*Since opPFRSQRT() calculates a full precision inverse square root, treat the followup iteration as a NOP*/ +static int opPFRSQIT1(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + UN_USED(src); + + return 0; +} +static int opPFSUB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] -= src.f[0]; + cpu_state.MM[cpu_reg].f[1] -= src.f[1]; + + return 0; +} +static int opPFSUBR(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; + + return 0; +} +static int opPI2FD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = (float)src.sl[0]; + cpu_state.MM[cpu_reg].f[1] = (float)src.sl[1]; + + return 0; +} +static int opPMULHRW(uint32_t fetchdat) +{ + if (cpu_mod == 3) + { + cpu_state.MM[cpu_reg].w[0] = (((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = (((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = (((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = (((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(1); + } + else + { + MMX_REG src; + + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t)(cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t)(cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t)(cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t)(cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(2); + } + return 0; +} + +const OpFn OP_TABLE(3DNOW)[256] = +{ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FD, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2ID, ILLEGAL, ILLEGAL, +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*90*/ opPFCMPGE, ILLEGAL, ILLEGAL, ILLEGAL, opPFMIN, ILLEGAL, opPFRCP, opPFRSQRT, ILLEGAL, ILLEGAL, opPFSUB, ILLEGAL, ILLEGAL, ILLEGAL, opPFADD, ILLEGAL, +/*a0*/ opPFCMPGT, ILLEGAL, ILLEGAL, ILLEGAL, opPFMAX, ILLEGAL, opPFRCPIT1, opPFRSQIT1, ILLEGAL, ILLEGAL, opPFSUBR, ILLEGAL, ILLEGAL, ILLEGAL, opPFACC, ILLEGAL, +/*b0*/ opPFCMPEQ, ILLEGAL, ILLEGAL, ILLEGAL, opPFMUL, ILLEGAL, opPFRCPIT2, opPMULHRW, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPAVGUSB, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + +static int op3DNOW_a16(uint32_t fetchdat) +{ + uint8_t opcode; + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + + return x86_opcodes_3DNOW[opcode](0); +} +static int op3DNOW_a32(uint32_t fetchdat) +{ + uint8_t opcode; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + + return x86_opcodes_3DNOW[opcode](0); +} diff --git a/src/cpu_common/x86_ops_amd.h b/src/cpu_common/x86_ops_amd.h new file mode 100644 index 000000000..8f003e1fb --- /dev/null +++ b/src/cpu_common/x86_ops_amd.h @@ -0,0 +1,192 @@ +/* + * 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. + * + * AMD SYSCALL and SYSRET CPU Instructions. + * + * Version: @(#)x86_ops_amd.h 1.0.4 2018/10/17 + * + * Author: Miran Grca, + * Copyright 2016-2018 Miran Grca. + */ + +/* 0 = Limit 0-15 + 1 = Base 0-15 + 2 = Base 16-23 (bits 0-7), Access rights + 8-11 Type + 12 S + 13, 14 DPL + 15 P + 3 = Limit 16-19 (bits 0-3), Base 24-31 (bits 8-15), granularity, etc. + 4 A + 6 DB + 7 G */ + +#define AMD_SYSCALL_EIP (star & 0xFFFFFFFF) +#define AMD_SYSCALL_SB ((star >> 32) & 0xFFFF) +#define AMD_SYSRET_SB ((star >> 48) & 0xFFFF) + +/* 0F 05 */ +static int opSYSCALL(uint32_t fetchdat) +{ + uint16_t syscall_cs_seg_data[4] = {0, 0, 0, 0}; + uint16_t syscall_ss_seg_data[4] = {0, 0, 0, 0}; + + if (!(cr0 & 1)) return internal_illegal("SYSCALL: CPU not in protected mode"); + if (!AMD_SYSCALL_SB) return internal_illegal("SYSCALL: AMD SYSCALL SB MSR is zero"); + + /* Set VM, IF, RF to 0. */ + /* cpu_state.eflags &= ~0x00030200; + cpu_state.flags &= ~0x0200; */ + + /* Let's do this by the AMD spec. */ + ECX = cpu_state.pc; + + cpu_state.eflags &= ~0x0002; + cpu_state.flags &= ~0x0200; + + /* CS */ + cpu_state.seg_cs.seg = AMD_SYSCALL_SB & ~7; + if (AMD_SYSCALL_SB & 4) + { + if (cpu_state.seg_cs.seg >= ldt.limit) + { + x386_dynarec_log("Bigger than LDT limit %04X %04X CS\n",AMD_SYSCALL_SB,ldt.limit); + x86gpf(NULL, AMD_SYSCALL_SB & ~3); + return 1; + } + cpu_state.seg_cs.seg +=ldt.base; + } + else + { + if (cpu_state.seg_cs.seg >= gdt.limit) + { + x386_dynarec_log("Bigger than GDT limit %04X %04X CS\n",AMD_SYSCALL_SB,gdt.limit); + x86gpf(NULL, AMD_SYSCALL_SB & ~3); + return 1; + } + cpu_state.seg_cs.seg += gdt.base; + } + cpl_override = 1; + + syscall_cs_seg_data[0] = 0xFFFF; + syscall_cs_seg_data[1] = 0; + syscall_cs_seg_data[2] = 0x9B00; + syscall_cs_seg_data[3] = 0xC0; + + cpl_override = 0; + + use32 = 0x300; + CS = (AMD_SYSCALL_SB & ~3) | 0; + + do_seg_load(&cpu_state.seg_cs, syscall_cs_seg_data); + use32 = 0x300; + + CS = (CS & 0xFFFC) | 0; + + cpu_state.seg_cs.limit = 0xFFFFFFFF; + cpu_state.seg_cs.limit_high = 0xFFFFFFFF; + + /* SS */ + syscall_ss_seg_data[0] = 0xFFFF; + syscall_ss_seg_data[1] = 0; + syscall_ss_seg_data[2] = 0x9300; + syscall_ss_seg_data[3] = 0xC0; + do_seg_load(&cpu_state.seg_ss, syscall_ss_seg_data); + cpu_state.seg_ss.seg = (AMD_SYSCALL_SB + 8) & 0xFFFC; + stack32 = 1; + + cpu_state.seg_ss.limit = 0xFFFFFFFF; + cpu_state.seg_ss.limit_high = 0xFFFFFFFF; + + cpu_state.seg_ss.checked = 0; + + cpu_state.pc = AMD_SYSCALL_EIP; + + CLOCK_CYCLES(20); + + CPU_BLOCK_END(); + + return 0; +} + +/* 0F 07 */ +static int opSYSRET(uint32_t fetchdat) +{ + uint16_t sysret_cs_seg_data[4] = {0, 0, 0, 0}; + uint16_t sysret_ss_seg_data[4] = {0, 0, 0, 0}; + + if (!AMD_SYSRET_SB) return internal_illegal("SYSRET: CS MSR is zero"); + if (!(cr0 & 1)) return internal_illegal("SYSRET: CPU not in protected mode"); + + cpu_state.pc = ECX; + + cpu_state.eflags |= (1 << 1); + + /* CS */ + cpu_state.seg_cs.seg = AMD_SYSRET_SB & ~7; + if (AMD_SYSRET_SB & 4) + { + if (cpu_state.seg_cs.seg >= ldt.limit) + { + x386_dynarec_log("Bigger than LDT limit %04X %04X CS\n",AMD_SYSRET_SB,ldt.limit); + x86gpf(NULL, AMD_SYSRET_SB & ~3); + return 1; + } + cpu_state.seg_cs.seg +=ldt.base; + } + else + { + if (cpu_state.seg_cs.seg >= gdt.limit) + { + x386_dynarec_log("Bigger than GDT limit %04X %04X CS\n",AMD_SYSRET_SB,gdt.limit); + x86gpf(NULL, AMD_SYSRET_SB & ~3); + return 1; + } + cpu_state.seg_cs.seg += gdt.base; + } + cpl_override = 1; + + sysret_cs_seg_data[0] = 0xFFFF; + sysret_cs_seg_data[1] = 0; + sysret_cs_seg_data[2] = 0xFB00; + sysret_cs_seg_data[3] = 0xC0; + + cpl_override = 0; + + use32 = 0x300; + CS = (AMD_SYSRET_SB & ~3) | 3; + + do_seg_load(&cpu_state.seg_cs, sysret_cs_seg_data); + flushmmucache_cr3(); + use32 = 0x300; + + CS = (CS & 0xFFFC) | 3; + + cpu_state.seg_cs.limit = 0xFFFFFFFF; + cpu_state.seg_cs.limit_high = 0xFFFFFFFF; + + /* SS */ + sysret_ss_seg_data[0] = 0xFFFF; + sysret_ss_seg_data[1] = 0; + sysret_ss_seg_data[2] = 0xF300; + sysret_ss_seg_data[3] = 0xC0; + do_seg_load(&cpu_state.seg_ss, sysret_ss_seg_data); + cpu_state.seg_ss.seg = ((AMD_SYSRET_SB + 8) & 0xFFFC) | 3; + stack32 = 1; + + cpu_state.seg_ss.limit = 0xFFFFFFFF; + cpu_state.seg_ss.limit_high = 0xFFFFFFFF; + + cpu_state.seg_ss.checked = 0; + + CLOCK_CYCLES(20); + + CPU_BLOCK_END(); + + return 0; +} diff --git a/src/cpu/x86_ops_arith.h b/src/cpu_common/x86_ops_arith.h similarity index 99% rename from src/cpu/x86_ops_arith.h rename to src/cpu_common/x86_ops_arith.h index 80a0da788..489fd5e57 100644 --- a/src/cpu/x86_ops_arith.h +++ b/src/cpu_common/x86_ops_arith.h @@ -718,6 +718,8 @@ static int op81_l_a16(uint32_t fetchdat) uint32_t src, dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getlong(); if (cpu_state.abrt) return 1; ARITH_MULTI(l, 32); if ((rmdat & 0x38) == 0x38) diff --git a/src/cpu/x86_ops_atomic.h b/src/cpu_common/x86_ops_atomic.h similarity index 92% rename from src/cpu/x86_ops_atomic.h rename to src/cpu_common/x86_ops_atomic.h index c490d747a..4011a0aa4 100644 --- a/src/cpu/x86_ops_atomic.h +++ b/src/cpu_common/x86_ops_atomic.h @@ -8,7 +8,7 @@ static int opCMPXCHG_b_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; if (AL == temp) seteab(getr8(cpu_reg)); else AL = temp; @@ -27,7 +27,7 @@ static int opCMPXCHG_b_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; if (AL == temp) seteab(getr8(cpu_reg)); else AL = temp; @@ -47,7 +47,7 @@ static int opCMPXCHG_w_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); else AX = temp; @@ -66,7 +66,7 @@ static int opCMPXCHG_w_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); else AX = temp; @@ -86,7 +86,7 @@ static int opCMPXCHG_l_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); else EAX = temp; @@ -105,7 +105,7 @@ static int opCMPXCHG_l_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); else EAX = temp; @@ -125,7 +125,7 @@ static int opCMPXCHG8B_a16(uint32_t fetchdat) return 0; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; if (EAX == temp && EDX == temp_hi) @@ -143,7 +143,7 @@ static int opCMPXCHG8B_a16(uint32_t fetchdat) if (temp == temp2 && temp_hi == temp2_hi) cpu_state.flags |= Z_FLAG; else - cpu_state.flags &= ~Z_FLAG; + cpu_state.flags &= ~Z_FLAG; cycles -= (cpu_mod == 3) ? 6 : 10; return 0; } @@ -157,7 +157,7 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat) return 0; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; if (EAX == temp && EDX == temp_hi) @@ -175,7 +175,7 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat) if (temp == temp2 && temp_hi == temp2_hi) cpu_state.flags |= Z_FLAG; else - cpu_state.flags &= ~Z_FLAG; + cpu_state.flags &= ~Z_FLAG; cycles -= (cpu_mod == 3) ? 6 : 10; return 0; } @@ -190,7 +190,7 @@ static int opXADD_b_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1; setadd8(temp, getr8(cpu_reg)); @@ -208,7 +208,7 @@ static int opXADD_b_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1; setadd8(temp, getr8(cpu_reg)); @@ -227,7 +227,7 @@ static int opXADD_w_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; setadd16(temp, cpu_state.regs[cpu_reg].w); @@ -245,7 +245,7 @@ static int opXADD_w_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; setadd16(temp, cpu_state.regs[cpu_reg].w); @@ -264,7 +264,7 @@ static int opXADD_l_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; setadd32(temp, cpu_state.regs[cpu_reg].l); @@ -282,7 +282,7 @@ static int opXADD_l_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; setadd32(temp, cpu_state.regs[cpu_reg].l); diff --git a/src/cpu_new/x86_ops_bcd.h b/src/cpu_common/x86_ops_bcd.h similarity index 100% rename from src/cpu_new/x86_ops_bcd.h rename to src/cpu_common/x86_ops_bcd.h diff --git a/src/cpu/x86_ops_bit.h b/src/cpu_common/x86_ops_bit.h similarity index 94% rename from src/cpu/x86_ops_bit.h rename to src/cpu_common/x86_ops_bit.h index 42d9aa4aa..df2d48619 100644 --- a/src/cpu/x86_ops_bit.h +++ b/src/cpu_common/x86_ops_bit.h @@ -3,12 +3,12 @@ static int opBT_w_r_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; temp = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 0); @@ -19,12 +19,12 @@ static int opBT_w_r_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; temp = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 1); @@ -35,12 +35,12 @@ static int opBT_l_r_a16(uint32_t fetchdat) uint32_t temp; fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; temp = geteal(); if (cpu_state.abrt) return 1; flags_rebuild(); if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 0); @@ -51,12 +51,12 @@ static int opBT_l_r_a32(uint32_t fetchdat) uint32_t temp; fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; temp = geteal(); if (cpu_state.abrt) return 1; flags_rebuild(); if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 1); @@ -161,7 +161,7 @@ static int opBA_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); - + temp = geteaw(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); @@ -185,7 +185,6 @@ static int opBA_w_a16(uint32_t fetchdat) break; default: - x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -205,7 +204,7 @@ static int opBA_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); - + temp = geteaw(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); @@ -229,7 +228,6 @@ static int opBA_w_a32(uint32_t fetchdat) break; default: - x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -250,7 +248,7 @@ static int opBA_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); - + temp = geteal(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); @@ -274,7 +272,6 @@ static int opBA_l_a16(uint32_t fetchdat) break; default: - x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -294,7 +291,7 @@ static int opBA_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); - + temp = geteal(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); @@ -318,7 +315,6 @@ static int opBA_l_a32(uint32_t fetchdat) break; default: - x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; diff --git a/src/cpu_new/x86_ops_bitscan.h b/src/cpu_common/x86_ops_bitscan.h similarity index 99% rename from src/cpu_new/x86_ops_bitscan.h rename to src/cpu_common/x86_ops_bitscan.h index 01d9c5795..46f0fc605 100644 --- a/src/cpu_new/x86_ops_bitscan.h +++ b/src/cpu_common/x86_ops_bitscan.h @@ -73,7 +73,7 @@ static int opBSF_l_a16(uint32_t fetchdat) static int opBSF_l_a32(uint32_t fetchdat) { uint32_t temp; - int instr_cycles = 0; + int instr_cycles = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) diff --git a/src/cpu/x86_ops_flag.h b/src/cpu_common/x86_ops_flag.h similarity index 98% rename from src/cpu/x86_ops_flag.h rename to src/cpu_common/x86_ops_flag.h index 8441b4987..099f2e35f 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu_common/x86_ops_flag.h @@ -99,7 +99,7 @@ static int opSAHF(uint32_t fetchdat) CLOCK_CYCLES(3); PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); -#if 0 +#ifdef USE_NEW_DYNAREC codegen_flags_changed = 0; #endif @@ -182,7 +182,7 @@ static int opPOPF_286(uint32_t fetchdat) CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); -#if 0 +#ifdef USE_NEW_DYNAREC codegen_flags_changed = 0; #endif @@ -242,7 +242,7 @@ static int opPOPF(uint32_t fetchdat) CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); -#if 0 +#ifdef USE_NEW_DYNAREC codegen_flags_changed = 0; #endif @@ -276,7 +276,7 @@ static int opPOPFD(uint32_t fetchdat) CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); -#if 0 +#ifdef USE_NEW_DYNAREC codegen_flags_changed = 0; #endif diff --git a/src/cpu_new/x86_ops_fpu.h b/src/cpu_common/x86_ops_fpu.h similarity index 96% rename from src/cpu_new/x86_ops_fpu.h rename to src/cpu_common/x86_ops_fpu.h index 8c264374f..a1976f268 100644 --- a/src/cpu_new/x86_ops_fpu.h +++ b/src/cpu_common/x86_ops_fpu.h @@ -1,3 +1,6 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ static int opESCAPE_d8_a16(uint32_t fetchdat) { return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); diff --git a/src/cpu/x86_ops_i686.h b/src/cpu_common/x86_ops_i686.h similarity index 96% rename from src/cpu/x86_ops_i686.h rename to src/cpu_common/x86_ops_i686.h index 6d4cf7484..2b34e0822 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu_common/x86_ops_i686.h @@ -8,10 +8,10 @@ * * x86 i686 (Pentium Pro/Pentium II) CPU Instructions. * - * Version: @(#)x86_ops_i686.h 1.0.5 2018/10/17 + * Version: @(#)x86_ops_i686.h 1.0.6 2020/01/27 * * Author: Miran Grca, - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2020 Miran Grca. */ /* 0 = Limit 0-15 @@ -63,8 +63,8 @@ static int opSYSENTER(uint32_t fetchdat) cgate16 = cgate32 = 0; \ /* Set VM, RF, and IF to 0. */ - cpu_state.eflags &= ~(VM_FLAG | 0x0001); - cpu_state.flags &= ~I_FLAG; + cpu_state.eflags &= ~0x0003; + cpu_state.flags &= ~0x0200; CS = (cs_msr & 0xFFFC); make_seg_data(sysenter_cs_seg_data, 0, 0xFFFFF, 11, 1, 0, 1, 1, 1, 0); @@ -190,8 +190,14 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) { /* FXRSTOR */ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif fpus = readmemw(easeg, cpu_state.eaaddr + 2); cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.TOP = (fpus >> 11) & 7; cpu_state.npxs &= fpus & ~0x3800; @@ -314,6 +320,9 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) cpu_state.eaaddr = old_eaaddr; cpu_state.npxc = 0x37F; +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; @@ -368,8 +377,14 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) { /* FXRSTOR */ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif fpus = readmemw(easeg, cpu_state.eaaddr + 2); cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.TOP = (fpus >> 11) & 7; cpu_state.npxs &= fpus & ~0x3800; @@ -492,6 +507,9 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) cpu_state.eaaddr = old_eaaddr; cpu_state.npxc = 0x37F; +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; diff --git a/src/cpu_new/x86_ops_inc_dec.h b/src/cpu_common/x86_ops_inc_dec.h similarity index 97% rename from src/cpu_new/x86_ops_inc_dec.h rename to src/cpu_common/x86_ops_inc_dec.h index d14bae863..ff4a4ab73 100644 --- a/src/cpu_new/x86_ops_inc_dec.h +++ b/src/cpu_common/x86_ops_inc_dec.h @@ -49,7 +49,7 @@ static int opINCDEC_b_a16(uint32_t fetchdat) { uint8_t temp; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); temp=geteab(); if (cpu_state.abrt) return 1; @@ -72,7 +72,7 @@ static int opINCDEC_b_a32(uint32_t fetchdat) { uint8_t temp; - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); temp=geteab(); if (cpu_state.abrt) return 1; diff --git a/src/cpu_new/x86_ops_int.h b/src/cpu_common/x86_ops_int.h similarity index 100% rename from src/cpu_new/x86_ops_int.h rename to src/cpu_common/x86_ops_int.h diff --git a/src/cpu_new/x86_ops_io.h b/src/cpu_common/x86_ops_io.h similarity index 100% rename from src/cpu_new/x86_ops_io.h rename to src/cpu_common/x86_ops_io.h diff --git a/src/cpu/x86_ops_jump.h b/src/cpu_common/x86_ops_jump.h similarity index 90% rename from src/cpu/x86_ops_jump.h rename to src/cpu_common/x86_ops_jump.h index 6eb9862af..c227939a3 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu_common/x86_ops_jump.h @@ -23,6 +23,8 @@ if (cond_ ## condition) \ { \ cpu_state.pc += offset; \ + if (!(cpu_state.op32 & 0x100)) \ + cpu_state.pc &= 0xffff; \ CLOCK_CYCLES_ALWAYS(timing_bt); \ CPU_BLOCK_END(); \ PREFETCH_RUN(timing_bt+timing_bnt, 2, -1, 0,0,0,0, 0); \ @@ -40,6 +42,7 @@ if (cond_ ## condition) \ { \ cpu_state.pc += offset; \ + cpu_state.pc &= 0xffff; \ CLOCK_CYCLES_ALWAYS(timing_bt); \ CPU_BLOCK_END(); \ PREFETCH_RUN(timing_bt+timing_bnt, 3, -1, 0,0,0,0, 0); \ @@ -95,6 +98,8 @@ static int opLOOPNE_w(uint32_t fetchdat) if (CX && !ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -110,6 +115,8 @@ static int opLOOPNE_l(uint32_t fetchdat) if (ECX && !ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -126,6 +133,8 @@ static int opLOOPE_w(uint32_t fetchdat) if (CX && ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -141,6 +150,8 @@ static int opLOOPE_l(uint32_t fetchdat) if (ECX && ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -157,6 +168,8 @@ static int opLOOP_w(uint32_t fetchdat) if (CX) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -172,6 +185,8 @@ static int opLOOP_l(uint32_t fetchdat) if (ECX) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -186,6 +201,8 @@ static int opJCXZ(uint32_t fetchdat) if (!CX) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CLOCK_CYCLES(4); CPU_BLOCK_END(); PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); @@ -202,6 +219,8 @@ static int opJECXZ(uint32_t fetchdat) if (!ECX) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CLOCK_CYCLES(4); CPU_BLOCK_END(); PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); @@ -217,6 +236,8 @@ static int opJMP_r8(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); CLOCK_CYCLES((is486) ? 3 : 7); PREFETCH_RUN(7, 2, -1, 0,0,0,0, 0); @@ -227,6 +248,7 @@ static int opJMP_r16(uint32_t fetchdat) { int16_t offset = (int16_t)getwordf(); cpu_state.pc += offset; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); CLOCK_CYCLES((is486) ? 3 : 7); PREFETCH_RUN(7, 3, -1, 0,0,0,0, 0); @@ -278,6 +300,7 @@ static int opCALL_r16(uint32_t fetchdat) int16_t addr = (int16_t)getwordf(); PUSH_W(cpu_state.pc); cpu_state.pc += addr; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); CLOCK_CYCLES((is486) ? 3 : 7); PREFETCH_RUN(7, 3, -1, 0,0,1,0, 0); diff --git a/src/cpu_new/x86_ops_misc.h b/src/cpu_common/x86_ops_misc.h similarity index 99% rename from src/cpu_new/x86_ops_misc.h rename to src/cpu_common/x86_ops_misc.h index e49825a5f..91118211b 100644 --- a/src/cpu_new/x86_ops_misc.h +++ b/src/cpu_common/x86_ops_misc.h @@ -616,7 +616,7 @@ static int opHLT(uint32_t fetchdat) { CLOCK_CYCLES_ALWAYS(100); if (!((cpu_state.flags & I_FLAG) && pic_intpending)) - cpu_state.pc--; + cpu_state.pc--; } else CLOCK_CYCLES(5); @@ -964,6 +964,7 @@ static int opRSM(uint32_t fetchdat) { leave_smm(); if(smi_latched) enter_smm(); + CPU_BLOCK_END(); return 0; } cpu_state.pc = cpu_state.oldpc; diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu_common/x86_ops_mmx.h similarity index 95% rename from src/cpu/x86_ops_mmx.h rename to src/cpu_common/x86_ops_mmx.h index 107710f77..f9a7f9357 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu_common/x86_ops_mmx.h @@ -11,7 +11,7 @@ } \ else \ { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \ CLOCK_CYCLES(2); \ } @@ -38,7 +38,7 @@ static int opEMMS(uint32_t fetchdat) x86illegal(); return 1; } - if (cr0 & 4) + if (cr0 & 0xc) { x86_int(7); return 1; diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu_common/x86_ops_mmx_arith.h similarity index 99% rename from src/cpu/x86_ops_mmx_arith.h rename to src/cpu_common/x86_ops_mmx_arith.h index e8e1f31e5..22c34c738 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu_common/x86_ops_mmx_arith.h @@ -321,7 +321,7 @@ static int opPMULLW_a32(uint32_t fetchdat) else { MMX_REG src; - + SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; @@ -350,8 +350,8 @@ static int opPMULHW_a16(uint32_t fetchdat) else { MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; @@ -378,8 +378,8 @@ static int opPMULHW_a32(uint32_t fetchdat) else { MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; diff --git a/src/cpu_new/x86_ops_mmx_cmp.h b/src/cpu_common/x86_ops_mmx_cmp.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_cmp.h rename to src/cpu_common/x86_ops_mmx_cmp.h diff --git a/src/cpu_new/x86_ops_mmx_logic.h b/src/cpu_common/x86_ops_mmx_logic.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_logic.h rename to src/cpu_common/x86_ops_mmx_logic.h diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu_common/x86_ops_mmx_mov.h similarity index 92% rename from src/cpu/x86_ops_mmx_mov.h rename to src/cpu_common/x86_ops_mmx_mov.h index a742941ea..e17721229 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu_common/x86_ops_mmx_mov.h @@ -12,8 +12,8 @@ static int opMOVD_l_mm_a16(uint32_t fetchdat) else { uint32_t dst; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].l[0] = dst; cpu_state.MM[cpu_reg].l[1] = 0; @@ -36,8 +36,8 @@ static int opMOVD_l_mm_a32(uint32_t fetchdat) else { uint32_t dst; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].l[0] = dst; cpu_state.MM[cpu_reg].l[1] = 0; @@ -59,7 +59,7 @@ static int opMOVD_mm_l_a16(uint32_t fetchdat) } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); @@ -78,7 +78,7 @@ static int opMOVD_mm_l_a32(uint32_t fetchdat) } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); @@ -100,7 +100,7 @@ static int opMOVQ_q_mm_a16(uint32_t fetchdat) { uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].q = dst; CLOCK_CYCLES(2); @@ -120,8 +120,8 @@ static int opMOVQ_q_mm_a32(uint32_t fetchdat) else { uint64_t dst; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].q = dst; CLOCK_CYCLES(2); @@ -141,7 +141,7 @@ static int opMOVQ_mm_q_a16(uint32_t fetchdat) } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu_common/x86_ops_mmx_pack.h similarity index 98% rename from src/cpu/x86_ops_mmx_pack.h rename to src/cpu_common/x86_ops_mmx_pack.h index 170aa0e42..b03ef842e 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu_common/x86_ops_mmx_pack.h @@ -12,7 +12,7 @@ static int opPUNPCKLDQ_a16(uint32_t fetchdat) { uint32_t src; - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].l[1] = src; @@ -33,8 +33,8 @@ static int opPUNPCKLDQ_a32(uint32_t fetchdat) else { uint32_t src; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].l[1] = src; diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu_common/x86_ops_mmx_shift.h similarity index 97% rename from src/cpu/x86_ops_mmx_shift.h rename to src/cpu_common/x86_ops_mmx_shift.h index edfe16276..a0a4d90c1 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu_common/x86_ops_mmx_shift.h @@ -6,7 +6,7 @@ } \ else \ { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ CLOCK_CYCLES(2); \ } @@ -53,7 +53,6 @@ static int opPSxxW_imm(uint32_t fetchdat) } break; default: - x386_dynarec_log("Bad PSxxW (0F 71) instruction %02X\n", op); cpu_state.pc = cpu_state.oldpc; x86illegal(); return 0; @@ -224,7 +223,6 @@ static int opPSxxD_imm(uint32_t fetchdat) } break; default: - x386_dynarec_log("Bad PSxxD (0F 72) instruction %02X\n", op); cpu_state.pc = cpu_state.oldpc; x86illegal(); return 0; @@ -376,7 +374,6 @@ static int opPSxxQ_imm(uint32_t fetchdat) cpu_state.MM[reg].q <<= shift; break; default: - x386_dynarec_log("Bad PSxxQ (0F 73) instruction %02X\n", op); cpu_state.pc = cpu_state.oldpc; x86illegal(); return 0; diff --git a/src/cpu/x86_ops_mov.h b/src/cpu_common/x86_ops_mov.h similarity index 99% rename from src/cpu/x86_ops_mov.h rename to src/cpu_common/x86_ops_mov.h index cf9bb82c0..dd49465bc 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu_common/x86_ops_mov.h @@ -688,7 +688,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat) return 0; } -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) #define opCMOV(condition) \ static int opCMOV ## condition ## _w_a16(uint32_t fetchdat) \ { \ diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu_common/x86_ops_mov_ctrl.h similarity index 88% rename from src/cpu/x86_ops_mov_ctrl.h rename to src/cpu_common/x86_ops_mov_ctrl.h index becb0e095..06a89884b 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu_common/x86_ops_mov_ctrl.h @@ -2,7 +2,6 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from CRx\n"); x86gpf(NULL, 0); return 1; } @@ -27,7 +26,6 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat) break; } default: - x386_dynarec_log("Bad read of CR%i %i\n",rmdat&7,cpu_reg); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -40,7 +38,6 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from CRx\n"); x86gpf(NULL, 0); return 1; } @@ -65,7 +62,6 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat) break; } default: - x386_dynarec_log("Bad read of CR%i %i\n",rmdat&7,cpu_reg); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -79,7 +75,6 @@ static int opMOV_r_DRx_a16(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from DRx\n"); x86gpf(NULL, 0); return 1; } @@ -93,7 +88,6 @@ static int opMOV_r_DRx_a32(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from DRx\n"); x86gpf(NULL, 0); return 1; } @@ -110,7 +104,6 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load CRx\n"); x86gpf(NULL,0); return 1; } @@ -127,11 +120,11 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) mmu_perm=4; if (is486 && !(cr0 & (1 << 30))) cpu_cache_int_enabled = 1; - else if (isibmcpu) - cpu_cache_int_enabled = 1; + else if (isibmcpu) + cpu_cache_int_enabled = 1; else - cpu_cache_int_enabled = 0; - if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_cache_int_enabled = 0; + if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) cpu_update_waitstates(); if (cr0 & 1) cpu_cur_status |= CPU_STATUS_PMODE; @@ -153,7 +146,6 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) } default: - x386_dynarec_log("Bad load CR%i\n", cpu_reg); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -168,7 +160,6 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat) if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load CRx\n"); x86gpf(NULL,0); return 1; } @@ -209,7 +200,6 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat) } default: - x386_dynarec_log("Bad load CR%i\n", cpu_reg); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -223,7 +213,6 @@ static int opMOV_DRx_r_a16(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load DRx\n"); x86gpf(NULL, 0); return 1; } @@ -237,7 +226,6 @@ static int opMOV_DRx_r_a32(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load DRx\n"); x86gpf(NULL, 0); return 1; } @@ -252,7 +240,6 @@ static int opMOV_r_TRx_a16(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from TRx\n"); x86gpf(NULL, 0); return 1; } @@ -266,7 +253,6 @@ static int opMOV_r_TRx_a32(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from TRx\n"); x86gpf(NULL, 0); return 1; } @@ -281,7 +267,6 @@ static int opMOV_TRx_r_a16(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load TRx\n"); x86gpf(NULL, 0); return 1; } @@ -294,7 +279,6 @@ static int opMOV_TRx_r_a32(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load TRx\n"); x86gpf(NULL, 0); return 1; } diff --git a/src/cpu_new/x86_ops_mov_seg.h b/src/cpu_common/x86_ops_mov_seg.h similarity index 100% rename from src/cpu_new/x86_ops_mov_seg.h rename to src/cpu_common/x86_ops_mov_seg.h diff --git a/src/cpu_new/x86_ops_movx.h b/src/cpu_common/x86_ops_movx.h similarity index 100% rename from src/cpu_new/x86_ops_movx.h rename to src/cpu_common/x86_ops_movx.h diff --git a/src/cpu_new/x86_ops_msr.h b/src/cpu_common/x86_ops_msr.h similarity index 100% rename from src/cpu_new/x86_ops_msr.h rename to src/cpu_common/x86_ops_msr.h diff --git a/src/cpu_new/x86_ops_mul.h b/src/cpu_common/x86_ops_mul.h similarity index 96% rename from src/cpu_new/x86_ops_mul.h rename to src/cpu_common/x86_ops_mul.h index f3e10e5a0..a96ce54a2 100644 --- a/src/cpu_new/x86_ops_mul.h +++ b/src/cpu_common/x86_ops_mul.h @@ -6,7 +6,7 @@ static int opIMUL_w_iw_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getword(); if (cpu_state.abrt) return 1; @@ -28,7 +28,7 @@ static int opIMUL_w_iw_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getword(); if (cpu_state.abrt) return 1; @@ -51,7 +51,7 @@ static int opIMUL_l_il_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getlong(); if (cpu_state.abrt) return 1; @@ -73,7 +73,7 @@ static int opIMUL_l_il_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getlong(); if (cpu_state.abrt) return 1; @@ -96,7 +96,7 @@ static int opIMUL_w_ib_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getbyte(); if (cpu_state.abrt) return 1; if (tempw2 & 0x80) tempw2 |= 0xff00; @@ -119,7 +119,7 @@ static int opIMUL_w_ib_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getbyte(); if (cpu_state.abrt) return 1; if (tempw2 & 0x80) tempw2 |= 0xff00; @@ -142,8 +142,8 @@ static int opIMUL_l_ib_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getbyte(); if (cpu_state.abrt) return 1; if (templ2 & 0x80) templ2 |= 0xffffff00; @@ -165,8 +165,8 @@ static int opIMUL_l_ib_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getbyte(); if (cpu_state.abrt) return 1; if (templ2 & 0x80) templ2 |= 0xffffff00; @@ -209,8 +209,8 @@ static int opIMUL_w_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - + SEG_CHECK_READ(cpu_state.ea_seg); + templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = templ & 0xFFFF; @@ -229,8 +229,8 @@ static int opIMUL_l_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; @@ -248,8 +248,8 @@ static int opIMUL_l_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu_common/x86_ops_pmode.h similarity index 94% rename from src/cpu/x86_ops_pmode.h rename to src/cpu_common/x86_ops_pmode.h index cdf89d98d..7fe5d4938 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu_common/x86_ops_pmode.h @@ -4,10 +4,8 @@ static int opARPL_a16(uint32_t fetchdat) NOTRM fetch_ea_16(fetchdat); - /* x386_dynarec_log("ARPL_a16\n"); */ if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - + SEG_CHECK_WRITE(cpu_state.ea_seg); temp_seg = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); @@ -30,10 +28,8 @@ static int opARPL_a32(uint32_t fetchdat) NOTRM fetch_ea_32(fetchdat); - /* x386_dynarec_log("ARPL_a32\n"); */ if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - + SEG_CHECK_WRITE(cpu_state.ea_seg); temp_seg = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); @@ -55,12 +51,12 @@ static int opARPL_a32(uint32_t fetchdat) static int opLAR_ ## name(uint32_t fetchdat) \ { \ int valid; \ - uint16_t sel, desc = 0; \ + uint16_t sel, desc = 0; \ \ NOTRM \ fetch_ea(fetchdat); \ if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ \ sel = geteaw(); if (cpu_state.abrt) return 1; \ \ @@ -107,7 +103,7 @@ opLAR(l_a32, fetch_ea_32, 1, 1) static int opLSL_ ## name(uint32_t fetchdat) \ { \ int valid; \ - uint16_t sel, desc = 0; \ + uint16_t sel, desc = 0; \ \ NOTRM \ fetch_ea(fetchdat); \ @@ -169,7 +165,6 @@ static int op0F00_common(uint32_t fetchdat, int ea32) uint16_t desc, sel; uint8_t access; - /* x386_dynarec_log("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ switch (rmdat & 0x38) { case 0x00: /*SLDT*/ @@ -189,7 +184,6 @@ static int op0F00_common(uint32_t fetchdat, int ea32) case 0x10: /*LLDT*/ if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { - x386_dynarec_log("Invalid LLDT!\n"); x86gpf(NULL,0); return 1; } @@ -217,7 +211,6 @@ static int op0F00_common(uint32_t fetchdat, int ea32) case 0x18: /*LTR*/ if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { - x386_dynarec_log("Invalid LTR!\n"); x86gpf(NULL,0); break; } @@ -289,7 +282,6 @@ static int op0F00_common(uint32_t fetchdat, int ea32) break; default: - x386_dynarec_log("Bad 0F 00 opcode %02X\n", rmdat & 0x38); cpu_state.pc -= 3; x86illegal(); break; @@ -318,14 +310,13 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) { uint32_t base; uint16_t limit, tempw; - /* x386_dynarec_log("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ switch (rmdat & 0x38) { case 0x00: /*SGDT*/ if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(gdt.limit); - base = gdt.base; /* is32 ? gdt.base : (gdt.base & 0xffffff); */ + base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff); if (is286) base |= 0xff000000; writememl(easeg, cpu_state.eaaddr + 2, base); @@ -346,16 +337,13 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) case 0x10: /*LGDT*/ if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { - x386_dynarec_log("Invalid LGDT!\n"); x86gpf(NULL,0); break; } - /* x386_dynarec_log("LGDT %08X:%08X\n", easeg, eaaddr); */ if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); limit = geteaw(); base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - /* x386_dynarec_log(" %08X %04X\n", base, limit); */ gdt.limit = limit; gdt.base = base; if (!is32) gdt.base &= 0xffffff; @@ -365,16 +353,13 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) case 0x18: /*LIDT*/ if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { - x386_dynarec_log("Invalid LIDT!\n"); x86gpf(NULL,0); break; } - /* x386_dynarec_log("LIDT %08X:%08X\n", easeg, eaaddr); */ if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); limit = geteaw(); base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - /* x386_dynarec_log(" %08X %04X\n", base, limit); */ idt.limit = limit; idt.base = base; if (!is32) idt.base &= 0xffffff; @@ -394,7 +379,6 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) case 0x30: /*LMSW*/ if ((CPL || cpu_state.eflags&VM_FLAG) && (msw&1)) { - x386_dynarec_log("LMSW - ring not zero!\n"); x86gpf(NULL, 0); break; } @@ -421,11 +405,10 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) { if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { - x386_dynarec_log("Invalid INVLPG!\n"); x86gpf(NULL, 0); break; } - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); mmu_invalidate(ds + cpu_state.eaaddr); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, rmdat, 0,0,0,0, ea32); @@ -433,7 +416,6 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) } default: - x386_dynarec_log("Bad 0F 01 opcode %02X\n", rmdat & 0x38); cpu_state.pc -= 3; x86illegal(); break; diff --git a/src/cpu_new/x86_ops_prefix.h b/src/cpu_common/x86_ops_prefix.h similarity index 100% rename from src/cpu_new/x86_ops_prefix.h rename to src/cpu_common/x86_ops_prefix.h diff --git a/src/cpu_new/x86_ops_rep.h b/src/cpu_common/x86_ops_rep.h similarity index 100% rename from src/cpu_new/x86_ops_rep.h rename to src/cpu_common/x86_ops_rep.h diff --git a/src/cpu_new/x86_ops_ret.h b/src/cpu_common/x86_ops_ret.h similarity index 96% rename from src/cpu_new/x86_ops_ret.h rename to src/cpu_common/x86_ops_ret.h index 133c6153b..1ebe67b9c 100644 --- a/src/cpu_new/x86_ops_ret.h +++ b/src/cpu_common/x86_ops_ret.h @@ -1,9 +1,16 @@ +#ifdef USE_NEW_DYNAREC +#define CPU_SET_OXPC +#else +#define CPU_SET_OXPC oxpc = cpu_state.pc; +#endif + #define RETF_a16(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ { \ pmoderetf(0, stack_offset); \ return 1; \ } \ + CPU_SET_OXPC \ if (stack32) \ { \ cpu_state.pc = readmemw(ss, ESP); \ @@ -14,7 +21,7 @@ cpu_state.pc = readmemw(ss, SP); \ loadcs(readmemw(ss, SP + 2)); \ } \ - if (cpu_state.abrt) return 1; \ + if (cpu_state.abrt) return 1; \ if (stack32) ESP += 4 + stack_offset; \ else SP += 4 + stack_offset; \ cycles -= timing_retf_rm; @@ -25,6 +32,7 @@ pmoderetf(1, stack_offset); \ return 1; \ } \ + CPU_SET_OXPC \ if (stack32) \ { \ cpu_state.pc = readmeml(ss, ESP); \ @@ -106,6 +114,7 @@ static int opIRET_286(uint32_t fetchdat) else { uint16_t new_cs; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmemw(ss, ESP); @@ -172,7 +181,7 @@ static int opIRET(uint32_t fetchdat) } else { - if (msw&1) + if (msw&1) { optype = IRET; pmodeiret(0); @@ -181,6 +190,7 @@ static int opIRET(uint32_t fetchdat) else { uint16_t new_cs; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmemw(ss, ESP); @@ -226,6 +236,7 @@ static int opIRETD(uint32_t fetchdat) else { uint16_t new_cs; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmeml(ss, ESP); diff --git a/src/cpu_new/x86_ops_set.h b/src/cpu_common/x86_ops_set.h similarity index 100% rename from src/cpu_new/x86_ops_set.h rename to src/cpu_common/x86_ops_set.h diff --git a/src/cpu/x86_ops_stack.h b/src/cpu_common/x86_ops_stack.h similarity index 97% rename from src/cpu/x86_ops_stack.h rename to src/cpu_common/x86_ops_stack.h index 20b0aa766..9ca1171a0 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu_common/x86_ops_stack.h @@ -278,9 +278,9 @@ static int opPOPL_a16(uint32_t fetchdat) temp = POP_L(); if (cpu_state.abrt) return 1; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(temp); if (cpu_state.abrt) { @@ -470,17 +470,17 @@ static int opLEAVE_l(uint32_t fetchdat) } -PUSH_SEG_OPS(CS) -PUSH_SEG_OPS(DS) -PUSH_SEG_OPS(ES) -PUSH_SEG_OPS(FS) -PUSH_SEG_OPS(GS) -PUSH_SEG_OPS(SS) +PUSH_SEG_OPS(CS); +PUSH_SEG_OPS(DS); +PUSH_SEG_OPS(ES); +PUSH_SEG_OPS(FS); +PUSH_SEG_OPS(GS); +PUSH_SEG_OPS(SS); -POP_SEG_OPS(DS, &cpu_state.seg_ds) -POP_SEG_OPS(ES, &cpu_state.seg_es) -POP_SEG_OPS(FS, &cpu_state.seg_fs) -POP_SEG_OPS(GS, &cpu_state.seg_gs) +POP_SEG_OPS(DS, &cpu_state.seg_ds); +POP_SEG_OPS(ES, &cpu_state.seg_es); +POP_SEG_OPS(FS, &cpu_state.seg_fs); +POP_SEG_OPS(GS, &cpu_state.seg_gs); static int opPOP_SS_w(uint32_t fetchdat) @@ -488,7 +488,7 @@ static int opPOP_SS_w(uint32_t fetchdat) uint16_t temp_seg; uint32_t temp_esp = ESP; temp_seg = POP_W(); if (cpu_state.abrt) return 1; - loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } CLOCK_CYCLES(is486 ? 3 : 7); PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); @@ -508,7 +508,7 @@ static int opPOP_SS_l(uint32_t fetchdat) uint32_t temp_seg; uint32_t temp_esp = ESP; temp_seg = POP_L(); if (cpu_state.abrt) return 1; - loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } CLOCK_CYCLES(is486 ? 3 : 7); PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); diff --git a/src/cpu/x86_ops_string.h b/src/cpu_common/x86_ops_string.h similarity index 85% rename from src/cpu/x86_ops_string.h rename to src/cpu_common/x86_ops_string.h index 41e368cc7..c02725138 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu_common/x86_ops_string.h @@ -7,7 +7,7 @@ static int opMOVSB_a16(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememb(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } + else { DI++; SI++; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); return 0; @@ -21,7 +21,7 @@ static int opMOVSB_a32(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememb(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } + else { EDI++; ESI++; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); return 0; @@ -36,7 +36,7 @@ static int opMOVSW_a16(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememw(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } + else { DI += 2; SI += 2; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); return 0; @@ -50,7 +50,7 @@ static int opMOVSW_a32(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememw(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } + else { EDI += 2; ESI += 2; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); return 0; @@ -65,7 +65,7 @@ static int opMOVSL_a16(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememl(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } + else { DI += 4; SI += 4; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,1, 0); return 0; @@ -79,7 +79,7 @@ static int opMOVSL_a32(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememl(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } + else { EDI += 4; ESI += 4; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,1, 1); return 0; @@ -96,7 +96,7 @@ static int opCMPSB_a16(uint32_t fetchdat) dst = readmemb(es, DI); if (cpu_state.abrt) return 1; setsub8(src, dst); if (cpu_state.flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } + else { DI++; SI++; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); return 0; @@ -111,7 +111,7 @@ static int opCMPSB_a32(uint32_t fetchdat) dst = readmemb(es, EDI); if (cpu_state.abrt) return 1; setsub8(src, dst); if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } + else { EDI++; ESI++; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); return 0; @@ -127,7 +127,7 @@ static int opCMPSW_a16(uint32_t fetchdat) dst = readmemw(es, DI); if (cpu_state.abrt) return 1; setsub16(src, dst); if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } + else { DI += 2; SI += 2; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); return 0; @@ -142,7 +142,7 @@ static int opCMPSW_a32(uint32_t fetchdat) dst = readmemw(es, EDI); if (cpu_state.abrt) return 1; setsub16(src, dst); if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } + else { EDI += 2; ESI += 2; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); return 0; @@ -158,7 +158,7 @@ static int opCMPSL_a16(uint32_t fetchdat) dst = readmeml(es, DI); if (cpu_state.abrt) return 1; setsub32(src, dst); if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } + else { DI += 4; SI += 4; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 0); return 0; @@ -173,7 +173,7 @@ static int opCMPSL_a32(uint32_t fetchdat) dst = readmeml(es, EDI); if (cpu_state.abrt) return 1; setsub32(src, dst); if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } + else { EDI += 4; ESI += 4; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 1); return 0; @@ -181,20 +181,20 @@ static int opCMPSL_a32(uint32_t fetchdat) static int opSTOSB_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememb(es, DI, AL); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI--; - else DI++; + else DI++; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); return 0; } static int opSTOSB_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememb(es, EDI, AL); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; + else EDI++; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); return 0; @@ -202,20 +202,20 @@ static int opSTOSB_a32(uint32_t fetchdat) static int opSTOSW_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememw(es, DI, AX); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; + else DI += 2; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); return 0; } static int opSTOSW_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememw(es, EDI, AX); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; + else EDI += 2; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); return 0; @@ -223,20 +223,20 @@ static int opSTOSW_a32(uint32_t fetchdat) static int opSTOSL_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememl(es, DI, EAX); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; + else DI += 4; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0); return 0; } static int opSTOSL_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; + else EDI += 4; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,0,1, 1); return 0; @@ -251,7 +251,7 @@ static int opLODSB_a16(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; AL = temp; if (cpu_state.flags & D_FLAG) SI--; - else SI++; + else SI++; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); return 0; @@ -264,7 +264,7 @@ static int opLODSB_a32(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; AL = temp; if (cpu_state.flags & D_FLAG) ESI--; - else ESI++; + else ESI++; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); return 0; @@ -278,7 +278,7 @@ static int opLODSW_a16(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; AX = temp; if (cpu_state.flags & D_FLAG) SI -= 2; - else SI += 2; + else SI += 2; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); return 0; @@ -291,7 +291,7 @@ static int opLODSW_a32(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; AX = temp; if (cpu_state.flags & D_FLAG) ESI -= 2; - else ESI += 2; + else ESI += 2; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); return 0; @@ -305,7 +305,7 @@ static int opLODSL_a16(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; EAX = temp; if (cpu_state.flags & D_FLAG) SI -= 4; - else SI += 4; + else SI += 4; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); return 0; @@ -318,7 +318,7 @@ static int opLODSL_a32(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; EAX = temp; if (cpu_state.flags & D_FLAG) ESI -= 4; - else ESI += 4; + else ESI += 4; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0,1,0,0, 1); return 0; @@ -333,7 +333,7 @@ static int opSCASB_a16(uint32_t fetchdat) temp = readmemb(es, DI); if (cpu_state.abrt) return 1; setsub8(AL, temp); if (cpu_state.flags & D_FLAG) DI--; - else DI++; + else DI++; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); return 0; @@ -346,7 +346,7 @@ static int opSCASB_a32(uint32_t fetchdat) temp = readmemb(es, EDI); if (cpu_state.abrt) return 1; setsub8(AL, temp); if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; + else EDI++; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); return 0; @@ -360,7 +360,7 @@ static int opSCASW_a16(uint32_t fetchdat) temp = readmemw(es, DI); if (cpu_state.abrt) return 1; setsub16(AX, temp); if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; + else DI += 2; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); return 0; @@ -373,7 +373,7 @@ static int opSCASW_a32(uint32_t fetchdat) temp = readmemw(es, EDI); if (cpu_state.abrt) return 1; setsub16(AX, temp); if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; + else EDI += 2; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); return 0; @@ -387,7 +387,7 @@ static int opSCASL_a16(uint32_t fetchdat) temp = readmeml(es, DI); if (cpu_state.abrt) return 1; setsub32(EAX, temp); if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; + else DI += 4; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,0, 0); return 0; @@ -400,7 +400,7 @@ static int opSCASL_a32(uint32_t fetchdat) temp = readmeml(es, EDI); if (cpu_state.abrt) return 1; setsub32(EAX, temp); if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; + else EDI += 4; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,0, 1); return 0; @@ -409,13 +409,13 @@ static int opSCASL_a32(uint32_t fetchdat) static int opINSB_a16(uint32_t fetchdat) { uint8_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); temp = inb(DX); writememb(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI--; - else DI++; + else DI++; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); return 0; @@ -423,13 +423,13 @@ static int opINSB_a16(uint32_t fetchdat) static int opINSB_a32(uint32_t fetchdat) { uint8_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); temp = inb(DX); writememb(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; + else EDI++; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); return 0; @@ -438,14 +438,14 @@ static int opINSB_a32(uint32_t fetchdat) static int opINSW_a16(uint32_t fetchdat) { uint16_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); temp = inw(DX); writememw(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; + else DI += 2; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); return 0; @@ -453,14 +453,14 @@ static int opINSW_a16(uint32_t fetchdat) static int opINSW_a32(uint32_t fetchdat) { uint16_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); temp = inw(DX); writememw(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; + else EDI += 2; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); return 0; @@ -469,8 +469,8 @@ static int opINSW_a32(uint32_t fetchdat) static int opINSL_a16(uint32_t fetchdat) { uint32_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); @@ -478,7 +478,7 @@ static int opINSL_a16(uint32_t fetchdat) temp = inl(DX); writememl(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; + else DI += 4; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 0,1,0,1, 0); return 0; @@ -486,8 +486,8 @@ static int opINSL_a16(uint32_t fetchdat) static int opINSL_a32(uint32_t fetchdat) { uint32_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); @@ -495,7 +495,7 @@ static int opINSL_a32(uint32_t fetchdat) temp = inl(DX); writememl(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; + else EDI += 4; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 0,1,0,1, 1); return 0; @@ -509,7 +509,7 @@ static int opOUTSB_a16(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; check_io_perm(DX); if (cpu_state.flags & D_FLAG) SI--; - else SI++; + else SI++; outb(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); @@ -523,7 +523,7 @@ static int opOUTSB_a32(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; check_io_perm(DX); if (cpu_state.flags & D_FLAG) ESI--; - else ESI++; + else ESI++; outb(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); @@ -539,7 +539,7 @@ static int opOUTSW_a16(uint32_t fetchdat) check_io_perm(DX); check_io_perm(DX + 1); if (cpu_state.flags & D_FLAG) SI -= 2; - else SI += 2; + else SI += 2; outw(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); @@ -554,7 +554,7 @@ static int opOUTSW_a32(uint32_t fetchdat) check_io_perm(DX); check_io_perm(DX + 1); if (cpu_state.flags & D_FLAG) ESI -= 2; - else ESI += 2; + else ESI += 2; outw(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); @@ -572,7 +572,7 @@ static int opOUTSL_a16(uint32_t fetchdat) check_io_perm(DX + 2); check_io_perm(DX + 3); if (cpu_state.flags & D_FLAG) SI -= 4; - else SI += 4; + else SI += 4; outl(EDX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 0,1,0,1, 0); @@ -589,7 +589,7 @@ static int opOUTSL_a32(uint32_t fetchdat) check_io_perm(DX + 2); check_io_perm(DX + 3); if (cpu_state.flags & D_FLAG) ESI -= 4; - else ESI += 4; + else ESI += 4; outl(EDX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 0,1,0,1, 1); diff --git a/src/cpu/x86_ops_xchg.h b/src/cpu_common/x86_ops_xchg.h similarity index 99% rename from src/cpu/x86_ops_xchg.h rename to src/cpu_common/x86_ops_xchg.h index 3880f70e7..6a787273e 100644 --- a/src/cpu/x86_ops_xchg.h +++ b/src/cpu_common/x86_ops_xchg.h @@ -1,6 +1,7 @@ static int opXCHG_b_a16(uint32_t fetchdat) { uint8_t temp; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -14,6 +15,7 @@ static int opXCHG_b_a16(uint32_t fetchdat) static int opXCHG_b_a32(uint32_t fetchdat) { uint8_t temp; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -28,6 +30,7 @@ static int opXCHG_b_a32(uint32_t fetchdat) static int opXCHG_w_a16(uint32_t fetchdat) { uint16_t temp; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -41,6 +44,7 @@ static int opXCHG_w_a16(uint32_t fetchdat) static int opXCHG_w_a32(uint32_t fetchdat) { uint16_t temp; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -55,6 +59,7 @@ static int opXCHG_w_a32(uint32_t fetchdat) static int opXCHG_l_a16(uint32_t fetchdat) { uint32_t temp; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -68,6 +73,7 @@ static int opXCHG_l_a16(uint32_t fetchdat) static int opXCHG_l_a32(uint32_t fetchdat) { uint32_t temp; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); diff --git a/src/cpu_new/x86seg.h b/src/cpu_common/x86seg.h similarity index 100% rename from src/cpu_new/x86seg.h rename to src/cpu_common/x86seg.h diff --git a/src/cpu/x87.c b/src/cpu_common/x87.c similarity index 64% rename from src/cpu/x87.c rename to src/cpu_common/x87.c index 5016661a3..8a5363cd8 100644 --- a/src/cpu/x87.c +++ b/src/cpu_common/x87.c @@ -6,10 +6,10 @@ #define fplog 0 #include #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" -#include "../pic.h" +#include "mem.h" +#include "pic.h" #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" @@ -37,6 +37,49 @@ fpu_log(const char *fmt, ...) #endif +#ifdef USE_NEW_DYNAREC +#define X87_TAG_VALID 0 +#define X87_TAG_ZERO 1 +#define X87_TAG_INVALID 2 +#define X87_TAG_EMPTY 3 + +uint16_t x87_gettag() +{ + uint16_t ret = 0; + int c; + + for (c = 0; c < 8; c++) + { + if (cpu_state.tag[c] == TAG_EMPTY) + ret |= X87_TAG_EMPTY << (c * 2); + else if (cpu_state.tag[c] & TAG_UINT64) + ret |= 2 << (c*2); + else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx) + ret |= X87_TAG_ZERO << (c * 2); + else + ret |= X87_TAG_VALID << (c * 2); + } + + return ret; +} + +void x87_settag(uint16_t new_tag) +{ + int c; + + for (c = 0; c < 8; c++) + { + int tag = (new_tag >> (c * 2)) & 3; + + if (tag == X87_TAG_EMPTY) + cpu_state.tag[c] = TAG_EMPTY; + else if (tag == 2) + cpu_state.tag[c] = TAG_VALID | TAG_UINT64; + else + cpu_state.tag[c] = TAG_VALID; + } +} +#else uint16_t x87_gettag() { uint16_t ret = 0; @@ -64,6 +107,7 @@ void x87_settag(uint16_t new_tag) cpu_state.tag[6] = (new_tag >> 12) & 3; cpu_state.tag[7] = (new_tag >> 14) & 3; } +#endif #ifdef ENABLE_808X_LOG diff --git a/src/cpu_common/x87.h b/src/cpu_common/x87.h new file mode 100644 index 000000000..be30c280c --- /dev/null +++ b/src/cpu_common/x87.h @@ -0,0 +1,58 @@ +#define C0 (1<<8) +#define C1 (1<<9) +#define C2 (1<<10) +#define C3 (1<<14) + +uint32_t x87_pc_off,x87_op_off; +uint16_t x87_pc_seg,x87_op_seg; + +static inline void x87_set_mmx() +{ +#ifdef USE_NEW_DYNAREC + cpu_state.TOP = 0; + *(uint64_t *)cpu_state.tag = 0x0101010101010101ull; + cpu_state.ismmx = 1; +#else + uint64_t *p; + cpu_state.TOP = 0; + p = (uint64_t *)cpu_state.tag; + *p = 0; + cpu_state.ismmx = 1; +#endif +} + +static inline void x87_emms() +{ +#ifdef USE_NEW_DYNAREC + *(uint64_t *)cpu_state.tag = 0; + cpu_state.ismmx = 0; +#else + uint64_t *p; + p = (uint64_t *)cpu_state.tag; + *p = 0; + cpu_state.ismmx = 0; +#endif +} + + +uint16_t x87_gettag(); +void x87_settag(uint16_t new_tag); + +#ifdef USE_NEW_DYNAREC +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) +/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ +#define TAG_UINT64 (1 << 7) + +#define X87_ROUNDING_NEAREST 0 +#define X87_ROUNDING_DOWN 1 +#define X87_ROUNDING_UP 2 +#define X87_ROUNDING_CHOP 3 + +void codegen_set_rounding_mode(int mode); +#else +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) +/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ +#define TAG_UINT64 (1 << 2) +#endif diff --git a/src/cpu/x87_ops.h b/src/cpu_common/x87_ops.h similarity index 97% rename from src/cpu/x87_ops.h rename to src/cpu_common/x87_ops.h index bf54afa40..239b449f2 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu_common/x87_ops.h @@ -25,6 +25,7 @@ #ifdef _MSC_VER # include #endif +// #include "x87_timings.h" #ifdef ENABLE_FPU_LOG extern void fpu_log(const char *fmt, ...); @@ -38,11 +39,6 @@ static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZ #define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)] -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) - #define STATUS_ZERODIVIDE 4 #ifdef FPU_8087 @@ -92,12 +88,18 @@ static __inline void x87_checkexceptions() static __inline void x87_push(double i) { +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP&7] = i; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#else cpu_state.TOP=(cpu_state.TOP-1)&7; cpu_state.ST[cpu_state.TOP] = i; cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? 1 : 0; +#endif } -static inline void x87_push_u64(uint64_t i) +static __inline void x87_push_u64(uint64_t i) { union { @@ -107,26 +109,62 @@ static inline void x87_push_u64(uint64_t i) td.ll = i; +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP&7] = td.d; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#else cpu_state.TOP=(cpu_state.TOP-1)&7; cpu_state.ST[cpu_state.TOP] = td.d; cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? 1 : 0; +#endif } static __inline double x87_pop() { +#ifdef USE_NEW_DYNAREC + double t = cpu_state.ST[cpu_state.TOP&7]; + cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY; + cpu_state.TOP++; + return t; +#else double t = cpu_state.ST[cpu_state.TOP]; cpu_state.tag[cpu_state.TOP&7] = 3; cpu_state.TOP=(cpu_state.TOP+1)&7; return t; +#endif } +static int old_round = FE_TONEAREST; + +static __inline void x87_round_save(void) +{ + old_round = fegetround(); +} + +static __inline void x87_round_set(void) +{ + old_round = fegetround(); + + fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); +} + +static __inline void x87_round_restore(void) +{ + fesetround(old_round); +} + +#ifdef PCEM_CODE static __inline int64_t x87_fround(double b) { +#ifdef PCEM_CODE int64_t a, c; +#endif - switch ((cpu_state.npxc>>10)&3) + switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ +#ifdef PCEM_CODE a = (int64_t)floor(b); c = (int64_t)floor(b + 1.0); if ((b - a) < (c - b)) @@ -135,16 +173,35 @@ static __inline int64_t x87_fround(double b) return c; else return (a & 1) ? c : a; +#else + return (int64_t)round(b); +#endif case 1: /*Down*/ return (int64_t)floor(b); case 2: /*Up*/ return (int64_t)ceil(b); case 3: /*Chop*/ +#ifdef PCEM_CODE return (int64_t)b; - default: - return (int64_t)0; +#else + return (int64_t)trunc(b); +#endif } + + return 0; } +#else +static __inline int64_t x87_fround(double b) +{ + int64_t ret; + + x87_round_set(); + ret = (int64_t) rint(b); + x87_round_restore(); + + return ret; +} +#endif #define BIAS80 16383 #define BIAS64 1023 @@ -155,6 +212,7 @@ static __inline double x87_ld80() int64_t exp64final; int64_t mant64; int64_t sign; + struct { int16_t begin; union @@ -163,6 +221,7 @@ static __inline double x87_ld80() uint64_t ll; } eind; } test; + test.eind.ll = readmeml(easeg,cpu_state.eaaddr); test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32; test.begin = readmemw(easeg,cpu_state.eaaddr+8); @@ -251,6 +310,17 @@ static __inline void x87_ld_frstor(int reg) cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); +#ifdef USE_NEW_DYNAREC + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) + { + cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; + } + else + { + cpu_state.tag[reg] &= ~TAG_UINT64; + cpu_state.ST[reg] = x87_ld80(); + } +#else if (cpu_state.MM_w4[reg] == 0x5555 && cpu_state.tag[reg] == 2) { cpu_state.tag[reg] = TAG_UINT64; @@ -258,6 +328,7 @@ static __inline void x87_ld_frstor(int reg) } else cpu_state.ST[reg] = x87_ld80(); +#endif } static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) @@ -338,7 +409,7 @@ static __inline uint16_t x87_compare(double a, double b) #endif } -static inline uint16_t x87_ucompare(double a, double b) +static __inline uint16_t x87_ucompare(double a, double b) { #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__ uint32_t result; @@ -412,6 +483,55 @@ typedef union } while (0) #endif +// #ifdef USE_NEW_DYNAREC +#if 1 +#define FP_TAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#define FP_FTAG() cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; +#define FP_LSTAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64; +#define FP_LSQ() cpu_state.MM[cpu_state.TOP&7].q = temp64; +#define FP_LSRETQ() temp64 = cpu_state.MM[cpu_state.TOP&7].q; +#define FP_NTAG() cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; +#ifdef USE_NEW_DYNAREC +#define FP_NNPXC() codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#else +#define FP_NNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); +#endif +#define FP_TOP(x) (x & 7) +#define FP_DTAG 0ULL +#define FP_CTAG 0x0101010101010101ull +#define FP_EMPTY TAG_EMPTY +#ifdef USE_NEW_DYNAREC +#define FP_RNPXC() codegen_set_rounding_mode(X87_ROUNDING_NEAREST); +#else +#define FP_RNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); +#endif +#define FP_ZTAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#define FP_DECTOP() cpu_state.TOP--; +#define FP_INCTOP() cpu_state.TOP++; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +#define FP_686 +#endif +#else +#define FP_TAG() cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; +#define FP_FTAG() cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; +#define FP_LSTAG() cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; +#define FP_LSQ() cpu_state.MM[cpu_state.TOP].q = temp64; +#define FP_LSRETQ() temp64 = cpu_state.MM[cpu_state.TOP].q; +#define FP_NTAG() cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; +#define FP_NNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); +#define FP_TOP(x) (x) +#define FP_DTAG 0x0303030303030303ll +#define FP_CTAG 0ULL +#define FP_EMPTY 3 +#define FP_RNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); +#define FP_ZTAG() cpu_state.tag[cpu_state.TOP&7] = 1; +#define FP_DECTOP() cpu_state.TOP = (cpu_state.TOP - 1) & 7 +#define FP_INCTOP() cpu_state.TOP = (cpu_state.TOP + 1) & 7 +#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#define FP_686 +#endif +#endif + #include "x87_ops_arith.h" #include "x87_ops_misc.h" #include "x87_ops_loadstore.h" @@ -1050,7 +1170,7 @@ const OpFn OP_TABLE(fpu_da_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) const OpFn OP_TABLE(fpu_686_da_a16)[256] = { opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, @@ -1283,7 +1403,7 @@ const OpFn OP_TABLE(fpu_db_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) const OpFn OP_TABLE(fpu_686_db_a16)[256] = { opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, @@ -1856,7 +1976,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) const OpFn OP_TABLE(fpu_686_df_a16)[256] = { opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, diff --git a/src/cpu_common/x87_ops_arith.h b/src/cpu_common/x87_ops_arith.h new file mode 100644 index 000000000..e90761ca1 --- /dev/null +++ b/src/cpu_common/x87_ops_arith.h @@ -0,0 +1,435 @@ +#define opFPU(name, optype, a_size, load_var, get, use_var) \ +static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + ST(0) += use_var; \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(8); \ + return 0; \ +} \ +static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + cpu_state.npxs &= ~(C0|C2|C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ + CLOCK_CYCLES(4); \ + return 0; \ +} \ +static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + cpu_state.npxs &= ~(C0|C2|C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ + x87_pop(); \ + CLOCK_CYCLES(4); \ + return 0; \ +} \ +static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + x87_div(ST(0), ST(0), use_var); \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(73); \ + return 0; \ +} \ +static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + x87_div(ST(0), use_var, ST(0)); \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(73); \ + return 0; \ +} \ +static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + ST(0) *= use_var; \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(11); \ + return 0; \ +} \ +static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + ST(0) -= use_var; \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(8); \ + return 0; \ +} \ +static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + ST(0) = use_var - ST(0); \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(8); \ + return 0; \ +} + + +opFPU(s, x87_ts, 16, t.i, geteal, t.s) +#ifndef FPU_8087 +opFPU(s, x87_ts, 32, t.i, geteal, t.s) +#endif +opFPU(d, x87_td, 16, t.i, geteaq, t.d) +#ifndef FPU_8087 +opFPU(d, x87_td, 32, t.i, geteaq, t.d) +#endif + +opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t) +#ifndef FPU_8087 +opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t) +#endif +opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t) +#ifndef FPU_8087 +opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t) +#endif + + + + +static int opFADD(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) + ST(fetchdat & 7); + FP_TAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFADDr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); + FP_FTAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFADDP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(8); + return 0; +} + +static int opFCOM(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0; + CLOCK_CYCLES(4); + return 0; +} + +static int opFCOMP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); + x87_pop(); + CLOCK_CYCLES(4); + return 0; +} + +static int opFCOMPP(uint32_t fetchdat) +{ + uint64_t *p, *q; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + p = (uint64_t *)&ST(0); + q = (uint64_t *)&ST(1); + if ((*p == ((uint64_t)1 << 63) && *q == 0) && is386) + cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ + else + cpu_state.npxs |= x87_compare(ST(0), ST(1)); + + x87_pop(); + x87_pop(); + CLOCK_CYCLES(4); + return 0; +} +#ifndef FPU_8087 +static int opFUCOMPP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); + x87_pop(); + x87_pop(); + CLOCK_CYCLES(5); + return 0; +} + +#ifdef FP_686 +static int opFCOMI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(4); + return 0; +} +static int opFCOMIP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES(4); + return 0; +} +#endif +#endif + +static int opFDIV(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(0), ST(0), ST(fetchdat & 7)); + FP_TAG(); + CLOCK_CYCLES(73); + return 0; +} +static int opFDIVr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); + FP_FTAG(); + CLOCK_CYCLES(73); + return 0; +} +static int opFDIVP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(73); + return 0; +} + +static int opFDIVR(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(0), ST(fetchdat&7), ST(0)); + FP_TAG(); + CLOCK_CYCLES(73); + return 0; +} +static int opFDIVRr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); + FP_FTAG(); + CLOCK_CYCLES(73); + return 0; +} +static int opFDIVRP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(73); + return 0; +} + +static int opFMUL(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) * ST(fetchdat & 7); + FP_TAG(); + CLOCK_CYCLES(16); + return 0; +} +static int opFMULr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); + FP_FTAG(); + CLOCK_CYCLES(16); + return 0; +} +static int opFMULP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(16); + return 0; +} + +static int opFSUB(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) - ST(fetchdat & 7); + FP_TAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFSUBr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); + FP_FTAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFSUBP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(8); + return 0; +} + +static int opFSUBR(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(fetchdat & 7) - ST(0); + FP_TAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFSUBRr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); + FP_FTAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFSUBRP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(8); + return 0; +} + +#ifndef FPU_8087 +static int opFUCOM(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); + CLOCK_CYCLES(4); + return 0; +} + +static int opFUCOMP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); + x87_pop(); + CLOCK_CYCLES(4); + return 0; +} + +#ifdef FP_686 +static int opFUCOMI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(4); + return 0; +} +static int opFUCOMIP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES(4); + return 0; +} +#endif +#endif diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu_common/x87_ops_loadstore.h similarity index 97% rename from src/cpu/x87_ops_loadstore.h rename to src/cpu_common/x87_ops_loadstore.h index 3001e8ca8..b5ad491f9 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu_common/x87_ops_loadstore.h @@ -101,8 +101,8 @@ static int opFILDiq_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp64 = geteaq(); if (cpu_state.abrt) return 1; x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP].q = temp64; - cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; + FP_LSQ(); + FP_LSTAG(); CLOCK_CYCLES(10); return 0; @@ -116,8 +116,8 @@ static int opFILDiq_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp64 = geteaq(); if (cpu_state.abrt) return 1; x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP].q = temp64; - cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; + FP_LSQ(); + FP_LSTAG(); CLOCK_CYCLES(10); return 0; @@ -186,7 +186,7 @@ static int FISTPiq_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP].q; + FP_LSRETQ() else temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; @@ -202,7 +202,7 @@ static int FISTPiq_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP].q; + FP_LSRETQ() else temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; diff --git a/src/cpu/x87_ops_misc.h b/src/cpu_common/x87_ops_misc.h similarity index 88% rename from src/cpu/x87_ops_misc.h rename to src/cpu_common/x87_ops_misc.h index 36dbd8a76..406c6c86d 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu_common/x87_ops_misc.h @@ -21,7 +21,6 @@ static int opFSTSW_AX(uint32_t fetchdat) #endif - static int opFNOP(uint32_t fetchdat) { FP_ENTER(); @@ -49,10 +48,10 @@ static int opFINIT(uint32_t fetchdat) #else cpu_state.npxc = 0x37F; #endif - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); + FP_RNPXC(); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; - *p = 0x0303030303030303ll; + *p = FP_DTAG; cpu_state.TOP = 0; cpu_state.ismmx = 0; CLOCK_CYCLES(17); @@ -65,7 +64,7 @@ static int opFFREE(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY; CLOCK_CYCLES(3); return 0; } @@ -74,7 +73,7 @@ static int opFFREEP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY; if (cpu_state.abrt) return 1; x87_pop(); CLOCK_CYCLES(3); return 0; @@ -113,7 +112,7 @@ static int FSTOR() case 0x000: /*16-bit real mode*/ case 0x001: /*16-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -122,7 +121,7 @@ static int FSTOR() case 0x100: /*32-bit real mode*/ case 0x101: /*32-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -144,7 +143,7 @@ static int FSTOR() p = (uint64_t *)cpu_state.tag; if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*p)) + !cpu_state.TOP && (*p == FP_CTAG)) cpu_state.ismmx = 1; CLOCK_CYCLES((cr0 & 1) ? 34 : 44); @@ -154,7 +153,7 @@ static int opFSTOR_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); FSTOR(); return cpu_state.abrt; } @@ -163,7 +162,7 @@ static int opFSTOR_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); FSTOR(); return cpu_state.abrt; } @@ -174,7 +173,7 @@ static int FSAVE() uint64_t *p; FP_ENTER(); - cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (cpu_state.TOP << 11); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (FP_TOP(cpu_state.TOP) << 11); switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { @@ -306,10 +305,10 @@ static int FSAVE() } cpu_state.npxc = 0x37F; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); + FP_RNPXC(); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; - *p = 0x0303030303030303ll; + *p = FP_DTAG; cpu_state.TOP = 0; cpu_state.ismmx = 0; @@ -320,7 +319,7 @@ static int opFSAVE_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); FSAVE(); return cpu_state.abrt; } @@ -329,7 +328,7 @@ static int opFSAVE_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); FSAVE(); return cpu_state.abrt; } @@ -339,8 +338,8 @@ static int opFSTSW_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11)); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11)); CLOCK_CYCLES(3); return cpu_state.abrt; } @@ -349,8 +348,8 @@ static int opFSTSW_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11)); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11)); CLOCK_CYCLES(3); return cpu_state.abrt; } @@ -367,8 +366,8 @@ static int opFLD(uint32_t fetchdat) old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; x87_push(ST(fetchdat&7)); - cpu_state.tag[cpu_state.TOP] = old_tag; - cpu_state.MM[cpu_state.TOP].q = old_i64; + cpu_state.tag[FP_TOP(cpu_state.TOP)] = old_tag; + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = old_i64; CLOCK_CYCLES(4); return 0; } @@ -383,11 +382,11 @@ static int opFXCH(uint32_t fetchdat) td = ST(0); ST(0) = ST(fetchdat&7); ST(fetchdat&7) = td; - old_tag = cpu_state.tag[cpu_state.TOP]; - cpu_state.tag[cpu_state.TOP] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + old_tag = cpu_state.tag[FP_TOP(cpu_state.TOP)]; + cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; - old_i64 = cpu_state.MM[cpu_state.TOP].q; - cpu_state.MM[cpu_state.TOP].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + old_i64 = cpu_state.MM[FP_TOP(cpu_state.TOP)].q; + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; CLOCK_CYCLES(4); @@ -399,7 +398,7 @@ static int opFCHS(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = -ST(0); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(6); return 0; } @@ -409,7 +408,7 @@ static int opFABS(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = fabs(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(3); return 0; } @@ -430,7 +429,7 @@ static int opFXAM(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; cpu_state.npxs &= ~(C0|C1|C2|C3); - if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3); + if (cpu_state.tag[cpu_state.TOP&7] == FP_EMPTY) cpu_state.npxs |= (C0|C3); else if (ST(0) == 0.0) cpu_state.npxs |= C3; else cpu_state.npxs |= C2; if (ST(0) < 0.0) cpu_state.npxs |= C1; @@ -497,7 +496,7 @@ static int opFLDZ(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(0.0); - cpu_state.tag[cpu_state.TOP&7] = 1; + FP_ZTAG(); CLOCK_CYCLES(4); return 0; } @@ -507,7 +506,7 @@ static int opF2XM1(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = pow(2.0, ST(0)) - 1.0; - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(200); return 0; } @@ -517,7 +516,7 @@ static int opFYL2X(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(1) = ST(1) * (log(ST(0)) / log(2.0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; + FP_NTAG(); x87_pop(); CLOCK_CYCLES(250); return 0; @@ -527,8 +526,8 @@ static int opFYL2XP1(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; + ST(1) = ST(1) * (log(ST(0)+1.0) / log(2.0)); + FP_NTAG(); x87_pop(); CLOCK_CYCLES(250); return 0; @@ -539,7 +538,7 @@ static int opFPTAN(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = tan(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); x87_push(1.0); cpu_state.npxs &= ~C2; CLOCK_CYCLES(235); @@ -551,7 +550,7 @@ static int opFPATAN(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(1) = atan2(ST(1), ST(0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; + FP_NTAG(); x87_pop(); CLOCK_CYCLES(250); return 0; @@ -561,7 +560,7 @@ static int opFDECSTP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.TOP = (cpu_state.TOP - 1) & 7; + FP_DECTOP(); CLOCK_CYCLES(4); return 0; } @@ -570,7 +569,7 @@ static int opFINCSTP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.TOP = (cpu_state.TOP + 1) & 7; + FP_INCTOP(); CLOCK_CYCLES(4); return 0; } @@ -582,7 +581,7 @@ static int opFPREM(uint32_t fetchdat) cpu_state.pc++; temp64 = (int64_t)(ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); cpu_state.npxs &= ~(C0|C1|C2|C3); if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; @@ -598,7 +597,7 @@ static int opFPREM1(uint32_t fetchdat) cpu_state.pc++; temp64 = (int64_t)(ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); cpu_state.npxs &= ~(C0|C1|C2|C3); if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; @@ -613,7 +612,7 @@ static int opFSQRT(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = sqrt(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(83); return 0; } @@ -626,7 +625,7 @@ static int opFSINCOS(uint32_t fetchdat) cpu_state.pc++; td = ST(0); ST(0) = sin(td); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); x87_push(cos(td)); cpu_state.npxs &= ~C2; CLOCK_CYCLES(330); @@ -636,10 +635,18 @@ static int opFSINCOS(uint32_t fetchdat) static int opFRNDINT(uint32_t fetchdat) { + double rounded; FP_ENTER(); cpu_state.pc++; - ST(0) = (double)x87_fround(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + rounded = (double) x87_fround(ST(0)); +#ifndef PCEM_CODE + if (rounded > ST(0)) + cpu_state.npxs |= C1; + else + cpu_state.npxs &= ~C1; +#endif + ST(0) = rounded; + FP_TAG(); CLOCK_CYCLES(21); return 0; } @@ -651,7 +658,7 @@ static int opFSCALE(uint32_t fetchdat) cpu_state.pc++; temp64 = (int64_t)ST(1); ST(0) = ST(0) * pow(2.0, (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(30); return 0; } @@ -662,7 +669,7 @@ static int opFSIN(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = sin(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); cpu_state.npxs &= ~C2; CLOCK_CYCLES(300); return 0; @@ -673,7 +680,7 @@ static int opFCOS(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = cos(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); cpu_state.npxs &= ~C2; CLOCK_CYCLES(300); return 0; @@ -689,7 +696,7 @@ static int FLDENV() case 0x000: /*16-bit real mode*/ case 0x001: /*16-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -697,7 +704,7 @@ static int FLDENV() case 0x100: /*32-bit real mode*/ case 0x101: /*32-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -735,7 +742,7 @@ static int opFLDCW_a16(uint32_t fetchdat) tempw = geteaw(); if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); CLOCK_CYCLES(4); return 0; } @@ -749,7 +756,7 @@ static int opFLDCW_a32(uint32_t fetchdat) tempw = geteaw(); if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); CLOCK_CYCLES(4); return 0; } @@ -839,7 +846,7 @@ static int opFSTCW_a32(uint32_t fetchdat) #endif #ifndef FPU_8087 -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#ifdef FP_686 #define opFCMOV(condition) \ static int opFCMOV ## condition(uint32_t fetchdat) \ { \ @@ -847,8 +854,8 @@ static int opFSTCW_a32(uint32_t fetchdat) cpu_state.pc++; \ if (cond_ ## condition) \ { \ - cpu_state.tag[cpu_state.TOP] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ - cpu_state.MM[cpu_state.TOP].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ + cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ ST(0) = ST(fetchdat & 7); \ } \ CLOCK_CYCLES(4); \ diff --git a/src/cpu_new/386.c b/src/cpu_new/386.c deleted file mode 100644 index 2b2268920..000000000 --- a/src/cpu_new/386.c +++ /dev/null @@ -1,303 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#ifndef INFINITY -# define INFINITY (__builtin_inff()) -#endif -#define HAVE_STDARG_H -#include "../86box.h" -#include "cpu.h" -#include "../timer.h" -#include "x86.h" -#include "x87.h" -#include "../nmi.h" -#include "../mem.h" -#include "../pic.h" -#include "../pit.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "386_common.h" -#include "codegen.h" - - -#ifdef ENABLE_386_LOG -int x386_do_log = ENABLE_386_LOG; - - -void -x386_log(const char *fmt, ...) -{ - va_list ap; - - if (x386_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define x386_log(fmt, ...) -#endif - - -#undef CPU_BLOCK_END -#define CPU_BLOCK_END() - - -extern int codegen_flags_changed; - -int tempc, oldcpl, optype, inttype, oddeven = 0; -int timetolive; - -uint16_t oldcs; - -uint32_t oldds, oldss, olddslimit, oldsslimit, - olddslimitw, oldsslimitw; -uint32_t oxpc; -uint32_t rmdat32; -uint32_t backupregs[16]; - -x86seg _oldds; - - -static __inline void -fetch_ea_32_long(uint32_t rmdat) -{ - uint8_t sib; - uint32_t addr; - - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (cpu_rm == 4) { - sib = rmdat >> 8; - - switch (cpu_mod) { - case 0: - cpu_state.eaaddr = cpu_state.regs[sib & 7].l; - cpu_state.pc++; - break; - case 1: - cpu_state.pc++; - cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; - break; - case 2: - cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; - cpu_state.pc += 5; - break; - } - /*SIB byte present*/ - if ((sib & 7) == 5 && !cpu_mod) - cpu_state.eaaddr = getlong(); - else if ((sib & 6) == 4 && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (((sib >> 3) & 7) != 4) - cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); - } else { - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) { - if (cpu_rm == 5 && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (cpu_mod == 1) { - cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); - cpu_state.pc++; - } else - cpu_state.eaaddr += getlong(); - } else if (cpu_rm == 5) - cpu_state.eaaddr = getlong(); - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } -} - - -static __inline void -fetch_ea_16_long(uint32_t rmdat) -{ - uint32_t addr; - - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (!cpu_mod && cpu_rm == 6) - cpu_state.eaaddr = getword(); - else { - switch (cpu_mod) { - case 0: - cpu_state.eaaddr = 0; - break; - case 1: - cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; - break; - case 2: - cpu_state.eaaddr = getword(); - break; - } - cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); - if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - cpu_state.eaaddr &= 0xFFFF; - } - - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } -} - - -#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; } -#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0 - -#include "x86_flags.h" - -#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ -#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 -#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ -#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 - - -#define OP_TABLE(name) ops_ ## name - -#define CLOCK_CYCLES(c) cycles -= (c) -#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) - -#include "x86_ops.h" - - -void -exec386(int cycs) -{ - uint8_t opcode; - int vector, tempi, cycdiff, oldcyc; - int cycle_period, ins_cycles; - uint32_t addr; - - cycles += cycs; - - while (cycles > 0) { - cycle_period = (timer_target - (uint32_t)tsc) + 1; - - x86_was_reset = 0; - cycdiff = 0; - oldcyc = cycles; - while (cycdiff < cycle_period) { - ins_cycles = cycles; - - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; - - fetchdat = fastreadl(cs + cpu_state.pc); - - if (!cpu_state.abrt) { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; - - cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } - - if (cpu_state.abrt) { - flags_rebuild(); - tempi = cpu_state.abrt; - cpu_state.abrt = 0; - x86_doabrt(tempi); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - cpu_state.pc = cpu_state.oldpc; - x386_log("Double fault %i\n", ins); - pmodeint(8, 0); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); -#ifdef ENABLE_386_LOG - x386_log("Triple fault - reset\n"); -#endif - } - } - } - - ins_cycles -= cycles; - tsc += ins_cycles; - - cycdiff = oldcyc - cycles; - - if (trap) { - flags_rebuild(); - if (msw&1) - pmodeint(1,0); - else { - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - addr = (1 << 2) + idt.base; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - } - } else if (nmi && nmi_enable && nmi_mask) { - cpu_state.oldpc = cpu_state.pc; - x86_int(2); - nmi_enable = 0; - if (nmi_auto_clear) { - nmi_auto_clear = 0; - nmi = 0; - } - } else if ((cpu_state.flags & I_FLAG) && pic_intpending) { - vector = picinterrupt(); - if (vector != 0xFF) { - flags_rebuild(); - if (msw & 1) - pmodeint(vector, 0); - else { - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - addr = (vector << 2) + idt.base; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - } - } - } - - ins++; - - if (timetolive) { - timetolive--; - if (!timetolive) - fatal("Life expired\n"); - } - } - - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process(); - } -} diff --git a/src/cpu_new/codegen.c b/src/cpu_new/codegen.c index 243f61791..9758788b1 100644 --- a/src/cpu_new/codegen.c +++ b/src/cpu_new/codegen.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86_ops.h" #include "codegen.h" diff --git a/src/cpu_new/codegen.h b/src/cpu_new/codegen.h index d4f2563f6..039a34c0f 100644 --- a/src/cpu_new/codegen.h +++ b/src/cpu_new/codegen.h @@ -2,7 +2,7 @@ #define _CODEGEN_H_ #include "mem.h" -#include "x86_ops.h" +#include "../cpu_common/x86_ops.h" /*Handling self-modifying code (of which there is a lot on x86) : diff --git a/src/cpu_new/codegen_accumulate.c b/src/cpu_new/codegen_accumulate.c index c9b85ba78..726f5258f 100644 --- a/src/cpu_new/codegen_accumulate.c +++ b/src/cpu_new/codegen_accumulate.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/cpu_new/codegen_allocator.c b/src/cpu_new/codegen_allocator.c index b78c4df12..9f5d87852 100644 --- a/src/cpu_new/codegen_allocator.c +++ b/src/cpu_new/codegen_allocator.c @@ -9,9 +9,9 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_arm.c b/src/cpu_new/codegen_backend_arm.c index ddabbb5c5..8ad2d0011 100644 --- a/src/cpu_new/codegen_backend_arm.c +++ b/src/cpu_new/codegen_backend_arm.c @@ -2,9 +2,9 @@ #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_arm64.c b/src/cpu_new/codegen_backend_arm64.c index 32489000f..1cfd27d9e 100644 --- a/src/cpu_new/codegen_backend_arm64.c +++ b/src/cpu_new/codegen_backend_arm64.c @@ -2,9 +2,9 @@ #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_arm64_ops.c b/src/cpu_new/codegen_backend_arm64_ops.c index 44cf87647..f55b0d569 100644 --- a/src/cpu_new/codegen_backend_arm64_ops.c +++ b/src/cpu_new/codegen_backend_arm64_ops.c @@ -1,9 +1,9 @@ #ifdef __aarch64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_arm64_uops.c b/src/cpu_new/codegen_backend_arm64_uops.c index e9cf28684..b7cf12023 100644 --- a/src/cpu_new/codegen_backend_arm64_uops.c +++ b/src/cpu_new/codegen_backend_arm64_uops.c @@ -1,9 +1,9 @@ #ifdef __aarch64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x87.h" diff --git a/src/cpu_new/codegen_backend_arm_ops.c b/src/cpu_new/codegen_backend_arm_ops.c index 1b2ef28f3..4bb86c2e7 100644 --- a/src/cpu_new/codegen_backend_arm_ops.c +++ b/src/cpu_new/codegen_backend_arm_ops.c @@ -1,9 +1,9 @@ #ifdef __ARM_EABI__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_arm_uops.c b/src/cpu_new/codegen_backend_arm_uops.c index 1dbaab407..0ef7ed7eb 100644 --- a/src/cpu_new/codegen_backend_arm_uops.c +++ b/src/cpu_new/codegen_backend_arm_uops.c @@ -2,9 +2,9 @@ #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x87.h" diff --git a/src/cpu_new/codegen_backend_x86-64.c b/src/cpu_new/codegen_backend_x86-64.c index 4615aa381..d93fce248 100644 --- a/src/cpu_new/codegen_backend_x86-64.c +++ b/src/cpu_new/codegen_backend_x86-64.c @@ -1,9 +1,9 @@ #ifdef __amd64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86-64_ops.c b/src/cpu_new/codegen_backend_x86-64_ops.c index 8bb91da1c..dc1718892 100644 --- a/src/cpu_new/codegen_backend_x86-64_ops.c +++ b/src/cpu_new/codegen_backend_x86-64_ops.c @@ -1,9 +1,9 @@ #ifdef __amd64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86-64_ops_sse.c b/src/cpu_new/codegen_backend_x86-64_ops_sse.c index b8177648e..3a74910f2 100644 --- a/src/cpu_new/codegen_backend_x86-64_ops_sse.c +++ b/src/cpu_new/codegen_backend_x86-64_ops_sse.c @@ -1,9 +1,9 @@ #ifdef __amd64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86-64_uops.c b/src/cpu_new/codegen_backend_x86-64_uops.c index bff4e3775..f497aa569 100644 --- a/src/cpu_new/codegen_backend_x86-64_uops.c +++ b/src/cpu_new/codegen_backend_x86-64_uops.c @@ -1,9 +1,9 @@ #ifdef __amd64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x87.h" diff --git a/src/cpu_new/codegen_backend_x86.c b/src/cpu_new/codegen_backend_x86.c index d83d99af0..d364b7634 100644 --- a/src/cpu_new/codegen_backend_x86.c +++ b/src/cpu_new/codegen_backend_x86.c @@ -3,9 +3,9 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86_ops.c b/src/cpu_new/codegen_backend_x86_ops.c index f5010e356..766ce0fc6 100644 --- a/src/cpu_new/codegen_backend_x86_ops.c +++ b/src/cpu_new/codegen_backend_x86_ops.c @@ -1,9 +1,9 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86_ops_fpu.c b/src/cpu_new/codegen_backend_x86_ops_fpu.c index dd1e658fb..03734ca90 100644 --- a/src/cpu_new/codegen_backend_x86_ops_fpu.c +++ b/src/cpu_new/codegen_backend_x86_ops_fpu.c @@ -1,9 +1,9 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86_ops_sse.c b/src/cpu_new/codegen_backend_x86_ops_sse.c index d829e4097..83a54f64a 100644 --- a/src/cpu_new/codegen_backend_x86_ops_sse.c +++ b/src/cpu_new/codegen_backend_x86_ops_sse.c @@ -1,9 +1,9 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86_uops.c b/src/cpu_new/codegen_backend_x86_uops.c index 679a7b77b..af801382c 100644 --- a/src/cpu_new/codegen_backend_x86_uops.c +++ b/src/cpu_new/codegen_backend_x86_uops.c @@ -1,9 +1,9 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu_new/codegen_block.c b/src/cpu_new/codegen_block.c index acff96a92..eec6d467c 100644 --- a/src/cpu_new/codegen_block.c +++ b/src/cpu_new/codegen_block.c @@ -1,8 +1,9 @@ #include #include -#include "../86box.h" +#include +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ir.c b/src/cpu_new/codegen_ir.c index 7d305737b..6aa2e6546 100644 --- a/src/cpu_new/codegen_ir.c +++ b/src/cpu_new/codegen_ir.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_ops.c b/src/cpu_new/codegen_ops.c index c1c6e54e7..2870c2b72 100644 --- a/src/cpu_new/codegen_ops.c +++ b/src/cpu_new/codegen_ops.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_ir.h" diff --git a/src/cpu_new/codegen_ops_3dnow.c b/src/cpu_new/codegen_ops_3dnow.c index 2406fe8e0..c2c0e85a6 100644 --- a/src/cpu_new/codegen_ops_3dnow.c +++ b/src/cpu_new/codegen_ops_3dnow.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_arith.c b/src/cpu_new/codegen_ops_arith.c index 70eddd4a9..f2c85eeba 100644 --- a/src/cpu_new/codegen_ops_arith.c +++ b/src/cpu_new/codegen_ops_arith.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_branch.c b/src/cpu_new/codegen_ops_branch.c index 5bea31781..853b0308a 100644 --- a/src/cpu_new/codegen_ops_branch.c +++ b/src/cpu_new/codegen_ops_branch.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "386_common.h" diff --git a/src/cpu_new/codegen_ops_fpu_arith.c b/src/cpu_new/codegen_ops_fpu_arith.c index 3f5621c3c..99384b3d4 100644 --- a/src/cpu_new/codegen_ops_fpu_arith.c +++ b/src/cpu_new/codegen_ops_fpu_arith.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_fpu_constant.c b/src/cpu_new/codegen_ops_fpu_constant.c index bca268ee3..cb048547c 100644 --- a/src/cpu_new/codegen_ops_fpu_constant.c +++ b/src/cpu_new/codegen_ops_fpu_constant.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_fpu_loadstore.c b/src/cpu_new/codegen_ops_fpu_loadstore.c index 599ab800e..879760518 100644 --- a/src/cpu_new/codegen_ops_fpu_loadstore.c +++ b/src/cpu_new/codegen_ops_fpu_loadstore.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_fpu_misc.c b/src/cpu_new/codegen_ops_fpu_misc.c index 7de92a39c..cb54ce791 100644 --- a/src/cpu_new/codegen_ops_fpu_misc.c +++ b/src/cpu_new/codegen_ops_fpu_misc.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_helpers.c b/src/cpu_new/codegen_ops_helpers.c index 9fc754e6c..feae979bb 100644 --- a/src/cpu_new/codegen_ops_helpers.c +++ b/src/cpu_new/codegen_ops_helpers.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "386_common.h" diff --git a/src/cpu_new/codegen_ops_jump.c b/src/cpu_new/codegen_ops_jump.c index a4d2b8847..2e304abc3 100644 --- a/src/cpu_new/codegen_ops_jump.c +++ b/src/cpu_new/codegen_ops_jump.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "386_common.h" diff --git a/src/cpu_new/codegen_ops_logic.c b/src/cpu_new/codegen_ops_logic.c index 87607ab2d..372fb2e60 100644 --- a/src/cpu_new/codegen_ops_logic.c +++ b/src/cpu_new/codegen_ops_logic.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_misc.c b/src/cpu_new/codegen_ops_misc.c index 3896e7ebc..eb73a4f81 100644 --- a/src/cpu_new/codegen_ops_misc.c +++ b/src/cpu_new/codegen_ops_misc.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" @@ -359,11 +359,11 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return -1; case 0x28: /*JMP far*/ + uop_MOVZX(ir, IREG_pc, src_reg); uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_LOAD_FUNC_ARG_IMM(ir, 1, cpu_state.oldpc); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); uop_CALL_FUNC(ir, loadcsjmp); - uop_MOVZX(ir, IREG_pc, src_reg); return -1; case 0x30: /*PUSH*/ @@ -466,11 +466,11 @@ uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return -1; case 0x28: /*JMP far*/ + uop_MOV(ir, IREG_pc, src_reg); uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_LOAD_FUNC_ARG_IMM(ir, 1, cpu_state.oldpc); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); uop_CALL_FUNC(ir, loadcsjmp); - uop_MOV(ir, IREG_pc, src_reg); return -1; case 0x30: /*PUSH*/ diff --git a/src/cpu_new/codegen_ops_mmx_arith.c b/src/cpu_new/codegen_ops_mmx_arith.c index 6b42273fa..91c6a61d0 100644 --- a/src/cpu_new/codegen_ops_mmx_arith.c +++ b/src/cpu_new/codegen_ops_mmx_arith.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mmx_cmp.c b/src/cpu_new/codegen_ops_mmx_cmp.c index 649e8550f..187f15fc4 100644 --- a/src/cpu_new/codegen_ops_mmx_cmp.c +++ b/src/cpu_new/codegen_ops_mmx_cmp.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mmx_loadstore.c b/src/cpu_new/codegen_ops_mmx_loadstore.c index 37ab3199a..a4413478e 100644 --- a/src/cpu_new/codegen_ops_mmx_loadstore.c +++ b/src/cpu_new/codegen_ops_mmx_loadstore.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mmx_logic.c b/src/cpu_new/codegen_ops_mmx_logic.c index 4a554b238..3bd78ec70 100644 --- a/src/cpu_new/codegen_ops_mmx_logic.c +++ b/src/cpu_new/codegen_ops_mmx_logic.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mmx_pack.c b/src/cpu_new/codegen_ops_mmx_pack.c index 6e9616271..9f1ae7aed 100644 --- a/src/cpu_new/codegen_ops_mmx_pack.c +++ b/src/cpu_new/codegen_ops_mmx_pack.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mmx_shift.c b/src/cpu_new/codegen_ops_mmx_shift.c index 014001d53..4f99050d5 100644 --- a/src/cpu_new/codegen_ops_mmx_shift.c +++ b/src/cpu_new/codegen_ops_mmx_shift.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mov.c b/src/cpu_new/codegen_ops_mov.c index 87d7bc8bb..d6bfc85b6 100644 --- a/src/cpu_new/codegen_ops_mov.c +++ b/src/cpu_new/codegen_ops_mov.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "386_common.h" diff --git a/src/cpu_new/codegen_ops_shift.c b/src/cpu_new/codegen_ops_shift.c index 2d0b760d2..c3d5db504 100644 --- a/src/cpu_new/codegen_ops_shift.c +++ b/src/cpu_new/codegen_ops_shift.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_stack.c b/src/cpu_new/codegen_ops_stack.c index 28b346446..eb1f4d18e 100644 --- a/src/cpu_new/codegen_ops_stack.c +++ b/src/cpu_new/codegen_ops_stack.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_reg.c b/src/cpu_new/codegen_reg.c index 70b654998..b5af4a050 100644 --- a/src/cpu_new/codegen_reg.c +++ b/src/cpu_new/codegen_reg.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_backend.h" diff --git a/src/cpu_new/codegen_timing_486.c b/src/cpu_new/codegen_timing_486.c index b4054b32f..970514f29 100644 --- a/src/cpu_new/codegen_timing_486.c +++ b/src/cpu_new/codegen_timing_486.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu_new/codegen_timing_686.c b/src/cpu_new/codegen_timing_686.c index 609a5e068..58afb7262 100644 --- a/src/cpu_new/codegen_timing_686.c +++ b/src/cpu_new/codegen_timing_686.c @@ -10,9 +10,9 @@ */ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu_new/codegen_timing_common.c b/src/cpu_new/codegen_timing_common.c index 3b47a2734..5eaa7f532 100644 --- a/src/cpu_new/codegen_timing_common.c +++ b/src/cpu_new/codegen_timing_common.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen_timing_common.h" diff --git a/src/cpu_new/codegen_timing_k6.c b/src/cpu_new/codegen_timing_k6.c index 9c216de9a..5aa05cb87 100644 --- a/src/cpu_new/codegen_timing_k6.c +++ b/src/cpu_new/codegen_timing_k6.c @@ -1,10 +1,10 @@ /*Most of the vector instructions here are a total guess. Some of the timings are based on http://users.atw.hu/instlatx64/AuthenticAMD0000562_K6_InstLatX86.txt*/ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" -#include "../machine/machine.h" +#include "mem.h" +#include "machine.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu_new/codegen_timing_pentium.c b/src/cpu_new/codegen_timing_pentium.c index 1e4c104fd..f923646a6 100644 --- a/src/cpu_new/codegen_timing_pentium.c +++ b/src/cpu_new/codegen_timing_pentium.c @@ -11,12 +11,12 @@ */ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_ops.h" diff --git a/src/cpu_new/codegen_timing_winchip.c b/src/cpu_new/codegen_timing_winchip.c index f488078a5..53159a375 100644 --- a/src/cpu_new/codegen_timing_winchip.c +++ b/src/cpu_new/codegen_timing_winchip.c @@ -1,10 +1,10 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_ops.h" diff --git a/src/cpu_new/codegen_timing_winchip2.c b/src/cpu_new/codegen_timing_winchip2.c index e7294b917..360683522 100644 --- a/src/cpu_new/codegen_timing_winchip2.c +++ b/src/cpu_new/codegen_timing_winchip2.c @@ -8,9 +8,9 @@ - Instructions with prefixes can pair if both instructions are fully decoded when the first instruction starts execution.*/ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu_new/x86_flags_dynarec.h b/src/cpu_new/x86_flags_dynarec.h deleted file mode 100644 index 2a5212afa..000000000 --- a/src/cpu_new/x86_flags_dynarec.h +++ /dev/null @@ -1,528 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -/* This file is needed so that the dynarec can use the old flags - functions, while the interpreter can use the new ones. */ -extern int tempc; - -enum -{ - FLAGS_UNKNOWN, - - FLAGS_ZN8, - FLAGS_ZN16, - FLAGS_ZN32, - - FLAGS_ADD8, - FLAGS_ADD16, - FLAGS_ADD32, - - FLAGS_SUB8, - FLAGS_SUB16, - FLAGS_SUB32, - - FLAGS_SHL8, - FLAGS_SHL16, - FLAGS_SHL32, - - FLAGS_SHR8, - FLAGS_SHR16, - FLAGS_SHR32, - - FLAGS_SAR8, - FLAGS_SAR16, - FLAGS_SAR32, - - FLAGS_INC8, - FLAGS_INC16, - FLAGS_INC32, - - FLAGS_DEC8, - FLAGS_DEC16, - FLAGS_DEC32 -}; - -static __inline int ZF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - return !cpu_state.flags_res; - - case FLAGS_UNKNOWN: - return cpu_state.flags & Z_FLAG; - - default: - return 0; - } -} - -static __inline int NF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: - return cpu_state.flags_res & 0x80; - - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: - return cpu_state.flags_res & 0x8000; - - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: - return cpu_state.flags_res & 0x80000000; - - case FLAGS_UNKNOWN: - return cpu_state.flags & N_FLAG; - - default: - return 0; - } -} - -static __inline int PF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; - - case FLAGS_UNKNOWN: - return cpu_state.flags & P_FLAG; - - default: - return 0; - } -} - -static __inline int VF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - return 0; - - case FLAGS_ADD8: - case FLAGS_INC8: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); - case FLAGS_ADD16: - case FLAGS_INC16: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); - case FLAGS_ADD32: - case FLAGS_INC32: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); - - case FLAGS_SUB8: - case FLAGS_DEC8: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); - case FLAGS_SUB16: - case FLAGS_DEC16: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); - case FLAGS_SUB32: - case FLAGS_DEC32: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); - - case FLAGS_SHL8: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80); - case FLAGS_SHL16: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x8000); - case FLAGS_SHL32: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80000000); - - case FLAGS_SHR8: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80)); - case FLAGS_SHR16: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x8000)); - case FLAGS_SHR32: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); - - case FLAGS_UNKNOWN: - return cpu_state.flags & V_FLAG; - - default: - return 0; - } -} - -static __inline int AF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - return 0; - - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10; - - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10; - - case FLAGS_UNKNOWN: - return cpu_state.flags & A_FLAG; - - default: - return 0; - } -} - -static __inline int CF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ADD8: - return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100; - case FLAGS_ADD16: - return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000; - case FLAGS_ADD32: - return (cpu_state.flags_res < cpu_state.flags_op1); - - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - return (cpu_state.flags_op1 < cpu_state.flags_op2); - - case FLAGS_SHL8: - return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80; - case FLAGS_SHL16: - return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000; - case FLAGS_SHL32: - return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000; - - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - return (cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - - case FLAGS_SAR8: - return ((int8_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR16: - return ((int16_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR32: - return ((int32_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - return 0; - - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_UNKNOWN: - return cpu_state.flags & C_FLAG; - - default: - return 0; - } -} - -static __inline void flags_rebuild_dynarec() -{ - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - uint16_t tempf = 0; - if (CF_SET_dynarec()) tempf |= C_FLAG; - if (PF_SET_dynarec()) tempf |= P_FLAG; - if (AF_SET_dynarec()) tempf |= A_FLAG; - if (ZF_SET_dynarec()) tempf |= Z_FLAG; - if (NF_SET_dynarec()) tempf |= N_FLAG; - if (VF_SET_dynarec()) tempf |= V_FLAG; - cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf; - cpu_state.flags_op = FLAGS_UNKNOWN; - } -} - -static __inline void flags_extract_dynarec() -{ - cpu_state.flags_op = FLAGS_UNKNOWN; -} - -static __inline void flags_rebuild_c_dynarec() -{ - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - if (CF_SET_dynarec()) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - } -} - -static __inline void setznp8_dynarec(uint8_t val) -{ - cpu_state.flags_op = FLAGS_ZN8; - cpu_state.flags_res = val; -} -static __inline void setznp16_dynarec(uint16_t val) -{ - cpu_state.flags_op = FLAGS_ZN16; - cpu_state.flags_res = val; -} -static __inline void setznp32_dynarec(uint32_t val) -{ - cpu_state.flags_op = FLAGS_ZN32; - cpu_state.flags_res = val; -} - -#define set_flags_shift_dynarec(op, orig, shift, res) \ - cpu_state.flags_op = op; \ - cpu_state.flags_res = res; \ - cpu_state.flags_op1 = orig; \ - cpu_state.flags_op2 = shift; - -static __inline void setadd8_dynarec(uint8_t a, uint8_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xff; - cpu_state.flags_op = FLAGS_ADD8; -} -static __inline void setadd16_dynarec(uint16_t a, uint16_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xffff; - cpu_state.flags_op = FLAGS_ADD16; -} -static __inline void setadd32_dynarec(uint32_t a, uint32_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b; - cpu_state.flags_op = FLAGS_ADD32; -} -static __inline void setadd8nc_dynarec(uint8_t a, uint8_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xff; - cpu_state.flags_op = FLAGS_INC8; -} -static __inline void setadd16nc_dynarec(uint16_t a, uint16_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xffff; - cpu_state.flags_op = FLAGS_INC16; -} -static __inline void setadd32nc_dynarec(uint32_t a, uint32_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b; - cpu_state.flags_op = FLAGS_INC32; -} - -static __inline void setsub8_dynarec(uint8_t a, uint8_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xff; - cpu_state.flags_op = FLAGS_SUB8; -} -static __inline void setsub16_dynarec(uint16_t a, uint16_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xffff; - cpu_state.flags_op = FLAGS_SUB16; -} -static __inline void setsub32_dynarec(uint32_t a, uint32_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - b; - cpu_state.flags_op = FLAGS_SUB32; -} - -static __inline void setsub8nc_dynarec(uint8_t a, uint8_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xff; - cpu_state.flags_op = FLAGS_DEC8; -} -static __inline void setsub16nc_dynarec(uint16_t a, uint16_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xffff; - cpu_state.flags_op = FLAGS_DEC16; -} -static __inline void setsub32nc_dynarec(uint32_t a, uint32_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - b; - cpu_state.flags_op = FLAGS_DEC32; -} - -static __inline void setadc8_dynarec(uint8_t a, uint8_t b) -{ - uint16_t c=(uint16_t)a+(uint16_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=znptable8[c&0xFF]; - if (c&0x100) cpu_state.flags|=C_FLAG; - if (!((a^b)&0x80)&&((a^c)&0x80)) cpu_state.flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; -} -static __inline void setadc16_dynarec(uint16_t a, uint16_t b) -{ - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=znptable16[c&0xFFFF]; - if (c&0x10000) cpu_state.flags|=C_FLAG; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) cpu_state.flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; -} -static __inline void setadc32_dynarec(uint32_t a, uint32_t b) -{ - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); - cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG); - if ((ca) || (c==a && tempc)) cpu_state.flags|=C_FLAG; - if ((a^b)&(a^c)&0x80000000) cpu_state.flags|=V_FLAG; - if (((a&0xF)-((b&0xF)+tempc))&0x10) cpu_state.flags|=A_FLAG; -} - -extern void cpu_386_flags_extract(); -extern void cpu_386_flags_rebuild(); \ No newline at end of file diff --git a/src/cpu_new/x86seg.c b/src/cpu_new/x86seg.c index c07f002ea..12ad3753b 100644 --- a/src/cpu_new/x86seg.c +++ b/src/cpu_new/x86seg.c @@ -24,13 +24,13 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../device.h" -#include "../timer.h" -#include "../machine/machine.h" -#include "../mem.h" -#include "../nvr.h" +#include "device.h" +#include "timer.h" +#include "machine.h" +#include "mem.h" +#include "nvr.h" #include "x86.h" #include "x86_flags.h" #include "386_common.h" diff --git a/src/cpu_table.txt b/src/cpu_table.txt new file mode 100644 index 000000000..038cebc74 --- /dev/null +++ b/src/cpu_table.txt @@ -0,0 +1,3 @@ +Comparing files CPU\cpu_table.c and CPU_NEW\CPU_TABLE.C +FC: no differences encountered + diff --git a/src/device.c b/src/device.c index 97318c50d..dddf24551 100644 --- a/src/device.c +++ b/src/device.c @@ -47,8 +47,8 @@ #include "86box.h" #include "config.h" #include "device.h" -#include "machine/machine.h" -#include "sound/sound.h" +#include "machine.h" +#include "sound.h" #define DEVICE_MAX 256 /* max # of devices */ diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 4b1313cb1..f6ed1ae35 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -22,9 +22,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../machine/machine.h" -#include "../device.h" +#include "86box.h" +#include "machine.h" +#include "device.h" #include "hdc.h" #include "hdc_ide.h" #include "hdd.h" diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index 920c087d5..91f1071a4 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -28,17 +28,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../pic.h" -#include "../rom.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "pic.h" +#include "rom.h" +#include "cpu.h" +#include "machine.h" +#include "timer.h" +#include "plat.h" +#include "ui.h" #include "hdc.h" #include "hdd.h" diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index f70dd7db7..c3438e8dd 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -67,16 +67,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../dma.h" -#include "../io.h" -#include "../mca.h" -#include "../mem.h" -#include "../pic.h" -#include "../rom.h" -#include "../timer.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "dma.h" +#include "86box_io.h" +#include "mca.h" +#include "mem.h" +#include "pic.h" +#include "rom.h" +#include "timer.h" +#include "ui.h" #include "hdc.h" #include "hdd.h" diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 5fedee57d..3e6c4a6f1 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -28,20 +28,20 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../mem.h" -#include "../pic.h" -#include "../pci.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../scsi/scsi_device.h" -#include "../cdrom/cdrom.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "86box_io.h" +#include "mem.h" +#include "pic.h" +#include "pci.h" +#include "rom.h" +#include "timer.h" +#include "device.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "plat.h" +#include "ui.h" #include "hdc.h" #include "hdc_ide.h" #include "hdd.h" @@ -278,6 +278,8 @@ ide_irq_raise(ide_t *ide) /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ + ide_log("IDE %i: IRQ raise\n", ide->board); + if (!(ide->fdisk & 2)) { if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); @@ -298,6 +300,8 @@ ide_irq_lower(ide_t *ide) /* ide_log("Lowering IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ + ide_log("IDE %i: IRQ lower\n", ide->board); + if (ide->irqstat) { if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); @@ -318,6 +322,7 @@ ide_irq_update(ide_t *ide) /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ if (!(ide->fdisk & 2) && ide->irqstat) { + ide_log("IDE %i: IRQ update raise\n", ide->board); if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) { ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); @@ -326,6 +331,7 @@ ide_irq_update(ide_t *ide) picint(1 << ide_boards[ide->board]->irq); } } else if (ide->fdisk & 2) { + ide_log("IDE %i: IRQ update lower\n", ide->board); if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); else if (ide_boards[ide->board]->irq != -1) @@ -877,11 +883,17 @@ ide_atapi_callback(ide_t *ide) switch(ide->sc->packet_status) { case PHASE_IDLE: +#ifdef ENABLE_IDE_LOG + ide_log("PHASE_IDLE\n"); +#endif ide->sc->pos = 0; ide->sc->phase = 1; ide->sc->status = READY_STAT | DRQ_STAT | (ide->sc->status & ERR_STAT); return; case PHASE_COMMAND: +#ifdef ENABLE_IDE_LOG + ide_log("PHASE_COMMAND\n"); +#endif ide->sc->status = BUSY_STAT | (ide->sc->status & ERR_STAT); if (ide->packet_command) { ide->packet_command(ide->sc, ide->sc->atapi_cdb); @@ -890,6 +902,9 @@ ide_atapi_callback(ide_t *ide) } return; case PHASE_COMPLETE: +#ifdef ENABLE_IDE_LOG + ide_log("PHASE_COMPLETE\n"); +#endif ide->sc->status = READY_STAT; ide->sc->phase = 3; ide->sc->packet_status = PHASE_NONE; @@ -897,12 +912,18 @@ ide_atapi_callback(ide_t *ide) return; case PHASE_DATA_IN: case PHASE_DATA_OUT: +#ifdef ENABLE_IDE_LOG + ide_log("PHASE_DATA_IN or PHASE_DATA_OUT\n"); +#endif ide->sc->status = READY_STAT | DRQ_STAT | (ide->sc->status & ERR_STAT); ide->sc->phase = !(ide->sc->packet_status & 0x01) << 1; ide_irq_raise(ide); return; case PHASE_DATA_IN_DMA: case PHASE_DATA_OUT_DMA: +#ifdef ENABLE_IDE_LOG + ide_log("PHASE_DATA_IN_DMA or PHASE_DATA_OUT_DMA\n"); +#endif out = (ide->sc->packet_status & 0x01); if (ide_bm[ide->board] && ide_bm[ide->board]->dma) { @@ -932,11 +953,17 @@ ide_atapi_callback(ide_t *ide) return; case PHASE_ERROR: +#ifdef ENABLE_IDE_LOG + ide_log("PHASE_ERROR\n"); +#endif ide->sc->status = READY_STAT | ERR_STAT; ide->sc->phase = 3; ide->sc->packet_status = PHASE_NONE; ide_irq_raise(ide); return; + default: + ide_log("PHASE_UNKNOWN %02X\n", ide->sc->packet_status); + return; } } @@ -1001,6 +1028,9 @@ ide_atapi_packet_read(ide_t *ide, int length) if (!dev || !dev->temp_buffer || (dev->packet_status != PHASE_DATA_IN)) return 0; + if (dev->packet_status == PHASE_DATA_IN) + ide_log("PHASE_DATA_IN read: %i, %i< %i, %i\n", dev->request_pos, dev->max_transfer_len, dev->pos, dev->packet_len); + bufferw = (uint16_t *) dev->temp_buffer; bufferl = (uint32_t *) dev->temp_buffer; @@ -1689,7 +1719,7 @@ ide_read_data(ide_t *ide, int length) ide->secount = (ide->secount - 1) & 0xff; if (ide->secount) { ide_next_sector(ide); - ide->atastat = BSY_STAT; + ide->atastat = BSY_STAT | READY_STAT | DSC_STAT; if (ide->command == WIN_READ_MULTIPLE) ide_callback(ide_boards[ide->board]); else @@ -1923,7 +1953,7 @@ ide_callback(void *priv) ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F))) { if (ide->type != IDE_HDD) goto abort_cmd; - if ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F)) { + if ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F) && !ide->lba) { if ((ide->cylinder >= ide->tracks) || (ide->head >= ide->hpc) || !ide->sector || (ide->sector > ide->spt)) goto id_not_found; @@ -1984,7 +2014,7 @@ ide_callback(void *priv) ide_set_signature(ide); goto abort_cmd; } - if (ide->cfg_spt == 0) + if (!ide->lba && (ide->cfg_spt == 0)) goto id_not_found; if (ide->do_initial_read) { @@ -2014,7 +2044,7 @@ ide_callback(void *priv) ide_log("IDE %i: DMA read aborted (bad device or board)\n", ide->channel); goto abort_cmd; } - if (ide->cfg_spt == 0) { + if (!ide->lba && (ide->cfg_spt == 0)) { ide_log("IDE %i: DMA read aborted (SPECIFY failed)\n", ide->channel); goto id_not_found; } @@ -2066,7 +2096,7 @@ ide_callback(void *priv) mand error. */ if ((ide->type == IDE_ATAPI) || !ide->blocksize) goto abort_cmd; - if (ide->cfg_spt == 0) + if (!ide->lba && (ide->cfg_spt == 0)) goto id_not_found; if (ide->do_initial_read) { @@ -2095,7 +2125,7 @@ ide_callback(void *priv) case WIN_WRITE_NORETRY: if (ide->type == IDE_ATAPI) goto abort_cmd; - if (ide->cfg_spt == 0) + if (!ide->lba && (ide->cfg_spt == 0)) goto id_not_found; hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide_irq_raise(ide); @@ -2117,7 +2147,7 @@ ide_callback(void *priv) ide_log("IDE %i: DMA write aborted (bad device type or board)\n", ide->channel); goto abort_cmd; } - if (ide->cfg_spt == 0) { + if (!ide->lba && (ide->cfg_spt == 0)) { ide_log("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel); goto id_not_found; } @@ -2162,7 +2192,7 @@ ide_callback(void *priv) case WIN_WRITE_MULTIPLE: if (ide->type == IDE_ATAPI) goto abort_cmd; - if (ide->cfg_spt == 0) + if (!ide->lba && (ide->cfg_spt == 0)) goto id_not_found; hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide->blockcount++; @@ -2185,7 +2215,7 @@ ide_callback(void *priv) case WIN_VERIFY_ONCE: if (ide->type == IDE_ATAPI) goto abort_cmd; - if (ide->cfg_spt == 0) + if (!ide->lba && (ide->cfg_spt == 0)) goto id_not_found; ide->pos=0; ide->atastat = DRDY_STAT | DSC_STAT; @@ -2196,7 +2226,7 @@ ide_callback(void *priv) case WIN_FORMAT: if (ide->type == IDE_ATAPI) goto abort_cmd; - if (ide->cfg_spt == 0) + if (!ide->lba && (ide->cfg_spt == 0)) goto id_not_found; hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->secount); diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 1e6fce712..5e2b19e8d 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -25,17 +25,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cdrom/cdrom.h" -#include "../scsi/scsi_device.h" -#include "../scsi/scsi_cdrom.h" -#include "../dma.h" -#include "../io.h" -#include "../device.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../pci.h" -#include "../pic.h" +#include "86box.h" +#include "cdrom.h" +#include "scsi_device.h" +#include "scsi_cdrom.h" +#include "dma.h" +#include "86box_io.h" +#include "device.h" +#include "keyboard.h" +#include "mem.h" +#include "pci.h" +#include "pic.h" #include "hdc.h" #include "hdc_ide.h" #include "hdc_ide_sff8038i.h" @@ -74,21 +74,24 @@ sff_log(const char *fmt, ...) void -sff_bus_master_handlers(sff8038i_t *dev, uint16_t old_base, uint16_t new_base, int enabled) +sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base) { - io_removehandler(old_base, 0x08, - sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, - sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, - dev); + if (dev->base != 0x0000) { + io_removehandler(dev->base, 0x08, + sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, + sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, + dev); + } - if (enabled && new_base) { - io_sethandler(new_base, 0x08, + if (enabled && (base != 0x0000)) { + io_sethandler(base, 0x08, sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, dev); } dev->enabled = enabled; + dev->base = base; } @@ -370,14 +373,16 @@ sff_bus_master_set_irq(int channel, void *priv) channel &= 0x01; if (dev->status & 0x04) { - if ((dev->irq_mode == 2) && (channel & 1) && pci_use_mirq(0)) + sff_log("SFF8038i: Channel %i IRQ raise\n", channel); + if ((dev->irq_mode == 2) && channel && pci_use_mirq(0)) pci_set_mirq(0, 0); else if (dev->irq_mode == 1) pci_set_irq(dev->slot, dev->irq_pin); else picint(1 << (14 + channel)); } else { - if ((dev->irq_mode == 2) && (channel & 1) && pci_use_mirq(0)) + sff_log("SFF8038i: Channel %i IRQ lower\n", channel); + if ((dev->irq_mode == 2) && channel && pci_use_mirq(0)) pci_clear_mirq(0, 0); else if (dev->irq_mode == 1) pci_clear_irq(dev->slot, dev->irq_pin); @@ -416,6 +421,10 @@ sff_reset(void *p) { int i = 0; +#ifdef ENABLE_SFF_LOG + sff_log("SFF8038i: Reset\n"); +#endif + for (i = 0; i < CDROM_NUM; i++) { if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv) @@ -426,6 +435,9 @@ sff_reset(void *p) (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) zip_reset((scsi_common_t *) zip_drives[i].priv); } + + sff_bus_master_set_irq(0x00, p); + sff_bus_master_set_irq(0x01, p); } diff --git a/src/disk/hdc_ide_sff8038i.h b/src/disk/hdc_ide_sff8038i.h index 16b6ce524..bad14a7c6 100644 --- a/src/disk/hdc_ide_sff8038i.h +++ b/src/disk/hdc_ide_sff8038i.h @@ -8,7 +8,7 @@ * * Emulation core dispatcher. * - * Version: @(#)hdc_ide_sff8038i.h 1.0.1 2020/01/14 + * Version: @(#)hdc_ide_sff8038i.h 1.0.2 2020/01/26 * * Authors: Sarah Walker, * Miran Grca, @@ -20,6 +20,7 @@ typedef struct { uint8_t command, status, ptr0, enabled; + uint16_t base, pad; uint32_t ptr, ptr_cur, addr; int count, eot, @@ -30,7 +31,7 @@ typedef struct extern const device_t sff8038i_device; -extern void sff_bus_master_handlers(sff8038i_t *dev, uint16_t old_base, uint16_t new_base, int enabled); +extern void sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base); extern int sff_bus_master_dma_read(int channel, uint8_t *data, int transfer_length, void *priv); extern int sff_bus_master_dma_write(int channel, uint8_t *data, int transfer_length, void *priv); diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index 683ade1fc..8f29d4fa4 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -30,15 +30,15 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../pic.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "pic.h" +#include "cpu.h" +#include "machine.h" +#include "timer.h" +#include "plat.h" +#include "ui.h" #include "hdc.h" #include "hdd.h" @@ -463,7 +463,7 @@ mfm_readw(uint16_t port, void *priv) mfm->secount = (mfm->secount - 1) & 0xff; if (mfm->secount) { next_sector(mfm); - mfm->status = STAT_BUSY; + mfm->status = STAT_BUSY | STAT_READY | STAT_DSC; timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); } else ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index a980ec6e8..f096879c6 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -77,16 +77,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../ui.h" -#include "../plat.h" -#include "../dma.h" -#include "../pic.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "timer.h" +#include "device.h" +#include "ui.h" +#include "plat.h" +#include "dma.h" +#include "pic.h" #include "hdc.h" #include "hdd.h" diff --git a/src/disk/hdc_xta.c b/src/disk/hdc_xta.c index c821ef98d..9a3d57186 100644 --- a/src/disk/hdc_xta.c +++ b/src/disk/hdc_xta.c @@ -94,16 +94,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" +#include "plat.h" +#include "ui.h" #include "hdc.h" #include "hdd.h" diff --git a/src/disk/hdc_xtide.c b/src/disk/hdc_xtide.c index 2e7a5b359..26ef50cb8 100644 --- a/src/disk/hdc_xtide.c +++ b/src/disk/hdc_xtide.c @@ -36,11 +36,11 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "hdc.h" #include "hdc_ide.h" diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 97bbf3ddb..6163e8e06 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -20,11 +20,11 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "plat.h" +#include "ui.h" #include "hdd.h" -#include "../cdrom/cdrom.h" +#include "cdrom.h" hard_disk_t hdd[HDD_NUM]; diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index 6a6e4ee02..7002c0634 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -28,9 +28,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../plat.h" -#include "../random.h" +#include "86box.h" +#include "plat.h" +#include "random.h" #include "hdd.h" diff --git a/src/disk/hdd_table.c b/src/disk/hdd_table.c index 0ef0829e1..7a68fdb99 100644 --- a/src/disk/hdd_table.c +++ b/src/disk/hdd_table.c @@ -22,7 +22,7 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "hdd.h" diff --git a/src/disk/zip.c b/src/disk/zip.c index 1bbec776b..429c68dab 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -22,16 +22,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../config.h" -#include "../timer.h" -#include "../device.h" -#include "../piix.h" -#include "../scsi/scsi_device.h" -#include "../nvr.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "timer.h" +#include "config.h" +#include "timer.h" +#include "device.h" +#include "piix.h" +#include "scsi_device.h" +#include "nvr.h" +#include "plat.h" +#include "ui.h" #include "hdc.h" #include "hdc_ide.h" #include "zip.h" @@ -815,8 +815,14 @@ zip_update_request_length(zip_t *dev, int len, int block_len) /* For media access commands, make sure the requested DRQ length matches the block length. */ switch (dev->current_cdb[0]) { case 0x08: + case 0x0a: case 0x28: + case 0x2a: case 0xa8: + case 0xaa: + /* Round it to the nearest 2048 bytes. */ + dev->max_transfer_len = (dev->max_transfer_len >> 9) << 9; + /* Make sure total length is not bigger than sum of the lengths of all the requested blocks. */ bt = (dev->requested_blocks * block_len); diff --git a/src/dma.c b/src/dma.c index f9a02f365..802c0e836 100644 --- a/src/dma.c +++ b/src/dma.c @@ -8,7 +8,7 @@ * * Implementation of the Intel DMA controllers. * - * Version: @(#)dma.c 1.0.8 2020/01/14 + * Version: @(#)dma.c 1.0.9 2020/01/26 * * Authors: Sarah Walker, * Miran Grca, @@ -23,17 +23,12 @@ #include #include #include "86box.h" -#ifdef USE_NEW_DYNAREC -#include "cpu_new/cpu.h" -#include "cpu_new/x86.h" -#else -#include "cpu/cpu.h" -#include "cpu/x86.h" -#endif +#include "cpu_common/cpu.h" +#include "cpu_common/x86.h" #include "machine/machine.h" #include "mca.h" #include "mem.h" -#include "io.h" +#include "86box_io.h" #include "dma.h" @@ -672,6 +667,20 @@ dma_alias_set(void) } +void +dma_alias_set_piix(void) +{ + io_sethandler(0x0090, 1, + dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); + io_sethandler(0x0094, 3, + dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); + io_sethandler(0x0098, 1, + dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); + io_sethandler(0x009C, 3, + dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); +} + + void dma_alias_remove(void) { diff --git a/src/dma.h b/src/dma.h index 5340ba2ea..7761107f1 100644 --- a/src/dma.h +++ b/src/dma.h @@ -8,7 +8,7 @@ * * Definitions for the Intel DMA controller. * - * Version: @(#)dma.h 1.0.3 2020/01/14 + * Version: @(#)dma.h 1.0.4 2020/01/26 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -86,6 +86,7 @@ extern int dma_channel_read(int channel); extern int dma_channel_write(int channel, uint16_t val); extern void dma_alias_set(void); +extern void dma_alias_set_piix(void); extern void dma_alias_remove(void); extern void dma_alias_remove_piix(void); diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 495f8c3d1..d4eebc796 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -9,13 +9,13 @@ * Implementation of the NEC uPD-765 and compatible floppy disk * controller. * - * Version: @(#)fdc.c 1.0.21 2019/10/20 + * Version: @(#)fdc.c 1.0.22 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -24,15 +24,15 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../timer.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "cpu.h" +#include "machine.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "timer.h" +#include "ui.h" #include "fdd.h" #include "fdc.h" @@ -702,10 +702,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->stat = 0x00; fdc->pnum = fdc->ptot = 0; } - if (val&4) { - fdc->stat = 0x80; - fdc->pnum = fdc->ptot = 0; - } if ((val&4) && !(fdc->dor&4)) { timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); fdc->interrupt = -1; @@ -775,7 +771,16 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->stat |= 0x10; fdc_log("Starting FDC command %02X\n",fdc->command); - switch (fdc->command & 0x1f) { + if (((fdc->command & 0x1f) == 0x02) || ((fdc->command & 0x1f) == 0x05) || + ((fdc->command & 0x1f) == 0x06) || ((fdc->command & 0x1f) == 0x0a) || + ((fdc->command & 0x1f) == 0x0c) || ((fdc->command & 0x1f) == 0x0d) || + ((fdc->command & 0x1f) == 0x11) || ((fdc->command & 0x1f) == 0x16) || + ((fdc->command & 0x1f) == 0x19) || ((fdc->command & 0x1f) == 0x1d)) + fdc->processed_cmd = fdc->command & 0x1f; + else + fdc->processed_cmd = fdc->command; + + switch (fdc->processed_cmd) { case 0x01: /*Mode*/ if (fdc->flags & FDC_FLAG_NSC) { fdc->pnum = 0; @@ -921,7 +926,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } if (fdc->pnum == fdc->ptot) { fdc_log("Got all params %02X\n", fdc->command); - fdc->interrupt = fdc->command & 0x1F; + fdc->interrupt = fdc->processed_cmd; fdc->reset_stat = 0; /* Disable timer if enabled. */ timer_disable(&fdc->timer); @@ -950,7 +955,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) break; } /* Process the firt phase of the command. */ - switch (fdc->interrupt & 0x1F) { + switch (fdc->processed_cmd) { case 0x02: /* Read a track */ fdc_io_command_phase1(fdc, 0); fdc->read_track_sector.id.c = fdc->params[1]; @@ -1072,7 +1077,8 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->stat = (1 << fdc->drive); if (!(fdc->flags & FDC_FLAG_PCJR)) fdc->stat |= 0x80; - fdc->head = (fdc->params[0] & 4) ? 1 : 0; + /* fdc->head = (fdc->params[0] & 4) ? 1 : 0; */ + fdc->head = 0; /* TODO: See if this is correct. */ fdc->st0 = fdc->params[0] & 0x03; fdc->st0 |= (fdc->params[0] & 4); fdc->st0 |= 0x80; @@ -1210,21 +1216,22 @@ fdc_read(uint16_t addr, void *priv) } } else { if (is486 || !fdc->enable_3f1) - return 0xff; + ret = 0xff; + else { + ret = 0x70; - ret = 0x70; + drive = real_drive(fdc, fdc->dor & 3); - drive = real_drive(fdc, fdc->dor & 3); + if (drive) + ret &= ~0x40; + else + ret &= ~0x20; - if (drive) - ret &= ~0x40; - else - ret &= ~0x20; - - if (fdc->dor & 0x10) - ret |= 1; - if (fdc->dor & 0x20) - ret |= 2; + if (fdc->dor & 0x10) + ret |= 1; + if (fdc->dor & 0x20) + ret |= 2; + } } break; case 2: @@ -1994,6 +2001,13 @@ fdc_set_swap(fdc_t *fdc, uint8_t swap) } +void +fdc_set_irq(fdc_t *fdc, int irq) +{ + fdc->irq = irq; +} + + void fdc_set_base(fdc_t *fdc, int base) { diff --git a/src/floppy/fdc.h b/src/floppy/fdc.h index c6c3a90bf..4fae14c62 100644 --- a/src/floppy/fdc.h +++ b/src/floppy/fdc.h @@ -9,15 +9,15 @@ * Implementation of the NEC uPD-765 and compatible floppy disk * controller. * - * Version: @(#)fdc.h 1.0.8 2019/10/20 + * Version: @(#)fdc.h 1.0.9 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2018,2019 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2018-2020 Fred N. van Kempen. */ #ifndef EMU_FDC_H # define EMU_FDC_H @@ -36,7 +36,7 @@ typedef struct { - uint8_t dor, stat, command, dat, st0, swap; + uint8_t dor, stat, command, processed_cmd, dat, st0, swap; uint8_t swwp, disable_write; uint8_t params[256], res[256]; uint8_t specify[256], format_dat[256]; @@ -154,6 +154,7 @@ extern int fdc_is_verify(fdc_t *fdc); extern void fdc_overrun(fdc_t *fdc); extern void fdc_set_base(fdc_t *fdc, int base); +extern void fdc_set_irq(fdc_t *fdc, int irq); extern int fdc_getdata(fdc_t *fdc, int last); extern int fdc_data(fdc_t *fdc, uint8_t data); diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 24bd46313..37f100002 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -24,10 +24,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" +#include "ui.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_fdi.h" diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 860c424c2..8eb4d0f42 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -26,13 +26,13 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../dma.h" -#include "../nvr.h" -#include "../random.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "timer.h" +#include "dma.h" +#include "nvr.h" +#include "random.h" +#include "plat.h" +#include "ui.h" #include "fdd.h" #include "fdc.h" #include "fdd_86f.h" @@ -826,7 +826,7 @@ d86f_byteperiod(int drive) int d86f_is_mfm(int drive) { - return (d86f_track_flags(drive) & 8) ? 1 : 0; + return ((d86f_track_flags(drive) & 0x18) == 0x08) ? 1 : 0; } diff --git a/src/floppy/fdd_common.c b/src/floppy/fdd_common.c index 3b3bfa338..3ad3db4aa 100644 --- a/src/floppy/fdd_common.c +++ b/src/floppy/fdd_common.c @@ -19,8 +19,8 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" +#include "86box.h" +#include "timer.h" #include "fdd.h" #include "fdd_common.h" diff --git a/src/floppy/fdd_fdi.c b/src/floppy/fdd_fdi.c index f9e42ed6b..04315377a 100644 --- a/src/floppy/fdd_fdi.c +++ b/src/floppy/fdd_fdi.c @@ -26,9 +26,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_img.h" diff --git a/src/floppy/fdd_imd.c b/src/floppy/fdd_imd.c index a9c9c21fa..14078ee01 100644 --- a/src/floppy/fdd_imd.c +++ b/src/floppy/fdd_imd.c @@ -23,9 +23,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_imd.h" diff --git a/src/floppy/fdd_img.c b/src/floppy/fdd_img.c index e1417254a..54039a320 100644 --- a/src/floppy/fdd_img.c +++ b/src/floppy/fdd_img.c @@ -30,10 +30,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../config.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "config.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_img.h" diff --git a/src/floppy/fdd_json.c b/src/floppy/fdd_json.c index 465e1d6a0..9b96f0c3b 100644 --- a/src/floppy/fdd_json.c +++ b/src/floppy/fdd_json.c @@ -51,9 +51,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdc.h" diff --git a/src/floppy/fdd_mfm.c b/src/floppy/fdd_mfm.c index 507a0c0a2..13d9e88a0 100644 --- a/src/floppy/fdd_mfm.c +++ b/src/floppy/fdd_mfm.c @@ -22,9 +22,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_img.h" diff --git a/src/floppy/fdd_td0.c b/src/floppy/fdd_td0.c index a230a7ae8..b7517f437 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -35,9 +35,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_td0.h" diff --git a/src/floppy/fdi2raw.c b/src/floppy/fdi2raw.c index d01054e97..bf54babfb 100644 --- a/src/floppy/fdi2raw.c +++ b/src/floppy/fdi2raw.c @@ -37,7 +37,7 @@ /* ELSE */ #define xmalloc malloc #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "fdi2raw.h" diff --git a/src/game/gameport.c b/src/game/gameport.c index e41489111..f2c545a26 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -39,12 +39,12 @@ #include #include #include -#include "../86box.h" -#include "../machine/machine.h" -#include "../cpu/cpu.h" -#include "../device.h" -#include "../io.h" -#include "../timer.h" +#include "86box.h" +#include "machine.h" +#include "cpu.h" +#include "device.h" +#include "86box_io.h" +#include "timer.h" #include "gameport.h" #include "joystick_ch_flightstick_pro.h" #include "joystick_standard.h" diff --git a/src/game/joystick_ch_flightstick_pro.c b/src/game/joystick_ch_flightstick_pro.c index 062e753a6..5b7b99da8 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -39,9 +39,9 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "timer.h" #include "gameport.h" #include "joystick_standard.h" diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index e207b5173..29b31f590 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -39,9 +39,9 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "timer.h" #include "gameport.h" #include "joystick_standard.h" diff --git a/src/game/joystick_sw_pad.c b/src/game/joystick_sw_pad.c index 09030d8ad..5a8c0d284 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -60,9 +60,9 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "timer.h" #include "gameport.h" #include "joystick_sw_pad.h" diff --git a/src/game/joystick_tm_fcs.c b/src/game/joystick_tm_fcs.c index 69fa19d2b..afb4ac1b5 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -39,9 +39,9 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "timer.h" #include "gameport.h" #include "joystick_standard.h" diff --git a/src/hwm.c b/src/hwm.c new file mode 100644 index 000000000..b3142c7a4 --- /dev/null +++ b/src/hwm.c @@ -0,0 +1,36 @@ +/* + * 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. + * + * Common functions for hardware monitor chips. + * + * Version: @(#)hwm.c 1.0.0 2020/03/22 + * + * Author: RichardG, + * Copyright 2020 RichardG. + */ + +#include +#include "device.h" +#include "hwm.h" + + +hwm_values_t hwm_values; + + +void +hwm_set_values(hwm_values_t new_values) +{ + hwm_values = new_values; +} + + +hwm_values_t* +hwm_get_values() +{ + return &hwm_values; +} diff --git a/src/hwm.h b/src/hwm.h new file mode 100644 index 000000000..c5d482fb7 --- /dev/null +++ b/src/hwm.h @@ -0,0 +1,38 @@ +/* + * 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. + * + * Definitions for the hardware monitor chips. + * + * Version: @(#)hwm.h 1.0.0 2020/03/21 + * + * Author: RichardG, + * Copyright 2020 RichardG. + */ +#ifndef EMU_HWM_H +# define EMU_HWM_H + + +#define VDIV(v, r1, r2) (((v) * (r2)) / ((r1) + (r2))) + + +typedef struct _hwm_values_ { + uint16_t fans[4]; + uint8_t temperatures[4]; + uint8_t voltages[8]; +} hwm_values_t; + + +extern void hwm_set_values(hwm_values_t new_values); +extern hwm_values_t* hwm_get_values(); + + +extern const device_t w83781d_device; +extern const device_t as99127f_device; + + +#endif /*EMU_HWM_H*/ diff --git a/src/hwm_w83781d.c b/src/hwm_w83781d.c new file mode 100644 index 000000000..1f6b3ab26 --- /dev/null +++ b/src/hwm_w83781d.c @@ -0,0 +1,482 @@ +/* + * 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. + * + * Emulation of the Winbond W83781D hardware monitoring chip. + * + * Version: @(#)hwm_w83781d.c 1.0.0 2020/03/21 + * + * Author: RichardG, + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "smbus.h" +#include "hwm.h" + + +#define W83781D_SMBUS 0x10000 +#define W83781D_AS99127F 0x20000 +#define W83781D_VENDOR_ID ((dev->local & W83781D_AS99127F) ? 0x12C3 : 0x5CA3) + +#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) +#define W83781D_RPM_TO_REG(r, d) CLAMP(1350000 / (r * d), 1, 255) +#define W83781D_TEMP_TO_REG(t) ((t) * 8) << 5 + + +typedef struct { + uint32_t local; + hwm_values_t* values; + + uint8_t regs[64]; + uint8_t regs_bank1[6]; + uint8_t regs_bank2[6]; + uint8_t addr_register; + uint8_t data_register; + + uint8_t smbus_addr_main; + uint8_t smbus_addr_temp2; + uint8_t smbus_addr_temp3; + uint8_t hbacs; + uint8_t active_bank; +} w83781d_t; + + +static uint8_t w83781d_isa_read(uint16_t port, void *priv); +static uint8_t w83781d_smbus_read_byte(uint8_t addr, void *priv); +static uint8_t w83781d_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); +static uint16_t w83781d_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv); +static uint8_t w83781d_read(w83781d_t *dev, uint8_t reg, uint8_t bank); +static void w83781d_isa_write(uint16_t port, uint8_t val, void *priv); +static void w83781d_smbus_write_byte(uint8_t addr, uint8_t val, void *priv); +static void w83781d_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv); +static void w83781d_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv); +static uint8_t w83781d_write(w83781d_t *dev, uint8_t reg, uint8_t val, uint8_t bank); +static void w83781d_reset(w83781d_t *dev, uint8_t initialization); + + +static void +w83781d_remap(w83781d_t *dev) +{ + if (!(dev->local & W83781D_SMBUS)) return; + + smbus_removehandler(0x00, 0x80, + w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, + w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, + dev); + + if (dev->smbus_addr_main) smbus_sethandler(dev->smbus_addr_main, 1, + w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, + w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, + dev); + + if (dev->smbus_addr_temp2) smbus_sethandler(dev->smbus_addr_temp2, 1, + w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, + w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, + dev); + + if (dev->smbus_addr_temp3) smbus_sethandler(dev->smbus_addr_temp3, 1, + w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, + w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, + dev); +} + + +static uint8_t +w83781d_isa_read(uint16_t port, void *priv) +{ + w83781d_t *dev = (w83781d_t *) priv; + uint8_t ret = 0xFF; + + switch (port - (dev->local & 0xFFFF)) { + case 0x0: + ret = dev->addr_register & 0x7F; + break; + case 0x1: + ret = w83781d_read(dev, dev->addr_register, dev->active_bank); + + if (dev->active_bank == 0 && + (dev->addr_register == 0x41 || dev->addr_register == 0x43 || dev->addr_register == 0x45 || dev->addr_register == 0x56 || + (dev->addr_register >= 0x60 && dev->addr_register < 0x7F))) { + /* auto-increment registers */ + dev->addr_register++; + } + break; + } + + return ret; +} + + +static uint8_t +w83781d_smbus_read_byte(uint8_t addr, void *priv) +{ + w83781d_t *dev = (w83781d_t *) priv; + + return w83781d_read(dev, dev->addr_register, 0); +} + + +static uint8_t +w83781d_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + w83781d_t *dev = (w83781d_t *) priv; + + return w83781d_read(dev, cmd, 0); +} + + +static uint16_t +w83781d_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + w83781d_t *dev = (w83781d_t *) priv; + uint8_t rethi = 0; + uint8_t retlo = 0; + uint8_t bank = 0; + + if (addr == dev->smbus_addr_temp2 || addr == dev->smbus_addr_temp3) { + if (addr == dev->smbus_addr_temp2) + bank = 2; + else + bank = 3; + + switch (cmd & 0x3) { + case 0x0: + rethi = w83781d_read(dev, 0x50, bank); + retlo = w83781d_read(dev, 0x51, bank); + break; + case 0x1: + rethi = retlo = w83781d_read(dev, 0x52, bank); + break; + case 0x2: + rethi = w83781d_read(dev, 0x53, bank); + retlo = w83781d_read(dev, 0x54, bank); + break; + case 0x3: + rethi = w83781d_read(dev, 0x55, bank); + retlo = w83781d_read(dev, 0x56, bank); + break; + } + + return (retlo << 8) | rethi; /* byte-swapped for some reason */ + } + + return w83781d_read(dev, cmd, bank); +} + + +static uint8_t +w83781d_read(w83781d_t *dev, uint8_t reg, uint8_t bank) +{ + uint8_t ret = 0; + + if ((reg >> 4) == 0x5 && bank != 0) { + /* bank-switched temperature registers */ + if (bank == 1) + ret = dev->regs_bank1[reg - 0x50]; + else + ret = dev->regs_bank2[reg - 0x50]; + } else { + /* regular registers */ + if (reg == 0x4F) /* special case for two-byte vendor ID register */ + ret = dev->hbacs ? (W83781D_VENDOR_ID >> 8) : (W83781D_VENDOR_ID & 0xFF); + else if (reg >= 0x60) /* read auto-increment value RAM registers from their non-auto-increment locations */ + ret = dev->regs[reg - 0x40]; + else + ret = dev->regs[reg - 0x20]; + } + + return ret; +} + + +static void +w83781d_isa_write(uint16_t port, uint8_t val, void *priv) +{ + w83781d_t *dev = (w83781d_t *) priv; + + switch (port - (dev->local & 0xFFFF)) { + case 0x0: + dev->addr_register = val & 0x7F; + break; + case 0x1: + w83781d_write(dev, dev->addr_register, val, dev->active_bank); + + if (dev->active_bank == 0 && + (dev->addr_register == 0x41 || dev->addr_register == 0x43 || dev->addr_register == 0x45 || dev->addr_register == 0x56 || + (dev->addr_register >= 0x60 && dev->addr_register < 0x7F))) { + /* auto-increment registers */ + dev->addr_register++; + } + break; + } +} + + +static void +w83781d_smbus_write_byte(uint8_t addr, uint8_t val, void *priv) +{ + w83781d_t *dev = (w83781d_t *) priv; + + dev->addr_register = val; +} + + +static void +w83781d_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) +{ + w83781d_t *dev = (w83781d_t *) priv; + + w83781d_write(dev, cmd, val, 0); +} + + +static void +w83781d_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) +{ + w83781d_t *dev = (w83781d_t *) priv; + uint8_t valhi = (val >> 8); + uint8_t vallo = (val & 0xFF); + uint8_t bank = 0; + + if (addr == dev->smbus_addr_temp2 || addr == dev->smbus_addr_temp3) { + if (addr == dev->smbus_addr_temp2) + bank = 2; + else + bank = 3; + + switch (cmd & 0x3) { + case 0x0: + w83781d_write(dev, 0x50, valhi, bank); + w83781d_write(dev, 0x51, vallo, bank); + break; + case 0x1: + w83781d_write(dev, 0x52, vallo, bank); + break; + case 0x2: + w83781d_write(dev, 0x53, valhi, bank); + w83781d_write(dev, 0x54, vallo, bank); + break; + case 0x3: + w83781d_write(dev, 0x55, valhi, bank); + w83781d_write(dev, 0x56, vallo, bank); + break; + break; + } + return; + } + + w83781d_write(dev, cmd, vallo, bank); +} + + +static uint8_t +w83781d_write(w83781d_t *dev, uint8_t reg, uint8_t val, uint8_t bank) +{ + uint8_t remap = 0; + + if ((reg >> 4) == 0x5 && bank != 0) { + /* bank-switched temperature registers */ + switch (reg) { + case 0x50: case 0x51: + /* read-only registers */ + return 0; + } + + if (bank == 1) + dev->regs_bank1[reg - 0x50] = val; + else + dev->regs_bank2[reg - 0x50] = val; + + return 1; + } + + /* regular registers */ + switch (reg) { + case 0x41: case 0x42: case 0x4F: case 0x58: + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2A: + case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6A: + /* read-only registers */ + return 0; + } + + if (reg >= 0x60) /* write auto-increment value RAM registers to their non-auto-increment locations */ + dev->regs[reg - 0x40] = val; + else + dev->regs[reg - 0x20] = val; + + switch (reg) { + case 0x40: + if (val >> 7) { + /* INITIALIZATION bit set: reset all registers except main SMBus address */ + w83781d_reset(dev, 1); + } + break; + case 0x47: + /* update FAN1/FAN2 values to match the new divisor */ + dev->regs[0x08] = W83781D_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x27] >> 4) & 0x3)); + dev->regs[0x09] = W83781D_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x27] >> 6) & 0x3)); + break; + case 0x48: + if (dev->local & W83781D_SMBUS) { + dev->smbus_addr_main = (dev->regs[0x28] & 0x7F); + remap = 1; + } + break; + case 0x4A: + if (dev->local & W83781D_SMBUS) { + /* DIS_T2 and DIS_T3 bits can disable those interfaces */ + if ((dev->regs[0x2A] >> 3) & 0x1) + dev->smbus_addr_temp2 = 0x00; + else + dev->smbus_addr_temp2 = 0x48 + (dev->regs[0x2A] & 0x7); + if (dev->regs[0x2A] >> 7) + dev->smbus_addr_temp3 = 0x00; + else + dev->smbus_addr_temp3 = 0x48 + ((dev->regs[0x2A] >> 4) & 0x7); + remap = 1; + } + break; + case 0x4B: + /* update FAN3 value to match the new divisor */ + dev->regs[0x0A] = W83781D_RPM_TO_REG(dev->values->fans[2], 1 << ((dev->regs[0x2B] >> 6) & 0x3)); + break; + case 0x4E: + dev->hbacs = (dev->regs[0x2E] & 0x80); + /* FIXME: Winbond's datasheet does not specify how BANKSEL[0:2] work */ + if (dev->regs[0x2E] & 0x1) + dev->active_bank = 0; + else if (dev->regs[0x2E] & 0x2) + dev->active_bank = 1; + else if (dev->regs[0x2E] & 0x4) + dev->active_bank = 2; + break; + } + + if (remap) + w83781d_remap(dev); + + return 1; +} + + +static void +w83781d_reset(w83781d_t *dev, uint8_t initialization) +{ + memset(dev->regs, 0, 64); + memset(dev->regs_bank1, 0, 6); + memset(dev->regs_bank2, 0, 6); + + /* WARNING: Array elements are register - 0x20. */ + uint8_t i; + for (i = 0; i <= 6; i++) + dev->regs[i] = dev->values->voltages[i]; + dev->regs[0x07] = dev->values->temperatures[0]; + for (i = 0; i <= 2; i++) + dev->regs[0x08 + i] = W83781D_RPM_TO_REG(dev->values->fans[i], 2); + dev->regs[0x20] = 0x01; + dev->regs[0x26] = 0x40; + dev->regs[0x27] = 0x50; + if (dev->local & W83781D_SMBUS) { + if (!initialization) /* don't reset main SMBus address if the reset was triggered by the INITIALIZATION bit */ + dev->smbus_addr_main = 0x2D; + dev->regs[0x28] = dev->smbus_addr_main; + dev->regs[0x2A] = 0x01; + dev->smbus_addr_temp2 = 0x48 + (dev->regs[0x2A] & 0x7); + dev->smbus_addr_temp3 = 0x48 + ((dev->regs[0x2A] >> 4) & 0x7); + } else { + dev->regs[0x28] = 0x00; + dev->regs[0x2A] = 0x88; + dev->smbus_addr_temp2 = dev->smbus_addr_temp3 = 0x00; + } + dev->regs[0x29] = 0x02; + dev->regs[0x2B] = 0x44; + dev->regs[0x2C] = 0x01; + dev->regs[0x2D] = 0x15; + dev->regs[0x2E] = 0x80; + dev->hbacs = (dev->regs[0x2E] & 0x80); + dev->regs[0x2F] = W83781D_VENDOR_ID >> 8; + dev->regs[0x37] = 0x80; + dev->regs[0x38] = (dev->local & W83781D_AS99127F) ? 0x31 : 0x10; + + /* WARNING: Array elements are register - 0x50. */ + uint16_t temp; + temp = W83781D_TEMP_TO_REG(dev->values->temperatures[1]); + dev->regs_bank1[0x0] = temp >> 8; + dev->regs_bank1[0x1] = temp & 0xFF; + dev->regs_bank1[0x3] = 0x4B; + dev->regs_bank1[0x5] = 0x50; + temp = W83781D_TEMP_TO_REG(dev->values->temperatures[2]); + dev->regs_bank2[0x0] = temp >> 8; + dev->regs_bank2[0x1] = temp & 0xFF; + dev->regs_bank2[0x3] = 0x4B; + dev->regs_bank2[0x5] = 0x50; + + w83781d_remap(dev); +} + + +static void +w83781d_close(void *priv) +{ + w83781d_t *dev = (w83781d_t *) priv; + + uint16_t isa_io = dev->local & 0xFFFF; + if (isa_io) + io_removehandler(isa_io, 2, w83781d_isa_read, NULL, NULL, w83781d_isa_write, NULL, NULL, dev); + + free(dev); +} + + +static void * +w83781d_init(const device_t *info) +{ + w83781d_t *dev = (w83781d_t *) malloc(sizeof(w83781d_t)); + memset(dev, 0, sizeof(w83781d_t)); + + dev->local = info->local; + dev->values = hwm_get_values(); + w83781d_reset(dev, 0); + + uint16_t isa_io = dev->local & 0xFFFF; + if (isa_io) + io_sethandler(isa_io, 2, w83781d_isa_read, NULL, NULL, w83781d_isa_write, NULL, NULL, dev); + + return dev; +} + + +const device_t w83781d_device = { + "Winbond W83781D Hardware Monitor", + DEVICE_ISA, + 0x295 | W83781D_SMBUS, + w83781d_init, w83781d_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +/* + * ASUS rebadged version of the W83781D. + * Some claim it's SMBus-only, yet the BIOS clearly reads most values over ISA, + * except TEMP3 (CPU Temperature) which is read over SMBus. + */ +const device_t as99127f_device = { + "ASUS AS99127F Hardware Monitor", + DEVICE_ISA, + 0x295 | W83781D_SMBUS | W83781D_AS99127F, + w83781d_init, w83781d_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/i82335.c b/src/i82335.c index 37cf60306..7be061601 100644 --- a/src/i82335.c +++ b/src/i82335.c @@ -4,7 +4,7 @@ #include #include #include -#include "io.h" +#include "86box_io.h" #include "mem.h" typedef struct diff --git a/src/ibm_5161.c b/src/ibm_5161.c index 7cf6fed64..2374bdec3 100644 --- a/src/ibm_5161.c +++ b/src/ibm_5161.c @@ -19,7 +19,7 @@ #include #include "86box.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "apm.h" #include "dma.h" #include "mem.h" @@ -27,7 +27,7 @@ #include "timer.h" #include "pit.h" #include "port_92.h" -#include "machine/machine.h" +#include "machine.h" #include "intel_sio.h" diff --git a/src/intel_flash.c b/src/intel_flash.c index 7530912f5..396899621 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -25,7 +25,7 @@ #include "86box.h" #include "device.h" #include "mem.h" -#include "machine/machine.h" +#include "machine.h" #include "timer.h" #include "nvr.h" #include "plat.h" @@ -97,7 +97,7 @@ flash_read(uint32_t addr, void *p) case CMD_IID: if (addr & 1) - ret = dev->flash_id & 0xff; + ret = dev->flash_id & 0xff; else ret = 0x89; break; @@ -314,6 +314,16 @@ intel_flash_add_mappings(flash_t *dev) } +static void +intel_flash_reset(void *priv) +{ + flash_t *dev = (flash_t *) priv; + + dev->command = CMD_READ_ARRAY; + dev->status = 0; +} + + static void * intel_flash_init(const device_t *info) { @@ -461,11 +471,11 @@ intel_flash_close(void *p) const device_t intel_flash_bxt_ami_device = { "Intel 28F001BXT/28F002BXT Flash BIOS", - 0, + DEVICE_PCI, FLAG_INV_A16, intel_flash_init, intel_flash_close, - NULL, + intel_flash_reset, NULL, NULL, NULL, NULL }; @@ -474,11 +484,11 @@ const device_t intel_flash_bxt_ami_device = const device_t intel_flash_bxtw_ami_device = { "Intel 28F100BXT/28F200BXT Flash BIOS", - 0, + DEVICE_PCI, FLAG_INV_A16 | FLAG_WORD, intel_flash_init, intel_flash_close, - NULL, + intel_flash_reset, NULL, NULL, NULL, NULL }; #endif @@ -487,10 +497,10 @@ const device_t intel_flash_bxtw_ami_device = const device_t intel_flash_bxt_device = { "Intel 28F001BXT/28F002BXT Flash BIOS", - 0, 0, + DEVICE_PCI, 0, intel_flash_init, intel_flash_close, - NULL, + intel_flash_reset, NULL, NULL, NULL, NULL }; @@ -498,9 +508,9 @@ const device_t intel_flash_bxt_device = const device_t intel_flash_bxb_device = { "Intel 28F001BXB/28F002BXB Flash BIOS", - 0, FLAG_BXB, + DEVICE_PCI, FLAG_BXB, intel_flash_init, intel_flash_close, - NULL, + intel_flash_reset, NULL, NULL, NULL, NULL }; diff --git a/src/intel_piix.c b/src/intel_piix.c index d5fdfc36f..09c46f37c 100644 --- a/src/intel_piix.c +++ b/src/intel_piix.c @@ -10,13 +10,13 @@ * word 0 - base address * word 1 - bits 1-15 = byte count, bit 31 = end of transfer * - * Version: @(#)intel_piix.c 1.0.22 2018/10/31 + * Version: @(#)intel_piix.c 1.0.23 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -26,34 +26,92 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cdrom/cdrom.h" -#include "cpu/cpu.h" -#include "scsi/scsi_device.h" -#include "scsi/scsi_cdrom.h" +#include "cdrom.h" +#include "cpu.h" +#include "scsi_device.h" +#include "scsi_cdrom.h" #include "dma.h" -#include "io.h" +#include "86box_io.h" #include "device.h" #include "apm.h" #include "keyboard.h" +#include "machine.h" #include "mem.h" +#include "timer.h" +#include "nvr.h" #include "pci.h" #include "pic.h" #include "port_92.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "disk/hdc_ide_sff8038i.h" -#include "disk/zip.h" -#include "machine/machine.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "hdc_ide_sff8038i.h" +#include "zip.h" +#include "machine.h" +#include "smbus.h" #include "piix.h" +#define ACPI_TIMER_FREQ 3579545 +#define PM_FREQ ACPI_TIMER_FREQ + +#define RSM_STS (1 << 15) +#define PWRBTN_STS (1 << 8) + +#define RTC_EN (1 << 10) +#define PWRBTN_EN (1 << 8) +#define GBL_EN (1 << 5) +#define TMROF_EN (1 << 0) + +#define SCI_EN (1 << 0) +#define SUS_EN (1 << 13) + +#define ACPI_ENABLE 0xf1 +#define ACPI_DISABLE 0xf0 + + typedef struct { - int type; - uint8_t cur_readout_reg, - readout_regs[256], - regs[256], regs_ide[256]; + uint16_t io_base; + int base_channel; +} ddma_t; + + +typedef struct +{ + uint8_t gpireg[3], gporeg[4]; + uint16_t pmsts, pmen, + pmcntrl; + uint32_t glbctl; + uint64_t tmr_overflow_time; + int timer_index; +} power_t; + + +typedef struct +{ + uint8_t stat, next_stat, ctl, cmd, addr, + data0, data1, + index, + data[32]; + pc_timer_t command_timer; +} piix_smbus_t; + + +typedef struct +{ + uint8_t cur_readout_reg, rev, + type, func_shift, + max_func, pci_slot, + regs[4][256], + readout_regs[256], board_config[2]; + uint16_t func0_id, + usb_io_base, power_io_base, + smbus_io_base; sff8038i_t *bm[2]; + ddma_t ddma[2]; + power_t power; + piix_smbus_t smbus; + nvr_t * nvr; } piix_t; @@ -77,15 +135,489 @@ piix_log(const char *fmt, ...) #endif -static void -piix_bus_master_handlers(piix_t *dev, uint16_t old_base) +static +void do_irq(piix_t *dev, int func, int level) { - uint16_t base; + if ((dev == NULL) || (func > dev->max_func) /*|| + (dev->regs[func][0x3d] < PCI_INTA) || (dev->regs[func][0x3d] < PCI_INTD)*/) + return; - base = (dev->regs_ide[0x20] & 0xf0) | (dev->regs_ide[0x21] << 8); + if (level) { +#ifdef WRONG_SPEC + pci_set_irq(dev->pci_slot, dev->regs[func][0x3d]); +#else + picintlevel(1 << 9); +#endif + piix_log("Raising IRQ...\n"); + } else { +#ifdef WRONG_SPEC + pci_clear_irq(dev->pci_slot, dev->regs[func][0x3d]); +#else + picintc(1 << 9); +#endif + piix_log("Lowering IRQ...\n"); + } +} - sff_bus_master_handlers(dev->bm[0], old_base, base, (dev->regs_ide[0x04] & 1)); - sff_bus_master_handlers(dev->bm[1], old_base + 8, base + 8, (dev->regs_ide[0x04] & 1)); + +static void +piix_ide_legacy_handlers(piix_t *dev, int bus) +{ + if (bus & 0x01) { + ide_pri_disable(); + if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x41] & 0x80)) + ide_pri_enable(); + } + + if (bus & 0x02) { + ide_sec_disable(); + if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x43] & 0x80)) + ide_sec_enable(); + } +} + + +static void +piix_ide_bm_handlers(piix_t *dev) +{ + uint16_t base = (dev->regs[1][0x20] & 0xf0) | (dev->regs[1][0x21] << 8); + + sff_bus_master_handler(dev->bm[0], (dev->regs[1][0x04] & 1), base); + sff_bus_master_handler(dev->bm[1], (dev->regs[1][0x04] & 1), base + 8); +} + + +static uint8_t +kbc_alias_reg_read(uint16_t addr, void *p) +{ + uint8_t ret = inb(0x61); + + return ret; +} + + +static void +kbc_alias_reg_write(uint16_t addr, uint8_t val, void *p) +{ + outb(0x61, val); +} + + +static void +kbc_alias_update_io_mapping(piix_t *dev) +{ + io_removehandler(0x0063, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_removehandler(0x0065, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_removehandler(0x0067, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + + if (dev->regs[0][0x4e] & 0x08) { + io_sethandler(0x0063, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_sethandler(0x0065, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_sethandler(0x0067, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + } +} + + +static uint8_t +ddma_reg_read(uint16_t addr, void *p) +{ + ddma_t *dev = (ddma_t *) p; + uint8_t ret = 0xff; + int rel_ch = (addr & 0x30) >> 4; + int ch = dev->base_channel + rel_ch; + int dmab = (ch >= 4) ? 0xc0 : 0x00; + + switch (addr & 0x0f) { + case 0x00: + ret = dma[ch].ac & 0xff; + break; + case 0x01: + ret = (dma[ch].ac >> 8) & 0xff; + break; + case 0x02: + ret = dma[ch].page; + break; + case 0x04: + ret = dma[ch].cc & 0xff; + break; + case 0x05: + ret = (dma[ch].cc >> 8) & 0xff; + break; + case 0x09: + ret = inb(dmab + 0x08); + break; + } + + return ret; +} + + +static void +ddma_reg_write(uint16_t addr, uint8_t val, void *p) +{ + ddma_t *dev = (ddma_t *) p; + int rel_ch = (addr & 0x30) >> 4; + int ch = dev->base_channel + rel_ch; + int page_regs[4] = { 7, 3, 1, 2 }; + int i, dmab = (ch >= 4) ? 0xc0 : 0x00; + + switch (addr & 0x0f) { + case 0x00: + dma[ch].ab = (dma[ch].ab & 0xffff00) | val; + dma[ch].ac = dma[ch].ab; + break; + case 0x01: + dma[ch].ab = (dma[ch].ab & 0xff00ff) | (val << 8); + dma[ch].ac = dma[ch].ab; + break; + case 0x02: + if (ch >= 4) + outb(0x88 + page_regs[rel_ch], val); + else + outb(0x80 + page_regs[rel_ch], val); + break; + case 0x04: + dma[ch].cb = (dma[ch].cb & 0xffff00) | val; + dma[ch].cc = dma[ch].cb; + break; + case 0x05: + dma[ch].cb = (dma[ch].cb & 0xff00ff) | (val << 8); + dma[ch].cc = dma[ch].cb; + break; + case 0x08: + outb(dmab + 0x08, val); + break; + case 0x09: + outb(dmab + 0x09, val); + break; + case 0x0a: + outb(dmab + 0x0a, val); + break; + case 0x0b: + outb(dmab + 0x0b, val); + break; + case 0x0d: + outb(dmab + 0x0d, val); + break; + case 0x0e: + for (i = 0; i < 4; i++) + outb(dmab + 0x0a, i); + break; + case 0x0f: + outb(dmab + 0x0a, (val << 2) | rel_ch); + break; + } +} + + +static void +ddma_update_io_mapping(piix_t *dev, int n) +{ + int base_reg = 0x92 + (n << 1); + + if (dev->ddma[n].io_base != 0x0000) + io_removehandler(dev->usb_io_base, 0x40, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->ddma[n]); + + dev->ddma[n].io_base = (dev->regs[0][base_reg] & ~0x3f) | (dev->regs[0][base_reg + 1] << 8); + + if (dev->ddma[n].io_base != 0x0000) + io_sethandler(dev->ddma[n].io_base, 0x40, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->ddma[n]); +} + + +static uint8_t +usb_reg_read(uint16_t addr, void *p) +{ + uint8_t ret = 0xff; + + switch (addr & 0x1f) { + case 0x10: case 0x11: case 0x12: case 0x13: + /* Port status */ + ret = 0x00; + break; + } + + return ret; +} + + +static void +usb_reg_write(uint16_t addr, uint8_t val, void *p) +{ +} + + +static void +usb_update_io_mapping(piix_t *dev) +{ + if (dev->usb_io_base != 0x0000) + io_removehandler(dev->usb_io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, dev); + + dev->usb_io_base = (dev->regs[2][0x20] & ~0x1f) | (dev->regs[2][0x21] << 8); + + if ((dev->regs[2][PCI_REG_COMMAND] & PCI_COMMAND_IO) && (dev->usb_io_base != 0x0000)) + io_sethandler(dev->usb_io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, dev); +} + + +static uint32_t +power_reg_readl(uint16_t addr, void *p) +{ + piix_t *dev = (piix_t *) p; + uint32_t timer; + uint32_t ret = 0xffffffff; + + switch (addr & 0x3c) { + case 0x08: + /* ACPI timer */ + timer = (tsc * ACPI_TIMER_FREQ) / machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed; + timer &= 0x00ffffff; + ret = timer; + break; + } + + piix_log("ACPI: Read L %08X from %04X\n", ret, addr); + + return ret; +} + + +static uint16_t +power_reg_readw(uint16_t addr, void *p) +{ + piix_t *dev = (piix_t *) p; + uint16_t ret = 0xffff; + uint32_t ret32; + + switch (addr & 0x3c) { + case 0x00: + break; + default: + ret32 = power_reg_readl(addr, p); + if (addr & 0x02) + ret = (ret32 >> 16) & 0xffff; + else + ret = ret32 & 0xffff; + break; + } + + piix_log("ACPI: Read W %08X from %04X\n", ret, addr); + + return ret; +} + + +static uint8_t +power_reg_read(uint16_t addr, void *p) +{ + piix_t *dev = (piix_t *) p; + uint32_t timer; + uint8_t ret = 0xff; + uint16_t ret16; + + switch (addr & 0x3f) { + case 0x30: case 0x31: case 0x32: + ret = dev->power.gporeg[addr & 0x03]; + piix_log("ACPI: Read B %02X from GPIREG %01X\n", ret, addr & 0x03); + break; + case 0x34: case 0x35: case 0x36: case 0x37: + ret = dev->power.gporeg[addr & 0x03]; + piix_log("ACPI: Read B %02X from GPOREG %01X\n", ret, addr & 0x03); + break; + default: + ret16 = power_reg_readw(addr, p); + if (addr & 0x01) + ret = (ret16 >> 8) & 0xff; + else + ret = ret16 & 0xff; + break; + } + + return ret; +} + + +static void +power_reg_write(uint16_t addr, uint8_t val, void *p) +{ + piix_t *dev = (piix_t *) p; + + piix_log("ACPI: Write %02X to %04X\n", val, addr); + + switch (addr & 0x3f) { + case 0x34: case 0x35: case 0x36: case 0x37: + dev->power.gporeg[addr & 0x03] = val; + break; + } +} + + +static void +power_update_io_mapping(piix_t *dev) +{ + if (dev->power_io_base != 0x0000) + io_removehandler(dev->power_io_base, 0x40, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, dev); + + dev->power_io_base = (dev->regs[3][0x41] << 8) | (dev->regs[3][0x40] & 0xc0); + + if ((dev->regs[3][0x80] & 0x01) && (dev->power_io_base != 0x0000)) + io_sethandler(dev->power_io_base, 0x40, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, dev); +} + + +static uint8_t +smbus_reg_read(uint16_t addr, void *priv) +{ + piix_t *dev = (piix_t *) priv; + uint8_t ret = 0x00; + + switch (addr - dev->smbus_io_base) { + case 0x00: + ret = dev->smbus.stat; + break; + case 0x02: + dev->smbus.index = 0; + ret = dev->smbus.ctl; + break; + case 0x03: + ret = dev->smbus.cmd; + break; + case 0x04: + ret = dev->smbus.addr; + break; + case 0x05: + ret = dev->smbus.data0; + break; + case 0x06: + ret = dev->smbus.data1; + break; + case 0x07: + ret = dev->smbus.data[dev->smbus.index++]; + if (dev->smbus.index > 31) + dev->smbus.index = 0; + break; + } + + piix_log("smbus_reg_read %02x %02x\n", addr - dev->smbus_io_base, ret); + + return ret; +} + + +static void +smbus_reg_write(uint16_t addr, uint8_t val, void *priv) +{ + piix_t *dev = (piix_t *) priv; + uint8_t smbus_addr; + uint8_t smbus_read; + uint16_t temp; + + piix_log("smbus_reg_write %02x %02x\n", addr - dev->smbus_io_base, val); + + dev->smbus.next_stat = 0; + switch (addr - dev->smbus_io_base) { + case 0x00: + /* some status bits are reset by writing 1 to them */ + for (smbus_addr = 0x02; smbus_addr <= 0x10; smbus_addr = smbus_addr << 1) { + if (val & smbus_addr) + dev->smbus.stat = dev->smbus.stat & ~smbus_addr; + } + break; + case 0x02: + dev->smbus.ctl = val & ~(0x40); /* START always reads 0 */ + if (val & 0x40) { /* dispatch command if START is set */ + smbus_addr = (dev->smbus.addr >> 1); + if (!smbus_has_device(smbus_addr)) { + /* raise DEV_ERR if no device is at this address */ + dev->smbus.next_stat = 0x4; + break; + } + smbus_read = (dev->smbus.addr & 0x01); + + switch ((val >> 2) & 0x7) { + case 0x0: /* quick R/W */ + dev->smbus.next_stat = 0x2; + break; + case 0x1: /* byte R/W */ + if (smbus_read) + dev->smbus.data0 = smbus_read_byte(smbus_addr); + else + smbus_write_byte(smbus_addr, dev->smbus.data0); + dev->smbus.next_stat = 0x2; + break; + case 0x2: /* byte data R/W */ + if (smbus_read) + dev->smbus.data0 = smbus_read_byte_cmd(smbus_addr, dev->smbus.cmd); + else + smbus_write_byte_cmd(smbus_addr, dev->smbus.cmd, dev->smbus.data0); + dev->smbus.next_stat = 0x2; + break; + case 0x3: /* word data R/W */ + if (smbus_read) { + temp = smbus_read_word_cmd(smbus_addr, dev->smbus.cmd); + dev->smbus.data0 = (temp & 0xFF); + dev->smbus.data1 = (temp >> 8); + } else { + temp = (dev->smbus.data1 << 8) | dev->smbus.data0; + smbus_write_word_cmd(smbus_addr, dev->smbus.cmd, temp); + } + dev->smbus.next_stat = 0x2; + break; + case 0x5: /* block R/W */ + if (smbus_read) + dev->smbus.data0 = smbus_read_block_cmd(smbus_addr, dev->smbus.cmd, dev->smbus.data); + else + smbus_write_block_cmd(smbus_addr, dev->smbus.cmd, dev->smbus.data, dev->smbus.data0); + dev->smbus.next_stat = 0x2; + break; + } + } + break; + case 0x03: + dev->smbus.cmd = val; + break; + case 0x04: + dev->smbus.addr = val; + break; + case 0x05: + dev->smbus.data0 = val; + break; + case 0x06: + dev->smbus.data1 = val; + break; + case 0x07: + dev->smbus.data[dev->smbus.index++] = val; + if (dev->smbus.index > 31) + dev->smbus.index = 0; + break; + } + + if (dev->smbus.next_stat) { + dev->smbus.stat = 0x1; + timer_disable(&dev->smbus.command_timer); + timer_set_delay_u64(&dev->smbus.command_timer, 10 * TIMER_USEC); + } +} + + +static void +smbus_inter(void *priv) +{ + piix_t *dev = (piix_t *) priv; + dev->smbus.stat = dev->smbus.next_stat; +} + + +static void +smbus_update_io_mapping(piix_t *dev) +{ + if (dev->smbus_io_base != 0x0000) + io_removehandler(dev->smbus_io_base, 0x10, smbus_reg_read, NULL, NULL, smbus_reg_write, NULL, NULL, dev); + + dev->smbus_io_base = (dev->regs[3][0x91] << 8) | (dev->regs[3][0x90] & 0xf0); + + if ((dev->regs[3][PCI_REG_COMMAND] & PCI_COMMAND_IO) && (dev->regs[3][0xd2] & 0x01) && (dev->smbus_io_base != 0x0000)) + io_sethandler(dev->smbus_io_base, 0x10, smbus_reg_read, NULL, NULL, smbus_reg_write, NULL, NULL, dev); } @@ -93,161 +625,391 @@ static void piix_write(int func, int addr, uint8_t val, void *priv) { piix_t *dev = (piix_t *) priv; - uint8_t valxor; - uint16_t old_base; + uint8_t *fregs; - if ((func == 1) && (dev->type & 0x100)) /* PB640's PIIX has no IDE part. */ + /* Return on unsupported function. */ + if (func > dev->max_func) return; - if (func > 1) - return; + piix_log("PIIX function %i write: %02X to %02X\n", func, val, addr); + fregs = (uint8_t *) dev->regs[func]; - old_base = (dev->regs_ide[0x20] & 0xf0) | (dev->regs_ide[0x21] << 8); - - if (func == 1) { /*IDE*/ - piix_log("PIIX IDE write: %02X %02X\n", addr, val); - valxor = val ^ dev->regs_ide[addr]; - - switch (addr) { - case 0x04: - dev->regs_ide[0x04] = (val & 5) | 2; - if (valxor & 0x01) { - ide_pri_disable(); - ide_sec_disable(); - if (val & 0x01) { - if (dev->regs_ide[0x41] & 0x80) - ide_pri_enable(); - if (dev->regs_ide[0x43] & 0x80) - ide_sec_enable(); - } - - piix_bus_master_handlers(dev, old_base); - } - break; - case 0x07: - dev->regs_ide[0x07] = val & 0x3e; - break; - case 0x0d: - dev->regs_ide[0x0d] = val; - break; - - case 0x20: - dev->regs_ide[0x20] = (val & ~0x0f) | 1; - if (valxor) - piix_bus_master_handlers(dev, old_base); - break; - case 0x21: - dev->regs_ide[0x21] = val; - if (valxor) - piix_bus_master_handlers(dev, old_base); - break; - - case 0x40: - dev->regs_ide[0x40] = val; - break; - case 0x41: - dev->regs_ide[0x41] = val; - if (valxor & 0x80) { - ide_pri_disable(); - if ((val & 0x80) && (dev->regs_ide[0x04] & 0x01)) - ide_pri_enable(); - } - break; - case 0x42: - dev->regs_ide[0x42] = val; - break; - case 0x43: - dev->regs_ide[0x43] = val; - if (valxor & 0x80) { - ide_sec_disable(); - if ((val & 0x80) && (dev->regs_ide[0x04] & 0x01)) - ide_sec_enable(); - } - break; - case 0x44: - if (dev->type >= 3) dev->regs_ide[0x44] = val; - break; - } - } else { - piix_log("PIIX writing value %02X to register %02X\n", val, addr); - valxor = val ^ dev->regs[addr]; - - if ((addr >= 0x0f) && (addr < 0x4c)) + if (func == 0) switch (addr) { + case 0x04: + fregs[0x04] = (val & 0x08) | 0x07; + break; + case 0x05: + if (dev->type > 1) + fregs[0x05] = (val & 0x01); + break; + case 0x07: + if ((val & 0x40) && (dev->type > 1)) + fregs[0x07] &= 0xbf; + if (val & 0x20) + fregs[0x07] &= 0xdf; + if (val & 0x10) + fregs[0x07] &= 0xef; + if (val & 0x08) + fregs[0x07] &= 0xf7; + if (val & 0x04) + fregs[0x07] &= 0xfb; + break; + case 0x4c: + fregs[0x4c] = val; + if (val & 0x80) { + if (dev->type > 1) + dma_alias_remove(); + else + dma_alias_remove_piix(); + } else { + if (dev->type > 1) + dma_alias_set(); + else + dma_alias_set_piix(); + } + 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; + case 0x4f: + if (dev->type > 3) + fregs[0x4f] = val & 0x07; + else if (dev->type == 3) + fregs[0x4f] = val & 0x01; + break; + case 0x60: case 0x61: case 0x62: case 0x63: + piix_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x03), val); + fregs[addr] = val & 0x8f; + if (val & 0x80) + pci_set_irq_routing(PCI_INTA + (addr & 0x03), PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA + (addr & 0x03), val & 0xf); + break; + case 0x64: + if (dev->type > 3) + fregs[0x64] = val; + break; + case 0x69: + if (dev->type > 1) + fregs[0x69] = val & 0xfe; + else + fregs[0x69] = val & 0xfa; + break; + case 0x6a: + switch (dev->type) { + case 1: + default: + fregs[0x6a] = (fregs[0x6a] & 0xfb) | (val & 0x04); + fregs[0x0e] = (val & 0x04) ? 0x80 : 0x00; + piix_log("PIIX: Write %02X\n", val); + dev->max_func = 0 + !!(val & 0x04); + break; + case 3: + fregs[0x6a] = val & 0xd1; + piix_log("PIIX3: Write %02X\n", val); + dev->max_func = 1 + !!(val & 0x10); + break; + case 4: + fregs[0x6a] = val & 0x80; + break; + } + break; + case 0x6b: + if ((dev->type > 1) && (val & 0x80)) + fregs[0x6b] &= 0x7f; return; - - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: - return; - - case 0x4c: - if (valxor) { - if (dev->type == 3) - dma_alias_remove(); - else - dma_alias_remove_piix(); - if (!(val & 0x80)) - dma_alias_set(); - } + case 0x70: case 0x71: + if ((dev->type > 1) && (addr == 0x71)) break; - case 0x4e: - keyboard_at_set_mouse_scan((val & 0x10) ? 1 : 0); - break; - case 0x60: - piix_log("Set IRQ routing: INT A -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + if (dev->type < 4) { + piix_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); + if (dev->type > 1) + fregs[addr] = val & 0xef; else - pci_set_irq_routing(PCI_INTA, val & 0xf); - break; - case 0x61: - piix_log("Set IRQ routing: INT B -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTB, val & 0xf); - break; - case 0x62: - piix_log("Set IRQ routing: INT C -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTC, val & 0xf); - break; - case 0x63: - piix_log("Set IRQ routing: INT D -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTD, val & 0xf); - break; - case 0x6a: - if (dev->type == 3) - dev->regs[addr] = (val & 0xFD) | (dev->regs[addr] | 2); - else - dev->regs[addr] = (val & 0xFC) | (dev->regs[addr] | 3); - return; - case 0x70: - piix_log("Set MIRQ routing: MIRQ0 -> %02X\n", val); + fregs[addr] = val & 0xcf; if (val & 0x80) pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); else pci_set_mirq_routing(PCI_MIRQ0, val & 0xf); - break; - piix_log("MIRQ0 is %s\n", (val & 0x20) ? "disabled" : "enabled"); - case 0x71: - if (dev->type == 1) { - piix_log("Set MIRQ routing: MIRQ1 -> %02X\n", val); - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ1, val & 0xf); - } - break; - } + piix_log("MIRQ%i is %s\n", addr & 0x01, (val & 0x20) ? "disabled" : "enabled"); + } + break; + case 0x76: case 0x77: + if (dev->type > 1) + fregs[addr] = val & 0x87; + else + fregs[addr] = val & 0x8f; + break; + case 0x78: case 0x79: + if (dev->type < 4) + fregs[addr] = val; + break; + case 0x80: + if (dev->type > 1) + fregs[addr] = val & 0x7f; + break; + case 0x81: + if (dev->type > 1) + fregs[addr] = val & 0x0f; + break; + case 0x90: + if (dev->type > 3) + fregs[addr] = val; + break; + case 0x91: + if (dev->type > 3) + fregs[addr] = val & 0xfc; + break; + case 0x92: case 0x93: case 0x94: case 0x95: + if (dev->type == 4) { + if (addr & 0x01) + fregs[addr] = val & 0xc0; + else + fregs[addr] = val & 0xff; + ddma_update_io_mapping(dev, (addr >> 2) & 1); + } + break; + case 0xa0: + if (dev->type < 4) + fregs[addr] = val & 0x1f; + break; + case 0xa2: case 0xa5: case 0xa6: case 0xa8: + case 0xaa: case 0xac: case 0xae: + if (dev->type < 4) + fregs[addr] = val & 0xff; + break; + case 0xa3: case 0xab: + if (dev->type == 3) + fregs[addr] = val & 0x01; + break; + case 0xa4: + if (dev->type < 4) + fregs[addr] = val & 0xfb; + break; + case 0xa7: + if (dev->type == 3) + fregs[addr] = val & 0xef; + else if (dev->type < 3) + fregs[addr] = val; + break; + case 0xb0: + if (dev->type > 3) + fregs[addr] = (fregs[addr] & 0x8c) | (val & 0x73); + break; + case 0xb1: + if (dev->type > 3) + fregs[addr] = val & 0xdf; + break; + case 0xb2: + if (dev->type > 3) + fregs[addr] = val; + break; + case 0xb3: + if (dev->type > 3) + fregs[addr] = val & 0xfb; + break; + case 0xcb: + if (dev->type == 4) { + fregs[addr] = val & 0x3d; - dev->regs[addr] = val; + nvr_at_handler(0, 0x0070, dev->nvr); + nvr_at_handler(0, 0x0072, dev->nvr); + + if ((val & 0x01) && (dev->regs[2][0xff] & 0x10)) + nvr_at_handler(1, 0x0070, dev->nvr); + if (val & 0x04) + nvr_at_handler(1, 0x0072, dev->nvr); + + nvr_wp_set(!!(val & 0x08), 0, dev->nvr); + nvr_wp_set(!!(val & 0x10), 1, dev->nvr); + } + break; + } else if (func == 1) switch(addr) { /* IDE */ + case 0x04: + fregs[0x04] = (val & 5); + if (dev->type < 3) + fregs[0x04] |= 0x02; + piix_ide_legacy_handlers(dev, 0x03); + piix_ide_bm_handlers(dev); + break; + case 0x07: + if (val & 0x20) + fregs[0x07] &= 0xdf; + if (val & 0x10) + fregs[0x07] &= 0xef; + if (val & 0x08) + fregs[0x07] &= 0xf7; + break; + case 0x0d: + fregs[0x0d] = val & 0xf0; + break; + case 0x20: + fregs[0x20] = (val & 0xf0) | 1; + piix_ide_bm_handlers(dev); + break; + case 0x21: + fregs[0x21] = val; + piix_ide_bm_handlers(dev); + break; + case 0x3c: + piix_log("IDE IRQ write: %02X\n", val); + fregs[0x3c] = val; + break; + case 0x40: case 0x42: + fregs[addr] = val; + break; + case 0x41: case 0x43: + fregs[addr] = val & ((dev->type > 1) ? 0xf3 : 0xb3); + piix_ide_legacy_handlers(dev, 1 << !!(addr & 0x02)); + break; + case 0x44: + if (dev->type > 1) + fregs[0x44] = val; + break; + case 0x48: + if (dev->type > 3) + fregs[0x48] = val & 0x0f; + break; + case 0x4a: case 0x4b: + if (dev->type > 4) + fregs[addr] = val & 0x33; + break; + } else if (func == 2) switch(addr) { /* USB */ + case 0x04: + fregs[0x04] = (val & 5); + usb_update_io_mapping(dev); + break; + case 0x07: + if (val & 0x20) + fregs[0x07] &= 0xdf; + if (val & 0x10) + fregs[0x07] &= 0xef; + if (val & 0x08) + fregs[0x07] &= 0xf7; + break; + case 0x0d: + fregs[0x0d] = val & 0xf0; + break; + case 0x20: + fregs[0x20] = (val & 0xe0) | 1; + usb_update_io_mapping(dev); + break; + case 0x21: + fregs[0x21] = val; + usb_update_io_mapping(dev); + break; + case 0x3c: + fregs[0x3c] = val; + break; + case 0x6a: + if (dev->type < 4) + fregs[0x6a] = val & 0x01; + break; + case 0xc0: + fregs[0xc0] = val; + break; + case 0xc1: + fregs[0xc1] = val & 0xbf; + break; + case 0xff: + if (dev->type >= 4) { + fregs[addr] = val & 0x10; + nvr_at_handler(0, 0x0070, dev->nvr); + if ((dev->regs[0][0xcb] & 0x01) && (dev->regs[2][0xff] & 0x10)) + nvr_at_handler(1, 0x0070, dev->nvr); + } + break; + } else if (func == 3) switch(addr) { /* Power Management */ + case 0x04: + fregs[0x04] = (val & 1); + power_update_io_mapping(dev); + smbus_update_io_mapping(dev); + break; + case 0x07: + if (val & 0x08) + fregs[0x07] &= 0xf7; + break; +#if 0 + case 0x3c: + fregs[0x3c] = val; + break; +#endif + case 0x40: + fregs[0x40] = (val & 0xc0) | 1; + power_update_io_mapping(dev); + break; + case 0x41: + fregs[0x41] = val; + power_update_io_mapping(dev); + break; + case 0x44: case 0x45: case 0x46: case 0x47: + case 0x48: case 0x49: + case 0x4c: case 0x4d: case 0x4e: + case 0x54: case 0x55: case 0x56: case 0x57: + case 0x59: case 0x5a: + case 0x5c: case 0x5d: case 0x5e: case 0x5f: + case 0x60: case 0x61: case 0x62: + case 0x64: case 0x65: + case 0x67: case 0x68: case 0x69: + case 0x6c: case 0x6e: case 0x6f: + case 0x70: case 0x71: + case 0x74: case 0x77: case 0x78: case 0x79: + case 0x7c: case 0x7d: + case 0xd3: case 0xd4: + case 0xd5: + fregs[addr] = val; + break; + case 0x4a: + fregs[addr] = val & 0x73; + break; + case 0x4b: + fregs[addr] = val & 0x01; + break; + case 0x4f: case 0x80: case 0xd2: + fregs[addr] = val & 0x0f; + if (addr == 0x80) + power_update_io_mapping(dev); + else if (addr == 0xd2) + smbus_update_io_mapping(dev); + break; + case 0x50: + fregs[addr] = val & 0x3f; + break; + case 0x51: + fregs[addr] = val & 0x58; + break; + case 0x52: + fregs[addr] = val & 0x7f; + break; + case 0x58: + fregs[addr] = val & 0x77; + break; + case 0x5b: + fregs[addr] = val & 0x03; + break; + case 0x63: + fregs[addr] = val & 0xf7; + break; + case 0x66: + fregs[addr] = val & 0xef; + break; + case 0x6a: case 0x72: case 0x7a: case 0x7e: + fregs[addr] = val & 0x1f; + break; + case 0x6d: case 0x75: + fregs[addr] = val & 0x80; + break; + case 0x90: + fregs[0x90] = (val & 0xf0) | 1; + smbus_update_io_mapping(dev); + break; + case 0x91: + fregs[0x91] = val; + smbus_update_io_mapping(dev); + break; } } @@ -256,133 +1018,17 @@ static uint8_t piix_read(int func, int addr, void *priv) { piix_t *dev = (piix_t *) priv; + uint8_t ret = 0xff, *fregs; - if ((func == 1) && (dev->type & 0x100)) /* PB640's PIIX has no IDE part. */ - return 0xff; - if (func > 1) - return 0xff; + /* Return on unsupported function. */ + if (func <= dev->max_func) { + fregs = (uint8_t *) dev->regs[func]; + ret = fregs[addr]; - if (func == 1) { /*IDE*/ - if (addr == 4) - return (dev->regs_ide[addr] & 5) | 2; - else if (addr == 5) - return 0; - else if (addr == 6) - return 0x80; - else if (addr == 7) - return dev->regs_ide[addr] & 0x3E; - else if (addr == 0xD) - return dev->regs_ide[addr] & 0xF0; - else if (addr == 0x20) - return (dev->regs_ide[addr] & 0xF0) | 1; - else if (addr == 0x22) - return 0; - else if (addr == 0x23) - return 0; - else if (addr == 0x41) { - if (dev->type == 3) - return dev->regs_ide[addr] & 0xF3; - else - return dev->regs_ide[addr] & 0xB3; - } else if (addr == 0x43) { - if (dev->type == 3) - return dev->regs_ide[addr] & 0xF3; - else - return dev->regs_ide[addr] & 0xB3; - } else - return dev->regs_ide[addr]; - } else { - if ((addr & 0xFC) == 0x60) - return dev->regs[addr] & 0x8F; - - if (addr == 4) { - if (dev->type & 0x100) - return (dev->regs[addr] & 0x80) | 0x0F; - else - return (dev->regs[addr] & 0x80) | 7; - } else if (addr == 5) { - if (dev->type == 3) - return dev->regs[addr] & 1; - else - return 0; - } else if (addr == 6) - return dev->regs[addr] & 0x80; - else if (addr == 7) { - if (dev->type == 3) - return dev->regs[addr]; - else { - if (dev->type & 0x100) - return dev->regs[addr] & 0x02; - else - return dev->regs[addr] & 0x3E; - } - } else if (addr == 0x4E) - return (dev->regs[addr] & 0xEF) | keyboard_at_get_mouse_scan(); - else if (addr == 0x69) - return dev->regs[addr] & 0xFE; - else if (addr == 0x6A) { - if (dev->type == 3) - return dev->regs[addr] & 0xD1; - else - return dev->regs[addr] & 0x07; - } else if (addr == 0x6B) { - if (dev->type == 3) - return dev->regs[addr] & 0x80; - else - return 0; - } - else if (addr == 0x70) { - if (dev->type == 3) - return dev->regs[addr] & 0xEF; - else - return dev->regs[addr] & 0xCF; - } else if (addr == 0x71) { - if (dev->type == 3) - return 0; - else - return dev->regs[addr] & 0xCF; - } else if (addr == 0x76) { - if (dev->type == 3) - return dev->regs[addr] & 0x87; - else - return dev->regs[addr] & 0x8F; - } else if (addr == 0x77) { - if (dev->type == 3) - return dev->regs[addr] & 0x87; - else - return dev->regs[addr] & 0x8F; - } else if (addr == 0x80) { - if (dev->type == 3) - return dev->regs[addr] & 0x7F; - else if (dev->type == 1) - return 0; - } else if (addr == 0x82) { - if (dev->type == 3) - return dev->regs[addr] & 0x0F; - else - return 0; - } else if (addr == 0xA0) - return dev->regs[addr] & 0x1F; - else if (addr == 0xA3) { - if (dev->type == 3) - return dev->regs[addr] & 1; - else - return 0; - } else if (addr == 0xA7) { - if (dev->type == 3) - return dev->regs[addr]; - else - return dev->regs[addr] & 0xEF; - } else if (addr == 0xAB) { - if (dev->type == 3) - return dev->regs[addr]; - else - return dev->regs[addr] & 0xFE; - } else - return dev->regs[addr]; + piix_log("PIIX function %i read: %02X from %02X\n", func, ret, addr); } - return 0; + return ret; } @@ -391,7 +1037,11 @@ board_write(uint16_t port, uint8_t val, void *priv) { piix_t *dev = (piix_t *) priv; - if (port == 0x00e0) + if (port == 0x0078) + dev->board_config[0] = val; + else if (port == 0x0079) + dev->board_config[1] = val; + else if (port == 0x00e0) dev->cur_readout_reg = val; else if (port == 0x00e1) dev->readout_regs[dev->cur_readout_reg] = val; @@ -402,9 +1052,13 @@ static uint8_t board_read(uint16_t port, void *priv) { piix_t *dev = (piix_t *) priv; - uint8_t ret = 0xff; + uint8_t ret = 0x64; - if (port == 0x00e0) + if (port == 0x0078) + ret = dev->board_config[0]; + else if (port == 0x0079) + ret = dev->board_config[1]; + else if (port == 0x00e0) ret = dev->cur_readout_reg; else if (port == 0x00e1) ret = dev->readout_regs[dev->cur_readout_reg]; @@ -414,89 +1068,137 @@ board_read(uint16_t port, void *priv) static void -piix_reset_hard(void *priv) +piix_reset_hard(piix_t *dev) { - piix_t *piix = (piix_t *) priv; + int i; + uint8_t *fregs; - uint16_t old_base = (piix->regs_ide[0x20] & 0xf0) | (piix->regs_ide[0x21] << 8); + uint16_t old_base = (dev->regs[1][0x20] & 0xf0) | (dev->regs[1][0x21] << 8); - if (!(piix->type & 0x100)) { /* PB640's PIIX has no IDE part. */ - sff_bus_master_reset(piix->bm[0], old_base); - sff_bus_master_reset(piix->bm[1], old_base + 8); + sff_bus_master_reset(dev->bm[0], old_base); + sff_bus_master_reset(dev->bm[1], old_base + 8); + + if (dev->type == 4) { + sff_set_irq_mode(dev->bm[0], 0); + sff_set_irq_mode(dev->bm[1], 0); } - memset(piix->regs, 0, 256); - memset(piix->regs_ide, 0, 256); +#ifdef ENABLE_PIIX_LOG + piix_log("piix_reset_hard()\n"); +#endif + ide_pri_disable(); + ide_sec_disable(); - piix->regs[0x00] = 0x86; piix->regs[0x01] = 0x80; /*Intel*/ - if (piix->type == 3) { - piix->regs[0x02] = 0x00; piix->regs[0x03] = 0x70; /*82371SB (PIIX3)*/ - } else { - piix->regs[0x02] = 0x2e; piix->regs[0x03] = 0x12; /*82371FB (PIIX)*/ + if (dev->type > 3) { + nvr_at_handler(0, 0x0072, dev->nvr); + nvr_wp_set(0, 0, dev->nvr); + nvr_wp_set(0, 1, dev->nvr); + nvr_at_handler(1, 0x0074, dev->nvr); + nvr_at_handler(1, 0x0076, dev->nvr); } - if (piix->type & 0x100) - piix->regs[0x04] = 0x06; + + /* Clear all 4 functions' arrays and set their vendor and device ID's. */ + for (i = 0; i < 4; i++) { + memset(dev->regs[i], 0, 256); + dev->regs[i][0x00] = 0x86; dev->regs[i][0x01] = 0x80; /* Intel */ + dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); + dev->regs[i][0x03] = (dev->func0_id >> 8); + } + + /* Function 0: PCI to ISA Bridge */ + fregs = (uint8_t *) dev->regs[0]; + piix_log("PIIX Function 0: 8086:%02X%02X\n", fregs[0x03], fregs[0x02]); + fregs[0x04] = 0x07; + fregs[0x06] = 0x80; fregs[0x07] = 0x02; + if (dev->type == 4) + fregs[0x08] = (dev->rev & 0x08) ? 0x02 : (dev->rev & 0x07); else - piix->regs[0x04] = 0x07; - piix->regs[0x05] = 0x00; - piix->regs[0x06] = 0x80; piix->regs[0x07] = 0x02; - if (piix->type & 0x100) - piix->regs[0x08] = 0x02; /*A0 stepping*/ - else - piix->regs[0x08] = 0x00; /*A0 stepping*/ - piix->regs[0x09] = 0x00; piix->regs[0x0a] = 0x01; piix->regs[0x0b] = 0x06; - if (piix->type & 0x100) - piix->regs[0x0e] = 0x00; /*Single-function device*/ - else - piix->regs[0x0e] = 0x80; /*Multi-function device*/ - piix->regs[0x4c] = 0x4d; - piix->regs[0x4e] = 0x03; - if (piix->type == 3) - piix->regs[0x4f] = 0x00; - piix->regs[0x60] = piix->regs[0x61] = piix->regs[0x62] = piix->regs[0x63] = 0x80; - piix->regs[0x69] = 0x02; - piix->regs[0x70] = 0xc0; - if (piix->type != 3) - piix->regs[0x71] = 0xc0; - piix->regs[0x76] = piix->regs[0x77] = 0x0c; - piix->regs[0x78] = 0x02; piix->regs[0x79] = 0x00; - if (piix->type == 3) { - piix->regs[0x80] = piix->regs[0x82] = 0x00; - } - piix->regs[0xa0] = 0x08; - piix->regs[0xa2] = piix->regs[0xa3] = 0x00; - piix->regs[0xa4] = piix->regs[0xa5] = piix->regs[0xa6] = piix->regs[0xa7] = 0x00; - piix->regs[0xa8] = 0x0f; - piix->regs[0xaa] = piix->regs[0xab] = 0x00; - piix->regs[0xac] = 0x00; - piix->regs[0xae] = 0x00; + fregs[0x08] = dev->rev; + fregs[0x09] = 0x00; + fregs[0x0a] = 0x01; fregs[0x0b] = 0x06; + fregs[0x0e] = (dev->type > 1) ? 0x80 : 0x00; + fregs[0x4c] = 0x4d; + fregs[0x4e] = 0x03; + fregs[0x60] = fregs[0x61] = fregs[0x62] = fregs[0x63] = 0x80; + fregs[0x64] = (dev->type > 3) ? 0x10 : 0x00; + fregs[0x69] = 0x02; + fregs[0x70] = (dev->type < 4) ? 0x80 : 0x00; + fregs[0x71] = (dev->type < 3) ? 0x80 : 0x00; + fregs[0x76] = fregs[0x77] = (dev->type > 1) ? 0x04 : 0x0c; + fregs[0x78] = (dev->type < 4) ? 0x02 : 0x00; + fregs[0xa0] = (dev->type < 4) ? 0x08 : 0x00; + fregs[0xa8] = (dev->type < 4) ? 0x0f : 0x00; + if (dev->type == 4) + fregs[0xb0] = (is_pentium) ? 0x00 : 0x04; + fregs[0xcb] = (dev->type > 3) ? 0x21 : 0x00; + dev->max_func = 0; - piix->regs_ide[0x00] = 0x86; piix->regs_ide[0x01] = 0x80; /*Intel*/ - if (piix->type == 3) { - piix->regs_ide[0x02] = 0x10; piix->regs_ide[0x03] = 0x70; /*82371SB (PIIX3)*/ - } else { - piix->regs_ide[0x02] = 0x30; piix->regs_ide[0x03] = 0x12; /*82371FB (PIIX)*/ + /* Function 1: IDE */ + fregs = (uint8_t *) dev->regs[1]; + piix_log("PIIX Function 1: 8086:%02X%02X\n", fregs[0x03], fregs[0x02]); + fregs[0x04] = (dev->type > 3) ? 0x05 : 0x07; + fregs[0x06] = 0x80; fregs[0x07] = 0x02; + if (dev->type == 4) + fregs[0x08] = dev->rev & 0x07; + else + fregs[0x08] = dev->rev; + fregs[0x09] = 0x80; + fregs[0x0a] = 0x01; fregs[0x0b] = 0x01; + fregs[0x20] = 0x01; + dev->max_func = 0; /* It starts with IDE disabled, then enables it. */ + + /* Function 2: USB */ + if (dev->type > 1) { + fregs = (uint8_t *) dev->regs[2]; + piix_log("PIIX Function 2: 8086:%02X%02X\n", fregs[0x03], fregs[0x02]); + fregs[0x04] = 0x05; + fregs[0x06] = 0x80; fregs[0x07] = 0x02; + if (dev->type == 4) + fregs[0x08] = dev->rev & 0x07; + else + fregs[0x08] = dev->rev; + fregs[0x0a] = 0x03; fregs[0x0b] = 0x0c; + fregs[0x20] = 0x01; + fregs[0x3d] = 0x04; + fregs[0x60] = (dev->type > 3) ? 0x10: 0x00; + fregs[0x6a] = (dev->type == 3) ? 0x01 : 0x00; + fregs[0xc1] = 0x20; + fregs[0xff] = (dev->type > 3) ? 0x10 : 0x00; + dev->max_func = 1; /* It starts with USB disabled, then enables it. */ + } + + /* Function 3: Power Management */ + if (dev->type > 3) { + fregs = (uint8_t *) dev->regs[3]; + piix_log("PIIX Function 3: 8086:%02X%02X\n", fregs[0x03], fregs[0x02]); + fregs[0x06] = 0x80; fregs[0x07] = 0x02; + fregs[0x08] = (dev->rev & 0x08) ? 0x02 : (dev->rev & 0x07); + fregs[0x0a] = 0x80; fregs[0x0b] = 0x06; + /* NOTE: The Specification Update says this should default to 0x00 and be read-only. */ +#ifdef WRONG_SPEC + fregs[0x3d] = 0x01; +#endif + fregs[0x40] = 0x01; + fregs[0x90] = 0x01; + dev->max_func = 3; } - piix->regs_ide[0x04] = 0x03; piix->regs_ide[0x05] = 0x00; - piix->regs_ide[0x06] = 0x80; piix->regs_ide[0x07] = 0x02; - piix->regs_ide[0x08] = 0x00; - piix->regs_ide[0x09] = 0x80; piix->regs_ide[0x0a] = 0x01; piix->regs_ide[0x0b] = 0x01; - piix->regs_ide[0x0d] = 0x00; - piix->regs_ide[0x0e] = 0x00; - piix->regs_ide[0x20] = 0x01; piix->regs_ide[0x21] = piix->regs_ide[0x22] = piix->regs_ide[0x23] = 0x00; /*Bus master interface base address*/ - piix->regs_ide[0x40] = piix->regs_ide[0x42] = 0x00; - piix->regs_ide[0x41] = piix->regs_ide[0x43] = 0x00; - if (piix->type == 3) - piix->regs_ide[0x44] = 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); - pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); - if (piix->type != 3) + if (dev->type < 4) + pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); + if (dev->type < 3) pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + + if (dev->type == 4) { + dev->power.gporeg[0] = 0xff; + dev->power.gporeg[1] = 0xbf; + dev->power.gporeg[2] = 0xff; + dev->power.gporeg[3] = 0x7f; + } } @@ -512,30 +1214,40 @@ piix_close(void *p) static void *piix_init(const device_t *info) { - piix_t *piix = (piix_t *) malloc(sizeof(piix_t)); - memset(piix, 0, sizeof(piix_t)); + int i; + CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu]; - pci_add_card(7, piix_read, piix_write, piix); + piix_t *dev = (piix_t *) malloc(sizeof(piix_t)); + memset(dev, 0, sizeof(piix_t)); - piix->type = info->local; + dev->type = info->local & 0x0f; + /* If (dev->type == 4) and (dev->rev & 0x08), then this is PIIX4E. */ + dev->rev = (info->local >> 4) & 0x0f; + dev->func_shift = info->local >> 8; + dev->func0_id = info->local >> 16; + + dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev); + piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot); + + dev->bm[0] = device_add_inst(&sff8038i_device, 1); + dev->bm[1] = device_add_inst(&sff8038i_device, 2); + + if (dev->type > 3) + dev->nvr = device_add(&piix4_nvr_device); + + piix_reset_hard(dev); device_add(&apm_device); - - if (!(piix->type & 0x100)) { /* PB640's PIIX has no IDE part. */ - piix->bm[0] = device_add_inst(&sff8038i_device, 1); - piix->bm[1] = device_add_inst(&sff8038i_device, 2); - } - - piix_reset_hard(piix); - device_add(&port_92_pci_device); dma_alias_set(); - pci_enable_mirq(0); - pci_enable_mirq(1); + if (dev->type < 4) + pci_enable_mirq(0); + if (dev->type < 3) + pci_enable_mirq(1); - piix->readout_regs[1] = 0x40; + dev->readout_regs[1] = 0x40; /* Port E1 register 01 (TODO: Find how multipliers > 3.0 are defined): @@ -547,65 +1259,68 @@ static void 1000 = 150 MHz, 1010 = 200 MHz, 1100 = 180 MHz, 1110 = ??? MHz; 1001 = 75 MHz, 1011 = 100 MHz, 1101 = 90 MHz, 1111 = ??? MHz */ - switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].pci_speed) { - case 20000000: - piix->readout_regs[1] |= 0x30; - break; - case 25000000: - default: - piix->readout_regs[1] |= 0x00; - break; - case 30000000: - piix->readout_regs[1] |= 0x20; - break; - case 33333333: - piix->readout_regs[1] |= 0x10; - break; - } + if (cpu_busspeed <= 0x40000000) + dev->readout_regs[1] |= 0x30; + else if ((cpu_busspeed > 0x40000000) && (cpu_busspeed <= 0x50000000)) + dev->readout_regs[1] |= 0x00; + else if ((cpu_busspeed > 0x50000000) && (cpu_busspeed <= 0x60000000)) + dev->readout_regs[1] |= 0x20; + else if (cpu_busspeed > 0x60000000) + dev->readout_regs[1] |= 0x10; - switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed) { - case 75000000: - piix->readout_regs[1] |= 0x82; /* 50 MHz * 1.5 multiplier */ - break; - case 90000000: - piix->readout_regs[1] |= 0x82; /* 60 MHz * 1.5 multiplier */ - break; - case 100000000: - if ((piix->readout_regs[1] & 0x30) == 0x10) - piix->readout_regs[1] |= 0x82; /* 66 MHz * 1.5 multiplier */ - else - piix->readout_regs[1] |= 0x02; /* 50 MHz * 2.0 multiplier */ - break; - case 12000000: - piix->readout_regs[1] |= 0x02; /* 60 MHz * 2.0 multiplier */ - break; - case 125000000: - piix->readout_regs[1] |= 0x00; /* 50 MHz * 2.5 multiplier */ - break; - case 133333333: - piix->readout_regs[1] |= 0x02; /* 66 MHz * 2.0 multiplier */ - break; - case 150000000: - if ((piix->readout_regs[1] & 0x30) == 0x20) - piix->readout_regs[1] |= 0x00; /* 60 MHz * 2.5 multiplier */ - else - piix->readout_regs[1] |= 0x80; /* 50 MHz * 3.0 multiplier */ - break; - case 166666666: - piix->readout_regs[1] |= 0x00; /* 66 MHz * 2.5 multiplier */ - break; - case 180000000: - piix->readout_regs[1] |= 0x80; /* 60 MHz * 3.0 multiplier */ - break; - case 200000000: - piix->readout_regs[1] |= 0x80; /* 66 MHz * 3.0 multiplier */ - break; - } + if (cpu_dmulti <= 1.5) + dev->readout_regs[1] |= 0x82; + else if ((cpu_dmulti > 1.5) && (cpu_dmulti <= 2.0)) + dev->readout_regs[1] |= 0x02; + else if ((cpu_dmulti > 2.0) && (cpu_dmulti <= 2.5)) + dev->readout_regs[1] |= 0x00; + else if (cpu_dmulti > 2.5) + dev->readout_regs[1] |= 0x80; - io_sethandler(0x0078, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, piix); - io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, piix); + io_sethandler(0x0078, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev); + io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev); - return piix; + dev->board_config[0] = 0xff; + /* Register 0x0079: */ + /* Bit 7: 0 = Keep password, 0 = Clear password. */ + /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ + /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ + /* Bit 4: External CPU clock (Switch 8). */ + /* Bit 3: External CPU clock (Switch 7). */ + /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ + /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ + /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ + /* Bit 2: 0 = On-board audio absent, 1 = On-board audio present. */ + /* Bit 0: 0 = 1.5x multiplier, 0 = 2x multiplier. */ + dev->board_config[1] = 0xe0; + if ((cpu_s->rspeed == 75000000) && (cpu_busspeed == 50000000)) + dev->board_config[1] |= 0x01; + else if ((cpu_s->rspeed == 90000000) && (cpu_busspeed == 60000000)) + dev->board_config[1] |= (0x01 | 0x08); + else if ((cpu_s->rspeed == 100000000) && (cpu_busspeed == 50000000)) + dev->board_config[1] |= 0x00; + else if ((cpu_s->rspeed == 100000000) && (cpu_busspeed == 66666666)) + dev->board_config[1] |= (0x01 | 0x10); + else if ((cpu_s->rspeed == 120000000) && (cpu_busspeed == 60000000)) + dev->board_config[1] |= 0x08; + else if ((cpu_s->rspeed == 133333333) && (cpu_busspeed == 66666666)) + dev->board_config[1] |= 0x10; + else + dev->board_config[1] |= 0x10; /* TODO: how are the overdrive processors configured? */ + + smbus_init(); + dev->smbus.stat = 0; + dev->smbus.ctl = 0; + dev->smbus.cmd = 0; + dev->smbus.addr = 0; + dev->smbus.data0 = 0; + dev->smbus.data1 = 0; + dev->smbus.index = 0; + for (i = 0; i < 32; i++) + dev->smbus.data[i] = 0; + timer_add(&dev->smbus.command_timer, smbus_inter, dev, 0); + + return dev; } @@ -613,21 +1328,7 @@ const device_t piix_device = { "Intel 82371FB (PIIX)", DEVICE_PCI, - 1, - piix_init, - piix_close, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -const device_t piix_pb640_device = -{ - "Intel 82371FB (PIIX) (PB640)", - DEVICE_PCI, - 0x101, + 0x122e0101, piix_init, piix_close, NULL, @@ -641,7 +1342,35 @@ const device_t piix3_device = { "Intel 82371SB (PIIX3)", DEVICE_PCI, - 3, + 0x70000403, + piix_init, + piix_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +const device_t piix4_device = +{ + "Intel 82371AB/EB (PIIX4/PIIX4E)", + DEVICE_PCI, + 0x71100004, + piix_init, + piix_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +const device_t piix4e_device = +{ + "Intel 82371EB (PIIX4E)", + DEVICE_PCI, + 0x71100094, piix_init, piix_close, NULL, diff --git a/src/intel_sio.c b/src/intel_sio.c index 45cdf2975..d0a5da9f4 100644 --- a/src/intel_sio.c +++ b/src/intel_sio.c @@ -21,7 +21,7 @@ #include #include "86box.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "apm.h" #include "dma.h" #include "mem.h" @@ -29,7 +29,7 @@ #include "timer.h" #include "pit.h" #include "port_92.h" -#include "machine/machine.h" +#include "machine.h" #include "intel_sio.h" @@ -248,7 +248,7 @@ sio_config_read(uint16_t port, void *priv) case 5: ret = 0xd3; - switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].pci_speed) { + switch (cpu_pci_speed) { case 20000000: ret |= 0x0c; break; @@ -341,7 +341,7 @@ sio_init(const device_t *info) sio_t *sio = (sio_t *) malloc(sizeof(sio_t)); memset(sio, 0, sizeof(sio_t)); - pci_add_card(2, sio_read, sio_write, sio); + pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, sio); device_add(&apm_device); diff --git a/src/io.c b/src/io.c index 8e1ed59f8..6e53aafe2 100644 --- a/src/io.c +++ b/src/io.c @@ -25,9 +25,9 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "io.h" -#include "cpu/cpu.h" -#include "machine/m_amstrad.h" +#include "86box_io.h" +#include "cpu.h" +#include "m_amstrad.h" #define NPORTS 65536 /* PC/AT supports 64K ports */ @@ -333,9 +333,27 @@ inb(uint16_t port) io_log("IOTRACE(%04X): inb(%04x)=%02x\n", IO_TRACE, port, ret); #endif + /* if (port == 0x386) { + ret = 0x00; + found = 1; + } + + if (port == 0x406) { + ret = 0x00; + found = 1; + } + + if (port == 0xf87) { + ret = 0x00; + found = 1; + } */ + if (!found) sub_cycles(io_delay); + // if (!found) + // pclog("inb(%04X) = %02X\n", port, ret); + return(ret); } @@ -365,6 +383,9 @@ outb(uint16_t port, uint8_t val) if (!found) sub_cycles(io_delay); + // if (!found) + // pclog("outb(%04X, %02X)\n", port, val); + return; } diff --git a/src/isamem.c b/src/isamem.c index a6f29deb5..9a37909c2 100644 --- a/src/isamem.c +++ b/src/isamem.c @@ -74,8 +74,8 @@ #include #include #include "86box.h" -#include "machine/machine.h" -#include "io.h" +#include "machine.h" +#include "86box_io.h" #include "mem.h" #include "device.h" #include "ui.h" diff --git a/src/isartc.c b/src/isartc.c index 22da01027..c83460aaa 100644 --- a/src/isartc.c +++ b/src/isartc.c @@ -71,10 +71,10 @@ #include #include #include "86box.h" -#include "cpu/cpu.h" +#include "cpu.h" #include "timer.h" -#include "machine/machine.h" -#include "io.h" +#include "machine.h" +#include "86box_io.h" #include "device.h" #include "nvr.h" #include "ui.h" diff --git a/src/keyboard.c b/src/keyboard.c index 68f5017df..1c770f69d 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -23,7 +23,7 @@ #include #include #include "86box.h" -#include "machine/machine.h" +#include "machine.h" #include "keyboard.h" diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 7da1c4380..c81f07bfa 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -26,22 +26,22 @@ #define HAVE_STDARG_H #include #include "86box.h" -#include "cpu/cpu.h" +#include "cpu.h" #include "timer.h" -#include "io.h" +#include "86box_io.h" #include "pic.h" #include "pit.h" #include "ppi.h" #include "mem.h" #include "device.h" -#include "machine/machine.h" -#include "machine/m_xt_xi8088.h" -#include "machine/m_at_t3100e.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" -#include "sound/sound.h" -#include "sound/snd_speaker.h" -#include "video/video.h" +#include "machine.h" +#include "m_xt_xi8088.h" +#include "m_at_t3100e.h" +#include "fdd.h" +#include "fdc.h" +#include "sound.h" +#include "snd_speaker.h" +#include "video.h" #include "keyboard.h" @@ -57,6 +57,8 @@ #define PS2_REFRESH_TIME (16 * TIMER_USEC) +#define RESET_DELAY_TIME (100 * 10) /* 600ms */ + #define CCB_UNUSED 0x80 #define CCB_TRANSLATE 0x40 #define CCB_PCMODE 0x20 @@ -95,7 +97,7 @@ typedef struct { uint8_t mem[0x100]; int out_new, out_delayed; - int last_irq; + int last_irq, reset_delay; uint32_t flags; @@ -568,6 +570,9 @@ static const scancode scancode_set3[512] = { }; +static void add_data_kbd(uint16_t val); + + #ifdef ENABLE_KEYBOARD_AT_LOG int keyboard_at_do_log = ENABLE_KEYBOARD_AT_LOG; @@ -667,11 +672,17 @@ kbd_poll(void *priv) (mouse_queue_start != mouse_queue_end)) { dev->out_new = mouse_queue[mouse_queue_start] | 0x100; mouse_queue_start = (mouse_queue_start + 1) & 0xf; - } else if (!(dev->status&STAT_OFULL) && dev->out_new == -1 && + } else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && !(dev->mem[0]&0x10) && (key_queue_start != key_queue_end)) { dev->out_new = key_queue[key_queue_start]; key_queue_start = (key_queue_start + 1) & 0xf; } + + if (dev->reset_delay) { + dev->reset_delay--; + if (!dev->reset_delay) + add_data_kbd(0xaa); + } } @@ -697,6 +708,9 @@ add_data_vals(atkbd_t *dev, uint8_t *val, uint8_t len) uint8_t or = 0; uint8_t send; + if (dev->reset_delay) + return; + translate = translate || (keyboard_mode & 0x40) || xt_mode; translate = translate || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2); @@ -744,6 +758,9 @@ add_data_kbd(uint16_t val) uint8_t fake_shift[4]; uint8_t num_lock = 0, shift_states = 0; + if (dev->reset_delay) + return; + translate = translate || (keyboard_mode & 0x40) || xt_mode; translate = translate || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2); @@ -1002,6 +1019,7 @@ write_output(atkbd_t *dev, uint8_t val) cpu_set_edx(); } } + /* Mask off the A20 stuff because we use mem_a20_key directly for that. */ dev->output_port = val; } @@ -1481,20 +1499,6 @@ write64_ami(void *priv, uint8_t val) dev->output_locked = 1; return 0; - case 0xca: /* read keyboard mode */ -#ifdef ENABLE_KEYBOARD_AT_LOG - kbd_log("ATkbd: AMI - read keyboard mode\n"); -#endif - add_data(dev, 0x00); /*ISA mode*/ - return 0; - - case 0xcb: /* set keyboard mode */ -#ifdef ENABLE_KEYBOARD_AT_LOG - kbd_log("ATkbd: AMI - set keyboard mode\n"); -#endif - dev->want60 = 1; - return 0; - case 0xef: /* ??? - sent by AMI486 */ #ifdef ENABLE_KEYBOARD_AT_LOG kbd_log("ATkbd: ??? - sent by AMI486\n"); @@ -1988,11 +1992,12 @@ do_command: #endif key_queue_start = key_queue_end = 0; /*Clear key queue*/ add_data_kbd(0xfa); - add_data_kbd(0xaa); /* Set scan code set to 2. */ keyboard_mode = (keyboard_mode & 0xfc) | 0x02; set_scancode_map(dev); + + dev->reset_delay = RESET_DELAY_TIME; break; default: @@ -2107,6 +2112,20 @@ do_command: set_enable_kbd(dev, 1); break; + case 0xca: /* read keyboard mode */ +#ifdef ENABLE_KEYBOARD_AT_LOG + kbd_log("ATkbd: AMI - read keyboard mode\n"); +#endif + add_data(dev, ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00); /*ISA mode*/ + break; + + case 0xcb: /* set keyboard mode */ +#ifdef ENABLE_KEYBOARD_AT_LOG + kbd_log("ATkbd: AMI - set keyboard mode\n"); +#endif + dev->want60 = 1; + break; + case 0xd0: /* read output port */ #ifdef ENABLE_KEYBOARD_AT_LOG kbd_log("ATkbd: read output port\n"); @@ -2191,6 +2210,9 @@ kbd_read(uint16_t port, void *priv) atkbd_t *dev = (atkbd_t *)priv; uint8_t ret = 0xff; + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) + sub_cycles(ISA_CYCLES(8)); + if (((dev->flags & KBC_VEN_MASK) == KBC_VEN_XI8088) && (port == 0x63)) port = 0x61; @@ -2270,7 +2292,7 @@ kbd_reset(void *priv) dev->first_write = 1; dev->status = STAT_UNLOCKED | STAT_CD; dev->mem[0] = 0x01; - if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_XI8088) + // if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_XI8088) dev->mem[0] |= CCB_TRANSLATE; dev->wantirq = 0; write_output(dev, 0xcf); diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 7f8be716c..e74e926fb 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -26,18 +26,18 @@ #include "86box.h" #include "device.h" #include "timer.h" -#include "floppy/fdd.h" -#include "machine/machine.h" -#include "machine/m_xt_t1000.h" -#include "io.h" +#include "fdd.h" +#include "machine.h" +#include "m_xt_t1000.h" +#include "86box_io.h" #include "pic.h" #include "pit.h" #include "ppi.h" #include "mem.h" #include "rom.h" -#include "sound/sound.h" -#include "sound/snd_speaker.h" -#include "video/video.h" +#include "sound.h" +#include "snd_speaker.h" +#include "video.h" #include "keyboard.h" diff --git a/src/lpt.c b/src/lpt.c index f67eba3cc..646cc2cd1 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -6,12 +6,11 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "lpt.h" #include "pic.h" -#include "sound/snd_lpt_dac.h" -#include "sound/snd_lpt_dss.h" -#include "printer/prt_devs.h" +#include "sound.h" +#include "prt_devs.h" lpt_port_t lpt_ports[3]; diff --git a/src/lpt.h b/src/lpt.h index c6a95fc4e..43a91a09a 100644 --- a/src/lpt.h +++ b/src/lpt.h @@ -53,3 +53,8 @@ extern char * lpt_device_get_name(int id); extern char * lpt_device_get_internal_name(int id); extern int lpt_device_get_from_internal_name(char *s); + +extern const lpt_device_t lpt_dac_device; +extern const lpt_device_t lpt_dac_stereo_device; + +extern const lpt_device_t dss_device; diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 3ebfee31a..d2c4325e3 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -48,31 +48,30 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pit.h" -#include "../ppi.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../keyboard.h" -#include "../mouse.h" -#include "../game/gameport.h" -#include "../lpt.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../sound/sound.h" -#include "../sound/snd_speaker.h" -#include "../video/video.h" -#include "../video/vid_cga.h" -#include "../video/vid_ega.h" -#include "../video/vid_mda.h" -#include "../video/vid_paradise.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "nmi.h" +#include "pic.h" +#include "pit.h" +#include "ppi.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "keyboard.h" +#include "mouse.h" +#include "gameport.h" +#include "lpt.h" +#include "fdd.h" +#include "fdc.h" +#include "sound.h" +#include "snd_speaker.h" +#include "video.h" +#include "vid_cga.h" +#include "vid_ega.h" +#include "vid_mda.h" #include "machine.h" #include "m_amstrad.h" diff --git a/src/machine/m_at.c b/src/machine/m_at.c index ca93a489e..25666f7bc 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -40,21 +40,21 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" -#include "../pic.h" -#include "../pit.h" -#include "../dma.h" -#include "../mem.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../nvr.h" -#include "../game/gameport.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../rom.h" -#include "../disk/hdc.h" +#include "86box.h" +#include "timer.h" +#include "pic.h" +#include "pit.h" +#include "dma.h" +#include "mem.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "nvr.h" +#include "gameport.h" +#include "keyboard.h" +#include "lpt.h" +#include "rom.h" +#include "hdc.h" #include "machine.h" diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 95b7ee98d..70c78226b 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -22,23 +22,19 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../device.h" -#include "../chipset/chipset.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../rom.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../disk/hdc.h" -#include "../video/video.h" -#include "../video/vid_cl54xx.h" -#include "../video/vid_et4000.h" -#include "../video/vid_oak_oti.h" -#include "../video/vid_paradise.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "device.h" +#include "chipset.h" +#include "keyboard.h" +#include "mem.h" +#include "rom.h" +#include "fdd.h" +#include "fdc.h" +#include "hdc.h" +#include "video.h" #include "machine.h" @@ -224,6 +220,26 @@ machine_at_goldstar386_init(const machine_t *model) return ret; } +int +machine_at_micronics386_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved(L"roms/machines/micronics386/386-Micronics-09-00021-EVEN.BIN", + L"roms/machines/micronics386/386-Micronics-09-00021-ODD.BIN", + 0x000f0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_init(model); + + device_add(&neat_device); + device_add(&fdc_at_device); + + return ret; +} + static void machine_at_scat_init(const machine_t *model, int is_v4) { diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 1efd3ee12..78562d82f 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -22,25 +22,24 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../device.h" -#include "../chipset/chipset.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../nvr.h" -#include "../pci.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../rom.h" -#include "../sio.h" -#include "../disk/hdc.h" -#include "../video/video.h" -#include "../video/vid_ht216.h" -#include "../intel_flash.h" -#include "../intel_sio.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "device.h" +#include "chipset.h" +#include "keyboard.h" +#include "mem.h" +#include "nvr.h" +#include "pci.h" +#include "fdd.h" +#include "fdc.h" +#include "rom.h" +#include "sio.h" +#include "hdc.h" +#include "video.h" +#include "intel_flash.h" +#include "intel_sio.h" #include "machine.h" @@ -68,24 +67,6 @@ machine_at_pb410a_init(const machine_t *model) return ret; } -int -machine_at_micronics386_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved(L"roms/machines/micronics386/386-Micronics-09-00021-EVEN.BIN", - L"roms/machines/micronics386/386-Micronics-09-00021-ODD.BIN", - 0x000f0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_init(model); - device_add(&keyboard_at_device); - device_add(&fdc_at_device); - - return ret; -} static void machine_at_ali1429_common_init(const machine_t *model) @@ -288,10 +269,10 @@ machine_at_win471_init(const machine_t *model) static void machine_at_sis_85c496_common_init(const machine_t *model) { - device_add(&ide_pci_device); + device_add(&ide_pci_2ch_device); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x05, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -352,6 +333,29 @@ machine_at_ls486e_init(const machine_t *model) } +int +machine_at_4dps_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/4dps/4DPS172G.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + machine_at_sis_85c496_common_init(model); + pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&w83787f_device); + device_add(&keyboard_ps2_pci_device); + + return ret; +} + + int machine_at_alfredo_init(const machine_t *model) { @@ -367,12 +371,12 @@ machine_at_alfredo_init(const machine_t *model) device_add(&ide_pci_2ch_device); pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); - pci_register_slot(0x02, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_ami_pci_device); device_add(&sio_device); device_add(&fdc37c663_device); @@ -382,3 +386,35 @@ machine_at_alfredo_init(const machine_t *model) return ret; } + + +int +machine_at_486sp3g_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/486sp3g/PCI-I-486SP3G_0306.001 (Beta).bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ide_pci_2ch_device); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_pci_device); + device_add(&sio_device); /* Site says it has a ZB, but the BIOS is designed for an IB. */ + device_add(&pc87306_device); + device_add(&intel_flash_bxt_ami_device); + + device_add(&i420zx_device); + + return ret; +} diff --git a/src/machine/m_at_commodore.c b/src/machine/m_at_commodore.c index 348c43e36..066a8ab7a 100644 --- a/src/machine/m_at_commodore.c +++ b/src/machine/m_at_commodore.c @@ -40,16 +40,16 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../io.h" -#include "../mem.h" -#include "../lpt.h" -#include "../rom.h" -#include "../serial.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "86box_io.h" +#include "mem.h" +#include "lpt.h" +#include "rom.h" +#include "serial.h" +#include "fdd.h" +#include "fdc.h" #include "machine.h" diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 801de3412..ac8175b27 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -21,16 +21,16 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "hdc.h" +#include "hdc_ide.h" #include "machine.h" diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c index 7053eef6b..15012e856 100644 --- a/src/machine/m_at_socket4_5.c +++ b/src/machine/m_at_socket4_5.c @@ -21,26 +21,24 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../chipset/chipset.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../keyboard.h" -#include "../intel_flash.h" -#include "../intel_sio.h" -#include "../piix.h" -#include "../sio.h" -#include "../video/video.h" -#include "../video/vid_cl54xx.h" -#include "../video/vid_s3.h" +#include "86box.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "chipset.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#include "keyboard.h" +#include "intel_flash.h" +#include "intel_sio.h" +#include "piix.h" +#include "sio.h" +#include "video.h" #include "machine.h" @@ -51,12 +49,12 @@ machine_at_premiere_common_init(const machine_t *model) device_add(&ide_pci_2ch_device); pci_init(PCI_CONFIG_TYPE_2); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); - pci_register_slot(0x02, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_ami_pci_device); device_add(&sio_zb_device); device_add(&fdc37c665_device); @@ -71,14 +69,14 @@ machine_at_award_common_init(const machine_t *model) device_add(&ide_pci_2ch_device); pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */ pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */ pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */ pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */ - pci_register_slot(0x02, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&fdc_at_device); device_add(&keyboard_ps2_pci_device); device_add(&sio_device); @@ -236,12 +234,12 @@ machine_at_p54tp4xe_init(const machine_t *model) /* Award BIOS, SMC FDC37C665. */ pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_pci_device); device_add(&i430fx_device); device_add(&piix_device); @@ -266,13 +264,13 @@ machine_at_endeavor_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); if (gfxcard == VID_INTERNAL) device_add(&s3_phoenix_trio64_onboard_pci_device); @@ -308,11 +306,11 @@ machine_at_zappa_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); @@ -337,12 +335,12 @@ machine_at_mb500n_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_pci_device); device_add(&i430fx_device); device_add(&piix_device); @@ -367,12 +365,12 @@ machine_at_president_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430fx_device); device_add(&piix_device); device_add(&keyboard_ps2_pci_device); @@ -398,12 +396,12 @@ machine_at_vectra54_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index a281b69c0..f48db0542 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -8,7 +8,7 @@ * * Implementation of Socket 7 and Super Socket 7 machines. * - * Version: @(#)m_at_socket7_s7.c 1.0.2 2020/01/18 + * Version: @(#)m_at_socket7_s7.c 1.0.3 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, @@ -23,25 +23,23 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../chipset/chipset.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../keyboard.h" -#include "../intel_flash.h" -#include "../intel_sio.h" -#include "../piix.h" -#include "../sio.h" -#include "../sst_flash.h" -#include "../via_vt82c586b.h" -#include "../video/video.h" -#include "../video/vid_cl54xx.h" -#include "../video/vid_s3.h" +#include "86box.h" +#include "mem.h" +#include "io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "chipset.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "keyboard.h" +#include "intel_flash.h" +#include "intel_sio.h" +#include "piix.h" +#include "sio.h" +#include "sst_flash.h" +#include "via_vt82c586b.h" +#include "video.h" #include "machine.h" @@ -51,13 +49,13 @@ machine_at_thor_common_init(const machine_t *model, int mr) machine_at_common_init_ex(model, mr); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 2, 1); pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 3, 2, 1); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430fx_device); device_add(&piix_device); device_add(&keyboard_ps2_ami_pci_device); @@ -116,14 +114,14 @@ machine_at_pb640_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 2, 1, 4); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430fx_pb640_device); - device_add(&piix_pb640_device); + device_add(&piix_device); device_add(&ide_isa_2ch_device); if (gfxcard == VID_INTERNAL) @@ -158,8 +156,8 @@ machine_at_acerm3a_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -191,8 +189,8 @@ machine_at_acerv35n_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -224,12 +222,12 @@ machine_at_ap53_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x06, PCI_CARD_ONBOARD, 1, 2, 3, 4); device_add(&i430hx_device); device_add(&piix3_device); @@ -255,12 +253,12 @@ machine_at_p55t2p4_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -285,12 +283,12 @@ machine_at_p55t2s_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); @@ -320,22 +318,23 @@ machine_at_tc430hx_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&pc87306_device); - device_add(&intel_flash_bxtw_ami_device); + device_add(&intel_flash_bxt_ami_device); return ret; } + int machine_at_equium5200_init(const machine_t *model) // Information about that machine on machine.h { @@ -354,13 +353,13 @@ machine_at_equium5200_init(const machine_t *model) // Information about that mac machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 0, 0, 0); // riser + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 0, 0, 0); // riser device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); @@ -387,12 +386,12 @@ machine_at_p55tvp4_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -417,12 +416,12 @@ machine_at_i430vx_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -447,12 +446,12 @@ machine_at_p55va_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -477,11 +476,11 @@ machine_at_j656vxd_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -491,6 +490,131 @@ machine_at_j656vxd_init(const machine_t *model) return ret; } + +int +machine_at_5tx52_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/5tx52/5itw002.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); /* PIIX4 */ + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83877tf_acorp_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_txp4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/txp4/0112L.001", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977tf_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_ym430tx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/ym430tx/YM430TX.003", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977tf_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_sp586tx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/sp586tx/Txa6-32gb.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977tf_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + int machine_at_mvp3_init(const machine_t *model) { @@ -505,12 +629,12 @@ machine_at_mvp3_init(const machine_t *model) machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0a, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); device_add(&via_mvp3_device); device_add(&via_vt82c586b_device); device_add(&keyboard_ps2_pci_device); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 18e4355c0..d6f590d7b 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Implementation of Socket 8 machines. + * Implementation of Socket 8 and Slot 1 machines. * * Version: @(#)m_at_socket8.c 1.0.0 2019/05/16 * @@ -19,23 +19,24 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../chipset/chipset.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../keyboard.h" -#include "../intel_flash.h" -#include "../intel_sio.h" -#include "../piix.h" -#include "../sio.h" -#include "../video/video.h" -#include "../video/vid_cl54xx.h" -#include "../video/vid_s3.h" +#include "86box.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "chipset.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "keyboard.h" +#include "intel_flash.h" +#include "intel_sio.h" +#include "piix.h" +#include "sio.h" +#include "sst_flash.h" +#include "hwm.h" +#include "video.h" +#include "cpu.h" #include "machine.h" @@ -56,13 +57,13 @@ machine_at_i440fx_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i440fx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -87,8 +88,8 @@ machine_at_s1668_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -103,5 +104,163 @@ machine_at_s1668_init(const machine_t *model) return ret; } - +#endif +int +machine_at_6abx3_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/6abx3/6abx3h1.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83877tf_device); + // device_add(&w83977tf_device); + // device_add(&intel_flash_bxt_device); + // device_add(&sst_flash_29ee020_device); + device_add(&intel_flash_bxt_device); + + return ret; +} +#if defined(DEV_BRANCH) && defined(USE_I686) +int +machine_at_p2bls_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/p2bls/1014ls.003", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977ef_device); + device_add(&sst_flash_39sf020_device); + + hwm_values_t machine_hwm = { + { /* fan speeds */ + 3000, /* Chassis */ + 3000, /* CPU */ + 3000, /* Power */ + 0 + }, { /* temperatures */ + 30, /* MB */ + 0, /* unused */ + 27, /* CPU */ + 0 + }, { /* voltages (divisors other than 16 = unclear how that number was achieved) */ + 2050 / 16, /* VCORE (2.05V by default) */ + 0, /* unused */ + 3300 / 16, /* +3.3V */ + 5000 / 27, /* +5V */ + VDIV(12000, 28, 10) / 16, /* +12V (with 28K/10K resistor divider suggested in the W83781D datasheet) */ + 12000 / 55, /* -12V */ + 5000 / 24, /* -5V */ + 0 + } + }; + if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2) + machine_hwm.voltages[0] = 2800 / 16; /* set higher VCORE (2.8V) for Klamath */ + hwm_set_values(machine_hwm); + device_add(&as99127f_device); + + return ret; +} + + +int +machine_at_p6bxt_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/p6bxt/bxt53s.BIN", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 3, 2, 1); /* Slot 5: Probably the integrated sound chip. */ + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&w83977tf_device); + device_add(&keyboard_ps2_pci_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_63a_init(const machine_t *model) +{ + + /* 440ZX Board. 440ZX is basically an underpowered 440BX. There no + difference between to chipsets other than the name. */ + int ret; + + ret = bios_load_linear(L"roms/machines/63a/63a-q3.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); // Integrated Sound? + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i440zx_device); + device_add(&piix4e_device); + device_add(&w83977tf_device); + device_add(&keyboard_ps2_pci_device); + device_add(&intel_flash_bxt_device); + + return ret; +} #endif diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index 6d25453b6..4244a96e5 100644 --- a/src/machine/m_at_t3100e.c +++ b/src/machine/m_at_t3100e.c @@ -152,17 +152,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../io.h" -#include "../mouse.h" -#include "../mem.h" -#include "../device.h" -#include "../keyboard.h" -#include "../rom.h" -#include "../cpu/cpu.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "86box.h" +#include "timer.h" +#include "86box_io.h" +#include "mouse.h" +#include "mem.h" +#include "device.h" +#include "keyboard.h" +#include "rom.h" +#include "cpu.h" +#include "fdd.h" +#include "fdc.h" #include "machine.h" #include "m_at_t3100e.h" diff --git a/src/machine/m_at_t3100e_vid.c b/src/machine/m_at_t3100e_vid.c index 683789a20..6f9f20200 100644 --- a/src/machine/m_at_t3100e_vid.c +++ b/src/machine/m_at_t3100e_vid.c @@ -57,14 +57,14 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../timer.h" -#include "../cpu/cpu.h" -#include "../video/video.h" -#include "../video/vid_cga.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "timer.h" +#include "cpu.h" +#include "video.h" +#include "vid_cga.h" #include "m_at_t3100e.h" diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index c50fe6364..d642b0099 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -87,22 +87,22 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../nmi.h" -#include "../mem.h" -#include "../pit.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../keyboard.h" -#include "../mouse.h" -#include "../game/gameport.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../disk/hdc.h" -#include "../video/video.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "nmi.h" +#include "mem.h" +#include "pit.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "keyboard.h" +#include "mouse.h" +#include "gameport.h" +#include "fdd.h" +#include "fdc.h" +#include "hdc.h" +#include "video.h" #include "machine.h" diff --git a/src/machine/m_olivetti_m24.c b/src/machine/m_olivetti_m24.c index 9bb84198f..f2fef9bb8 100644 --- a/src/machine/m_olivetti_m24.c +++ b/src/machine/m_olivetti_m24.c @@ -24,25 +24,25 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" -#include "../io.h" -#include "../pic.h" -#include "../pit.h" -#include "../ppi.h" -#include "../nmi.h" -#include "../mem.h" -#include "../device.h" -#include "../nvr.h" -#include "../keyboard.h" -#include "../mouse.h" -#include "../rom.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../sound/sound.h" -#include "../sound/snd_speaker.h" -#include "../video/video.h" +#include "86box.h" +#include "timer.h" +#include "86box_io.h" +#include "pic.h" +#include "pit.h" +#include "ppi.h" +#include "nmi.h" +#include "mem.h" +#include "device.h" +#include "nvr.h" +#include "keyboard.h" +#include "mouse.h" +#include "rom.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "sound.h" +#include "snd_speaker.h" +#include "video.h" #include "machine.h" diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index a5ff9cc8b..77628a800 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -26,25 +26,25 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../device.h" -#include "../serial.h" -#include "../keyboard.h" -#include "../rom.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../sound/sound.h" -#include "../sound/snd_speaker.h" -#include "../sound/snd_sn76489.h" -#include "../video/video.h" -#include "../video/vid_cga_comp.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "nmi.h" +#include "pic.h" +#include "pit.h" +#include "mem.h" +#include "device.h" +#include "serial.h" +#include "keyboard.h" +#include "rom.h" +#include "fdd.h" +#include "fdc.h" +#include "sound.h" +#include "snd_speaker.h" +#include "snd_sn76489.h" +#include "video.h" +#include "vid_cga_comp.h" #include "machine.h" diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 9ff547d45..c8a3ee8b2 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -37,31 +37,29 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../nmi.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../game/gameport.h" -#include "../lpt.h" -#include "../serial.h" -#include "../keyboard.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../sound/sound.h" -#include "../sound/snd_sn76489.h" -#include "../video/video.h" -#include "../video/vid_vga.h" -#include "../video/vid_ti_cf62011.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "pit.h" +#include "mem.h" +#include "nmi.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "gameport.h" +#include "lpt.h" +#include "serial.h" +#include "keyboard.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" +#include "sound.h" +#include "snd_sn76489.h" +#include "video.h" #include "machine.h" diff --git a/src/machine/m_ps1_hdc.c b/src/machine/m_ps1_hdc.c index 5c10ca69b..d767b7aa8 100644 --- a/src/machine/m_ps1_hdc.c +++ b/src/machine/m_ps1_hdc.c @@ -92,16 +92,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../device.h" -#include "../disk/hdc.h" -#include "../disk/hdd.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "timer.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "device.h" +#include "hdc.h" +#include "hdd.h" +#include "plat.h" +#include "ui.h" #include "machine.h" diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index a713278d9..fe6d3e6c4 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -2,25 +2,25 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../port_92.h" -#include "../serial.h" -#include "../disk/hdc.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../video/vid_vga.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "keyboard.h" +#include "lpt.h" +#include "port_92.h" +#include "serial.h" +#include "hdc.h" +#include "fdd.h" +#include "fdc.h" +#include "video.h" #include "machine.h" diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 7eb011931..c4b755a6d 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -42,35 +42,29 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#ifdef USE_NEW_DYNAREC -#include "../cpu_new/cpu.h" -#include "../cpu_new/x86.h" -#else -#include "../cpu/cpu.h" -#include "../cpu/x86.h" -#endif -#include "../timer.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../pit.h" -#include "../mca.h" -#include "../mem.h" -#include "../nmi.h" -#include "../rom.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../nvr.h" -#include "../nvr_ps2.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../mouse.h" -#include "../port_92.h" -#include "../serial.h" -#include "../video/video.h" -#include "../video/vid_vga.h" +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "timer.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "pit.h" +#include "mca.h" +#include "mem.h" +#include "nmi.h" +#include "rom.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "nvr.h" +#include "nvr_ps2.h" +#include "keyboard.h" +#include "lpt.h" +#include "mouse.h" +#include "port_92.h" +#include "serial.h" +#include "video.h" #include "machine.h" diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index bbcf7786c..658f8c1f0 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -24,24 +24,23 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../io.h" -#include "../pit.h" -#include "../nmi.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../keyboard.h" -#include "../sound/sound.h" -#include "../sound/snd_pssj.h" -#include "../sound/snd_sn76489.h" -#include "../video/video.h" -#include "../video/vid_cga_comp.h" +#include "86box.h" +#include "timer.h" +#include "86box_io.h" +#include "pit.h" +#include "nmi.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "keyboard.h" +#include "sound.h" +#include "snd_sn76489.h" +#include "video.h" +#include "vid_cga_comp.h" #include "machine.h" diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index c3bf07897..ec9cd1da6 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -2,18 +2,18 @@ #include #include #include -#include "../86box.h" -#include "../nmi.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../ibm_5161.h" -#include "../keyboard.h" -#include "../rom.h" +#include "86box.h" +#include "nmi.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "ibm_5161.h" +#include "keyboard.h" +#include "rom.h" #include "machine.h" diff --git a/src/machine/m_xt_compaq.c b/src/machine/m_xt_compaq.c index 1e312fe10..edc3cf007 100644 --- a/src/machine/m_xt_compaq.c +++ b/src/machine/m_xt_compaq.c @@ -21,19 +21,19 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../nmi.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../keyboard.h" -#include "../lpt.h" +#include "86box.h" +#include "cpu.h" +#include "nmi.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "keyboard.h" +#include "lpt.h" #include "machine.h" diff --git a/src/machine/m_xt_laserxt.c b/src/machine/m_xt_laserxt.c index f8408952e..41416769c 100644 --- a/src/machine/m_xt_laserxt.c +++ b/src/machine/m_xt_laserxt.c @@ -3,21 +3,21 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../timer.h" -#include "../pit.h" -#include "../rom.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "timer.h" +#include "pit.h" +#include "rom.h" #include "machine.h" -#include "../device.h" -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../keyboard.h" +#include "device.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "keyboard.h" static int laserxt_emspage[4]; diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index ee9bb8cd0..2e8fd40f9 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -87,24 +87,24 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../nmi.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../mem.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../video/video.h" -#include "../plat.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "nmi.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "keyboard.h" +#include "lpt.h" +#include "mem.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "video.h" +#include "plat.h" #include "machine.h" #include "m_xt_t1000.h" diff --git a/src/machine/m_xt_t1000_vid.c b/src/machine/m_xt_t1000_vid.c index 1e2d62e13..8196e8e59 100644 --- a/src/machine/m_xt_t1000_vid.c +++ b/src/machine/m_xt_t1000_vid.c @@ -42,14 +42,14 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../timer.h" -#include "../cpu/cpu.h" -#include "../video/video.h" -#include "../video/vid_cga.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "timer.h" +#include "cpu.h" +#include "video.h" +#include "vid_cga.h" #include "m_xt_t1000.h" diff --git a/src/machine/m_xt_xi8088.c b/src/machine/m_xt_xi8088.c index 162b6da11..42b0d2498 100644 --- a/src/machine/m_xt_xi8088.c +++ b/src/machine/m_xt_xi8088.c @@ -2,25 +2,25 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" -#include "../pic.h" -#include "../pit.h" -#include "../dma.h" -#include "../mem.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../nmi.h" -#include "../nvr.h" -#include "../game/gameport.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../rom.h" -#include "../disk/hdc.h" -#include "../video/video.h" +#include "86box.h" +#include "timer.h" +#include "pic.h" +#include "pit.h" +#include "dma.h" +#include "mem.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "nmi.h" +#include "nvr.h" +#include "gameport.h" +#include "keyboard.h" +#include "lpt.h" +#include "rom.h" +#include "hdc.h" +#include "video.h" #include "machine.h" -#include "../cpu/cpu.h" +#include "cpu.h" #include "m_xt_xi8088.h" diff --git a/src/machine/m_xt_zenith.c b/src/machine/m_xt_zenith.c index 23b44199d..d6b1b5261 100644 --- a/src/machine/m_xt_zenith.c +++ b/src/machine/m_xt_zenith.c @@ -24,22 +24,22 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../dma.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../serial.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "dma.h" +#include "nmi.h" +#include "pic.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "keyboard.h" +#include "lpt.h" +#include "serial.h" #include "machine.h" diff --git a/src/machine/machine.c b/src/machine/machine.c index c2f19bd47..d5a5680b1 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -8,15 +8,15 @@ * * Handling of the emulated machines. * - * Version: @(#)machine.c 1.0.38 2019/11/15 + * Version: @(#)machine.c 1.0.39 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #include #include @@ -24,18 +24,18 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../dma.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../lpt.h" -#include "../serial.h" -#include "../cpu/cpu.h" -#include "../video/video.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "dma.h" +#include "pic.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "lpt.h" +#include "serial.h" +#include "cpu.h" +#include "video.h" #include "machine.h" @@ -81,6 +81,8 @@ machine_init_ex(int m) mem_reset(); lpt_init(); + + smbase = 0x30000; } /* All good, boot the machine! */ diff --git a/src/machine/machine.h b/src/machine/machine.h index 6e03f707a..0a9bf8b35 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)machine.h 1.0.37 2020/01/22 + * Version: @(#)machine.h 1.0.38 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, @@ -190,6 +190,7 @@ extern int machine_at_neat_init(const machine_t *); extern int machine_at_neat_ami_init(const machine_t *); extern int machine_at_goldstar386_init(const machine_t *); +extern int machine_at_micronics386_init(const machine_t *); extern int machine_at_award286_init(const machine_t *); @@ -210,7 +211,6 @@ extern const device_t *at_commodore_sl386sx_get_device(void); /* m_at_386dx_486.c */ extern int machine_at_pb410a_init(const machine_t *); -extern int machine_at_micronics386_init(const machine_t *); extern int machine_at_ali1429_init(const machine_t *); extern int machine_at_winbios1429_init(const machine_t *); @@ -228,7 +228,9 @@ extern int machine_at_win471_init(const machine_t *); extern int machine_at_r418_init(const machine_t *); extern int machine_at_ls486e_init(const machine_t *); +extern int machine_at_4dps_init(const machine_t *); extern int machine_at_alfredo_init(const machine_t *); +extern int machine_at_486sp3g_init(const machine_t *); /* m_at_commodore.c */ extern int machine_at_cmdpc_init(const machine_t *); @@ -287,6 +289,11 @@ extern int machine_at_i430vx_init(const machine_t *); extern int machine_at_p55va_init(const machine_t *); extern int machine_at_j656vxd_init(const machine_t *); +extern int machine_at_5tx52_init(const machine_t *); +extern int machine_at_txp4_init(const machine_t *); +extern int machine_at_ym430tx_init(const machine_t *); +extern int machine_at_sp586tx_init(const machine_t *); + extern int machine_at_mvp3_init(const machine_t *); #ifdef EMU_DEVICE_H @@ -299,6 +306,13 @@ extern int machine_at_i440fx_init(const machine_t *); extern int machine_at_s1668_init(const machine_t *); #endif +extern int machine_at_6abx3_init(const machine_t *); +#if defined(DEV_BRANCH) && defined(USE_I686) /*P2B-LS has no VIA C3 BIOS support, so further investigation may be needed*/ +extern int machine_at_p2bls_init(const machine_t *); +extern int machine_at_p6bxt_init(const machine_t *); +extern int machine_at_63a_init(const machine_t *); +#endif + /* m_at_t3100e.c */ extern int machine_at_t3100e_init(const machine_t *); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 18fc0cf36..c3e4c4959 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.54 2020/01/22 + * Version: @(#)machine_table.c 1.0.55 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, @@ -25,14 +25,20 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "machine.h" +#ifdef USE_NEW_DYNAREC +#define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}} +#define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"Cyrix", cpus_6x863V}, {"", NULL}} +#define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86}, {"", NULL}} +#define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"Cyrix", cpus_6x86SS7}, {"", NULL}} +#else #if defined(DEV_BRANCH) && defined(USE_AMD_K) #define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}} #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) @@ -52,6 +58,8 @@ #define MACHINE_CPUS_PENTIUM_S7 {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}} #endif #endif +#define MACHINE_CPUS_PENTIUM_SS7 MACHINE_CPUS_PENTIUM_S7 +#endif const machine_t machines[] = { { "[8088] AMI XT clone", "amixt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_amixt_init, NULL }, @@ -76,7 +84,7 @@ const machine_t machines[] = { { "[8088] Xi8088", "xi8088", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, xi8088_get_device }, { "[8088] Zenith Data SupersPort", "zdsupers", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 128, 640, 128, 0, machine_xt_zenith_init, NULL }, - { "[8086] Amstrad PC1512", "pc1512", {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device }, + { "[8086] Amstrad PC1512", "pc1512", {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device }, { "[8086] Amstrad PC1640", "pc1640", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc1640_init, pc1640_get_device }, { "[8086] Amstrad PC2086", "pc2086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc2086_init, pc2086_get_device }, { "[8086] Amstrad PC3086", "pc3086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc3086_init, pc3086_get_device }, @@ -118,8 +126,8 @@ const machine_t machines[] = { { "[286 ISA] Toshiba T3100e", "t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL }, { "[286 ISA] Trigem 286M", "tg286m", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_tg286m_init, NULL }, - { "[286 ISA] Samsung Deskmaster 286", "deskmaster286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_deskmaster286_init, NULL }, - + { "[286 ISA] Samsung Deskmaster 286", "deskmaster286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_deskmaster286_init, NULL }, + { "[286 MCA] IBM PS/2 model 50", "ibmps2_m50", {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL }, { "[386SX ISA] AMA-932J", "ama932j", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device }, @@ -127,105 +135,115 @@ const machine_t machines[] = { { "[386SX ISA] AMI Unknown 386SX", "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL }, #endif { "[386SX ISA] Amstrad MegaPC", "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 32, 1, 127, machine_at_wd76c10_init, NULL }, - { "[386SX ISA] Commodore SL386SX", "cbm_sl386sx25", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1024, 8192, 512, 127, machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device }, + { "[386SX ISA] Commodore SL386SX", "cbm_sl386sx25", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1024, 8192, 512, 127, machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device }, { "[386SX ISA] DTK 386SX clone", "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_neat_init, NULL }, { "[386SX ISA] IBM PS/1 model 2121", "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, { "[386SX ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, { "[386SX ISA] KMX-C-02", "kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_kmxc02_init, NULL }, { "[386SX ISA] Goldstar 386", "goldstar386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_goldstar386_init, NULL }, + { "[386SX ISA] Micronics 09-00021", "micronics386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_micronics386_init, NULL }, + { "[386SX MCA] IBM PS/2 model 55SX", "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"IBM",cpus_IBM486SLC},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL }, - { "[386DX ISA] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, { "[386DX ISA] Dataexpert SX495 (386DX)", "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, - { "[386DX ISA] Micronics 09-00021", "micronics386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 16, 1, 127, machine_at_micronics386_init, NULL }, + { "[386DX ISA] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_MR495) { "[386DX ISA] MR 386DX clone", "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, #endif #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) { "[386DX ISA] Compaq Portable III (386)", "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 1, 14, 1, 127, machine_at_portableiii386_init, NULL }, #endif - { "[386DX VLB] Dataexpert SX495 (386DX)", "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, - { "[386DX VLB] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_MR495) - { "[386DX VLB] MR 386DX clone", "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, -#endif + { "[386DX MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL }, { "[386DX MCA] IBM PS/2 model 80", "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 12, 1, 63, machine_ps2_model_80_init, NULL }, - { "[486 ISA] Packard Bell PB410A", "pb410a", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL }, - - { "[486 VLB] Award 486 clone", "award486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, - { "[486 VLB] Dataexpert SX495 (486)", "ami486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, + { "[486 ISA] Dataexpert SX495 (486)", "ami486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, + { "[486 ISA] Olystar LIL1429", "ali1429", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_ali1429_init, NULL }, + { "[486 ISA] AMI SiS 471", "ami471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ami471_init, NULL }, + { "[486 ISA] AMI WinBIOS 486", "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_winbios1429_init, NULL }, + { "[486 ISA] AMI WinBIOS SiS 471", "win471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_win471_init, NULL }, + { "[486 ISA] Award 486 clone", "award486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, + { "[486 ISA] DTK PKM-0038S E-2", "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_dtk486_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_PS1M2133) - { "[486 VLB] IBM PS/1 model 2133", "ibmps1_2133", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_NONMI, 1, 64, 1, 127, machine_ps1_m2133_init, NULL }, + { "[486 ISA] IBM PS/1 model 2133", "ibmps1_2133", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_NONMI, 1, 64, 1, 127, machine_ps1_m2133_init, NULL }, #endif - { "[486 VLB] Olystar LIL1429", "ali1429", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_ali1429_init, NULL }, - - { "[486 VLB] AMI SiS 471", "ami471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ami471_init, NULL }, - { "[486 VLB] AMI WinBIOS 486", "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_winbios1429_init, NULL }, - { "[486 VLB] AMI WinBIOS SiS 471", "win471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_win471_init, NULL }, - { "[486 VLB] DTK PKM-0038S E-2", "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_dtk486_init, NULL }, - #if defined(DEV_BRANCH) && defined(USE_MR495) - { "[486 VLB] MR 486 clone", "mr486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, + { "[486 ISA] MR 486 clone", "mr486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, #endif - { "[486 VLB] Phoenix SiS 471", "px471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_px471_init, NULL }, + { "[486 ISA] Packard Bell PB410A", "pb410a", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 64, 1, 127, machine_at_pb410a_init, NULL }, + { "[486 ISA] Phoenix SiS 471", "px471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_px471_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_PS2M70T4) { "[486 MCA] IBM PS/2 model 70 (type 4)", "ibmps2_m70_type4", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL }, #endif - { "[486 PCI] Intel Classic/PCI", "alfredo", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_alfredo_init, NULL }, - { "[486 PCI] Lucky Star LS-486E", "ls486e", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_ls486e_init, NULL }, - { "[486 PCI] Rise Computer R418", "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL }, + { "[486 PCI] Intel Classic/PCI", "alfredo", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_alfredo_init, NULL }, + { "[486 PCI] Lucky Star LS-486E", "ls486e", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_ls486e_init, NULL }, + { "[486 PCI] Rise Computer R418", "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL }, + { "[486 PCI] Zida 4DPS", "4dps", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_4dps_init, NULL }, + { "[486 PCI] ASUS P/I-486SP3G", "486sp3g", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_486sp3g_init, NULL }, - { "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL }, + { "[Socket 4 LX] Intel Premiere/PCI", "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL }, + { "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_VPP60) - { "[Socket 4 LX] IBM PS/ValuePoint P60", "valuepointp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL }, + { "[Socket 4 LX] IBM PS/ValuePoint P60", "valuepointp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL }, #endif - { "[Socket 4 LX] Intel Premiere/PCI", "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL }, - { "[Socket 4 LX] Micro Star 586MC1", "586mc1", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL }, + { "[Socket 4 LX] Micro Star 586MC1", "586mc1", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL }, - { "[Socket 5 NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp90_init, NULL }, - { "[Socket 5 NX] Intel Premiere/PCI II", "plato", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, - { "[Socket 5 NX] Gigabyte GA-586IP", "430nx", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_430nx_init, NULL }, + { "[Socket 5 NX] Intel Premiere/PCI II", "plato", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, + { "[Socket 5 NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp90_init, NULL }, + { "[Socket 5 NX] Gigabyte GA-586IP", "430nx", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_430nx_init, NULL }, - { "[Socket 5 FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, + { "[Socket 5 FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_VECTRA54) - { "[Socket 5 FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_vectra54_init, NULL }, + { "[Socket 5 FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 255, machine_at_vectra54_init, NULL }, #endif - { "[Socket 5 FX] Intel Advanced/ZP", "zappa", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL }, - { "[Socket 5 FX] PC Partner MB500N", "mb500n", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL }, - { "[Socket 5 FX] President Award 430FX PCI","president", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL }, + { "[Socket 5 FX] Intel Advanced/ZP", "zappa", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL }, + { "[Socket 5 FX] PC Partner MB500N", "mb500n", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL }, + { "[Socket 5 FX] President Award 430FX PCI","president", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL }, - { "[Socket 7-3V FX] Intel Advanced/ATX", "thor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, + { "[Socket 7 FX] Intel Advanced/ATX", "thor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_MRTHOR) - { "[Socket 7-3V FX] MR Intel Advanced/ATX", "mrthor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, + { "[Socket 7 FX] MR Intel Advanced/ATX", "mrthor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, #endif - { "[Socket 7-3V FX] Intel Advanced/EV", "endeavor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, - { "[Socket 7-3V FX] Packard Bell PB640", "pb640", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device }, - - { "[Socket 7-3V HX] Acer M3a", "acerm3a", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL }, - { "[Socket 7-3V HX] AOpen AP53", "ap53", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL }, - { "[Socket 7-3V HX] SuperMicro Super P55T2S","p55t2s", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL }, - { "[Socket 7 HX] Acer V35n", "acerv35n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL }, - { "[Socket 7 HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL }, + { "[Socket 7 FX] Intel Advanced/EV", "endeavor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, + { "[Socket 7 FX] Packard Bell PB640", "pb640", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device }, + + { "[Socket 7 HX] Acer M3a", "acerm3a", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL }, + { "[Socket 7 HX] Acer V35n", "acerv35n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL }, + { "[Socket 7 HX] AOpen AP53", "ap53", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL }, + { "[Socket 7 HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL }, + { "[Socket 7 HX] SuperMicro Super P55T2S", "p55t2s", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_TC430HX) - { "[Socket 7 HX] TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_tc430hx_init, NULL }, - { "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_equium5200_init, NULL }, + { "[Socket 7 HX] TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_tc430hx_init, NULL }, + { "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_equium5200_init, NULL }, #endif - { "[Socket 7 VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL }, - { "[Socket 7 VX] Epox P55-VA", "p55va", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL }, - { "[Socket 7 VX] Jetway J656VXD", "j656vxd", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_j656vxd_init, NULL }, - { "[Socket 7 VX] Shuttle HOT-557", "430vx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL }, + { "[Socket 7 VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL }, + { "[Socket 7 VX] Epox P55-VA", "p55va", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL }, + { "[Socket 7 VX] Jetway J656VXD", "j656vxd", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_j656vxd_init, NULL }, + { "[Socket 7 VX] Shuttle HOT-557", "430vx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL }, - { "[Super 7 MVP3] FIC VA-503+", "ficva503p", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_mvp3_init, NULL }, + { "[Socket 7 TX] Acorp 5TX52", "5tx52", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_5tx52_init, NULL }, + { "[Socket 7 TX] ASUS TXP4", "txp4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_txp4_init, NULL }, + { "[Socket 7 TX] Intel YM430TX", "ym430tx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_ym430tx_init, NULL }, + { "[Socket 7 TX] San-LI/Superpower SP-586TX","sp586tx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_sp586tx_init, NULL }, + + { "[Super Socket 7] FIC VA-503+", "ficva503p", MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_I686) { "[Socket 8 FX] Tyan Titan-Pro AT", "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_i440fx_init, NULL }, { "[Socket 8 FX] Tyan Titan-Pro ATX", "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_s1668_init, NULL }, + + { "[Slot 1 BX] Lucky Star 6ABX3", "6abx3", {{"Intel", cpus_PentiumII}, {"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_6abx3_init, NULL }, +#else + { "[Slot 1 BX] Lucky Star 6ABX3", "6abx3", {{"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_6abx3_init, NULL }, +#endif +#if defined(DEV_BRANCH) && defined(USE_I686) + { "[Slot 1 BX] ASUS P2B-LS", "p2bls", {{"Intel", cpus_PentiumII}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p2bls_init, NULL }, + { "[Socket 370 BX] ECS P6BXT-A+", "p6bxt", {{"Intel", cpus_PGA370}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p6bxt_init, NULL }, + { "[Socket 370 ZX] Soltek SL-63A1", "63a", {{"Intel", cpus_PGA370}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_63a_init, NULL }, #endif { NULL, NULL, {{"", 0}, {"", 0}, {"", 0}, {"", 0}, {"", 0}}, 0, 0, 0, 0, 0, NULL, NULL } }; diff --git a/src/machine/machine_table_new.c b/src/machine/machine_table_new.c deleted file mode 100644 index e51885bf4..000000000 --- a/src/machine/machine_table_new.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * 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. - * - * Handling of the emulated machines. - * - * NOTES: OpenAT wip for 286-class machine with open BIOS. - * PS2_M80-486 wip, pending receipt of TRM's for machine. - * - * Version: @(#)machine_table.c 1.0.54 2020/01/22 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu_new/cpu.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "machine.h" - - -#define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}} -#define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"Cyrix", cpus_6x863V}, {"", NULL}} -#define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86}, {"", NULL}} -#define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"Cyrix", cpus_6x86SS7}, {"", NULL}} - -const machine_t machines[] = { - { "[8088] AMI XT clone", "amixt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_amixt_init, NULL }, - { "[8088] Compaq Portable", "portable", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL }, - { "[8088] DTK XT clone", "dtk", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_dtk_init, NULL }, - { "[8088] IBM PC (1981)", "ibmpc", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 16, 64, 16, 0, machine_pc_init, NULL }, - { "[8088] IBM PC (1982)", "ibmpc82", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 256, 256, 0, machine_pc82_init, NULL }, - { "[8088] IBM PCjr", "ibmpcjr", {{"Intel", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device }, - { "[8088] IBM XT (1982)", "ibmxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 256, 64, 0, machine_xt_init, NULL }, - { "[8088] IBM XT (1986)", "ibmxt86", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 64, 0, machine_xt86_init, NULL }, - { "[8088] Generic XT clone", "genxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_genxt_init, NULL }, - { "[8088] Juko XT clone", "jukopc", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_jukopc_init, NULL }, - { "[8088] OpenXT", "open_xt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_open_xt_init, NULL }, - { "[8088] Phoenix XT clone", "pxxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_pxxt_init, NULL }, - { "[8088] Schneider EuroPC", "europc", {{"Siemens", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_HDC | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL }, - { "[8088] Tandy 1000", "tandy", {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_tandy_init, tandy1k_get_device }, - { "[8088] Tandy 1000 HX", "tandy1000hx", {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 256, 640, 128, 0, machine_tandy1000hx_init, tandy1k_hx_get_device }, - { "[8088] Toshiba T1000", "t1000", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, t1000_get_device }, -#if defined(DEV_BRANCH) && defined(USE_LASERXT) - { "[8088] VTech Laser Turbo XT", "ltxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 256, 0, machine_xt_laserxt_init, NULL }, -#endif - { "[8088] Xi8088", "xi8088", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, xi8088_get_device }, - { "[8088] Zenith Data SupersPort", "zdsupers", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 128, 640, 128, 0, machine_xt_zenith_init, NULL }, - - { "[8086] Amstrad PC1512", "pc1512", {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device }, - { "[8086] Amstrad PC1640", "pc1640", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc1640_init, pc1640_get_device }, - { "[8086] Amstrad PC2086", "pc2086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc2086_init, pc2086_get_device }, - { "[8086] Amstrad PC3086", "pc3086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc3086_init, pc3086_get_device }, - { "[8086] Amstrad PC20(0)", "pc200", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_pc200_init, pc200_get_device }, - { "[8086] Amstrad PPC512/640", "ppc512", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_ppc512_init, ppc512_get_device }, - { "[8086] Olivetti M24", "olivetti_m24", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL }, - { "[8086] Tandy 1000 SL/2", "tandy1000sl2", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 512, 768, 128, 0, machine_tandy1000sl2_init, NULL }, - { "[8086] Toshiba T1200", "t1200", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, t1200_get_device }, -#if defined(DEV_BRANCH) && defined(USE_LASERXT) - { "[8086] VTech Laser XT3", "lxt3", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 256, 0, machine_xt_lxt3_init, NULL }, -#endif - - { "[286 ISA] AMI 286 clone", "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, - { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL }, - { "[286 ISA] Phoenix 286 clone", "px286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_px286_init, NULL }, - { "[286 ISA] Quadtel 286 clone", "quadt286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_quadt286_init, NULL }, - { "[286 ISA] Commodore PC 30 III", "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, - { "[286 ISA] Compaq Portable II", "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - { "[286 ISA] Compaq Portable III", "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 640,16384, 128, 127, machine_at_portableiii_init, NULL }, -#endif - { "[286 ISA] GW-286CT GEAR", "gw286ct", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_gw286ct_init, NULL }, - { "[286 ISA] Hyundai Super-286TR", "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_super286tr_init, NULL }, - { "[286 ISA] IBM AT", "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibm_init, NULL }, - { "[286 ISA] AMI IBM AT", "ibmatami", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatami_init, NULL }, - { "[286 ISA] Quadtel IBM AT", "ibmatquadtel", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatquadtel_init, NULL }, - { "[286 ISA] Phoenix IBM AT", "ibmatpx", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatpx_init, NULL }, - { "[286 ISA] IBM PS/1 model 2011", "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC | MACHINE_PS2, 512,16384, 512, 63, machine_ps1_m2011_init, NULL }, - { "[286 ISA] IBM PS/2 model 30-286", "ibmps2_m30_286", {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC | MACHINE_PS2, 1, 16, 1, 127, machine_ps2_m30_286_init, NULL }, - { "[286 ISA] IBM XT Model 286", "ibmxt286", {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 127, machine_at_ibmxt286_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_SIEMENS) - { "[286 ISA] Siemens PCD-2L", "siemens", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_siemens_init, NULL }, -#endif -#if defined(DEV_BRANCH) && defined(USE_OPEN_AT) - { "[286 ISA] OpenAT", "open_at", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_open_at_init, NULL }, -#endif - { "[286 ISA] Samsung SPC-4200P", "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 512, 2048, 128, 127, machine_at_spc4200p_init, NULL }, - { "[286 ISA] Samsung SPC-4216P", "spc4216p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 1, 5, 1, 127, machine_at_spc4216p_init, NULL }, - { "[286 ISA] Toshiba T3100e", "t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL }, - { "[286 ISA] Trigem 286M", "tg286m", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_tg286m_init, NULL }, - - { "[286 ISA] Samsung Deskmaster 286", "deskmaster286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_deskmaster286_init, NULL }, - - { "[286 MCA] IBM PS/2 model 50", "ibmps2_m50", {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL }, - - { "[386SX ISA] AMA-932J", "ama932j", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device }, -#if defined(DEV_BRANCH) && defined(USE_AMI386SX) - { "[386SX ISA] AMI Unknown 386SX", "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL }, -#endif - { "[386SX ISA] Amstrad MegaPC", "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 32, 1, 127, machine_at_wd76c10_init, NULL }, - { "[386SX ISA] Commodore SL386SX", "cbm_sl386sx25", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1024, 8192, 512, 127, machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device }, - { "[386SX ISA] DTK 386SX clone", "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_neat_init, NULL }, - { "[386SX ISA] IBM PS/1 model 2121", "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, - { "[386SX ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, - { "[386SX ISA] KMX-C-02", "kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_kmxc02_init, NULL }, - - { "[386SX ISA] Goldstar 386", "goldstar386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_goldstar386_init, NULL }, - { "[386SX MCA] IBM PS/2 model 55SX", "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"IBM",cpus_IBM486SLC},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL }, - - { "[386DX ISA] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, - { "[386DX ISA] Dataexpert SX495 (386DX)", "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, - { "[386DX ISA] Micronics 09-00021", "micronics386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 16, 1, 127, machine_at_micronics386_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_MR495) - { "[386DX ISA] MR 386DX clone", "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, -#endif -#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - { "[386DX ISA] Compaq Portable III (386)", "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 1, 14, 1, 127, machine_at_portableiii386_init, NULL }, -#endif - - { "[386DX VLB] Dataexpert SX495 (386DX)", "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, - { "[386DX VLB] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_MR495) - { "[386DX VLB] MR 386DX clone", "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, -#endif - - { "[386DX MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL }, - { "[386DX MCA] IBM PS/2 model 80", "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 12, 1, 63, machine_ps2_model_80_init, NULL }, - - { "[486 ISA] Packard Bell PB410A", "pb410a", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL }, - - { "[486 VLB] Award 486 clone", "award486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, - { "[486 VLB] Dataexpert SX495 (486)", "ami486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_PS1M2133) - { "[486 VLB] IBM PS/1 model 2133", "ibmps1_2133", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_NONMI, 1, 64, 1, 127, machine_ps1_m2133_init, NULL }, -#endif - { "[486 VLB] Olystar LIL1429", "ali1429", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_ali1429_init, NULL }, - - { "[486 VLB] AMI SiS 471", "ami471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ami471_init, NULL }, - { "[486 VLB] AMI WinBIOS 486", "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_winbios1429_init, NULL }, - { "[486 VLB] AMI WinBIOS SiS 471", "win471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_win471_init, NULL }, - { "[486 VLB] DTK PKM-0038S E-2", "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_dtk486_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_MR495) - { "[486 VLB] MR 486 clone", "mr486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, -#endif - { "[486 VLB] Phoenix SiS 471", "px471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_px471_init, NULL }, - -#if defined(DEV_BRANCH) && defined(USE_PS2M70T4) - { "[486 MCA] IBM PS/2 model 70 (type 4)", "ibmps2_m70_type4", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL }, -#endif - - { "[486 PCI] Intel Classic/PCI", "alfredo", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_alfredo_init, NULL }, - { "[486 PCI] Lucky Star LS-486E", "ls486e", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_ls486e_init, NULL }, - { "[486 PCI] Rise Computer R418", "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL }, - - { "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_VPP60) - { "[Socket 4 LX] IBM PS/ValuePoint P60", "valuepointp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL }, -#endif - { "[Socket 4 LX] Intel Premiere/PCI", "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL }, - { "[Socket 4 LX] Micro Star 586MC1", "586mc1", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL }, - - { "[Socket 5 NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp90_init, NULL }, - { "[Socket 5 NX] Intel Premiere/PCI II", "plato", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, - { "[Socket 5 NX] Gigabyte GA-586IP", "430nx", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_430nx_init, NULL }, - - { "[Socket 5 FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_VECTRA54) - { "[Socket 5 FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_vectra54_init, NULL }, -#endif - { "[Socket 5 FX] Intel Advanced/ZP", "zappa", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL }, - { "[Socket 5 FX] PC Partner MB500N", "mb500n", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL }, - { "[Socket 5 FX] President Award 430FX PCI","president", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL }, - - { "[Socket 7-3V FX] Intel Advanced/ATX", "thor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_MRTHOR) - { "[Socket 7-3V FX] MR Intel Advanced/ATX", "mrthor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, -#endif - { "[Socket 7-3V FX] Intel Advanced/EV", "endeavor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, - { "[Socket 7-3V FX] Packard Bell PB640", "pb640", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device }, - - { "[Socket 7-3V HX] Acer M3a", "acerm3a", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL }, - { "[Socket 7-3V HX] AOpen AP53", "ap53", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL }, - { "[Socket 7-3V HX] SuperMicro Super P55T2S","p55t2s", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL }, - { "[Socket 7 HX] Acer V35n", "acerv35n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL }, - { "[Socket 7 HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_TC430HX) - { "[Socket 7 HX] TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_tc430hx_init, NULL }, - { "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_equium5200_init, NULL }, -#endif - - { "[Socket 7 VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL }, - { "[Socket 7 VX] Epox P55-VA", "p55va", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL }, - { "[Socket 7 VX] Jetway J656VXD", "j656vxd", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_j656vxd_init, NULL }, - { "[Socket 7 VX] Shuttle HOT-557", "430vx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL }, - - { "[Super 7 MVP3] FIC VA-503+", "ficva503p", MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_mvp3_init, NULL }, - -#if defined(DEV_BRANCH) && defined(USE_I686) - { "[Socket 8 FX] Tyan Titan-Pro AT", "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_i440fx_init, NULL }, - { "[Socket 8 FX] Tyan Titan-Pro ATX", "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_s1668_init, NULL }, -#endif - { NULL, NULL, {{"", 0}, {"", 0}, {"", 0}, {"", 0}, {"", 0}}, 0, 0, 0, 0, 0, NULL, NULL } -}; - - -int -machine_count(void) -{ - return((sizeof(machines) / sizeof(machine)) - 1); -} - - -char * -machine_getname(void) -{ - return((char *)machines[machine].name); -} - - -char * -machine_getname_ex(int m) -{ - return((char *)machines[m].name); -} - - -const device_t * -machine_getdevice(int m) -{ - if (machines[m].get_device) - return(machines[m].get_device()); - - return(NULL); -} - - -char * -machine_get_internal_name(void) -{ - return((char *)machines[machine].internal_name); -} - - -char * -machine_get_internal_name_ex(int m) -{ - return((char *)machines[m].internal_name); -} - - -int -machine_get_nvrmask(int m) -{ - return(machines[m].nvrmask); -} - - -int -machine_get_machine_from_internal_name(char *s) -{ - int c = 0; - - while (machines[c].init != NULL) { - if (!strcmp(machines[c].internal_name, (const char *)s)) - return(c); - c++; - } - - return(0); -} diff --git a/src/machine_table.txt b/src/machine_table.txt new file mode 100644 index 000000000..0b331e8c7 --- /dev/null +++ b/src/machine_table.txt @@ -0,0 +1,3 @@ +Comparing files MACHINE\machine_table.c and MACHINE\MACHINE_TABLE_NEW.C +FC: no differences encountered + diff --git a/src/mca.c b/src/mca.c index 73e227b8e..b9ab31487 100644 --- a/src/mca.c +++ b/src/mca.c @@ -2,7 +2,7 @@ #include #include #include -#include "io.h" +#include "86box_io.h" #include "mca.h" diff --git a/src/mem.c b/src/mem.c index 0741e18d5..114bca468 100644 --- a/src/mem.c +++ b/src/mem.c @@ -12,15 +12,15 @@ * the DYNAMIC_TABLES=1 enables this. Will eventually go * away, either way... * - * Version: @(#)mem.c 1.0.22 2019/12/02 + * Version: @(#)mem.c 1.0.23 2020/01/25 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #include #include @@ -30,23 +30,27 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu/cpu.h" -#include "cpu/x86_ops.h" -#include "cpu/x86.h" -#include "machine/machine.h" -#include "machine/m_xt_xi8088.h" +#include "cpu.h" +#include "x86_ops.h" +#include "x86.h" +#include "machine.h" +#include "m_xt_xi8088.h" #include "config.h" -#include "io.h" +#include "86box_io.h" #include "mem.h" #include "rom.h" #ifdef USE_DYNAREC -# include "cpu/codegen.h" +# include "codegen_public.h" +#else +#ifdef USE_NEW_DYNAREC +# define PAGE_MASK_SHIFT 6 #else # define PAGE_MASK_INDEX_MASK 3 # define PAGE_MASK_INDEX_SHIFT 10 -# define PAGE_MASK_MASK 63 # define PAGE_MASK_SHIFT 4 #endif +# define PAGE_MASK_MASK 63 +#endif #define FIXME 0 @@ -105,12 +109,18 @@ int mem_a20_key = 0, int mmuflush = 0; int mmu_perm = 4; +uint64_t *byte_dirty_mask; +uint64_t *byte_code_present_mask; + +uint32_t purgable_page_list_head = 0; +int purgeable_page_count = 0; + /* FIXME: re-do this with a 'mem_ops' struct. */ static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; -static int _mem_state[MEM_MAPPINGS_NO]; +static int _mem_state[MEM_MAPPINGS_NO], _mem_state_bak[MEM_MAPPINGS_NO]; #if FIXME #if (MEM_GRANULARITY_BITS >= 12) @@ -433,13 +443,17 @@ addwritelookup(uint32_t virt, uint32_t phys) writelookup2[writelookup[writelnext]] = -1; } +#ifdef USE_NEW_DYNAREC + if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) +#else #ifdef USE_DYNAREC if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page) #else if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3]) +#endif #endif page_lookup[virt >> 12] = &pages[phys >> 12]; - else + else writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; writelookupp[writelnext] = mmu_perm; @@ -512,16 +526,15 @@ writemembl(uint32_t addr, uint8_t val) mem_mapping_t *map; mem_logical_addr = addr; - if (page_lookup[addr>>12]) - { + if (page_lookup[addr>>12]) { page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); - return; } if (cr0 >> 31) { addr = mmutranslate_write(addr); - if (addr == 0xffffffff) return; + if (addr == 0xffffffff) + return; } addr &= rammask; @@ -530,6 +543,297 @@ writemembl(uint32_t addr, uint8_t val) map->write_b(addr, val, map->p); } + +#ifdef USE_NEW_DYNAREC +uint16_t +readmemwl(uint32_t addr) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr & 0xfff) > 0xffe) { + if (cr0 >> 31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffff; + if (mmutranslate_read(addr+1) == 0xffffffff) + return 0xffff; + } + return readmembl(addr)|(readmembl(addr+1)<<8); + } else if (readlookup2[addr >> 12] != -1) + return *(uint16_t *)(readlookup2[addr >> 12] + addr); + } + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr == 0xffffffff) + return 0xffff; + } + + addr &= rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map && map->read_w) + return map->read_w(addr, map->p); + + if (map && map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8); + + return 0xffff; +} + + +void +writememwl(uint32_t addr, uint16_t val) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFFE) { + if (cr0 >> 31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+1) == 0xffffffff) + return; + } + writemembl(addr,val); + writemembl(addr+1,val>>8); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; + return; + } + } + + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_w(addr, val, page_lookup[addr>>12]); + return; + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } + + addr &= rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_w) + map->write_w(addr, val, map->p); + else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + } + } +} + + +uint32_t +readmemll(uint32_t addr) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 3) { + if (!cpu_cyrix_alignment || (addr & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr&0xFFF)>0xFFC) { + if (cr0>>31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffffffff; + if (mmutranslate_read(addr+3) == 0xffffffff) + return 0xffffffff; + } + return readmemwl(addr)|(readmemwl(addr+2)<<16); + } else if (readlookup2[addr >> 12] != -1) + return *(uint32_t *)(readlookup2[addr >> 12] + addr); + } + + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) + return 0xFFFFFFFF; + } + + addr&=rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->read_l) + return map->read_l(addr, map->p); + + if (map->read_w) + return map->read_w(addr, map->p) | (map->read_w(addr + 2, map->p) << 16); + + if (map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8) | + (map->read_b(addr + 2, map->p) << 16) | (map->read_b(addr + 3, map->p) << 24); + } + + return 0xffffffff; +} + + +void +writememll(uint32_t addr, uint32_t val) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 3) { + if (!cpu_cyrix_alignment || (addr & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFFC) { + if (cr0>>31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+3) == 0xffffffff) + return; + } + writememwl(addr,val); + writememwl(addr+2,val>>16); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; + return; + } + } + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); + return; + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } + + addr&=rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_l) + map->write_l(addr, val, map->p); + else if (map->write_w) { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + } else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + } + } +} + + +uint64_t +readmemql(uint32_t addr) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 7) { + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFF8) { + if (cr0>>31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffffffff; + if (mmutranslate_read(addr+7) == 0xffffffff) + return 0xffffffff; + } + return readmemll(addr)|((uint64_t)readmemll(addr+4)<<32); + } else if (readlookup2[addr >> 12] != -1) + return *(uint64_t *)(readlookup2[addr >> 12] + addr); + } + + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) + return 0xFFFFFFFF; + } + + addr&=rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map && map->read_l) + return map->read_l(addr, map->p) | ((uint64_t)map->read_l(addr + 4, map->p) << 32); + + return readmemll(addr) | ((uint64_t)readmemll(addr+4)<<32); +} + + +void +writememql(uint32_t addr, uint64_t val) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 7) { + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFF8) { + if (cr0>>31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+7) == 0xffffffff) + return; + } + writememll(addr, val); + writememll(addr+4, val >> 32); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint64_t *)(writelookup2[addr >> 12] + addr) = val; + return; + } + } + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); + page_lookup[addr>>12]->write_l(addr + 4, val >> 32, page_lookup[addr>>12]); + return; + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } + + addr&=rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_l) { + map->write_l(addr, val, map->p); + map->write_l(addr + 4, val >> 32, map->p); + } else if (map->write_w) { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + map->write_w(addr + 4, val >> 32, map->p); + map->write_w(addr + 6, val >> 48, map->p); + } else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + map->write_b(addr + 4, val >> 32, map->p); + map->write_b(addr + 5, val >> 40, map->p); + map->write_b(addr + 6, val >> 48, map->p); + map->write_b(addr + 7, val >> 56, map->p); + } + } +} +#else uint8_t readmemb386l(uint32_t seg, uint32_t addr) { @@ -553,10 +857,12 @@ readmemwl(uint32_t seg, uint32_t addr) if (addr2 & 1) { if (!cpu_cyrix_alignment || (addr2 & 7) == 7) sub_cycles(timing_misaligned); - if ((addr2 & 0xFFF) > 0xffe) { + if ((addr2 & 0xfff) > 0xffe) { if (cr0 >> 31) { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; - if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff; + if (mmutranslate_read(addr2) == 0xffffffff) + return 0xffff; + if (mmutranslate_read(addr2+1) == 0xffffffff) + return 0xffff; } if (is386) return readmemb386l(seg,addr)|(((uint16_t) readmemb386l(seg,addr+1))<<8); else return readmembl(seg+addr)|(((uint16_t) readmembl(seg+addr+1))<<8); @@ -568,7 +874,7 @@ readmemwl(uint32_t seg, uint32_t addr) if (cr0 >> 31) { addr2 = mmutranslate_read(addr2); if (addr2 == 0xffffffff) - return 0xFFFF; + return 0xffff; } addr2 &= rammask; @@ -843,6 +1149,7 @@ writememql(uint32_t seg, uint32_t addr, uint64_t val) return; } } +#endif int @@ -894,6 +1201,7 @@ mem_readw_phys(uint32_t addr) return temp; } + uint32_t mem_readl_phys(uint32_t addr) { @@ -914,6 +1222,7 @@ mem_readl_phys(uint32_t addr) return temp; } + void mem_writeb_phys(uint32_t addr, uint8_t val) { @@ -925,6 +1234,7 @@ mem_writeb_phys(uint32_t addr, uint8_t val) map->write_b(addr, val, map->p); } + void mem_writel_phys(uint32_t addr, uint32_t val) { @@ -943,6 +1253,7 @@ mem_writel_phys(uint32_t addr, uint32_t val) } } + uint8_t mem_read_ram(uint32_t addr, void *priv) { @@ -970,6 +1281,114 @@ mem_read_raml(uint32_t addr, void *priv) } +#ifdef USE_NEW_DYNAREC +static inline int +page_index(page_t *p) +{ + return ((uintptr_t)p - (uintptr_t)pages) / sizeof(page_t); +} + + +void +page_add_to_evict_list(page_t *p) +{ + pages[purgable_page_list_head].evict_prev = page_index(p); + p->evict_next = purgable_page_list_head; + p->evict_prev = 0; + purgable_page_list_head = pages[purgable_page_list_head].evict_prev; + purgeable_page_count++; +} + + +void +page_remove_from_evict_list(page_t *p) +{ + if (!page_in_evict_list(p)) + fatal("page_remove_from_evict_list: not in evict list!\n"); + if (p->evict_prev) + pages[p->evict_prev].evict_next = p->evict_next; + else + purgable_page_list_head = p->evict_next; + if (p->evict_next) + pages[p->evict_next].evict_prev = p->evict_prev; + p->evict_prev = EVICT_NOT_IN_LIST; + purgeable_page_count--; +} + + +void +mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) +{ + if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + + p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + p->byte_dirty_mask[byte_offset] |= byte_mask; + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +} + + +void +mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) +{ + if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + + if ((addr & 0xf) == 0xf) + mask |= (mask << 1); + *(uint16_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + if ((addr & PAGE_BYTE_MASK_MASK) == PAGE_BYTE_MASK_MASK) { + p->byte_dirty_mask[byte_offset+1] |= 1; + if ((p->byte_code_present_mask[byte_offset+1] & 1) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } else + byte_mask |= (byte_mask << 1); + + p->byte_dirty_mask[byte_offset] |= byte_mask; + + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +} + + +void +mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) +{ + if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)0xf << (addr & PAGE_BYTE_MASK_MASK); + + if ((addr & 0xf) >= 0xd) + mask |= (mask << 1); + *(uint32_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + p->byte_dirty_mask[byte_offset] |= byte_mask; + if (!page_in_evict_list(p) && ((p->code_present_mask & mask) || (p->byte_code_present_mask[byte_offset] & byte_mask))) + page_add_to_evict_list(p); + if ((addr & PAGE_BYTE_MASK_MASK) > (PAGE_BYTE_MASK_MASK-3)) { + uint32_t byte_mask_2 = 0xf >> (4 - (addr & 3)); + + p->byte_dirty_mask[byte_offset+1] |= byte_mask_2; + if ((p->byte_code_present_mask[byte_offset+1] & byte_mask_2) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } + } +} +#else void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) { @@ -1017,6 +1436,7 @@ mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) *(uint32_t *)&p->mem[addr & 0xfff] = val; } } +#endif void @@ -1169,12 +1589,32 @@ mem_write_nulll(uint32_t addr, uint32_t val, void *p) void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) { + uint64_t mask; +#ifdef USE_NEW_DYNAREC + page_t *p; + + start_addr &= ~PAGE_MASK_MASK; + end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; + + for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { + if ((start_addr >> 12) >= pages_sz) + continue; + + mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + p = &pages[start_addr >> 12]; + + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +#else uint32_t cur_addr; start_addr &= ~PAGE_MASK_MASK; end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { - uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); /* Do nothing if the pages array is empty or DMA reads/writes to/from PCI device memory addresses may crash the emulator. */ @@ -1182,6 +1622,7 @@ mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) if (cur_addr < pages_sz) pages[cur_addr].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; } +#endif } @@ -1278,11 +1719,11 @@ mem_mapping_recalc(uint64_t base, uint64_t size) for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { if ((map->read_b || map->read_w || map->read_l) && mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) { + read_mapping[c >> MEM_GRANULARITY_BITS] = map; if (map->exec) _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); else _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; - read_mapping[c >> MEM_GRANULARITY_BITS] = map; } if ((map->write_b || map->write_w || map->write_l) && mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) @@ -1440,8 +1881,22 @@ mem_set_mem_state(uint32_t base, uint32_t size, int state) { uint32_t c; - for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { + _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state[(c + base) >> MEM_GRANULARITY_BITS]; _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = state; + } + + mem_mapping_recalc(base, size); +} + + +void +mem_restore_mem_state(uint32_t base, uint32_t size) +{ + uint32_t c; + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS]; mem_mapping_recalc(base, size); } @@ -1521,11 +1976,17 @@ mem_reset(void) m = 4096; } else { /* 80386+; maximum address space is 4GB. */ - m = (mem_size + 384) >> 2; - if ((m << 2) < (mem_size + 384)) - m++; - if (m < 4096) - m = 4096; + if (is486) { + /* We need this since there might be BIOS execution at the end of RAM, + which could break the recompiler if there's not enough page elements. */ + m = 1048576; + } else { + m = (mem_size + 384) >> 2; + if ((m << 2) < (mem_size + 384)) + m++; + if (m < 4096) + m = 4096; + } } } else { /* 8088/86; maximum address space is 1MB. */ @@ -1572,12 +2033,32 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); memset(pages, 0x00, pages_sz*sizeof(page_t)); +#ifdef USE_NEW_DYNAREC + if (byte_dirty_mask) { + free(byte_dirty_mask); + byte_dirty_mask = NULL; + } + byte_dirty_mask = malloc((mem_size * 1024) / 8); + memset(byte_dirty_mask, 0, (mem_size * 1024) / 8); + + if (byte_code_present_mask) { + free(byte_code_present_mask); + byte_code_present_mask = NULL; + } + byte_code_present_mask = malloc((mem_size * 1024) / 8); + memset(byte_code_present_mask, 0, (mem_size * 1024) / 8); +#endif for (c = 0; c < pages_sz; c++) { pages[c].mem = &ram[c << 12]; pages[c].write_b = mem_write_ramb_page; pages[c].write_w = mem_write_ramw_page; pages[c].write_l = mem_write_raml_page; +#ifdef USE_NEW_DYNAREC + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; +#endif } memset(_mem_exec, 0x00, sizeof(_mem_exec)); @@ -1585,6 +2066,7 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); memset(&base_mapping, 0x00, sizeof(base_mapping)); memset(_mem_state, 0x00, sizeof(_mem_state)); + memset(_mem_state_bak, 0x00, sizeof(_mem_state_bak)); mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); @@ -1630,6 +2112,11 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); mem_mapping_disable(&ram_remapped_mapping); mem_a20_init(); + +#ifdef USE_NEW_DYNAREC + purgable_page_list_head = 0; + purgeable_page_count = 0; +#endif } @@ -1667,7 +2154,7 @@ mem_remap_top(int kb) { int c; uint32_t start = (mem_size >= 1024) ? mem_size : 1024; - int size = mem_size - 640; + int offset, size = mem_size - 640; mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); if (mem_size <= 640) return; @@ -1683,10 +2170,16 @@ mem_remap_top(int kb) size = kb; for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { - pages[c].mem = &ram[0xA0000 + ((c - ((start * 1024) >> 12)) << 12)]; + offset = c - ((start * 1024) >> 12); + pages[c].mem = &ram[0xA0000 + (offset << 12)]; pages[c].write_b = mem_write_ramb_page; pages[c].write_w = mem_write_ramw_page; pages[c].write_l = mem_write_raml_page; +#ifdef USE_NEW_DYNAREC + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64]; +#endif } mem_set_mem_state(start * 1024, size * 1024, @@ -1697,6 +2190,7 @@ mem_remap_top(int kb) flushmmucache(); } + void mem_reset_page_blocks(void) { @@ -1708,8 +2202,13 @@ mem_reset_page_blocks(void) pages[c].write_b = mem_write_ramb_page; pages[c].write_w = mem_write_ramw_page; pages[c].write_l = mem_write_raml_page; +#ifdef USE_NEW_DYNAREC + pages[c].block = BLOCK_INVALID; + pages[c].block_2 = BLOCK_INVALID; +#else pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = NULL; pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = NULL; +#endif } } diff --git a/src/mem.h b/src/mem.h index 6b5641ee6..badcb2d3c 100644 --- a/src/mem.h +++ b/src/mem.h @@ -8,15 +8,15 @@ * * Definitions for the memory interface. * - * Version: @(#)mem.h 1.0.10 2019/10/19 + * Version: @(#)mem.h 1.0.11 2020/01/25 * * Authors: Sarah Walker, * Fred N. van Kempen, * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2020 Miran Grca. */ #ifndef EMU_MEM_H # define EMU_MEM_H @@ -262,6 +262,7 @@ extern void mem_mapping_disable(mem_mapping_t *); extern void mem_mapping_enable(mem_mapping_t *); extern void mem_set_mem_state(uint32_t base, uint32_t size, int state); +extern void mem_restore_mem_state(uint32_t base, uint32_t size); extern uint8_t mem_readb_phys(uint32_t addr); extern uint16_t mem_readw_phys(uint32_t addr); @@ -302,6 +303,7 @@ extern void flushmmucache_cr3(void); extern void flushmmucache_nopc(void); extern void mmu_invalidate(uint32_t addr); +extern void mem_a20_init(void); extern void mem_a20_recalc(void); extern void mem_add_upper_bios(void); diff --git a/src/mem.txt b/src/mem.txt new file mode 100644 index 000000000..e0b8dbede --- /dev/null +++ b/src/mem.txt @@ -0,0 +1,2466 @@ +Comparing files mem.c and MEM_NEW.C +***** mem.c + + +***** MEM_NEW.C + +uint64_t *byte_dirty_mask; +uint64_t *byte_code_present_mask; + +uint32_t purgable_page_list_head = 0; +int purgeable_page_count = 0; + + +***** + +***** mem.c + +#ifdef USE_DYNAREC + if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || + (phys & ~0xfff) == recomp_page) +#else + if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3]) +#endif + page_lookup[virt >> 12] = &pages[phys >> 12]; + else + writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; +***** MEM_NEW.C + + if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) + page_lookup[virt >> 12] = &pages[phys >> 12];//(uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)] +; + else + writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; +***** + +***** mem.c + page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); + + return; +***** MEM_NEW.C + page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); + return; +***** + +***** mem.c + addr = mmutranslate_write(addr); + if (addr == 0xffffffff) + return; +***** MEM_NEW.C + addr = mmutranslate_write(addr); + if (addr == 0xFFFFFFFF) + return; +***** + +***** mem.c + if (map && map->write_b) + map->write_b(addr, val, map->p); +} +***** MEM_NEW.C + if (map && map->write_b) + return map->write_b(addr, val, map->p); +} +***** + +***** mem.c + +uint8_t +readmemb386l(uint32_t seg, uint32_t addr) +{ + return readmembl(addr + seg); +} + + +void +writememb386l(uint32_t seg, uint32_t addr, uint8_t val) +{ + writemembl(addr + seg, val); +} + + +***** MEM_NEW.C + + +***** + +***** mem.c +uint16_t +readmemwl(uint32_t seg, uint32_t addr) +{ +***** MEM_NEW.C +uint16_t +readmemwl(uint32_t addr) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 1) { + if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr2 & 0xFFF) > 0xffe) { + if (cr0 >> 31) { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; + if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff; + } + if (is386) return readmemb386l(seg,addr)|(((uint16_t) readmemb386l(seg,addr+1))<<8); + else return readmembl(seg+addr)|(((uint16_t) readmembl(seg+addr+1))<<8); + } + else if (readlookup2[addr2 >> 12] != (uintptr_t) -1) + return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2); + } + + if (cr0 >> 31) { + addr2 = mmutranslate_read(addr2); + if (addr2 == 0xffffffff) + return 0xFFFF; +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFFE) { + if (cr0 >> 31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffff; + if (mmutranslate_read(addr+1) == 0xffffffff) + return 0xffff; + } + return readmembl(addr)|(readmembl(addr+1)<<8); + } else if (readlookup2[addr >> 12] != -1) + return *(uint16_t *)(readlookup2[addr >> 12] + addr); + } + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) + return 0xFFFF; +***** + +***** mem.c + + addr2 &= rammask; + + map = read_mapping[addr2 >> MEM_GRANULARITY_BITS]; + + if (map && map->read_w) + return map->read_w(addr2, map->p); + + if (map && map->read_b) { + if (AT) + return map->read_b(addr2, map->p) | + ((uint16_t) (map->read_b(addr2 + 1, map->p)) << 8); + else + return map->read_b(addr2, map->p) | + ((uint16_t) (map->read_b(seg + ((addr + 1) & 0xffff), map->p)) << 8); + } +***** MEM_NEW.C + + addr &= rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->read_w) + return map->read_w(addr, map->p); + + if (map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8); + } +***** + +***** mem.c +void +writememwl(uint32_t seg, uint32_t addr, uint16_t val) +{ +***** MEM_NEW.C +void +writememwl(uint32_t addr, uint16_t val) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 1) { + if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr2 & 0xFFF) > 0xffe) { + if (cr0 >> 31) { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+1) == 0xffffffff) return; + } + if (is386) { + writememb386l(seg,addr,val); + writememb386l(seg,addr+1,val>>8); + } else { + writemembl(seg+addr,val); + writemembl(seg+addr+1,val>>8); + } + return; + } else if (writelookup2[addr2 >> 12] != (uintptr_t) -1) { + *(uint16_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFFE) { + if (cr0 >> 31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+1) == 0xffffffff) + return; + } + writemembl(addr,val); + writemembl(addr+1,val>>8); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; + return; +***** + +***** mem.c + + if (page_lookup[addr2>>12]) { + page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]); + return; +***** MEM_NEW.C + + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_w(addr, val, page_lookup[addr>>12]); + return; +***** + +***** mem.c + } + + if (cr0 >> 31) { + addr2 = mmutranslate_write(addr2); + if (addr2 == 0xffffffff) return; + } +***** MEM_NEW.C + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } +***** + +***** mem.c + + addr2 &= rammask; + + map = write_mapping[addr2 >> MEM_GRANULARITY_BITS]; + + if (map && map->write_w) { + map->write_w(addr2, val, map->p); + return; + } + + if (map && map->write_b) { + map->write_b(addr2, val, map->p); + map->write_b(addr2 + 1, val >> 8, map->p); + return; + } +***** MEM_NEW.C + + addr &= rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_w) + map->write_w(addr, val, map->p); + else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + } + } +***** + +***** mem.c +uint32_t +readmemll(uint32_t seg, uint32_t addr) +{ +***** MEM_NEW.C +uint32_t +readmemll(uint32_t addr) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 3) { + if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr2 & 0xfff) > 0xffc) { + if (cr0 >> 31) { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff; + } + return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); + } else if (readlookup2[addr2 >> 12] != (uintptr_t) -1) + return *(uint32_t *)(readlookup2[addr2 >> 12] + addr2); + } +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 3) { + if (!cpu_cyrix_alignment || (addr & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr&0xFFF)>0xFFC) { + if (cr0>>31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffffffff; + if (mmutranslate_read(addr+3) == 0xffffffff) + return 0xffffffff; + } + return readmemwl(addr)|(readmemwl(addr+2)<<16); + } else if (readlookup2[addr >> 12] != -1) + return *(uint32_t *)(readlookup2[addr >> 12] + addr); + } +***** + +***** mem.c + + if (cr0 >> 31) { + addr2 = mmutranslate_read(addr2); + if (addr2 == 0xffffffff) + return 0xffffffff; + } +***** MEM_NEW.C + + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) + return 0xFFFFFFFF; + } +***** + +***** mem.c + + addr2 &= rammask; + + map = read_mapping[addr2 >> MEM_GRANULARITY_BITS]; + + if (map && map->read_l) + return map->read_l(addr2, map->p); + + if (map && map->read_w) + return map->read_w(addr2, map->p) | + ((uint32_t) (map->read_w(addr2 + 2, map->p)) << 16); + + if (map && map->read_b) + return map->read_b(addr2, map->p) | + ((uint32_t) (map->read_b(addr2 + 1, map->p)) << 8) | + ((uint32_t) (map->read_b(addr2 + 2, map->p)) << 16) | + ((uint32_t) (map->read_b(addr2 + 3, map->p)) << 24); + +***** MEM_NEW.C + + addr&=rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->read_l) + return map->read_l(addr, map->p); + + if (map->read_w) + return map->read_w(addr, map->p) | (map->read_w(addr + 2, map->p) << 16); + + if (map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8) | + (map->read_b(addr + 2, map->p) << 16) | (map->read_b(addr + 3, map->p) << 24); + } + +***** + +***** mem.c +void +writememll(uint32_t seg, uint32_t addr, uint32_t val) +{ +***** MEM_NEW.C +void +writememll(uint32_t addr, uint32_t val) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 3) { + if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr2 & 0xfff) > 0xffc) { + if (cr0 >> 31) { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+3) == 0xffffffff) return; + } + writememwl(seg,addr,val); + writememwl(seg,addr+2,val>>16); + return; + } else if (writelookup2[addr2 >> 12] != (uintptr_t) -1) { + *(uint32_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 3) { + if (!cpu_cyrix_alignment || (addr & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFFC) { + if (cr0>>31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+3) == 0xffffffff) + return; + } + writememwl(addr,val); + writememwl(addr+2,val>>16); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; + return; +***** + +***** mem.c + } + + if (page_lookup[addr2>>12]) { + page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); + return; +***** MEM_NEW.C + } + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); + return; +***** + +***** mem.c + } + + if (cr0 >> 31) { + addr2 = mmutranslate_write(addr2); + if (addr2 == 0xffffffff) return; + } +***** MEM_NEW.C + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } +***** + +***** mem.c + + addr2 &= rammask; + + map = write_mapping[addr2 >> MEM_GRANULARITY_BITS]; + + if (map && map->write_l) { + map->write_l(addr2, val, map->p); + return; + } + if (map && map->write_w) { + map->write_w(addr2, val, map->p); + map->write_w(addr2 + 2, val >> 16, map->p); + return; + } + if (map && map->write_b) { + map->write_b(addr2, val, map->p); + map->write_b(addr2 + 1, val >> 8, map->p); + map->write_b(addr2 + 2, val >> 16, map->p); + map->write_b(addr2 + 3, val >> 24, map->p); + return; + } +***** MEM_NEW.C + + addr&=rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_l) + map->write_l(addr, val, map->p); + else if (map->write_w) { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + } else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + } + } +***** + +***** mem.c +uint64_t +readmemql(uint32_t seg, uint32_t addr) +{ +***** MEM_NEW.C +uint64_t +readmemql(uint32_t addr) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 7) { + sub_cycles(timing_misaligned); + if ((addr2 & 0xfff) > 0xff8) { + if (cr0 >> 31) { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff; + } + return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32); + } else if (readlookup2[addr2 >> 12] != (uintptr_t) -1) + return *(uint64_t *)(readlookup2[addr2 >> 12] + addr2); + } +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 7) { + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFF8) { + if (cr0>>31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffffffff; + if (mmutranslate_read(addr+7) == 0xffffffff) + return 0xffffffff; + } + return readmemll(addr)|((uint64_t)readmemll(addr+4)<<32); + } else if (readlookup2[addr >> 12] != -1) + return *(uint64_t *)(readlookup2[addr >> 12] + addr); + } +***** + +***** mem.c + + if (cr0 >> 31) { + addr2 = mmutranslate_read(addr2); + if (addr2 == 0xffffffff) + return -1; + } +***** MEM_NEW.C + + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) + return 0xFFFFFFFF; + } +***** + +***** mem.c + + addr2 &= rammask; + + map = read_mapping[addr2 >> MEM_GRANULARITY_BITS]; + if (map && map->read_l) + return map->read_l(addr2, map->p) | ((uint64_t)map->read_l(addr2 + 4, map->p) << 32); + + return readmemll(seg,addr) | ((uint64_t)readmemll(seg,addr+4)<<32); +} +***** MEM_NEW.C + + addr&=rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map && map->read_l) + return map->read_l(addr, map->p) | ((uint64_t)map->read_l(addr + 4, map->p) << 32); + + return readmemll(addr) | ((uint64_t)readmemll(addr+4)<<32); +} +***** + +***** mem.c +void +writememql(uint32_t seg, uint32_t addr, uint64_t val) +{ +***** MEM_NEW.C +void +writememql(uint32_t addr, uint64_t val) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 7) { + sub_cycles(timing_misaligned); + if ((addr2 & 0xfff) > 0xff8) { + if (cr0 >> 31) { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+7) == 0xffffffff) return; + } + writememll(seg, addr, val); + writememll(seg, addr+4, val >> 32); + return; + } else if (writelookup2[addr2 >> 12] != (uintptr_t) -1) { + *(uint64_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 7) { + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFF8) { + if (cr0>>31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+7) == 0xffffffff) + return; + } + writememll(addr, val); + writememll(addr+4, val >> 32); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint64_t *)(writelookup2[addr >> 12] + addr) = val; + return; +***** + +***** mem.c + } + + if (page_lookup[addr2>>12]) { + page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); + page_lookup[addr2>>12]->write_l(addr2 + 4, val >> 32, page_lookup[addr2>>12]); + return; +***** MEM_NEW.C + } + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); + page_lookup[addr>>12]->write_l(addr + 4, val >> 32, page_lookup[addr>>12]); + return; +***** + +***** mem.c + } + + if (cr0 >> 31) { + addr2 = mmutranslate_write(addr2); + if (addr2 == 0xffffffff) return; + } +***** MEM_NEW.C + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } +***** + +***** mem.c + + addr2 &= rammask; + + map = write_mapping[addr2 >> MEM_GRANULARITY_BITS]; + + if (map && map->write_l) { + map->write_l(addr2, val, map->p); + map->write_l(addr2+4, val >> 32, map->p); + return; + } + if (map && map->write_w) { + map->write_w(addr2, val, map->p); + map->write_w(addr2 + 2, val >> 16, map->p); + map->write_w(addr2 + 4, val >> 32, map->p); + map->write_w(addr2 + 6, val >> 48, map->p); + return; + } + if (map && map->write_b) { + map->write_b(addr2, val, map->p); + map->write_b(addr2 + 1, val >> 8, map->p); + map->write_b(addr2 + 2, val >> 16, map->p); + map->write_b(addr2 + 3, val >> 24, map->p); + map->write_b(addr2 + 4, val >> 32, map->p); + map->write_b(addr2 + 5, val >> 40, map->p); + map->write_b(addr2 + 6, val >> 48, map->p); + map->write_b(addr2 + 7, val >> 56, map->p); + return; + } +***** MEM_NEW.C + + addr&=rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_l) { + map->write_l(addr, val, map->p); + map->write_l(addr + 4, val >> 32, map->p); + } else if (map->write_w) { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + map->write_w(addr + 4, val >> 32, map->p); + map->write_w(addr + 6, val >> 48, map->p); + } else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + map->write_b(addr + 4, val >> 32, map->p); + map->write_b(addr + 5, val >> 40, map->p); + map->write_b(addr + 6, val >> 48, map->p); + map->write_b(addr + 7, val >> 56, map->p); + } + } +***** + +***** mem.c + +void +***** MEM_NEW.C + + +void +***** + +***** mem.c + +void +mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) +{ +#ifdef USE_DYNAREC + if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != p->mem[addr & 0xfff]) { +#endif + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + p->mem[addr & 0xfff] = val; + } +} +***** MEM_NEW.C + +static inline int +page_index(page_t *p) +{ + return ((uintptr_t)p - (uintptr_t)pages) / sizeof(page_t); +} +***** + +***** mem.c +void +mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) +{ +#ifdef USE_DYNAREC + if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != *(uint16_t *)&p->mem[addr & 0xfff]) { +#endif + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + if ((addr & 0xf) == 0xf) + mask |= (mask << 1); + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + *(uint16_t *)&p->mem[addr & 0xfff] = val; + } +} +***** MEM_NEW.C +void +page_add_to_evict_list(page_t *p) +{ + pages[purgable_page_list_head].evict_prev = page_index(p); + p->evict_next = purgable_page_list_head; + p->evict_prev = 0; + purgable_page_list_head = pages[purgable_page_list_head].evict_prev; + purgeable_page_count++; +} +***** + +***** mem.c +void +mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) +{ +#ifdef USE_DYNAREC + if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != *(uint32_t *)&p->mem[addr & 0xfff]) { +#endif + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + if ((addr & 0xf) >= 0xd) + mask |= (mask << 1); + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + *(uint32_t *)&p->mem[addr & 0xfff] = val; + } +} +***** MEM_NEW.C +void +page_remove_from_evict_list(page_t *p) +{ + if (!page_in_evict_list(p)) + fatal("page_remove_from_evict_list: not in evict list!\n"); + if (p->evict_prev) + pages[p->evict_prev].evict_next = p->evict_next; + else + purgable_page_list_head = p->evict_next; + if (p->evict_next) + pages[p->evict_next].evict_prev = p->evict_prev; + p->evict_prev = EVICT_NOT_IN_LIST; + purgeable_page_count--; +} +***** + +***** mem.c +void +mem_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[addr >> 12]); +} +***** MEM_NEW.C +void +mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) +{ + if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + + p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + p->byte_dirty_mask[byte_offset] |= byte_mask; + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +} +***** + +***** mem.c +void +mem_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[addr >> 12]); +} +***** MEM_NEW.C +void +mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) +{ + if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + + if ((addr & 0xf) == 0xf) + mask |= (mask << 1); + *(uint16_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + if ((addr & PAGE_BYTE_MASK_MASK) == PAGE_BYTE_MASK_MASK) { + p->byte_dirty_mask[byte_offset+1] |= 1; + if ((p->byte_code_present_mask[byte_offset+1] & 1) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } else + byte_mask |= (byte_mask << 1); + + p->byte_dirty_mask[byte_offset] |= byte_mask; + + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +} +***** + +***** mem.c +void +mem_write_raml(uint32_t addr, uint32_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[addr >> 12]); +} +***** MEM_NEW.C +void +mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) +{ + if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)0xf << (addr & PAGE_BYTE_MASK_MASK); + + if ((addr & 0xf) >= 0xd) + mask |= (mask << 1); + *(uint32_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + p->byte_dirty_mask[byte_offset] |= byte_mask; + if (!page_in_evict_list(p) && ((p->code_present_mask & mask) || (p->byte_code_present_mask[byte_offset] & byte_mask))) + page_add_to_evict_list(p); + if ((addr & PAGE_BYTE_MASK_MASK) > (PAGE_BYTE_MASK_MASK-3)) { + uint32_t byte_mask_2 = 0xf >> (4 - (addr & 3)); + + p->byte_dirty_mask[byte_offset+1] |= byte_mask_2; + if ((p->byte_code_present_mask[byte_offset+1] & byte_mask_2) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } + } +} +***** + +***** mem.c + +static uint8_t +mem_read_remapped(uint32_t addr, void *priv) +{ + if(addr >= (mem_size * 1024) && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return ram[addr]; +} +***** MEM_NEW.C + +void +mem_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[addr >> 12]); +} +***** + +***** mem.c + +static uint16_t +mem_read_remappedw(uint32_t addr, void *priv) +{ + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return *(uint16_t *)&ram[addr]; +} +***** MEM_NEW.C + +void +mem_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[addr >> 12]); +} +***** + +***** mem.c + +static uint32_t +mem_read_remappedl(uint32_t addr, void *priv) +{ + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return *(uint32_t *)&ram[addr]; +} +***** MEM_NEW.C + +void +mem_write_raml(uint32_t addr, uint32_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[addr >> 12]); +} +***** + +***** mem.c + +static void +mem_write_remapped(uint32_t addr, uint8_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); +} +***** MEM_NEW.C + +static uint8_t +mem_read_remapped(uint32_t addr, void *priv) +{ + if(addr >= (mem_size * 1024) && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return ram[addr]; +} +***** + +***** mem.c + +static void +mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) +***** MEM_NEW.C + +static uint16_t +mem_read_remappedw(uint32_t addr, void *priv) +{ + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) +***** + +***** mem.c + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); +} +***** MEM_NEW.C + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return *(uint16_t *)&ram[addr]; +} +***** + +***** mem.c + +static void +mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) +***** MEM_NEW.C + +static uint32_t +mem_read_remappedl(uint32_t addr, void *priv) +{ + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) +***** + +***** mem.c + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); +} +***** MEM_NEW.C + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return *(uint32_t *)&ram[addr]; +} +***** + +***** mem.c + +uint8_t +mem_read_bios(uint32_t addr, void *priv) +{ + uint8_t ret = 0xff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = rom[addr - biosaddr]; + + return ret; +} +***** MEM_NEW.C + +static void +mem_write_remapped(uint32_t addr, uint8_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); +} +***** + +***** mem.c + +uint16_t +mem_read_biosw(uint32_t addr, void *priv) +{ + uint16_t ret = 0xffff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = *(uint16_t *)&rom[addr - biosaddr]; + + return ret; +} +***** MEM_NEW.C + +static void +mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); +} +***** + +***** mem.c + +uint32_t +mem_read_biosl(uint32_t addr, void *priv) +{ + uint32_t ret = 0xffffffff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = *(uint32_t *)&rom[addr - biosaddr]; + + return ret; +} +***** MEM_NEW.C + +static void +mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); +} +***** + +***** mem.c + +void +mem_write_null(uint32_t addr, uint8_t val, void *p) +{ +} +***** MEM_NEW.C + +uint8_t +mem_read_bios(uint32_t addr, void *priv) +{ + uint8_t ret = 0xff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = rom[addr - biosaddr]; + + return ret; +} +***** + +***** mem.c + +void +mem_write_nullw(uint32_t addr, uint16_t val, void *p) +{ +} +***** MEM_NEW.C + +uint16_t +mem_read_biosw(uint32_t addr, void *priv) +{ + uint16_t ret = 0xffff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = *(uint16_t *)&rom[addr - biosaddr]; + + return ret; +} +***** + +***** mem.c + +void +mem_write_nulll(uint32_t addr, uint32_t val, void *p) +{ +} +***** MEM_NEW.C + +uint32_t +mem_read_biosl(uint32_t addr, void *priv) +{ + uint32_t ret = 0xffffffff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = *(uint32_t *)&rom[addr - biosaddr]; + + return ret; +} +***** + +***** mem.c +void +mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) +{ + uint32_t cur_addr; + start_addr &= ~PAGE_MASK_MASK; + end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; + + for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { + uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + /* Do nothing if the pages array is empty or DMA reads/writes to/from PCI device memory addresses + may crash the emulator. */ + cur_addr = (start_addr >> 12); + if (cur_addr < pages_sz) + pages[cur_addr].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + } +} +***** MEM_NEW.C +void +mem_write_null(uint32_t addr, uint8_t val, void *p) +{ +} +***** + +***** mem.c + +static __inline int +mem_mapping_read_allowed(uint32_t flags, int state) +{ + switch (state & MEM_READ_MASK) { + case MEM_READ_DISABLED: + return 0; + + case MEM_READ_ANY: + return 1; + + /* On external and 0 mappings without ROMCS. */ + case MEM_READ_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + + /* On external and 0 mappings with ROMCS. */ + case MEM_READ_ROMCS: + return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + + /* On any external mappings. */ + case MEM_READ_EXTANY: + return !(flags & MEM_MAPPING_INTERNAL); + + case MEM_READ_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + + default: + fatal("mem_mapping_read_allowed : bad state %x\n", state); + } + + return 0; +} +***** MEM_NEW.C + +void +mem_write_nullw(uint32_t addr, uint16_t val, void *p) +{ +} +***** + +***** mem.c + +static __inline int +mem_mapping_write_allowed(uint32_t flags, int state) +{ + switch (state & MEM_WRITE_MASK) { + case MEM_WRITE_DISABLED: + return 0; + + case MEM_WRITE_ANY: + return 1; + + /* On external and 0 mappings without ROMCS. */ + case MEM_WRITE_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + + /* On external and 0 mappings with ROMCS. */ + case MEM_WRITE_ROMCS: + return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + + /* On any external mappings. */ + case MEM_WRITE_EXTANY: + return !(flags & MEM_MAPPING_INTERNAL); + + case MEM_WRITE_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + + default: + fatal("mem_mapping_write_allowed : bad state %x\n", state); + } + + return 0; +} +***** MEM_NEW.C + +void +mem_write_nulll(uint32_t addr, uint32_t val, void *p) +{ +} +***** + +***** mem.c + +static void +mem_mapping_recalc(uint64_t base, uint64_t size) +{ + mem_mapping_t *map = base_mapping.next; + uint64_t c; + + if (! size) return; + + /* Clear out old mappings. */ + for (c = base; c < base + size; c += MEM_GRANULARITY_SIZE) { + read_mapping[c >> MEM_GRANULARITY_BITS] = NULL; + write_mapping[c >> MEM_GRANULARITY_BITS] = NULL; + _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; + } + + /* Walk mapping list. */ + while (map != NULL) { + /*In range?*/ + if (map->enable && (uint64_t)map->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)map->base + (uint64_t)map->siz +e) > (uint64_t)base) { + uint64_t start = (map->base < base) ? map->base : base; + uint64_t end = (((uint64_t)map->base + (uint64_t)map->size) < (base + size)) ? ((uint64_t)map->base + (uint64 +_t)map->size) : (base + size); + if (start < map->base) + start = map->base; + + for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) { + if (map->exec) + _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); + else + _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; + read_mapping[c >> MEM_GRANULARITY_BITS] = map; + } + if ((map->write_b || map->write_w || map->write_l) && + mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) + write_mapping[c >> MEM_GRANULARITY_BITS] = map; + } + } + map = map->next; + } + + flushmmucache_cr3(); +} +***** MEM_NEW.C + +void +mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) +{ + uint64_t mask; + page_t *p; + + start_addr &= ~PAGE_MASK_MASK; + end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; + + for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { + if ((start_addr >> 12) >= pages_sz) + continue; + + mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + p = &pages[start_addr >> 12]; + + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +} +***** + +***** mem.c + +void +mem_mapping_del(mem_mapping_t *map) +{ + mem_mapping_t *ptr; + + /* Disable the entry. */ + mem_mapping_disable(map); + + /* Zap it from the list. */ + for (ptr = &base_mapping; ptr->next != NULL; ptr = ptr->next) { + if (ptr->next == map) { + ptr->next = map->next; + break; + } + } +} +***** MEM_NEW.C + +static __inline int +mem_mapping_read_allowed(uint32_t flags, int state) +{ + switch (state & MEM_READ_MASK) { + case MEM_READ_DISABLED: + return 0; + + case MEM_READ_ANY: + return 1; + + /* On external and 0 mappings without ROMCS. */ + case MEM_READ_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + + /* On external and 0 mappings with ROMCS. */ + case MEM_READ_ROMCS: + return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + + /* On any external mappings. */ + case MEM_READ_EXTANY: + return !(flags & MEM_MAPPING_INTERNAL); + + case MEM_READ_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + + default: + fatal("mem_mapping_read_allowed : bad state %x\n", state); + } + + return 0; +} +***** + +***** mem.c + +void +mem_mapping_add(mem_mapping_t *map, + uint32_t base, + uint32_t size, + uint8_t (*read_b)(uint32_t addr, void *p), + uint16_t (*read_w)(uint32_t addr, void *p), + uint32_t (*read_l)(uint32_t addr, void *p), + void (*write_b)(uint32_t addr, uint8_t val, void *p), + void (*write_w)(uint32_t addr, uint16_t val, void *p), + void (*write_l)(uint32_t addr, uint32_t val, void *p), + uint8_t *exec, + uint32_t fl, + void *p) +{ + mem_mapping_t *dest = &base_mapping; + + /* Add mapping to the end of the list.*/ + while (dest->next) + dest = dest->next; + dest->next = map; + map->prev = dest; + + if (size) + map->enable = 1; + else + map->enable = 0; + map->base = base; + map->size = size; + map->read_b = read_b; + map->read_w = read_w; + map->read_l = read_l; + map->write_b = write_b; + map->write_w = write_w; + map->write_l = write_l; + map->exec = exec; + map->flags = fl; + map->p = p; + map->dev = NULL; + map->next = NULL; + + mem_mapping_recalc(map->base, map->size); +} +***** MEM_NEW.C + +static __inline int +mem_mapping_write_allowed(uint32_t flags, int state) +{ + switch (state & MEM_WRITE_MASK) { + case MEM_WRITE_DISABLED: + return 0; + + case MEM_WRITE_ANY: + return 1; + + /* On external and 0 mappings without ROMCS. */ + case MEM_WRITE_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + + /* On external and 0 mappings with ROMCS. */ + case MEM_WRITE_ROMCS: + return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + + /* On any external mappings. */ + case MEM_WRITE_EXTANY: + return !(flags & MEM_MAPPING_INTERNAL); + + case MEM_WRITE_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + + default: + fatal("mem_mapping_write_allowed : bad state %x\n", state); + } + + return 0; +} +***** + +***** mem.c + +void +mem_mapping_set_handler(mem_mapping_t *map, + uint8_t (*read_b)(uint32_t addr, void *p), + uint16_t (*read_w)(uint32_t addr, void *p), + uint32_t (*read_l)(uint32_t addr, void *p), + void (*write_b)(uint32_t addr, uint8_t val, void *p), + void (*write_w)(uint32_t addr, uint16_t val, void *p), + void (*write_l)(uint32_t addr, uint32_t val, void *p)) +{ + map->read_b = read_b; + map->read_w = read_w; + map->read_l = read_l; + map->write_b = write_b; + map->write_w = write_w; + map->write_l = write_l; + + mem_mapping_recalc(map->base, map->size); +} +***** MEM_NEW.C + +static void +mem_mapping_recalc(uint64_t base, uint64_t size) +{ + mem_mapping_t *map = base_mapping.next; + uint64_t c; + + if (! size) return; + + /* Clear out old mappings. */ + for (c = base; c < base + size; c += MEM_GRANULARITY_SIZE) { + read_mapping[c >> MEM_GRANULARITY_BITS] = NULL; + write_mapping[c >> MEM_GRANULARITY_BITS] = NULL; + _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; + } + + /* Walk mapping list. */ + while (map != NULL) { + /*In range?*/ + if (map->enable && (uint64_t)map->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)map->base + (uint64_t)map->siz +e) > (uint64_t)base) { + uint64_t start = (map->base < base) ? map->base : base; + uint64_t end = (((uint64_t)map->base + (uint64_t)map->size) < (base + size)) ? ((uint64_t)map->base + (uint64 +_t)map->size) : (base + size); + if (start < map->base) + start = map->base; + + for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) { + read_mapping[c >> MEM_GRANULARITY_BITS] = map; + if (map->exec) + _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); + else + _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; + } + if ((map->write_b || map->write_w || map->write_l) && + mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) + write_mapping[c >> MEM_GRANULARITY_BITS] = map; + } + } + map = map->next; + } + + flushmmucache_cr3(); +} +***** + +***** mem.c +void +mem_mapping_set_addr(mem_mapping_t *map, uint32_t base, uint32_t size) +{ + /* Remove old mapping. */ + map->enable = 0; + mem_mapping_recalc(map->base, map->size); + + /* Set new mapping. */ + map->enable = 1; + map->base = base; + map->size = size; + + mem_mapping_recalc(map->base, map->size); +} +***** MEM_NEW.C +void +mem_mapping_del(mem_mapping_t *map) +{ + mem_mapping_t *ptr; + + /* Disable the entry. */ + mem_mapping_disable(map); + + /* Zap it from the list. */ + for (ptr = &base_mapping; ptr->next != NULL; ptr = ptr->next) { + if (ptr->next == map) { + ptr->next = map->next; + break; + } + } +} +***** + +***** mem.c +void +mem_mapping_set_exec(mem_mapping_t *map, uint8_t *exec) +{ + map->exec = exec; + +***** MEM_NEW.C +void +mem_mapping_add(mem_mapping_t *map, + uint32_t base, + uint32_t size, + uint8_t (*read_b)(uint32_t addr, void *p), + uint16_t (*read_w)(uint32_t addr, void *p), + uint32_t (*read_l)(uint32_t addr, void *p), + void (*write_b)(uint32_t addr, uint8_t val, void *p), + void (*write_w)(uint32_t addr, uint16_t val, void *p), + void (*write_l)(uint32_t addr, uint32_t val, void *p), + uint8_t *exec, + uint32_t fl, + void *p) +{ + mem_mapping_t *dest = &base_mapping; + + /* Add mapping to the end of the list.*/ + while (dest->next) + dest = dest->next; + dest->next = map; + map->prev = dest; + + if (size) + map->enable = 1; + else + map->enable = 0; + map->base = base; + map->size = size; + map->read_b = read_b; + map->read_w = read_w; + map->read_l = read_l; + map->write_b = write_b; + map->write_w = write_w; + map->write_l = write_l; + map->exec = exec; + map->flags = fl; + map->p = p; + map->dev = NULL; + map->next = NULL; + +***** + +***** mem.c +void +mem_mapping_set_p(mem_mapping_t *map, void *p) +{ + map->p = p; +} +***** MEM_NEW.C +void +mem_mapping_set_handler(mem_mapping_t *map, + uint8_t (*read_b)(uint32_t addr, void *p), + uint16_t (*read_w)(uint32_t addr, void *p), + uint32_t (*read_l)(uint32_t addr, void *p), + void (*write_b)(uint32_t addr, uint8_t val, void *p), + void (*write_w)(uint32_t addr, uint16_t val, void *p), + void (*write_l)(uint32_t addr, uint32_t val, void *p)) +{ + map->read_b = read_b; + map->read_w = read_w; + map->read_l = read_l; + map->write_b = write_b; + map->write_w = write_w; + map->write_l = write_l; + + mem_mapping_recalc(map->base, map->size); +} +***** + +***** mem.c +void +mem_mapping_set_dev(mem_mapping_t *map, void *p) +{ + map->dev = p; +} + + +void +mem_mapping_disable(mem_mapping_t *map) +{ + map->enable = 0; + +***** MEM_NEW.C +void +mem_mapping_set_addr(mem_mapping_t *map, uint32_t base, uint32_t size) +{ + /* Remove old mapping. */ + map->enable = 0; + mem_mapping_recalc(map->base, map->size); + + /* Set new mapping. */ + map->enable = 1; + map->base = base; + map->size = size; + +***** + +***** mem.c +void +mem_mapping_enable(mem_mapping_t *map) +{ + map->enable = 1; + +***** MEM_NEW.C +void +mem_mapping_set_exec(mem_mapping_t *map, uint8_t *exec) +{ + map->exec = exec; + +***** + +***** mem.c +void +mem_set_mem_state(uint32_t base, uint32_t size, int state) +{ + uint32_t c; + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { + _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state[(c + base) >> MEM_GRANULARITY_BITS]; + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = state; + } + + mem_mapping_recalc(base, size); +} +***** MEM_NEW.C +void +mem_mapping_set_p(mem_mapping_t *map, void *p) +{ + map->p = p; +} +***** + +***** mem.c +void +mem_restore_mem_state(uint32_t base, uint32_t size) +{ + uint32_t c; + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS]; + + mem_mapping_recalc(base, size); +} +***** MEM_NEW.C +void +mem_mapping_set_dev(mem_mapping_t *map, void *p) +{ + map->dev = p; +} +***** + +***** mem.c +void +mem_add_bios(void) +{ + if (biosmask > 0x1ffff) { + /* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */ + mem_mapping_add(&bios_mapping, 0xe0000, 0x20000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(0x0e0000, 0x20000, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } else { + mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(biosaddr, biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } +***** MEM_NEW.C +void +mem_mapping_disable(mem_mapping_t *map) +{ + map->enable = 0; + + mem_mapping_recalc(map->base, map->size); +} + + +void +mem_mapping_enable(mem_mapping_t *map) +{ + map->enable = 1; + + mem_mapping_recalc(map->base, map->size); +} + + +void +mem_set_mem_state(uint32_t base, uint32_t size, int state) +{ + uint32_t c; + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { + _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state[(c + base) >> MEM_GRANULARITY_BITS]; + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = state; + } +***** + +***** mem.c + + if (AT) { + mem_mapping_add(&bios_high_mapping, biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } +} +***** MEM_NEW.C + + mem_mapping_recalc(base, size); +} +***** + +***** mem.c +void +mem_a20_init(void) +{ + if (AT) { + rammask = cpu_16bitbus ? 0xefffff : 0xffefffff; + flushmmucache(); + mem_a20_state = mem_a20_key | mem_a20_alt; + } else { + rammask = 0xfffff; + flushmmucache(); + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + } +} +***** MEM_NEW.C +void +mem_restore_mem_state(uint32_t base, uint32_t size) +{ + uint32_t c; + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS]; + + mem_mapping_recalc(base, size); +} +***** + +***** mem.c + +/* Reset the memory state. */ +void +mem_reset(void) +{ + uint32_t c, m; + + m = 1024UL * mem_size; + if (ram != NULL) { + free(ram); + ram = NULL; + } + ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ + memset(ram, 0x00, m); + + /* + * Allocate the page table based on how much RAM we have. + * We re-allocate the table on each (hard) reset, as the + * memory amount could have changed. + */ + if (AT) { + if (cpu_16bitbus) { + /* 80186/286; maximum address space is 16MB. */ + m = 4096; + } else { + /* 80386+; maximum address space is 4GB. */ + m = (mem_size + 384) >> 2; + if ((m << 2) < (mem_size + 384)) + m++; + if (m < 4096) + m = 4096; + } + } else { + /* 8088/86; maximum address space is 1MB. */ + m = 256; + } +***** MEM_NEW.C + +void +mem_add_bios(void) +{ + if (biosmask > 0x1ffff) { + /* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */ + mem_mapping_add(&bios_mapping, 0xe0000, 0x20000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(0x0e0000, 0x20000, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } else { + mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(biosaddr, biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } +***** + +***** mem.c + + /* + * Allocate and initialize the (new) page table. + * We only do this if the size of the page table has changed. + */ +#if DYNAMIC_TABLES +mem_log("MEM: reset: previous pages=%08lx, pages_sz=%i\n", pages, pages_sz); +#endif + if (pages_sz != m) { + pages_sz = m; + if (pages) { + free(pages); + pages = NULL; + } + pages = (page_t *)malloc(m*sizeof(page_t)); +#if DYNAMIC_TABLES +mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); +#endif + +#if DYNAMIC_TABLES + /* Allocate the (new) lookup tables. */ + if (page_lookup != NULL) free(page_lookup); + page_lookup = (page_t **)malloc(pages_sz*sizeof(page_t *)); + + if (readlookup2 != NULL) free(readlookup2); + readlookup2 = malloc(pages_sz*sizeof(uintptr_t)); + + if (writelookup2 != NULL) free(writelookup2); + writelookup2 = malloc(pages_sz*sizeof(uintptr_t)); + +#endif + } + +#if DYNAMIC_TABLES + memset(page_lookup, 0x00, pages_sz * sizeof(page_t *)); +#else + memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); +#endif + + memset(pages, 0x00, pages_sz*sizeof(page_t)); + +***** MEM_NEW.C + + if (AT) { + mem_mapping_add(&bios_high_mapping, biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } +} + +***** + +***** mem.c + + for (c = 0; c < pages_sz; c++) { + pages[c].mem = &ram[c << 12]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + } +***** MEM_NEW.C + +void +mem_a20_init(void) +{ + if (AT) { + rammask = cpu_16bitbus ? 0xefffff : 0xffefffff; + flushmmucache(); + mem_a20_state = mem_a20_key | mem_a20_alt; + } else { + rammask = 0xfffff; + flushmmucache(); + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + } +} + + +/* Reset the memory state. */ +void +mem_reset(void) +{ + uint32_t c, m; + + m = 1024UL * mem_size; + if (ram != NULL) { + free(ram); + ram = NULL; + } + ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ + memset(ram, 0x00, m); + + /* + * Allocate the page table based on how much RAM we have. + * We re-allocate the table on each (hard) reset, as the + * memory amount could have changed. + */ + if (AT) { + if (cpu_16bitbus) { + /* 80186/286; maximum address space is 16MB. */ + m = 4096; + } else { + /* 80386+; maximum address space is 4GB. */ + m = (mem_size + 384) >> 2; + if ((m << 2) < (mem_size + 384)) + m++; + if (m < 4096) + m = 4096; + } + } else { + /* 8088/86; maximum address space is 1MB. */ + m = 256; + } +***** + +***** mem.c + + memset(_mem_exec, 0x00, sizeof(_mem_exec)); + + memset(&base_mapping, 0x00, sizeof(base_mapping)); + + memset(_mem_state, 0x00, sizeof(_mem_state)); + memset(_mem_state_bak, 0x00, sizeof(_mem_state_bak)); + + mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(0x0c0000, 0x40000, + MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + mem_mapping_add(&ram_low_mapping, 0x00000, + (mem_size > 640) ? 0xa0000 : mem_size * 1024, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram, MEM_MAPPING_INTERNAL, NULL); + + if (mem_size > 1024) { + if (cpu_16bitbus && mem_size > 16256) { + mem_set_mem_state(0x100000, (16256 - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((16256 - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } else { + mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((mem_size - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } + } +***** MEM_NEW.C + + /* + * Allocate and initialize the (new) page table. + * We only do this if the size of the page table has changed. + */ +#if DYNAMIC_TABLES +mem_log("MEM: reset: previous pages=%08lx, pages_sz=%i\n", pages, pages_sz); +#endif + if (pages_sz != m) { + pages_sz = m; + if (pages) { + free(pages); + pages = NULL; + } + pages = (page_t *)malloc(m*sizeof(page_t)); +#if DYNAMIC_TABLES +mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); +#endif + +#if DYNAMIC_TABLES + /* Allocate the (new) lookup tables. */ + if (page_lookup != NULL) free(page_lookup); + page_lookup = (page_t **)malloc(pages_sz*sizeof(page_t *)); + + if (readlookup2 != NULL) free(readlookup2); + readlookup2 = malloc(pages_sz*sizeof(uintptr_t)); + + if (writelookup2 != NULL) free(writelookup2); + writelookup2 = malloc(pages_sz*sizeof(uintptr_t)); + +#endif + } +***** + +***** mem.c + + if (mem_size > 768) + mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); + + mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, + mem_read_remapped,mem_read_remappedw,mem_read_remappedl, + mem_write_remapped,mem_write_remappedw,mem_write_remappedl, + ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_disable(&ram_remapped_mapping); + + mem_a20_init(); +} + +***** MEM_NEW.C + +#if DYNAMIC_TABLES + memset(page_lookup, 0x00, pages_sz * sizeof(page_t *)); +#else + memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); +#endif + + memset(pages, 0x00, pages_sz*sizeof(page_t)); + +***** + +***** mem.c + +void +mem_init(void) +{ + /* Perform a one-time init. */ + ram = rom = NULL; + pages = NULL; +#if DYNAMIC_TABLES + page_lookup = NULL; + readlookup2 = NULL; + writelookup2 = NULL; + +#else + /* Allocate the lookup tables. */ + page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *)); + + readlookup2 = malloc((1<<20)*sizeof(uintptr_t)); + + writelookup2 = malloc((1<<20)*sizeof(uintptr_t)); +#endif + +#if FIXME + memset(ff_array, 0xff, sizeof(ff_array)); +#endif + + /* Reset the memory state. */ + mem_reset(); +} + + +void +mem_remap_top(int kb) +{ + int c; + uint32_t start = (mem_size >= 1024) ? mem_size : 1024; + int size = mem_size - 640; + + mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); + if (mem_size <= 640) return; + + if (kb == 0) { + /* Called to disable the mapping. */ + mem_mapping_disable(&ram_remapped_mapping); + + return; + } + + if (size > kb) + size = kb; + + for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { + pages[c].mem = &ram[0xA0000 + ((c - ((start * 1024) >> 12)) << 12)]; + pages[c].write_b = mem_write_ramb_page; +***** MEM_NEW.C + + if (byte_dirty_mask) { + free(byte_dirty_mask); + byte_dirty_mask = NULL; + } + byte_dirty_mask = malloc((mem_size * 1024) / 8); + memset(byte_dirty_mask, 0, (mem_size * 1024) / 8); + + if (byte_code_present_mask) { + free(byte_code_present_mask); + byte_code_present_mask = NULL; + } + byte_code_present_mask = malloc((mem_size * 1024) / 8); + memset(byte_code_present_mask, 0, (mem_size * 1024) / 8); + + for (c = 0; c < pages_sz; c++) { + pages[c].mem = &ram[c << 12]; + pages[c].write_b = mem_write_ramb_page; +***** + +***** mem.c + pages[c].write_l = mem_write_raml_page; + } +***** MEM_NEW.C + pages[c].write_l = mem_write_raml_page; + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; + } +***** + +***** mem.c + + mem_set_mem_state(start * 1024, size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); + mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024)); + + flushmmucache(); +} + +void +mem_reset_page_blocks(void) +{ + uint32_t c; + + if (pages == NULL) return; + + for (c = 0; c < pages_sz; c++) { + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = NULL; + pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = NULL; + } +} + + +void +mem_a20_recalc(void) +{ + int state; + + if (! AT) { + rammask = 0xfffff; + flushmmucache(); + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + + return; + } +***** MEM_NEW.C + + memset(_mem_exec, 0x00, sizeof(_mem_exec)); + + memset(&base_mapping, 0x00, sizeof(base_mapping)); + + memset(_mem_state, 0x00, sizeof(_mem_state)); + memset(_mem_state_bak, 0x00, sizeof(_mem_state)); + + mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(0x0c0000, 0x40000, + MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + mem_mapping_add(&ram_low_mapping, 0x00000, + (mem_size > 640) ? 0xa0000 : mem_size * 1024, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram, MEM_MAPPING_INTERNAL, NULL); + + if (mem_size > 1024) { + if (cpu_16bitbus && mem_size > 16256) { + mem_set_mem_state(0x100000, (16256 - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((16256 - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } else { + mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((mem_size - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } + } +***** + +***** mem.c + + state = mem_a20_key | mem_a20_alt; + if (state && !mem_a20_state) { + rammask = (AT && cpu_16bitbus) ? 0xffffff : 0xffffffff; + flushmmucache(); + } else if (!state && mem_a20_state) { + rammask = (AT && cpu_16bitbus) ? 0xefffff : 0xffefffff; + flushmmucache(); + } + + mem_a20_state = state; +} +***** MEM_NEW.C + + if (mem_size > 768) + mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); + + mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, + mem_read_remapped,mem_read_remappedw,mem_read_remappedl, + mem_write_remapped,mem_write_remappedw,mem_write_remappedl, + ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_disable(&ram_remapped_mapping); + + mem_a20_init(); + + purgable_page_list_head = 0; + purgeable_page_count = 0; +} +***** + +Resync Failed. Files are too different. +***** mem.c +***** MEM_NEW.C + + +void +mem_init(void) +{ + /* Perform a one-time init. */ + ram = rom = NULL; + pages = NULL; +#if DYNAMIC_TABLES + page_lookup = NULL; + readlookup2 = NULL; + writelookup2 = NULL; + +#else + /* Allocate the lookup tables. */ + page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *)); + + readlookup2 = malloc((1<<20)*sizeof(uintptr_t)); + + writelookup2 = malloc((1<<20)*sizeof(uintptr_t)); +#endif + +#if FIXME + memset(ff_array, 0xff, sizeof(ff_array)); +#endif + + /* Reset the memory state. */ + mem_reset(); +} + + +void +mem_remap_top(int kb) +{ + int c; + uint32_t start = (mem_size >= 1024) ? mem_size : 1024; + int offset, size = mem_size - 640; + + mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); + if (mem_size <= 640) return; + + if (kb == 0) { + /* Called to disable the mapping. */ + mem_mapping_disable(&ram_remapped_mapping); + + return; + } + + if (size > kb) + size = kb; + + for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { + offset = c - ((start * 1024) >> 12); + pages[c].mem = &ram[0xA0000 + (offset << 12)]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64]; + } + + mem_set_mem_state(start * 1024, size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); + mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024)); + + flushmmucache(); +} + +void +mem_reset_page_blocks(void) +{ + uint32_t c; + + if (pages == NULL) return; + + for (c = 0; c < pages_sz; c++) { + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + pages[c].block = BLOCK_INVALID; + pages[c].block_2 = BLOCK_INVALID; + } +} + + +void +mem_a20_recalc(void) +{ + int state; + + if (! AT) { + rammask = 0xfffff; + flushmmucache(); + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + + return; + } + +***** + diff --git a/src/mem_new.c b/src/mem_new.c deleted file mode 100644 index 84f3aa597..000000000 --- a/src/mem_new.c +++ /dev/null @@ -1,1805 +0,0 @@ -/* - * 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. - * - * Memory handling and MMU. - * - * NOTE: Experimenting with dynamically allocated lookup tables; - * the DYNAMIC_TABLES=1 enables this. Will eventually go - * away, either way... - * - * Version: @(#)mem.c 1.0.22 2019/12/02 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "cpu_new/cpu.h" -#include "cpu_new/x86_ops.h" -#include "cpu_new/x86.h" -#include "machine/machine.h" -#include "machine/m_xt_xi8088.h" -#include "config.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#ifdef USE_DYNAREC -# include "cpu_new/codegen.h" -#else -# define PAGE_MASK_INDEX_MASK 3 -# define PAGE_MASK_INDEX_SHIFT 10 -# define PAGE_MASK_MASK 63 -# define PAGE_MASK_SHIFT 4 -#endif - - -#define FIXME 0 -#define DYNAMIC_TABLES 0 /* experimental */ - - -mem_mapping_t base_mapping, - ram_low_mapping, /* 0..640K mapping */ -#if 1 - ram_mid_mapping, -#endif - ram_remapped_mapping, /* 640..1024K mapping */ - ram_high_mapping, /* 1024K+ mapping */ - ram_remapped_mapping, - ram_split_mapping, - bios_mapping, - bios_high_mapping; - -page_t *pages, /* RAM page table */ - **page_lookup; /* pagetable lookup */ -uint32_t pages_sz; /* #pages in table */ - -uint8_t *ram; /* the virtual RAM */ -uint32_t rammask; - -uint8_t *rom; /* the virtual ROM */ -uint32_t biosmask, biosaddr; - -uint32_t pccache; -uint8_t *pccache2; - -int readlnext; -int readlookup[256], - readlookupp[256]; -uintptr_t *readlookup2; -int writelnext; -int writelookup[256], - writelookupp[256]; -uintptr_t *writelookup2; - -uint32_t mem_logical_addr; - -int shadowbios = 0, - shadowbios_write; -int readlnum = 0, - writelnum = 0; -int cachesize = 256; - -uint32_t get_phys_virt, - get_phys_phys; - -int mem_a20_key = 0, - mem_a20_alt = 0, - mem_a20_state = 0; - -int mmuflush = 0; -int mmu_perm = 4; - -uint64_t *byte_dirty_mask; -uint64_t *byte_code_present_mask; - -uint32_t purgable_page_list_head = 0; -int purgeable_page_count = 0; - - -/* FIXME: re-do this with a 'mem_ops' struct. */ -static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; -static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; -static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; -static int _mem_state[MEM_MAPPINGS_NO]; - -#if FIXME -#if (MEM_GRANULARITY_BITS >= 12) -static uint8_t ff_array[MEM_GRANULARITY_SIZE]; -#else -static uint8_t ff_array[4096]; /* Must be at least one page. */ -#endif -#else -static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; -#endif - - -#ifdef ENABLE_MEM_LOG -int mem_do_log = ENABLE_MEM_LOG; - - -static void -mem_log(const char *fmt, ...) -{ - va_list ap; - - if (mem_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define mem_log(fmt, ...) -#endif - - -int -mem_addr_is_ram(uint32_t addr) -{ - mem_mapping_t *mapping = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - return (mapping == &ram_low_mapping) || (mapping == &ram_high_mapping) || (mapping == &ram_mid_mapping) || (mapping == &ram_remapped_mapping); -} - - -void -resetreadlookup(void) -{ - int c; - - /* This is NULL after app startup, when mem_init() has not yet run. */ -#if DYNAMIC_TABLES -mem_log("MEM: reset_lookup: pages=%08lx, lookup=%08lx, pages_sz=%i\n", pages, page_lookup, pages_sz); -#endif - - /* Initialize the page lookup table. */ -#if DYNAMIC_TABLES - memset(page_lookup, 0x00, pages_sz*sizeof(page_t *)); -#else - memset(page_lookup, 0x00, (1<<20)*sizeof(page_t *)); -#endif - - /* Initialize the tables for lower (<= 1024K) RAM. */ - for (c = 0; c < 256; c++) { - readlookup[c] = 0xffffffff; - writelookup[c] = 0xffffffff; - } - - /* Initialize the tables for high (> 1024K) RAM. */ -#if DYNAMIC_TABLES - memset(readlookup2, 0xff, pages_sz*sizeof(uintptr_t)); - memset(writelookup2, 0xff, pages_sz*sizeof(uintptr_t)); -#else - memset(readlookup2, 0xff, (1<<20)*sizeof(uintptr_t)); - memset(writelookup2, 0xff, (1<<20)*sizeof(uintptr_t)); -#endif - - readlnext = 0; - writelnext = 0; - pccache = 0xffffffff; -} - - -void -flushmmucache(void) -{ - int c; - - for (c = 0; c < 256; c++) { - if (readlookup[c] != (int) 0xffffffff) { - readlookup2[readlookup[c]] = -1; - readlookup[c] = 0xffffffff; - } - if (writelookup[c] != (int) 0xffffffff) { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xffffffff; - } - } - mmuflush++; - - pccache = (uint32_t)0xffffffff; - pccache2 = (uint8_t *)0xffffffff; - -#ifdef USE_DYNAREC - codegen_flush(); -#endif -} - - -void -flushmmucache_nopc(void) -{ - int c; - - for (c = 0; c < 256; c++) { - if (readlookup[c] != (int) 0xffffffff) { - readlookup2[readlookup[c]] = -1; - readlookup[c] = 0xffffffff; - } - if (writelookup[c] != (int) 0xffffffff) { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xffffffff; - } - } -} - - -void -flushmmucache_cr3(void) -{ - int c; - - for (c = 0; c < 256; c++) { - if (readlookup[c] != (int) 0xffffffff) { - readlookup2[readlookup[c]] = -1; - readlookup[c] = 0xffffffff; - } - if (writelookup[c] != (int) 0xffffffff) { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xffffffff; - } - } -} - - -void -mem_flush_write_page(uint32_t addr, uint32_t virt) -{ - page_t *page_target = &pages[addr >> 12]; - int c; - - for (c = 0; c < 256; c++) { - if (writelookup[c] != (int) 0xffffffff) { - uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)]; - - if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) { - writelookup2[writelookup[c]] = -1; - page_lookup[writelookup[c]] = NULL; - writelookup[c] = 0xffffffff; - } - } - } -} - - -#define mmutranslate_read(addr) mmutranslatereal(addr,0) -#define mmutranslate_write(addr) mmutranslatereal(addr,1) -#define rammap(x) ((uint32_t *)(_mem_exec[(x) >> MEM_GRANULARITY_BITS]))[((x) >> 2) & MEM_GRANULARITY_QMASK] - -uint32_t -mmutranslatereal(uint32_t addr, int rw) -{ - uint32_t temp,temp2,temp3; - uint32_t addr2; - - if (cpu_state.abrt) return -1; - - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp = temp2 = rammap(addr2); - if (! (temp&1)) { - cr2 = addr; - temp &= 1; - if (CPL == 3) temp |= 4; - if (rw) temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return -1; - } - - if ((temp & 0x80) && (cr4 & CR4_PSE)) { - /*4MB page*/ - if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3 && !cpl_override) || cr0 & WP_FLAG))) { - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - - return -1; - } - - mmu_perm = temp & 4; - rammap(addr2) |= 0x20; - - return (temp & ~0x3fffff) + (addr & 0x3fffff); - } - - temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); - temp3 = temp & temp2; - if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && ((CPL == 3 && !cpl_override) || cr0&WP_FLAG))) { - cr2 = addr; - temp &= 1; - if (CPL == 3) temp |= 4; - if (rw) temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return -1; - } - - mmu_perm = temp & 4; - rammap(addr2) |= 0x20; - rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw?0x60:0x20); - - return (temp&~0xfff)+(addr&0xfff); -} - - -uint32_t -mmutranslate_noabrt(uint32_t addr, int rw) -{ - uint32_t temp,temp2,temp3; - uint32_t addr2; - - if (cpu_state.abrt) - return -1; - - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp = temp2 = rammap(addr2); - - if (! (temp & 1)) - return -1; - - if ((temp & 0x80) && (cr4 & CR4_PSE)) { - /*4MB page*/ - if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (CPL == 3 || cr0 & WP_FLAG))) - return -1; - - return (temp & ~0x3fffff) + (addr & 0x3fffff); - } - - temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); - temp3 = temp & temp2; - - if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG))) - return -1; - - return (temp & ~0xfff) + (addr & 0xfff); -} - - -void -mmu_invalidate(uint32_t addr) -{ - flushmmucache_cr3(); -} - - -uint8_t -mem_addr_range_match(uint32_t addr, uint32_t start, uint32_t len) -{ - if (addr < start) - return 0; - else if (addr >= (start + len)) - return 0; - else - return 1; -} - - -uint32_t -mem_addr_translate(uint32_t addr, uint32_t chunk_start, uint32_t len) -{ - uint32_t mask = len - 1; - - return chunk_start + (addr & mask); -} - - -void -addreadlookup(uint32_t virt, uint32_t phys) -{ - if (virt == 0xffffffff) return; - - if (readlookup2[virt>>12] != (uintptr_t) -1) return; - - if (readlookup[readlnext] != (int) 0xffffffff) - readlookup2[readlookup[readlnext]] = -1; - - readlookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; - - readlookupp[readlnext] = mmu_perm; - readlookup[readlnext++] = virt >> 12; - readlnext &= (cachesize-1); - - sub_cycles(9); -} - - -void -addwritelookup(uint32_t virt, uint32_t phys) -{ - if (virt == 0xffffffff) return; - - if (page_lookup[virt >> 12]) return; - - if (writelookup[writelnext] != -1) { - page_lookup[writelookup[writelnext]] = NULL; - writelookup2[writelookup[writelnext]] = -1; - } - - if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) - page_lookup[virt >> 12] = &pages[phys >> 12];//(uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; - else - writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; - - writelookupp[writelnext] = mmu_perm; - writelookup[writelnext++] = virt >> 12; - writelnext &= (cachesize - 1); - - sub_cycles(9); -} - - -uint8_t * -getpccache(uint32_t a) -{ - uint32_t a2; - - a2 = a; - - if (cr0 >> 31) { - a = mmutranslate_read(a); - - if (a == 0xffffffff) return ram; - } - a &= rammask; - - if (_mem_exec[a >> MEM_GRANULARITY_BITS]) { - if (is286) { - if (read_mapping[a >> MEM_GRANULARITY_BITS] && (read_mapping[a >> MEM_GRANULARITY_BITS]->flags & MEM_MAPPING_ROM)) - cpu_prefetch_cycles = cpu_rom_prefetch_cycles; - else - cpu_prefetch_cycles = cpu_mem_prefetch_cycles; - } - - return &_mem_exec[a >> MEM_GRANULARITY_BITS][(uintptr_t)(a & MEM_GRANULARITY_PAGE) - (uintptr_t)(a2 & ~0xfff)]; - } - - mem_log("Bad getpccache %08X\n", a); - -#if FIXME - return &ff_array[0-(uintptr_t)(a2 & ~0xfff)]; -#else - return (uint8_t *)&ff_pccache; -#endif -} - - -uint8_t -readmembl(uint32_t addr) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - if (cr0 >> 31) { - addr = mmutranslate_read(addr); - if (addr == 0xFFFFFFFF) return 0xFF; - } - addr &= rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->read_b) - return map->read_b(addr, map->p); - return 0xFF; -} - - -void -writemembl(uint32_t addr, uint8_t val) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (page_lookup[addr>>12]) { - page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); - return; - } - if (cr0 >> 31) { - addr = mmutranslate_write(addr); - if (addr == 0xFFFFFFFF) - return; - } - addr &= rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->write_b) - return map->write_b(addr, val, map->p); -} - - -uint16_t -readmemwl(uint32_t addr) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - sub_cycles(timing_misaligned); - if ((addr & 0xFFF) > 0xFFE) { - if (cr0 >> 31) { - if (mmutranslate_read(addr) == 0xffffffff) - return 0xffff; - if (mmutranslate_read(addr+1) == 0xffffffff) - return 0xffff; - } - return readmembl(addr)|(readmembl(addr+1)<<8); - } else if (readlookup2[addr >> 12] != -1) - return *(uint16_t *)(readlookup2[addr >> 12] + addr); - } - if (cr0>>31) { - addr = mmutranslate_read(addr); - if (addr==0xFFFFFFFF) - return 0xFFFF; - } - - addr &= rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map) { - if (map->read_w) - return map->read_w(addr, map->p); - - if (map->read_b) - return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8); - } - - return 0xffff; -} - - -void -writememwl(uint32_t addr, uint16_t val) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - sub_cycles(timing_misaligned); - if ((addr & 0xFFF) > 0xFFE) { - if (cr0 >> 31) { - if (mmutranslate_write(addr) == 0xffffffff) - return; - if (mmutranslate_write(addr+1) == 0xffffffff) - return; - } - writemembl(addr,val); - writemembl(addr+1,val>>8); - return; - } else if (writelookup2[addr >> 12] != -1) { - *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; - return; - } - } - - if (page_lookup[addr>>12]) { - page_lookup[addr>>12]->write_w(addr, val, page_lookup[addr>>12]); - return; - } - if (cr0>>31) { - addr = mmutranslate_write(addr); - if (addr==0xFFFFFFFF) - return; - } - - addr &= rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map) { - if (map->write_w) - map->write_w(addr, val, map->p); - else if (map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - } - } -} - - -uint32_t -readmemll(uint32_t addr) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - sub_cycles(timing_misaligned); - if ((addr&0xFFF)>0xFFC) { - if (cr0>>31) { - if (mmutranslate_read(addr) == 0xffffffff) - return 0xffffffff; - if (mmutranslate_read(addr+3) == 0xffffffff) - return 0xffffffff; - } - return readmemwl(addr)|(readmemwl(addr+2)<<16); - } else if (readlookup2[addr >> 12] != -1) - return *(uint32_t *)(readlookup2[addr >> 12] + addr); - } - - if (cr0>>31) { - addr = mmutranslate_read(addr); - if (addr==0xFFFFFFFF) - return 0xFFFFFFFF; - } - - addr&=rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map) { - if (map->read_l) - return map->read_l(addr, map->p); - - if (map->read_w) - return map->read_w(addr, map->p) | (map->read_w(addr + 2, map->p) << 16); - - if (map->read_b) - return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8) | - (map->read_b(addr + 2, map->p) << 16) | (map->read_b(addr + 3, map->p) << 24); - } - - return 0xffffffff; -} - - -void -writememll(uint32_t addr, uint32_t val) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - sub_cycles(timing_misaligned); - if ((addr & 0xFFF) > 0xFFC) { - if (cr0>>31) { - if (mmutranslate_write(addr) == 0xffffffff) - return; - if (mmutranslate_write(addr+3) == 0xffffffff) - return; - } - writememwl(addr,val); - writememwl(addr+2,val>>16); - return; - } else if (writelookup2[addr >> 12] != -1) { - *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; - return; - } - } - if (page_lookup[addr>>12]) { - page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); - return; - } - if (cr0>>31) { - addr = mmutranslate_write(addr); - if (addr==0xFFFFFFFF) - return; - } - - addr&=rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map) { - if (map->write_l) - map->write_l(addr, val, map->p); - else if (map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); - } else if (map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); - } - } -} - - -uint64_t -readmemql(uint32_t addr) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 7) { - sub_cycles(timing_misaligned); - if ((addr & 0xFFF) > 0xFF8) { - if (cr0>>31) { - if (mmutranslate_read(addr) == 0xffffffff) - return 0xffffffff; - if (mmutranslate_read(addr+7) == 0xffffffff) - return 0xffffffff; - } - return readmemll(addr)|((uint64_t)readmemll(addr+4)<<32); - } else if (readlookup2[addr >> 12] != -1) - return *(uint64_t *)(readlookup2[addr >> 12] + addr); - } - - if (cr0>>31) { - addr = mmutranslate_read(addr); - if (addr==0xFFFFFFFF) - return 0xFFFFFFFF; - } - - addr&=rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->read_l) - return map->read_l(addr, map->p) | ((uint64_t)map->read_l(addr + 4, map->p) << 32); - - return readmemll(addr) | ((uint64_t)readmemll(addr+4)<<32); -} - - -void -writememql(uint32_t addr, uint64_t val) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 7) { - sub_cycles(timing_misaligned); - if ((addr & 0xFFF) > 0xFF8) { - if (cr0>>31) { - if (mmutranslate_write(addr) == 0xffffffff) - return; - if (mmutranslate_write(addr+7) == 0xffffffff) - return; - } - writememll(addr, val); - writememll(addr+4, val >> 32); - return; - } else if (writelookup2[addr >> 12] != -1) { - *(uint64_t *)(writelookup2[addr >> 12] + addr) = val; - return; - } - } - if (page_lookup[addr>>12]) { - page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); - page_lookup[addr>>12]->write_l(addr + 4, val >> 32, page_lookup[addr>>12]); - return; - } - if (cr0>>31) { - addr = mmutranslate_write(addr); - if (addr==0xFFFFFFFF) - return; - } - - addr&=rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map) { - if (map->write_l) { - map->write_l(addr, val, map->p); - map->write_l(addr + 4, val >> 32, map->p); - } else if (map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); - map->write_w(addr + 4, val >> 32, map->p); - map->write_w(addr + 6, val >> 48, map->p); - } else if (map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); - map->write_b(addr + 4, val >> 32, map->p); - map->write_b(addr + 5, val >> 40, map->p); - map->write_b(addr + 6, val >> 48, map->p); - map->write_b(addr + 7, val >> 56, map->p); - } - } -} - - -int -mem_mapping_is_romcs(uint32_t addr, int write) -{ - mem_mapping_t *map; - - if (write) - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - else - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (map) - return !!(map->flags & MEM_MAPPING_ROMCS); - else - return 0; -} - - -uint8_t -mem_readb_phys(uint32_t addr) -{ - mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) - return _mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]; - else if (map && map->read_b) - return map->read_b(addr, map->p); - else - return 0xff; -} - - -uint16_t -mem_readw_phys(uint32_t addr) -{ - mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - uint16_t temp; - - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) - return ((uint16_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_HMASK]; - else if (map && map->read_w) - return map->read_w(addr, map->p); - else { - temp = mem_readb_phys(addr + 1) << 8; - temp |= mem_readb_phys(addr); - } - - return temp; -} - -uint32_t -mem_readl_phys(uint32_t addr) -{ - mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - uint32_t temp; - - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) - return ((uint32_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_HMASK]; - else if (map && map->read_l) - return map->read_l(addr, map->p); - else { - temp = mem_readb_phys(addr + 3) << 24; - temp |= mem_readb_phys(addr + 2) << 16; - temp |= mem_readb_phys(addr + 1) << 8; - temp |= mem_readb_phys(addr); - } - - return temp; -} - - -void -mem_writeb_phys(uint32_t addr, uint8_t val) -{ - mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) - _mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK] = val; - else if (map && map->write_b) - map->write_b(addr, val, map->p); -} - -void -mem_writel_phys(uint32_t addr, uint32_t val) -{ - mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) - _mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK] = val; - else if (map && map->write_l) - map->write_l(addr, val, map->p); - else - { - mem_writeb_phys(addr, val & 0xff); - mem_writeb_phys(addr + 1, (val >> 8) & 0xff); - mem_writeb_phys(addr + 2, (val >> 16) & 0xff); - mem_writeb_phys(addr + 3, (val >> 24) & 0xff); - } -} - -uint8_t -mem_read_ram(uint32_t addr, void *priv) -{ - addreadlookup(mem_logical_addr, addr); - - return ram[addr]; -} - - -uint16_t -mem_read_ramw(uint32_t addr, void *priv) -{ - addreadlookup(mem_logical_addr, addr); - - return *(uint16_t *)&ram[addr]; -} - - -uint32_t -mem_read_raml(uint32_t addr, void *priv) -{ - addreadlookup(mem_logical_addr, addr); - - return *(uint32_t *)&ram[addr]; -} - - -static inline int -page_index(page_t *p) -{ - return ((uintptr_t)p - (uintptr_t)pages) / sizeof(page_t); -} - - -void -page_add_to_evict_list(page_t *p) -{ - pages[purgable_page_list_head].evict_prev = page_index(p); - p->evict_next = purgable_page_list_head; - p->evict_prev = 0; - purgable_page_list_head = pages[purgable_page_list_head].evict_prev; - purgeable_page_count++; -} - - -void -page_remove_from_evict_list(page_t *p) -{ - if (!page_in_evict_list(p)) - fatal("page_remove_from_evict_list: not in evict list!\n"); - if (p->evict_prev) - pages[p->evict_prev].evict_next = p->evict_next; - else - purgable_page_list_head = p->evict_next; - if (p->evict_next) - pages[p->evict_next].evict_prev = p->evict_prev; - p->evict_prev = EVICT_NOT_IN_LIST; - purgeable_page_count--; -} - - -void -mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) -{ - if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); - - p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - p->byte_dirty_mask[byte_offset] |= byte_mask; - if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } -} - - -void -mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) -{ - if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); - - if ((addr & 0xf) == 0xf) - mask |= (mask << 1); - *(uint16_t *)&p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - if ((addr & PAGE_BYTE_MASK_MASK) == PAGE_BYTE_MASK_MASK) { - p->byte_dirty_mask[byte_offset+1] |= 1; - if ((p->byte_code_present_mask[byte_offset+1] & 1) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } else - byte_mask |= (byte_mask << 1); - - p->byte_dirty_mask[byte_offset] |= byte_mask; - - if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } -} - - -void -mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) -{ - if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t)0xf << (addr & PAGE_BYTE_MASK_MASK); - - if ((addr & 0xf) >= 0xd) - mask |= (mask << 1); - *(uint32_t *)&p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - p->byte_dirty_mask[byte_offset] |= byte_mask; - if (!page_in_evict_list(p) && ((p->code_present_mask & mask) || (p->byte_code_present_mask[byte_offset] & byte_mask))) - page_add_to_evict_list(p); - if ((addr & PAGE_BYTE_MASK_MASK) > (PAGE_BYTE_MASK_MASK-3)) { - uint32_t byte_mask_2 = 0xf >> (4 - (addr & 3)); - - p->byte_dirty_mask[byte_offset+1] |= byte_mask_2; - if ((p->byte_code_present_mask[byte_offset+1] & byte_mask_2) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } - } -} - - -void -mem_write_ram(uint32_t addr, uint8_t val, void *priv) -{ - addwritelookup(mem_logical_addr, addr); - mem_write_ramb_page(addr, val, &pages[addr >> 12]); -} - - -void -mem_write_ramw(uint32_t addr, uint16_t val, void *priv) -{ - addwritelookup(mem_logical_addr, addr); - mem_write_ramw_page(addr, val, &pages[addr >> 12]); -} - - -void -mem_write_raml(uint32_t addr, uint32_t val, void *priv) -{ - addwritelookup(mem_logical_addr, addr); - mem_write_raml_page(addr, val, &pages[addr >> 12]); -} - - -static uint8_t -mem_read_remapped(uint32_t addr, void *priv) -{ - if(addr >= (mem_size * 1024) && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addreadlookup(mem_logical_addr, addr); - return ram[addr]; -} - - -static uint16_t -mem_read_remappedw(uint32_t addr, void *priv) -{ - if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addreadlookup(mem_logical_addr, addr); - return *(uint16_t *)&ram[addr]; -} - - -static uint32_t -mem_read_remappedl(uint32_t addr, void *priv) -{ - if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addreadlookup(mem_logical_addr, addr); - return *(uint32_t *)&ram[addr]; -} - - -static void -mem_write_remapped(uint32_t addr, uint8_t val, void *priv) -{ - uint32_t oldaddr = addr; - if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addwritelookup(mem_logical_addr, addr); - mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); -} - - -static void -mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) -{ - uint32_t oldaddr = addr; - if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addwritelookup(mem_logical_addr, addr); - mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); -} - - -static void -mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) -{ - uint32_t oldaddr = addr; - if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addwritelookup(mem_logical_addr, addr); - mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); -} - - -uint8_t -mem_read_bios(uint32_t addr, void *priv) -{ - uint8_t ret = 0xff; - - addr &= 0x000fffff; - - if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) - ret = rom[addr - biosaddr]; - - return ret; -} - - -uint16_t -mem_read_biosw(uint32_t addr, void *priv) -{ - uint16_t ret = 0xffff; - - addr &= 0x000fffff; - - if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) - ret = *(uint16_t *)&rom[addr - biosaddr]; - - return ret; -} - - -uint32_t -mem_read_biosl(uint32_t addr, void *priv) -{ - uint32_t ret = 0xffffffff; - - addr &= 0x000fffff; - - if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) - ret = *(uint32_t *)&rom[addr - biosaddr]; - - return ret; -} - - -void -mem_write_null(uint32_t addr, uint8_t val, void *p) -{ -} - - -void -mem_write_nullw(uint32_t addr, uint16_t val, void *p) -{ -} - - -void -mem_write_nulll(uint32_t addr, uint32_t val, void *p) -{ -} - - -void -mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) -{ - uint64_t mask; - page_t *p; - - start_addr &= ~PAGE_MASK_MASK; - end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; - - for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { - if ((start_addr >> 12) >= pages_sz) - continue; - - mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - - p = &pages[start_addr >> 12]; - - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } -} - - -static __inline int -mem_mapping_read_allowed(uint32_t flags, int state) -{ - switch (state & MEM_READ_MASK) { - case MEM_READ_DISABLED: - return 0; - - case MEM_READ_ANY: - return 1; - - /* On external and 0 mappings without ROMCS. */ - case MEM_READ_EXTERNAL: - return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); - - /* On external and 0 mappings with ROMCS. */ - case MEM_READ_ROMCS: - return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); - - /* On any external mappings. */ - case MEM_READ_EXTANY: - return !(flags & MEM_MAPPING_INTERNAL); - - case MEM_READ_INTERNAL: - return !(flags & MEM_MAPPING_EXTERNAL); - - default: - fatal("mem_mapping_read_allowed : bad state %x\n", state); - } - - return 0; -} - - -static __inline int -mem_mapping_write_allowed(uint32_t flags, int state) -{ - switch (state & MEM_WRITE_MASK) { - case MEM_WRITE_DISABLED: - return 0; - - case MEM_WRITE_ANY: - return 1; - - /* On external and 0 mappings without ROMCS. */ - case MEM_WRITE_EXTERNAL: - return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); - - /* On external and 0 mappings with ROMCS. */ - case MEM_WRITE_ROMCS: - return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); - - /* On any external mappings. */ - case MEM_WRITE_EXTANY: - return !(flags & MEM_MAPPING_INTERNAL); - - case MEM_WRITE_INTERNAL: - return !(flags & MEM_MAPPING_EXTERNAL); - - default: - fatal("mem_mapping_write_allowed : bad state %x\n", state); - } - - return 0; -} - - -static void -mem_mapping_recalc(uint64_t base, uint64_t size) -{ - mem_mapping_t *map = base_mapping.next; - uint64_t c; - - if (! size) return; - - /* Clear out old mappings. */ - for (c = base; c < base + size; c += MEM_GRANULARITY_SIZE) { - read_mapping[c >> MEM_GRANULARITY_BITS] = NULL; - write_mapping[c >> MEM_GRANULARITY_BITS] = NULL; - _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; - } - - /* Walk mapping list. */ - while (map != NULL) { - /*In range?*/ - if (map->enable && (uint64_t)map->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)map->base + (uint64_t)map->size) > (uint64_t)base) { - uint64_t start = (map->base < base) ? map->base : base; - uint64_t end = (((uint64_t)map->base + (uint64_t)map->size) < (base + size)) ? ((uint64_t)map->base + (uint64_t)map->size) : (base + size); - if (start < map->base) - start = map->base; - - for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { - if ((map->read_b || map->read_w || map->read_l) && - mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) { - read_mapping[c >> MEM_GRANULARITY_BITS] = map; - if (map->exec) - _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); - else - _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; - } - if ((map->write_b || map->write_w || map->write_l) && - mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) - write_mapping[c >> MEM_GRANULARITY_BITS] = map; - } - } - map = map->next; - } - - flushmmucache_cr3(); -} - - -void -mem_mapping_del(mem_mapping_t *map) -{ - mem_mapping_t *ptr; - - /* Disable the entry. */ - mem_mapping_disable(map); - - /* Zap it from the list. */ - for (ptr = &base_mapping; ptr->next != NULL; ptr = ptr->next) { - if (ptr->next == map) { - ptr->next = map->next; - break; - } - } -} - - -void -mem_mapping_add(mem_mapping_t *map, - uint32_t base, - uint32_t size, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p), - uint8_t *exec, - uint32_t fl, - void *p) -{ - mem_mapping_t *dest = &base_mapping; - - /* Add mapping to the end of the list.*/ - while (dest->next) - dest = dest->next; - dest->next = map; - map->prev = dest; - - if (size) - map->enable = 1; - else - map->enable = 0; - map->base = base; - map->size = size; - map->read_b = read_b; - map->read_w = read_w; - map->read_l = read_l; - map->write_b = write_b; - map->write_w = write_w; - map->write_l = write_l; - map->exec = exec; - map->flags = fl; - map->p = p; - map->dev = NULL; - map->next = NULL; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_mapping_set_handler(mem_mapping_t *map, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p)) -{ - map->read_b = read_b; - map->read_w = read_w; - map->read_l = read_l; - map->write_b = write_b; - map->write_w = write_w; - map->write_l = write_l; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_mapping_set_addr(mem_mapping_t *map, uint32_t base, uint32_t size) -{ - /* Remove old mapping. */ - map->enable = 0; - mem_mapping_recalc(map->base, map->size); - - /* Set new mapping. */ - map->enable = 1; - map->base = base; - map->size = size; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_mapping_set_exec(mem_mapping_t *map, uint8_t *exec) -{ - map->exec = exec; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_mapping_set_p(mem_mapping_t *map, void *p) -{ - map->p = p; -} - - -void -mem_mapping_set_dev(mem_mapping_t *map, void *p) -{ - map->dev = p; -} - - -void -mem_mapping_disable(mem_mapping_t *map) -{ - map->enable = 0; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_mapping_enable(mem_mapping_t *map) -{ - map->enable = 1; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_set_mem_state(uint32_t base, uint32_t size, int state) -{ - uint32_t c; - - for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) - _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = state; - - mem_mapping_recalc(base, size); -} - - -void -mem_add_bios(void) -{ - if (biosmask > 0x1ffff) { - /* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */ - mem_mapping_add(&bios_mapping, 0xe0000, 0x20000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); - - mem_set_mem_state(0x0e0000, 0x20000, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); - } else { - mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); - - mem_set_mem_state(biosaddr, biosmask + 1, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); - } - - if (AT) { - mem_mapping_add(&bios_high_mapping, biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); - - mem_set_mem_state(biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); - } -} - - -void -mem_a20_init(void) -{ - if (AT) { - rammask = cpu_16bitbus ? 0xefffff : 0xffefffff; - flushmmucache(); - mem_a20_state = mem_a20_key | mem_a20_alt; - } else { - rammask = 0xfffff; - flushmmucache(); - mem_a20_key = mem_a20_alt = mem_a20_state = 0; - } -} - - -/* Reset the memory state. */ -void -mem_reset(void) -{ - uint32_t c, m; - - m = 1024UL * mem_size; - if (ram != NULL) { - free(ram); - ram = NULL; - } - ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ - memset(ram, 0x00, m); - - /* - * Allocate the page table based on how much RAM we have. - * We re-allocate the table on each (hard) reset, as the - * memory amount could have changed. - */ - if (AT) { - if (cpu_16bitbus) { - /* 80186/286; maximum address space is 16MB. */ - m = 4096; - } else { - /* 80386+; maximum address space is 4GB. */ - m = (mem_size + 384) >> 2; - if ((m << 2) < (mem_size + 384)) - m++; - if (m < 4096) - m = 4096; - } - } else { - /* 8088/86; maximum address space is 1MB. */ - m = 256; - } - - /* - * Allocate and initialize the (new) page table. - * We only do this if the size of the page table has changed. - */ -#if DYNAMIC_TABLES -mem_log("MEM: reset: previous pages=%08lx, pages_sz=%i\n", pages, pages_sz); -#endif - if (pages_sz != m) { - pages_sz = m; - if (pages) { - free(pages); - pages = NULL; - } - pages = (page_t *)malloc(m*sizeof(page_t)); -#if DYNAMIC_TABLES -mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); -#endif - -#if DYNAMIC_TABLES - /* Allocate the (new) lookup tables. */ - if (page_lookup != NULL) free(page_lookup); - page_lookup = (page_t **)malloc(pages_sz*sizeof(page_t *)); - - if (readlookup2 != NULL) free(readlookup2); - readlookup2 = malloc(pages_sz*sizeof(uintptr_t)); - - if (writelookup2 != NULL) free(writelookup2); - writelookup2 = malloc(pages_sz*sizeof(uintptr_t)); - -#endif - } - -#if DYNAMIC_TABLES - memset(page_lookup, 0x00, pages_sz * sizeof(page_t *)); -#else - memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); -#endif - - memset(pages, 0x00, pages_sz*sizeof(page_t)); - - - if (byte_dirty_mask) { - free(byte_dirty_mask); - byte_dirty_mask = NULL; - } - byte_dirty_mask = malloc((mem_size * 1024) / 8); - memset(byte_dirty_mask, 0, (mem_size * 1024) / 8); - - if (byte_code_present_mask) { - free(byte_code_present_mask); - byte_code_present_mask = NULL; - } - byte_code_present_mask = malloc((mem_size * 1024) / 8); - memset(byte_code_present_mask, 0, (mem_size * 1024) / 8); - - for (c = 0; c < pages_sz; c++) { - pages[c].mem = &ram[c << 12]; - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - pages[c].evict_prev = EVICT_NOT_IN_LIST; - pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; - pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; - } - - memset(_mem_exec, 0x00, sizeof(_mem_exec)); - - memset(&base_mapping, 0x00, sizeof(base_mapping)); - - memset(_mem_state, 0x00, sizeof(_mem_state)); - - mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(0x0c0000, 0x40000, - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - - mem_mapping_add(&ram_low_mapping, 0x00000, - (mem_size > 640) ? 0xa0000 : mem_size * 1024, - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram, MEM_MAPPING_INTERNAL, NULL); - - if (mem_size > 1024) { - if (cpu_16bitbus && mem_size > 16256) { - mem_set_mem_state(0x100000, (16256 - 1024) * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, - ((16256 - 1024) * 1024), - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); - } else { - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, - ((mem_size - 1024) * 1024), - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); - } - } - - if (mem_size > 768) - mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); - - mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, - mem_read_remapped,mem_read_remappedw,mem_read_remappedl, - mem_write_remapped,mem_write_remappedw,mem_write_remappedl, - ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&ram_remapped_mapping); - - mem_a20_init(); - - purgable_page_list_head = 0; - purgeable_page_count = 0; -} - - -void -mem_init(void) -{ - /* Perform a one-time init. */ - ram = rom = NULL; - pages = NULL; -#if DYNAMIC_TABLES - page_lookup = NULL; - readlookup2 = NULL; - writelookup2 = NULL; - -#else - /* Allocate the lookup tables. */ - page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *)); - - readlookup2 = malloc((1<<20)*sizeof(uintptr_t)); - - writelookup2 = malloc((1<<20)*sizeof(uintptr_t)); -#endif - -#if FIXME - memset(ff_array, 0xff, sizeof(ff_array)); -#endif - - /* Reset the memory state. */ - mem_reset(); -} - - -void -mem_remap_top(int kb) -{ - int c; - uint32_t start = (mem_size >= 1024) ? mem_size : 1024; - int offset, size = mem_size - 640; - - mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); - if (mem_size <= 640) return; - - if (kb == 0) { - /* Called to disable the mapping. */ - mem_mapping_disable(&ram_remapped_mapping); - - return; - } - - if (size > kb) - size = kb; - - for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { - offset = c - ((start * 1024) >> 12); - pages[c].mem = &ram[0xA0000 + (offset << 12)]; - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - pages[c].evict_prev = EVICT_NOT_IN_LIST; - pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64]; - pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64]; - } - - mem_set_mem_state(start * 1024, size * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); - mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024)); - - flushmmucache(); -} - -void -mem_reset_page_blocks(void) -{ - uint32_t c; - - if (pages == NULL) return; - - for (c = 0; c < pages_sz; c++) { - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - pages[c].block = BLOCK_INVALID; - pages[c].block_2 = BLOCK_INVALID; - } -} - - -void -mem_a20_recalc(void) -{ - int state; - - if (! AT) { - rammask = 0xfffff; - flushmmucache(); - mem_a20_key = mem_a20_alt = mem_a20_state = 0; - - return; - } - - state = mem_a20_key | mem_a20_alt; - if (state && !mem_a20_state) { - rammask = (AT && cpu_16bitbus) ? 0xffffff : 0xffffffff; - flushmmucache(); - } else if (!state && mem_a20_state) { - rammask = (AT && cpu_16bitbus) ? 0xefffff : 0xffefffff; - flushmmucache(); - } - - mem_a20_state = state; -} diff --git a/src/mouse_bus.c b/src/mouse_bus.c index 36b039d28..df7794adf 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -75,7 +75,7 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "pic.h" #include "timer.h" #include "device.h" diff --git a/src/mouse_ps2.c b/src/mouse_ps2.c index cb7653664..cbd3e5695 100644 --- a/src/mouse_ps2.c +++ b/src/mouse_ps2.c @@ -143,6 +143,27 @@ ps2_write(uint8_t val, void *priv) keyboard_at_adddata_mouse(dev->sample_rate); break; + case 0xeb: /* Get mouse data */ + keyboard_at_adddata_mouse(0xfa); + + temp = 0; + if (dev->x < 0) + temp |= 0x10; + if (dev->y < 0) + temp |= 0x20; + if (mouse_buttons & 1) + temp |= 1; + if (mouse_buttons & 2) + temp |= 2; + if ((mouse_buttons & 4) && (dev->flags & FLAG_INTELLI)) + temp |= 4; + keyboard_at_adddata_mouse(temp); + keyboard_at_adddata_mouse(dev->x & 0xff); + keyboard_at_adddata_mouse(dev->y & 0xff); + if (dev->flags & FLAG_INTMODE) + keyboard_at_adddata_mouse(dev->z); + break; + case 0xf2: /* read ID */ keyboard_at_adddata_mouse(0xfa); if (dev->flags & FLAG_INTMODE) @@ -169,6 +190,7 @@ ps2_write(uint8_t val, void *priv) case 0xff: /* reset */ dev->mode = MODE_STREAM; dev->flags &= 0x88; + mouse_queue_start = mouse_queue_end = 0; keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse(0xaa); keyboard_at_adddata_mouse(0x00); diff --git a/src/network.rar b/src/network.rar new file mode 100644 index 000000000..363c66769 Binary files /dev/null and b/src/network.rar differ diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c index 282219ab3..51084ed79 100644 --- a/src/network/net_3c503.c +++ b/src/network/net_3c503.c @@ -48,13 +48,13 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../mem.h" -#include "../random.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "mem.h" +#include "random.h" +#include "device.h" #include "network.h" #include "net_dp8390.h" #include "net_3c503.h" @@ -617,7 +617,7 @@ threec503_nic_init(const device_t *info) dev->regs.gacfr = 0x09; /* Start with RAM mapping enabled. */ /* Attach ourselves to the network module. */ - network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx); + network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL); return(dev); } diff --git a/src/network/net_dp8390.c b/src/network/net_dp8390.c index 3c30a23e5..4b1fa3edd 100644 --- a/src/network/net_dp8390.c +++ b/src/network/net_dp8390.c @@ -7,7 +7,7 @@ * Emulation of the DP8390 Network Interface Controller used by * the WD family, NE1000/NE2000 family, and 3Com 3C503 NIC's. * - * Version: @(#)net_dp8390.c 1.0.2 2018/10/21 + * Version: @(#)net_dp8390.c 1.0.3 2020/03/23 * * Authors: Miran Grca, * Bochs project, @@ -23,8 +23,8 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" +#include "86box.h" +#include "device.h" #include "network.h" #include "net_dp8390.h" @@ -204,7 +204,7 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val) /* Check for start-tx */ if ((val & 0x04) && dev->TCR.loop_cntl) { if (dev->TCR.loop_cntl) { - dp8390_rx(dev, &dev->mem[(dev->tx_page_start * 256) - dev->mem_start], + dp8390_rx(dev, dev->mem, dev->tx_bytes); } } else if (val & 0x04) { @@ -224,7 +224,7 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val) /* Send the packet to the system driver */ dev->CR.tx_packet = 1; - network_tx(&dev->mem[(dev->tx_page_start * 256) - dev->mem_start], dev->tx_bytes); + network_tx(dev->mem, dev->tx_bytes); /* some more debug */ #ifdef ENABLE_DP8390_LOG @@ -388,7 +388,7 @@ dp8390_rx(void *priv, uint8_t *buf, int io_len) pkthdr[0], pkthdr[1], pkthdr[2], pkthdr[3]); /* Copy into buffer, update curpage, and signal interrupt if config'd */ - startptr = &dev->mem[(dev->curr_page * 256) - dev->mem_start]; + startptr = dev->mem + ((dev->curr_page * 256) - dev->mem_start); memcpy(startptr, pkthdr, sizeof(pkthdr)); if ((nextpage > dev->curr_page) || ((dev->curr_page + pages) == dev->page_stop)) { @@ -396,7 +396,7 @@ dp8390_rx(void *priv, uint8_t *buf, int io_len) } else { endbytes = (dev->page_stop - dev->curr_page) * 256; memcpy(startptr+sizeof(pkthdr), buf, endbytes-sizeof(pkthdr)); - startptr = &dev->mem[(dev->page_start * 256) - dev->mem_start]; + startptr = dev->mem + ((dev->page_start * 256) - dev->mem_start); memcpy(startptr, buf+endbytes-sizeof(pkthdr), io_len-endbytes+8); } dev->curr_page = nextpage; diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 0fd45626c..8feb13c5c 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -52,15 +52,15 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../mca.h" -#include "../pci.h" -#include "../pic.h" -#include "../random.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "mca.h" +#include "pci.h" +#include "pic.h" +#include "random.h" +#include "device.h" #include "network.h" #include "net_dp8390.h" #include "net_ne2000.h" @@ -1465,7 +1465,7 @@ nic_init(const device_t *info) nic_reset(dev); /* Attach ourselves to the network module. */ - network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx); + network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL); nelog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name, dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq); diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 771b55e8e..6ca9a2fe3 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -51,11 +51,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_dynld.h" -// #include "../ui.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "plat_dynld.h" #include "network.h" @@ -185,7 +184,7 @@ poll_thread(void *arg) if (pcap == NULL) break; /* Wait for the next packet to arrive. */ - if (network_get_wait()) + if (network_get_wait() || (poll_card->wait && poll_card->wait(poll_card->priv))) data = NULL; else data = (uint8_t *)f_pcap_next((void *)pcap, &h); diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 49de94317..d2e20acd3 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -7,7 +7,7 @@ * Emulation of the AMD PCnet LANCE NIC controller for both the ISA, VLB, * and PCI buses. * - * Version: @(#)net_pcnet.c 1.0.0 2019/11/09 + * Version: @(#)net_pcnet.c 1.0.1 2020/03/23 * * Authors: Miran Grca, * TheCollector1995, @@ -31,21 +31,20 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../dma.h" -#include "../mem.h" -#include "../rom.h" -#include "../pci.h" -#include "../pic.h" -#include "../random.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "dma.h" +#include "mem.h" +#include "rom.h" +#include "pci.h" +#include "pic.h" +#include "random.h" +#include "device.h" #include "network.h" #include "net_pcnet.h" #include "bswap.h" - /* PCI info. */ #define PCI_VENDID 0x1022 /* AMD */ #define PCI_DEVID 0x2000 /* PCnet-PCI II (Am79c970A) */ @@ -119,37 +118,37 @@ typedef struct RTNETETHERHDR /** @name Bus configuration sub register accessors. * @{ */ -#define BCR_DWIO(S) ((S)->aBCR[BCR_BSBC] & 0x0080) -#define BCR_SSIZE32(S) ((S)->aBCR[BCR_SWS ] & 0x0100) +#define BCR_DWIO(S) !!((S)->aBCR[BCR_BSBC] & 0x0080) +#define BCR_SSIZE32(S) !!((S)->aBCR[BCR_SWS ] & 0x0100) #define BCR_SWSTYLE(S) ((S)->aBCR[BCR_SWS ] & 0x00FF) /** @} */ /** @name CSR subregister accessors. * @{ */ -#define CSR_INIT(S) ((S)->aCSR[0] & 0x0001) /**< Init assertion */ -#define CSR_STRT(S) ((S)->aCSR[0] & 0x0002) /**< Start assertion */ -#define CSR_STOP(S) ((S)->aCSR[0] & 0x0004) /**< Stop assertion */ -#define CSR_TDMD(S) ((S)->aCSR[0] & 0x0008) /**< Transmit demand. (perform xmit poll now (readable, settable, not clearable) */ -#define CSR_TXON(S) ((S)->aCSR[0] & 0x0010) /**< Transmit on (readonly) */ -#define CSR_RXON(S) ((S)->aCSR[0] & 0x0020) /**< Receive On */ -#define CSR_INEA(S) ((S)->aCSR[0] & 0x0040) /**< Interrupt Enable */ -#define CSR_LAPPEN(S) ((S)->aCSR[3] & 0x0020) /**< Look Ahead Packet Processing Enable */ -#define CSR_DXSUFLO(S) ((S)->aCSR[3] & 0x0040) /**< Disable Transmit Stop on Underflow error */ -#define CSR_ASTRP_RCV(S) ((S)->aCSR[4] & 0x0400) /**< Auto Strip Receive */ -#define CSR_DPOLL(S) ((S)->aCSR[4] & 0x1000) /**< Disable Transmit Polling */ -#define CSR_SPND(S) ((S)->aCSR[5] & 0x0001) /**< Suspend */ -#define CSR_LTINTEN(S) ((S)->aCSR[5] & 0x4000) /**< Last Transmit Interrupt Enable */ -#define CSR_TOKINTD(S) ((S)->aCSR[5] & 0x8000) /**< Transmit OK Interrupt Disable */ +#define CSR_INIT(S) !!((S)->aCSR[0] & 0x0001) /**< Init assertion */ +#define CSR_STRT(S) !!((S)->aCSR[0] & 0x0002) /**< Start assertion */ +#define CSR_STOP(S) !!((S)->aCSR[0] & 0x0004) /**< Stop assertion */ +#define CSR_TDMD(S) !!((S)->aCSR[0] & 0x0008) /**< Transmit demand. (perform xmit poll now (readable, settable, not clearable) */ +#define CSR_TXON(S) !!((S)->aCSR[0] & 0x0010) /**< Transmit on (readonly) */ +#define CSR_RXON(S) !!((S)->aCSR[0] & 0x0020) /**< Receive On */ +#define CSR_INEA(S) !!((S)->aCSR[0] & 0x0040) /**< Interrupt Enable */ +#define CSR_LAPPEN(S) !!((S)->aCSR[3] & 0x0020) /**< Look Ahead Packet Processing Enable */ +#define CSR_DXSUFLO(S) !!((S)->aCSR[3] & 0x0040) /**< Disable Transmit Stop on Underflow error */ +#define CSR_ASTRP_RCV(S) !!((S)->aCSR[4] & 0x0400) /**< Auto Strip Receive */ +#define CSR_DPOLL(S) !!((S)->aCSR[4] & 0x1000) /**< Disable Transmit Polling */ +#define CSR_SPND(S) !!((S)->aCSR[5] & 0x0001) /**< Suspend */ +#define CSR_LTINTEN(S) !!((S)->aCSR[5] & 0x4000) /**< Last Transmit Interrupt Enable */ +#define CSR_TOKINTD(S) !!((S)->aCSR[5] & 0x8000) /**< Transmit OK Interrupt Disable */ -#define CSR_STINT ((S)->aCSR[7] & 0x0800) /**< Software Timer Interrupt */ -#define CSR_STINTE ((S)->aCSR[7] & 0x0400) /**< Software Timer Interrupt Enable */ +#define CSR_STINT !!((S)->aCSR[7] & 0x0800) /**< Software Timer Interrupt */ +#define CSR_STINTE !!((S)->aCSR[7] & 0x0400) /**< Software Timer Interrupt Enable */ -#define CSR_DRX(S) ((S)->aCSR[15] & 0x0001) /**< Disable Receiver */ -#define CSR_DTX(S) ((S)->aCSR[15] & 0x0002) /**< Disable Transmit */ -#define CSR_LOOP(S) ((S)->aCSR[15] & 0x0004) /**< Loopback Enable */ -#define CSR_DRCVPA(S) ((S)->aCSR[15] & 0x2000) /**< Disable Receive Physical Address */ -#define CSR_DRCVBC(S) ((S)->aCSR[15] & 0x4000) /**< Disable Receive Broadcast */ -#define CSR_PROM(S) ((S)->aCSR[15] & 0x8000) /**< Promiscuous Mode */ +#define CSR_DRX(S) !!((S)->aCSR[15] & 0x0001) /**< Disable Receiver */ +#define CSR_DTX(S) !!((S)->aCSR[15] & 0x0002) /**< Disable Transmit */ +#define CSR_LOOP(S) !!((S)->aCSR[15] & 0x0004) /**< Loopback Enable */ +#define CSR_DRCVPA(S) !!((S)->aCSR[15] & 0x2000) /**< Disable Receive Physical Address */ +#define CSR_DRCVBC(S) !!((S)->aCSR[15] & 0x4000) /**< Disable Receive Broadcast */ +#define CSR_PROM(S) !!((S)->aCSR[15] & 0x8000) /**< Promiscuous Mode */ /** @name CSR register accessors. * @{ */ @@ -193,14 +192,14 @@ typedef struct { mem_mapping_t mmio_mapping; const char *name; int board; - int is_pci, is_vlb; + int is_pci, is_vlb, is_isa; int PCIBase; int MMIOBase; uint32_t base_address; int base_irq; - int dma_channel; - int card; /* PCI card slot */ - int xmit_pos; + int dma_channel; + int card; /* PCI card slot */ + int xmit_pos; /** Register Address Pointer */ uint32_t u32RAP; /** Internal interrupt service */ @@ -214,6 +213,7 @@ typedef struct { uint8_t aPROM[16]; uint16_t aCSR[CSR_MAX_REG]; uint16_t aBCR[BCR_MAX_RAP]; + uint16_t aMII[MII_MAX_REG]; /** The loopback transmit buffer (avoid stack allocations). */ uint8_t abLoopBuf[4096]; /** The recv buffer. */ @@ -222,14 +222,18 @@ typedef struct { int iLog2DescSize; /** Bits 16..23 in 16-bit mode */ uint32_t GCUpperPhys; + /** We are waiting/about to start waiting for more receive buffers. */ + int fMaybeOutOfSpace; /** True if we signal the guest that RX packets are missing. */ int fSignalRxMiss; /** Link speed to be reported through CSR68. */ uint32_t u32LinkSpeed; /** Error counter for bad receive descriptors. */ uint32_t uCntBadRMD; - uint8_t maclocal[6]; /* configured MAC (local) address */ - pc_timer_t poll_timer; + uint16_t u16CSR0LastSeenByGuest; + uint64_t last_poll; + uint8_t maclocal[6]; /* configured MAC (local) address */ + pc_timer_t poll_timer, timer_soft_int; } nic_t; /** @todo All structs: big endian? */ @@ -359,10 +363,10 @@ static void pcnetAsyncTransmit(nic_t *dev); static void pcnetPollRxTx(nic_t *dev); static void pcnetPollTimer(nic_t *dev); static void pcnetUpdateIrq(nic_t *dev); -static uint16_t pcnet_bcr_readw(nic_t *dev, uint16_t rap); -static void pcnet_bcr_writew(nic_t *dev, uint16_t rap, uint16_t val); -static void pcnet_csr_writew(nic_t *dev, uint16_t rap, uint16_t val); -static void pcnetCanReceive(nic_t *dev); +static uint16_t pcnet_bcr_readw(nic_t *dev, uint16_t rap); +static void pcnet_bcr_writew(nic_t *dev, uint16_t rap, uint16_t val); +static void pcnet_csr_writew(nic_t *dev, uint16_t rap, uint16_t val); +static int pcnetCanReceive(nic_t *dev); #ifdef ENABLE_PCNET_LOG @@ -400,7 +404,6 @@ pcnet_do_irq(nic_t *dev, int issue) } } - /** * Load transmit message descriptor * Make sure we read the own flag first. @@ -794,14 +797,14 @@ pcnetTdraAddr(nic_t *dev, int idx) static void pcnetSoftReset(nic_t *dev) { - pcnetlog(3, "%s: pcnetSoftReset\n", dev->name); + pcnetlog(3, "%s: pcnetSoftReset\n", dev->name); dev->u32Lnkst = 0x40; dev->GCRDRA = 0; dev->GCTDRA = 0; dev->u32RAP = 0; - dev->aCSR[0] = 0x0004; + dev->aCSR[0] = 0x0004; dev->aCSR[3] = 0x0000; dev->aCSR[4] = 0x0115; dev->aCSR[5] = 0x0000; @@ -818,14 +821,25 @@ pcnetSoftReset(nic_t *dev) CSR_XMTRC(dev) = 1; CSR_RCVRL(dev) = 1; CSR_XMTRL(dev) = 1; - dev->aCSR[80] = 0x1410; - if (dev->is_pci) { - dev->aCSR[88] = 0x1003; - dev->aCSR[89] = 0x0262; - } else { - dev->aCSR[88] = 0x3003; - dev->aCSR[89] = 0x0000; - } + dev->aCSR[80] = 0x1410; + + switch (dev->board) { + case DEV_AM79C970A: + dev->aCSR[88] = 0x1003; + dev->aCSR[89] = 0x0262; + break; + case DEV_AM79C973: + dev->aCSR[88] = 0x5003; + dev->aCSR[89] = 0x0262; + break; + case DEV_AM79C960: + case DEV_AM79C960_EB: + case DEV_AM79C960_VLB: + dev->aCSR[88] = 0x3003; + dev->aCSR[89] = 0x0262; + break; + } + dev->aCSR[94] = 0x0000; dev->aCSR[100] = 0x0200; dev->aCSR[103] = 0x0105; @@ -839,90 +853,75 @@ pcnetSoftReset(nic_t *dev) static void pcnetUpdateIrq(nic_t *dev) { - dev->iISR = 0; - - dev->aCSR[0] &= ~0x0080; /* clear INTR */ + int iISR = 0; + uint16_t csr0; - if ((!(dev->aCSR[3] & 0x4000) && (dev->aCSR[0] & 0x4000)) /* BABL */ || - (!(dev->aCSR[3] & 0x1000) && (dev->aCSR[0] & 0x1000)) /* MISS */ || - (!(dev->aCSR[3] & 0x0100) && (dev->aCSR[0] & 0x0100)) /* IDON */ || - (!(dev->aCSR[3] & 0x0200) && (dev->aCSR[0] & 0x0200)) /* TINT */ || - (!(dev->aCSR[3] & 0x0400) && (dev->aCSR[0] & 0x0400)) /* RINT */ || - (!(dev->aCSR[3] & 0x0800) && (dev->aCSR[0] & 0x0800)) /* MERR */ || - (!(dev->aCSR[4] & 0x0001) && (dev->aCSR[4] & 0x0002)) /* JAB */ || - (!(dev->aCSR[4] & 0x0004) && (dev->aCSR[4] & 0x0008)) /* TXSTRT */ || - (!(dev->aCSR[4] & 0x0010) && (dev->aCSR[4] & 0x0020)) /* RCVO */ || - (!(dev->aCSR[4] & 0x0100) && (dev->aCSR[4] & 0x0200)) /* MFCO */ || - ((dev->aCSR[5] & 0x0040) && (dev->aCSR[5] & 0x0080)) /* EXDINT */ || - ((dev->aCSR[5] & 0x0008) && (dev->aCSR[5] & 0x0010)) /* MPINT */) { - dev->iISR = CSR_INEA(dev); /* CSR_INEA */ - dev->aCSR[0] |= 0x0080; /* set INTR */ + csr0 = dev->aCSR[0]; + + csr0 &= ~0x0080; /* clear INTR */ + + if (((csr0 & ~dev->aCSR[3]) & 0x5f00) || + (((dev->aCSR[4]>>1) & ~dev->aCSR[4]) & 0x0115) || + (((dev->aCSR[5]>>1) & dev->aCSR[5]) & 0x0048)) { + iISR = !!(csr0 & 0x0040); /* CSR_INEA */ + csr0 |= 0x0080; /* set INTR */ } - - if (dev->aCSR[4] & 0x0080) { /* UINT */ - dev->aCSR[4] &= ~0x0080; - dev->aCSR[4] |= 0x0040; - dev->iISR = 1; /* CSR_INEA */ - dev->aCSR[0] |= 0x0080; /* set INTR */ - pcnetlog(3, "%s: user int\n", dev->name); - } - - if (((dev->aCSR[5] & 0x0400) && (dev->aCSR[5] & 0x0800)) /* SINT */ || - ((dev->aCSR[5] & 0x0100) && (dev->aCSR[5] & 0x0200)) /* SLPINT */ ) { - dev->iISR = 1; /* CSR_INEA */ - dev->aCSR[0] |= 0x0080; /* set INTR */ + + if (dev->aCSR[4] & 0x0080) { /* UINTCMD */ + dev->aCSR[4] &= ~0x0080; /* clear UINTCMD */ + dev->aCSR[4] |= 0x0040; /* set UINT */ + pcnetlog(2, "%s: user int\n", dev->name); } - pcnetlog(3, "%s: pcnetUpdateIrq: set irq isr=%02x, TINT=%04x\n", dev->name, !!dev->iISR, dev->aCSR[0] & 0x0200); - + if (dev->aCSR[4] & csr0 & 0x0040 /* CSR_INEA */) { + csr0 |= 0x0080; /* set INTR */ + iISR = 1; + } + + if (((dev->aCSR[5]>>1) & dev->aCSR[5]) & 0x0500) { + iISR = 1; + csr0 |= 0x0080; /* set INTR */ + } + + if ((dev->aCSR[7] & 0x0c00) == 0x0c00) /* STINT + STINTE */ + iISR = 1; + + dev->aCSR[0] = csr0; + + pcnetlog(2, "%s: pcnetUpdateIrq: iISR=%d\n", dev->name, iISR); + /* normal path is to _not_ change the IRQ status */ - if (dev->iISR) - pcnet_do_irq(dev, 1); + if (iISR != dev->iISR) { + pcnet_do_irq(dev, iISR); + dev->iISR = iISR; + } } static void pcnetInit(nic_t *dev) { - int i; + int i; pcnetlog(3, "%s: pcnetInit: init_addr=%#010x\n", dev->name, PHYSADDR(dev, CSR_IADR(dev))); /** @todo Documentation says that RCVRL and XMTRL are stored as two's complement! * Software is allowed to write these registers directly. */ #define PCNET_INIT() do { \ - DMAPageRead(PHYSADDR(dev, CSR_IADR(dev)), \ - (uint8_t *)&initblk, sizeof(initblk)); \ - dev->aCSR[15] = le32_to_cpu(initblk.mode); \ - CSR_RCVRL(dev) = (initblk.rlen < 9) ? (1 << initblk.rlen) : 512; \ - CSR_XMTRL(dev) = (initblk.tlen < 9) ? (1 << initblk.tlen) : 512; \ - dev->aCSR[ 6] = (initblk.tlen << 12) | (initblk.rlen << 8); \ - dev->aCSR[ 8] = le32_to_cpu(initblk.ladrf1); \ - dev->aCSR[ 9] = le32_to_cpu(initblk.ladrf2); \ - dev->aCSR[10] = le32_to_cpu(initblk.ladrf3); \ - dev->aCSR[11] = le32_to_cpu(initblk.ladrf4); \ - dev->aCSR[12] = le32_to_cpu(initblk.padr1); \ - dev->aCSR[13] = le32_to_cpu(initblk.padr2); \ - dev->aCSR[14] = le32_to_cpu(initblk.padr3); \ - dev->GCRDRA = PHYSADDR(dev, initblk.rdra); \ - dev->GCTDRA = PHYSADDR(dev, initblk.tdra); \ -} while (0) - -#define PCNET_INIT16() do { \ - DMAPageRead(PHYSADDR(dev, CSR_IADR(dev)), \ - (uint8_t *)&initblk, sizeof(initblk)); \ - dev->aCSR[15] = le32_to_cpu(initblk.mode); \ - CSR_RCVRL(dev) = (1 << initblk.rlen); \ - CSR_XMTRL(dev) = (1 << initblk.tlen); \ - dev->aCSR[ 6] = (initblk.tlen << 12) | (initblk.rlen << 8); \ - dev->aCSR[ 8] = le32_to_cpu(initblk.ladrf1); \ - dev->aCSR[ 9] = le32_to_cpu(initblk.ladrf2); \ - dev->aCSR[10] = le32_to_cpu(initblk.ladrf3); \ - dev->aCSR[11] = le32_to_cpu(initblk.ladrf4); \ - dev->aCSR[12] = le32_to_cpu(initblk.padr1); \ - dev->aCSR[13] = le32_to_cpu(initblk.padr2); \ - dev->aCSR[14] = le32_to_cpu(initblk.padr3); \ - dev->GCRDRA = PHYSADDR(dev, initblk.rdra); \ - dev->GCTDRA = PHYSADDR(dev, initblk.tdra); \ + DMAPageRead(PHYSADDR(dev, CSR_IADR(dev)), \ + (uint8_t *)&initblk, sizeof(initblk)); \ + dev->aCSR[15] = le16_to_cpu(initblk.mode); \ + CSR_RCVRL(dev) = (initblk.rlen < 9) ? (1 << initblk.rlen) : 512; \ + CSR_XMTRL(dev) = (initblk.tlen < 9) ? (1 << initblk.tlen) : 512; \ + dev->aCSR[ 6] = (initblk.tlen << 12) | (initblk.rlen << 8); \ + dev->aCSR[ 8] = le16_to_cpu(initblk.ladrf1); \ + dev->aCSR[ 9] = le16_to_cpu(initblk.ladrf2); \ + dev->aCSR[10] = le16_to_cpu(initblk.ladrf3); \ + dev->aCSR[11] = le16_to_cpu(initblk.ladrf4); \ + dev->aCSR[12] = le16_to_cpu(initblk.padr1); \ + dev->aCSR[13] = le16_to_cpu(initblk.padr2); \ + dev->aCSR[14] = le16_to_cpu(initblk.padr3); \ + dev->GCRDRA = PHYSADDR(dev, initblk.rdra); \ + dev->GCTDRA = PHYSADDR(dev, initblk.tdra); \ } while (0) if (BCR_SSIZE32(dev)) { @@ -934,14 +933,14 @@ pcnetInit(nic_t *dev) } else { struct INITBLK16 initblk; dev->GCUpperPhys = (0xff00 & (uint32_t)dev->aCSR[2]) << 16; - PCNET_INIT16(); + PCNET_INIT(); pcnetlog(3, "%s: initblk.rlen=%#04x, initblk.tlen=%#04x\n", dev->name, initblk.rlen, initblk.tlen); } #undef PCNET_INIT - int cbRxBuffers = 0; + size_t cbRxBuffers = 0; for (i = CSR_RCVRL(dev); i >= 1; i--) { RMD rmd; uint32_t rdaddr = PHYSADDR(dev, pcnetRdraAddr(dev, i)); @@ -968,7 +967,7 @@ pcnetInit(nic_t *dev) * usually 1536 bytes and should therefore not run into condition. If they are still * short in RX buffers we notify this condition. */ - dev->fSignalRxMiss = (cbRxBuffers == 0 || cbRxBuffers >= 32*128); + dev->fSignalRxMiss = (cbRxBuffers == 0 || cbRxBuffers >= 32*1024); CSR_RCVRC(dev) = CSR_RCVRL(dev); CSR_XMTRC(dev) = CSR_XMTRL(dev); @@ -1009,8 +1008,8 @@ pcnetStart(nic_t *dev) if (!CSR_DRX(dev)) dev->aCSR[0] |= 0x0020; /* set RXON */ dev->aCSR[0] &= ~0x0004; /* clear STOP bit */ - dev->aCSR[0] |= 0x0002; /* STRT */ - pcnetPollTimer(dev); + dev->aCSR[0] |= 0x0002; /* STRT */ + pcnetPollTimer(dev); } @@ -1024,7 +1023,7 @@ pcnetStop(nic_t *dev) dev->aCSR[0] = 0x0004; dev->aCSR[4] &= ~0x02c2; dev->aCSR[5] &= ~0x0011; - pcnetPollTimer(dev); + pcnetPollTimer(dev); } @@ -1033,7 +1032,6 @@ pcnetStop(nic_t *dev) * Note: Once a descriptor belongs to the network card (this driver), it cannot be changed * by the host (the guest driver) anymore. Well, it could but the results are undefined by * definition. - * @param fSkipCurrent if true, don't scan the current RDTE. */ static void pcnetRdtePoll(nic_t *dev) @@ -1052,27 +1050,26 @@ pcnetRdtePoll(nic_t *dev) if (i < 1) i = CSR_RCVRL(dev); - addr = pcnetRdraAddr(dev, i); - CSR_CRDA(dev) = CSR_CRBA(dev) = 0; - CSR_CRBC(dev) = CSR_CRST(dev) = 0; - if (!pcnetRmdLoad(dev, &rmd, PHYSADDR(dev, addr), 1)) - return; - if (!IS_RMD_BAD(rmd)) { - CSR_CRDA(dev) = addr; /* Receive Descriptor Address */ - CSR_CRBA(dev) = rmd.rmd0.rbadr; /* Receive Buffer Address */ - CSR_CRBC(dev) = rmd.rmd1.bcnt; /* Receive Byte Count */ - CSR_CRST(dev) = ((uint32_t *)&rmd)[1] >> 16; /* Receive Status */ - pcnetCanReceive(dev); - } else { - /* This is not problematic since we don't own the descriptor - * We actually do own it, otherwise pcnetRmdLoad would have returned false. - * Don't flood the release log with errors. - */ - if (++dev->uCntBadRMD < 50) - pcnetlog(1, "%s: BAD RMD ENTRIES AT %#010x (i=%d)\n", - dev->name, addr, i); - return; - } + addr = pcnetRdraAddr(dev, i); + CSR_CRDA(dev) = CSR_CRBA(dev) = 0; + CSR_CRBC(dev) = CSR_CRST(dev) = 0; + if (!pcnetRmdLoad(dev, &rmd, PHYSADDR(dev, addr), 1)) + return; + if (!IS_RMD_BAD(rmd)) { + CSR_CRDA(dev) = addr; /* Receive Descriptor Address */ + CSR_CRBA(dev) = rmd.rmd0.rbadr; /* Receive Buffer Address */ + CSR_CRBC(dev) = rmd.rmd1.bcnt; /* Receive Byte Count */ + CSR_CRST(dev) = ((uint32_t *)&rmd)[1] >> 16; /* Receive Status */ + } else { + /* This is not problematic since we don't own the descriptor + * We actually do own it, otherwise pcnetRmdLoad would have returned false. + * Don't flood the release log with errors. + */ + if (++dev->uCntBadRMD < 50) + pcnetlog(1, "%s: BAD RMD ENTRIES AT %#010x (i=%d)\n", + dev->name, addr, i); + return; + } /* * The next descriptor. @@ -1204,13 +1201,12 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) { nic_t *dev = (nic_t *)priv; int is_padr = 0, is_bcast = 0, is_ladr = 0; - uint32_t iRxDesc; - int cbPacket; - uint8_t buf1[60]; - + uint32_t iRxDesc; + int cbPacket; + uint8_t buf1[60]; if (CSR_DRX(dev) || CSR_STOP(dev) || CSR_SPND(dev) || !size) - return; + return; /* if too small buffer, then expand it */ if (size < 60) { @@ -1233,16 +1229,16 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) || (is_bcast = padr_bcast(dev, buf, size)) || (is_ladr = ladr_match(dev, buf, size))) { - if (HOST_IS_OWNER(CSR_CRST(dev))) - pcnetRdtePoll(dev); + if (HOST_IS_OWNER(CSR_CRST(dev))) + pcnetRdtePoll(dev); if (HOST_IS_OWNER(CSR_CRST(dev))) { /* Not owned by controller. This should not be possible as * we already called pcnetCanReceive(). */ - const uint32_t cb = 1 << dev->iLog2DescSize; + const unsigned cb = 1 << dev->iLog2DescSize; uint32_t GCPhys = dev->GCRDRA; iRxDesc = CSR_RCVRL(dev); - + while (iRxDesc-- > 0) { RMD rmd; pcnetRmdLoad(dev, &rmd, PHYSADDR(dev, GCPhys), 0); @@ -1250,11 +1246,11 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) } dev->aCSR[0] |= 0x1000; /* Set MISS flag */ CSR_MISSC(dev)++; - pcnetlog(2, "%s: pcnetReceiveNoSync: packet missed\n", dev->name); + pcnetlog(2, "%s: pcnetReceiveNoSync: packet missed\n", dev->name); } else { - RTNETETHERHDR *pEth = (RTNETETHERHDR *)buf; + RTNETETHERHDR *pEth = (RTNETETHERHDR *)buf; int fStrip = 0; - int len_802_3; + size_t len_802_3; uint8_t *src = &dev->abRecvBuf[8]; uint32_t crda = CSR_CRDA(dev); uint32_t next_crda; @@ -1269,36 +1265,40 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) * * NB: CSR_ASTRP_RCV bit affects only 802.3 frames! */ - len_802_3 = cpu_to_be16(pEth->EtherType); + len_802_3 = cpu_to_be16(pEth->EtherType); if (len_802_3 < 46 && CSR_ASTRP_RCV(dev)) { size = MIN(sizeof(RTNETETHERHDR) + len_802_3, size); fStrip = 1; } - - memcpy(src, buf, size); - + + memcpy(src, buf, size); + if (!fStrip) { /* In loopback mode, Runt Packed Accept is always enabled internally; * don't do any padding because guest may be looping back very short packets. */ + if (!CSR_LOOP(dev)) + while (size < 60) + src[size++] = 0; + uint32_t fcs = UINT32_MAX; uint8_t *p = src; - while (p != &src[size]) - CRC(fcs, *p++); + while (p != &src[size]) + CRC(fcs, *p++); /* FCS at the end of the packet */ ((uint32_t *)&src[size])[0] = htonl(fcs); size += 4; - } + } - cbPacket = size; + cbPacket = (int)size; pcnetRmdLoad(dev, &rmd, PHYSADDR(dev, crda), 0); /* if (!CSR_LAPPEN(dev)) */ rmd.rmd1.stp = 1; - int cbBuf = MIN(4096 - rmd.rmd1.bcnt, size); + size_t cbBuf = MIN(4096 - rmd.rmd1.bcnt, size); uint32_t rbadr = PHYSADDR(dev, rmd.rmd0.rbadr); /* save the old value to check if it was changed as long as we didn't @@ -1319,9 +1319,9 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) /* RX disabled in the meantime? If so, abort RX. */ if (CSR_DRX(dev) || CSR_STOP(dev) || CSR_SPND(dev)) { - pcnetlog(3, "%s: RX disabled 1\n", dev->name); + pcnetlog(3, "%s: RX disabled 1\n", dev->name); return; - } + } /* Was the register modified in the meantime? If so, don't touch the * register but still update the RX descriptor. */ @@ -1332,9 +1332,9 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) } else iRxDesc = CSR_RCVRC(dev); - src += cbBuf; - size -= cbBuf; - + src += cbBuf; + size -= cbBuf; + while (size > 0) { /* Read the entire next descriptor as we're likely to need it. */ next_crda = pcnetRdraAddr(dev, iRxDesc); @@ -1352,7 +1352,7 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) crda = next_crda; rmd = next_rmd; - cbBuf = MIN(4096 - rmd.rmd1.bcnt, size); + cbBuf = MIN(4096 - (size_t)rmd.rmd1.bcnt, size); uint32_t rbadr2 = PHYSADDR(dev, rmd.rmd0.rbadr); /* We have to leave the critical section here or we risk deadlocking @@ -1362,9 +1362,9 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) /* RX disabled in the meantime? If so, abort RX. */ if (CSR_DRX(dev) || CSR_STOP(dev) || CSR_SPND(dev)) { - pcnetlog(3, "%s: RX disabled 2\n", dev->name); + pcnetlog(3, "%s: RX disabled 2\n", dev->name); return; - } + } /* Was the register modified in the meantime? If so, don't touch the * register but still update the RX descriptor. */ @@ -1374,10 +1374,10 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) CSR_RCVRC(dev) = iRxDesc; } else { iRxDesc = CSR_RCVRC(dev); - } + } - src += cbBuf; - size -= cbBuf; + src += cbBuf; + size -= cbBuf; } if (size == 0) { @@ -1388,7 +1388,7 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) rmd.rmd2.mcnt = cbPacket; rmd.rmd2.zeros = 0; } else { - pcnetlog(2, "%s: Overflow by %ubytes\n", dev->name, size); + pcnetlog(1, "%s: Overflow by %ubytes\n", dev->name, size); rmd.rmd1.oflo = 1; rmd.rmd1.buff = 1; rmd.rmd1.err = 1; @@ -1398,18 +1398,15 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) pcnetRmdStorePassHost(dev, &rmd, PHYSADDR(dev, crda)); dev->aCSR[0] |= 0x0400; - pcnetlog(2, "%s: RINT set, RCVRC=%d CRDA=%#010x\n", dev->name, + pcnetlog(1, "%s: RINT set, RCVRC=%d CRDA=%#010x\n", dev->name, CSR_RCVRC(dev), PHYSADDR(dev, CSR_CRDA(dev))); /* guest driver is owner: force repoll of current and next RDTEs */ CSR_CRST(dev) = 0; - } } + } - if (!CSR_LOOP(dev)) - pcnetPollRxTx(dev); - - pcnetUpdateIrq(dev); + pcnetUpdateIrq(dev); } @@ -1432,7 +1429,8 @@ pcnetAsyncTransmit(nic_t *dev) /* * Iterate the transmit descriptors. */ - int cMax = 32; + unsigned cFlushIrq = 0; + int cMax = 32; do { TMD tmd; if (!pcnetTdtePoll(dev, &tmd)) @@ -1447,52 +1445,55 @@ pcnetAsyncTransmit(nic_t *dev) */ if (tmd.tmd1.stp && tmd.tmd1.enp) { const int cb = 4096 - tmd.tmd1.bcnt; - pcnetlog(1, "%s: pcnetAsyncTransmit: stp&enp: cb=%d xmtrc=%#x\n", dev->name, cb, CSR_XMTRC(dev)); - dev->xmit_pos = cb; - DMAPageRead(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb); - - if (fLoopback) { - /* From the manual: ``A zero length buffer is acceptable as - * long as it is not the last buffer in a chain (STP = 0 and - * ENP = 1).'' That means that the first buffer might have a - * zero length if it is not the last one in the chain. */ - if (cb <= MAX_FRAME) { - if (HOST_IS_OWNER(CSR_CRST(dev))) - pcnetRdtePoll(dev); - - pcnetReceiveNoSync(dev, dev->abLoopBuf, dev->xmit_pos); - } else if (cb == 4096) { - /* The Windows NT4 pcnet driver sometimes marks the first - * unused descriptor as owned by us. Ignore that (by - * passing it back). Do not update the ring counter in this - * case (otherwise that driver becomes even more confused, - * which causes transmit to stall for about 10 seconds). - * This is just a workaround, not a final solution. */ - /* r=frank: IMHO this is the correct implementation. The - * manual says: ``If the OWN bit is set and the buffer - * length is 0, the OWN bit will be cleared. In the C-LANCE - * the buffer length of 0 is interpreted as a 4096-byte - * buffer.'' */ - /* r=michaln: Perhaps not quite right. The C-LANCE (Am79C90) - * datasheet explains that the old LANCE (Am7990) ignored - * the top four bits next to BCNT and a count of 0 was - * interpreted as 4096. In the C-LANCE, that is still the - * case if the top bits are all ones. If all 16 bits are - * zero, the C-LANCE interprets it as zero-length transmit - * buffer. It's not entirely clear if the later models - * (PCnet-ISA, PCnet-PCI) behave like the C-LANCE or not. - * It is possible that the actual behavior of the C-LANCE - * and later hardware is that the buffer lengths are *16-bit* - * two's complement numbers between 0 and 4096. AMD's drivers - * in fact generally treat the length as a 16-bit quantity. */ - pcnetlog(1, "%s: pcnetAsyncTransmit: illegal 4kb frame -> ignoring\n", dev->name); - pcnetTmdStorePassHost(dev, &tmd, PHYSADDR(dev, CSR_CXDA(dev))); - break; - } - } else { - pcnetlog(3, "%s: pcnetAsyncTransmit: transmit loopbuf stp and enp\n", dev->name); - network_tx(dev->abLoopBuf, dev->xmit_pos); - } + pcnetlog("%s: pcnetAsyncTransmit: stp&enp: cb=%d xmtrc=%#x\n", dev->name, cb, CSR_XMTRC(dev)); + + /* From the manual: ``A zero length buffer is acceptable as + * long as it is not the last buffer in a chain (STP = 0 and + * ENP = 1).'' That means that the first buffer might have a + * zero length if it is not the last one in the chain. */ + if (cb <= MAX_FRAME) { + dev->xmit_pos = cb; + DMAPageRead(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb); + + if (fLoopback) { + if (HOST_IS_OWNER(CSR_CRST(dev))) + pcnetRdtePoll(dev); + + pcnetReceiveNoSync(dev, dev->abLoopBuf, dev->xmit_pos); + } else { + pcnetlog(3, "%s: pcnetAsyncTransmit: transmit loopbuf stp and enp, xmit pos = %d\n", dev->name, dev->xmit_pos); + network_tx(dev->abLoopBuf, dev->xmit_pos); + } + } else if (cb == 4096) { + /* The Windows NT4 pcnet driver sometimes marks the first + * unused descriptor as owned by us. Ignore that (by + * passing it back). Do not update the ring counter in this + * case (otherwise that driver becomes even more confused, + * which causes transmit to stall for about 10 seconds). + * This is just a workaround, not a final solution. + */ + /* r=frank: IMHO this is the correct implementation. The + * manual says: ``If the OWN bit is set and the buffer + * length is 0, the OWN bit will be cleared. In the C-LANCE + * the buffer length of 0 is interpreted as a 4096-byte + * buffer.'' + */ + /* r=michaln: Perhaps not quite right. The C-LANCE (Am79C90) + * datasheet explains that the old LANCE (Am7990) ignored + * the top four bits next to BCNT and a count of 0 was + * interpreted as 4096. In the C-LANCE, that is still the + * case if the top bits are all ones. If all 16 bits are + * zero, the C-LANCE interprets it as zero-length transmit + * buffer. It's not entirely clear if the later models + * (PCnet-ISA, PCnet-PCI) behave like the C-LANCE or not. + * It is possible that the actual behavior of the C-LANCE + * and later hardware is that the buffer lengths are *16-bit* + * two's complement numbers between 0 and 4096. AMD's drivers + * in fact generally treat the length as a 16-bit quantity. */ + pcnetlog(1, "%s: pcnetAsyncTransmit: illegal 4kb frame -> ignoring\n", dev->name); + pcnetTmdStorePassHost(dev, &tmd, PHYSADDR(dev, CSR_CXDA(dev))); + break; + } /* Write back the TMD and pass it to the host (clear own bit). */ pcnetTmdStorePassHost(dev, &tmd, PHYSADDR(dev, CSR_CXDA(dev))); @@ -1502,7 +1503,7 @@ pcnetAsyncTransmit(nic_t *dev) CSR_XMTRC(dev) = CSR_XMTRL(dev); } else { CSR_XMTRC(dev)--; - } + } } else if (tmd.tmd1.stp) { /* * Read TMDs until end-of-packet or tdte poll fails (underflow). @@ -1511,19 +1512,10 @@ pcnetAsyncTransmit(nic_t *dev) * waste time finding out how much space we actually need even if * we could reliably do that on SMP guests. */ - int cb = 4096 - tmd.tmd1.bcnt; - dev->xmit_pos = pcnetCalcPacketLen(dev, cb); - DMAPageRead(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb); - if (fLoopback) { - if (HOST_IS_OWNER(CSR_CRST(dev))) - pcnetRdtePoll(dev); - pcnetlog(3, "%s: pcnetAsyncTransmit: receive loopback stp\n", dev->name); - pcnetReceiveNoSync(dev, dev->abLoopBuf, dev->xmit_pos); - } else { - pcnetlog(3, "%s: pcnetAsyncTransmit: transmit loopbuf stp\n", dev->name); - network_tx(dev->abLoopBuf, dev->xmit_pos); - } - + unsigned cb = 4096 - tmd.tmd1.bcnt; + dev->xmit_pos = pcnetCalcPacketLen(dev, cb); + DMAPageRead(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb); + for (;;) { /* * Advance the ring counter register and check the next tmd. @@ -1541,6 +1533,8 @@ pcnetAsyncTransmit(nic_t *dev) */ tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1; dev->aCSR[0] |= 0x0200; /* set TINT */ + /* Don't allow the guest to clear TINT before reading it */ + dev->u16CSR0LastSeenByGuest &= ~0x0200; if (!CSR_DXSUFLO(dev)) /* stop on xmit underflow */ dev->aCSR[0] &= ~0x0010; /* clear TXON */ pcnetTmdStorePassHost(dev, &tmd, GCPhysPrevTmd); @@ -1557,22 +1551,25 @@ pcnetAsyncTransmit(nic_t *dev) pcnetTmdLoad(dev, &tmd, PHYSADDR(dev, CSR_CXDA(dev)), 0); cb = 4096 - tmd.tmd1.bcnt; if (dev->xmit_pos + cb <= MAX_FRAME) { /** @todo this used to be ... + cb < MAX_FRAME. */ - int off = dev->xmit_pos; - dev->xmit_pos = cb + off; - DMAPageRead(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf + off, cb); - } + int off = dev->xmit_pos; + dev->xmit_pos = cb + off; + DMAPageRead(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf + off, cb); + } /* * Done already? */ if (tmd.tmd1.enp) { - if (fLoopback) { - pcnetlog(3, "%s: pcnetAsyncTransmit: receive loopback enp\n", dev->name); - pcnetReceiveNoSync(dev, dev->abLoopBuf, dev->xmit_pos); - } else { - pcnetlog(3, "%s: pcnetAsyncTransmit: transmit loopbuf enp\n", dev->name); - network_tx(dev->abLoopBuf, dev->xmit_pos); - } + if (fLoopback) { + if (HOST_IS_OWNER(CSR_CRST(dev))) + pcnetRdtePoll(dev); + + pcnetlog(3, "%s: pcnetAsyncTransmit: receive loopback enp\n", dev->name); + pcnetReceiveNoSync(dev, dev->abLoopBuf, dev->xmit_pos); + } else { + pcnetlog(3, "%s: pcnetAsyncTransmit: transmit loopbuf enp\n", dev->name); + network_tx(dev->abLoopBuf, dev->xmit_pos); + } /* Write back the TMD, pass it to the host */ pcnetTmdStorePassHost(dev, &tmd, PHYSADDR(dev, CSR_CXDA(dev))); @@ -1588,16 +1585,23 @@ pcnetAsyncTransmit(nic_t *dev) } /* Update TDMD, TXSTRT and TINT. */ dev->aCSR[0] &= ~0x0008; /* clear TDMD */ - dev->aCSR[4] |= 0x0008; /* set TXSTRT */ - if ( !CSR_TOKINTD(dev) /* Transmit OK Interrupt Disable, no infl. on errors. */ - || (CSR_LTINTEN(dev) && tmd.tmd1.ltint) - || tmd.tmd1.err) { - dev->aCSR[0] |= 0x0200; /* set TINT */ - pcnetUpdateIrq(dev); + dev->aCSR[4] |= 0x0008; /* set TXSTRT */ + dev->xmit_pos = -1; + if (!CSR_TOKINTD(dev) /* Transmit OK Interrupt Disable, no infl. on errors. */ + || (CSR_LTINTEN(dev) && tmd.tmd1.ltint) + || tmd.tmd1.err) { + cFlushIrq++; } if (--cMax == 0) break; } while (CSR_TXON(dev)); /* transfer on */ + + if (cFlushIrq) { + dev->aCSR[0] |= 0x0200; /* set TINT */ + /* Don't allow the guest to clear TINT before reading it */ + dev->u16CSR0LastSeenByGuest &= ~0x0200; + pcnetUpdateIrq(dev); + } } @@ -1613,7 +1617,7 @@ pcnetPollRxTx(nic_t *dev) * true but pcnetCanReceive() returned false for some other reason we need to check * _now_ if we have to wakeup pcnetWaitReceiveAvail(). */ - if (HOST_IS_OWNER(CSR_CRST(dev))) + if (HOST_IS_OWNER(CSR_CRST(dev)) || dev->fMaybeOutOfSpace) pcnetRdtePoll(dev); } @@ -1630,8 +1634,8 @@ pcnetPollTimer(nic_t *dev) pcnetUpdateIrq(dev); - if (!CSR_STOP(dev) && !CSR_SPND(dev) && !CSR_DPOLL(dev)) - pcnetPollRxTx(dev); + if (!CSR_STOP(dev) && !CSR_SPND(dev) && (!CSR_DPOLL(dev) || dev->fMaybeOutOfSpace)) + pcnetPollRxTx(dev); } @@ -1640,27 +1644,37 @@ pcnetHardReset(nic_t *dev) { pcnetlog(2, "%s: pcnetHardReset\n", dev->name); + dev->iISR = 0; + pcnet_do_irq(dev, 0); + + /* Many of the BCR values would normally be read from the EEPROM. */ dev->aBCR[BCR_MSRDA] = 0x0005; dev->aBCR[BCR_MSWRA] = 0x0005; - dev->aBCR[BCR_MC ] = 0x0002; + dev->aBCR[BCR_MC] = 0x0002; dev->aBCR[BCR_LNKST] = 0x00c0; - dev->aBCR[BCR_LED1 ] = 0x0084; - dev->aBCR[BCR_LED2 ] = 0x0088; - dev->aBCR[BCR_LED3 ] = 0x0090; + dev->aBCR[BCR_LED1] = 0x0084; + dev->aBCR[BCR_LED2] = 0x0088; + dev->aBCR[BCR_LED3] = 0x0090; - /* For ISA PnP cards, BCR8 reports IRQ/DMA (e.g. 0x0035 means IRQ 3, DMA 5). */ - if (dev->board == PCNET_ISA) - dev->aBCR[8] = (dev->dma_channel) | (dev->base_irq << 4); - - dev->aBCR[BCR_FDC ] = 0x0000; - dev->aBCR[BCR_BSBC ] = 0x9001; + /* For ISA PnP cards, BCR8 reports IRQ/DMA (e.g. 0x0035 means IRQ 3, DMA 5). */ + if (dev->is_isa) + dev->aBCR[8] = dev->dma_channel | (dev->base_irq << 4); + + dev->aBCR[BCR_FDC] = 0x0000; + dev->aBCR[BCR_BSBC] = 0x9001; dev->aBCR[BCR_EECAS] = 0x0002; - dev->aBCR[BCR_SWS ] = 0x0200; - dev->iLog2DescSize = 3; - dev->aBCR[BCR_PLAT ] = 0xff06; - + dev->aBCR[BCR_STVAL] = 0xffff; + dev->aCSR[58] = dev->aBCR[BCR_SWS] = 0x0200; /* CSR58 is an alias for BCR20 */ + dev->iLog2DescSize = 3; + dev->aBCR[BCR_PLAT] = 0xff06; + dev->aBCR[BCR_MIICAS] = 0x20; /* Auto-negotiation on. */ + dev->aBCR[BCR_MIIADDR] = 0; /* Internal PHY on Am79C973 would be (0x1e << 5) */ + dev->aBCR[BCR_PCIVID] = 0x1022; + dev->aBCR[BCR_PCISID] = 0x0020; + dev->aBCR[BCR_PCISVID] = 0x1022; + /* Reset the error counter. */ - dev->uCntBadRMD = 0; + dev->uCntBadRMD = 0; pcnetSoftReset(dev); } @@ -1669,53 +1683,50 @@ pcnetHardReset(nic_t *dev) static void pcnet_csr_writew(nic_t *dev, uint16_t rap, uint16_t val) { - uint16_t old_inea = CSR_INEA(dev); - pcnetlog(1, "%s: pcnet_csr_writew: rap=%d val=%#06x\n", dev->name, rap, val); switch (rap) { case 0: - /* Clear any interrupt flags. */ - dev->aCSR[0] &= ~(val & 0x7f00); - dev->aCSR[0] = (dev->aCSR[0] & ~0x0040) | (val & 0x0048); - val = (val & 0x007f) | (dev->aCSR[0] & 0x7f00); + { + uint16_t csr0 = dev->aCSR[0]; + /* Clear any interrupt flags. + * Don't clear an interrupt flag which was not seen by the guest yet. */ + csr0 &= ~(val & 0x7f00 & dev->u16CSR0LastSeenByGuest); + csr0 = (csr0 & ~0x0040) | (val & 0x0048); + val = (val & 0x007f) | (csr0 & 0x7f00); - /* If STOP, STRT and INIT are set, clear STRT and INIT */ - if ((val & 7) == 7) - val &= ~3; + /* If STOP, STRT and INIT are set, clear STRT and INIT */ + if ((val & 7) == 7) + val &= ~3; - pcnetlog(2, "%s: CSR0 val = %04x, val2 = %04x\n", dev->name, val, dev->aCSR[0]); + pcnetlog(2, "%s: CSR0 val = %04x, val2 = %04x\n", dev->name, val, dev->aCSR[0]); - if (old_inea && !(val & 0x40)) { - pcnetlog(3, "%s: pcnet_csr_writew(): Disable IRQ\n", dev->name); - dev->iISR = 0; - dev->aCSR[0] &= ~0x0080; - pcnet_do_irq(dev, 0); - } + dev->aCSR[0] = csr0; - if (!CSR_STOP(dev) && (val & 4)) { - pcnetlog(3, "%s: pcnet_csr_writew(): Stop\n", dev->name); - pcnetStop(dev); - } + if (!CSR_STOP(dev) && (val & 4)) { + pcnetlog(3, "%s: pcnet_csr_writew(): Stop\n", dev->name); + pcnetStop(dev); + } - if (!CSR_INIT(dev) && (val & 1)) { - pcnetlog(3, "%s: pcnet_csr_writew(): Init\n", dev->name); - pcnetInit(dev); - } + if (!CSR_INIT(dev) && (val & 1)) { + pcnetlog(3, "%s: pcnet_csr_writew(): Init\n", dev->name); + pcnetInit(dev); + } - if (!CSR_STRT(dev) && (val & 2)) { - pcnetlog(3, "%s: pcnet_csr_writew(): Start\n", dev->name); - pcnetStart(dev); - } + if (!CSR_STRT(dev) && (val & 2)) { + pcnetlog(3, "%s: pcnet_csr_writew(): Start\n", dev->name); + pcnetStart(dev); + } - if (CSR_TDMD(dev)) { - pcnetlog(3, "%s: pcnet_csr_writew(): Transmit\n", dev->name); - pcnetAsyncTransmit(dev); - } + if (CSR_TDMD(dev)) { + pcnetlog(3, "%s: pcnet_csr_writew(): Transmit\n", dev->name); + pcnetAsyncTransmit(dev); + } + } + return; - return; case 2: /* IADRH */ - if (dev->board == PCNET_ISA) - val &= 0x00ff; /* Upper 8 bits ignored on ISA chips. */ + if (dev->is_isa) + val &= 0x00ff; /* Upper 8 bits ignored on ISA chips. */ case 1: /* IADRL */ case 8: /* LADRF 0..15 */ case 9: /* LADRF 16..31 */ @@ -1753,66 +1764,79 @@ pcnet_csr_writew(nic_t *dev, uint16_t rap, uint16_t val) case 72: /* RCVRC */ case 74: /* XMTRC */ case 112: /* MISSC */ - if (CSR_STOP(dev) || CSR_SPND(dev)) - break; - return; + if (CSR_STOP(dev) || CSR_SPND(dev)) + break; + return; case 3: /* Interrupt Mask and Deferral Control */ - break; + break; case 4: /* Test and Features Control */ - dev->aCSR[4] &= ~(val & 0x026a); - val &= ~0x026a; - val |= dev->aCSR[4] & 0x026a; - break; - case 5: /* Extended Control and Interrupt 1 */ - dev->aCSR[5] &= ~(val & 0x0a90); - val &= ~0x0a90; - val |= dev->aCSR[5] & 0x0a90; - break; - case 16: - pcnet_csr_writew(dev,1,val); - return; - case 17: - pcnet_csr_writew(dev,2,val); - return; + dev->aCSR[4] &= ~(val & 0x026a); + val &= ~0x026a; + val |= dev->aCSR[4] & 0x026a; + break; + case 5: /* Extended Control and Interrupt 1 */ + dev->aCSR[5] &= ~(val & 0x0a90); + val &= ~0x0a90; + val |= dev->aCSR[5] & 0x0a90; + break; + case 7: /* Extended Control and Interrupt 2 */ + { + uint16_t csr7 = dev->aCSR[7]; + csr7 &= ~0x0400; + csr7 &= ~(val & 0x0800); + csr7 |= (val & 0x0400); + dev->aCSR[7] = csr7; + } + return; + case 15: /* Mode */ + break; + case 16: /* IADRL */ + pcnet_csr_writew(dev,1,val); + return; + case 17: /* IADRH */ + pcnet_csr_writew(dev,2,val); + return; /* * 24 and 25 are the Base Address of Receive Descriptor. * We combine and mirror these in GCRDRA. */ case 24: /* BADRL */ case 25: /* BADRU */ - if (!CSR_STOP(dev) && !CSR_SPND(dev)) { - pcnetlog(3, "%s: WRITE CSR%d, %#06x, ignoring!!\n", dev->name, rap, val); - return; - } - if (rap == 24) - dev->GCRDRA = (dev->GCRDRA & 0xffff0000) | (val & 0x0000ffff); - else - dev->GCRDRA = (dev->GCRDRA & 0x0000ffff) | ((val & 0x0000ffff) << 16); - pcnetlog(3, "%s: WRITE CSR%d, %#06x => GCRDRA=%08x (alt init)\n", dev->name, rap, val, dev->GCRDRA); - if (dev->GCRDRA & (dev->iLog2DescSize - 1)) - pcnetlog(1, "%s: Warning: Misaligned RDRA (GCRDRA=%#010x)\n", dev->name, dev->GCRDRA); - break; + if (!CSR_STOP(dev) && !CSR_SPND(dev)) { + pcnetlog(3, "%s: WRITE CSR%d, %#06x, ignoring!!\n", dev->name, rap, val); + return; + } + if (rap == 24) + dev->GCRDRA = (dev->GCRDRA & 0xffff0000) | (val & 0x0000ffff); + else + dev->GCRDRA = (dev->GCRDRA & 0x0000ffff) | ((val & 0x0000ffff) << 16); + pcnetlog(3, "%s: WRITE CSR%d, %#06x => GCRDRA=%08x (alt init)\n", dev->name, rap, val, dev->GCRDRA); + if (dev->GCRDRA & (dev->iLog2DescSize - 1)) + pcnetlog(1, "%s: Warning: Misaligned RDRA (GCRDRA=%#010x)\n", dev->name, dev->GCRDRA); + break; /* * 30 & 31 are the Base Address of Transmit Descriptor. * We combine and mirrorthese in GCTDRA. */ case 30: /* BADXL */ case 31: /* BADXU */ - if (!CSR_STOP(dev) && !CSR_SPND(dev)) { - pcnetlog(3, "%s: WRITE CSR%d, %#06x !!\n", dev->name, rap, val); - return; - } - if (rap == 30) - dev->GCTDRA = (dev->GCTDRA & 0xffff0000) | (val & 0x0000ffff); - else - dev->GCTDRA = (dev->GCTDRA & 0x0000ffff) | ((val & 0x0000ffff) << 16); - pcnetlog(3, "%s: WRITE CSR%d, %#06x => GCTDRA=%08x (alt init)\n", dev->name, rap, val, dev->GCTDRA); - if (dev->GCTDRA & (dev->iLog2DescSize - 1)) - pcnetlog(1, "%s: Warning: Misaligned TDRA (GCTDRA=%#010x)\n", dev->name, dev->GCTDRA); - break; + if (!CSR_STOP(dev) && !CSR_SPND(dev)) { + pcnetlog(3, "%s: WRITE CSR%d, %#06x !!\n", dev->name, rap, val); + return; + } + if (rap == 30) + dev->GCTDRA = (dev->GCTDRA & 0xffff0000) | (val & 0x0000ffff); + else + dev->GCTDRA = (dev->GCTDRA & 0x0000ffff) | ((val & 0x0000ffff) << 16); + + pcnetlog(3, "%s: WRITE CSR%d, %#06x => GCTDRA=%08x (alt init)\n", dev->name, rap, val, dev->GCTDRA); + + if (dev->GCTDRA & (dev->iLog2DescSize - 1)) + pcnetlog(1, "%s: Warning: Misaligned TDRA (GCTDRA=%#010x)\n", dev->name, dev->GCTDRA); + break; case 58: /* Software Style */ - pcnet_bcr_writew(dev,BCR_SWS,val); - break; + pcnet_bcr_writew(dev,BCR_SWS,val); + break; /* * Registers 76 and 78 aren't stored correctly (see todos), but I'm don't dare * try fix that right now. So, as a quick hack for 'alt init' I'll just correct them here. @@ -1821,21 +1845,21 @@ pcnet_csr_writew(nic_t *dev, uint16_t rap, uint16_t val) /** @todo receive ring length is stored in two's complement! */ case 78: /* XMTRL */ /** @todo call pcnetUpdateRingHandlers */ /** @todo transmit ring length is stored in two's complement! */ - if (!CSR_STOP(dev) && !CSR_SPND(dev)) { - pcnetlog(3, "%s: WRITE CSR%d, %#06x !!\n", dev->name, rap, val); - return; - } - pcnetlog(3, "%s: WRITE CSR%d, %#06x (hacked %#06x) (alt init)\n", dev->name, - rap, val, 1 + ~val); - val = 1 + ~val; - - /* - * HACK ALERT! Set the counter registers too. - */ - dev->aCSR[rap - 4] = val; - break; - default: + if (!CSR_STOP(dev) && !CSR_SPND(dev)) { + pcnetlog(3, "%s: WRITE CSR%d, %#06x !!\n", dev->name, rap, val); return; + } + pcnetlog(3, "%s: WRITE CSR%d, %#06x (hacked %#06x) (alt init)\n", dev->name, + rap, val, 1 + ~val); + val = 1 + ~val; + + /* + * HACK ALERT! Set the counter registers too. + */ + dev->aCSR[rap - 4] = val; + break; + default: + return; } dev->aCSR[rap] = val; @@ -1845,10 +1869,10 @@ pcnet_csr_writew(nic_t *dev, uint16_t rap, uint16_t val) /** * Encode a 32-bit link speed into a custom 16-bit floating-point value */ -static uint16_t +static uint16_t pcnetLinkSpd(uint32_t speed) { - unsigned exp = 0; + unsigned exp = 0; while (speed & 0xFFFFE000) { speed /= 10; @@ -1865,62 +1889,64 @@ pcnet_csr_readw(nic_t *dev, uint16_t rap) switch (rap) { case 0: - pcnetUpdateIrq(dev); - val = dev->aCSR[0]; - val |= (val & 0x7800) ? 0x8000 : 0; - break; + pcnetUpdateIrq(dev); + val = dev->aCSR[0]; + val |= (val & 0x7800) ? 0x8000 : 0; + dev->u16CSR0LastSeenByGuest = val; + break; case 16: - return pcnet_csr_readw(dev,1); + return pcnet_csr_readw(dev,1); case 17: - return pcnet_csr_readw(dev,2); + return pcnet_csr_readw(dev,2); case 58: - return pcnet_bcr_readw(dev,BCR_SWS); - case 68: /* Custom register to pass link speed to driver */ - return pcnetLinkSpd(dev->u32LinkSpeed); + return pcnet_bcr_readw(dev,BCR_SWS); + case 68: /* Custom register to pass link speed to driver */ + return pcnetLinkSpd(dev->u32LinkSpeed); case 88: - val = dev->aCSR[89]; - val <<= 16; - val |= dev->aCSR[88]; - break; + val = dev->aCSR[89]; + val <<= 16; + val |= dev->aCSR[88]; + break; default: - val = dev->aCSR[rap]; - break; + val = dev->aCSR[rap]; + break; } pcnetlog(3, "%s: pcnet_csr_readw rap=%d val=0x%04x\n", dev->name, rap, val); return val; } -static void +static void pcnet_bcr_writew(nic_t *dev, uint16_t rap, uint16_t val) { rap &= 0x7f; pcnetlog(3, "%s: pcnet_bcr_writew rap=%d val=0x%04x\n", dev->name, rap, val); switch (rap) { case BCR_SWS: - if (!(CSR_STOP(dev) || CSR_SPND(dev))) - return; - val &= ~0x0300; - switch (val & 0x00ff) { - default: - case 0: - val |= 0x0200; /* 16 bit */ - dev->iLog2DescSize = 3; - dev->GCUpperPhys = (0xff00 & dev->aCSR[2]) << 16; - break; - case 1: - val |= 0x0100; /* 32 bit */ - dev->iLog2DescSize = 4; - dev->GCUpperPhys = 0; - break; - case 2: - case 3: - val |= 0x0300; /* 32 bit */ - dev->iLog2DescSize = 4; - dev->GCUpperPhys = 0; - break; - } - /* fall through */ + if (!(CSR_STOP(dev) || CSR_SPND(dev))) + return; + val &= ~0x0300; + switch (val & 0x00ff) { + default: + case 0: + val |= 0x0200; /* 16 bit */ + dev->iLog2DescSize = 3; + dev->GCUpperPhys = (0xff00 & dev->aCSR[2]) << 16; + break; + case 1: + val |= 0x0100; /* 32 bit */ + dev->iLog2DescSize = 4; + dev->GCUpperPhys = 0; + break; + case 2: + case 3: + val |= 0x0300; /* 32 bit */ + dev->iLog2DescSize = 4; + dev->GCUpperPhys = 0; + break; + } + dev->aCSR[58] = val; + /* fall through */ case BCR_LNKST: case BCR_LED1: case BCR_LED2: @@ -1930,13 +1956,156 @@ pcnet_bcr_writew(nic_t *dev, uint16_t rap, uint16_t val) case BCR_BSBC: case BCR_EECAS: case BCR_PLAT: - dev->aBCR[rap] = val; - break; + case BCR_MIICAS: + case BCR_MIIADDR: + dev->aBCR[rap] = val; + break; + + case BCR_STVAL: + val &= 0xffff; + dev->aBCR[BCR_STVAL] = val; + if (dev->board == DEV_AM79C973) + timer_set_delay_u64(&dev->timer_soft_int, (12.8 * val) * TIMER_USEC); + break; + + case BCR_MIIMDR: + dev->aMII[dev->aBCR[BCR_MIIADDR] & 0x1f] = val; + break; + default: - break; + break; } } +static uint16_t +pcnet_mii_readw(nic_t *dev, uint16_t miiaddr) +{ + uint16_t val; + int autoneg, duplex, fast, isolate; + + /* If the DANAS (BCR32.7) bit is set, the MAC does not do any + * auto-negotiation and the PHY must be set up explicitly. DANAS + * effectively disables most other BCR32 bits. + */ + if (dev->aBCR[BCR_MIICAS] & 0x80) { + /* PHY controls auto-negotiation. */ + autoneg = duplex = fast = 1; + } else { + /* BCR32 controls auto-negotiation. */ + autoneg = (dev->aBCR[BCR_MIICAS] & 0x20) != 0; + duplex = (dev->aBCR[BCR_MIICAS] & 0x10) != 0; + fast = (dev->aBCR[BCR_MIICAS] & 0x08) != 0; + } + + /* Electrically isolating the PHY mostly disables it. */ + isolate = (dev->aMII[0] & 0x400) != 0; + + switch (miiaddr) { + case 0: + /* MII basic mode control register. */ + val = 0; + if (autoneg) + val |= 0x1000; /* Enable auto negotiation. */ + if (fast) + val |= 0x2000; /* 100 Mbps */ + if (duplex) /* Full duplex forced */ + val |= 0x0100; /* Full duplex */ + if (isolate) /* PHY electrically isolated. */ + val |= 0x0400; /* Isolated */ + break; + + case 1: + /* MII basic mode status register. */ + val = 0x7800 /* Can do 100mbps FD/HD and 10mbps FD/HD. */ + | 0x0040 /* Mgmt frame preamble not required. */ + | 0x0020 /* Auto-negotiation complete. */ + | 0x0008 /* Able to do auto-negotiation. */ + | 0x0004 /* Link up. */ + | 0x0001; /* Extended Capability, i.e. registers 4+ valid. */ + if (isolate) { + val &= ~(0x0020 | 0x0004); + } + if (!autoneg) { + /* Auto-negotiation disabled. */ + if (duplex) + val &= ~0x2800; /* Full duplex forced. */ + else + val &= ~0x5000; /* Half duplex forced. */ + + if (fast) + val &= ~0x1800; /* 100 Mbps forced */ + else + val &= ~0x6000; /* 10 Mbps forced */ + } + break; + + case 2: + /* PHY identifier 1. */ + val = 0x22; /* Am79C874/AC101 PHY */ + break; + + case 3: + /* PHY identifier 2. */ + val = 0x561b; /* Am79C874/AC101 PHY */ + break; + + case 4: + /* Advertisement control register. */ + val = 0x01e0 /* Try 100mbps FD/HD and 10mbps FD/HD. */ + | 0x0001; /* CSMA selector. */ + break; + + case 5: + /* Link partner ability register. */ + if (!isolate) { + val = 0x8000 /* Next page bit. */ + | 0x4000 /* Link partner acked us. */ + | 0x0400 /* Can do flow control. */ + | 0x01e0 /* Can do 100mbps FD/HD and 10mbps FD/HD. */ + | 0x0001; /* Use CSMA selector. */ + } else { + val = 0; + } + break; + + case 6: + /* Auto negotiation expansion register. */ + if (!isolate) { + val = 0x0008 /* Link partner supports npage. */ + | 0x0004 /* Enable npage words. */ + | 0x0001; /* Can do N-way auto-negotiation. */ + } else { + val = 0; + } + break; + + case 18: + /* Diagnostic Register (FreeBSD pcn/ac101 driver reads this). */ + if (!isolate) { + val = 0x1000 /* Receive PLL locked. */ + | 0x0200; /* Signal detected. */ + + if (autoneg) { + val |= 0x0400 /* 100Mbps rate. */ + | 0x0800; /* Full duplex. */ + } else { + if (fast) + val |= 0x0400; /* 100Mbps rate. */ + if (duplex) + val |= 0x0800; /* Full duplex. */ + } + } else { + val = 0; + } + break; + + default: + val = 0; + break; + } + + return val; +} static uint16_t pcnet_bcr_readw(nic_t *dev, uint16_t rap) @@ -1951,6 +2120,14 @@ pcnet_bcr_readw(nic_t *dev, uint16_t rap) val = dev->aBCR[rap] & ~0x8000; val |= (val & 0x017f & dev->u32Lnkst) ? 0x8000 : 0; break; + + case BCR_MIIADDR: + if ((dev->board == DEV_AM79C973) && (((dev->aBCR[BCR_MIIADDR] >> 5) & 0x1f) == 0)) { + uint16_t miiaddr = dev->aBCR[BCR_MIIADDR] & 0x1f; + val = pcnet_mii_readw(dev, miiaddr); + } else + val = 0xffff; + break; default: val = rap < BCR_MAX_RAP ? dev->aBCR[rap] : 0; break; @@ -2399,7 +2576,7 @@ pcnet_pci_read(int func, int addr, void *p) case 0x07: return 2; case 0x08: - return 0x10; /*Revision ID*/ + return (dev->board == DEV_AM79C973) ? 0x40 : 0x10; /*Revision ID*/ case 0x09: return 0; /*Programming interface*/ case 0x0A: @@ -2426,6 +2603,14 @@ pcnet_pci_read(int func, int addr, void *p) return pcnet_pci_bar[1].addr_regs[2]; case 0x17: return pcnet_pci_bar[1].addr_regs[3]; + case 0x2C: + return 0x22; + case 0x2D: + return 0x10; + case 0x2E: + return 0x00; + case 0x2F: + return 0x20; case 0x3C: return dev->base_irq; case 0x3D: @@ -2449,9 +2634,11 @@ pcnet_pci_read(int func, int addr, void *p) * @returns VBox status code. * @param pThis The PCnet instance data. */ -static void +static int pcnetCanReceive(nic_t *dev) { + int rc = 0; + if (!CSR_DRX(dev) && !CSR_STOP(dev) && !CSR_SPND(dev)) { if (HOST_IS_OWNER(CSR_CRST(dev)) && dev->GCRDRA) pcnetRdtePoll(dev); @@ -2460,11 +2647,47 @@ pcnetCanReceive(nic_t *dev) /** @todo Notify the guest _now_. Will potentially increase the interrupt load */ if (dev->fSignalRxMiss) dev->aCSR[0] |= 0x1000; /* Set MISS flag */ - } + } else + rc = 1; } + + return rc; } +static int +pcnetWaitReceiveAvail(void *priv) +{ + nic_t *dev = (nic_t *) priv; + + dev->fMaybeOutOfSpace = !pcnetCanReceive(dev); + + return dev->fMaybeOutOfSpace; +} + +static void +pcnetTimerSoftInt(void *priv) +{ + nic_t *dev = (nic_t *) priv; + + dev->aCSR[7] |= 0x0800; /* STINT */ + pcnetUpdateIrq(dev); + timer_advance_u64(&dev->timer_soft_int, (12.8 * (dev->aBCR[BCR_STVAL] & 0xffff)) * TIMER_USEC); +} + +static void +pcnetTimerCallback(void *priv) +{ + nic_t *dev = (nic_t *) priv; + +#ifdef ENABLE_PCNET_LOG + pcnetlog(3, "Timer Callback to RX\n"); +#endif + pcnetPollRxTx(dev); + + timer_disable(&dev->poll_timer); +} + static void * pcnet_init(const device_t *info) { @@ -2489,6 +2712,7 @@ pcnet_init(const device_t *info) dev->is_pci = !!(info->flags & DEVICE_PCI); dev->is_vlb = !!(info->flags & DEVICE_VLB); + dev->is_isa = !!(info->flags & (DEVICE_ISA | DEVICE_AT)); if (dev->is_pci) { pcnet_mem_init(dev, 0x0fffff00); @@ -2524,9 +2748,10 @@ pcnet_init(const device_t *info) dev->aPROM[6] = dev->aPROM[7] = 0x00; /* Reserved Location: must be 00h */ - dev->aPROM[8] = 0x00; + dev->aPROM[8] = 0x00; /* Hardware ID: must be 11h if compatibility to AMD drivers is desired */ + /* 0x00/0xFF=ISA, 0x01=PnP, 0x10=VLB, 0x11=PCI */ if (dev->is_pci) dev->aPROM[9] = 0x11; else if (dev->is_vlb) @@ -2537,13 +2762,14 @@ pcnet_init(const device_t *info) /* User programmable space, init with 0 */ dev->aPROM[10] = dev->aPROM[11] = 0x00; - /* LSByte of two-byte checksum, which is the sum of bytes 00h-0Bh - and bytes 0Eh and 0Fh, must therefore be initialized with 0! */ - dev->aPROM[12] = dev->aPROM[13] = 0x00; - - /* Must be ASCII W (57h) if compatibility to AMD - driver software is desired */ - dev->aPROM[14] = dev->aPROM[15] = 0x57; + if (dev->board == DEV_AM79C960_EB) { + dev->aPROM[14] = 0x52; + dev->aPROM[15] = 0x44; /* NI6510 EtherBlaster 'RD' signature. */ + } else { + /* Must be ASCII W (57h) if compatibility to AMD + driver software is desired */ + dev->aPROM[14] = dev->aPROM[15] = 0x57; + } for (c = 0, checksum = 0; c < 16; c++) checksum += dev->aPROM[c]; @@ -2573,7 +2799,7 @@ pcnet_init(const device_t *info) dev->base_address = device_get_config_hex16("base"); dev->base_irq = device_get_config_int("irq"); if (dev->is_vlb) - dev->dma_channel = 0; + dev->dma_channel = -1; else dev->dma_channel = device_get_config_int("dma"); pcnet_ioset(dev, dev->base_address, 0x20); @@ -2585,13 +2811,18 @@ pcnet_init(const device_t *info) dev->aPROM[3], dev->aPROM[4], dev->aPROM[5]); pcnetlog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name, - dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq); + dev->is_pci?"PCI":"VLB/ISA", dev->base_address, dev->base_irq); /* Reset the board. */ pcnetHardReset(dev); /* Attach ourselves to the network module. */ - network_attach(dev, dev->aPROM, pcnetReceiveNoSync); + network_attach(dev, dev->aPROM, pcnetReceiveNoSync, pcnetWaitReceiveAvail); + + if (dev->board == DEV_AM79C973) + timer_add(&dev->timer_soft_int, pcnetTimerSoftInt, dev, 0); + + timer_add(&dev->poll_timer, pcnetTimerCallback, dev, 0); return(dev); } @@ -2603,8 +2834,14 @@ pcnet_close(void *priv) nic_t *dev = (nic_t *)priv; pcnetlog(1, "%s: closed\n", dev->name); - - free(dev); + + if (dev) { + timer_disable(&dev->poll_timer); + + free(dev); + dev = NULL; + + } } @@ -2739,29 +2976,47 @@ static const device_config_t pcnet_vlb_config[] = } }; -const device_t pcnet_pci_device = { - "AMD PCnet-PCI", - DEVICE_PCI, - PCNET_PCI, - pcnet_init, pcnet_close, NULL, - NULL, NULL, NULL, - pcnet_pci_config -}; - -const device_t pcnet_isa_device = { - "AMD PCnet-ISA", +const device_t pcnet_am79c960_device = { + "AMD Am79c960 (PCnet-ISA) ", DEVICE_AT | DEVICE_ISA, - PCNET_ISA, + DEV_AM79C960, pcnet_init, pcnet_close, NULL, NULL, NULL, NULL, pcnet_isa_config }; -const device_t pcnet_vlb_device = { - "AMD PCnet-VL", +const device_t pcnet_am79c960_eb_device = { + "AMD Am79c960EB (PCnet-ISA) ", + DEVICE_AT | DEVICE_ISA, + DEV_AM79C960_EB, + pcnet_init, pcnet_close, NULL, + NULL, NULL, NULL, + pcnet_isa_config +}; + +const device_t pcnet_am79c960_vlb_device = { + "AMD Am79c960 (PCnet-VL) ", DEVICE_VLB, - PCNET_VLB, + DEV_AM79C960_VLB, pcnet_init, pcnet_close, NULL, NULL, NULL, NULL, pcnet_vlb_config }; + +const device_t pcnet_am79c970a_device = { + "AMD Am79c970a (PCnet-PCI II)", + DEVICE_PCI, + DEV_AM79C970A, + pcnet_init, pcnet_close, NULL, + NULL, NULL, NULL, + pcnet_pci_config +}; + +const device_t pcnet_am79c973_device = { + "AMD Am79c973 (PCnet-FAST)", + DEVICE_PCI, + DEV_AM79C973, + pcnet_init, pcnet_close, NULL, + NULL, NULL, NULL, + pcnet_pci_config +}; diff --git a/src/network/net_pcnet.h b/src/network/net_pcnet.h index da4859368..eb6a51d7b 100644 --- a/src/network/net_pcnet.h +++ b/src/network/net_pcnet.h @@ -7,7 +7,7 @@ * Emulation of the AMD PCnet LANCE NIC controller for both the ISA * and PCI buses. * - * Version: @(#)net_pcnet.c 1.0.0 2019/11/09 + * Version: @(#)net_pcnet.c 1.0.1 2020/03/23 * * Authors: Miran Grca, * TheCollector1995, @@ -19,17 +19,20 @@ #ifndef NET_PCNET_H # define NET_PCNET_H - enum { - PCNET_NONE = 0, - PCNET_ISA = 1, /* 16-bit ISA */ - PCNET_PCI = 2, /* 32-bit PCI */ - PCNET_VLB = 3 /* 32-bit VLB */ + DEV_NONE = 0, + DEV_AM79C960 = 1, /* PCnet-ISA (ISA, 10 Mbps, NE2100/NE1500T compatible) */ + DEV_AM79C960_EB = 2, /* PCnet-ISA (ISA, 10 Mbps, Racal InterLan EtherBlaster compatible) */ + DEV_AM79C960_VLB = 3, /* PCnet-VLB (VLB, 10 Mbps, NE2100/NE1500T compatible) */ + DEV_AM79C970A = 4, /* PCnet-PCI II (PCI, 10 Mbps) */ + DEV_AM79C973 = 5 /* PCnet-FAST III (PCI, 10/100 Mbps) */ }; -extern const device_t pcnet_isa_device; -extern const device_t pcnet_pci_device; -extern const device_t pcnet_vlb_device; +extern const device_t pcnet_am79c960_device; +extern const device_t pcnet_am79c960_eb_device; +extern const device_t pcnet_am79c960_vlb_device; +extern const device_t pcnet_am79c970a_device; +extern const device_t pcnet_am79c973_device; #endif /*NET_PCNET_H*/ diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 8b8304854..66d26a31b 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -53,10 +53,9 @@ #define HAVE_STDARG_H #include "slirp/slirp.h" #include "slirp/queue.h" -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -// #include "../ui.h" +#include "86box.h" +#include "device.h" +#include "plat.h" #include "network.h" @@ -148,7 +147,7 @@ poll_thread(void *arg) /* Wait for the next packet to arrive. */ data_valid = 0; - if (!network_get_wait() && (QueuePeek(slirpq) != 0)) { + if ((!network_get_wait() && !(poll_card->wait && poll_card->wait(poll_card->priv))) && (QueuePeek(slirpq) != 0)) { /* Grab a packet from the queue. */ // ui_sb_update_icon(SB_NETWORK, 1); diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 2148a2142..e11fb1e57 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -48,16 +48,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../machine/machine.h" -#include "../mca.h" -#include "../pci.h" -#include "../pic.h" -#include "../random.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "machine.h" +#include "mca.h" +#include "pci.h" +#include "pic.h" +#include "random.h" +#include "device.h" #include "network.h" #include "net_dp8390.h" #include "net_wd8003.h" @@ -771,7 +771,7 @@ wd_init(const device_t *info) mem_mapping_disable(&dev->ram_mapping); /* Attach ourselves to the network module. */ - network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx); + network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL); if (!(dev->board_chip & WE_ID_BUS_MCA)) { wdlog("%s: attached IO=0x%X IRQ=%d, RAM addr=0x%06x\n", dev->name, diff --git a/src/network/network.c b/src/network/network.c index 475a3674e..3b3e08ca5 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.13 2019/12/02 + * Version: @(#)network.c 1.0.14 2020/03/23 * * Author: Fred N. van Kempen, * @@ -55,10 +55,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "ui.h" #include "network.h" #include "net_3c503.h" #include "net_ne2000.h" @@ -71,12 +71,14 @@ static netcard_t net_cards[] = { NULL }, { "[ISA] 3Com EtherLink II (3C503)","3c503", &threec503_device, NULL }, - { "[ISA] AMD PCnet-ISA", "pcnetisa", &pcnet_isa_device, + { "[ISA] AMD PCnet-ISA", "pcnetisa", &pcnet_am79c960_device, NULL }, { "[ISA] Novell NE1000", "ne1k", &ne1000_device, NULL }, { "[ISA] Novell NE2000", "ne2k", &ne2000_device, NULL }, + { "[ISA] Racal Interlan EtherBlaster", "pcnetracal", &pcnet_am79c960_eb_device, + NULL }, { "[ISA] Realtek RTL8019AS", "ne2kpnp", &rtl8019as_device, NULL }, { "[ISA] Western Digital WD8003E", "wd8003e", &wd8003e_device, @@ -91,11 +93,13 @@ static netcard_t net_cards[] = { NULL }, { "[MCA] Western Digital WD8003E/A", "wd8003ea", &wd8003ea_device, NULL }, - { "[PCI] AMD PCnet-PCI", "pcnetpci", &pcnet_pci_device, + { "[PCI] AMD PCnet-FAST III", "pcnetfast", &pcnet_am79c973_device, + NULL }, + { "[PCI] AMD PCnet-PCI II", "pcnetpci", &pcnet_am79c970a_device, NULL }, { "[PCI] Realtek RTL8029AS", "ne2kpci", &rtl8029as_device, NULL }, - { "[VLB] AMD PCnet-VL", "pcnetvlb", &pcnet_vlb_device, + { "[VLB] AMD PCnet-VL", "pcnetvlb", &pcnet_am79c960_vlb_device, NULL }, { "", "", NULL, NULL } @@ -219,13 +223,14 @@ network_init(void) * modules. */ void -network_attach(void *dev, uint8_t *mac, NETRXCB rx) +network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait) { if (network_card == 0) return; /* Save the card's info. */ net_cards[network_card].priv = dev; net_cards[network_card].rx = rx; + net_cards[network_card].wait = wait; network_mac = mac; network_set_wait(0); diff --git a/src/network/network.h b/src/network/network.h index feae064ee..7edfabf5c 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -65,6 +65,7 @@ enum { typedef void (*NETRXCB)(void *, uint8_t *, int); +typedef int (*NETWAITCB)(void *); typedef struct { @@ -74,6 +75,7 @@ typedef struct { void *priv; int (*poll)(void *); NETRXCB rx; + NETWAITCB wait; } netcard_t; typedef struct { @@ -99,7 +101,7 @@ extern void network_busy(uint8_t set); extern void network_end(void); extern void network_init(void); -extern void network_attach(void *, uint8_t *, NETRXCB); +extern void network_attach(void *, uint8_t *, NETRXCB, NETWAITCB); extern void network_close(void); extern void network_reset(void); extern int network_available(void); diff --git a/src/network/pcap_if.c b/src/network/pcap_if.c index 439dbfa94..b73639b48 100644 --- a/src/network/pcap_if.c +++ b/src/network/pcap_if.c @@ -54,9 +54,9 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" -#include "../plat_dynld.h" +#include "86box.h" +#include "plat.h" +#include "plat_dynld.h" static void *pcap_handle; /* handle to WinPcap DLL */ diff --git a/src/nmi.c b/src/nmi.c index e00061d0c..808113bfa 100644 --- a/src/nmi.c +++ b/src/nmi.c @@ -5,7 +5,7 @@ #include #include #include -#include "io.h" +#include "86box_io.h" #include "nmi.h" diff --git a/src/nvr.c b/src/nvr.c index bb72ebf2d..28b099ba1 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -55,7 +55,7 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "machine/machine.h" +#include "machine.h" #include "mem.h" #include "timer.h" #include "plat.h" diff --git a/src/nvr.h b/src/nvr.h index 85d54082a..ce283fe92 100644 --- a/src/nvr.h +++ b/src/nvr.h @@ -8,7 +8,7 @@ * * Definitions for the generic NVRAM/CMOS driver. * - * Version: @(#)nvr.h 1.0.13 2020/01/20 + * Version: @(#)nvr.h 1.0.14 2020/01/24 * * Author: Fred N. van Kempen, , * David Hrdlička, @@ -50,7 +50,7 @@ # define EMU_NVR_H -#define NVR_MAXSIZE 128 /* max size of NVR data */ +#define NVR_MAXSIZE 256 /* max size of NVR data */ /* Conversion from BCD to Binary and vice versa. */ #define RTC_BCD(x) (((x) % 10) | (((x) / 10) << 4)) @@ -91,6 +91,7 @@ extern const device_t at_nvr_device; extern const device_t ps_nvr_device; extern const device_t amstrad_nvr_device; extern const device_t ibmat_nvr_device; +extern const device_t piix4_nvr_device; extern const device_t ls486e_nvr_device; extern const device_t via_nvr_device; #endif @@ -112,6 +113,7 @@ extern void nvr_time_get(struct tm *); extern void nvr_time_set(struct tm *); extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr); +extern void nvr_wp_set(int set, int h, nvr_t *nvr); #endif /*EMU_NVR_H*/ diff --git a/src/nvr_at.c b/src/nvr_at.c index d9a9c692f..cfc3509f5 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -189,7 +189,7 @@ * including the later update (DS12887A) which implemented a * "century" register to be compatible with Y2K. * - * Version: @(#)nvr_at.c 1.0.18 2020/01/20 + * Version: @(#)nvr_at.c 1.0.19 2020/01/24 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -226,9 +226,9 @@ #include #include #include "86box.h" -#include "cpu/cpu.h" -#include "machine/machine.h" -#include "io.h" +#include "cpu.h" +#include "machine.h" +#include "86box_io.h" #include "mem.h" #include "nmi.h" #include "pic.h" @@ -286,14 +286,17 @@ #define RTC_CENTURY_VIA 0x7F /* century register for VIA VT82C586B */ #define RTC_REGS 14 /* number of registers */ +#define FLAG_LS_HACK 0x01 +#define FLAG_PIIX4 0x02 + typedef struct { int8_t stat; uint8_t cent; - uint8_t def, ls_hack; + uint8_t def, flags; - uint8_t addr[8]; + uint8_t addr[8], wp[2]; int16_t count, state; @@ -304,6 +307,9 @@ typedef struct { } local_t; +static uint8_t nvr_at_inited = 0; + + /* Get the current NVR time. */ static void time_get(nvr_t *nvr, struct tm *tm) @@ -582,7 +588,7 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) case 0x2e: case 0x2f: - if (local->ls_hack) { + if (local->flags & FLAG_LS_HACK) { /* 2E and 2F are a simple sum of the values of 0E to 2D. */ for (i = 0x0e; i < 0x2e; i++) checksum += (uint16_t) nvr->regs[i]; @@ -593,6 +599,10 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) /*FALLTHROUGH*/ default: /* non-RTC registers are just NVRAM */ + if ((local->addr[addr_id] >= 0x38) && (local->addr[addr_id] <= 0x3f) && local->wp[0]) + break; + if ((local->addr[addr_id] >= 0xb8) && (local->addr[addr_id] <= 0xbf) && local->wp[1]) + break; if (nvr->regs[local->addr[addr_id]] != val) { nvr->regs[local->addr[addr_id]] = val; nvr_dosave = 1; @@ -615,6 +625,8 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) /* Some chipsets use a 256 byte NVRAM but ports 70h and 71h always access only 128 bytes. */ if (addr_id == 0x0) local->addr[addr_id] &= 0x7f; + else if ((addr_id == 0x1) && (local->flags & FLAG_PIIX4)) + local->addr[addr_id] = (local->addr[addr_id] & 0x7f) | 0x80; if (!(machines[machine].flags & MACHINE_MCA) && !(machines[machine].flags & MACHINE_NONMI)) nmi_mask = (~val & 0x80); @@ -651,7 +663,7 @@ nvr_read(uint16_t addr, void *priv) break; case 0x2c: - if (local->ls_hack) + if (local->flags & FLAG_LS_HACK) ret = nvr->regs[local->addr[addr_id]] & 0x7f; else ret = nvr->regs[local->addr[addr_id]]; @@ -659,7 +671,7 @@ nvr_read(uint16_t addr, void *priv) case 0x2e: case 0x2f: - if (local->ls_hack) { + if (local->flags & FLAG_LS_HACK) { checksum = (nvr->regs[0x2e] << 8) | nvr->regs[0x2f]; if (nvr->regs[0x2c] & 0x80) checksum -= 0x80; @@ -759,6 +771,15 @@ nvr_at_handler(int set, uint16_t base, nvr_t *nvr) } +void +nvr_wp_set(int set, int h, nvr_t *nvr) +{ + local_t *local = (local_t *) nvr->data; + + local->wp[h] = set; +} + + static void * nvr_at_init(const device_t *info) { @@ -777,7 +798,7 @@ nvr_at_init(const device_t *info) /* This is machine specific. */ nvr->size = machines[machine].nvrmask + 1; local->def = 0x00; - local->ls_hack = 0; + local->flags = 0x00; switch(info->local & 7) { case 0: /* standard AT, no century register */ nvr->irq = 8; @@ -785,10 +806,12 @@ nvr_at_init(const device_t *info) break; case 5: /* Lucky Star LS-486E */ - local->ls_hack = 1; + local->flags |= FLAG_LS_HACK; /*FALLTHROUGH*/ case 1: /* standard AT */ + if (info->local == 9) + local->flags |= FLAG_PIIX4; nvr->irq = 8; local->cent = RTC_CENTURY_AT; break; @@ -824,19 +847,23 @@ nvr_at_init(const device_t *info) /* Initialize the generic NVR. */ nvr_init(nvr); - /* Start the timers. */ - timer_add(&local->update_timer, timer_update, nvr, 0); + if (nvr_at_inited == 0) { + /* Start the timers. */ + timer_add(&local->update_timer, timer_update, nvr, 0); - timer_add(&local->rtc_timer, timer_intr, nvr, 0); - timer_load_count(nvr); - timer_set_delay_u64(&local->rtc_timer, RTCCONST); + timer_add(&local->rtc_timer, timer_intr, nvr, 0); + timer_load_count(nvr); + timer_set_delay_u64(&local->rtc_timer, RTCCONST); - /* Set up the I/O handler for this device. */ - io_sethandler(0x0070, 2, - nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr); - if (info->local & 8) { - io_sethandler(0x0072, 2, + /* Set up the I/O handler for this device. */ + io_sethandler(0x0070, 2, nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr); + if (info->local & 8) { + io_sethandler(0x0072, 2, + nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr); + } + + nvr_at_inited = 1; } return(nvr); @@ -862,6 +889,9 @@ nvr_at_close(void *priv) free(nvr->data); free(nvr); + + if (nvr_at_inited == 1) + nvr_at_inited = 0; } @@ -910,6 +940,15 @@ const device_t ibmat_nvr_device = { NULL }; +const device_t piix4_nvr_device = { + "Intel PIIX4 PC/AT NVRAM", + DEVICE_ISA | DEVICE_AT, + 9, + nvr_at_init, nvr_at_close, NULL, + NULL, nvr_at_speed_changed, + NULL +}; + const device_t ls486e_nvr_device = { "Lucky Star LS-486E PC/AT NVRAM", DEVICE_ISA | DEVICE_AT, diff --git a/src/nvr_ps2.c b/src/nvr_ps2.c index 483d67529..b4074039d 100644 --- a/src/nvr_ps2.c +++ b/src/nvr_ps2.c @@ -40,9 +40,9 @@ #include #include #include "86box.h" -#include "machine/machine.h" +#include "machine.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "mem.h" #include "timer.h" #include "nvr.h" diff --git a/src/pc.c b/src/pc.c index 841bb9a23..3c67989c0 100644 --- a/src/pc.c +++ b/src/pc.c @@ -26,24 +26,17 @@ #include #include #include + #define HAVE_STDARG_H #include "86box.h" #include "config.h" #include "mem.h" -#ifdef USE_NEW_DYNAREC +#include "cpu.h" #ifdef USE_DYNAREC -#include "cpu_new/cpu.h" -# include "cpu_new/codegen.h" +# include "codegen_public.h" #endif -#include "cpu_new/x86_ops.h" -#else -#include "cpu/cpu.h" -#ifdef USE_DYNAREC -# include "cpu/codegen.h" -#endif -#include "cpu/x86_ops.h" -#endif -#include "io.h" +#include "x86_ops.h" +#include "86box_io.h" #include "rom.h" #include "dma.h" #include "pci.h" @@ -54,31 +47,32 @@ #include "random.h" #include "timer.h" #include "nvr.h" -#include "machine/machine.h" +#include "machine.h" #include "bugger.h" +#include "postcard.h" #include "isamem.h" #include "isartc.h" #include "lpt.h" #include "serial.h" #include "keyboard.h" #include "mouse.h" -#include "game/gameport.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" -#include "disk/hdd.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "scsi/scsi.h" -#include "scsi/scsi_device.h" -#include "cdrom/cdrom.h" -#include "disk/zip.h" -#include "scsi/scsi_disk.h" -#include "cdrom/cdrom_image.h" -#include "network/network.h" -#include "sound/sound.h" -#include "sound/midi.h" -#include "sound/snd_speaker.h" -#include "video/video.h" +#include "gameport.h" +#include "fdd.h" +#include "fdc.h" +#include "hdd.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "scsi.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "zip.h" +#include "scsi_disk.h" +#include "cdrom_image.h" +#include "network.h" +#include "sound.h" +#include "midi.h" +#include "snd_speaker.h" +#include "video.h" #include "ui.h" #include "plat.h" #include "plat_midi.h" @@ -119,6 +113,7 @@ int vid_cga_contrast = 0, /* (C) video */ force_43 = 0; /* (C) video */ int serial_enabled[SERIAL_MAX] = {0,0}, /* (C) enable serial ports */ bugger_enabled = 0, /* (C) enable ISAbugger */ + postcard_enabled = 0, /* (C) enable POST card */ isamem_type[ISAMEM_MAX] = { 0,0,0,0 }, /* (C) enable ISA mem cards */ isartc_type = 0; /* (C) enable ISA RTC card */ int gfxcard = 0; /* (C) graphics/video card */ @@ -786,7 +781,9 @@ pc_reset_hard_init(void) /* Needs the status bar... */ if (bugger_enabled) - device_add(&bugger_device); + device_add(&bugger_device); + if (postcard_enabled) + device_add(&postcard_device); /* Reset the CPU module. */ resetx86(); diff --git a/src/pci.c b/src/pci.c index 082361c36..ada976629 100644 --- a/src/pci.c +++ b/src/pci.c @@ -25,9 +25,9 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "machine/machine.h" -#include "cpu/cpu.h" -#include "io.h" +#include "machine.h" +#include "cpu.h" +#include "86box_io.h" #include "pic.h" #include "mem.h" #include "device.h" @@ -127,7 +127,15 @@ pci_write(uint16_t port, uint8_t val, void *priv) pci_log("Writing to PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv); } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); +#endif } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); +#endif } break; @@ -150,7 +158,15 @@ pci_read(uint16_t port, void *priv) if (slot != 0xff) { if (pci_cards[slot].read) return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); +#endif } +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); +#endif } return 0xff; @@ -235,10 +251,17 @@ pci_type2_write(uint16_t port, uint8_t val, void *priv) if (! pci_bus) { slot = pci_card_to_slot_mapping[pci_card]; if (slot != 0xff) { - if (pci_cards[slot].write) { + if (pci_cards[slot].write) pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv); - } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); +#endif } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); +#endif } } } @@ -261,10 +284,17 @@ pci_type2_read(uint16_t port, void *priv) if (! pci_bus) { slot = pci_card_to_slot_mapping[pci_card]; if (slot != 0xff) { - if (pci_cards[slot].read) { + if (pci_cards[slot].read) return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); - } +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); +#endif } +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); +#endif } return 0xff; @@ -613,7 +643,7 @@ pci_slots_clear(void) } -static uint8_t +uint8_t trc_read(uint16_t port, void *priv) { return trc_reg & 0xfb; @@ -628,20 +658,20 @@ trc_reset(uint8_t val) cpu_alt_reset = 0; + pci_reset(); + keyboard_at_reset(); + mem_a20_alt = 0; mem_a20_recalc(); flushmmucache(); - - pci_reset(); - keyboard_at_reset(); } resetx86(); } -static void +void trc_write(uint16_t port, uint8_t val, void *priv) { pci_log("TRC Write: %02X\n", val); @@ -760,7 +790,9 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), if (((dev->type == PCI_CARD_NORMAL) && (add_type >= PCI_ADD_NORMAL)) || ((dev->type == PCI_CARD_ONBOARD) && (add_type == PCI_ADD_VIDEO)) || ((dev->type == PCI_CARD_SCSI) && (add_type == PCI_ADD_SCSI)) || - ((dev->id == add_type) && (add_type < PCI_ADD_NORMAL))) { + ((dev->type == PCI_CARD_NORTHBRIDGE) && (add_type == PCI_ADD_NORTHBRIDGE)) || + ((dev->type == PCI_CARD_SOUTHBRIDGE) && (add_type == PCI_ADD_SOUTHBRIDGE)) || + ((dev->id == add_type) && (add_type < PCI_ADD_NORTHBRIDGE))) { dev->read = read; dev->write = write; dev->priv = priv; diff --git a/src/pci.h b/src/pci.h index 18a93d9fb..473f27389 100644 --- a/src/pci.h +++ b/src/pci.h @@ -46,16 +46,21 @@ #define PCI_IRQ_DISABLED -1 enum { - PCI_CARD_NORMAL = 0, + PCI_CARD_NORTHBRIDGE = 0, + PCI_CARD_SOUTHBRIDGE, + PCI_CARD_NORMAL, PCI_CARD_ONBOARD, PCI_CARD_SCSI, PCI_CARD_SPECIAL }; - -#define PCI_ADD_NORMAL 0x80 -#define PCI_ADD_VIDEO 0x81 -#define PCI_ADD_SCSI 0x82 +enum { + PCI_ADD_NORTHBRIDGE = 0x80, + PCI_ADD_SOUTHBRIDGE, + PCI_ADD_NORMAL, + PCI_ADD_VIDEO, + PCI_ADD_SCSI +}; typedef union { uint32_t addr; @@ -90,6 +95,10 @@ extern void pci_close(void); extern uint8_t pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); extern void trc_init(void); + +extern uint8_t trc_read(uint16_t port, void *priv); +extern void trc_write(uint16_t port, uint8_t val, void *priv); + extern void pci_elcr_set_enabled(int enabled); diff --git a/src/pci_dummy.c b/src/pci_dummy.c index 6a790ff14..02819618b 100644 --- a/src/pci_dummy.c +++ b/src/pci_dummy.c @@ -4,7 +4,7 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "pci.h" #include "pci_dummy.h" diff --git a/src/pic.c b/src/pic.c index 12cbcb251..ad8cc00d5 100644 --- a/src/pic.c +++ b/src/pic.c @@ -21,9 +21,9 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu/cpu.h" -#include "machine/machine.h" -#include "io.h" +#include "cpu.h" +#include "machine.h" +#include "86box_io.h" #include "pci.h" #include "pic.h" #include "timer.h" @@ -345,6 +345,35 @@ pic2_write(uint16_t addr, uint8_t val, void *priv) pic.pend &= ~4; pic_updatepending(); } else if (!(val & 8)) { /*OCW2*/ +#ifdef ENABLE_PIC_LOG + switch ((val >> 5) & 0x07) { + case 0x00: + pic_log("Rotate in automatic EOI mode (clear)\n"); + break; + case 0x01: + pic_log("Non-specific EOI command\n"); + break; + case 0x02: + pic_log("No operation\n"); + break; + case 0x03: + pic_log("Specific EOI command\n"); + break; + case 0x04: + pic_log("Rotate in automatic EOI mode (set)\n"); + break; + case 0x05: + pic_log("Rotate on on-specific EOI command\n"); + break; + case 0x06: + pic_log("Set priority command\n"); + break; + case 0x07: + pic_log("Rotate on specific EOI command\n"); + break; + } +#endif + pic2.ocw2 = val; if ((val & 0xE0) == 0x60) { pic2.ins &= ~(1 << (val & 7)); @@ -512,21 +541,32 @@ pic_process_interrupt(PIC* target_pic, int c) { uint8_t pending = target_pic->pend & ~target_pic->mask; int ret = -1; + /* TODO: On init, a PIC need to get a pointer to one of these, and rotate as needed + if in rotate mode. */ + /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */ + int priority_xt[16] = { 7, 6, 5, 4, 3, 2, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1 }; + int priority_at[16] = { 14, 13, -1, 4, 3, 2, 1, 0, 12, 11, 10, 9, 8, 7, 6, 5 }; + int i; int pic_int = c & 7; int pic_int_num = 1 << pic_int; int in_service = 0; - in_service = (target_pic->ins & (pic_int_num - 1)); /* Is anything of higher priority already in service? */ - in_service |= (target_pic->ins & pic_int_num); /* Is the current IRQ already in service? */ if (AT) { - /* AT-specific stuff. */ - if (c >= 8) - in_service |= (pic.ins & 0x03); /* IRQ 8 to 15, are IRQ's with higher priorities than the - cascade IRQ already in service? */ - /* For IRQ 0 to 7, the cascade IRQ's in service bit indicates that one or - more IRQ's between 8 and 15 are already in service. */ + for (i = 0; i < 16; i++) { + if ((priority_at[i] != -1) && (priority_at[i] >= priority_at[c])) { + if (i < 8) + in_service |= (pic.ins & (1 << i)); + else + in_service |= (pic2.ins & (1 << i)); + } + } + } else { + for (i = 0; i < 16; i++) { + if ((priority_xt[i] != -1) && (priority_xt[i] >= priority_xt[c])) + in_service |= (pic.ins & (1 << i)); + } } if ((pending & pic_int_num) && !in_service) { diff --git a/src/piix.h b/src/piix.h index 6de1d65b3..2987cef7e 100644 --- a/src/piix.h +++ b/src/piix.h @@ -8,14 +8,15 @@ * * Emulation core dispatcher. * - * Version: @(#)piix.h 1.0.3 2018/05/11 + * Version: @(#)piix.h 1.0.4 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ extern const device_t piix_device; -extern const device_t piix_pb640_device; extern const device_t piix3_device; +extern const device_t piix4_device; +extern const device_t piix4e_device; diff --git a/src/pit.c b/src/pit.c index eaab7a4e3..f3421a8f4 100644 --- a/src/pit.c +++ b/src/pit.c @@ -24,11 +24,11 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu/cpu.h" +#include "cpu.h" #include "device.h" #include "timer.h" #include "dma.h" -#include "io.h" +#include "86box_io.h" #include "nmi.h" #include "pic.h" #include "timer.h" @@ -43,7 +43,8 @@ pit_t *pit, *pit2; double cpuclock, PITCONSTD, SYSCLK, - isa_timing, bus_timing; + isa_timing, + bus_timing, pci_timing; uint64_t PITCONST, ISACONST, CGACONST, @@ -1024,7 +1025,9 @@ pit_set_clock(int clock) TIMER_USEC = (uint64_t)((cpuclock / 1000000.0) * (double)(1ull << 32)); isa_timing = (cpuclock / (double)8000000.0); + bus_timing = (cpuclock / (double)cpu_busspeed); + pci_timing = (cpuclock / (double)cpu_pci_speed); if (cpu_busspeed >= 30000000) SYSCLK = bus_timing * 4.0; diff --git a/src/port_92.c b/src/port_92.c index 1c5f1b2bf..7230111f2 100644 --- a/src/port_92.c +++ b/src/port_92.c @@ -22,13 +22,9 @@ #include #include "86box.h" #include "device.h" -#ifdef USE_NEW_DYNAREC -#include "cpu_new/cpu.h" -#else -#include "cpu/cpu.h" -#endif +#include "cpu.h" #include "timer.h" -#include "io.h" +#include "86box_io.h" #include "keyboard.h" #include "mem.h" #include "pit.h" diff --git a/src/postcard.c b/src/postcard.c new file mode 100644 index 000000000..9662d3ae6 --- /dev/null +++ b/src/postcard.c @@ -0,0 +1,142 @@ +/* + * 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. + * + * Implementation of a port 80h POST diagnostic card. + * + * Version: @(#)postcard.c 1.0.0 2020/03/23 + * + * Author: RichardG, + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include "86box.h" +#include "86box_io.h" +#include "device.h" +#include "machine.h" +#include "plat.h" +#include "ui.h" +#include "postcard.h" + + +static uint16_t postcard_port; +static uint8_t postcard_written; +static uint8_t postcard_code, postcard_prev_code; +#define UISTR_LEN 13 +static char postcard_str[UISTR_LEN]; /* UI output string */ + + +extern void ui_sb_bugui(char *__str); + + +#ifdef ENABLE_POSTCARD_LOG +int postcard_do_log = ENABLE_POSTCARD_LOG; + + +static void +postcard_log(const char *fmt, ...) +{ + va_list ap; + + if (postcard_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +int postcard_do_log = 0; + +#define postcard_log(fmt, ...) +#endif + + +static void +postcard_setui(void) +{ + if (!postcard_written) + sprintf(postcard_str, "POST: -- --"); + else if (postcard_written == 1) + sprintf(postcard_str, "POST: %02X --", postcard_code); + else + sprintf(postcard_str, "POST: %02X %02X", postcard_code, postcard_prev_code); + + ui_sb_bugui(postcard_str); + + if (postcard_do_log) { + /* log same string sent to the UI */ + int len = strlen(postcard_str); + postcard_str[len + 1] = '\0'; + postcard_str[len] = '\n'; + postcard_log(postcard_str); + } +} + + +static void +postcard_reset(void) +{ + postcard_written = 0; + postcard_code = postcard_prev_code = 0x00; + + postcard_setui(); +} + + +static void +postcard_write(uint16_t port, uint8_t val, void *priv) +{ + postcard_prev_code = postcard_code; + postcard_code = val; + if (postcard_written < 2) + postcard_written++; + + postcard_setui(); +} + + +static void * +postcard_init(const device_t *info) +{ + postcard_reset(); + + if (machines[machine].flags & MACHINE_MCA) + postcard_port = 0x680; /* MCA machines */ + else if (strstr(machines[machine].name, " PS/2 ")) + postcard_port = 0x90; /* ISA PS/2 machines */ + else + postcard_port = 0x80; /* AT and clone machines */ + postcard_log("POST card initializing on port %04Xh\n", postcard_port); + + if (postcard_port) io_sethandler(postcard_port, 1, + NULL, NULL, NULL, postcard_write, NULL, NULL, NULL); + + return postcard_write; +} + + +static void +postcard_close(UNUSED(void *priv)) +{ + if (postcard_port) io_removehandler(postcard_port, 1, + NULL, NULL, NULL, postcard_write, NULL, NULL, NULL); +} + + +const device_t postcard_device = { + "POST Card", + DEVICE_ISA, + 0, + postcard_init, postcard_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/postcard.h b/src/postcard.h new file mode 100644 index 000000000..4bfc912f5 --- /dev/null +++ b/src/postcard.h @@ -0,0 +1,35 @@ +/* + * 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. + * + * Implementation of a port 80h POST diagnostic card. + * + * Version: @(#)postcard.c 1.0.0 2020/03/23 + * + * Author: RichardG, + * Copyright 2020 RichardG. + */ +#ifndef POSTCARD_H +# define POSTCARD_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables. */ +extern const device_t postcard_device; + + +/* Functions. */ + +#ifdef __cplusplus +} +#endif + + +#endif /*BUGGER_H*/ diff --git a/src/printer/png.c b/src/printer/png.c index 752df0080..7d4555bd2 100644 --- a/src/printer/png.c +++ b/src/printer/png.c @@ -52,11 +52,11 @@ #include #define PNG_DEBUG 0 #include -#include "../86box.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "../ui.h" -#include "../video/video.h" +#include "86box.h" +#include "plat.h" +#include "plat_dynld.h" +#include "ui.h" +#include "video.h" #include "png_struct.h" #ifdef _WIN32 diff --git a/src/printer/prt_cpmap.c b/src/printer/prt_cpmap.c index f7c7330f6..8713d0809 100644 --- a/src/printer/prt_cpmap.c +++ b/src/printer/prt_cpmap.c @@ -53,8 +53,8 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" #include "printer.h" diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index c74449ba6..c965285ab 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -56,18 +56,18 @@ #include #include #include FT_FREETYPE_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../pit.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "../ui.h" -#include "../lpt.h" -#include "../video/video.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "pit.h" +#include "plat.h" +#include "plat_dynld.h" +#include "ui.h" +#include "lpt.h" +#include "video.h" #include "png_struct.h" #include "printer.h" #include "prt_devs.h" diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 92ce3d83c..22d5f85b8 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -22,14 +22,14 @@ #include #include #include -#include "../86box.h" -#include "../lang/language.h" -#include "../lpt.h" -#include "../timer.h" -#include "../pit.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "../ui.h" +#include "86box.h" +#include "language.h" +#include "lpt.h" +#include "timer.h" +#include "pit.h" +#include "plat.h" +#include "plat_dynld.h" +#include "ui.h" #include "prt_devs.h" #if defined(_WIN32) && !defined(__WINDOWS__) diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index 404e27c86..9219221f1 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -56,12 +56,12 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../pit.h" -#include "../plat.h" -#include "../lpt.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "pit.h" +#include "plat.h" +#include "lpt.h" #include "printer.h" #include "prt_devs.h" diff --git a/src/rom.c b/src/rom.c index 8d8c23e99..1853fb3f0 100644 --- a/src/rom.c +++ b/src/rom.c @@ -33,8 +33,8 @@ #include "mem.h" #include "rom.h" #include "plat.h" -#include "machine/machine.h" -#include "machine/m_xt_xi8088.h" +#include "machine.h" +#include "m_xt_xi8088.h" #ifdef ENABLE_ROM_LOG @@ -121,7 +121,7 @@ rom_read(uint32_t addr, void *priv) return 0xff; if (addr >= (rom->mapping.base + rom->sz)) return 0xff; - return(rom->rom[addr & rom->mask]); + return(rom->rom[(addr - rom->mapping.base) & rom->mask]); } @@ -139,7 +139,7 @@ rom_readw(uint32_t addr, void *priv) return 0xffff; if (addr >= (rom->mapping.base + rom->sz)) return 0xffff; - return(*(uint16_t *)&rom->rom[addr & rom->mask]); + return(*(uint16_t *)&rom->rom[(addr - rom->mapping.base) & rom->mask]); } @@ -157,7 +157,7 @@ rom_readl(uint32_t addr, void *priv) return 0xffffffff; if (addr >= (rom->mapping.base + rom->sz)) return 0xffffffff; - return(*(uint32_t *)&rom->rom[addr & rom->mask]); + return(*(uint32_t *)&rom->rom[(addr - rom->mapping.base) & rom->mask]); } diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index c23e7f83d..a5a509494 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -24,20 +24,21 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../disk/hdc.h" -#include "../disk/hdd.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "hdc.h" +#include "hdd.h" +#include "plat.h" #include "scsi.h" #include "scsi_device.h" -#include "../cdrom/cdrom.h" -#include "../disk/zip.h" +#include "cdrom.h" +#include "zip.h" #include "scsi_disk.h" #include "scsi_aha154x.h" #include "scsi_buslogic.h" #include "scsi_ncr5380.h" #include "scsi_ncr53c8xx.h" +#include "scsi_spock.h" #ifdef WALTJE # include "scsi_wd33c93.h" #endif @@ -60,7 +61,7 @@ static SCSI_CARD scsi_cards[] = { { "[ISA] Adaptec AHA-154xB", "aha154xb", &aha154xb_device, }, { "[ISA] Adaptec AHA-154xC", "aha154xc", &aha154xc_device, }, { "[ISA] Adaptec AHA-154xCF", "aha154xcf", &aha154xcf_device, }, - { "[ISA] BusLogic BT-542B", "bt542b", &buslogic_542b_1991_device, }, + { "[ISA] BusLogic BT-542B", "bt542b", &buslogic_542b_1991_device, }, { "[ISA] BusLogic BT-542BH", "bt542bh", &buslogic_device, }, { "[ISA] BusLogic BT-545S", "bt545s", &buslogic_545s_device, }, { "[ISA] Longshine LCS-6821N", "lcs6821n", &scsi_lcs6821n_device, }, @@ -72,9 +73,11 @@ static SCSI_CARD scsi_cards[] = { #endif { "[MCA] Adaptec AHA-1640", "aha1640", &aha1640_device, }, { "[MCA] BusLogic BT-640A", "bt640a", &buslogic_640a_device, }, + { "[MCA] IBM PS/2 SCSI", "spock", &spock_device, }, { "[PCI] BusLogic BT-958D", "bt958d", &buslogic_pci_device, }, { "[PCI] NCR 53C810", "ncr53c810", &ncr53c810_pci_device, }, - //{ "[PCI] NCR 53C825A", "ncr53c825a", &ncr53c825a_pci_device, }, + { "[PCI] NCR 53C825A", "ncr53c825a", &ncr53c825a_pci_device, }, + { "[PCI] NCR 53C860", "ncr53c860", &ncr53c860_pci_device, }, { "[PCI] NCR 53C875", "ncr53c875", &ncr53c875_pci_device, }, { "[VLB] BusLogic BT-445S", "bt445s", &buslogic_445s_device, }, { "", "", NULL, }, diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index ef7921a35..b3ec5f4a9 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -24,19 +24,18 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mca.h" -#include "../mem.h" -#include "../mca.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../dma.h" -#include "../pic.h" -#include "../plat.h" -// #include "../cpu/cpu.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mca.h" +#include "mem.h" +#include "mca.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "dma.h" +#include "pic.h" +#include "plat.h" #include "scsi.h" #include "scsi_aha154x.h" #include "scsi_x54x.h" diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 28ecdb612..48d19c9f5 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -27,19 +27,19 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mca.h" -#include "../mem.h" -#include "../mca.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../dma.h" -#include "../pic.h" -#include "../pci.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mca.h" +#include "mem.h" +#include "mca.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "dma.h" +#include "pic.h" +#include "pci.h" +#include "plat.h" #include "scsi.h" #include "scsi_buslogic.h" #include "scsi_device.h" diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 2f87dac04..6527340f9 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)scsi_cdrom.c 1.0.74 2020/01/17 + * Version: @(#)scsi_cdrom.c 1.0.75 2020/03/23 * * Author: Miran Grca, * @@ -23,19 +23,19 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../timer.h" -#include "../device.h" -#include "../piix.h" -#include "../scsi/scsi_device.h" -#include "../nvr.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../sound/sound.h" -#include "../plat.h" -#include "../ui.h" -#include "../cdrom/cdrom.h" +#include "86box.h" +#include "config.h" +#include "timer.h" +#include "device.h" +#include "piix.h" +#include "scsi_device.h" +#include "nvr.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "sound.h" +#include "plat.h" +#include "ui.h" +#include "cdrom.h" #include "scsi_cdrom.h" @@ -139,9 +139,15 @@ const uint8_t scsi_cdrom_command_flags[0x100] = IMPLEMENTED, /* 0xBD */ IMPLEMENTED | CHECK_READY, /* 0xBE */ IMPLEMENTED | CHECK_READY, /* 0xBF */ - 0, 0, /* 0xC0-0xC1 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC0 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC1 */ IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC2 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC3-0xCC */ + 0, /* 0xC3 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC4 */ + 0, /* 0xC5 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC6 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC7 */ + 0, 0, 0, 0, 0, /* 0xC8-0xCC */ IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCD */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCE-0xD9 */ IMPLEMENTED | SCSI_ONLY, /* 0xDA */ @@ -151,6 +157,7 @@ const uint8_t scsi_cdrom_command_flags[0x100] = }; static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | + GPMODEP_DISCONNECT_PAGE | GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | GPMODEP_CAPABILITIES_PAGE | @@ -207,7 +214,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_scsi = { { { 0, 0 }, { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - { 0, 0 }, + { GPMODE_DISCONNECT_PAGE, 0x0e, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -254,7 +261,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = { { { 0, 0 }, { GPMODE_R_W_ERROR_PAGE, 6, 0xFF, 0xFF, 0, 0, 0, 0 }, - { 0, 0 }, + { GPMODE_DISCONNECT_PAGE, 0x0e, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -562,6 +569,10 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) case 0x08: case 0x28: case 0xa8: + /* Round it to the nearest 2048 bytes. */ + dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11; + /* FALLTHROUGH */ + case 0xb9: case 0xbe: /* Make sure total length is not bigger than sum of the lengths of @@ -668,6 +679,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case 0xb8: case 0xb9: case 0xbe: + case 0xc6: + case 0xc7: if (dev->current_cdb[0] == 0x42) dev->callback += 40.0; /* Account for seek time. */ @@ -1536,6 +1549,26 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) toc_format, ide->cylinder, dev->buffer[1]); */ return; + case GPCMD_READ_DISC_INFORMATION_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + scsi_cdrom_buf_alloc(dev, 65536); + + if ((!dev->drv->ops) && ((cdb[1] & 3) == 2)) { + scsi_cdrom_not_ready(dev); + return; + } + + memset(dev->buffer, 0, 4); + + cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); + + len = 4; + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + return; + case GPCMD_READ_CD_OLD: /* IMPORTANT: Convert the command to new read CD for pass through purposes. */ @@ -1976,6 +2009,36 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); break; + case GPCMD_AUDIO_TRACK_SEARCH: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_track_search(dev->drv, pos, cdb[9], cdb[1] & 1); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + + case GPCMD_TOSHIBA_PLAY_AUDIO: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_toshiba_audio_play(dev->drv, pos, cdb[9]); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + case GPCMD_PLAY_AUDIO_10: case GPCMD_PLAY_AUDIO_12: case GPCMD_PLAY_AUDIO_MSF: @@ -1993,13 +2056,13 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) len = (cdb[7] << 8) | cdb[8]; break; case GPCMD_PLAY_AUDIO_12: + /* This is apparently deprecated in the ATAPI spec, and apparently + has been since 1995 (!). Hence I'm having to guess most of it. */ msf = 0; pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; len = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; break; case GPCMD_PLAY_AUDIO_MSF: - /* This is apparently deprecated in the ATAPI spec, and apparently - has been since 1995 (!). Hence I'm having to guess most of it. */ msf = 1; pos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; @@ -2114,6 +2177,37 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) scsi_cdrom_data_command_finish(dev, len, len, len, 0); break; + case GPCMD_READ_SUBCODEQ_PLAYING_STATUS: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = cdb[1] & 0x1f; + + scsi_cdrom_buf_alloc(dev, alloc_length); + + if (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } + + if (!alloc_length) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + break; + } + + len = alloc_length; + + memset(dev->buffer, 0, len); + dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + break; + case GPCMD_READ_DVD_STRUCTURE: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); @@ -2172,6 +2266,13 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) scsi_cdrom_command_complete(dev); break; + + case GPCMD_CADDY_EJECT: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + break; case GPCMD_INQUIRY: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); @@ -2217,10 +2318,15 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[idx++] = 0x01; dev->buffer[idx++] = 0x00; dev->buffer[idx++] = 68; - ide_padstr8(dev->buffer + idx, 8, EMU_NAME); /* Vendor */ + if (dev->drv->bus_type == CDROM_BUS_SCSI) + ide_padstr8(dev->buffer + idx, 8, "TOSHIBA"); /* Vendor */ + else + ide_padstr8(dev->buffer + idx, 8, EMU_NAME); /* Vendor */ idx += 8; - ide_padstr8(dev->buffer + idx, 40, device_identify_ex); /* Product */ - + if (dev->drv->bus_type == CDROM_BUS_SCSI) + ide_padstr8(dev->buffer + idx, 40, "XM6201TASUN32XCD1103"); /* Product */ + else + ide_padstr8(dev->buffer + idx, 40, device_identify_ex); /* Product */ idx += 40; ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Product */ idx += 20; @@ -2253,10 +2359,16 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[6] = 1; /* 16-bit transfers supported */ dev->buffer[7] = 0x20; /* Wide bus supported */ } - - ide_padstr8(dev->buffer + 8, 8, EMU_NAME); /* Vendor */ - ide_padstr8(dev->buffer + 16, 16, device_identify); /* Product */ - ide_padstr8(dev->buffer + 32, 4, EMU_VERSION); /* Revision */ + + if (dev->drv->bus_type == CDROM_BUS_SCSI) { + ide_padstr8(dev->buffer + 8, 8, "TOSHIBA"); /* Vendor */ + ide_padstr8(dev->buffer + 16, 16, "XM6201TASUN32XCD"); /* Product */ + ide_padstr8(dev->buffer + 32, 4, "1103"); /* Revision */ + } else { + ide_padstr8(dev->buffer + 8, 8, EMU_NAME); /* Vendor */ + ide_padstr8(dev->buffer + 16, 16, device_identify); /* Product */ + ide_padstr8(dev->buffer + 32, 4, EMU_VERSION); /* Revision */ + } idx = 36; @@ -2281,13 +2393,21 @@ atapi_out: scsi_cdrom_command_complete(dev); break; +#if 0 case GPCMD_PAUSE_RESUME_ALT: +#endif case GPCMD_PAUSE_RESUME: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); cdrom_audio_pause_resume(dev->drv, cdb[8] & 0x01); scsi_cdrom_command_complete(dev); break; + case GPCMD_STILL: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->drv->cd_status = CD_STATUS_PAUSED; + scsi_cdrom_command_complete(dev); + break; + case GPCMD_SEEK_6: case GPCMD_SEEK_10: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index c0fe14694..61aca0b81 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -20,9 +20,9 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../disk/hdd.h" +#include "86box.h" +#include "device.h" +#include "hdd.h" #include "scsi.h" #include "scsi_device.h" diff --git a/src/scsi/scsi_device.h b/src/scsi/scsi_device.h index 5527dae0e..181e4ea7e 100644 --- a/src/scsi/scsi_device.h +++ b/src/scsi/scsi_device.h @@ -8,7 +8,7 @@ * * Definitions for the generic SCSI device command handler. * - * Version: @(#)scsi_device.h 1.0.17 2019/09/26 + * Version: @(#)scsi_device.h 1.0.18 2020/03/23 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -102,8 +102,14 @@ #define GPCMD_PLAY_CD 0xbc #define GPCMD_MECHANISM_STATUS 0xbd #define GPCMD_READ_CD 0xbe -#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to PCem. */ +#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to 86Box. */ +#define GPCMD_AUDIO_TRACK_SEARCH 0xc0 /* Toshiba Vendor Unique command */ +#define GPCMD_TOSHIBA_PLAY_AUDIO 0xc1 /* Toshiba Vendor Unique command */ #define GPCMD_PAUSE_RESUME_ALT 0xc2 +#define GPCMD_STILL 0xc2 /* Toshiba Vendor Unique command */ +#define GPCMD_CADDY_EJECT 0xc4 /* Toshiba Vendor Unique command */ +#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS 0xc6 /* Toshiba Vendor Unique command */ +#define GPCMD_READ_DISC_INFORMATION_TOSHIBA 0xc7 /* Toshiba Vendor Unique command */ #define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */ #define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 61ee5c43f..a8fcc73bc 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -19,17 +19,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../device.h" -#include "../nvr.h" -#include "../piix.h" -#include "../disk/hdd.h" -#include "../disk/hdc.h" +#include "86box.h" +#include "timer.h" +#include "device.h" +#include "nvr.h" +#include "piix.h" +#include "hdd.h" +#include "hdc.h" #include "scsi_device.h" -#include "../disk/hdc_ide.h" -#include "../plat.h" -#include "../ui.h" +#include "hdc_ide.h" +#include "plat.h" +#include "ui.h" #include "scsi_disk.h" diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index c361c2d14..9a652e8e1 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -27,17 +27,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../dma.h" -#include "../pic.h" -#include "../mca.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "dma.h" +#include "pic.h" +#include "mca.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "plat.h" #include "scsi.h" #include "scsi_device.h" #include "scsi_ncr5380.h" diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 56af023a1..77c9d0143 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -32,25 +32,28 @@ #include #define HAVE_STDARG_H #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../dma.h" -#include "../pic.h" -#include "../mem.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../nvr.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "dma.h" +#include "pic.h" +#include "mem.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "nvr.h" +#include "plat.h" #include "scsi.h" #include "scsi_device.h" #include "scsi_ncr53c8xx.h" #define NCR53C8XX_ROM L"roms/scsi/ncr53c8xx/NCR307.BIN" +#define HA_ID 7 + #define CHIP_810 0x01 #define CHIP_825 0x03 +#define CHIP_860 0x06 #define CHIP_875 0x0f #define NCR_SCNTL0_TRG 0x01 @@ -302,6 +305,10 @@ typedef struct { uint32_t adder; pc_timer_t timer; + +#ifdef USE_WDTR + uint8_t tr_set[16]; +#endif } ncr53c8xx_t; @@ -401,7 +408,7 @@ ncr53c8xx_soft_reset(ncr53c8xx_t *dev) dev->scntl3 = 0; dev->sstat0 = 0; dev->sstat1 = 0; - dev->scid = 7; + dev->scid = HA_ID; dev->sxfer = 0; dev->socl = 0; dev->sdid = 0; @@ -428,13 +435,21 @@ ncr53c8xx_soft_reset(ncr53c8xx_t *dev) if (dev->chip >= CHIP_825) { /* This *IS* a wide SCSI controller, so reset all SCSI devices. */ - for (i = 0; i < 16; i++) + for (i = 0; i < 16; i++) { +#ifdef USE_WDTR + dev->tr_set[i] = 0; +#endif scsi_device_reset(&scsi_devices[i]); + } } else { /* This is *NOT* a wide SCSI controller, so do not touch SCSI devices with ID's >= 8. */ - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { +#ifdef USE_WDTR + dev->tr_set[i] = 0; +#endif scsi_device_reset(&scsi_devices[i]); + } } } @@ -802,9 +817,9 @@ ncr53c8xx_do_wdtr(ncr53c8xx_t *dev, int exponent) ncr53c8xx_log("Target-initiated WDTR (%08X)\n", dev); ncr53c8xx_set_phase(dev, PHASE_MI); dev->msg_action = 4; - ncr53c8xx_add_msg_byte(dev, 0x01); /* EXTENDED MESSAGE */ - ncr53c8xx_add_msg_byte(dev, 0x02); /* EXTENDED MESSAGE LENGTH */ - ncr53c8xx_add_msg_byte(dev, 0x03); /* WIDE DATA TRANSFER REQUEST */ + ncr53c8xx_add_msg_byte(dev, 0x01); /* EXTENDED MESSAGE */ + ncr53c8xx_add_msg_byte(dev, 0x02); /* EXTENDED MESSAGE LENGTH */ + ncr53c8xx_add_msg_byte(dev, 0x03); /* WIDE DATA TRANSFER REQUEST */ ncr53c8xx_add_msg_byte(dev, exponent); /* TRANSFER WIDTH EXPONENT (16-bit) */ } #endif @@ -925,13 +940,14 @@ ncr53c8xx_do_msgout(ncr53c8xx_t *dev, uint8_t id) break; case 3: ncr53c8xx_log("WDTR (ignored)\n"); +#ifdef USE_WDTR + dev->tr_set[dev->sdid] = 1; +#endif if (arg > 0x01) { ncr53c8xx_bad_message(dev, msg); return; } -#ifdef USE_WDTR ncr53c8xx_set_phase(dev, PHASE_CMD); -#endif break; case 5: ncr53c8xx_log("PPR (ignored)\n"); @@ -960,9 +976,14 @@ ncr53c8xx_do_msgout(ncr53c8xx_t *dev, uint8_t id) scsi_device_command_stop(sd); ncr53c8xx_disconnect(dev); break; + case 0x0c: + /* BUS DEVICE RESET message, reset wide transfer request. */ +#ifdef USE_WDTR + dev->tr_set[dev->sdid] = 0; +#endif + /* FALLTHROUGH */ case 0x06: case 0x0e: - case 0x0c: /* clear the current I/O process */ scsi_device_command_stop(sd); ncr53c8xx_disconnect(dev); @@ -977,10 +998,11 @@ ncr53c8xx_do_msgout(ncr53c8xx_t *dev, uint8_t id) dev->current_lun = msg & 7; ncr53c8xx_log("Select LUN %d\n", dev->current_lun); #ifdef USE_WDTR - ncr53c8xx_do_wdtr(dev, 0x01); -#else - ncr53c8xx_set_phase(dev, PHASE_CMD); + if ((dev->chip == CHIP_875) && !dev->tr_set[dev->sdid]) + ncr53c8xx_do_wdtr(dev, 0x01); + else #endif + ncr53c8xx_set_phase(dev, PHASE_CMD); } break; } @@ -2625,6 +2647,7 @@ ncr53c8xx_init(const device_t *info) ncr53c8xx_pci_bar[0].addr_regs[0] = 1; ncr53c8xx_pci_bar[1].addr_regs[0] = 0; dev->chip = info->local; + ncr53c8xx_pci_regs[0x04] = 3; ncr53c8xx_mem_init(dev, 0x0fffff00); @@ -2632,12 +2655,14 @@ ncr53c8xx_init(const device_t *info) dev->has_bios = device_get_config_int("bios"); if (dev->has_bios) - rom_init(&dev->bios, NCR53C8XX_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&dev->bios, NCR53C8XX_ROM, 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (dev->chip >= CHIP_825) { - if (dev->chip == CHIP_875) { dev->chip_rev = 0x04; dev->nvr_path = L"ncr53c875.nvr"; + } else if (dev->chip == CHIP_860) { + dev->chip_rev = 0x04; + dev->nvr_path = L"ncr53c860.nvr"; } else { dev->chip_rev = 0x26; dev->nvr_path = L"ncr53c825a.nvr"; @@ -2654,8 +2679,8 @@ ncr53c8xx_init(const device_t *info) ncr53c8xx_bios_disable(dev); #endif } else { - if (dev->has_bios) - rom_init(&dev->bios, NCR53C8XX_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + /* if (dev->has_bios) + rom_init(&dev->bios, NCR53C8XX_ROM, 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); */ dev->nvr_path = L"ncr53c810.nvr"; } @@ -2715,6 +2740,16 @@ const device_t ncr53c825a_pci_device = ncr53c8xx_pci_config }; +const device_t ncr53c860_pci_device = +{ + "NCR 53c860 (SCSI)", + DEVICE_PCI, + CHIP_860, + ncr53c8xx_init, ncr53c8xx_close, NULL, + NULL, NULL, NULL, + ncr53c8xx_pci_config +}; + const device_t ncr53c875_pci_device = { "NCR 53c875 (SCSI)", diff --git a/src/scsi/scsi_ncr53c8xx.h b/src/scsi/scsi_ncr53c8xx.h index e50e6d954..b84c91c1c 100644 --- a/src/scsi/scsi_ncr53c8xx.h +++ b/src/scsi/scsi_ncr53c8xx.h @@ -27,6 +27,7 @@ extern const device_t ncr53c810_pci_device; extern const device_t ncr53c825a_pci_device; +extern const device_t ncr53c860_pci_device; extern const device_t ncr53c875_pci_device; diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c new file mode 100644 index 000000000..1a26b6b49 --- /dev/null +++ b/src/scsi/scsi_spock.c @@ -0,0 +1,1160 @@ +/* + * 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. + * + * Implementation of the IBM PS/2 SCSI controller with + * cache for MCA only. + * + * Version: @(#)scsi_spock.c 1.0.1 2020/03/23 + * + * Authors: Sarah Walker, + * TheCollector1995, + * + * Copyright 2020 Sarah Walker. + * Copyright 2020 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "dma.h" +#include "pic.h" +#include "mca.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "plat.h" +#include "scsi.h" +#include "scsi_device.h" +#include "scsi_spock.h" + +#define SPOCK_U68_1990_ROM L"roms/scsi/ibm/64f4376.bin" +#define SPOCK_U69_1990_ROM L"roms/scsi/ibm/64f4377.bin" + +#define SPOCK_U68_1991_ROM L"roms/scsi/ibm/92F2244.U68" +#define SPOCK_U69_1991_ROM L"roms/scsi/ibm/92F2245.U69" + +#define SPOCK_TIME (20) + +typedef enum +{ + SCSI_STATE_IDLE, + SCSI_STATE_SELECT, + SCSI_STATE_SELECT_FAILED, + SCSI_STATE_SEND_COMMAND, + SCSI_STATE_END_PHASE +} scsi_state_t; + +#pragma pack(push,1) +typedef struct { + uint16_t pos; + uint16_t pos2; + uint16_t pos3; + uint16_t pos4; + uint16_t pos5; + uint16_t pos6; + uint16_t pos7; + uint16_t pos8; +} get_pos_info_t; + +typedef struct { + uint16_t scb_status; + uint16_t retry_count; + uint32_t residual_byte_count; + uint32_t sg_list_element_addr; + uint16_t device_dep_status_len; + uint16_t cmd_status; + uint16_t error; + uint16_t reserved; + uint16_t cache_info_status; + uint32_t scb_addr; +} get_complete_stat_t; + +typedef struct { + uint32_t sys_buf_addr; + uint32_t sys_buf_byte_count; +} SGE; + +typedef struct { + uint16_t command; + uint16_t enable; + uint32_t lba_addr; + SGE sge; + uint32_t term_status_block_addr; + uint32_t scb_chain_addr; + uint16_t block_count; + uint16_t block_length; +} scb_t; +#pragma pack(pop) + +typedef struct { + rom_t bios_rom; + + int bios_ver; + int irq, irq_inactive; + + uint8_t pos_regs[8]; + + uint8_t basic_ctrl; + uint32_t command; + + uint8_t attention, + attention_pending; + int attention_wait; + + uint8_t cir[4], + cir_pending[4]; + + uint8_t irq_status; + + uint32_t scb_addr; + + uint8_t status; + + get_complete_stat_t get_complete_stat; + get_pos_info_t get_pos_info; + + scb_t scb; + int scb_id; + + int cmd_status; + int cir_status; + + uint8_t pacing; + + uint8_t buf[0x600]; + + struct { + int phys_id; + int lun_id; + } dev_id[SCSI_ID_MAX]; + + uint8_t last_status; + uint8_t cdb[12]; + int cdb_len; + int cdb_id; + uint32_t data_ptr, data_len; + uint8_t temp_cdb[12]; + + int irq_requests[SCSI_ID_MAX]; + + pc_timer_t callback_timer; + + int cmd_timer; + + int scb_state; + int in_reset; + int in_invalid; + + uint64_t temp_period; + double media_period; + + scsi_state_t scsi_state; +} spock_t; + +#define CTRL_RESET (1 << 7) +#define CTRL_DMA_ENA (1 << 1) +#define CTRL_IRQ_ENA (1 << 0) + +#define STATUS_CMD_FULL (1 << 3) +#define STATUS_CMD_EMPTY (1 << 2) +#define STATUS_IRQ (1 << 1) +#define STATUS_BUSY (1 << 0) + +#define ENABLE_PT (1 << 12) + +#define CMD_MASK 0xff3f +#define CMD_ASSIGN 0x040e +#define CMD_DEVICE_INQUIRY 0x1c0b +#define CMD_DMA_PACING_CONTROL 0x040d +#define CMD_FEATURE_CONTROL 0x040c +#define CMD_GET_POS_INFO 0x1c0a +#define CMD_INVALID_412 0x0412 +#define CMD_GET_COMPLETE_STATUS 0x1c07 +#define CMD_FORMAT_UNIT 0x1c16 +#define CMD_READ_DATA 0x1c01 +#define CMD_READ_DEVICE_CAPACITY 0x1c09 +#define CMD_REQUEST_SENSE 0x1c08 +#define CMD_RESET 0x0400 +#define CMD_SEND_OTHER_SCSI 0x241f +#define CMD_UNKNOWN_1C10 0x1c10 +#define CMD_UNKNOWN_1C11 0x1c11 +#define CMD_WRITE_DATA 0x1c02 +#define CMD_VERIFY 0x1c03 + +#define IRQ_TYPE_NONE 0x0 +#define IRQ_TYPE_SCB_COMPLETE 0x1 +#define IRQ_TYPE_SCB_COMPLETE_RETRY 0x5 +#define IRQ_TYPE_ADAPTER_HW_FAILURE 0x7 +#define IRQ_TYPE_IMM_CMD_COMPLETE 0xa +#define IRQ_TYPE_COMMAND_FAIL 0xc +#define IRQ_TYPE_COMMAND_ERROR 0xe +#define IRQ_TYPE_SW_SEQ_ERROR 0xf +#define IRQ_TYPE_RESET_COMPLETE 0x10 + + +#ifdef ENABLE_SPOCK_LOG +int spock_do_log = ENABLE_SPOCK_LOG; + + +static void +spock_log(const char *fmt, ...) +{ + va_list ap; + + if (spock_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define spock_log(fmt, ...) +#endif + +static void +spock_rethink_irqs(spock_t *scsi) +{ + int irq_pending = 0; + int c; + + if (!scsi->irq_status) { + for (c = 0; c < SCSI_ID_MAX; c++) { + if (scsi->irq_requests[c] != IRQ_TYPE_NONE) { + /* Found IRQ */ + scsi->irq_status = c | (scsi->irq_requests[c] << 4); + spock_log("Found IRQ: status = %02x\n", scsi->irq_status); + scsi->status |= STATUS_IRQ; + irq_pending = 1; + break; + } + } + } else + irq_pending = 1; + + if (scsi->basic_ctrl & CTRL_IRQ_ENA) { + if (irq_pending) { + spock_log("IRQ issued\n"); + scsi->irq_inactive = 0; + picint(1 << scsi->irq); + } else { + /* No IRQs pending, clear IRQ state */ + spock_log("IRQ cleared\n"); + scsi->irq_status = 0; + scsi->irq_inactive = 1; + scsi->status &= ~STATUS_IRQ; + picintc(1 << scsi->irq); + } + } else { + spock_log("IRQ disabled\n"); + picintc(1 << scsi->irq); + } +} + +static __inline void +spock_set_irq(spock_t *scsi, int id, int type) +{ + spock_log("spock_set_irq id=%i type=%x %02x\n", id, type, scsi->irq_status); + scsi->irq_requests[id] = type; + if (!scsi->irq_status) /* Don't change IRQ status if one is currently being processed */ + spock_rethink_irqs(scsi); +} + +static __inline void +spock_clear_irq(spock_t *scsi, int id) +{ + spock_log("spock_clear_irq id=%i\n", id); + scsi->irq_requests[id] = IRQ_TYPE_NONE; + spock_rethink_irqs(scsi); +} + +static void +spock_add_to_period(spock_t *scsi, int TransferLength) +{ + scsi->temp_period += (uint64_t) TransferLength; +} + +static void +spock_write(uint16_t port, uint8_t val, void *p) +{ + spock_t *scsi = (spock_t *)p; + + spock_log("spock_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc); + + switch (port & 7) { + case 0: case 1: case 2: case 3: /*Command Interface Register*/ + scsi->cir_pending[port & 3] = val; + if (port & 2) + scsi->cir_status |= 2; + else + scsi->cir_status |= 1; + break; + + case 4: /*Attention Register*/ + scsi->attention_pending = val; + scsi->attention_wait = 2; + scsi->status |= STATUS_BUSY; + break; + + case 5: /*Basic Control Register*/ + if ((scsi->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { + spock_log("Spock: SCSI reset and busy\n"); + scsi->in_reset = 1; + scsi->cmd_timer = SPOCK_TIME * 2; + scsi->status |= STATUS_BUSY; + } + scsi->basic_ctrl = val; + spock_rethink_irqs(scsi); + break; + } +} + +static void +spock_writew(uint16_t port, uint16_t val, void *p) +{ + spock_t *scsi = (spock_t *)p; + + switch (port & 7) { + case 0: /*Command Interface Register*/ + scsi->cir_pending[0] = val & 0xff; + scsi->cir_pending[1] = val >> 8; + scsi->cir_status |= 1; + break; + case 2: /*Command Interface Register*/ + scsi->cir_pending[2] = val & 0xff; + scsi->cir_pending[3] = val >> 8; + scsi->cir_status |= 2; + break; + } + + spock_log("spock_writew: port=%04x val=%04x\n", port, val); +} + + +static uint8_t +spock_read(uint16_t port, void *p) +{ + spock_t *scsi = (spock_t *)p; + uint8_t temp = 0xff; + + switch (port & 7) { + case 0: case 1: case 2: case 3: /*Command Interface Register*/ + temp = scsi->cir_pending[port & 3]; + break; + + case 4: /*Attention Register*/ + temp = scsi->attention_pending; + break; + case 5: /*Basic Control Register*/ + temp = scsi->basic_ctrl; + break; + case 6: /*IRQ status*/ + temp = scsi->irq_status; + break; + case 7: /*Basic Status Register*/ + temp = scsi->status; + if (scsi->cir_status == 0) { + spock_log("Status Cmd Empty\n"); + temp |= STATUS_CMD_EMPTY; + } + if (scsi->cir_status == 3) { + spock_log("Status Cmd Full\n"); + temp |= STATUS_CMD_FULL; + } + break; + } + + spock_log("spock_read: port=%04x val=%02x %04x(%05x):%04x %02x\n", port, temp, CS, cs, cpu_state.pc, BH); + return temp; +} + +static uint16_t +spock_readw(uint16_t port, void *p) +{ + spock_t *scsi = (spock_t *)p; + uint16_t temp = 0xffff; + + switch (port & 7) { + case 0: /*Command Interface Register*/ + temp = scsi->cir_pending[0] | (scsi->cir_pending[1] << 8); + break; + case 2: /*Command Interface Register*/ + temp = scsi->cir_pending[2] | (scsi->cir_pending[3] << 8); + break; + } + + spock_log("spock_readw: port=%04x val=%04x\n", port, temp); + return temp; +} + +static void +spock_rd_sge(spock_t *scsi, uint32_t Address, SGE *SG) +{ + DMAPageRead(Address, (uint8_t *)SG, sizeof(SGE)); + spock_add_to_period(scsi, sizeof(SGE)); +} + +static int +spock_get_len(spock_t *scsi, scb_t *scb) +{ + uint32_t DataToTransfer = 0, i = 0; + + spock_log("Data Buffer write: length %d, pointer 0x%04X\n", + scsi->data_len, scsi->data_ptr); + + if (!scsi->data_len) + return(0); + + if (scb->enable & ENABLE_PT) { + for (i = 0; i < scsi->data_len; i += 8) { + spock_rd_sge(scsi, scsi->data_ptr + i, &scb->sge); + + DataToTransfer += scb->sge.sys_buf_byte_count; + } + return(DataToTransfer); + } else { + return(scsi->data_len); + } +} + +static void +spock_process_imm_cmd(spock_t *scsi) +{ + int i; + int adapter_id, phys_id, lun_id; + + switch (scsi->command & CMD_MASK) { + case CMD_ASSIGN: + adapter_id = (scsi->command >> 16) & 15; + phys_id = (scsi->command >> 20) & 7; + lun_id = (scsi->command >> 24) & 7; + + if (adapter_id == 15) { + if (phys_id == 7) /*Device 15 always adapter*/ + spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + else /*Can not re-assign device 15 (always adapter)*/ + spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL); + } else { + if (scsi->command & (1 << 23)) { + spock_log("Physical Device Number -1\n"); + scsi->dev_id[adapter_id].phys_id = -1; + spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + } else if (phys_id == 7) { /*Can not assign adapter*/ + spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL); + } else { + scsi->dev_id[adapter_id].phys_id = phys_id; + scsi->dev_id[adapter_id].lun_id = lun_id; + spock_log("Assign: adapter dev=%x scsi ID=%i LUN=%i\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id); + spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + } + } + break; + + case CMD_DMA_PACING_CONTROL: + scsi->pacing = scsi->cir[2]; + spock_log("Pacing control: %i\n", scsi->pacing); + spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; + + case CMD_FEATURE_CONTROL: + spock_log("Feature control: timeout=%is d-rate=%i\n", (scsi->command >> 16) & 0x1fff, scsi->command >> 29); + spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; + + case CMD_INVALID_412: + spock_log("Invalid 412\n"); + spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; + + case CMD_RESET: + spock_log("Reset Command\n"); + if ((scsi->attention & 15) == 15) { /*Adapter reset*/ + for (i = 0; i < 7; i++) + scsi_device_reset(&scsi_devices[i]); + spock_log("Adapter Reset\n"); + + scsi->scb_state = 0; + } + spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; + + default: + fatal("scsi_callback: Bad command %02x\n", scsi->command); + break; + } +} + +static void +spock_execute_cmd(spock_t *scsi, scb_t *scb) +{ + int c; + int old_scb_state; + + if (scsi->in_reset) { + spock_log("Reset type = %d\n", scsi->in_reset); + + scsi->status &= ~STATUS_BUSY; + scsi->irq_status = 0; + + for (c = 0; c < SCSI_ID_MAX; c++) + spock_clear_irq(scsi, c); + + if (scsi->in_reset == 1) { + scsi->basic_ctrl |= CTRL_IRQ_ENA; + spock_set_irq(scsi, 0x0f, IRQ_TYPE_RESET_COMPLETE); + } else + spock_set_irq(scsi, 0x0f, IRQ_TYPE_RESET_COMPLETE); + + /*Reset device mappings*/ + for (c = 0; c < 7; c++) { + scsi->dev_id[c].phys_id = c; + scsi->dev_id[c].lun_id = 0; + } + for (; c < (SCSI_ID_MAX-1); c++) + scsi->dev_id[c].phys_id = -1; + + scsi->in_reset = 0; + return; + } + + if (scsi->in_invalid) { + spock_log("Invalid command\n"); + spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_ERROR); + scsi->in_invalid = 0; + return; + } + + do + { + old_scb_state = scsi->scb_state; + + switch (scsi->scb_state) { + case 0: /* Idle */ + break; + + case 1: /* Select */ + if (scsi->dev_id[scsi->scb_id].phys_id == -1) { + uint16_t term_stat_block_addr7 = (0xe << 8) | 0; + uint16_t term_stat_block_addr8 = (0xa << 8) | 0; + + spock_log("Start failed, SCB ID = %d\n", scsi->scb_id); + spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); + scsi->scb_state = 0; + DMAPageWrite(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2); + DMAPageWrite(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2); + break; + } + + DMAPageRead(scsi->scb_addr, (uint8_t *)&scb->command, 2); + DMAPageRead(scsi->scb_addr + 2, (uint8_t *)&scb->enable, 2); + DMAPageRead(scsi->scb_addr + 4, (uint8_t *)&scb->lba_addr, 4); + DMAPageRead(scsi->scb_addr + 8, (uint8_t *)&scb->sge.sys_buf_addr, 4); + DMAPageRead(scsi->scb_addr + 12, (uint8_t *)&scb->sge.sys_buf_byte_count, 4); + DMAPageRead(scsi->scb_addr + 16, (uint8_t *)&scb->term_status_block_addr, 4); + DMAPageRead(scsi->scb_addr + 20, (uint8_t *)&scb->scb_chain_addr, 4); + DMAPageRead(scsi->scb_addr + 24, (uint8_t *)&scb->block_count, 2); + DMAPageRead(scsi->scb_addr + 26, (uint8_t *)&scb->block_length, 2); + + spock_log("SCB : \n" + " Command = %04x\n" + " Enable = %04x\n" + " LBA addr = %08x\n" + " System buffer addr = %08x\n" + " System buffer byte count = %08x\n" + " Terminate status block addr = %08x\n" + " SCB chain address = %08x\n" + " Block count = %04x\n" + " Block length = %04x\n", + scb->command, scb->enable, scb->lba_addr, + scb->sge.sys_buf_addr, scb->sge.sys_buf_byte_count, + scb->term_status_block_addr, scb->scb_chain_addr, + scb->block_count, scb->block_length); + + if (scb->command == 0x245f) { /*Issued by NT October 1991 and December 1991 (Undocumented version of Send Other SCSI?)*/ + spock_log("Send Other SCSI (BIOS?)\n"); + scb->command = CMD_SEND_OTHER_SCSI; + } + + switch (scb->command & CMD_MASK) { + case CMD_GET_COMPLETE_STATUS: + { + spock_log("Get Complete Status\n"); + get_complete_stat_t *get_complete_stat = &scsi->get_complete_stat; + + get_complete_stat->scb_status = 0x201; + get_complete_stat->retry_count = 0; + get_complete_stat->residual_byte_count = 0; + get_complete_stat->sg_list_element_addr = 0; + get_complete_stat->device_dep_status_len = 0x0c; + get_complete_stat->cmd_status = scsi->cmd_status << 8; + get_complete_stat->error = 0; + get_complete_stat->reserved = 0; + get_complete_stat->cache_info_status = 0; + get_complete_stat->scb_addr = scsi->scb_addr; + + DMAPageWrite(scb->sge.sys_buf_addr, (uint8_t *)&get_complete_stat->scb_status, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 2, (uint8_t *)&get_complete_stat->retry_count, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 4, (uint8_t *)&get_complete_stat->residual_byte_count, 4); + DMAPageWrite(scb->sge.sys_buf_addr + 8, (uint8_t *)&get_complete_stat->sg_list_element_addr, 4); + DMAPageWrite(scb->sge.sys_buf_addr + 12, (uint8_t *)&get_complete_stat->device_dep_status_len, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 14, (uint8_t *)&get_complete_stat->cmd_status, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 16, (uint8_t *)&get_complete_stat->error, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 18, (uint8_t *)&get_complete_stat->reserved, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 20, (uint8_t *)&get_complete_stat->cache_info_status, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 22, (uint8_t *)&get_complete_stat->scb_addr, 4); + scsi->scb_state = 3; + } + break; + + case CMD_UNKNOWN_1C10: + spock_log("Unknown 1C10\n"); + DMAPageRead(scb->sge.sys_buf_addr, scsi->buf, scb->sge.sys_buf_byte_count); + scsi->scb_state = 3; + break; + + case CMD_UNKNOWN_1C11: + spock_log("Unknown 1C11\n"); + DMAPageWrite(scb->sge.sys_buf_addr, scsi->buf, scb->sge.sys_buf_byte_count); + scsi->scb_state = 3; + break; + + case CMD_GET_POS_INFO: + { + spock_log("Get POS Info\n"); + get_pos_info_t *get_pos_info = &scsi->get_pos_info; + + get_pos_info->pos = 0x8eff; + get_pos_info->pos2 = scsi->pos_regs[3] | (scsi->pos_regs[2] << 8); + get_pos_info->pos3 = 0x0e | (scsi->pos_regs[4] << 8); + get_pos_info->pos4 = 1 << 12; + get_pos_info->pos4 = (7 << 8) | 8; + get_pos_info->pos5 = (16 << 8) | scsi->pacing; + get_pos_info->pos6 = (30 << 8) | 1; + get_pos_info->pos7 = 0; + get_pos_info->pos8 = 0; + + DMAPageWrite(scb->sge.sys_buf_addr, (uint8_t *)&get_pos_info->pos, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 2, (uint8_t *)&get_pos_info->pos2, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 4, (uint8_t *)&get_pos_info->pos3, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 6, (uint8_t *)&get_pos_info->pos4, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 8, (uint8_t *)&get_pos_info->pos5, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 10, (uint8_t *)&get_pos_info->pos6, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 12, (uint8_t *)&get_pos_info->pos7, 2); + DMAPageWrite(scb->sge.sys_buf_addr + 14, (uint8_t *)&get_pos_info->pos8, 2); + scsi->scb_state = 3; + } + break; + + case CMD_DEVICE_INQUIRY: + spock_log("Device Inquiry\n"); + scsi->cdb[0] = GPCMD_INQUIRY; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = 0; /*Page code*/ + scsi->cdb[3] = 0; + scsi->cdb[4] = scb->sge.sys_buf_byte_count; /*Allocation length*/ + scsi->cdb[5] = 0; /*Control*/ + scsi->cdb_len = 6; + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->data_ptr = scb->sge.sys_buf_addr; + scsi->data_len = scb->sge.sys_buf_byte_count; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; + + case CMD_SEND_OTHER_SCSI: + spock_log("Send Other SCSI\n"); + DMAPageRead(scsi->scb_addr + 0x18, scsi->cdb, 12); + scsi->cdb[1] = (scsi->cdb[1] & 0x1f) | (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/ + scsi->cdb_len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6; + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; + + case CMD_READ_DEVICE_CAPACITY: + spock_log("Device Capacity\n"); + scsi->cdb[0] = GPCMD_READ_CDROM_CAPACITY; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = 0; /*LBA*/ + scsi->cdb[3] = 0; + scsi->cdb[4] = 0; + scsi->cdb[5] = 0; + scsi->cdb[6] = 0; /*Reserved*/ + scsi->cdb[7] = 0; + scsi->cdb[8] = 0; + scsi->cdb[9] = 0; /*Control*/ + scsi->cdb_len = 10; + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; + + case CMD_READ_DATA: + spock_log("Device Read Data\n"); + scsi->cdb[0] = GPCMD_READ_10; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb[5] = scb->lba_addr & 0xff; + scsi->cdb[6] = 0; /*Reserved*/ + scsi->cdb[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb[8] = scb->block_count & 0xff; + scsi->cdb[9] = 0; /*Control*/ + scsi->cdb_len = 10; + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; + + case CMD_WRITE_DATA: + spock_log("Device Write Data\n"); + scsi->cdb[0] = GPCMD_WRITE_10; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb[5] = scb->lba_addr & 0xff; + scsi->cdb[6] = 0; /*Reserved*/ + scsi->cdb[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb[8] = scb->block_count & 0xff; + scsi->cdb[9] = 0; /*Control*/ + scsi->cdb_len = 10; + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; + + case CMD_VERIFY: + spock_log("Device Verify\n"); + scsi->cdb[0] = GPCMD_VERIFY_10; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb[5] = scb->lba_addr & 0xff; + scsi->cdb[6] = 0; /*Reserved*/ + scsi->cdb[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb[8] = scb->block_count & 0xff; + scsi->cdb[9] = 0; /*Control*/ + scsi->cdb_len = 10; + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->data_len = 0; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; + + case CMD_REQUEST_SENSE: + spock_log("Device Request Sense\n"); + scsi->cdb[0] = GPCMD_REQUEST_SENSE; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = 0; + scsi->cdb[3] = 0; + scsi->cdb[4] = scb->sge.sys_buf_byte_count; /*Allocation length*/ + scsi->cdb[5] = 0; + scsi->cdb_len = 6; + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; + } + break; + + case 2: /* Wait */ + if (scsi->scsi_state == SCSI_STATE_IDLE) { + if (scsi->last_status == SCSI_STATUS_OK) { + scsi->scb_state = 3; + spock_log("Status is Good on device ID %d\n", scsi->cdb_id); + } else if (scsi->last_status == SCSI_STATUS_CHECK_CONDITION) { + uint16_t term_stat_block_addr7 = (0xc << 8) | 2; + uint16_t term_stat_block_addr8 = 0x20; + uint16_t term_stat_block_addrb = scsi->scb_addr & 0xffff; + uint16_t term_stat_block_addrc = scsi->scb_addr >> 16; + + spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); + scsi->scb_state = 0; + spock_log("Status Check Condition on device ID %d\n", scsi->cdb_id); + DMAPageWrite(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2); + DMAPageWrite(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2); + DMAPageWrite(scb->term_status_block_addr + 0xb*2, (uint8_t *)&term_stat_block_addrb, 2); + DMAPageWrite(scb->term_status_block_addr + 0xc*2, (uint8_t *)&term_stat_block_addrc, 2); + } + } else if (scsi->scsi_state == SCSI_STATE_SELECT_FAILED) { + uint16_t term_stat_block_addr7 = (0xc << 8) | 2; + uint16_t term_stat_block_addr8 = 0x10; + spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); + scsi->scb_state = 0; + DMAPageWrite(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2); + DMAPageWrite(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2); + } + break; + + case 3: /* Complete */ + if (scb->enable & 1) { + scsi->scb_state = 1; + scsi->scb_addr = scb->scb_chain_addr; + spock_log("Next SCB - %08x\n", scsi->scb_addr); + } else { + spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_SCB_COMPLETE); + scsi->scb_state = 0; + spock_log("Complete SCB\n"); + } + break; + } + } while (scsi->scb_state != old_scb_state); +} + +static void +spock_process_scsi(spock_t *scsi, scb_t *scb) +{ + int c; + double p; + scsi_device_t *sd; + + switch (scsi->scsi_state) { + case SCSI_STATE_IDLE: + break; + + case SCSI_STATE_SELECT: + if ((scsi->cdb_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[scsi->cdb_id])) { + scsi->scsi_state = SCSI_STATE_SEND_COMMAND; + spock_log("Device selected at ID %i\n", scsi->cdb_id); + break; + } else { + spock_log("Device selection failed at ID %i\n", scsi->cdb_id); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + if (!scsi->cmd_timer) { + spock_log("Callback to reset\n"); + scsi->cmd_timer = 1; + } + spock_add_to_period(scsi, 1); + } + break; + + case SCSI_STATE_SELECT_FAILED: + break; + + case SCSI_STATE_SEND_COMMAND: + sd = &scsi_devices[scsi->cdb_id]; + memset(scsi->temp_cdb, 0x00, 12); + + if (scsi->cdb_len < 12) { + memcpy(scsi->temp_cdb, scsi->cdb, + scsi->cdb_len); + spock_add_to_period(scsi, scsi->cdb_len); + } else { + memcpy(scsi->temp_cdb, scsi->cdb, + 12); + spock_add_to_period(scsi, 12); + } + + scsi->data_ptr = scb->sge.sys_buf_addr; + scsi->data_len = scb->sge.sys_buf_byte_count; + + sd->buffer_length = spock_get_len(scsi, scb); + + scsi_device_command_phase0(sd, scsi->temp_cdb); + spock_log("SCSI ID %i: Command %02X: CDB1 = %02x, LUN = %i, Buffer Length %i, SCSI Phase %02X\n", scsi->cdb_id, scsi->temp_cdb[0], scsi->temp_cdb[1], scsi->dev_id[scsi->scb_id].lun_id, sd->buffer_length, sd->phase); + + if (sd->phase != SCSI_PHASE_STATUS && sd->buffer_length > 0) { + p = scsi_device_get_callback(sd); + if (p <= 0.0) + spock_add_to_period(scsi, sd->buffer_length); + else + scsi->media_period += p; + + if (scb->enable & ENABLE_PT) { + int32_t buflen = sd->buffer_length; + int sg_pos = 0; + uint32_t DataTx = 0; + uint32_t Address; + + if (scb->sge.sys_buf_byte_count > 0) { + for (c = 0; c < scsi->data_len; c += 8) { + spock_rd_sge(scsi, scsi->data_ptr + c, &scb->sge); + + Address = scb->sge.sys_buf_addr; + DataTx = MIN((int) scb->sge.sys_buf_byte_count, buflen); + + if ((sd->phase == SCSI_PHASE_DATA_IN) && DataTx) { + spock_log("Writing S/G segment %i: length %i, pointer %08X\n", c, DataTx, Address); + DMAPageWrite(Address, &sd->sc->temp_buffer[sg_pos], DataTx); + } else if ((sd->phase == SCSI_PHASE_DATA_OUT) && DataTx) { + spock_log("Reading S/G segment %i: length %i, pointer %08X\n", c, DataTx, Address); + DMAPageRead(Address, &sd->sc->temp_buffer[sg_pos], DataTx); + } + + sg_pos += scb->sge.sys_buf_byte_count; + buflen -= scb->sge.sys_buf_byte_count; + + if (buflen < 0) + buflen = 0; + } + } + } else { + if (sd->phase == SCSI_PHASE_DATA_IN) { + DMAPageWrite(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int)scsi->data_len)); + } else if (sd->phase == SCSI_PHASE_DATA_OUT) + DMAPageRead(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int)scsi->data_len)); + } + + scsi_device_command_phase1(sd); + } + scsi->last_status = sd->status; + scsi->scsi_state = SCSI_STATE_END_PHASE; + break; + + case SCSI_STATE_END_PHASE: + scsi->scsi_state = SCSI_STATE_IDLE; + + spock_log("State to idle\n"); + if (!scsi->cmd_timer) { + scsi->cmd_timer = 1; + } + spock_add_to_period(scsi, 1); + break; + } +} + +static void +spock_callback(void *priv) +{ + double period; + spock_t *scsi = (spock_t *)priv; + scb_t *scb = &scsi->scb; + + scsi->temp_period = 0; + scsi->media_period = 0.0; + + if (scsi->cmd_timer) { + scsi->cmd_timer--; + if (!scsi->cmd_timer) { + spock_execute_cmd(scsi, scb); + } + } + + if (scsi->attention_wait && + (scsi->scb_state == 0 || (scsi->attention_pending & 0xf0) == 0xe0)) { + scsi->attention_wait--; + if (!scsi->attention_wait) { + scsi->attention = scsi->attention_pending; + scsi->status &= ~STATUS_BUSY; + scsi->cir[0] = scsi->cir_pending[0]; + scsi->cir[1] = scsi->cir_pending[1]; + scsi->cir[2] = scsi->cir_pending[2]; + scsi->cir[3] = scsi->cir_pending[3]; + scsi->cir_status = 0; + + switch (scsi->attention >> 4) { + case 1: /*Immediate command*/ + scsi->cmd_status = 0x0a; + scsi->command = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); + switch (scsi->command & CMD_MASK) { + case CMD_ASSIGN: + case CMD_DMA_PACING_CONTROL: + case CMD_FEATURE_CONTROL: + case CMD_INVALID_412: + case CMD_RESET: + spock_process_imm_cmd(scsi); + break; + } + break; + + case 3: case 4: case 0x0f: /*Start SCB*/ + scsi->cmd_status = 1; + scsi->scb_addr = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); + scsi->scb_id = scsi->attention & 0x0f; + scsi->cmd_timer = SPOCK_TIME * 2; + spock_log("Start SCB at %08x\n", scsi->scb_addr); + scsi->scb_state = 1; + break; + + case 5: /*Invalid*/ + case 0x0a: /*Invalid*/ + scsi->in_invalid = 1; + scsi->cmd_timer = SPOCK_TIME * 2; + break; + + case 0x0e: /*EOI*/ + scsi->irq_status = 0; + spock_clear_irq(scsi, scsi->attention & 0xf); + break; + } + } + } + + spock_process_scsi(scsi, scb); + + period = 0.2 * ((double) scsi->temp_period); + timer_on(&scsi->callback_timer, (scsi->media_period + period + 10.0), 0); + spock_log("Temporary period: %lf us (%" PRIi64 " periods)\n", scsi->callback_timer.period, scsi->temp_period); +} + +static void +spock_mca_write(int port, uint8_t val, void *priv) +{ + spock_t *scsi = (spock_t *)priv; + + if (port < 0x102) + return; + + spock_log("spock_mca_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc); + + io_removehandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, spock_read, spock_readw, NULL, spock_write, spock_writew, NULL, scsi); + mem_mapping_disable(&scsi->bios_rom.mapping); + + scsi->pos_regs[port & 7] = val; + + spock_log("SCSI pos reg write POS2 = %02x, POS3 = %02x, POS4 = %02x\n", scsi->pos_regs[2], scsi->pos_regs[3], scsi->pos_regs[4]); + + if (scsi->pos_regs[2] & 1) { + spock_log("spock scsi io = %04x\n", (((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540); + io_sethandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, spock_read, spock_readw, NULL, spock_write, spock_writew, NULL, scsi); + if ((scsi->pos_regs[2] >> 4) == 0x0f) + mem_mapping_disable(&scsi->bios_rom.mapping); + else { + spock_log("Spock BIOS segment select (hex val) = %02x, enabled bios area is %s\n", scsi->pos_regs[2] >> 4, (scsi->pos_regs[4] & 0x80) ? "32KB" : "16KB"); + mem_mapping_set_addr(&scsi->bios_rom.mapping, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000, 0x8000); + } + } +} + +static uint8_t +spock_mca_read(int port, void *priv) +{ + spock_t *scsi = (spock_t *)priv; + + spock_log("spock_mca_read: port=%04x %02x %04x:%04x\n", port, scsi->pos_regs[port & 7], CS,cpu_state.pc); + + return scsi->pos_regs[port & 7]; +} + +static uint8_t +spock_mca_feedb(void *priv) +{ + spock_t *scsi = (spock_t *)priv; + + return (scsi->pos_regs[2] & 0x01); +} + +static void +spock_mca_reset(void *priv) +{ + spock_t *scsi = (spock_t *)priv; + int i; + + scsi->in_reset = 2; + scsi->cmd_timer = SPOCK_TIME * 50; + scsi->status = STATUS_BUSY; + scsi->scsi_state = SCSI_STATE_IDLE; + scsi->scb_state = 0; + scsi->in_invalid = 0; + scsi->attention_wait = 0; + scsi->basic_ctrl = 0; + + /* Reset all devices on controller reset. */ + for (i = 0; i < 7; i++) + scsi_device_reset(&scsi_devices[i]); +} + +static void * +spock_init(const device_t *info) +{ + int c; + spock_t *scsi = malloc(sizeof(spock_t)); + memset(scsi, 0x00, sizeof(spock_t)); + + scsi->irq = 14; + + scsi->bios_ver = device_get_config_int("bios_ver"); + + if (scsi->bios_ver) + rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1991_ROM, SPOCK_U69_1991_ROM, + 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL); + else + rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1990_ROM, SPOCK_U69_1990_ROM, + 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL); + + mem_mapping_disable(&scsi->bios_rom.mapping); + + scsi->pos_regs[0] = 0xff; + scsi->pos_regs[1] = 0x8e; + // mca_add(spock_mca_read, spock_mca_write, spock_mca_feedb, spock_mca_reset, scsi); + mca_add(spock_mca_read, spock_mca_write, spock_mca_feedb, scsi); + + scsi->in_reset = 2; + scsi->cmd_timer = SPOCK_TIME * 50; + scsi->status = STATUS_BUSY; + + for (c = 0; c < (SCSI_ID_MAX-1); c++) + scsi->dev_id[c].phys_id = -1; + + scsi->dev_id[SCSI_ID_MAX-1].phys_id = 7; + + timer_add(&scsi->callback_timer, spock_callback, scsi, 1); + scsi->callback_timer.period = 10.0; + timer_set_delay_u64(&scsi->callback_timer, (uint64_t) (scsi->callback_timer.period * ((double) TIMER_USEC))); + + return scsi; +} + +static void +spock_close(void *p) +{ + spock_t *scsi = (spock_t *)p; + + if (scsi) { + free(scsi); + scsi = NULL; + } +} + +static int +spock_available(void) +{ + return rom_present(SPOCK_U68_1991_ROM) && rom_present(SPOCK_U69_1991_ROM) && + rom_present(SPOCK_U68_1990_ROM) && rom_present(SPOCK_U69_1990_ROM); +} + +static const device_config_t spock_rom_config[] = { + { + "bios_ver", "BIOS Version", CONFIG_SELECTION, "", 1, + { + { + "1991 BIOS (>1GB)", 1 + }, + { + "1990 BIOS", 0 + }, + { + "" + } + }, + }, + { + "", "", -1 + } +}; + +const device_t spock_device = +{ + "IBM PS/2 SCSI Adapter (Spock)", + DEVICE_MCA, + 0, + spock_init, spock_close, NULL, + spock_available, + NULL, NULL, + spock_rom_config +}; diff --git a/src/sound/snd_wss.h b/src/scsi/scsi_spock.h similarity index 57% rename from src/sound/snd_wss.h rename to src/scsi/scsi_spock.h index 77fc9f08c..bf064421c 100644 --- a/src/sound/snd_wss.h +++ b/src/scsi/scsi_spock.h @@ -6,20 +6,20 @@ * * This file is part of the 86Box distribution. * - * Windows Sound System emulation. + * Implementation of the IBM PS/2 SCSI controller with + * cache for MCA only. * - * Version: @(#)snd_wss.c 1.0.0 2018/08/11 + * Version: @(#)scsi_spock.h 1.0.0 2020/03/10 * * Authors: Sarah Walker, * TheCollector1995, * - * Copyright 2012-2018 Sarah Walker. - * Copyright 2018 TheCollector1995. + * Copyright 2020 Sarah Walker. + * Copyright 2020 TheCollector1995. */ -#ifndef SND_WSS_H -# define SND_WSS_H - -extern const device_t wss_device; -extern const device_t ncr_business_audio_device; +#ifndef SCSI_SPOCK_H +# define SCSI_SPOCK_H -#endif /*SND_WSS_H*/ +extern const device_t spock_device; + +#endif /*SCSI_SPOCK_H*/ \ No newline at end of file diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 8c8a5985d..f41d013a0 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -28,18 +28,18 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../dma.h" -#include "../pic.h" -#include "../pci.h" -#include "../mca.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "dma.h" +#include "pic.h" +#include "pci.h" +#include "mca.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "plat.h" #include "scsi.h" #include "scsi_device.h" #include "scsi_aha154x.h" diff --git a/src/serial.c b/src/serial.c index 51297a64b..7d35466a7 100644 --- a/src/serial.c +++ b/src/serial.c @@ -10,15 +10,15 @@ * * Now passes all the AMIDIAG tests. * - * Version: @(#)serial.h 1.0.13 2019/10/31 + * Version: @(#)serial.h 1.0.14 2020/01/24 * * Author: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #include #include @@ -30,8 +30,8 @@ #include "86box.h" #include "device.h" #include "timer.h" -#include "machine/machine.h" -#include "io.h" +#include "machine.h" +#include "86box_io.h" #include "pic.h" #include "mem.h" #include "rom.h" @@ -95,7 +95,7 @@ serial_transmit_period(serial_t *dev) ddlab = (double) dev->dlab; /* Bit period based on DLAB. */ - dev->transmit_period = (16000000.0 * ddlab) / 1843200.0; + dev->transmit_period = (16000000.0 * ddlab) / dev->clock_src; } @@ -337,6 +337,16 @@ serial_reset_fifo(serial_t *dev) } +void +serial_set_clock_src(serial_t *dev, double clock_src) +{ + dev->clock_src = clock_src; + + serial_transmit_period(dev); + serial_update_speed(dev); +} + + void serial_write(uint16_t addr, uint8_t val, void *p) { @@ -676,6 +686,7 @@ serial_init(const device_t *info) /* Default to 1200,N,7. */ dev->dlab = 96; dev->fcr = 0x06; + dev->clock_src = 1843200.0; serial_transmit_period(dev); timer_add(&dev->transmit_timer, serial_transmit_timer, dev, 0); timer_add(&dev->timeout_timer, serial_timeout_timer, dev, 0); diff --git a/src/serial.h b/src/serial.h index 73238c87b..7ec03dc66 100644 --- a/src/serial.h +++ b/src/serial.h @@ -8,15 +8,15 @@ * * Definitions for the NS8250/16450/16550 UART emulation. * - * Version: @(#)serial.h 1.0.12 2019/10/31 + * Version: @(#)serial.h 1.0.13 2020/01/24 * * Author: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #ifndef EMU_SERIAL_H # define EMU_SERIAL_H @@ -53,7 +53,7 @@ typedef struct serial_s rcvr_fifo[16], xmit_fifo[16]; pc_timer_t transmit_timer, timeout_timer; - double transmit_period; + double clock_src, transmit_period; struct serial_device_s *sd; } serial_t; @@ -78,6 +78,7 @@ extern void serial_clear_fifo(serial_t *dev); extern void serial_write_fifo(serial_t *dev, uint8_t dat); extern void serial_set_next_inst(int ni); extern void serial_standalone_init(void); +extern void serial_set_clock_src(serial_t *dev, double clock_src); extern const device_t i8250_device; extern const device_t i8250_pcjr_device; diff --git a/src/sio.h b/src/sio.h index 76f3a08f1..6009545ee 100644 --- a/src/sio.h +++ b/src/sio.h @@ -8,10 +8,10 @@ * * Definitions for the Super I/O chips. * - * Version: @(#)sio.h 1.0.6 2019/05/17 + * Version: @(#)sio.h 1.0.7 2020/01/25 * * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. + * Copyright 2017-2020 Fred N. van Kempen. */ #ifndef EMU_SIO_H # define EMU_SIO_H @@ -28,9 +28,14 @@ extern const device_t fdc37c935_device; extern const device_t pc87306_device; extern const device_t sio_detect_device; extern const device_t um8669f_device; +extern const device_t w83787f_device; extern const device_t w83877f_device; extern const device_t w83877f_president_device; extern const device_t w83877tf_device; +extern const device_t w83877tf_acorp_device; +extern const device_t w83977f_device; +extern const device_t w83977tf_device; +extern const device_t w83977ef_device; #endif /*EMU_SIO_H*/ diff --git a/src/sio_acc3221.c b/src/sio_acc3221.c index 18f759f17..93de9cb0a 100644 --- a/src/sio_acc3221.c +++ b/src/sio_acc3221.c @@ -20,16 +20,16 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "device.h" #include "pci.h" #include "lpt.h" #include "serial.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" typedef struct acc3221_t diff --git a/src/sio_detect.c b/src/sio_detect.c index bc0a3e377..189ef3caf 100644 --- a/src/sio_detect.c +++ b/src/sio_detect.c @@ -21,10 +21,10 @@ #include #include "86box.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" diff --git a/src/sio_fdc37c669.c b/src/sio_fdc37c669.c index 1f484af41..1bee36e59 100644 --- a/src/sio_fdc37c669.c +++ b/src/sio_fdc37c669.c @@ -19,16 +19,16 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "device.h" #include "pci.h" #include "lpt.h" #include "serial.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" diff --git a/src/sio_fdc37c66x.c b/src/sio_fdc37c66x.c index c1560f920..78d49c991 100644 --- a/src/sio_fdc37c66x.c +++ b/src/sio_fdc37c66x.c @@ -23,16 +23,16 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "device.h" #include "pci.h" #include "lpt.h" #include "serial.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" diff --git a/src/sio_fdc37c67x.c b/src/sio_fdc37c67x.c new file mode 100644 index 000000000..3560f8fde --- /dev/null +++ b/src/sio_fdc37c67x.c @@ -0,0 +1,519 @@ +/* + * 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. + * + * Emulation of the Winbond W83977F Super I/O Chip. + * + * Winbond W83977F Super I/O Chip + * Used by the Award 430TX + * + * Version: @(#)sio_w83977f.c 1.0.0 2020/01/24 + * + * Author: Miran Grca, + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "timer.h" +#include "pci.h" +#include "mem.h" +#include "rom.h" +#include "lpt.h" +#include "serial.h" +#include "fdd.h" +#include "fdc.h" +#include "sio.h" + + +#define HEFRAS (dev->regs[0x26] & 0x40) + + +typedef struct { + uint8_t tries, regs[48], + dev_regs[256][208]; + int locked, rw_locked, + cur_reg, base_address, + type; + fdc_t *fdc; + serial_t *uart[2]; +} w83977f_t; + + +static void w83977f_write(uint16_t port, uint8_t val, void *priv); +static uint8_t w83977f_read(uint16_t port, void *priv); + + +static void +w83977f_remap(w83977f_t *dev) +{ + io_removehandler(0x3f0, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); + io_removehandler(0x370, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); + + dev->base_address = (HEFRAS ? 0x370 : 0x3f0); + + io_sethandler(dev->base_address, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); +} + + +static uint8_t +get_lpt_length(w83977f_t *dev) +{ + uint8_t length = 4; + + if (((dev->dev_regs[1][0xc0] & 0x07) != 0x00) && ((dev->dev_regs[1][0xc0] & 0x07) != 0x02) && + ((dev->dev_regs[1][0xc0] & 0x07) != 0x04)) + length = 8; + + return length; +} + + +static void +w83977f_fdc_handler(w83977f_t *dev) +{ + uint16_t io_base = (dev->dev_regs[0][0x30] << 8) | dev->dev_regs[0][0x31]; + + fdc_remove(dev->fdc); + + pclog("fdc: %02X %02X %04X\n", dev->dev_regs[0][0x00], dev->regs[0x22], io_base); + if ((dev->dev_regs[0][0x00] & 0x01) && (dev->regs[0x22] & 0x01) && (io_base >= 0x100) && (io_base <= 0xff8)) + fdc_set_base(dev->fdc, io_base); + + fdc_set_irq(dev->fdc, dev->dev_regs[0][0x40] & 0x0f); +} + + +static void +w83977f_lpt_handler(w83977f_t *dev) +{ + uint16_t io_mask, io_base = (dev->dev_regs[1][0x30] << 8) | dev->dev_regs[1][0x31]; + int io_len = get_lpt_length(dev); + io_base &= (0xfff & ~io_len); + io_mask = 0xffc; + if (io_len == 8) + io_mask = 0xff8; + + lpt1_remove(); + + if ((dev->dev_regs[1][0x00] & 0x01) && (dev->regs[0x22] & 0x08) && (io_base >= 0x100) && (io_base <= io_mask)) + lpt1_init(io_base); + + lpt1_irq(dev->dev_regs[1][0x40] & 0x0f); +} + + +static void +w83977f_serial_handler(w83977f_t *dev, int uart) +{ + uint16_t io_base = (dev->dev_regs[2 + uart][0x30] << 8) | dev->dev_regs[2 + uart][0x31]; + double clock_src = 24000000.0 / 13.0; + + serial_remove(dev->uart[uart]); + + if ((dev->dev_regs[2 + uart][0x00] & 0x01) && (dev->regs[0x22] & (0x10 << uart)) && (io_base >= 0x100) && (io_base <= 0xff8)) + serial_setup(dev->uart[uart], io_base, dev->dev_regs[2 + uart][0x40] & 0x0f); + + switch (dev->dev_regs[2 + uart][0xc0] & 0x03) { + case 0x00: + clock_src = 24000000.0 / 13.0; + break; + case 0x01: + clock_src = 24000000.0 / 12.0; + break; + case 0x02: + clock_src = 24000000.0 / 1.0; + break; + case 0x03: + clock_src = 24000000.0 / 1.625; + break; + } + + serial_set_clock_src(dev->uart[uart], clock_src); +} + + +static void +w83977f_write(uint16_t port, uint8_t val, void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t valxor = 0; + uint8_t ld = dev->regs[7]; + + // pclog("W83977F Write: %04X %02X\n", port, val); + + if (index) { + if ((val == 0x87) && !dev->locked) { + if (dev->tries) { + dev->locked = 1; + dev->tries = 0; + } else + dev->tries++; + } else { + if (dev->locked) { + if (val == 0xaa) + dev->locked = 0; + else + dev->cur_reg = val; + } else { + if (dev->tries) + dev->tries = 0; + } + } + return; + } else { + if (dev->locked) { + if (dev->rw_locked) + return; + if (dev->cur_reg >= 0x30) { + valxor = val ^ dev->dev_regs[ld][dev->cur_reg - 0x30]; + dev->dev_regs[ld][dev->cur_reg - 0x30] = val; + } else { + valxor = val ^ dev->regs[dev->cur_reg]; + dev->regs[dev->cur_reg] = val; + } + } else + return; + } + + switch (dev->cur_reg) { + case 0x02: + if (valxor & 0x02) + softresetx86(); + break; + case 0x22: + if (valxor & 0x20) + w83977f_serial_handler(dev, 1); + if (valxor & 0x10) + w83977f_serial_handler(dev, 0); + if (valxor & 0x08) + w83977f_lpt_handler(dev); + if (valxor & 0x01) + w83977f_fdc_handler(dev); + break; + case 0x26: + if (valxor & 0x20) + dev->rw_locked = (val & 0x20) ? 1 : 0; + case 0x30: + if (valxor & 0x01) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0x60: case 0x61: + if (valxor & 0xff) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0x70: + if (valxor & 0x0f) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0xf0: + switch (ld) { + case 0x00: + if (valxor & 0x20) + fdc_update_drv2en(dev->fdc, (val & 0x20) ? 0 : 1); + if (valxor & 0x10) + fdc_set_swap(dev->fdc, (val & 0x10) ? 1 : 0); + if (valxor & 0x01) + fdc_update_enh_mode(dev->fdc, (val & 0x01) ? 1 : 0); + break; + case 0x01: + if (valxor & 0x07) + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + if (valxor & 0x03) + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0xf1: + switch (ld) { + case 0x00: + if (valxor & 0xc0) + fdc_update_boot_drive(dev->fdc, (val & 0xc0) >> 6); + if (valxor & 0x0c) + fdc_update_densel_force(dev->fdc, (val & 0x0c) >> 2); + if (valxor & 0x02) + fdc_set_diswr(dev->fdc, (val & 0x02) ? 1 : 0); + if (valxor & 0x01) + fdc_set_swwp(dev->fdc, (val & 0x01) ? 1 : 0); + break; + } + break; + case 0xf2: + switch (ld) { + case 0x00: + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, val & 0x03); + break; + } + break; + case 0xf4: case 0xf5: case 0xf6: case 0xf7: + switch (ld) { + case 0x00: + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, dev->cur_reg & 0x03, (val & 0x18) >> 3); + break; + } + break; + } +} + + +static uint8_t +w83977f_read(uint16_t port, void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + uint8_t ret = 0xff; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ld = dev->regs[7]; + + if (dev->locked) { + if (index) + ret = dev->cur_reg; + else { + if (!dev->rw_locked) { + if ((dev->cur_reg == 0xf2) && (ld == 0x00)) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); + else if (dev->cur_reg >= 0x30) + ret = dev->dev_regs[ld][dev->cur_reg - 0x30]; + else + ret = dev->regs[dev->cur_reg]; + } + } + } + + // pclog("W83977F Read: %04X %02X\n", port, ret); + + return ret; +} + + +static void +w83977f_reset(w83977f_t *dev) +{ + int i; + + memset(dev->regs, 0, 48); + for (i = 0; i < 256; i++) + memset(dev->dev_regs[i], 0, 208); + + dev->regs[0x20] = 0x97; + dev->regs[0x21] = dev->type ? 0x73 : 0x71; + dev->regs[0x22] = 0xff; + dev->regs[0x24] = dev->type ? 0x84 : 0xa4; + + /* WARNING: Array elements are register - 0x30. */ + /* Logical Device 0 (FDC) */ + dev->dev_regs[0][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[0][0x01] = 0x02; + dev->dev_regs[0][0x30] = 0x03; dev->dev_regs[0][0x31] = 0xf0; + dev->dev_regs[0][0x40] = 0x06; + if (!dev->type) + dev->dev_regs[0][0x41] = 0x02; /* Read-only */ + dev->dev_regs[0][0x44] = 0x02; + dev->dev_regs[0][0xc0] = 0x0e; + + /* Logical Device 1 (Parallel Port) */ + dev->dev_regs[1][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[1][0x01] = 0x02; + dev->dev_regs[1][0x30] = 0x03; dev->dev_regs[1][0x31] = 0x78; + dev->dev_regs[1][0x40] = 0x07; + if (!dev->type) + dev->dev_regs[1][0x41] = 0x02; /* Read-only */ + dev->dev_regs[1][0x44] = 0x04; + dev->dev_regs[1][0xc0] = 0x3c; /* The datasheet says default is 3f, but also default is priner mode. */ + + /* Logical Device 2 (UART A) */ + dev->dev_regs[2][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[2][0x01] = 0x02; + dev->dev_regs[2][0x30] = 0x03; dev->dev_regs[2][0x31] = 0xf8; + dev->dev_regs[2][0x40] = 0x04; + if (!dev->type) + dev->dev_regs[2][0x41] = 0x02; /* Read-only */ + + /* Logical Device 3 (UART B) */ + dev->dev_regs[3][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[3][0x01] = 0x02; + dev->dev_regs[3][0x30] = 0x02; dev->dev_regs[3][0x31] = 0xf8; + dev->dev_regs[3][0x40] = 0x03; + if (!dev->type) + dev->dev_regs[3][0x41] = 0x02; /* Read-only */ + + /* Logical Device 4 (RTC) */ + if (!dev->type) { + dev->dev_regs[4][0x00] = 0x01; + dev->dev_regs[4][0x01] = 0x02; + dev->dev_regs[4][0x30] = 0x00; dev->dev_regs[4][0x31] = 0x70; + dev->dev_regs[4][0x40] = 0x08; + dev->dev_regs[4][0x41] = 0x02; /* Read-only */ + } + + /* Logical Device 5 (KBC) */ + dev->dev_regs[5][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[5][0x01] = 0x02; + dev->dev_regs[5][0x30] = 0x00; dev->dev_regs[5][0x31] = 0x60; + dev->dev_regs[5][0x40] = 0x01; + if (!dev->type) + dev->dev_regs[5][0x41] = 0x02; /* Read-only */ + dev->dev_regs[5][0x42] = 0x0c; + if (!dev->type) + dev->dev_regs[5][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[5][0xc0] = dev->type ? 0x83 : 0x40; + + /* Logical Device 6 (IR) = UART C */ + if (!dev->type) { + dev->dev_regs[6][0x01] = 0x02; + dev->dev_regs[6][0x41] = 0x02; /* Read-only */ + dev->dev_regs[6][0x44] = 0x04; + dev->dev_regs[6][0x45] = 0x04; + } + + /* Logical Device 7 (Auxiliary I/O Part I) */ + if (!dev->type) + dev->dev_regs[7][0x01] = 0x02; + if (!dev->type) + dev->dev_regs[7][0x41] = 0x02; /* Read-only */ + if (!dev->type) + dev->dev_regs[7][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[7][0xb0] = 0x01; dev->dev_regs[7][0xb1] = 0x01; + dev->dev_regs[7][0xb2] = 0x01; dev->dev_regs[7][0xb3] = 0x01; + dev->dev_regs[7][0xb4] = 0x01; dev->dev_regs[7][0xb5] = 0x01; + dev->dev_regs[7][0xb6] = 0x01; + if (dev->type) + dev->dev_regs[7][0xb7] = 0x01; + + /* Logical Device 8 (Auxiliary I/O Part II) */ + if (!dev->type) + dev->dev_regs[8][0x01] = 0x02; + if (!dev->type) + dev->dev_regs[8][0x41] = 0x02; /* Read-only */ + if (!dev->type) + dev->dev_regs[8][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[8][0xb8] = 0x01; dev->dev_regs[8][0xb9] = 0x01; + dev->dev_regs[8][0xba] = 0x01; dev->dev_regs[8][0xbb] = 0x01; + dev->dev_regs[8][0xbc] = 0x01; dev->dev_regs[8][0xbd] = 0x01; + dev->dev_regs[8][0xbe] = 0x01; dev->dev_regs[8][0xbf] = 0x01; + + /* Logical Device 9 (Auxiliary I/O Part III) */ + if (dev->type) { + dev->dev_regs[7][0xb0] = 0x01; dev->dev_regs[7][0xb1] = 0x01; + dev->dev_regs[7][0xb2] = 0x01; dev->dev_regs[7][0xb3] = 0x01; + dev->dev_regs[7][0xb4] = 0x01; dev->dev_regs[7][0xb5] = 0x01; + dev->dev_regs[7][0xb6] = 0x01; dev->dev_regs[7][0xb7] = 0x01; + } + + fdc_reset(dev->fdc); + + serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); + serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); + + w83977f_fdc_handler(dev); + w83977f_lpt_handler(dev); + w83977f_serial_handler(dev, 0); + w83977f_serial_handler(dev, 1); + + w83977f_remap(dev); + + dev->locked = 0; + dev->rw_locked = 0; +} + + +static void +w83977f_close(void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + + free(dev); +} + + +static void * +w83977f_init(const device_t *info) +{ + w83977f_t *dev = (w83977f_t *) malloc(sizeof(w83977f_t)); + memset(dev, 0, sizeof(w83977f_t)); + + dev->type = info->local; + + dev->fdc = device_add(&fdc_at_smc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + w83977f_reset(dev); + + return dev; +} + + +const device_t w83977f_device = { + "Winbond W83977F Super I/O", + 0, + 0, + w83977f_init, w83977f_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +const device_t w83977tf_device = { + "Winbond W83977TF Super I/O", + 0, + 1, + w83977f_init, w83977f_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio_fdc37c93x.c b/src/sio_fdc37c93x.c index ef3380ee4..f34bc7e8e 100644 --- a/src/sio_fdc37c93x.c +++ b/src/sio_fdc37c93x.c @@ -20,16 +20,16 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "device.h" #include "pci.h" #include "lpt.h" #include "serial.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" diff --git a/src/sio_pc87306.c b/src/sio_pc87306.c index c2d3ceaf8..7b9a733b6 100644 --- a/src/sio_pc87306.c +++ b/src/sio_pc87306.c @@ -19,18 +19,19 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "device.h" #include "lpt.h" #include "mem.h" +#include "nvr.h" #include "pci.h" #include "rom.h" #include "serial.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" @@ -40,6 +41,7 @@ typedef struct { int cur_reg; fdc_t *fdc; serial_t *uart[2]; + nvr_t *nvr; } pc87306_t; @@ -287,6 +289,14 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) } } break; + case 4: + // pclog("NVR RAM mask set to %i\n", !!(val & 0x80)); + break; + case 5: + // pclog("Reserved set to %i\n", !!(val & 0x04)); + // pclog("RTC is now %sabled\n", (val & 0x08) ? "en" : "dis"); + // pclog("NVR RAM bank set to %i\n", !!(val & 0x20)); + break; case 9: if (valxor & 0x44) { fdc_update_enh_mode(dev->fdc, (val & 4) ? 1 : 0); @@ -298,6 +308,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) pc87306_gpio_init(dev); break; case 0x12: + // pclog("NVR RAM 38-3F lock set to %i\n", !!(val & 0x01)); if (valxor & 0x30) pc87306_gpio_init(dev); break; @@ -406,6 +417,8 @@ pc87306_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); + // dev->nvr = device_add(&piix4_nvr_device); + pc87306_reset(dev); io_sethandler(0x02e, 0x0002, diff --git a/src/sio_um8669f.c b/src/sio_um8669f.c index d946c251c..0d7b21511 100644 --- a/src/sio_um8669f.c +++ b/src/sio_um8669f.c @@ -28,13 +28,13 @@ PnP registers : #include #include "86box.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "pci.h" #include "lpt.h" #include "serial.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" @@ -181,7 +181,8 @@ um8669f_pnp_read(uint16_t port, void *priv) } -void um8669f_write(uint16_t port, uint8_t val, void *priv) +void +um8669f_write(uint16_t port, uint8_t val, void *priv) { um8669f_t *dev = (um8669f_t *) priv; int new_pnp_active; @@ -224,7 +225,8 @@ void um8669f_write(uint16_t port, uint8_t val, void *priv) } -uint8_t um8669f_read(uint16_t port, void *priv) +uint8_t +um8669f_read(uint16_t port, void *priv) { um8669f_t *dev = (um8669f_t *) priv; uint8_t ret = 0xff; @@ -297,7 +299,7 @@ um8669f_init(const device_t *info) um8669f_t *dev = (um8669f_t *) malloc(sizeof(um8669f_t)); memset(dev, 0, sizeof(um8669f_t)); - dev->fdc = device_add(&fdc_at_device); + dev->fdc = device_add(&fdc_at_smc_device); dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); diff --git a/src/sio_w83787f.c b/src/sio_w83787f.c new file mode 100644 index 000000000..df77b5062 --- /dev/null +++ b/src/sio_w83787f.c @@ -0,0 +1,387 @@ +/* + * 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. + * + * Emulation of the Winbond W83787F/IF Super I/O Chip. + * + * Winbond W83787F Super I/O Chip + * Used by the Award 430HX + * + * Version: @(#)sio_w83787f.c 1.0.0 2020/01/11 + * + * Author: Miran Grca, + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "timer.h" +#include "pci.h" +#include "mem.h" +#include "rom.h" +#include "lpt.h" +#include "serial.h" +#include "fdd.h" +#include "fdc.h" +#include "sio.h" + + +#define FDDA_TYPE (dev->regs[7] & 3) +#define FDDB_TYPE ((dev->regs[7] >> 2) & 3) +#define FDDC_TYPE ((dev->regs[7] >> 4) & 3) +#define FDDD_TYPE ((dev->regs[7] >> 6) & 3) + +#define FD_BOOT (dev->regs[8] & 3) +#define SWWP ((dev->regs[8] >> 4) & 1) +#define DISFDDWR ((dev->regs[8] >> 5) & 1) + +#define EN3MODE ((dev->regs[9] >> 5) & 1) + +#define DRV2EN_NEG (dev->regs[0xB] & 1) /* 0 = drive 2 installed */ +#define INVERTZ ((dev->regs[0xB] >> 1) & 1) /* 0 = invert DENSEL polarity */ +#define IDENT ((dev->regs[0xB] >> 3) & 1) + +#define HEFERE ((dev->regs[0xC] >> 5) & 1) + + +typedef struct { + uint8_t tries, regs[42]; + uint16_t reg_init; + int locked, rw_locked, + cur_reg, + key; + fdc_t *fdc; + serial_t *uart[2]; +} w83787f_t; + + +static void w83787f_write(uint16_t port, uint8_t val, void *priv); +static uint8_t w83787f_read(uint16_t port, void *priv); + + +static void +w83787f_remap(w83787f_t *dev) +{ + io_removehandler(0x250, 0x0003, + w83787f_read, NULL, NULL, w83787f_write, NULL, NULL, dev); + io_sethandler(0x250, 0x0003, + w83787f_read, NULL, NULL, w83787f_write, NULL, NULL, dev); + dev->key = 0x88 | HEFERE; +} + + +#ifdef FIXME +/* FIXME: Implement EPP (and ECP) parallel port modes. */ +static uint8_t +get_lpt_length(w83787f_t *dev) +{ + uint8_t length = 4; + + if (dev->regs[9] & 0x80) { + if (dev->regs[0] & 0x04) + length = 8; /* EPP mode. */ + if (dev->regs[0] & 0x08) + length |= 0x80; /* ECP mode. */ + } + + return length; +} +#endif + + +static void +w83787f_serial_handler(w83787f_t *dev, int uart) +{ + int urs0 = !!(dev->regs[1] & (1 << uart)); + int urs1 = !!(dev->regs[1] & (4 << uart)); + int urs2 = !!(dev->regs[3] & (8 >> uart)); + int urs, irq = 4; + uint16_t addr = 0x3f8, enable = 1; + + urs = (urs1 << 1) | urs0; + + if (urs2) { + addr = uart ? 0x3f8 : 0x2f8; + irq = uart ? 4 : 3; + } else { + switch (urs) { + case 0: + addr = uart ? 0x3e8 : 0x2e8; + irq = uart ? 4 : 3; + break; + case 1: + addr = uart ? 0x2e8 : 0x3e8; + irq = uart ? 3 : 4; + break; + case 2: + addr = uart ? 0x2f8 : 0x3f8; + irq = uart ? 3 : 4; + break; + case 3: + default: + enable = 0; + break; + } + } + + if (dev->regs[4] & (0x20 >> uart)) + enable = 0; + + serial_remove(dev->uart[uart]); + if (enable) + serial_setup(dev->uart[uart], addr, irq); +} + + +static void +w83787f_lpt_handler(w83787f_t *dev) +{ + int ptrs0 = !!(dev->regs[1] & 4); + int ptrs1 = !!(dev->regs[1] & 5); + int ptrs, irq = 7; + uint16_t addr = 0x378, enable = 1; + + ptrs = (ptrs1 << 1) | ptrs0; + + switch (ptrs) { + case 0: + addr = 0x3bc; + irq = 7; + break; + case 1: + addr = 0x278; + irq = 5; + break; + case 2: + addr = 0x378; + irq = 7; + break; + case 3: + default: + enable = 0; + break; + } + + if (dev->regs[4] & 0x80) + enable = 0; + + lpt1_remove(); + if (enable) { + lpt1_init(addr); + lpt1_irq(irq); + } +} + + +static void +w83787f_fdc_handler(w83787f_t *dev) +{ + fdc_remove(dev->fdc); + if (!(dev->regs[0] & 0x20)) + fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? 0x03f0 : 0x0370); +} + + +static void +w83787f_write(uint16_t port, uint8_t val, void *priv) +{ + w83787f_t *dev = (w83787f_t *) priv; + uint8_t valxor = 0; + uint8_t max = 0x15; + pclog("W83787F: Write %02X to %04X\n", val, port); + + if (port == 0x250) { + if (val == dev->key) + dev->locked = 1; + else + dev->locked = 0; + return; + } else if (port == 0x251) { + if (val <= max) + dev->cur_reg = val; + return; + } else { + if (dev->locked) { + if (dev->rw_locked) + return; + if (dev->cur_reg == 6) + val &= 0xF3; + valxor = val ^ dev->regs[dev->cur_reg]; + dev->regs[dev->cur_reg] = val; + } else + return; + } + + switch (dev->cur_reg) { + case 0: + if (valxor & 0x30) + w83787f_fdc_handler(dev); + if (valxor & 0x0c) + w83787f_lpt_handler(dev); + break; + case 1: + if (valxor & 0x80) + fdc_set_swap(dev->fdc, (dev->regs[1] & 0x80) ? 1 : 0); + if (valxor & 0x30) + w83787f_lpt_handler(dev); + if (valxor & 0x0a) + w83787f_serial_handler(dev, 1); + if (valxor & 0x05) + w83787f_serial_handler(dev, 0); + break; + case 3: + if (valxor & 0x80) + w83787f_lpt_handler(dev); + if (valxor & 0x08) + w83787f_serial_handler(dev, 0); + if (valxor & 0x04) + w83787f_serial_handler(dev, 1); + break; + case 4: + if (valxor & 0x10) + w83787f_serial_handler(dev, 1); + if (valxor & 0x20) + w83787f_serial_handler(dev, 0); + if (valxor & 0x80) + w83787f_lpt_handler(dev); + break; + case 6: + if (valxor & 0x08) { + fdc_remove(dev->fdc); + if (!(dev->regs[6] & 0x08)) + fdc_set_base(dev->fdc, 0x03f0); + } + break; + case 7: + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, FDDA_TYPE); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, FDDB_TYPE); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, FDDC_TYPE); + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, FDDD_TYPE); + break; + case 8: + if (valxor & 0x03) + fdc_update_boot_drive(dev->fdc, FD_BOOT); + if (valxor & 0x10) + fdc_set_swwp(dev->fdc, SWWP ? 1 : 0); + if (valxor & 0x20) + fdc_set_diswr(dev->fdc, DISFDDWR ? 1 : 0); + break; + case 9: + if (valxor & 0x20) + fdc_update_enh_mode(dev->fdc, EN3MODE ? 1 : 0); + if (valxor & 0x40) + dev->rw_locked = (val & 0x40) ? 1 : 0; + if (valxor & 0x80) + w83787f_lpt_handler(dev); + break; + case 0xC: + if (valxor & 0x20) + w83787f_remap(dev); + break; + } +} + + +static uint8_t +w83787f_read(uint16_t port, void *priv) +{ + w83787f_t *dev = (w83787f_t *) priv; + uint8_t ret = 0xff; + + if (dev->locked) { + if (port == 0x251) + ret = dev->cur_reg; + else if (port == 0x252) { + if (dev->cur_reg == 7) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2)); + else if (!dev->rw_locked) + ret = dev->regs[dev->cur_reg]; + } + } + + pclog("W83787F: Read %02X from %04X\n", ret, port); + + return ret; +} + + +static void +w83787f_reset(w83787f_t *dev) +{ + lpt1_remove(); + lpt1_init(0x378); + lpt1_irq(7); + + fdc_reset(dev->fdc); + + memset(dev->regs, 0, 0x2A); + dev->regs[0x00] = 0x50; + dev->regs[0x01] = 0x2C; + dev->regs[0x03] = 0x30; + dev->regs[0x07] = 0xF5; + dev->regs[0x09] = dev->reg_init & 0xff; + dev->regs[0x0a] = 0x1F; + dev->regs[0x0c] = 0x2C; + dev->regs[0x0d] = 0xA3; + + serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); + serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); + + dev->key = 0x89; + + w83787f_remap(dev); + + dev->locked = 0; + dev->rw_locked = 0; +} + + +static void +w83787f_close(void *priv) +{ + w83787f_t *dev = (w83787f_t *) priv; + + free(dev); +} + + +static void * +w83787f_init(const device_t *info) +{ + w83787f_t *dev = (w83787f_t *) malloc(sizeof(w83787f_t)); + memset(dev, 0, sizeof(w83787f_t)); + + dev->fdc = device_add(&fdc_at_winbond_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->reg_init = info->local; + + w83787f_reset(dev); + + return dev; +} + + +const device_t w83787f_device = { + "Winbond W83787F/IF Super I/O", + 0, + 0x09, + w83787f_init, w83787f_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio_w83877f.c b/src/sio_w83877f.c index 69ad67286..c9304e7db 100644 --- a/src/sio_w83877f.c +++ b/src/sio_w83877f.c @@ -11,7 +11,7 @@ * Winbond W83877F Super I/O Chip * Used by the Award 430HX * - * Version: @(#)sio_w83877f.c 1.0.16 2020/01/11 + * Version: @(#)sio_w83877f.c 1.0.17 2020/01/25 * * Author: Miran Grca, * Copyright 2016-2020 Miran Grca. @@ -23,15 +23,15 @@ #include #include "86box.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "pci.h" #include "mem.h" #include "rom.h" #include "lpt.h" #include "serial.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" @@ -148,18 +148,65 @@ make_port(w83877f_t *dev, uint8_t reg) } +static void +w83877f_fdc_handler(w83877f_t *dev) +{ + fdc_remove(dev->fdc); + if (!(dev->regs[6] & 0x08) && (dev->regs[0x20] & 0xc0)) + fdc_set_base(dev->fdc, 0x03f0); +} + + +static void +w83877f_lpt_handler(w83877f_t *dev) +{ + uint8_t lpt_irq; + uint8_t lpt_irqs[8] = { 0, 7, 9, 10, 11, 14, 15, 5 }; + + lpt1_remove(); + if (!(dev->regs[4] & 0x80) && (dev->regs[0x23] & 0xc0)) + lpt1_init(make_port(dev, 0x23)); + + lpt_irq = 0xff; + + lpt_irq = lpt_irqs[ECPIRQ]; + if (lpt_irq == 0) + lpt_irq = PRTIQS; + + lpt1_irq(lpt_irq); +} + + static void w83877f_serial_handler(w83877f_t *dev, int uart) { int reg_mask = uart ? 0x10 : 0x20; - int reg_id = uart ? 0x24 : 0x25; + int reg_id = uart ? 0x25 : 0x24; int irq_mask = uart ? 0x0f : 0xf0; - int irq_shift = uart ? 4 : 0; + int irq_shift = uart ? 0 : 4; + double clock_src = 24000000.0 / 13.0; - if ((dev->regs[4] & reg_mask) || !(dev->regs[reg_id] & 0xc0)) - serial_remove(dev->uart[uart]); - else + serial_remove(dev->uart[uart]); + if (!(dev->regs[4] & reg_mask) && (dev->regs[reg_id] & 0xc0)) serial_setup(dev->uart[uart], make_port(dev, reg_id), (dev->regs[0x28] & irq_mask) >> irq_shift); + + switch (!!(dev->regs[0x19] & (0x02 >> uart))) { + case 0: + switch (!!(dev->regs[0x03] & (0x02 >> uart))) { + case 0: + clock_src = 24000000.0 / 13.0; + break; + case 1: + clock_src = 24000000.0 / 12.0; + break; + } + break; + case 1: + clock_src = 14769000.0; + break; + } + + serial_set_clock_src(dev->uart[uart], clock_src); } @@ -169,7 +216,6 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) w83877f_t *dev = (w83877f_t *) priv; uint8_t valxor = 0; uint8_t max = 0x2A; - uint8_t lpt_irq; if (port == 0x250) { if (val == dev->key) @@ -223,33 +269,30 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) switch (dev->cur_reg) { case 0: - if (valxor & 0x0c) { - lpt1_remove(); - if (!(dev->regs[4] & 0x80)) - lpt1_init(make_port(dev, 0x23)); - } + if (valxor & 0x0c) + w83877f_lpt_handler(dev); break; case 1: if (valxor & 0x80) fdc_set_swap(dev->fdc, (dev->regs[1] & 0x80) ? 1 : 0); break; + case 3: + if (valxor & 0x02) + w83877f_serial_handler(dev, 0); + if (valxor & 0x01) + w83877f_serial_handler(dev, 1); + break; case 4: if (valxor & 0x10) w83877f_serial_handler(dev, 1); if (valxor & 0x20) w83877f_serial_handler(dev, 0); - if (valxor & 0x80) { - lpt1_remove(); - if (!(dev->regs[4] & 0x80)) - lpt1_init(make_port(dev, 0x23)); - } + if (valxor & 0x80) + w83877f_lpt_handler(dev); break; case 6: - if (valxor & 0x08) { - fdc_remove(dev->fdc); - if (!(dev->regs[6] & 0x08)) - fdc_set_base(dev->fdc, 0x03f0); - } + if (valxor & 0x08) + w83877f_fdc_handler(dev); break; case 7: if (valxor & 0x03) @@ -274,11 +317,8 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) fdc_update_enh_mode(dev->fdc, EN3MODE ? 1 : 0); if (valxor & 0x40) dev->rw_locked = (val & 0x40) ? 1 : 0; - if (valxor & 0x80) { - lpt1_remove(); - if (!(dev->regs[4] & 0x80)) - lpt1_init(make_port(dev, 0x23)); - } + if (valxor & 0x80) + w83877f_lpt_handler(dev); break; case 0xB: if (valxor & 1) @@ -294,19 +334,19 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) if (valxor & 1) w83877f_remap(dev); break; + case 0x19: + if (valxor & 0x02) + w83877f_serial_handler(dev, 0); + if (valxor & 0x01) + w83877f_serial_handler(dev, 1); + break; case 0x20: - if (valxor) { - fdc_remove(dev->fdc); - if (!(dev->regs[4] & 0x80)) - fdc_set_base(dev->fdc, make_port(dev, 0x20)); - } + if (valxor) + w83877f_fdc_handler(dev); break; case 0x23: - if (valxor) { - lpt1_remove(); - if (!(dev->regs[4] & 0x80)) - lpt1_init(make_port(dev, 0x23)); - } + if (valxor) + w83877f_lpt_handler(dev); break; case 0x24: if (valxor & 0xfe) @@ -317,27 +357,19 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) w83877f_serial_handler(dev, 1); break; case 0x27: - if (valxor & 0xef) { - lpt_irq = 0xff; - - if (PRTIQS != 0x00) - lpt_irq = ECPIRQ; - - lpt1_irq(lpt_irq); - } + if (valxor & 0xef) + w83877f_lpt_handler(dev); break; case 0x28: if (valxor & 0xf) { if ((dev->regs[0x28] & 0x0f) == 0) dev->regs[0x28] |= 0x03; - if (!(dev->regs[2] & 0x10)) - serial_setup(dev->uart[1], make_port(dev, 0x25), dev->regs[0x28] & 0x0f); + w83877f_serial_handler(dev, 1); } if (valxor & 0xf0) { if ((dev->regs[0x28] & 0xf0) == 0) dev->regs[0x28] |= 0x40; - if (!(dev->regs[4] & 0x20)) - serial_setup(dev->uart[0], make_port(dev, 0x24), (dev->regs[0x28] & 0xf0) >> 4); + w83877f_serial_handler(dev, 0); } break; } @@ -355,7 +387,7 @@ w83877f_read(uint16_t port, void *priv) ret = dev->cur_reg; else if ((port == 0x3f1) || (port == 0x252)) { if (dev->cur_reg == 7) - ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2)); + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); else if ((dev->cur_reg >= 0x18) || !dev->rw_locked) ret = dev->regs[dev->cur_reg]; } @@ -368,9 +400,6 @@ w83877f_read(uint16_t port, void *priv) static void w83877f_reset(w83877f_t *dev) { - lpt1_remove(); - lpt1_init(0x378); - fdc_reset(dev->fdc); memset(dev->regs, 0, 0x2A); @@ -389,12 +418,16 @@ w83877f_reset(w83877f_t *dev) dev->regs[0x24] = (0x3f8 >> 2) & 0xfe; dev->regs[0x25] = (0x2f8 >> 2) & 0xfe; dev->regs[0x26] = (2 << 4) | 4; - dev->regs[0x27] = (6 << 4) | 7; + dev->regs[0x27] = (2 << 4) | 5; dev->regs[0x28] = (4 << 4) | 3; dev->regs[0x29] = 0x62; - serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); - serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); + w83877f_fdc_handler(dev); + + w83877f_lpt_handler(dev); + + w83877f_serial_handler(dev, 0); + w83877f_serial_handler(dev, 1); dev->base_address = 0x3f0; dev->key = 0x89; @@ -463,3 +496,13 @@ const device_t w83877tf_device = { NULL, NULL, NULL, NULL }; + + +const device_t w83877tf_acorp_device = { + "Winbond W83877TF Super I/O", + 0, + 0x0c05, + w83877f_init, w83877f_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio_w83977f.c b/src/sio_w83977f.c new file mode 100644 index 000000000..770ce2c7a --- /dev/null +++ b/src/sio_w83977f.c @@ -0,0 +1,535 @@ +/* + * 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. + * + * Emulation of the Winbond W83977F Super I/O Chip. + * + * Winbond W83977F Super I/O Chip + * Used by the Award 430TX + * + * Version: @(#)sio_w83977f.c 1.0.0 2020/01/24 + * + * Author: Miran Grca, + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "timer.h" +#include "pci.h" +#include "mem.h" +#include "rom.h" +#include "lpt.h" +#include "serial.h" +#include "fdd.h" +#include "fdc.h" +#include "sio.h" + + +#define HEFRAS (dev->regs[0x26] & 0x40) + + +typedef struct { + uint8_t tries, regs[48], + dev_regs[256][208]; + int locked, rw_locked, + cur_reg, base_address, + type; + fdc_t *fdc; + serial_t *uart[2]; +} w83977f_t; + + +static void w83977f_write(uint16_t port, uint8_t val, void *priv); +static uint8_t w83977f_read(uint16_t port, void *priv); + + +static void +w83977f_remap(w83977f_t *dev) +{ + io_removehandler(0x3f0, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); + io_removehandler(0x370, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); + + dev->base_address = (HEFRAS ? 0x370 : 0x3f0); + + io_sethandler(dev->base_address, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); +} + + +static uint8_t +get_lpt_length(w83977f_t *dev) +{ + uint8_t length = 4; + + if (((dev->dev_regs[1][0xc0] & 0x07) != 0x00) && ((dev->dev_regs[1][0xc0] & 0x07) != 0x02) && + ((dev->dev_regs[1][0xc0] & 0x07) != 0x04)) + length = 8; + + return length; +} + + +static void +w83977f_fdc_handler(w83977f_t *dev) +{ + uint16_t io_base = (dev->dev_regs[0][0x30] << 8) | dev->dev_regs[0][0x31]; + + fdc_remove(dev->fdc); + + if ((dev->dev_regs[0][0x00] & 0x01) && (dev->regs[0x22] & 0x01) && (io_base >= 0x100) && (io_base <= 0xff8)) + fdc_set_base(dev->fdc, io_base); + + fdc_set_irq(dev->fdc, dev->dev_regs[0][0x40] & 0x0f); +} + + +static void +w83977f_lpt_handler(w83977f_t *dev) +{ + uint16_t io_mask, io_base = (dev->dev_regs[1][0x30] << 8) | dev->dev_regs[1][0x31]; + int io_len = get_lpt_length(dev); + io_base &= (0xfff & ~io_len); + io_mask = 0xffc; + if (io_len == 8) + io_mask = 0xff8; + + lpt1_remove(); + + if ((dev->dev_regs[1][0x00] & 0x01) && (dev->regs[0x22] & 0x08) && (io_base >= 0x100) && (io_base <= io_mask)) + lpt1_init(io_base); + + lpt1_irq(dev->dev_regs[1][0x40] & 0x0f); +} + + +static void +w83977f_serial_handler(w83977f_t *dev, int uart) +{ + uint16_t io_base = (dev->dev_regs[2 + uart][0x30] << 8) | dev->dev_regs[2 + uart][0x31]; + double clock_src = 24000000.0 / 13.0; + + serial_remove(dev->uart[uart]); + + if ((dev->dev_regs[2 + uart][0x00] & 0x01) && (dev->regs[0x22] & (0x10 << uart)) && (io_base >= 0x100) && (io_base <= 0xff8)) + serial_setup(dev->uart[uart], io_base, dev->dev_regs[2 + uart][0x40] & 0x0f); + + switch (dev->dev_regs[2 + uart][0xc0] & 0x03) { + case 0x00: + clock_src = 24000000.0 / 13.0; + break; + case 0x01: + clock_src = 24000000.0 / 12.0; + break; + case 0x02: + clock_src = 24000000.0 / 1.0; + break; + case 0x03: + clock_src = 24000000.0 / 1.625; + break; + } + + serial_set_clock_src(dev->uart[uart], clock_src); +} + + +static void +w83977f_write(uint16_t port, uint8_t val, void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t valxor = 0; + uint8_t ld = dev->regs[7]; + + if (index) { + if ((val == 0x87) && !dev->locked) { + if (dev->tries) { + dev->locked = 1; + dev->tries = 0; + } else + dev->tries++; + } else { + if (dev->locked) { + if (val == 0xaa) + dev->locked = 0; + else + dev->cur_reg = val; + } else { + if (dev->tries) + dev->tries = 0; + } + } + return; + } else { + if (dev->locked) { + if (dev->rw_locked) + return; + if (dev->cur_reg >= 0x30) { + valxor = val ^ dev->dev_regs[ld][dev->cur_reg - 0x30]; + dev->dev_regs[ld][dev->cur_reg - 0x30] = val; + } else { + valxor = val ^ dev->regs[dev->cur_reg]; + dev->regs[dev->cur_reg] = val; + } + } else + return; + } + + switch (dev->cur_reg) { + case 0x02: + /* if (valxor & 0x02) + softresetx86(); */ + break; + case 0x22: + if (valxor & 0x20) + w83977f_serial_handler(dev, 1); + if (valxor & 0x10) + w83977f_serial_handler(dev, 0); + if (valxor & 0x08) + w83977f_lpt_handler(dev); + if (valxor & 0x01) + w83977f_fdc_handler(dev); + break; + case 0x26: + if (valxor & 0x40) + w83977f_remap(dev); + if (valxor & 0x20) + dev->rw_locked = (val & 0x20) ? 1 : 0; + break; + case 0x30: + if (valxor & 0x01) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0x60: case 0x61: + if (valxor & 0xff) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0x70: + if (valxor & 0x0f) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0xf0: + switch (ld) { + case 0x00: + if (valxor & 0x20) + fdc_update_drv2en(dev->fdc, (val & 0x20) ? 0 : 1); + if (valxor & 0x10) + fdc_set_swap(dev->fdc, (val & 0x10) ? 1 : 0); + if (valxor & 0x01) + fdc_update_enh_mode(dev->fdc, (val & 0x01) ? 1 : 0); + break; + case 0x01: + if (valxor & 0x07) + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + if (valxor & 0x03) + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0xf1: + switch (ld) { + case 0x00: + if (valxor & 0xc0) + fdc_update_boot_drive(dev->fdc, (val & 0xc0) >> 6); + if (valxor & 0x0c) + fdc_update_densel_force(dev->fdc, (val & 0x0c) >> 2); + if (valxor & 0x02) + fdc_set_diswr(dev->fdc, (val & 0x02) ? 1 : 0); + if (valxor & 0x01) + fdc_set_swwp(dev->fdc, (val & 0x01) ? 1 : 0); + break; + } + break; + case 0xf2: + switch (ld) { + case 0x00: + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, val & 0x03); + break; + } + break; + case 0xf4: case 0xf5: case 0xf6: case 0xf7: + switch (ld) { + case 0x00: + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, dev->cur_reg & 0x03, (val & 0x18) >> 3); + break; + } + break; + } +} + + +static uint8_t +w83977f_read(uint16_t port, void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + uint8_t ret = 0xff; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ld = dev->regs[7]; + + if (dev->locked) { + if (index) + ret = dev->cur_reg; + else { + if (!dev->rw_locked) { + if ((dev->cur_reg == 0xf2) && (ld == 0x00)) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); + else if (dev->cur_reg >= 0x30) + ret = dev->dev_regs[ld][dev->cur_reg - 0x30]; + else + ret = dev->regs[dev->cur_reg]; + } + } + } + + return ret; +} + + +static void +w83977f_reset(w83977f_t *dev) +{ + int i; + + memset(dev->regs, 0, 48); + for (i = 0; i < 256; i++) + memset(dev->dev_regs[i], 0, 208); + + if (dev->type < 2) { + dev->regs[0x20] = 0x97; + dev->regs[0x21] = dev->type ? 0x73 : 0x71; + } else { + dev->regs[0x20] = 0x52; + dev->regs[0x21] = 0xf0; + } + dev->regs[0x22] = 0xff; + dev->regs[0x24] = dev->type ? 0x84 : 0xa4; + + /* WARNING: Array elements are register - 0x30. */ + /* Logical Device 0 (FDC) */ + dev->dev_regs[0][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[0][0x01] = 0x02; + dev->dev_regs[0][0x30] = 0x03; dev->dev_regs[0][0x31] = 0xf0; + dev->dev_regs[0][0x40] = 0x06; + if (!dev->type) + dev->dev_regs[0][0x41] = 0x02; /* Read-only */ + dev->dev_regs[0][0x44] = 0x02; + dev->dev_regs[0][0xc0] = 0x0e; + + /* Logical Device 1 (Parallel Port) */ + dev->dev_regs[1][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[1][0x01] = 0x02; + dev->dev_regs[1][0x30] = 0x03; dev->dev_regs[1][0x31] = 0x78; + dev->dev_regs[1][0x40] = 0x07; + if (!dev->type) + dev->dev_regs[1][0x41] = 0x01 /*0x02*/; /* Read-only */ + dev->dev_regs[1][0x44] = 0x04; + dev->dev_regs[1][0xc0] = 0x3c; /* The datasheet says default is 3f, but also default is printer mode. */ + + /* Logical Device 2 (UART A) */ + dev->dev_regs[2][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[2][0x01] = 0x02; + dev->dev_regs[2][0x30] = 0x03; dev->dev_regs[2][0x31] = 0xf8; + dev->dev_regs[2][0x40] = 0x04; + if (!dev->type) + dev->dev_regs[2][0x41] = 0x02; /* Read-only */ + + /* Logical Device 3 (UART B) */ + dev->dev_regs[3][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[3][0x01] = 0x02; + dev->dev_regs[3][0x30] = 0x02; dev->dev_regs[3][0x31] = 0xf8; + dev->dev_regs[3][0x40] = 0x03; + if (!dev->type) + dev->dev_regs[3][0x41] = 0x02; /* Read-only */ + + /* Logical Device 4 (RTC) */ + if (!dev->type) { + dev->dev_regs[4][0x00] = 0x01; + dev->dev_regs[4][0x01] = 0x02; + dev->dev_regs[4][0x30] = 0x00; dev->dev_regs[4][0x31] = 0x70; + dev->dev_regs[4][0x40] = 0x08; + dev->dev_regs[4][0x41] = 0x02; /* Read-only */ + } + + /* Logical Device 5 (KBC) */ + dev->dev_regs[5][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[5][0x01] = 0x02; + dev->dev_regs[5][0x30] = 0x00; dev->dev_regs[5][0x31] = 0x60; + dev->dev_regs[5][0x32] = 0x00; dev->dev_regs[5][0x33] = 0x64; + dev->dev_regs[5][0x40] = 0x01; + if (!dev->type) + dev->dev_regs[5][0x41] = 0x02; /* Read-only */ + dev->dev_regs[5][0x42] = 0x0c; + if (!dev->type) + dev->dev_regs[5][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[5][0xc0] = dev->type ? 0x83 : 0x40; + + /* Logical Device 6 (IR) = UART C */ + if (!dev->type) { + dev->dev_regs[6][0x01] = 0x02; + dev->dev_regs[6][0x41] = 0x02; /* Read-only */ + dev->dev_regs[6][0x44] = 0x04; + dev->dev_regs[6][0x45] = 0x04; + } + + /* Logical Device 7 (Auxiliary I/O Part I) */ + if (!dev->type) + dev->dev_regs[7][0x01] = 0x02; + if (!dev->type) + dev->dev_regs[7][0x41] = 0x02; /* Read-only */ + if (!dev->type) + dev->dev_regs[7][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[7][0xb0] = 0x01; dev->dev_regs[7][0xb1] = 0x01; + dev->dev_regs[7][0xb2] = 0x01; dev->dev_regs[7][0xb3] = 0x01; + dev->dev_regs[7][0xb4] = 0x01; dev->dev_regs[7][0xb5] = 0x01; + dev->dev_regs[7][0xb6] = 0x01; + if (dev->type) + dev->dev_regs[7][0xb7] = 0x01; + + /* Logical Device 8 (Auxiliary I/O Part II) */ + if (!dev->type) + dev->dev_regs[8][0x01] = 0x02; + if (!dev->type) + dev->dev_regs[8][0x41] = 0x02; /* Read-only */ + if (!dev->type) + dev->dev_regs[8][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[8][0xb8] = 0x01; dev->dev_regs[8][0xb9] = 0x01; + dev->dev_regs[8][0xba] = 0x01; dev->dev_regs[8][0xbb] = 0x01; + dev->dev_regs[8][0xbc] = 0x01; dev->dev_regs[8][0xbd] = 0x01; + dev->dev_regs[8][0xbe] = 0x01; dev->dev_regs[8][0xbf] = 0x01; + + /* Logical Device 9 (Auxiliary I/O Part III) */ + if (dev->type) { + dev->dev_regs[9][0xb0] = 0x01; dev->dev_regs[9][0xb1] = 0x01; + dev->dev_regs[9][0xb2] = 0x01; dev->dev_regs[9][0xb3] = 0x01; + dev->dev_regs[9][0xb4] = 0x01; dev->dev_regs[9][0xb5] = 0x01; + dev->dev_regs[9][0xb6] = 0x01; dev->dev_regs[9][0xb7] = 0x01; + + dev->dev_regs[10][0xc0] = 0x8f; + } + + fdc_reset(dev->fdc); + + serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); + serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); + + w83977f_fdc_handler(dev); + w83977f_lpt_handler(dev); + w83977f_serial_handler(dev, 0); + w83977f_serial_handler(dev, 1); + + w83977f_remap(dev); + + dev->locked = 0; + dev->rw_locked = 0; +} + + +static void +w83977f_close(void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + + free(dev); +} + + +static void * +w83977f_init(const device_t *info) +{ + w83977f_t *dev = (w83977f_t *) malloc(sizeof(w83977f_t)); + memset(dev, 0, sizeof(w83977f_t)); + + dev->type = info->local; + + dev->fdc = device_add(&fdc_at_smc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + w83977f_reset(dev); + + return dev; +} + + +const device_t w83977f_device = { + "Winbond W83977F Super I/O", + 0, + 0, + w83977f_init, w83977f_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +const device_t w83977tf_device = { + "Winbond W83977TF Super I/O", + 0, + 1, + w83977f_init, w83977f_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +const device_t w83977ef_device = { + "Winbond W83977TF Super I/O", + 0, + 2, + w83977f_init, w83977f_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/smbus.c b/src/smbus.c new file mode 100644 index 000000000..171d4fad5 --- /dev/null +++ b/src/smbus.c @@ -0,0 +1,410 @@ +/* + * 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. + * + * Implement SMBus (System Management Bus) and its operations. + * + * Version: @(#)smbus.c 1.0.0 2020/03/21 + * + * Authors: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include "86box.h" +#include "smbus.h" + + +#define NADDRS 128 /* SMBus supports 128 addresses */ +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + + +typedef struct _smbus_ { + uint8_t (*read_byte)(uint8_t addr, void *priv); + uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv); + uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv); + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv); + + void (*write_byte)(uint8_t addr, uint8_t val, void *priv); + void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv); + void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv); + void (*write_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv); + + void *priv; + + struct _smbus_ *prev, *next; +} smbus_t; + +int smbus_initialized = 0; +smbus_t *smbus[NADDRS], *smbus_last[NADDRS]; + +#define ENABLE_SMBUS_LOG 1 +#ifdef ENABLE_SMBUS_LOG +int smbus_do_log = ENABLE_SMBUS_LOG; + + +static void +smbus_log(const char *fmt, ...) +{ + va_list ap; + + if (smbus_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define smbus_log(fmt, ...) +#endif + + +#ifdef ENABLE_SMBUS_LOG +static uint8_t smbus_null_read_byte(uint8_t addr, void *priv) { smbus_log("SMBus: read_byte(%02x)\n", addr); return(0xff); } +static uint8_t smbus_null_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) { smbus_log("SMBus: read_byte_cmd(%02x, %02x)\n", addr, cmd); return(0xff); } +static uint16_t smbus_null_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) { smbus_log("SMBus: read_word_cmd(%02x, %02x)\n", addr, cmd); return(0xffff); } +static uint8_t smbus_null_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv) { smbus_log("SMBus: read_block_cmd(%02x, %02x)\n", addr, cmd); return(0x00); }; +static void smbus_null_write_byte(uint8_t addr, uint8_t val, void *priv) { smbus_log("SMBus: write_byte(%02x, %02x)\n", addr, val); } +static void smbus_null_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) { smbus_log("SMBus: write_byte_cmd(%02x, %02x, %02x)\n", addr, cmd, val); } +static void smbus_null_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) { smbus_log("SMBus: write_word_cmd(%02x, %02x, %04x)\n", addr, cmd, val); } +static void smbus_null_write_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv) { smbus_log("SMBus: write_block_cmd(%02x, %02x, %02x)\n", addr, cmd, len); } +#endif + + +void +smbus_init(void) +{ + int c; + smbus_t *p, *q; + + if (!smbus_initialized) { + for (c=0; cprev; + free(p); + p = q; + } + p = NULL; + } + +#ifdef ENABLE_SMBUS_LOG + /* smbus[c] should be the only handler, pointing at the NULL catch handler. */ + p = (smbus_t *) malloc(sizeof(smbus_t)); + memset(p, 0, sizeof(smbus_t)); + smbus[c] = smbus_last[c] = p; + p->next = NULL; + p->prev = NULL; + p->read_byte = smbus_null_read_byte; + p->read_byte_cmd = smbus_null_read_byte_cmd; + p->read_word_cmd = smbus_null_read_word_cmd; + p->read_block_cmd = smbus_null_read_block_cmd; + p->write_byte = smbus_null_write_byte; + p->write_byte_cmd = smbus_null_write_byte_cmd; + p->write_word_cmd = smbus_null_write_word_cmd; + p->write_block_cmd = smbus_null_write_block_cmd; + p->priv = NULL; +#else + /* smbus[c] should be NULL. */ + smbus[c] = smbus_last[c] = NULL; +#endif + } +} + + +void +smbus_sethandler(uint8_t base, int size, + uint8_t (*read_byte)(uint8_t addr, void *priv), + uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + void (*write_byte)(uint8_t addr, uint8_t val, void *priv), + void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), + void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), + void (*write_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), + void *priv) +{ + int c; + smbus_t *p, *q = NULL; + + for (c = 0; c < size; c++) { + p = smbus_last[base + c]; + q = (smbus_t *) malloc(sizeof(smbus_t)); + memset(q, 0, sizeof(smbus_t)); + if (p) { + p->next = q; + q->prev = p; + } else { + smbus[base + c] = q; + q->prev = NULL; + } + + q->read_byte = read_byte; + q->read_byte_cmd = read_byte_cmd; + q->read_word_cmd = read_word_cmd; + q->read_block_cmd = read_block_cmd; + + q->write_byte = write_byte; + q->write_byte_cmd = write_byte_cmd; + q->write_word_cmd = write_word_cmd; + q->write_block_cmd = write_block_cmd; + + q->priv = priv; + q->next = NULL; + + smbus_last[base + c] = q; + } +} + + +void +smbus_removehandler(uint8_t base, int size, + uint8_t (*read_byte)(uint8_t addr, void *priv), + uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + void (*write_byte)(uint8_t addr, uint8_t val, void *priv), + void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), + void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), + void (*write_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), + void *priv) +{ + int c; + smbus_t *p; + + for (c = 0; c < size; c++) { + p = smbus[base + c]; + if (!p) + continue; + while(p) { + if ((p->read_byte == read_byte) && (p->read_byte_cmd == read_byte_cmd) && + (p->read_word_cmd == read_word_cmd) && (p->read_block_cmd == read_block_cmd) && + (p->write_byte == write_byte) && (p->write_byte_cmd == write_byte_cmd) && + (p->write_word_cmd == write_word_cmd) && (p->write_block_cmd == write_block_cmd) && + (p->priv == priv)) { + if (p->prev) + p->prev->next = p->next; + else + smbus[base + c] = p->next; + if (p->next) + p->next->prev = p->prev; + else + smbus_last[base + c] = p->prev; + free(p); + p = NULL; + break; + } + p = p->next; + } + } +} + + +void +smbus_handler(int set, uint8_t base, int size, + uint8_t (*read_byte)(uint8_t addr, void *priv), + uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + void (*write_byte)(uint8_t addr, uint8_t val, void *priv), + void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), + void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), + void (*write_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), + void *priv) +{ + if (set) + smbus_sethandler(base, size, read_byte, read_byte_cmd, read_word_cmd, read_block_cmd, write_byte, write_byte_cmd, write_word_cmd, write_block_cmd, priv); + else + smbus_removehandler(base, size, read_byte, read_byte_cmd, read_word_cmd, read_block_cmd, write_byte, write_byte_cmd, write_word_cmd, write_block_cmd, priv); +} + + +uint8_t +smbus_has_device(uint8_t addr) +{ + return(!!smbus[addr]); +} + + +uint8_t +smbus_read_byte(uint8_t addr) +{ + uint8_t ret = 0xff; + smbus_t *p; + int found = 0; + + p = smbus[addr]; + if (p) { + while(p) { + if (p->read_byte) { + ret &= p->read_byte(addr, p->priv); + found++; + } + p = p->next; + } + } + + return(ret); +} + +uint8_t +smbus_read_byte_cmd(uint8_t addr, uint8_t cmd) +{ + uint8_t ret = 0xff; + smbus_t *p; + int found = 0; + + p = smbus[addr]; + if (p) { + while(p) { + if (p->read_byte_cmd) { + ret &= p->read_byte_cmd(addr, cmd, p->priv); + found++; + } + p = p->next; + } + } + + return(ret); +} + +uint16_t +smbus_read_word_cmd(uint8_t addr, uint8_t cmd) +{ + uint16_t ret = 0xffff; + smbus_t *p; + int found = 0; + + p = smbus[addr]; + if (p) { + while(p) { + if (p->read_word_cmd) { + ret &= p->read_word_cmd(addr, cmd, p->priv); + found++; + } + p = p->next; + } + } + + return(ret); +} + +uint8_t +smbus_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data) +{ + uint8_t ret = 0; + smbus_t *p; + int found = 0; + + p = smbus[addr]; + if (p) { + while(p) { + if (p->read_block_cmd) { + ret = MAX(ret, p->read_block_cmd(addr, cmd, data, p->priv)); + found++; + } + p = p->next; + } + } + + return(ret); +} + + +void +smbus_write_byte(uint8_t addr, uint8_t val) +{ + smbus_t *p; + int found = 0; + + if (smbus[addr]) { + p = smbus[addr]; + while(p) { + if (p->write_byte) { + p->write_byte(addr, val, p->priv); + found++; + } + p = p->next; + } + } + + return; +} + +void +smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val) +{ + smbus_t *p; + int found = 0; + + if (smbus[addr]) { + p = smbus[addr]; + while(p) { + if (p->write_byte_cmd) { + p->write_byte_cmd(addr, cmd, val, p->priv); + found++; + } + p = p->next; + } + } + + return; +} + +void +smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val) +{ + smbus_t *p; + int found = 0; + + if (smbus[addr]) { + p = smbus[addr]; + while(p) { + if (p->write_word_cmd) { + p->write_word_cmd(addr, cmd, val, p->priv); + found++; + } + p = p->next; + } + } + + return; +} + +void +smbus_write_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len) +{ + smbus_t *p; + int found = 0; + + p = smbus[addr]; + if (p) { + while(p) { + if (p->write_block_cmd) { + p->write_block_cmd(addr, cmd, data, len, p->priv); + found++; + } + p = p->next; + } + } + + return; +} diff --git a/src/smbus.h b/src/smbus.h new file mode 100644 index 000000000..a4fec4a5c --- /dev/null +++ b/src/smbus.h @@ -0,0 +1,67 @@ +/* + * 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. + * + * Definitions for the SMBus handler. + * + * Version: @(#)smbus.h 1.0.0 2020/03/21 + * + * Authors: RichardG, + * + * Copyright 2020 RichardG. + */ +#ifndef EMU_SMBUS_H +# define EMU_SMBUS_H + + +extern void smbus_init(void); + +extern void smbus_sethandler(uint8_t base, int size, + uint8_t (*read_byte)(uint8_t addr, void *priv), + uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + void (*write_byte)(uint8_t addr, uint8_t val, void *priv), + void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), + void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), + void (*write_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), + void *priv); + +extern void smbus_removehandler(uint8_t base, int size, + uint8_t (*read_byte)(uint8_t addr, void *priv), + uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + void (*write_byte)(uint8_t addr, uint8_t val, void *priv), + void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), + void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), + void (*write_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), + void *priv); + +extern void smbus_handler(int set, uint8_t base, int size, + uint8_t (*read_byte)(uint8_t addr, void *priv), + uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + void (*write_byte)(uint8_t addr, uint8_t val, void *priv), + void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), + void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), + void (*write_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), + void *priv); + +extern uint8_t smbus_has_device(uint8_t addr); +extern uint8_t smbus_read_byte(uint8_t addr); +extern uint8_t smbus_read_byte_cmd(uint8_t addr, uint8_t cmd); +extern uint16_t smbus_read_word_cmd(uint8_t addr, uint8_t cmd); +extern uint8_t smbus_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data); +extern void smbus_write_byte(uint8_t addr, uint8_t val); +extern void smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val); +extern void smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val); +extern void smbus_write_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len); + + +#endif /*EMU_SMBUS_H*/ diff --git a/src/sound/midi.c b/src/sound/midi.c index 709b83faa..3c7da9966 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -25,18 +25,11 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_midi.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "plat_midi.h" #include "midi.h" -#include "midi_system.h" -#ifdef USE_FLUIDSYNTH -# include "midi_fluidsynth.h" -#endif -#ifdef USE_MUNT -# include "midi_mt32.h" -#endif #include "midi_input.h" diff --git a/src/sound/midi.h b/src/sound/midi.h index a0e89a50d..a41f369da 100644 --- a/src/sound/midi.h +++ b/src/sound/midi.h @@ -11,7 +11,7 @@ extern int midi_device_current; extern int midi_input_device_current; extern void (*input_msg)(void *p, uint8_t *msg); -extern int (*input_sysex)(void *p, uint8_t *buffer, uint32_t len, int abort); +extern int (*input_sysex)(void *p, uint8_t *buf, uint32_t len, int abort); extern void *midi_in_p; int midi_device_available(int card); @@ -96,4 +96,15 @@ extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #define MIDI_INPUT_NAME "MIDI Input Device" #define MIDI_INPUT_INTERNAL_NAME "midi_in" +#ifdef EMU_DEVICE_H +extern const device_t system_midi_device; +#ifdef USE_FLUIDSYNTH +extern const device_t fluidsynth_device; +#endif +#ifdef USE_MUNT +extern const device_t mt32_device; +extern const device_t cm32l_device; +#endif +#endif + #endif /*EMU_SOUND_MIDI_H*/ diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 822213d11..6a3f42c08 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -5,14 +5,13 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "../ui.h" +#include "86box.h" +#include "config.h" +#include "device.h" +#include "plat.h" +#include "plat_dynld.h" +#include "ui.h" #include "midi.h" -#include "midi_fluidsynth.h" #include "sound.h" diff --git a/src/sound/midi_fluidsynth.h b/src/sound/midi_fluidsynth.h deleted file mode 100644 index 518b1461d..000000000 --- a/src/sound/midi_fluidsynth.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t fluidsynth_device; diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index c62d98da2..1d6707d11 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -4,14 +4,13 @@ #include #include #include "munt/c_interface/c_interface.h" -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../rom.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "rom.h" +#include "plat.h" #include "sound.h" #include "midi.h" -#include "midi_mt32.h" extern void givealbuffer_midi(void *buf, uint32_t size); diff --git a/src/sound/midi_mt32.h b/src/sound/midi_mt32.h deleted file mode 100644 index 0aa012fa1..000000000 --- a/src/sound/midi_mt32.h +++ /dev/null @@ -1,2 +0,0 @@ -extern const device_t mt32_device; -extern const device_t cm32l_device; diff --git a/src/sound/midi_system.c b/src/sound/midi_system.c index 6ee56b01a..90c9bc36e 100644 --- a/src/sound/midi_system.c +++ b/src/sound/midi_system.c @@ -3,12 +3,11 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_midi.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "plat_midi.h" #include "midi.h" -#include "midi_system.h" #include "midi_input.h" diff --git a/src/sound/openal.c b/src/sound/openal.c index 185730a57..ad0d5f957 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -29,7 +29,7 @@ # include # include # include -#include "../86box.h" +#include "86box.h" #include "sound.h" #include "midi.h" diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index fd5631b12..f8681ff86 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -7,10 +7,10 @@ #include #include #include -#include "../86box.h" -#include "../dma.h" -#include "../pic.h" -#include "../timer.h" +#include "86box.h" +#include "dma.h" +#include "pic.h" +#include "timer.h" #include "sound.h" #include "snd_ad1848.h" diff --git a/src/sound/snd_ad1848.h b/src/sound/snd_ad1848.h index 6ec719475..0778cdfec 100644 --- a/src/sound/snd_ad1848.h +++ b/src/sound/snd_ad1848.h @@ -18,7 +18,7 @@ typedef struct ad1848_t int freq; pc_timer_t timer_count; - uint64_t timer_latch; + uint64_t timer_latch; int16_t buffer[SOUNDBUFLEN * 2]; int pos; diff --git a/src/sound/snd_adlib.c b/src/sound/snd_adlib.c index c0417f69d..29ace4e49 100644 --- a/src/sound/snd_adlib.c +++ b/src/sound/snd_adlib.c @@ -5,13 +5,12 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mca.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mca.h" +#include "device.h" #include "sound.h" -#include "snd_adlib.h" #include "snd_opl.h" diff --git a/src/sound/snd_adlib.h b/src/sound/snd_adlib.h deleted file mode 100644 index 4a6a161ca..000000000 --- a/src/sound/snd_adlib.h +++ /dev/null @@ -1,2 +0,0 @@ -extern const device_t adlib_device; -extern const device_t adlib_mca_device; diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index d4a29412d..c45f85b41 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -3,13 +3,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../dma.h" -#include "../pic.h" -#include "../device.h" -#include "../nvr.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "dma.h" +#include "pic.h" +#include "device.h" +#include "nvr.h" #include "sound.h" #include "filters.h" #include "snd_opl.h" diff --git a/src/sound/snd_adlibgold.h b/src/sound/snd_adlibgold.h deleted file mode 100644 index daea1b490..000000000 --- a/src/sound/snd_adlibgold.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t adgold_device; diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 2068710a9..5e87c993d 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -5,17 +5,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../nmi.h" -#include "../mem.h" -#include "../pci.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "nmi.h" +#include "mem.h" +#include "pci.h" +#include "timer.h" #include "sound.h" #include "midi.h" #include "snd_mpu401.h" -#include "snd_audiopci.h" #define N 16 diff --git a/src/sound/snd_audiopci.h b/src/sound/snd_audiopci.h deleted file mode 100644 index 66600ed24..000000000 --- a/src/sound/snd_audiopci.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t es1371_device; diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index 5d3e73c8d..829399932 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -5,11 +5,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "device.h" #include "sound.h" -#include "snd_cms.h" #define MASTER_CLOCK 7159090 diff --git a/src/sound/snd_cms.h b/src/sound/snd_cms.h deleted file mode 100644 index 41b6d6059..000000000 --- a/src/sound/snd_cms.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t cms_device; diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 9be46bb4c..946d8b7f6 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -7,12 +7,12 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "timer.h" #include "sound.h" #include "snd_emu8k.h" diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index c40c77f17..bcba6dc6f 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -5,16 +5,15 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../nmi.h" -#include "../pic.h" -#include "../dma.h" -#include "../timer.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "nmi.h" +#include "pic.h" +#include "dma.h" +#include "timer.h" +#include "device.h" #include "sound.h" #include "midi.h" -#include "snd_gus.h" enum { diff --git a/src/sound/snd_gus.h b/src/sound/snd_gus.h deleted file mode 100644 index 89e8ea331..000000000 --- a/src/sound/snd_gus.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t gus_device; diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index f368e3a21..1f1d57122 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -3,14 +3,13 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../lpt.h" -#include "../timer.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "lpt.h" +#include "timer.h" #include "sound.h" #include "filters.h" -#include "snd_lpt_dac.h" typedef struct lpt_dac_t { diff --git a/src/sound/snd_lpt_dac.h b/src/sound/snd_lpt_dac.h deleted file mode 100644 index d9f505353..000000000 --- a/src/sound/snd_lpt_dac.h +++ /dev/null @@ -1,2 +0,0 @@ -extern const lpt_device_t lpt_dac_device; -extern const lpt_device_t lpt_dac_stereo_device; diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index 72b5574af..973cb70de 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -3,14 +3,13 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../lpt.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "timer.h" +#include "lpt.h" #include "sound.h" #include "filters.h" -#include "snd_lpt_dss.h" typedef struct dss_t { diff --git a/src/sound/snd_lpt_dss.h b/src/sound/snd_lpt_dss.h deleted file mode 100644 index 07d37617a..000000000 --- a/src/sound/snd_lpt_dss.h +++ /dev/null @@ -1 +0,0 @@ -extern const lpt_device_t dss_device; diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index 86a4de83f..bdea9d911 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -27,14 +27,14 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../io.h" -#include "../machine/machine.h" -#include "../mca.h" -#include "../pic.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "86box_io.h" +#include "machine.h" +#include "mca.h" +#include "pic.h" +#include "timer.h" #include "sound.h" #include "snd_mpu401.h" #include "midi.h" @@ -155,10 +155,9 @@ MPU401_QueueByteEx(mpu_t *mpu, uint8_t data, int irq) return; } - if (mpu->queue_used == 0) { + if ((mpu->queue_used == 0) && !mpu->irq_mask) { mpu->state.irq_pending = 1; - if (irq) - picint(1 << mpu->irq); + picint(1 << mpu->irq); } if (mpu->queue_used < MPU401_QUEUE) { @@ -239,11 +238,16 @@ MPU401_Reset(mpu_t *mpu) { uint8_t i; +#ifdef DOSBOX_CODE if (mpu->mode == M_INTELLIGENT) { picintc(1 << mpu->irq); mpu->state.irq_pending = 0; } - +#else + picintc(1 << mpu->irq); + mpu->state.irq_pending = 0; +#endif + mpu->mode = M_INTELLIGENT; mpu->midi_thru = 0; mpu->state.rec = M_RECOFF; @@ -350,7 +354,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) return; /* In Intelligent mode, UART-only variants of the MPU-401 only support commands 0x3F and 0xFF. */ - if ((val != 0x3f) && (val != 0xff) && !mpu->intelligent) + if (!mpu->intelligent && (val != 0x3f) && (val != 0xff)) return; /* Hack: Enable midi through after the first mpu401 command is written. */ @@ -642,6 +646,7 @@ MPU401_WriteData(mpu_t *mpu, uint8_t val) static int length, cnt; uint8_t i; +#ifdef DOSBOX_CODE if (mpu->mode == M_UART) { midi_raw_out_byte(val); return; @@ -651,6 +656,12 @@ MPU401_WriteData(mpu_t *mpu, uint8_t val) mpu->state.command_byte = 0; return; } +#else + if (!mpu->intelligent || (mpu->mode == M_UART)) { + midi_raw_out_byte(val); + return; + } +#endif switch (mpu->state.command_byte) { /* 0xe# command data */ case 0x00: @@ -1073,7 +1084,7 @@ MPU401_ReadRaiseIRQ(mpu_t *mpu) picintc(1 << mpu->irq); mpu->state.irq_pending = 0; - if (mpu->queue_used) { + if (mpu->queue_used && !mpu->irq_mask) { /* Bytes remaining in queue, raise IRQ again. */ mpu->state.irq_pending = 1; picint(1 << mpu->irq); @@ -1097,10 +1108,17 @@ MPU401_ReadData(mpu_t *mpu) } /* Shouldn't this check mpu->mode? */ +#ifdef DOSBOX_CODE if (mpu->mode == M_UART) { MPU401_ReadRaiseIRQ(mpu); return ret; } +#else + if (!mpu->intelligent || (mpu->mode == M_UART)) { + MPU401_ReadRaiseIRQ(mpu); + return ret; + } +#endif if (mpu->state.rec_copy && !mpu->rec_queue_used) { mpu->state.rec_copy = 0; @@ -1204,10 +1222,17 @@ MPU401_Event(void *priv) mpu401_log("MPU-401 event callback\n"); +#ifdef DOSBOX_CODE if (mpu->mode == M_UART) { timer_disable(&mpu->mpu401_event_callback); return; } +#else + if (!mpu->intelligent || (mpu->mode == M_UART)) { + timer_disable(&mpu->mpu401_event_callback); + return; + } +#endif if (mpu->state.irq_pending) goto next_event; @@ -1365,7 +1390,11 @@ MPU401_InputMsg(void *p, uint8_t *msg) mpu401_log("MPU401 Input Msg\n"); +#ifdef DOSBOX_CODE if (mpu->mode == M_INTELLIGENT) { +#else + if (mpu->intelligent && (mpu->mode == M_INTELLIGENT)) { +#endif if (msg[0] < 0x80) { /* Expand running status */ msg[2] = msg[1]; @@ -1565,6 +1594,21 @@ MPU401_InputMsg(void *p, uint8_t *msg) } +void +mpu401_change_addr(mpu_t *mpu, uint16_t addr) +{ + if (mpu == NULL) + return; + if (mpu->addr) + io_removehandler(mpu->addr, 2, + mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + mpu->addr = addr; + if (mpu->addr) + io_sethandler(mpu->addr, 2, + mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); +} + + void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input) { @@ -1573,6 +1617,7 @@ mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input) mpu->queue_used = 0; mpu->queue_pos = 0; mpu->mode = M_UART; + mpu->addr = addr; /* Expalantion: MPU-401 starting in intelligent mode = Full MPU-401 intelligent mode capability; @@ -1581,8 +1626,8 @@ mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input) mpu->intelligent = (mode == M_INTELLIGENT) ? 1 : 0; mpu401_log("Starting as %s (mode is %s)\n", mpu->intelligent ? "INTELLIGENT" : "UART", (mode == M_INTELLIGENT) ? "INTELLIGENT" : "UART"); - if (addr) - io_sethandler(addr, 2, + if (mpu->addr) + io_sethandler(mpu->addr, 2, mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); io_sethandler(0x2A20, 16, NULL, NULL, NULL, imf_write, NULL, NULL, mpu); diff --git a/src/sound/snd_mpu401.h b/src/sound/snd_mpu401.h index 43ccc9bdb..99fe8b288 100644 --- a/src/sound/snd_mpu401.h +++ b/src/sound/snd_mpu401.h @@ -70,9 +70,10 @@ typedef enum RecState typedef struct mpu_t { - int midi_thru; + uint16_t addr; int uart_mode, intelligent, - irq, + irq, irq_mask, + midi_thru, queue_pos, queue_used; uint8_t rx_data, is_mca, status, @@ -139,7 +140,7 @@ typedef struct mpu_t uint32_t key[4]; } chanref[5], inputref[16]; pc_timer_t mpu401_event_callback, mpu401_eoi_callback, - mpu401_reset_callback; + mpu401_reset_callback; } mpu_t; extern int mpu401_standalone_enable, mpu401_already_loaded; @@ -149,6 +150,7 @@ extern const device_t mpu401_mca_device; extern uint8_t MPU401_ReadData(mpu_t *mpu); +extern void mpu401_change_addr(mpu_t *mpu, uint16_t addr); extern void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input); extern void mpu401_device_add(void); diff --git a/src/sound/snd_opl.c b/src/sound/snd_opl.c index 437ea62b5..6efc3fd5b 100644 --- a/src/sound/snd_opl.c +++ b/src/sound/snd_opl.c @@ -6,10 +6,10 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" #include "sound.h" #include "snd_opl.h" #include "snd_opl_backend.h" diff --git a/src/sound/snd_opl_backend.c b/src/sound/snd_opl_backend.c index 0a0e08d8e..2e8ae1df6 100644 --- a/src/sound/snd_opl_backend.c +++ b/src/sound/snd_opl_backend.c @@ -1,9 +1,17 @@ /* Copyright holders: Sarah Walker, SA1988 see COPYING for more details */ +#include +#include +#include +#include + +#include "86box.h" #include "nukedopl.h" #include "sound.h" #include "snd_opl_backend.h" +#include "cpu.h" +#include "mem.h" int opl_type = 0; @@ -129,6 +137,9 @@ opl_read(int nr, uint16_t addr) if (!(addr & 1)) return (opl[nr].status & opl[nr].status_mask) | (opl[nr].is_opl3 ? 0 : 0x06); + if (opl[nr].is_opl3 && ((addr & 3) == 3)) + return 0x00; + return opl[nr].is_opl3 ? 0 : 0xff; } diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index e10387df0..19aae50dc 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -5,21 +5,19 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../pic.h" -#include "../timer.h" -#include "../pit.h" -#include "../dma.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "pic.h" +#include "timer.h" +#include "pit.h" +#include "dma.h" +#include "device.h" #include "sound.h" #include "filters.h" #include "snd_mpu401.h" #include "snd_opl.h" -#include "snd_sb.h" #include "snd_sb_dsp.h" -#include "snd_pas16.h" /* Original PAS uses diff --git a/src/sound/snd_pas16.h b/src/sound/snd_pas16.h deleted file mode 100644 index d7a208faa..000000000 --- a/src/sound/snd_pas16.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t pas16_device; diff --git a/src/sound/snd_pssj.c b/src/sound/snd_pssj.c index 8714c540c..1f0000cb1 100644 --- a/src/sound/snd_pssj.c +++ b/src/sound/snd_pssj.c @@ -3,14 +3,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../timer.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "timer.h" +#include "device.h" #include "sound.h" -#include "snd_pssj.h" #include "snd_sn76489.h" diff --git a/src/sound/snd_pssj.h b/src/sound/snd_pssj.h deleted file mode 100644 index 71126f615..000000000 --- a/src/sound/snd_pssj.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t pssj_device; diff --git a/src/sound/snd_resid.cc b/src/sound/snd_resid.cc index a984323bd..931a4e1d0 100644 --- a/src/sound/snd_resid.cc +++ b/src/sound/snd_resid.cc @@ -3,7 +3,7 @@ #include #include #include "resid-fp/sid.h" -#include "../plat.h" +#include "plat.h" #include "snd_resid.h" diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index d1d43b3d4..25ed6b87d 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -24,20 +24,20 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mca.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mca.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "pic.h" #include "sound.h" #include "midi.h" #include "filters.h" #include "snd_emu8k.h" #include "snd_mpu401.h" #include "snd_opl.h" -#include "snd_sb.h" #include "snd_sb_dsp.h" //#define SB_DSP_RECORD_DEBUG @@ -679,9 +679,7 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; if (!(addr & 1)) - { mixer->index = val; - } else { // TODO: and this? 001h: @@ -721,6 +719,12 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->regs[0x46] = mixer->regs[0x47] = 8 << 4; mixer->regs[0x43] = 0; + + mixer->regs[0x83] = 0xff; + sb->dsp.sb_irqm8 = 0; + sb->dsp.sb_irqm16 = 0; + if (sb->mpu != NULL) + sb->mpu->irq_mask = 0; } else { @@ -728,6 +732,19 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) } switch (mixer->index) { + /* SB1/2 compatibility? */ + case 0x02: + mixer->regs[0x30] = ((mixer->regs[0x02] & 0xf) << 4) | 0x8; + mixer->regs[0x31] = ((mixer->regs[0x02] & 0xf) << 4) | 0x8; + break; + case 0x06: + mixer->regs[0x34] = ((mixer->regs[0x06] & 0xf) << 4) | 0x8; + mixer->regs[0x35] = ((mixer->regs[0x06] & 0xf) << 4) | 0x8; + break; + case 0x08: + mixer->regs[0x36] = ((mixer->regs[0x08] & 0xf) << 4) | 0x8; + mixer->regs[0x37] = ((mixer->regs[0x08] & 0xf) << 4) | 0x8; + break; /* SBPro compatibility. Copy values to sb16 registers. */ case 0x22: mixer->regs[0x30] = (mixer->regs[0x22] & 0xF0) | 0x8; @@ -746,7 +763,8 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->regs[0x37] = ((mixer->regs[0x28] & 0xf) << 4) | 0x8; break; case 0x0A: - mixer->regs[0x3A] = (mixer->regs[0x0A]*3)+10; + // mixer->regs[0x3A] = (mixer->regs[0x0A]*3)+10; + mixer->regs[0x3A] = (mixer->regs[0x0A] << 5) | 0x18; break; case 0x2E: mixer->regs[0x38] = (mixer->regs[0x2E] & 0xF0) | 0x8; @@ -774,6 +792,34 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) if (val & 0x40) sb_dsp_setdma16(&sb->dsp,6); if (val & 0x80) sb_dsp_setdma16(&sb->dsp,7); break; + + case 0x83: + /* Interrupt mask. */ + sb->dsp.sb_irqm8 = !(val & 0x01); + if (sb->dsp.sb_irqm8) + sb_irqc(&sb->dsp, 1); + sb->dsp.sb_irqm16 = !(val & 0x02); + if (sb->dsp.sb_irqm16) + sb_irqc(&sb->dsp, 0); + if (sb->mpu != NULL) { + sb->mpu->irq_mask = !(val & 0x04); + if (sb->mpu->irq_mask) { + picintc(1 << sb->mpu->irq); + sb->mpu->state.irq_pending = 0; + } + } + break; + + case 0x84: + /* MPU Control register, per the Linux source code. */ + if (sb->mpu != NULL) { + if ((val & 0x06) == 0x00) + mpu401_change_addr(sb->mpu, 0x330); + else if ((val & 0x06) == 0x04) + mpu401_change_addr(sb->mpu, 0x300); + else if ((val & 0x06) == 0x02) + mpu401_change_addr(sb->mpu, 0); + } } mixer->output_selector = mixer->regs[0x3C]; @@ -816,40 +862,56 @@ uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p) { sb_t *sb = (sb_t *)p; sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - uint8_t temp; + uint8_t temp, ret = 0xff; if (!(addr & 1)) - return mixer->index; + ret = mixer->index; sb_log("sb_ct1745: received register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); if (mixer->index>=0x30 && mixer->index<=0x47) - { - return mixer->regs[mixer->index]; - } - switch (mixer->index) + ret = mixer->regs[mixer->index]; + else switch (mixer->index) { case 0x00: - return mixer->regs[mixer->index]; + ret = mixer->regs[mixer->index]; + break; /*SB Pro compatibility*/ case 0x04: - return ((mixer->regs[0x33] >> 4) & 0x0f) | (mixer->regs[0x32] & 0xf0); + ret = ((mixer->regs[0x33] >> 4) & 0x0f) | (mixer->regs[0x32] & 0xf0); + break; case 0x0a: - return (mixer->regs[0x3a] - 10) / 3; + // ret = (mixer->regs[0x3a] - 10) / 3; + ret = (mixer->regs[0x3a] >> 5); + break; + case 0x02: + ret = ((mixer->regs[0x30] >> 4) & 0x0f); + break; + case 0x06: + ret = ((mixer->regs[0x34] >> 4) & 0x0f); + break; + case 0x08: + ret = ((mixer->regs[0x36] >> 4) & 0x0f); + break; case 0x22: - return ((mixer->regs[0x31] >> 4) & 0x0f) | (mixer->regs[0x30] & 0xf0); + ret = ((mixer->regs[0x31] >> 4) & 0x0f) | (mixer->regs[0x30] & 0xf0); + break; case 0x26: - return ((mixer->regs[0x35] >> 4) & 0x0f) | (mixer->regs[0x34] & 0xf0); + ret = ((mixer->regs[0x35] >> 4) & 0x0f) | (mixer->regs[0x34] & 0xf0); + break; case 0x28: - return ((mixer->regs[0x37] >> 4) & 0x0f) | (mixer->regs[0x36] & 0xf0); + ret = ((mixer->regs[0x37] >> 4) & 0x0f) | (mixer->regs[0x36] & 0xf0); + break; case 0x2e: - return ((mixer->regs[0x39] >> 4) & 0x0f) | (mixer->regs[0x38] & 0xf0); + ret = ((mixer->regs[0x39] >> 4) & 0x0f) | (mixer->regs[0x38] & 0xf0); + break; case 0x48: // Undocumented. The Creative Windows Mixer calls this after calling 3C (input selector). even when writing. // Also, the version I have (5.17) does not use the MIDI.L/R input selectors. it uses the volume to mute (Affecting the output, obviously) - return mixer->regs[mixer->index]; + ret = mixer->regs[mixer->index]; + break; case 0x80: /*TODO: Unaffected by mixer reset or soft reboot. @@ -858,37 +920,34 @@ uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p) switch (sb->dsp.sb_irqnum) { - case 2: return 1; - case 5: return 2; - case 7: return 4; - case 10: return 8; + case 2: ret = 1; break; + case 5: ret = 2; break; + case 7: ret = 4; break; + case 10: ret = 8; break; } break; case 0x81: - { /* TODO: Unaffected by mixer reset or soft reboot. - * Enabling multiple 8 or 16-bit DMA bits enables multiple DMA channels. - * Disabling all 8-bit DMA channel bits disables 8-bit DMA requests, - including translated 16-bit DMA requests. - * Disabling all 16-bit DMA channel bits enables translation of 16-bit DMA - requests to 8-bit ones, using the selected 8-bit DMA channel.*/ + * Enabling multiple 8 or 16-bit DMA bits enables multiple DMA channels. + * Disabling all 8-bit DMA channel bits disables 8-bit DMA requests, + including translated 16-bit DMA requests. + * Disabling all 16-bit DMA channel bits enables translation of 16-bit DMA + requests to 8-bit ones, using the selected 8-bit DMA channel.*/ - uint8_t result=0; - switch (sb->dsp.sb_8_dmanum) - { - case 0: result |= 1; break; - case 1: result |= 2; break; - case 3: result |= 8; break; - } - switch (sb->dsp.sb_16_dmanum) - { - case 5: result |= 0x20; break; - case 6: result |= 0x40; break; - case 7: result |= 0x80; break; - } - return result; - } + ret = 0; + switch (sb->dsp.sb_8_dmanum) { + case 0: ret |= 1; break; + case 1: ret |= 2; break; + case 3: ret |= 8; break; + } + switch (sb->dsp.sb_16_dmanum) + { + case 5: ret |= 0x20; break; + case 6: ret |= 0x40; break; + case 7: ret |= 0x80; break; + } + break; /* The Interrupt status register, addressed as register 82h on the Mixer register map, is used by the ISR to determine whether the interrupt is meant for it or for some other ISR, @@ -900,23 +959,59 @@ uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p) temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | 0x4000; if (sb->mpu) temp |= ((sb->mpu->state.irq_pending) ? 4 : 0); - return temp; + ret = temp; + break; + + case 0x83: + /* Interrupt mask. */ + ret = mixer->regs[mixer->index]; + break; + + case 0x84: + /* MPU Control. */ + if (sb->mpu == NULL) + ret = 0x02; + else { + if (sb->mpu->addr == 0x330) + ret = 0x00; + else if (sb->mpu->addr == 0x300) + ret = 0x04; + else if (sb->mpu->addr == 0) + ret = 0x02; + else + ret = 0x06; /* Should never happen. */ + } + break; + + case 0x90: + /* 3D Enhancement switch. */ + ret = mixer->regs[mixer->index]; + break; /* TODO: creative drivers read and write on 0xFE and 0xFF. not sure what they are supposed to be. */ - - + case 0xfd: + ret = 16; + break; + + case 0xfe: + ret = 6; + break; + default: sb_log("sb_ct1745: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } - return 0xff; + return ret; } void sb_ct1745_mixer_reset(sb_t* sb) { sb_ct1745_mixer_write(4,0,sb); sb_ct1745_mixer_write(5,0,sb); + + sb->mixer_sb16.regs[0xfd] = 16; + sb->mixer_sb16.regs[0xfe] = 6; } diff --git a/src/sound/snd_sb.h b/src/sound/snd_sb.h deleted file mode 100644 index feaec6c78..000000000 --- a/src/sound/snd_sb.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * - * Sound Blaster emulation. - * - * Version: @(#)sound_sb.h 1.0.3 2018/03/18 - * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#ifndef SOUND_SND_SB_H -# define SOUND_SND_SB_H - - -#define SADLIB 1 /* No DSP */ -#define SB1 2 /* DSP v1.05 */ -#define SB15 3 /* DSP v2.00 */ -#define SB2 4 /* DSP v2.01 - needed for high-speed DMA */ -#define SBPRO 5 /* DSP v3.00 */ -#define SBPRO2 6 /* DSP v3.02 + OPL3 */ -#define SB16 7 /* DSP v4.05 + OPL3 */ -#define SADGOLD 8 /* AdLib Gold */ -#define SND_WSS 9 /* Windows Sound System */ -#define SND_PAS16 10 /* Pro Audio Spectrum 16 */ - - -extern const device_t sb_1_device; -extern const device_t sb_15_device; -extern const device_t sb_mcv_device; -extern const device_t sb_2_device; -extern const device_t sb_pro_v1_device; -extern const device_t sb_pro_v2_device; -extern const device_t sb_pro_mcv_device; -extern const device_t sb_16_device; -extern const device_t sb_awe32_device; - - -#endif /*SOUND_SND_SB_H*/ diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 7ce08bfb9..5f86e79e6 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -12,17 +12,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../pic.h" -#include "../dma.h" -#include "../timer.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "pic.h" +#include "dma.h" +#include "timer.h" +#include "device.h" #include "filters.h" #include "sound.h" #include "midi.h" +#include "sound.h" #include "snd_mpu401.h" -#include "snd_sb.h" #include "snd_sb_dsp.h" @@ -182,9 +182,9 @@ void sb_irq(sb_dsp_t *dsp, int irq8) { sb_dsp_log("IRQ %i %02X\n", irq8, pic.mask); - if (irq8) + if (irq8 && !dsp->sb_irqm8) dsp->sb_irq8 = 1; - else + else if (!irq8 && !dsp->sb_irqm16) dsp->sb_irq16 = 1; picint(1 << dsp->sb_irqnum); diff --git a/src/sound/snd_sb_dsp.h b/src/sound/snd_sb_dsp.h index 9e60dfaac..96743e77e 100644 --- a/src/sound/snd_sb_dsp.h +++ b/src/sound/snd_sb_dsp.h @@ -1,3 +1,15 @@ +#define SADLIB 1 /* No DSP */ +#define SB1 2 /* DSP v1.05 */ +#define SB15 3 /* DSP v2.00 */ +#define SB2 4 /* DSP v2.01 - needed for high-speed DMA */ +#define SBPRO 5 /* DSP v3.00 */ +#define SBPRO2 6 /* DSP v3.02 + OPL3 */ +#define SB16 7 /* DSP v4.05 + OPL3 */ +#define SADGOLD 8 /* AdLib Gold */ +#define SND_WSS 9 /* Windows Sound System */ +#define SND_PAS16 10 /* Pro Audio Spectrum 16 */ + + typedef struct sb_dsp_t { int sb_type; @@ -49,6 +61,7 @@ typedef struct sb_dsp_t int sb_timei, sb_timeo; int sb_irq8, sb_irq16; + int sb_irqm8, sb_irqm16; uint8_t sb_asp_regs[256]; @@ -98,3 +111,4 @@ void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r); void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo); void sb_dsp_update(sb_dsp_t *dsp); +void sb_irqc(sb_dsp_t *dsp, int irq8); diff --git a/src/sound/snd_sn76489.c b/src/sound/snd_sn76489.c index 0f1b64ac1..1bcdcaf2d 100644 --- a/src/sound/snd_sn76489.c +++ b/src/sound/snd_sn76489.c @@ -4,9 +4,9 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "device.h" #include "sound.h" #include "snd_sn76489.h" diff --git a/src/sound/snd_speaker.c b/src/sound/snd_speaker.c index c6b9b1a8a..9423966db 100644 --- a/src/sound/snd_speaker.c +++ b/src/sound/snd_speaker.c @@ -20,9 +20,9 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" -#include "../pit.h" +#include "86box.h" +#include "timer.h" +#include "pit.h" #include "sound.h" #include "snd_speaker.h" diff --git a/src/sound/snd_ssi2001.c b/src/sound/snd_ssi2001.c index e20a08333..3f52e77a9 100644 --- a/src/sound/snd_ssi2001.c +++ b/src/sound/snd_ssi2001.c @@ -5,12 +5,11 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "device.h" #include "sound.h" #include "snd_resid.h" -#include "snd_ssi2001.h" typedef struct ssi2001_t diff --git a/src/sound/snd_ssi2001.h b/src/sound/snd_ssi2001.h deleted file mode 100644 index 83af6838a..000000000 --- a/src/sound/snd_ssi2001.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t ssi2001_device; diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index 7294107e3..5de5674b9 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -22,17 +22,16 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mca.h" -#include "../pic.h" -#include "../dma.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mca.h" +#include "pic.h" +#include "dma.h" +#include "device.h" #include "sound.h" #include "snd_ad1848.h" #include "snd_opl.h" -#include "snd_wss.h" /*530, 11, 3 - 530=23*/ diff --git a/src/sound/snd_ym7128.c b/src/sound/snd_ym7128.c index c255295c6..79db28b38 100644 --- a/src/sound/snd_ym7128.c +++ b/src/sound/snd_ym7128.c @@ -2,7 +2,7 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "snd_ym7128.h" diff --git a/src/sound/sound.c b/src/sound/sound.c index 9ccdefa99..df17cb865 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -23,28 +23,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../cdrom/cdrom.h" -#include "../disk/hdc_ide.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "cdrom.h" +#include "hdc_ide.h" +#include "plat.h" #include "sound.h" #include "midi.h" #include "snd_opl.h" -#include "snd_cms.h" -#include "snd_adlib.h" -#include "snd_adlibgold.h" -#include "snd_audiopci.h" -#include "snd_gus.h" #include "snd_mpu401.h" -#if defined(DEV_BRANCH) && defined(USE_PAS16) -# include "snd_pas16.h" -#endif -#include "snd_sb.h" #include "snd_sb_dsp.h" -#include "snd_ssi2001.h" -#include "snd_wss.h" #include "filters.h" diff --git a/src/sound/sound.h b/src/sound/sound.h index 5410a5602..34f5d0ca9 100644 --- a/src/sound/sound.h +++ b/src/sound/sound.h @@ -67,4 +67,46 @@ extern void givealbuffer(void *buf); extern void givealbuffer_cd(void *buf); +#ifdef EMU_DEVICE_H +/* AdLib and AdLib Gold */ +extern const device_t adlib_device; +extern const device_t adlib_mca_device; +extern const device_t adgold_device; + +/* Ensoniq AudioPCI */ +extern const device_t es1371_device; + +/* Creative Labs Game Blaster */ +extern const device_t cms_device; + +/* Gravis UltraSound and UltraSound Max */ +extern const device_t gus_device; + +#if defined(DEV_BRANCH) && defined(USE_PAS16) +/* Pro Audio Spectrum 16 */ +extern const device_t pas16_device; +#endif + +/* PSSJ - What is this device? */ +extern const device_t pssj_device; + +/* Creative Labs Sound Blaster */ +extern const device_t sb_1_device; +extern const device_t sb_15_device; +extern const device_t sb_mcv_device; +extern const device_t sb_2_device; +extern const device_t sb_pro_v1_device; +extern const device_t sb_pro_v2_device; +extern const device_t sb_pro_mcv_device; +extern const device_t sb_16_device; +extern const device_t sb_awe32_device; + +/* Innovation SSI-2001 */ +extern const device_t ssi2001_device; + +/* Windows Sound System */ +extern const device_t wss_device; +extern const device_t ncr_business_audio_device; +#endif + #endif /*EMU_SOUND_H*/ diff --git a/src/sst_flash.c b/src/sst_flash.c index 9826742f5..7cb3e3292 100644 --- a/src/sst_flash.c +++ b/src/sst_flash.c @@ -8,15 +8,15 @@ * * Implementation of an SST flash chip. * - * Version: @(#)sst_flash.c 1.0.19 2019/06/25 + * Version: @(#)sst_flash.c 1.0.1 2020/02/03 * * Authors: Sarah Walker, * Miran Grca, - * Melissa Goad, + * Melissa Goad, * * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. - * Copyright 2020 Melissa Goad. + * Copyright 2020 Melissa Goad. */ #include #include @@ -26,95 +26,163 @@ #include "86box.h" #include "device.h" #include "mem.h" -#include "machine/machine.h" +#include "machine.h" #include "timer.h" #include "nvr.h" #include "plat.h" + typedef struct sst_t { + uint8_t id, is_39, page_bytes, sdp; + int command_state, id_mode, - erase, dirty; + dirty; + + uint32_t size, mask, + page_mask, page_base; + uint8_t page_buffer[128]; uint8_t *array; - mem_mapping_t mapping[2], mapping_h[2]; + mem_mapping_t mapping[8], mapping_h[8]; + + pc_timer_t page_write_timer; } sst_t; static wchar_t flash_path[1024]; -#define SST_CHIP_ERASE 0x10 -#define SST_SECTOR_ERASE 0x30 -#define SST_ERASE 0x80 -#define SST_SET_ID_MODE 0x90 -#define SST_BYTE_PROGRAM 0xa0 -#define SST_CLEAR_ID_MODE 0xf0 +#define SST_CHIP_ERASE 0x10 /* Both 29 and 39, 6th cycle */ +#define SST_SDP_DISABLE 0x20 /* Only 29, Software data protect disable and write - treat as write */ +#define SST_SECTOR_ERASE 0x30 /* Only 39, 6th cycle */ +#define SST_SET_ID_MODE_ALT 0x60 /* Only 29, 6th cycle */ +#define SST_ERASE 0x80 /* Both 29 and 39 */ + /* With data 60h on 6th cycle, it's alt. ID */ +#define SST_SET_ID_MODE 0x90 /* Both 29 and 39 */ +#define SST_BYTE_PROGRAM 0xa0 /* Both 29 and 39 */ +#define SST_CLEAR_ID_MODE 0xf0 /* Both 29 and 39 */ + /* 1st cycle variant only on 39 */ - -static void -sst_new_command(sst_t *dev, uint8_t val) -{ - switch (val) { - case SST_CHIP_ERASE: - if (dev->erase) - memset(dev->array, 0xff, 0x20000); - dev->command_state = 0; - dev->erase = 0; - break; - - case SST_ERASE: - dev->command_state = 0; - dev->erase = 1; - break; - - case SST_SET_ID_MODE: - if (!dev->id_mode) - dev->id_mode = 1; - dev->command_state = 0; - dev->erase = 0; - break; - - case SST_BYTE_PROGRAM: - dev->command_state = 3; - dev->erase = 0; - break; - - case SST_CLEAR_ID_MODE: - if (dev->id_mode) - dev->id_mode = 0; - dev->command_state = 0; - dev->erase = 0; - break; - - default: - dev->command_state = 0; - dev->erase = 0; - } -} +#define SST_ID_MANUFACTURER 0xbf /* SST Manufacturer's ID */ +#define SST_ID_SST29EE010 0x07 +#define SST_ID_SST29LE_VE010 0x08 +#define SST_ID_SST29EE020 0x10 +#define SST_ID_SST29LE_VE020 0x12 +#define SST_ID_SST39SF512 0xb4 +#define SST_ID_SST39SF010 0xb5 +#define SST_ID_SST39SF020 0xb6 +#define SST_ID_SST39SF040 0xb7 static void sst_sector_erase(sst_t *dev, uint32_t addr) { - memset(&dev->array[addr & 0x1f000], 0xff, 4096); + memset(&dev->array[addr & (dev->mask & ~0xfff)], 0xff, 4096); dev->dirty = 1; } +static void +sst_new_command(sst_t *dev, uint32_t addr, uint8_t val) +{ + if (dev->command_state == 5) switch (val) { + case SST_CHIP_ERASE: + memset(dev->array, 0xff, 0x20000); + dev->command_state = 0; + break; + + case SST_SDP_DISABLE: + if (!dev->is_39) + dev->sdp = 0; + dev->command_state = 0; + break; + + case SST_SECTOR_ERASE: + if (dev->is_39) + sst_sector_erase(dev, addr); + dev->command_state = 0; + break; + + case SST_SET_ID_MODE_ALT: + dev->id_mode = 1; + dev->command_state = 0; + break; + + default: + dev->command_state = 0; + break; + } else switch (val) { + case SST_ERASE: + dev->command_state = 3; + break; + + case SST_SET_ID_MODE: + dev->id_mode = 1; + dev->command_state = 0; + break; + + case SST_BYTE_PROGRAM: + if (!dev->is_39) { + memset(dev->page_buffer, 0xff, 128); + dev->page_bytes = 0; + timer_on_auto(&dev->page_write_timer, 210.0); + } + dev->command_state = 6; + break; + + case SST_CLEAR_ID_MODE: + dev->id_mode = 0; + dev->command_state = 0; + break; + + default: + dev->command_state = 0; + break; + } +} + + +static void +sst_page_write(void *priv) +{ + sst_t *dev = (sst_t *) priv; + + memcpy(&(dev->array[dev->page_base]), dev->page_buffer, 128); + dev->dirty = 1; + dev->page_bytes = 0; + dev->command_state = 0; +} + + static uint8_t sst_read_id(uint32_t addr, void *p) { + sst_t *dev = (sst_t *) p; + if ((addr & 0xffff) == 0) - return 0xbf; /* SST */ + return SST_ID_MANUFACTURER; /* SST */ else if ((addr & 0xffff) == 1) - return 0xb5; /* 39SF010 */ + return dev->id; else return 0xff; } +static void +sst_buf_write(sst_t *dev, uint32_t addr, uint8_t val) +{ + dev->page_buffer[addr & 0x0000007f] = val; + timer_disable(&dev->page_write_timer); + dev->page_bytes++; + if (dev->page_bytes >= 128) + sst_page_write(dev); + else + timer_set_delay_u64(&dev->page_write_timer, 210 * TIMER_USEC); +} + + static void sst_write(uint32_t addr, uint8_t val, void *p) { @@ -122,33 +190,55 @@ sst_write(uint32_t addr, uint8_t val, void *p) switch (dev->command_state) { case 0: - if (val == 0xf0) { + case 3: + /* 1st and 4th Bus Write Cycle */ + if ((val == 0xf0) && dev->is_39 && (dev->command_state == 0)) { if (dev->id_mode) dev->id_mode = 0; - } else if ((addr & 0xffff) == 0x5555 && val == 0xaa) - dev->command_state = 1; - else dev->command_state = 0; + } else if (((addr & 0x7fff) == 0x5555) && (val == 0xaa)) + dev->command_state++; + else { + if (!dev->is_39 && !dev->sdp && (dev->command_state == 0)) { + /* 29 series, software data protection off, start loading the page. */ + dev->page_base = addr & dev->page_mask; /* First byte, A7 onwards of its address are the page mask. */ + dev->command_state = 7; + sst_buf_write(dev, addr, val); + } + dev->command_state = 0; + } break; case 1: - if ((addr & 0xffff) == 0x2aaa && val == 0x55) - dev->command_state = 2; + case 4: + /* 2nd and 5th Bus Write Cycle */ + if (((addr & 0x7fff) == 0x2aaa) && (val == 0x55)) + dev->command_state++; else dev->command_state = 0; break; case 2: - if ((addr & 0xffff) == 0x5555) - sst_new_command(dev, val); - else if ((val == SST_SECTOR_ERASE) && dev->erase) { - sst_sector_erase(dev, addr); - dev->command_state = 0; - } else + case 5: + /* 3rd and 6th Bus Write Cycle */ + if ((addr & 0x7fff) == 0x5555) + sst_new_command(dev, addr, val); + else dev->command_state = 0; break; - case 3: - dev->array[addr & 0x1ffff] = val; - dev->command_state = 0; - dev->dirty = 1; + case 6: + /* Page Load Cycle (29) / Data Write Cycle (39SF) */ + if (dev->is_39) { + dev->array[addr & dev->mask] = val; + dev->command_state = 0; + dev->dirty = 1; + } else { + dev->page_base = addr & dev->page_mask; /* First byte, A7 onwards of its address are the page mask. */ + dev->command_state++; + sst_buf_write(dev, addr, val); + } + break; + case 7: + if (!dev->is_39 && ((addr & dev->page_mask) == dev->page_base)) + sst_buf_write(dev, addr, val); break; } } @@ -214,19 +304,25 @@ sst_readl(uint32_t addr, void *p) static void sst_add_mappings(sst_t *dev) { - int i = 0; + int i = 0, count; uint32_t base, fbase; + uint32_t root_base; - for (i = 0; i < 2; i++) { - base = 0xe0000 + (i << 16); + count = dev->size >> 16; + root_base = 0x100000 - dev->size; + + for (i = 0; i < count; i++) { + base = root_base + (i << 16); fbase = base & biosmask; memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000); - mem_mapping_add(&(dev->mapping[i]), base, 0x10000, - sst_read, sst_readw, sst_readl, - sst_write, NULL, NULL, - dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev); + if (base >= 0xe0000) { + mem_mapping_add(&(dev->mapping[i]), base, 0x10000, + sst_read, sst_readw, sst_readl, + sst_write, NULL, NULL, + dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev); + } mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000), 0x10000, sst_read, sst_readw, sst_readl, sst_write, NULL, NULL, @@ -236,7 +332,7 @@ sst_add_mappings(sst_t *dev) static void * -sst_39sf010_init(const device_t *info) +sst_init(const device_t *info) { FILE *f; sst_t *dev = malloc(sizeof(sst_t)); @@ -260,31 +356,52 @@ sst_39sf010_init(const device_t *info) dev->array = (uint8_t *) malloc(biosmask + 1); memset(dev->array, 0xff, biosmask + 1); + dev->id = info->local; + dev->is_39 = (dev->id >= SST_ID_SST39SF512); + + if (dev->id == SST_ID_SST39SF512) + dev->size = 0x10000; + else if ((dev->id == SST_ID_SST29EE020) || (dev->id == SST_ID_SST29LE_VE020) || (dev->id == SST_ID_SST39SF020)) + dev->size = 0x40000; + else if (dev->id == SST_ID_SST39SF040) + dev->size = 0x80000; + else + dev->size = 0x20000; + dev->mask = dev->size - 1; + dev->page_mask = dev->mask & 0xffffff80; /* Filter out A0-A6. */ + dev->sdp = 1; + sst_add_mappings(dev); f = nvr_fopen(flash_path, L"rb"); if (f) { - if (fread(&(dev->array[0x00000]), 1, 0x20000, f) != 0x20000) - fatal("Less than 131072 bytes read from the SST Flash ROM file\n"); + if (fread(&(dev->array[0x00000]), 1, dev->size, f) != dev->size) + fatal("Less than %i bytes read from the SST Flash ROM file\n", dev->size); fclose(f); - } + } else + dev->dirty = 1; /* It is by definition dirty on creation. */ free(flash_name); free(machine_name); + if (!dev->is_39) + timer_add(&dev->page_write_timer, sst_page_write, dev, 0); + return dev; } static void -sst_39sf010_close(void *p) +sst_close(void *p) { FILE *f; sst_t *dev = (sst_t *)p; - f = nvr_fopen(flash_path, L"wb"); - fwrite(&(dev->array[0x00000]), 0x20000, 1, f); - fclose(f); + if (dev->dirty) { + f = nvr_fopen(flash_path, L"wb"); + fwrite(&(dev->array[0x00000]), dev->size, 1, f); + fclose(f); + } free(dev->array); dev->array = NULL; @@ -293,13 +410,49 @@ sst_39sf010_close(void *p) } +const device_t sst_flash_29ee010_device = +{ + "SST 29EE010 Flash BIOS", + 0, + SST_ID_SST29EE010, + sst_init, + sst_close, + NULL, + NULL, NULL, NULL, NULL +}; + + +const device_t sst_flash_29ee020_device = +{ + "SST 29EE020 Flash BIOS", + 0, + SST_ID_SST29EE020, + sst_init, + sst_close, + NULL, + NULL, NULL, NULL, NULL +}; + + const device_t sst_flash_39sf010_device = { "SST 39SF010 Flash BIOS", 0, - 0, - sst_39sf010_init, - sst_39sf010_close, + SST_ID_SST39SF010, + sst_init, + sst_close, + NULL, + NULL, NULL, NULL, NULL +}; + + +const device_t sst_flash_39sf020_device = +{ + "SST 39SF020 Flash BIOS", + 0, + SST_ID_SST39SF020, + sst_init, + sst_close, NULL, NULL, NULL, NULL, NULL }; diff --git a/src/sst_flash.h b/src/sst_flash.h index 809fc0c44..32607661c 100644 --- a/src/sst_flash.h +++ b/src/sst_flash.h @@ -8,10 +8,13 @@ * * Implementation of an SST flash chip. * - * Version: @(#)sst_flash.h 1.0.3 2020/01/14 + * Version: @(#)sst_flash.h 1.0.4 2020/02/03 * * Author: Melissa Goad, * Copyright 2020 Melissa Goad. */ +extern const device_t sst_flash_29ee010_device; +extern const device_t sst_flash_29ee020_device; extern const device_t sst_flash_39sf010_device; +extern const device_t sst_flash_39sf020_device; diff --git a/src/timer.h b/src/timer.h index 9941c3fdd..f75dc1727 100644 --- a/src/timer.h +++ b/src/timer.h @@ -1,7 +1,7 @@ #ifndef _TIMER_H_ #define _TIMER_H_ -#include "cpu/cpu.h" +#include "cpu.h" /* Maximum period, currently 1 second. */ #define MAX_USEC64 1000000ULL diff --git a/src/usb.c b/src/usb.c index 0577b5407..f962af311 100644 --- a/src/usb.c +++ b/src/usb.c @@ -5,7 +5,7 @@ #include #include #include -#include "io.h" +#include "86box_io.h" #include "mem.h" #include "usb.h" diff --git a/src/via_vt82c586b.c b/src/via_vt82c586b.c index a4eba54f4..3e2887ecc 100644 --- a/src/via_vt82c586b.c +++ b/src/via_vt82c586b.c @@ -6,7 +6,7 @@ * * Emulation of the VIA Apollo MVP3 southbridge * - * Version: @(#)via_vt82c586b.c 1.0.1 2020/01/17 + * Version: @(#)via_vt82c586b.c 1.0.2 2020/01/26 * * Authors: Sarah Walker, * Miran Grca, @@ -25,12 +25,12 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cdrom/cdrom.h" -#include "cpu/cpu.h" -#include "scsi/scsi_device.h" -#include "scsi/scsi_cdrom.h" +#include "cdrom.h" +#include "cpu.h" +#include "scsi_device.h" +#include "scsi_cdrom.h" #include "dma.h" -#include "io.h" +#include "86box_io.h" #include "device.h" #include "apm.h" #include "keyboard.h" @@ -40,11 +40,11 @@ #include "pci.h" #include "pic.h" #include "port_92.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "disk/hdc_ide_sff8038i.h" -#include "disk/zip.h" -#include "machine/machine.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "hdc_ide_sff8038i.h" +#include "zip.h" +#include "machine.h" #include "via_vt82c586b.h" @@ -62,7 +62,7 @@ typedef struct uint8_t power_regs[256]; sff8038i_t * bm[2]; nvr_t * nvr; - int nvr_enabled; + int nvr_enabled, slot; struct { @@ -221,13 +221,12 @@ via_vt82c586b_ide_handlers(via_vt82c586b_t *dev) static void -via_vt82c586b_bus_master_handlers(via_vt82c586b_t *dev, uint16_t old_base) +via_vt82c586b_bus_master_handlers(via_vt82c586b_t *dev) { - uint16_t base; - base = (dev->ide_regs[0x20] & 0xf0) | (dev->ide_regs[0x21] << 8); + uint16_t base = (dev->ide_regs[0x20] & 0xf0) | (dev->ide_regs[0x21] << 8); - sff_bus_master_handlers(dev->bm[0], old_base, base, (dev->ide_regs[0x04] & 1)); - sff_bus_master_handlers(dev->bm[1], old_base + 8, base + 8, (dev->ide_regs[0x04] & 1)); + sff_bus_master_handler(dev->bm[0], (dev->ide_regs[0x04] & 1), base); + sff_bus_master_handler(dev->bm[1], (dev->ide_regs[0x04] & 1), base + 8); } @@ -358,15 +357,11 @@ static void via_vt82c586b_write(int func, int addr, uint8_t val, void *priv) { via_vt82c586b_t *dev = (via_vt82c586b_t *) priv; - - uint16_t old_base, base; int c; if (func > 3) return; - old_base = (dev->ide_regs[0x20] & 0xf0) | (dev->ide_regs[0x21] << 8); - switch(func) { case 0: /* PCI-ISA bridge */ /* Read-only addresses */ @@ -379,8 +374,8 @@ via_vt82c586b_write(int func, int addr, uint8_t val, void *priv) case 0x04: dev->pci_isa_regs[0x04] = (val & 8) | 7; break; - case 0x06: - dev->pci_isa_regs[0x06] &= ~(val & 0xb0); + case 0x07: + dev->pci_isa_regs[0x07] &= ~(val & 0xb0); break; case 0x47: @@ -460,13 +455,12 @@ via_vt82c586b_write(int func, int addr, uint8_t val, void *priv) switch (addr) { case 0x04: - base = (dev->ide_regs[0x20] & 0xf0) | (dev->ide_regs[0x21] << 8); dev->ide_regs[0x04] = val & 0x85; via_vt82c586b_ide_handlers(dev); - via_vt82c586b_bus_master_handlers(dev, base); + via_vt82c586b_bus_master_handlers(dev); break; - case 0x06: - dev->ide_regs[0x06] &= ~(val & 0xb0); + case 0x07: + dev->ide_regs[0x07] &= ~(val & 0xf1); break; case 0x09: @@ -512,11 +506,11 @@ via_vt82c586b_write(int func, int addr, uint8_t val, void *priv) case 0x20: dev->ide_regs[0x20] = (val & 0xf0) | 1; - via_vt82c586b_bus_master_handlers(dev, old_base); + via_vt82c586b_bus_master_handlers(dev); break; case 0x21: dev->ide_regs[0x21] = val; - via_vt82c586b_bus_master_handlers(dev, old_base); + via_vt82c586b_bus_master_handlers(dev); break; case 0x3d: @@ -546,9 +540,10 @@ via_vt82c586b_write(int func, int addr, uint8_t val, void *priv) switch (addr) { case 0x04: dev->usb_regs[0x04] = val & 0x97; + usb_update_io_mapping(dev); break; case 0x07: - dev->usb_regs[0x07] = val & 0x7f; + dev->usb_regs[0x07] &= ~(val & 0x78); break; case 0x20: @@ -592,15 +587,15 @@ static void via_vt82c586b_t *dev = (via_vt82c586b_t *) malloc(sizeof(via_vt82c586b_t)); memset(dev, 0, sizeof(via_vt82c586b_t)); - pci_add_card(7, via_vt82c586b_read, via_vt82c586b_write, dev); + dev->slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, via_vt82c586b_read, via_vt82c586b_write, dev); dev->bm[0] = device_add_inst(&sff8038i_device, 1); - sff_set_slot(dev->bm[0], 7); + sff_set_slot(dev->bm[0], dev->slot); sff_set_irq_mode(dev->bm[0], 0); sff_set_irq_pin(dev->bm[0], PCI_INTA); dev->bm[1] = device_add_inst(&sff8038i_device, 2); - sff_set_slot(dev->bm[1], 7); + sff_set_slot(dev->bm[1], dev->slot); sff_set_irq_mode(dev->bm[1], 0); sff_set_irq_pin(dev->bm[1], PCI_INTA); diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index a62129f7d..2a4f9380d 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -21,14 +21,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" #include "video.h" -#include "vid_ati18800.h" #include "vid_ati_eeprom.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/video/vid_ati18800.h b/src/video/vid_ati18800.h deleted file mode 100644 index b41facab3..000000000 --- a/src/video/vid_ati18800.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t ati18800_wonder_device; -extern const device_t ati18800_vga88_device; -extern const device_t ati18800_device; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 28081efe9..29dd9cc4f 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -25,18 +25,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" #include "video.h" -#include "vid_ati28800.h" #include "vid_ati_eeprom.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_sc1502x_ramdac.h" #define VGAWONDERXL 1 diff --git a/src/video/vid_ati28800.h b/src/video/vid_ati28800.h deleted file mode 100644 index 9db0fa7bc..000000000 --- a/src/video/vid_ati28800.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -extern const device_t ati28800_device; -extern const device_t ati28800k_device; -extern const device_t compaq_ati28800_device; -#if defined(DEV_BRANCH) && defined(USE_XL24) -extern const device_t ati28800_wonderxl24_device; -#endif diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/vid_ati68860_ramdac.c index c814352b2..e0af06b45 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/vid_ati68860_ramdac.c @@ -41,19 +41,34 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_ati68860_ramdac.h" #include "vid_svga_render.h" -void -ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga) +typedef struct ati68860_ramdac_t { + uint8_t regs[16]; + void (*render)(struct svga_t *svga); + + int dac_addr, dac_pos; + int dac_r, dac_g; + PALETTE pal; + uint32_t pallook[2]; + + int ramdac_type; +} ati68860_ramdac_t; + + +void +ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) +{ + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + switch (addr) { case 0: svga_out(0x3c8, val, svga); @@ -143,8 +158,9 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_ } uint8_t -ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga) +ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga) { + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; uint8_t temp = 0; switch (addr) { @@ -180,8 +196,9 @@ ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga) void -ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type) +ati68860_set_ramdac_type(void *p, int type) { + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; int c; if (ramdac->ramdac_type != type) { @@ -211,6 +228,55 @@ ati68860_ramdac_init(const device_t *info) } +void +ati68860_ramdac_set_render(void *p, svga_t *svga) +{ + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + + svga->render = ramdac->render; +} + + +void +ati68860_ramdac_set_pallook(void *p, int i, uint32_t col) +{ + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + + ramdac->pallook[i] = col; +} + + +void +ati68860_hwcursor_draw(svga_t *svga, int displine) +{ + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; + int x, offset; + uint8_t dat; + uint32_t col0 = ramdac->pallook[0]; + uint32_t col1 = ramdac->pallook[1]; + + offset = svga->hwcursor_latch.xoff; + for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { + dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 1] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 1] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 2] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 2] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 3] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 3] ^= 0xFFFFFF; + dat >>= 2; + offset += 4; + } + + svga->hwcursor_latch.addr += 16; +} + + static void ati68860_ramdac_close(void *priv) { diff --git a/src/video/vid_ati68860_ramdac.h b/src/video/vid_ati68860_ramdac.h deleted file mode 100644 index 33e59ebc3..000000000 --- a/src/video/vid_ati68860_ramdac.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - * - * ATI 68860 RAMDAC emulation header (for Mach64) - * - * Version: @(#)vid_ati68860.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct ati68860_ramdac_t -{ - uint8_t regs[16]; - void (*render)(struct svga_t *svga); - - int dac_addr, dac_pos; - int dac_r, dac_g; - PALETTE pal; - uint32_t pallook[2]; - - int ramdac_type; -} ati68860_ramdac_t; - -extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga); -extern uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga); -extern void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type); - -extern const device_t ati68860_ramdac_device; diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index a7fee5958..ea499788d 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -20,11 +20,11 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../timer.h" -#include "../nvr.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" +#include "nvr.h" #include "vid_ati_eeprom.h" diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index a27621dde..576b2c774 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -23,20 +23,18 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../timer.h" -#include "../pci.h" -#include "../rom.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "timer.h" +#include "pci.h" +#include "rom.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_ati68860_ramdac.h" #include "vid_ati_eeprom.h" -#include "vid_ics2595.h" #ifdef CLAMP #undef CLAMP @@ -460,8 +458,6 @@ uint8_t mach64_in(uint16_t addr, void *p) void mach64_recalctimings(svga_t *svga) { mach64_t *mach64 = (mach64_t *)svga->p; - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; - ics2595_t *clock_gen = (ics2595_t *) svga->clock_gen; if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { @@ -471,7 +467,7 @@ void mach64_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; svga->rowoffset = (mach64->crtc_off_pitch >> 22); - svga->clock = (cpuclock * (double)(1ull << 32)) / clock_gen->output_clock; + svga->clock = (cpuclock * (double)(1ull << 32)) / ics2595_getclock(svga->clock_gen); svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; svga->linedbl = svga->rowcount = 0; svga->split = 0xffffff; @@ -479,7 +475,7 @@ void mach64_recalctimings(svga_t *svga) svga->rowcount = mach64->crtc_gen_cntl & 1; svga->rowoffset <<= 1; if (mach64->type == MACH64_GX) - svga->render = ramdac->render; + ati68860_ramdac_set_render(svga->ramdac, svga); switch ((mach64->crtc_gen_cntl >> 8) & 7) { case 1: @@ -1717,7 +1713,6 @@ static void mach64_vblank_start(svga_t *svga) uint8_t mach64_ext_readb(uint32_t addr, void *p) { mach64_t *mach64 = (mach64_t *)p; - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) mach64->svga.ramdac; uint8_t ret; if (!(addr & 0x400)) @@ -1843,9 +1838,9 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) case 0xc0: case 0xc1: case 0xc2: case 0xc3: if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), ramdac, &mach64->svga); + ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga); else - ret = ati68860_ramdac_in(addr & 3, ramdac, &mach64->svga); + ret = ati68860_ramdac_in(addr & 3, mach64->svga.ramdac, &mach64->svga); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: if (mach64->type == MACH64_VT2) @@ -2142,8 +2137,6 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; svga_t *svga = &mach64->svga; - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; - ics2595_t *clock_gen = (ics2595_t *) svga->clock_gen; mach64_log("mach64_ext_writeb : addr %08X val %02X\n", addr, val); @@ -2260,12 +2253,12 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0x60: case 0x61: case 0x62: case 0x63: WRITE8(addr, mach64->cur_clr0, val); if (mach64->type == MACH64_VT2) - ramdac->pallook[0] = makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff); + ati68860_ramdac_set_pallook(mach64->svga.ramdac, 0, makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff)); break; case 0x64: case 0x65: case 0x66: case 0x67: WRITE8(addr, mach64->cur_clr1, val); if (mach64->type == MACH64_VT2) - ramdac->pallook[1] = makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff); + ati68860_ramdac_set_pallook(mach64->svga.ramdac, 1, makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff)); break; case 0x68: case 0x69: case 0x6a: case 0x6b: WRITE8(addr, mach64->cur_offset, val); @@ -2295,11 +2288,11 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0x90: case 0x91: case 0x92: case 0x93: WRITE8(addr, mach64->clock_cntl, val); if (mach64->type == MACH64_GX) - ics2595_write(clock_gen, val & 0x40, val & 0xf); + ics2595_write(svga->clock_gen, val & 0x40, val & 0xf); else { pll_write(mach64, addr, val); - clock_gen->output_clock = mach64->pll_freq[mach64->clock_cntl & 3]; + ics2595_setclock(svga->clock_gen, mach64->pll_freq[mach64->clock_cntl & 3]); } svga_recalctimings(&mach64->svga); break; @@ -2327,14 +2320,14 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0xc0: case 0xc1: case 0xc2: case 0xc3: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, ramdac, &mach64->svga); + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, &mach64->svga); else - ati68860_ramdac_out(addr & 3, val, ramdac, &mach64->svga); + ati68860_ramdac_out(addr & 3, val, mach64->svga.ramdac, &mach64->svga); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: WRITE8(addr, mach64->dac_cntl, val); svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); - ati68860_set_ramdac_type(ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); + ati68860_set_ramdac_type(mach64->svga.ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: @@ -2407,7 +2400,6 @@ void mach64_ext_writel(uint32_t addr, uint32_t val, void *p) uint8_t mach64_ext_inb(uint16_t port, void *p) { mach64_t *mach64 = (mach64_t *)p; - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) mach64->svga.ramdac; uint8_t ret; switch (port) @@ -2494,9 +2486,9 @@ uint8_t mach64_ext_inb(uint16_t port, void *p) case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), ramdac, &mach64->svga); + ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga); else - ret = ati68860_ramdac_in(port & 3, ramdac, &mach64->svga); + ret = ati68860_ramdac_in(port & 3, mach64->svga.ramdac, &mach64->svga); break; case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: @@ -2564,7 +2556,6 @@ uint32_t mach64_ext_inl(uint16_t port, void *p) void mach64_ext_outb(uint16_t port, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) mach64->svga.ramdac; mach64_log("mach64_ext_outb : port %04X val %02X\n", port, val); switch (port) @@ -2647,9 +2638,9 @@ void mach64_ext_outb(uint16_t port, uint8_t val, void *p) case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, ramdac, &mach64->svga); + ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, &mach64->svga); else - ati68860_ramdac_out(port & 3, val, ramdac, &mach64->svga); + ati68860_ramdac_out(port & 3, val, mach64->svga.ramdac, &mach64->svga); break; case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: @@ -2789,34 +2780,6 @@ uint32_t mach64_readl(uint32_t addr, void *p) return svga_readl_linear(addr, svga); } -void mach64_hwcursor_draw(svga_t *svga, int displine) -{ - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; - int x, offset; - uint8_t dat; - uint32_t col0 = ramdac->pallook[0]; - uint32_t col1 = ramdac->pallook[1]; - - offset = svga->hwcursor_latch.xoff; - for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) - { - dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 1] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 1] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 2] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 2] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 3] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 3] ^= 0xFFFFFF; - dat >>= 2; - offset += 4; - } - svga->hwcursor_latch.addr += 16; -} #define CLAMP(x) do \ { \ @@ -3306,7 +3269,7 @@ static void *mach64_common_init(const device_t *info) svga_init(&mach64->svga, mach64, mach64->vram_size << 20, mach64_recalctimings, mach64_in, mach64_out, - mach64_hwcursor_draw, + NULL, mach64_overlay_draw); if (info->flags & DEVICE_PCI) @@ -3331,6 +3294,8 @@ static void *mach64_common_init(const device_t *info) mach64->pci_regs[0x33] = 0x00; mach64->svga.ramdac = device_add(&ati68860_ramdac_device); + mach64->svga.dac_hwcursor_draw = ati68860_hwcursor_draw; + mach64->svga.clock_gen = device_add(&ics2595_device); mach64->dst_cntl = 3; diff --git a/src/video/vid_ati_mach64.h b/src/video/vid_ati_mach64.h deleted file mode 100644 index c44444d7a..000000000 --- a/src/video/vid_ati_mach64.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - * - * ATi Mach64 graphics card emulation. - * - * Version: @(#)vid_ati_mach64.h 1.0.2 2018/03/18 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -extern const device_t mach64gx_isa_device; -extern const device_t mach64gx_vlb_device; -extern const device_t mach64gx_pci_device; -extern const device_t mach64vt2_device; diff --git a/src/video/vid_att20c49x_ramdac.c b/src/video/vid_att20c49x_ramdac.c index 1077c7e54..bce0a21c9 100644 --- a/src/video/vid_att20c49x_ramdac.c +++ b/src/video/vid_att20c49x_ramdac.c @@ -21,13 +21,21 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_att20c49x_ramdac.h" + + +typedef struct +{ + int type; + int state; + uint8_t ctrl; +} att49x_ramdac_t; + enum { @@ -35,9 +43,12 @@ enum ATT_492_3 }; + void -att49x_ramdac_out(uint16_t addr, uint8_t val, att49x_ramdac_t *ramdac, svga_t *svga) +att49x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { + att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; + switch (addr) { case 0x3C6: if (ramdac->state == 4) { @@ -93,10 +104,10 @@ att49x_ramdac_out(uint16_t addr, uint8_t val, att49x_ramdac_t *ramdac, svga_t *s uint8_t -att49x_ramdac_in(uint16_t addr, att49x_ramdac_t *ramdac, svga_t *svga) +att49x_ramdac_in(uint16_t addr, void *p, svga_t *svga) { - uint8_t temp; - temp = svga_in(addr, svga); + att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; + uint8_t temp = svga_in(addr, svga); switch (addr) { case 0x3C6: diff --git a/src/video/vid_att20c49x_ramdac.h b/src/video/vid_att20c49x_ramdac.h deleted file mode 100644 index 2a191afcf..000000000 --- a/src/video/vid_att20c49x_ramdac.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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. - * - * Header of the emulation of a Sierra SC1502X RAMDAC. - * - * Used by the TLIVESA1 driver for ET4000. - * - * Version: @(#)vid_sc1502x_ramdac.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct -{ - int type; - int state; - uint8_t ctrl; -} att49x_ramdac_t; - -extern void att49x_ramdac_out(uint16_t addr, uint8_t val, att49x_ramdac_t *ramdac, svga_t *svga); -extern uint8_t att49x_ramdac_in(uint16_t addr, att49x_ramdac_t *ramdac, svga_t *svga); - -extern const device_t att490_ramdac_device; -extern const device_t att492_ramdac_device; diff --git a/src/video/vid_av9194.c b/src/video/vid_av9194.c index ad3f706a1..bc48c08b7 100644 --- a/src/video/vid_av9194.c +++ b/src/video/vid_av9194.c @@ -21,9 +21,12 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "vid_av9194.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" +#include "video.h" +#include "vid_svga.h" float diff --git a/src/video/vid_av9194.h b/src/video/vid_av9194.h deleted file mode 100644 index 11760fe53..000000000 --- a/src/video/vid_av9194.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - * - * AV9194 clock generator emulation. - * - * Used by the S3 86c801 (V7-Mirage) card. - * - * Version: @(#)vid_av9194.c 1.0.1 2019/01/12 - * - * Authors: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - */ -float av9194_getclock(int clock, void *p); - -extern const device_t av9194_device; diff --git a/src/video/vid_bt48x_ramdac.c b/src/video/vid_bt48x_ramdac.c index 53dec87a6..20baf13eb 100644 --- a/src/video/vid_bt48x_ramdac.c +++ b/src/video/vid_bt48x_ramdac.c @@ -22,13 +22,29 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_bt48x_ramdac.h" + + +typedef struct +{ + PALETTE extpal; + uint32_t extpallook[256]; + uint8_t cursor32_data[256]; + uint8_t cursor64_data[1024]; + int hwc_y, hwc_x; + uint8_t cmd_r0; + uint8_t cmd_r1; + uint8_t cmd_r2; + uint8_t cmd_r3; + uint8_t cmd_r4; + uint8_t status; + uint8_t type; +} bt48x_ramdac_t; enum { @@ -69,8 +85,9 @@ bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga) void -bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt48x_ramdac_t *ramdac, svga_t *svga) +bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga) { + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; uint32_t o32; uint8_t *cd; uint16_t index; @@ -209,8 +226,9 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt48x_ramdac_t *r uint8_t -bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, bt48x_ramdac_t *ramdac, svga_t *svga) +bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) { + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; uint8_t temp = 0xff; uint8_t *cd; uint16_t index; @@ -330,6 +348,17 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, bt48x_ramdac_t *ramdac, svga_t } +void +bt48x_recalctimings(void *p, svga_t *svga) +{ + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; + + svga->interlace = ramdac->cmd_r2 & 0x08; + if (ramdac->cmd_r3 & 0x08) + svga->hdisp *= 2; /* x2 clock multiplier */ +} + + void bt48x_hwcursor_draw(svga_t *svga, int displine) { diff --git a/src/video/vid_bt48x_ramdac.h b/src/video/vid_bt48x_ramdac.h deleted file mode 100644 index ce952e1e8..000000000 --- a/src/video/vid_bt48x_ramdac.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - * - * Header of the emulation of the Brooktree BT484-BT485A - * true colour RAMDAC family. - * - * Version: @(#)vid_bt485_ramdac.h 1.0.5 2019/01/12 - * - * Authors: Miran Grca, - * TheCollector1995, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2018 TheCollector1995. - */ -typedef struct -{ - PALETTE extpal; - uint32_t extpallook[256]; - uint8_t cursor32_data[256]; - uint8_t cursor64_data[1024]; - int hwc_y, hwc_x; - uint8_t cmd_r0; - uint8_t cmd_r1; - uint8_t cmd_r2; - uint8_t cmd_r3; - uint8_t cmd_r4; - uint8_t status; - uint8_t type; -} bt48x_ramdac_t; - -extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt48x_ramdac_t *ramdac, svga_t *svga); -extern uint8_t bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, bt48x_ramdac_t *ramdac, svga_t *svga); -extern void bt48x_hwcursor_draw(svga_t *svga, int displine); - -extern const device_t bt484_ramdac_device; -extern const device_t att20c504_ramdac_device; -extern const device_t bt485_ramdac_device; -extern const device_t att20c505_ramdac_device; -extern const device_t bt485a_ramdac_device; diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 2cb05a1d2..91f04501b 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -22,14 +22,14 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_cga.h" #include "vid_cga_comp.h" diff --git a/src/video/vid_cga_comp.c b/src/video/vid_cga_comp.c index b5e87078f..0d4d5a0a5 100644 --- a/src/video/vid_cga_comp.c +++ b/src/video/vid_cga_comp.c @@ -23,9 +23,9 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" -#include "../mem.h" +#include "86box.h" +#include "timer.h" +#include "mem.h" #include "vid_cga.h" #include "vid_cga_comp.h" diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 65e2d66f0..4b3df6ddc 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -9,7 +9,7 @@ * Emulation of select Cirrus Logic cards (CL-GD 5428, * CL-GD 5429, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.32 2020/01/22 + * Version: @(#)vid_cl_54xx.c 1.0.34 2020/03/23 * * Authors: TheCollector1995, * Miran Grca, @@ -23,20 +23,21 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "mca.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "device.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_cl54xx.h" #define BIOS_GD5402_PATH L"roms/video/cirruslogic/avga2.rom" +#define BIOS_GD5402_ONBOARD_PATH L"roms/video/machines/cbm_sl386sx25/Commodore386SX-25_AVGA2.bin" #define BIOS_GD5420_PATH L"roms/video/cirruslogic/5420.vbi" #if defined(DEV_BRANCH) && defined(USE_CL5422) @@ -127,6 +128,10 @@ #define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02 #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01 +#define CL_GD5428_SYSTEM_BUS_MCA 5 +#define CL_GD5428_SYSTEM_BUS_VESA 6 +#define CL_GD5428_SYSTEM_BUS_ISA 7 + #define CL_GD5429_SYSTEM_BUS_VESA 5 #define CL_GD5429_SYSTEM_BUS_ISA 7 @@ -179,7 +184,7 @@ typedef struct gd54xx_t int unlock_special; } blt; - int pci, vlb; + int pci, vlb, mca; int countminusone; uint8_t pci_regs[256]; @@ -188,6 +193,9 @@ typedef struct gd54xx_t uint8_t fc; /* Feature Connector */ int card; + + uint8_t pos_regs[8]; + svga_t *mb_vga; uint32_t lfb_base; @@ -690,10 +698,19 @@ gd54xx_in(uint16_t addr, void *p) case 0x17: ret = svga->gdcreg[0x17] & ~(7 << 3); if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { - if (gd54xx->vlb) - ret |= (CL_GD5429_SYSTEM_BUS_VESA << 3); - else - ret |= (CL_GD5429_SYSTEM_BUS_ISA << 3); + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5428) { + if (gd54xx->vlb) + ret |= (CL_GD5428_SYSTEM_BUS_VESA << 3); + else if (gd54xx->mca) + ret |= (CL_GD5428_SYSTEM_BUS_MCA << 3); + else + ret |= (CL_GD5428_SYSTEM_BUS_ISA << 3); + } else { + if (gd54xx->vlb) + ret |= (CL_GD5429_SYSTEM_BUS_VESA << 3); + else + ret |= (CL_GD5429_SYSTEM_BUS_ISA << 3); + } } else { if (gd54xx->pci) ret |= (CL_GD543X_SYSTEM_BUS_PCI << 3); @@ -878,8 +895,14 @@ gd54xx_in(uint16_t addr, void *p) } else { if ((svga->gdcaddr < 2) && !gd54xx->unlocked) ret = (svga->gdcreg[svga->gdcaddr] & 0x0f); - else - ret = svga->gdcreg[svga->gdcaddr]; + else { + if (svga->gdcaddr == 0) + ret = gd543x_mmio_read(0xb8000, gd54xx); + else if (svga->gdcaddr == 1) + ret = gd543x_mmio_read(0xb8004, gd54xx); + else + ret = svga->gdcreg[svga->gdcaddr]; + } } break; case 0x3d4: @@ -893,7 +916,7 @@ gd54xx_in(uint16_t addr, void *p) !gd54xx->unlocked) ret = 0xff; else switch (svga->crtcreg) { - case 0x22: /*Graphis Data Latches Readback Register*/ + case 0x22: /*Graphics Data Latches Readback Register*/ /*Should this be & 7 if 8 byte latch is enabled? */ ret = svga->latch.b[svga->gdcreg[4] & 3]; break; @@ -959,8 +982,9 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) { svga_t *svga = &gd54xx->svga; uint32_t base, size; - - if (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + + if ((gd54xx->pci && (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) || + (gd54xx->mca && (!(gd54xx->pos_regs[2] & 1)))) { mem_mapping_disable(&svga->mapping); mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_disable(&gd54xx->mmio_mapping); @@ -993,7 +1017,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) } if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & 0x01) && - (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) { + (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { if (gd54xx->mmio_vram_overlap) { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000); @@ -1016,7 +1040,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) size = 16 * 1024 * 1024; else size = 4 * 1024 * 1024; - } else { /*VLB*/ + } else { /*VLB/ISA/MCA*/ base = 128*1024*1024; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) size = 16 * 1024 * 1024; @@ -1026,8 +1050,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&gd54xx->linear_mapping, base, size); - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && - (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */ else @@ -2891,6 +2914,33 @@ cl_pci_write(int func, int addr, uint8_t val, void *p) } } +static uint8_t +gd5428_mca_read(int port, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + return gd54xx->pos_regs[port & 7]; +} + +static void +gd5428_mca_write(int port, uint8_t val, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + if (port < 0x102) + return; + + gd54xx->pos_regs[port & 7] = val; + gd543x_recalc_mapping(gd54xx); +} + +static uint8_t +gd5428_mca_feedb(void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + return gd54xx->pos_regs[2] & 1; +} static void *gd54xx_init(const device_t *info) @@ -2903,14 +2953,18 @@ static void memset(gd54xx, 0, sizeof(gd54xx_t)); gd54xx->pci = !!(info->flags & DEVICE_PCI); - gd54xx->vlb = !!(info->flags & DEVICE_VLB); + gd54xx->vlb = !!(info->flags & DEVICE_VLB); + gd54xx->mca = !!(info->flags & DEVICE_MCA); gd54xx->rev = 0; gd54xx->has_bios = 1; switch (id) { case CIRRUS_ID_CLGD5402: - romfn = BIOS_GD5402_PATH; + if (info->local & 0x200) + romfn = BIOS_GD5402_ONBOARD_PATH; + else + romfn = BIOS_GD5402_PATH; break; case CIRRUS_ID_CLGD5420: @@ -2976,16 +3030,21 @@ static void romfn = BIOS_GD5480_PATH; break; } - - if (id >= CIRRUS_ID_CLGD5420) - vram = device_get_config_int("memory"); - else - vram = 0; - - if (vram) - gd54xx->vram_size = vram << 20; - else - gd54xx->vram_size = 1 << 19; + + if (info->flags & DEVICE_MCA) { + vram = 1; + gd54xx->vram_size = 1 << 20; + } else { + if (id >= CIRRUS_ID_CLGD5420) + vram = device_get_config_int("memory"); + else + vram = 0; + + if (vram) + gd54xx->vram_size = vram << 20; + else + gd54xx->vram_size = 1 << 19; + } gd54xx->vram_mask = gd54xx->vram_size - 1; @@ -3006,25 +3065,25 @@ static void mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); mem_mapping_set_p(&svga->mapping, gd54xx); - + mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, - gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, - gd543x_mmio_writeb, gd543x_mmio_writew, gd543x_mmio_writel, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); + gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, + gd543x_mmio_writeb, gd543x_mmio_writew, gd543x_mmio_writel, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); mem_mapping_disable(&gd54xx->mmio_mapping); mem_mapping_add(&gd54xx->linear_mapping, 0, 0, - gd54xx_readb_linear, gd54xx_readw_linear, gd54xx_readl_linear, - gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); + gd54xx_readb_linear, gd54xx_readw_linear, gd54xx_readl_linear, + gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_add(&gd54xx->aperture2_mapping, 0, 0, - gd5436_aperture2_readb, gd5436_aperture2_readw, gd5436_aperture2_readl, - gd5436_aperture2_writeb, gd5436_aperture2_writew, gd5436_aperture2_writel, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); + gd5436_aperture2_readb, gd5436_aperture2_readw, gd5436_aperture2_readl, + gd5436_aperture2_writeb, gd5436_aperture2_writew, gd5436_aperture2_writel, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); mem_mapping_disable(&gd54xx->aperture2_mapping); io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - + svga->hwcursor.yoff = 32; svga->hwcursor.xoff = 0; @@ -3065,6 +3124,12 @@ static void if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) gd54xx->unlocked = 1; + if (gd54xx->mca) { + gd54xx->pos_regs[0] = 0x7b; + gd54xx->pos_regs[1] = 0x91; + mca_add(gd5428_mca_read, gd5428_mca_write, gd5428_mca_feedb, gd54xx); + } + return gd54xx; } @@ -3307,7 +3372,7 @@ const device_t gd5402_onboard_device = { "Cirrus Logic GD-5402 (ACUMOS AVGA2) (On-Board)", DEVICE_AT | DEVICE_ISA, - CIRRUS_ID_CLGD5402, + CIRRUS_ID_CLGD5402 | 0x200, gd54xx_init, gd54xx_close, NULL, NULL, @@ -3397,6 +3462,20 @@ const device_t gd5428_vlb_device = gd5428_config }; +const device_t gd5428_mca_device = +{ + "Cirrus Logic CL-GD 5428 (IBM SVGA Adapter/A)", + DEVICE_MCA, + CIRRUS_ID_CLGD5428, + gd54xx_init, + gd54xx_close, + NULL, + gd5428_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + NULL +}; + const device_t gd5429_isa_device = { "Cirrus Logic CL-GD 5429 (ISA)", diff --git a/src/video/vid_cl54xx.h b/src/video/vid_cl54xx.h deleted file mode 100644 index 10c3eea0f..000000000 --- a/src/video/vid_cl54xx.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t gd5402_isa_device; -extern const device_t gd5402_onboard_device; -extern const device_t gd5420_isa_device; -#if defined(DEV_BRANCH) && defined(USE_CL5422) -extern const device_t gd5422_isa_device; -extern const device_t gd5424_vlb_device; -#endif -extern const device_t gd5426_vlb_device; -extern const device_t gd5428_isa_device; -extern const device_t gd5428_vlb_device; -extern const device_t gd5429_isa_device; -extern const device_t gd5429_vlb_device; -extern const device_t gd5430_vlb_device; -extern const device_t gd5430_pci_device; -extern const device_t gd5434_isa_device; -extern const device_t gd5434_vlb_device; -extern const device_t gd5434_pci_device; -extern const device_t gd5436_pci_device; -extern const device_t gd5440_onboard_pci_device; -extern const device_t gd5440_pci_device; -extern const device_t gd5446_pci_device; -extern const device_t gd5446_stb_pci_device; -extern const device_t gd5480_pci_device; \ No newline at end of file diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index 80393ecbb..93fad1cc8 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -22,14 +22,14 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../lpt.h" -#include "../pit.h" -#include "../mem.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "lpt.h" +#include "pit.h" +#include "mem.h" +#include "device.h" #include "video.h" #include "vid_cga.h" #include "vid_colorplus.h" diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index f17c526a1..d6bf29a72 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -24,14 +24,14 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_cga.h" #include "vid_cga_comp.h" diff --git a/src/video/vid_compaq_cga.h b/src/video/vid_compaq_cga.h deleted file mode 100644 index e6c684d52..000000000 --- a/src/video/vid_compaq_cga.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef VIDEO_COMPAQ_CGA_H -# define VIDEO_COMPAQ_CGA_H - - -#ifdef EMU_DEVICE_H -extern const device_t compaq_cga_device; -extern const device_t compaq_cga_2_device; -#endif - - -#endif /*VIDEO_COMPAQ_CGA_H*/ diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 05c617e2c..0b8753bd1 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -22,18 +22,17 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_ati_eeprom.h" #include "vid_ega.h" -#include "vid_ega_render.h" void ega_doblit(int y1, int y2, int wx, int wy, ega_t *ega); diff --git a/src/video/vid_ega.h b/src/video/vid_ega.h index 099fab4a0..170a91090 100644 --- a/src/video/vid_ega.h +++ b/src/video/vid_ega.h @@ -100,4 +100,32 @@ extern void ega_write(uint32_t addr, uint8_t val, void *p); extern uint8_t ega_read(uint32_t addr, void *p); +extern int firstline_draw, lastline_draw; +extern int displine; +extern int sc; + +extern uint32_t ma, ca; +extern int con, cursoron, cgablink; + +extern int scrollcache; + +extern uint8_t edatlookup[4][4]; + +#if defined(EMU_MEM_H) && defined(EMU_ROM_H) +void ega_render_blank(ega_t *ega); + +void ega_render_overscan_left(ega_t *ega); +void ega_render_overscan_right(ega_t *ega); + +void ega_render_text_40(ega_t *ega); +void ega_render_text_80(ega_t *ega); + +void ega_render_2bpp_lowres(ega_t *ega); +void ega_render_2bpp_highres(ega_t *ega); + +void ega_render_4bpp_lowres(ega_t *ega); +void ega_render_4bpp_highres(ega_t *ega); +#endif + + #endif /*VIDEO_EGA_H*/ diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index cf5ec7d50..471d3c531 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -20,14 +20,13 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" #include "video.h" #include "vid_ega.h" -#include "vid_ega_render.h" int diff --git a/src/video/vid_ega_render.h b/src/video/vid_ega_render.h deleted file mode 100644 index a905fc5dd..000000000 --- a/src/video/vid_ega_render.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - * - * EGA renderers. - * - * Version: @(#)vid_ega_render.h 1.0.3 2019/10/03 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - */ - -extern int firstline_draw, lastline_draw; -extern int displine; -extern int sc; - -extern uint32_t ma, ca; -extern int con, cursoron, cgablink; - -extern int scrollcache; - -extern uint8_t edatlookup[4][4]; - -void ega_render_blank(ega_t *ega); - -void ega_render_overscan_left(ega_t *ega); -void ega_render_overscan_right(ega_t *ega); - -void ega_render_text_40(ega_t *ega); -void ega_render_text_80(ega_t *ega); - -void ega_render_2bpp_lowres(ega_t *ega); -void ega_render_2bpp_highres(ega_t *ega); - -void ega_render_4bpp_lowres(ega_t *ega); -void ega_render_4bpp_highres(ega_t *ega); diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 3702098df..ad4bd13a9 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -8,7 +8,7 @@ * * Emulation of the Tseng Labs ET4000. * - * Version: @(#)vid_et4000.c 1.0.20 2018/10/04 + * Version: @(#)vid_et4000.c 1.0.20 2018/10/04e * * Authors: Fred N. van Kempen, * Miran Grca, @@ -42,18 +42,16 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../mca.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "86box_io.h" +#include "mca.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_sc1502x_ramdac.h" -#include "vid_et4000.h" #define BIOS_ROM_PATH L"roms/video/et4000/et4000.bin" diff --git a/src/video/vid_et4000.h b/src/video/vid_et4000.h deleted file mode 100644 index b0a566c61..000000000 --- a/src/video/vid_et4000.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - * - * Emulation of the Tseng Labs ET4000. - * - * Version: @(#)vid_et4000.c 1.0.9 2018/08/16 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#ifndef EMU_VID_ET4000_H -# define EMU_VID_ET4000_H - -extern const device_t et4000_isa_device; -extern const device_t et4000k_isa_device; -extern const device_t et4000k_tg286_isa_device; -extern const device_t et4000_mca_device; - -#endif /*EMU_VID_ET4000_H*/ \ No newline at end of file diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index c941d85fd..ccd8a6aee 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -25,19 +25,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "device.h" +#include "timer.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_icd2061.h" -#include "vid_stg_ramdac.h" #define BIOS_ROM_PATH_DIAMOND L"roms/video/et4000w32/et4000w32.bin" diff --git a/src/video/vid_et4000w32.h b/src/video/vid_et4000w32.h deleted file mode 100644 index 350933be5..000000000 --- a/src/video/vid_et4000w32.h +++ /dev/null @@ -1,5 +0,0 @@ -extern const device_t et4000w32p_vlb_device; -extern const device_t et4000w32p_pci_device; - -extern const device_t et4000w32p_cardex_vlb_device; -extern const device_t et4000w32p_cardex_pci_device; diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index 89f40da8c..9f76ada3e 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -21,17 +21,16 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../plat.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "plat.h" #include "video.h" -#include "vid_genius.h" #define BIOS_ROM_PATH L"roms/video/genius/8x12.bin" diff --git a/src/video/vid_genius.h b/src/video/vid_genius.h deleted file mode 100644 index e1388ec5c..000000000 --- a/src/video/vid_genius.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t genius_device; diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index fd3c85284..15538431f 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -21,17 +21,16 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../rom.h" -#include "../io.h" -#include "../timer.h" -#include "../lpt.h" -#include "../pit.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "mem.h" +#include "rom.h" +#include "86box_io.h" +#include "timer.h" +#include "lpt.h" +#include "pit.h" +#include "device.h" #include "video.h" -#include "vid_hercules.h" typedef struct { diff --git a/src/video/vid_hercules.h b/src/video/vid_hercules.h deleted file mode 100644 index 3c145e18f..000000000 --- a/src/video/vid_hercules.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t hercules_device; diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 2a4497bce..fc4f0ad97 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -21,16 +21,15 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../lpt.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "lpt.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" -#include "vid_herculesplus.h" /* extended CRTC registers */ diff --git a/src/video/vid_herculesplus.h b/src/video/vid_herculesplus.h deleted file mode 100644 index 72b47c35f..000000000 --- a/src/video/vid_herculesplus.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: John Elliott - see COPYING for more details -*/ -extern const device_t herculesplus_device; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index a0479a696..bb7be328c 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -21,18 +21,17 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../timer.h" -#include "../pic.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "mem.h" +#include "timer.h" +#include "pic.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_ht216.h" typedef struct ht216_t diff --git a/src/video/vid_ht216.h b/src/video/vid_ht216.h deleted file mode 100644 index abb15bba9..000000000 --- a/src/video/vid_ht216.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - * - * Video 7 VGA 1024i emulation header. - * - * Version: @(#)vid_ht216.h 1.0.1 2019/10/01 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2019 Sarah Walker. - * Copyright 2019 Miran Grca. - */ -extern const device_t g2_gc205_device; -extern const device_t v7_vga_1024i_device; -extern const device_t ht216_32_pb410a_device; diff --git a/src/video/vid_icd2061.c b/src/video/vid_icd2061.c index 1c1746df5..7dbe9d3ca 100644 --- a/src/video/vid_icd2061.c +++ b/src/video/vid_icd2061.c @@ -25,9 +25,18 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "vid_icd2061.h" +#include "86box.h" +#include "device.h" + + +typedef struct icd2061_t +{ + float freq[3]; + + int count, bit_count, + unlocked, state; + uint32_t data, ctrl; +} icd2061_t; #ifdef ENABLE_ICD2061_LOG @@ -51,10 +60,12 @@ icd2061_log(const char *fmt, ...) void -icd2061_write(icd2061_t *icd2061, int val) +icd2061_write(void *p, int val) { + icd2061_t *icd2061 = (icd2061_t *) p; + int nd, oc, nc; - int a, qa, q, pa, p, m, ps; + int a, qa, q, pa, p_, m, ps; nd = (val & 2) >> 1; /* Old data. */ oc = icd2061->state & 1; /* Old clock. */ @@ -96,14 +107,14 @@ icd2061_write(icd2061_t *icd2061, int val) m = ((icd2061->data >> 8) & 0x07); /* M (ICD2061) / R (ICS9161) */ qa = ((icd2061->data >> 1) & 0x7f); /* Q' (ICD2061) / M' (ICS9161) */ - p = pa + 3; /* P (ICD2061) / N (ICS9161) */ + p_ = pa + 3; /* P (ICD2061) / N (ICS9161) */ m = 1 << m; q = qa + 2; /* Q (ICD2061) / M (ICS9161) */ ps = (icd2061->ctrl & (1 << a)) ? 4 : 2; /* Prescale */ - icd2061->freq[a] = ((float)(p * ps) / (float)(q * m)) * 14318184.0f; + icd2061->freq[a] = ((float)(p_ * ps) / (float)(q * m)) * 14318184.0f; - icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p, m, q, a, icd2061->freq[a]); + icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p_, m, q, a, icd2061->freq[a]); } else if (a == 6) { icd2061->ctrl = ((icd2061->data >> 13) & 0xff); icd2061_log("ctrl = %02X\n", icd2061->ctrl); diff --git a/src/video/vid_icd2061.h b/src/video/vid_icd2061.h deleted file mode 100644 index 5b1c853e3..000000000 --- a/src/video/vid_icd2061.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - * - * ICD2061 clock generator emulation header. - * Also emulates the ICS9161 which is the same as the ICD2016, - * but without the need for tuning (which is irrelevant in - * emulation anyway). - * - * Used by ET4000w32/p (Diamond Stealth 32) and the S3 - * Vision964 family. - * - * Version: @(#)vid_icd2061.h 1.0.3 2018/10/04 - * - * Authors: Miran Grca, - * - * Copyright 2018 Miran Grca. - */ -typedef struct icd2061_t -{ - float freq[3]; - - int count, bit_count; - int unlocked, state; - uint32_t data, ctrl; -} icd2061_t; - -void icd2061_write(icd2061_t *icd2061, int val); -float icd2061_getclock(int clock, void *p); - -extern const device_t icd2061_device; -extern const device_t ics9161_device; - -/* The code is the same, the #define's are so that the correct name can be used. */ -#define ics9161_write icd2061_write -#define ics9161_getclock icd2061_getclock diff --git a/src/video/vid_ics2595.c b/src/video/vid_ics2595.c index 711fb4641..374dda318 100644 --- a/src/video/vid_ics2595.c +++ b/src/video/vid_ics2595.c @@ -21,9 +21,19 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "vid_ics2595.h" +#include "86box.h" +#include "device.h" + + +typedef struct ics2595_t +{ + int oldfs3, oldfs2; + int dat; + int pos, state; + + double clocks[16]; + double output_clock; +} ics2595_t; enum @@ -38,9 +48,11 @@ static int ics2595_div[4] = {8, 4, 2, 1}; void -ics2595_write(ics2595_t *ics2595, int strobe, int dat) +ics2595_write(void *p, int strobe, int dat) { - int d, n, l; + ics2595_t *ics2595 = (ics2595_t *) p; + int d, n; + int l; if (strobe) { if ((dat & 8) && !ics2595->oldfs3) { /*Data clock*/ @@ -94,6 +106,24 @@ ics2595_close(void *priv) } +double +ics2595_getclock(void *p) +{ + ics2595_t *ics2595 = (ics2595_t *) p; + + return ics2595->output_clock; +} + + +void +ics2595_setclock(void *p, double clock) +{ + ics2595_t *ics2595 = (ics2595_t *) p; + + ics2595->output_clock = clock; +} + + const device_t ics2595_device = { "ICS2595 clock chip", diff --git a/src/video/vid_ics2595.h b/src/video/vid_ics2595.h deleted file mode 100644 index 1453a38ba..000000000 --- a/src/video/vid_ics2595.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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. - * - * ICS2595 clock chip emulation header. Used by ATI Mach64. - * - * Version: @(#)vid_ics2595.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct ics2595_t -{ - int oldfs3, oldfs2; - int dat; - int pos, state; - - double clocks[16]; - double output_clock; -} ics2595_t; - -extern void ics2595_write(ics2595_t *ics2595, int strobe, int dat); - -extern const device_t ics2595_device; diff --git a/src/video/vid_im1024.c b/src/video/vid_im1024.c index 00954e2d6..301c0fd6e 100644 --- a/src/video/vid_im1024.c +++ b/src/video/vid_im1024.c @@ -54,17 +54,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../pit.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "timer.h" +#include "device.h" +#include "pit.h" +#include "plat.h" #include "video.h" #include "vid_pgc.h" -#include "vid_im1024.h" #define BIOS_ROM_PATH L"roms/video/im1024/im1024font.bin" diff --git a/src/video/vid_im1024.h b/src/video/vid_im1024.h deleted file mode 100644 index bf716b1d3..000000000 --- a/src/video/vid_im1024.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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. - * - * Header of the emulation of the ImageManager 1024 video - * controller. - * - * Version: @(#)vid_im1024.h 1.0.0 2019/03/03 - * - * Authors: John Elliott, - * - * Copyright 2019 John Elliott. - */ -extern const device_t im1024_device; diff --git a/src/video/vid_incolor.c b/src/video/vid_incolor.c index bd0d6e36f..d2373a836 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -21,16 +21,15 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../lpt.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "lpt.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" -#include "vid_incolor.h" /* extended CRTC registers */ diff --git a/src/video/vid_incolor.h b/src/video/vid_incolor.h deleted file mode 100644 index d75a97186..000000000 --- a/src/video/vid_incolor.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: John Elliott - see COPYING for more details -*/ -extern const device_t incolor_device; diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 2651e30ea..5e8abac8d 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -21,14 +21,14 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../lpt.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "lpt.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_mda.h" diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 9135450b2..fd27f7a54 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -18,16 +18,15 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "device.h" +#include "plat.h" #include "video.h" -#include "vid_mga.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -269,6 +268,7 @@ #define DWGCTRL_BLTMOD_MASK (0xf << 25) #define DWGCTRL_BLTMOD_BMONOLEF (0x0 << 25) #define DWGCTRL_BLTMOD_BFCOL (0x2 << 25) +#define DWGCTRL_BLTMOD_BU32BGR (0x3 << 25) #define DWGCTRL_BLTMOD_BMONOWF (0x4 << 25) #define DWGCTRL_BLTMOD_BU32RGB (0x7 << 25) #define DWGCTRL_BLTMOD_BUYUV (0xe << 25) @@ -1551,6 +1551,9 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) break; case REG_OPMODE: + thread_wait_mutex(mystique->dma.lock); + mystique->dma.state = DMA_STATE_IDLE; /* Interrupt DMA. */ + thread_release_mutex(mystique->dma.lock); mystique->dmamod = (val >> 2) & 3; mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); break; @@ -1958,6 +1961,7 @@ mystique_iload_write_l(uint32_t addr, uint32_t val, void *p) mystique_queue(mystique, 0, val, FIFO_WRITE_ILOAD_LONG); } + static void mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) { @@ -1995,7 +1999,9 @@ mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) } } -static uint8_t mystique_readb_linear(uint32_t addr, void *p) + +static uint8_t +mystique_readb_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; @@ -2009,7 +2015,10 @@ static uint8_t mystique_readb_linear(uint32_t addr, void *p) return svga->vram[addr & svga->vram_mask]; } -static uint16_t mystique_readw_linear(uint32_t addr, void *p) + + +static uint16_t +mystique_readw_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; @@ -2023,7 +2032,10 @@ static uint16_t mystique_readw_linear(uint32_t addr, void *p) return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; } -static uint32_t mystique_readl_linear(uint32_t addr, void *p) + + +static uint32_t +mystique_readl_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; @@ -2038,7 +2050,9 @@ static uint32_t mystique_readl_linear(uint32_t addr, void *p) return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; } -static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p) + +static void +mystique_writeb_linear(uint32_t addr, uint8_t val, void *p) { svga_t *svga = (svga_t *)p; @@ -2053,7 +2067,10 @@ static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p) svga->changedvram[addr >> 12] = changeframecount; svga->vram[addr] = val; } -static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p) + + +static void +mystique_writew_linear(uint32_t addr, uint16_t val, void *p) { svga_t *svga = (svga_t *)p; @@ -2068,7 +2085,10 @@ static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p) svga->changedvram[addr >> 12] = changeframecount; *(uint16_t *)&svga->vram[addr] = val; } -static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p) + + +static void +mystique_writel_linear(uint32_t addr, uint32_t val, void *p) { svga_t *svga = (svga_t *)p; @@ -2580,6 +2600,7 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) { svga_t *svga = &mystique->svga; uint32_t src, dst; + uint32_t dst2; uint64_t data64; int min_size = 8; uint32_t bltckey = mystique->dwgreg.fcol, bltcmsk = mystique->dwgreg.bcol; @@ -2877,6 +2898,45 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) mystique->dwgreg.iload_rem_count = size; break; + case DWGCTRL_BLTMOD_BU32BGR: + size += mystique->dwgreg.iload_rem_count; + while (size >= 32) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + dst2 = ((dst >> 16) & 0xff) | (dst & 0xff00) | ((dst & 0xff) << 16); /* BGR to RGB */ + + dst = bitop(data, dst2, mystique->dwgreg.dwgctrl_running); + + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("ILOAD RSTR/RPL BU32RGB pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } + + size = 0; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + + mystique->dwgreg.iload_rem_count = size; + break; + default: fatal("ILOAD DWGCTRL_ATYPE_RPL\n"); break; @@ -3063,6 +3123,21 @@ blit_iload_iload_high(mystique_t *mystique, uint32_t data, int size) size = 32; break; + case DWGCTRL_BLTMOD_BU32BGR: + r = ((data >> 16) & 0xff); + CLAMP(r); + g = ((data >> 8) & 0xff); + CLAMP(g); + b = (data & 0xff); + CLAMP(b); + + next_r = r; + next_g = g; + next_b = b; + + size = 32; + break; + default: fatal("blit_iload_iload_high bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); break; @@ -4332,6 +4407,7 @@ blit_iload_high(mystique_t *mystique) case DWGCTRL_ATYPE_RPL: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { case DWGCTRL_BLTMOD_BUYUV: + case DWGCTRL_BLTMOD_BU32BGR: mystique->dwgreg.length_cur = mystique->dwgreg.length; mystique->dwgreg.xdst = mystique->dwgreg.fxleft; mystique->dwgreg.iload_rem_data = 0; @@ -4531,9 +4607,12 @@ uint8_t mystique_pci_read(int func, int addr, void *p) case 0x03: ret = 0x05; break; case PCI_REG_COMMAND: - ret = mystique->pci_regs[PCI_REG_COMMAND]; break; /*Respond to IO and memory accesses*/ + ret = mystique->pci_regs[PCI_REG_COMMAND] | 0x80; break; /*Respond to IO and memory accesses*/ + case 0x05: + ret = 0x00; break; - case 0x07: ret = 0 << 1; break; /*Fast DEVSEL timing*/ + case 0x06: ret = 0x80; break; + case 0x07: ret = mystique->pci_regs[0x07]; break; /*Fast DEVSEL timing*/ case 0x08: ret = 0; break; /*Revision ID*/ case 0x09: ret = 0; break; /*Programming interface*/ @@ -4554,6 +4633,11 @@ uint8_t mystique_pci_read(int func, int addr, void *p) case 0x1a: ret = (mystique->iload_base >> 16) & 0x80; break; case 0x1b: ret = mystique->iload_base >> 24; break; + case 0x2c: ret = mystique->pci_regs[0x2c]; break; + case 0x2d: ret = mystique->pci_regs[0x2d]; break; + case 0x2e: ret = mystique->pci_regs[0x2e]; break; + case 0x2f: ret = mystique->pci_regs[0x2f]; break; + case 0x30: ret = mystique->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ case 0x31: ret = 0x00; break; case 0x32: ret = mystique->pci_regs[0x32]; break; @@ -4586,10 +4670,18 @@ mystique_pci_write(int func, int addr, uint8_t val, void *p) switch (addr) { case PCI_REG_COMMAND: - mystique->pci_regs[PCI_REG_COMMAND] = val & 0x23; + mystique->pci_regs[PCI_REG_COMMAND] = (val & 0x27) | 0x80; mystique_recalc_mapping(mystique); break; + case 0x07: + mystique->pci_regs[0x07] &= ~(val & 0x38); + break; + + case 0x0d: + mystique->pci_regs[0x0d] = val; + break; + case 0x11: mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); mystique_recalc_mapping(mystique); @@ -4636,7 +4728,16 @@ mystique_pci_write(int func, int addr, uint8_t val, void *p) mystique->int_line = val; return; - case 0x40: case 0x41: case 0x42: case 0x43: + case 0x40: + mystique->pci_regs[addr] = val & 0x3f; + break; + case 0x41: + mystique->pci_regs[addr] = val; + break; + case 0x42: + mystique->pci_regs[addr] = val & 0x1f; + break; + case 0x43: mystique->pci_regs[addr] = val; if (addr == 0x43) { if (val & 0x40) { @@ -4651,16 +4752,20 @@ mystique_pci_write(int func, int addr, uint8_t val, void *p) break; case 0x4c: case 0x4d: case 0x4e: case 0x4f: - mystique->pci_regs[addr-0x20] = val; + mystique->pci_regs[addr - 0x20] = val; break; - case 0x44: case 0x45: - mystique->pci_regs[addr] = val; + case 0x44: + mystique->pci_regs[addr] = val & 0xfc; + break; + case 0x45: + mystique->pci_regs[addr] = val & 0x3f; break; case 0x48: case 0x49: case 0x4a: case 0x4b: addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | (addr & 3); + /* pclog("mystique_ctrl_write_b(%04X, %02X)\n", addr, val); */ mystique_ctrl_write_b(addr, val, mystique); break; } @@ -4718,10 +4823,12 @@ mystique_init(const device_t *info) mem_mapping_disable(&mystique->iload_mapping); mystique->card = pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique); + mystique->pci_regs[0x06] = 0x80; + mystique->pci_regs[0x07] = 0 << 1; mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8]; - mystique->pci_regs[0x2d] = mystique->bios_rom.rom[0x7ff8]; - mystique->pci_regs[0x2e] = mystique->bios_rom.rom[0x7ff8]; - mystique->pci_regs[0x2f] = mystique->bios_rom.rom[0x7ff8]; + mystique->pci_regs[0x2d] = mystique->bios_rom.rom[0x7ff9]; + mystique->pci_regs[0x2e] = mystique->bios_rom.rom[0x7ffa]; + mystique->pci_regs[0x2f] = mystique->bios_rom.rom[0x7ffb]; mystique->svga.miscout = 1; mystique->pci_regs[0x41] = 0x01; /* vgaboot = 1 */ diff --git a/src/video/vid_mga.h b/src/video/vid_mga.h deleted file mode 100644 index 5291c81e4..000000000 --- a/src/video/vid_mga.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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. - * - * Matrox MGA graphics card emulation. - * - * Version: @(#)vid_mga.h 1.0.1 2020/01/18 - * - * Author: Sarah Walker, - * Copyright 2008-2020 Sarah Walker. - */ - -extern const device_t mystique_device; -extern const device_t mystique_220_device; diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 2addd8b32..09e56cb10 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -20,14 +20,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" -#include "vid_oak_oti.h" #include "vid_svga.h" #define BIOS_037C_PATH L"roms/video/oti/bios.bin" diff --git a/src/video/vid_oak_oti.h b/src/video/vid_oak_oti.h deleted file mode 100644 index e59d6bcc7..000000000 --- a/src/video/vid_oak_oti.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -extern const device_t oti037c_device; -extern const device_t oti067_device; -extern const device_t oti067_acer386_device; -extern const device_t oti067_ama932j_device; -extern const device_t oti077_device; diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 5333980de..ad05e824b 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -23,14 +23,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" -#include "vid_paradise.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/video/vid_paradise.h b/src/video/vid_paradise.h deleted file mode 100644 index bdc4734aa..000000000 --- a/src/video/vid_paradise.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -extern const device_t paradise_pvga1a_pc2086_device; -extern const device_t paradise_pvga1a_pc3086_device; -extern const device_t paradise_pvga1a_device; -extern const device_t paradise_wd90c11_megapc_device; -extern const device_t paradise_wd90c11_device; -extern const device_t paradise_wd90c30_device; diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 0dbaa9595..3db6b4521 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -79,14 +79,14 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../pit.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "timer.h" +#include "device.h" +#include "pit.h" +#include "plat.h" #include "video.h" #include "vid_cga.h" #include "vid_pgc.h" diff --git a/src/video/vid_pgc.h b/src/video/vid_pgc.h index 82ef899ea..d1e8c4ffa 100644 --- a/src/video/vid_pgc.h +++ b/src/video/vid_pgc.h @@ -181,7 +181,4 @@ extern void pgc_hndl_lut8(pgc_t *); extern void pgc_hndl_lut8rd(pgc_t *); -extern const device_t pgc_device; - - #endif /*VID_PGC_H*/ diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index f12239725..60d3a5f4b 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -21,24 +21,18 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "plat.h" #include "video.h" -#include "vid_s3.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_sdac_ramdac.h" -#include "vid_att20c49x_ramdac.h" -#include "vid_bt48x_ramdac.h" -#include "vid_av9194.h" -#include "vid_icd2061.h" -#include "../cpu/cpu.h" +#include "cpu.h" #define ROM_ORCHID_86C911 L"roms/video/s3/BIOS.BIN" #define ROM_METHEUS_86C928 L"roms/video/s3/928.vbi" @@ -1595,7 +1589,6 @@ uint8_t s3_in(uint16_t addr, void *p) void s3_recalctimings(svga_t *svga) { s3_t *s3 = (s3_t *)svga->p; - bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) svga->ramdac; int clk_sel = (svga->miscout >> 2) & 3; svga->hdisp = svga->hdisp_old; @@ -1616,11 +1609,9 @@ void s3_recalctimings(svga_t *svga) else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; if (!svga->rowoffset) svga->rowoffset = 256; - if (s3->chip == S3_VISION964 || s3->chip == S3_86C928) { - svga->interlace = ramdac->cmd_r2 & 0x08; - if (ramdac->cmd_r3 & 0x08) - svga->hdisp *= 2; /* x2 clock multiplier */ - } else + if (s3->chip == S3_VISION964 || s3->chip == S3_86C928) + bt48x_recalctimings(svga->ramdac, svga); + else svga->interlace = svga->crtc[0x42] & 0x20; if ((((svga->miscout >> 2) & 3) == 3) && (s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64)) @@ -3769,6 +3760,9 @@ static const device_config_t s3_config[] = { "4 MB", 4 }, + { + "8 MB", 8 + }, { "" } @@ -4034,7 +4028,7 @@ const device_t s3_phoenix_vision864_pci_device = const device_t s3_diamond_stealth64_vlb_device = { "S3 Trio64 (Diamond Stealth64 DRAM) VLB", - DEVICE_VLB, + DEVICE_PCI, S3_DIAMOND_STEALTH64_764, s3_init, s3_close, diff --git a/src/video/vid_s3.h b/src/video/vid_s3.h deleted file mode 100644 index a44d5cc27..000000000 --- a/src/video/vid_s3.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * - * Emulation of the S3 Trio32, S3 Trio64, and S3 Vision864 - * graphics cards. - * - * Version: @(#)vid_s3.h 1.0.4 2019/01/12 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -const device_t s3_orchid_86c911_isa_device; -const device_t s3_metheus_premier_86c928_isa_device; -const device_t s3_metheus_premier_86c928_vlb_device; -const device_t s3_v7mirage_86c801_isa_device; -const device_t s3_phoenix_86c805_vlb_device; -const device_t s3_bahamas64_vlb_device; -const device_t s3_bahamas64_pci_device; -const device_t s3_9fx_vlb_device; -const device_t s3_9fx_pci_device; -const device_t s3_phoenix_trio32_vlb_device; -const device_t s3_phoenix_trio32_pci_device; -const device_t s3_phoenix_trio64_vlb_device; -const device_t s3_phoenix_trio64_onboard_pci_device; -const device_t s3_phoenix_trio64_pci_device; -const device_t s3_phoenix_vision864_pci_device; -const device_t s3_phoenix_vision864_vlb_device; -const device_t s3_diamond_stealth64_pci_device; -const device_t s3_diamond_stealth64_vlb_device; -const device_t s3_diamond_stealth64_964_pci_device; -const device_t s3_diamond_stealth64_964_vlb_device; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 1e1bf4dad..358c3c749 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -23,16 +23,15 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "device.h" +#include "plat.h" #include "video.h" -#include "vid_s3_virge.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/video/vid_s3_virge.h b/src/video/vid_s3_virge.h deleted file mode 100644 index 2d340f649..000000000 --- a/src/video/vid_s3_virge.h +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t s3_virge_vlb_device; -extern const device_t s3_virge_pci_device; -extern const device_t s3_virge_988_vlb_device; -extern const device_t s3_virge_988_pci_device; -extern const device_t s3_virge_375_vlb_device; -extern const device_t s3_virge_375_pci_device; -extern const device_t s3_virge_375_4_vlb_device; -extern const device_t s3_virge_375_4_pci_device; diff --git a/src/video/vid_sc1502x_ramdac.c b/src/video/vid_sc1502x_ramdac.c index 75cb01995..882f892b0 100644 --- a/src/video/vid_sc1502x_ramdac.c +++ b/src/video/vid_sc1502x_ramdac.c @@ -29,12 +29,19 @@ #include "../timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_sc1502x_ramdac.h" + + +typedef struct +{ + int state; + uint8_t ctrl; +} sc1502x_ramdac_t; void -sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) +sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p; int oldbpp = 0; switch (addr) { @@ -102,10 +109,10 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t uint8_t -sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga) +sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga) { - uint8_t temp; - temp = svga_in(addr, svga); + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p; + uint8_t temp = svga_in(addr, svga); switch (addr) { case 0x3C6: diff --git a/src/video/vid_sc1502x_ramdac.h b/src/video/vid_sc1502x_ramdac.h deleted file mode 100644 index a5dcd234c..000000000 --- a/src/video/vid_sc1502x_ramdac.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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. - * - * Header of the emulation of a Sierra SC1502X RAMDAC. - * - * Used by the TLIVESA1 driver for ET4000. - * - * Version: @(#)vid_sc1502x_ramdac.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct -{ - int state; - uint8_t ctrl; -} sc1502x_ramdac_t; - -extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga); -extern uint8_t sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga); - -extern const device_t sc1502x_ramdac_device; diff --git a/src/video/vid_sdac_ramdac.c b/src/video/vid_sdac_ramdac.c index 44fb8d752..498daf432 100644 --- a/src/video/vid_sdac_ramdac.c +++ b/src/video/vid_sdac_ramdac.c @@ -21,13 +21,22 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_sdac_ramdac.h" + + +typedef struct sdac_ramdac_t +{ + uint16_t regs[256]; + int magic_count, + windex, rindex, + reg_ff, rs2; + uint8_t type, command; +} sdac_ramdac_t; static void @@ -96,8 +105,9 @@ sdac_reg_read(sdac_ramdac_t *ramdac, int reg) void -sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga) +sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) { + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; uint8_t rs = (addr & 0x03); rs |= (!!rs2 << 8); @@ -132,8 +142,9 @@ sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, sdac_ramdac_t *ramdac, svga uint8_t -sdac_ramdac_in(uint16_t addr, int rs2, sdac_ramdac_t *ramdac, svga_t *svga) +sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) { + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; uint8_t temp = 0xff; uint8_t rs = (addr & 0x03); rs |= (!!rs2 << 8); diff --git a/src/video/vid_sdac_ramdac.h b/src/video/vid_sdac_ramdac.h deleted file mode 100644 index e57d24519..000000000 --- a/src/video/vid_sdac_ramdac.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - * - * 87C716 'SDAC' true colour RAMDAC emulation header. - * - * Version: @(#)vid_sdac_ramdac.h 1.0.1 2019/09/13 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - */ -typedef struct sdac_ramdac_t -{ - uint16_t regs[256]; - int magic_count, - windex, rindex, - reg_ff, rs2; - uint8_t type, command; -} sdac_ramdac_t; - -extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga); -extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, sdac_ramdac_t *ramdac, svga_t *svga); -extern float sdac_getclock(int clock, void *p); - -extern const device_t gendac_ramdac_device; -extern const device_t sdac_ramdac_device; diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index 3ad4a2a54..7193783f1 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -19,17 +19,16 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../nmi.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "nmi.h" +#include "rom.h" +#include "device.h" #include "video.h" -#include "vid_sigma.h" #define ROM_SIGMA_FONT L"roms/video/sigma/sigma400_font.rom" diff --git a/src/video/vid_sigma.h b/src/video/vid_sigma.h deleted file mode 100644 index e331ad753..000000000 --- a/src/video/vid_sigma.h +++ /dev/null @@ -1,2 +0,0 @@ -extern const device_t sigma_device; - diff --git a/src/video/vid_stg_ramdac.c b/src/video/vid_stg_ramdac.c index 75722ef5a..4900ff5b8 100644 --- a/src/video/vid_stg_ramdac.c +++ b/src/video/vid_stg_ramdac.c @@ -27,7 +27,15 @@ #include "../timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_stg_ramdac.h" + + +typedef struct stg_ramdac_t +{ + int magic_count, index; + uint8_t regs[256]; + uint8_t command; +} stg_ramdac_t; + static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}}; @@ -82,8 +90,9 @@ stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) void -stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga) +stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { + stg_ramdac_t *ramdac = (stg_ramdac_t *) p; int didwrite, old; switch (addr) { @@ -136,8 +145,9 @@ stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga) uint8_t -stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga) +stg_ramdac_in(uint16_t addr, void *p, svga_t *svga) { + stg_ramdac_t *ramdac = (stg_ramdac_t *) p; uint8_t temp = 0xff; switch (addr) { diff --git a/src/video/vid_stg_ramdac.h b/src/video/vid_stg_ramdac.h deleted file mode 100644 index 76dbfcd3e..000000000 --- a/src/video/vid_stg_ramdac.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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. - * - * STG1702 true colour RAMDAC emulation header. - * - * Version: @(#)vid_stg_ramdac.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct stg_ramdac_t -{ - int magic_count, index; - uint8_t regs[256]; - uint8_t command; -} stg_ramdac_t; - -extern void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga); -extern uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga); -extern float stg_getclock(int clock, void *p); - -extern const device_t stg_ramdac_device; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 5314f33d8..efceec413 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -25,14 +25,14 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../io.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "timer.h" +#include "86box_io.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/video/vid_svga.h b/src/video/vid_svga.h index d04a1bb99..d2076c2eb 100644 --- a/src/video/vid_svga.h +++ b/src/video/vid_svga.h @@ -109,10 +109,10 @@ typedef struct svga_t void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr); float (*getclock)(int clock, void *p); - /*Called when VC=R18 and friends. If this returns zero then MA resetting - is skipped. Matrox Mystique in Power mode reuses this counter for - vertical line interrupt*/ - int (*line_compare)(struct svga_t *svga); + /* Called when VC=R18 and friends. If this returns zero then MA resetting + is skipped. Matrox Mystique in Power mode reuses this counter for + vertical line interrupt*/ + int (*line_compare)(struct svga_t *svga); /*If set then another device is driving the monitor output and the SVGA card should not attempt to display anything */ @@ -131,7 +131,6 @@ typedef struct svga_t dac_mask, dac_status, ksc5601_sbyte_mask; - int vertical_linedbl; /*Used to implement CRTC[0x17] bit 2 hsync divisor*/ @@ -188,3 +187,69 @@ enum { RAMDAC_6BIT = 0, RAMDAC_8BIT }; + + +/* We need a way to add a device with a pointer to a parent device so it can attach itself to it, and + possibly also a second ATi 68860 RAM DAC type that auto-sets SVGA render on RAM DAC render change. */ +extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); +extern uint8_t ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga); +extern void ati68860_set_ramdac_type(void *p, int type); +extern void ati68860_ramdac_set_render(void *p, svga_t *svga); +extern void ati68860_ramdac_set_pallook(void *p, int i, uint32_t col); +extern void ati68860_hwcursor_draw(svga_t *svga, int displine); + +extern void att49x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); +extern uint8_t att49x_ramdac_in(uint16_t addr, void *p, svga_t *svga); + +extern float av9194_getclock(int clock, void *p); + +extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga); +extern uint8_t bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga); +extern void bt48x_recalctimings(void *p, svga_t *svga); +extern void bt48x_hwcursor_draw(svga_t *svga, int displine); + +extern void icd2061_write(void *p, int val); +extern float icd2061_getclock(int clock, void *p); + +/* The code is the same, the #define's are so that the correct name can be used. */ +#define ics9161_write icd2061_write +#define ics9161_getclock icd2061_getclock + +extern void ics2595_write(void *p, int strobe, int dat); +extern double ics2595_getclock(void *p); +extern void ics2595_setclock(void *p, double clock); + +extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); +extern uint8_t sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga); + +extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga); +extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga); +extern float sdac_getclock(int clock, void *p); + +extern void stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); +extern uint8_t stg_ramdac_in(uint16_t addr, void *p, svga_t *svga); +extern float stg_getclock(int clock, void *p); + +extern void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); +extern uint8_t tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga); + + +#ifdef EMU_DEVICE_H +extern const device_t ati68860_ramdac_device; +extern const device_t att490_ramdac_device; +extern const device_t att492_ramdac_device; +extern const device_t av9194_device; +extern const device_t bt484_ramdac_device; +extern const device_t att20c504_ramdac_device; +extern const device_t bt485_ramdac_device; +extern const device_t att20c505_ramdac_device; +extern const device_t bt485a_ramdac_device; +extern const device_t gendac_ramdac_device; +extern const device_t ics2595_device; +extern const device_t icd2061_device; +extern const device_t ics9161_device; +extern const device_t sc1502x_ramdac_device; +extern const device_t sdac_ramdac_device; +extern const device_t stg_ramdac_device; +extern const device_t tkd8001_ramdac_device; +#endif diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 2448bd1fb..499c02f91 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -20,9 +20,9 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../timer.h" +#include "86box.h" +#include "mem.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 5c33070f2..e5db46fd0 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -23,45 +23,19 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../machine/machine.h" -#include "../mem.h" -#include "../device.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "machine.h" +#include "mem.h" +#include "device.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" -#include "vid_ati18800.h" -#include "vid_ati28800.h" -#include "vid_ati_mach64.h" #include "vid_cga.h" -#include "vid_cl54xx.h" -#include "vid_compaq_cga.h" #include "vid_ega.h" -#include "vid_et4000.h" -#include "vid_et4000w32.h" -#include "vid_genius.h" -#include "vid_hercules.h" -#include "vid_herculesplus.h" -#include "vid_ht216.h" -#include "vid_im1024.h" -#include "vid_incolor.h" #include "vid_colorplus.h" #include "vid_mda.h" -#include "vid_mga.h" -#include "vid_oak_oti.h" -#include "vid_paradise.h" -#include "vid_pgc.h" -#include "vid_s3.h" -#include "vid_s3_virge.h" -#include "vid_sigma.h" -#include "vid_tgui9440.h" -#include "vid_ti_cf62011.h" -#include "vid_tvga.h" -#include "vid_vga.h" -#include "vid_voodoo.h" -#include "vid_wy700.h" typedef struct { @@ -135,6 +109,7 @@ video_cards[] = { { "[ISA] VGA", "vga", &vga_device }, { "[ISA] Video 7 VGA 1024i", "v7_vga_1024i", &v7_vga_1024i_device }, { "[ISA] Wyse 700", "wy700", &wy700_device }, + { "[MCA] IBM 1MB SVGA Adapter/A (CL-GD 5428)", "ibm1mbsvga", &gd5428_mca_device }, { "[MCA] Tseng ET4000AX", "et4000mca", &et4000_mca_device }, { "[PCI] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_pci", &mach64gx_pci_device }, { "[PCI] ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device }, diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index a80ea293f..3290d25cf 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -60,20 +60,18 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../cpu/cpu.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "device.h" +#include "cpu.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_tkd8001_ramdac.h" -#include "vid_tgui9440.h" /*TGUI9400CXi has extended write modes, controlled by extended GDC registers : diff --git a/src/video/vid_tgui9440.h b/src/video/vid_tgui9440.h deleted file mode 100644 index 24208e913..000000000 --- a/src/video/vid_tgui9440.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t tgui9400cxi_device; -extern const device_t tgui9440_vlb_device; -extern const device_t tgui9440_pci_device; diff --git a/src/video/vid_ti_cf62011.c b/src/video/vid_ti_cf62011.c index e77ce27c9..dde469ba7 100644 --- a/src/video/vid_ti_cf62011.c +++ b/src/video/vid_ti_cf62011.c @@ -57,16 +57,14 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../video/video.h" -#include "../video/vid_vga.h" -#include "../video/vid_svga.h" -#include "vid_ti_cf62011.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "video.h" +#include "vid_svga.h" typedef struct { diff --git a/src/video/vid_ti_cf62011.h b/src/video/vid_ti_cf62011.h deleted file mode 100644 index 185f98511..000000000 --- a/src/video/vid_ti_cf62011.h +++ /dev/null @@ -1,4 +0,0 @@ -#if defined(DEV_BRANCH) && defined(USE_TI) -extern const device_t ti_cf62011_device; -#endif -extern const device_t ibm_ps1_2121_device; diff --git a/src/video/vid_tkd8001_ramdac.c b/src/video/vid_tkd8001_ramdac.c index e7c381a79..26118f1a4 100644 --- a/src/video/vid_tkd8001_ramdac.c +++ b/src/video/vid_tkd8001_ramdac.c @@ -21,18 +21,26 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../mem.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "mem.h" #include "video.h" #include "vid_svga.h" -#include "vid_tkd8001_ramdac.h" + + +typedef struct tkd8001_ramdac_t +{ + int state; + uint8_t ctrl; +} tkd8001_ramdac_t; void -tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga) +tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { + tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p; + switch (addr) { case 0x3C6: if (ramdac->state == 4) { @@ -70,8 +78,10 @@ tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t uint8_t -tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga) +tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga) { + tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p; + switch (addr) { case 0x3C6: if (ramdac->state == 4) diff --git a/src/video/vid_tkd8001_ramdac.h b/src/video/vid_tkd8001_ramdac.h deleted file mode 100644 index 3cfa166b0..000000000 --- a/src/video/vid_tkd8001_ramdac.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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. - * - * Trident TKD8001 RAMDAC emulation header. - * - * Version: @(#)vid_tkd8001_ramdac.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct tkd8001_ramdac_t -{ - int state; - uint8_t ctrl; -} tkd8001_ramdac_t; - -extern void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga); -extern uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga); - -extern const device_t tkd8001_ramdac_device; diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 8e2fd3bc3..301e03816 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -21,17 +21,15 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_tkd8001_ramdac.h" -#include "vid_tvga.h" #define TVGA8900B_ID 0x03 #define TVGA8900CLD_ID 0x33 diff --git a/src/video/vid_tvga.h b/src/video/vid_tvga.h deleted file mode 100644 index 6a4f0105a..000000000 --- a/src/video/vid_tvga.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t tvga8900b_device; -extern const device_t tvga8900d_device; diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index b01e9fa53..e38afa6d7 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -21,15 +21,14 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_vga.h" typedef struct vga_t diff --git a/src/video/vid_vga.h b/src/video/vid_vga.h deleted file mode 100644 index 533fdbb9a..000000000 --- a/src/video/vid_vga.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t vga_device; -extern const device_t ps1vga_device; -extern const device_t ps1vga_mca_device; diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 8e16ac236..e3c0d91a6 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -22,19 +22,18 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../device.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../plat.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "device.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "timer.h" +#include "device.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" -#include "vid_voodoo.h" #include "vid_voodoo_dither.h" #ifdef CLAMP diff --git a/src/video/vid_voodoo.h b/src/video/vid_voodoo.h deleted file mode 100644 index 9752899f7..000000000 --- a/src/video/vid_voodoo.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t voodoo_device; diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index b490dc4a6..00fb1b822 100644 --- a/src/video/vid_wy700.c +++ b/src/video/vid_wy700.c @@ -21,14 +21,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "device.h" #include "video.h" -#include "vid_wy700.h" #define WY700_XSIZE 1280 diff --git a/src/video/vid_wy700.h b/src/video/vid_wy700.h deleted file mode 100644 index 0c8a986fe..000000000 --- a/src/video/vid_wy700.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t wy700_device; diff --git a/src/video/video.c b/src/video/video.c index e7504f4b5..d3ed0794b 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -58,14 +58,14 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../config.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "config.h" +#include "timer.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" @@ -776,9 +776,11 @@ set_palette(PALETTE p) void destroy_bitmap(bitmap_t *b) { - if (b->dat != NULL) + if ((b != NULL) && (b->dat != NULL)) free(b->dat); - free(b); + + if (b != NULL) + free(b); } diff --git a/src/video/video.h b/src/video/video.h index a82993cfd..fad5359d4 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -190,4 +190,165 @@ extern uint32_t video_color_transform(uint32_t color); #endif +#ifdef EMU_DEVICE_H +/* ATi Mach64 */ +extern const device_t mach64gx_isa_device; +extern const device_t mach64gx_vlb_device; +extern const device_t mach64gx_pci_device; +extern const device_t mach64vt2_device; + +/* ATi 18800 */ +extern const device_t ati18800_wonder_device; +extern const device_t ati18800_vga88_device; +extern const device_t ati18800_device; + +/* ATi 28800 */ +extern const device_t ati28800_device; +extern const device_t ati28800k_device; +extern const device_t compaq_ati28800_device; +#if defined(DEV_BRANCH) && defined(USE_XL24) +extern const device_t ati28800_wonderxl24_device; +#endif + +/* Cirrus Logic CL-GD 54xx */ +extern const device_t gd5402_isa_device; +extern const device_t gd5402_onboard_device; +extern const device_t gd5420_isa_device; +#if defined(DEV_BRANCH) && defined(USE_CL5422) +extern const device_t gd5422_isa_device; +extern const device_t gd5424_vlb_device; +#endif +extern const device_t gd5426_vlb_device; +extern const device_t gd5428_isa_device; +extern const device_t gd5428_vlb_device; +extern const device_t gd5428_mca_device; +extern const device_t gd5429_isa_device; +extern const device_t gd5429_vlb_device; +extern const device_t gd5430_vlb_device; +extern const device_t gd5430_pci_device; +extern const device_t gd5434_isa_device; +extern const device_t gd5434_vlb_device; +extern const device_t gd5434_pci_device; +extern const device_t gd5436_pci_device; +extern const device_t gd5440_onboard_pci_device; +extern const device_t gd5440_pci_device; +extern const device_t gd5446_pci_device; +extern const device_t gd5446_stb_pci_device; +extern const device_t gd5480_pci_device; + +/* Compaq CGA */ +extern const device_t compaq_cga_device; +extern const device_t compaq_cga_2_device; + +/* Tseng ET4000AX */ +extern const device_t et4000_isa_device; +extern const device_t et4000k_isa_device; +extern const device_t et4000k_tg286_isa_device; +extern const device_t et4000_mca_device; + +/* Tseng ET4000-W32p */ +extern const device_t et4000w32p_vlb_device; +extern const device_t et4000w32p_pci_device; +extern const device_t et4000w32p_cardex_vlb_device; +extern const device_t et4000w32p_cardex_pci_device; + +/* MDSI Genius VHR */ +extern const device_t genius_device; + +/* Hercules */ +extern const device_t hercules_device; +extern const device_t herculesplus_device; +extern const device_t incolor_device; + +/* Headland GC-2xx/HT-2xx */ +extern const device_t g2_gc205_device; +extern const device_t v7_vga_1024i_device; +extern const device_t ht216_32_pb410a_device; + +/* Professional Graphics Controller */ +extern const device_t im1024_device; +extern const device_t pgc_device; + +/* Matrox Mystique */ +extern const device_t mystique_device; +extern const device_t mystique_220_device; + +/* Oak OTI-0x7 */ +extern const device_t oti037c_device; +extern const device_t oti067_device; +extern const device_t oti067_acer386_device; +extern const device_t oti067_ama932j_device; +extern const device_t oti077_device; + +/* Paradise/WD (S)VGA */ +extern const device_t paradise_pvga1a_pc2086_device; +extern const device_t paradise_pvga1a_pc3086_device; +extern const device_t paradise_pvga1a_device; +extern const device_t paradise_wd90c11_megapc_device; +extern const device_t paradise_wd90c11_device; +extern const device_t paradise_wd90c30_device; + +/* S3 9XX/8XX/Vision/Trio */ +const device_t s3_orchid_86c911_isa_device; +const device_t s3_metheus_premier_86c928_isa_device; +const device_t s3_metheus_premier_86c928_vlb_device; +const device_t s3_v7mirage_86c801_isa_device; +const device_t s3_phoenix_86c805_vlb_device; +const device_t s3_bahamas64_vlb_device; +const device_t s3_bahamas64_pci_device; +const device_t s3_9fx_vlb_device; +const device_t s3_9fx_pci_device; +const device_t s3_phoenix_trio32_vlb_device; +const device_t s3_phoenix_trio32_pci_device; +const device_t s3_phoenix_trio64_vlb_device; +const device_t s3_phoenix_trio64_onboard_pci_device; +const device_t s3_phoenix_trio64_pci_device; +const device_t s3_phoenix_vision864_pci_device; +const device_t s3_phoenix_vision864_vlb_device; +const device_t s3_diamond_stealth64_pci_device; +const device_t s3_diamond_stealth64_vlb_device; +const device_t s3_diamond_stealth64_964_pci_device; +const device_t s3_diamond_stealth64_964_vlb_device; + +/* S3 ViRGE */ +extern const device_t s3_virge_vlb_device; +extern const device_t s3_virge_pci_device; +extern const device_t s3_virge_988_vlb_device; +extern const device_t s3_virge_988_pci_device; +extern const device_t s3_virge_375_vlb_device; +extern const device_t s3_virge_375_pci_device; +extern const device_t s3_virge_375_4_vlb_device; +extern const device_t s3_virge_375_4_pci_device; + +/* Sigma Color 400 */ +extern const device_t sigma_device; + +/* Trident TGUI 94x0 */ +extern const device_t tgui9400cxi_device; +extern const device_t tgui9440_vlb_device; +extern const device_t tgui9440_pci_device; + +/* IBM PS/1 (S)VGA */ +#if defined(DEV_BRANCH) && defined(USE_TI) +extern const device_t ti_cf62011_device; +#endif +extern const device_t ibm_ps1_2121_device; + +/* Trident TVGA 8900 */ +extern const device_t tvga8900b_device; +extern const device_t tvga8900d_device; + +/* IBM VGA */ +extern const device_t vga_device; +extern const device_t ps1vga_device; +extern const device_t ps1vga_mca_device; + +/* 3DFX Voodoo Graphics */ +extern const device_t voodoo_device; + +/* Wyse 700 */ +extern const device_t wy700_device; +#endif + + #endif /*EMU_VIDEO_H*/ diff --git a/src/vnc.c b/src/vnc.c index 7b6040c4b..143b60964 100644 --- a/src/vnc.c +++ b/src/vnc.c @@ -25,7 +25,7 @@ #define HAVE_STDARG_H #include "86box.h" #include "device.h" -#include "video/video.h" +#include "video.h" #include "keyboard.h" #include "mouse.h" #include "plat.h" diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 851b7d287..fe204a04b 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -474,6 +474,9 @@ BEGIN CONTROL "ISABugger device",IDC_CHECK_BUGGER,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + CONTROL "POST card",IDC_CHECK_POSTCARD,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 + LTEXT "ISA RTC",IDT_1767,7,99,48,10 COMBOBOX IDC_COMBO_ISARTC,64,98,155,120, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 0e2287be5..bcc10bbd2 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.142 2020/01/18 +# Version: @(#)Makefile.mingw 1.0.143 2020/01/25 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -266,7 +266,7 @@ endif ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH := $(EXPATH) . cpu \ +VPATH := $(EXPATH) . cpu cpu_common \ cdrom chipset disk floppy game machine \ printer \ sound \ @@ -300,6 +300,17 @@ DEPFILE := win/.depends # Set up the correct toolchain flags. OPTS := $(EXTRAS) $(STUFF) +ifeq ($(WX), y) +OPTS += -I. \ + -Icpu -Icpu_common \ + -Icdrom -Ichipset -Idisk -Ifloppy -Igame -Imachine -Inetwork \ + -Iprinter -Isound -Iscsi -Ivideo -Ilang +else +OPTS += -iquote . \ + -iquote cpu -iquote cpu_common \ + -iquote cdrom -iquote chipset -iquote disk -iquote floppy -iquote game -iquote machine -iquote network \ + -iquote printer -iquote sound -iquote scsi -iquote video -iquote lang +endif ifdef EXFLAGS OPTS += $(EXFLAGS) endif @@ -338,7 +349,7 @@ else endif endif endif -AFLAGS := -msse2 -mfpmath=sse +AFLAGS := -msse2 -mfpmath=387 ifeq ($(ARM), y) DFLAGS := -march=armv7-a AOPTIM := @@ -467,7 +478,6 @@ endif ifeq ($(I686), y) OPTS += -DUSE_I686 -DEVBROBJ += m_at_socket8.o endif ifeq ($(LASERXT), y) @@ -539,8 +549,9 @@ endif # Final versions of the toolchain flags. CFLAGS := $(WX_FLAGS) $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ - $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ + $(AFLAGS) -pipe -fomit-frame-pointer -mstackrealign -Wall \ -fno-strict-aliasing +# -funroll-loops # Add freetyp2 references through pkgconfig CFLAGS := $(CFLAGS) `pkg-config.exe --cflags freetype2` @@ -559,7 +570,8 @@ INTELOBJ := intel_flash.o \ intel_sio.o intel_piix.o CPUOBJ := cpu.o cpu_table.o \ - 808x.o 386.o \ + 808x.o \ + 386.o 386_common.o \ 386_dynarec.o \ x86seg.o x87.o \ $(DYNARECOBJ) @@ -582,14 +594,18 @@ MCHOBJ := machine.o machine_table.o \ m_ps2_isa.o m_ps2_mca.o \ m_at_compaq.o \ m_at_286_386sx.o m_at_386dx_486.o \ - m_at_socket4_5.o m_at_socket7_s7.o + m_at_socket4_5.o m_at_socket7_s7.o \ + m_at_socket8.o -DEVOBJ := bugger.o ibm_5161.o isamem.o isartc.o lpt.o $(SERIAL) \ +DEVOBJ := bugger.o hwm.o hwm_w83781d.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ sio_acc3221.o \ sio_fdc37c66x.o sio_fdc37c669.o \ sio_fdc37c93x.o \ - sio_pc87306.o sio_w83877f.o \ + sio_pc87306.o \ + sio_w83787f.o \ + sio_w83877f.o sio_w83977f.o \ sio_um8669f.o \ + smbus.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ gameport.o \ @@ -626,7 +642,8 @@ SCSIOBJ := scsi.o scsi_device.o \ scsi_cdrom.o scsi_disk.o \ scsi_x54x.o \ scsi_aha154x.o scsi_buslogic.o \ - scsi_ncr5380.o scsi_ncr53c8xx.o + scsi_ncr5380.o scsi_ncr53c8xx.o \ + scsi_spock.o NETOBJ := network.o \ net_pcap.o \ @@ -788,7 +805,7 @@ all: $(PROG).exe pcap_if.exe $(PROG).exe: $(OBJ) 86Box.res @echo Linking $(PROG).exe .. - @$(CC) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) + @$(CC) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -pipe ifneq ($(DEBUG), y) @$(STRIP) $(PROG).exe endif diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw index 62713f351..23466a8f6 100644 --- a/src/win/Makefile_ndr.mingw +++ b/src/win/Makefile_ndr.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.141 2020/01/14 +# Version: @(#)Makefile.mingw 1.0.142 2020/01/25 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -266,7 +266,7 @@ endif ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH := $(EXPATH) . cpu_new \ +VPATH := $(EXPATH) . cpu_new cpu_common \ cdrom chipset disk floppy game machine \ printer \ sound \ @@ -300,6 +300,17 @@ DEPFILE := win/.depends # Set up the correct toolchain flags. OPTS := $(EXTRAS) $(STUFF) +ifeq ($(WX), y) +OPTS += -I. \ + -Icpu_new -Icpu_common \ + -Icdrom -Ichipset -Idisk -Ifloppy -Igame -Imachine -Inetwork \ + -Iprinter -Isound -Iscsi -Ivideo -Ilang +else +OPTS += -iquote . \ + -iquote cpu_new -iquote cpu_common \ + -iquote cdrom -iquote chipset -iquote disk -iquote floppy -iquote game -iquote machine -iquote network \ + -iquote printer -iquote sound -iquote scsi -iquote video -iquote lang +endif ifdef EXFLAGS OPTS += $(EXFLAGS) endif @@ -473,7 +484,6 @@ endif ifeq ($(I686), y) OPTS += -DUSE_I686 -DEVBROBJ += m_at_socket8.o endif ifeq ($(LASERXT), y) @@ -558,14 +568,15 @@ CXXFLAGS := $(CFLAGS) # Create the (final) list of objects to build. # ######################################################################### MAINOBJ := pc.o config.o random.o timer.o io.o apm_new.o dma.o nmi.o \ - pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem_new.o \ + pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o \ rom.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o $(VNCOBJ) $(RDPOBJ) INTELOBJ := intel_flash.o \ intel_sio.o intel_piix.o CPUOBJ := cpu.o cpu_table.o \ - 808x.o 386.o 386_common.o \ + 808x.o \ + 386.o 386_common.o \ 386_dynarec.o \ x86seg.o x87.o \ $(DYNARECOBJ) @@ -575,7 +586,7 @@ CHIPSETOBJ := acc2168.o acer_m3a.o ali1429.o headland.o \ sis_85c471.o sis_85c496.o \ via_mvp3.o wd76c10.o -MCHOBJ := machine.o machine_table_new.o \ +MCHOBJ := machine.o machine_table.o \ m_xt.o m_xt_compaq.o \ m_xt_t1000.o m_xt_t1000_vid.o \ m_xt_xi8088.o m_xt_zenith.o \ @@ -588,14 +599,18 @@ MCHOBJ := machine.o machine_table_new.o \ m_ps2_isa.o m_ps2_mca.o \ m_at_compaq.o \ m_at_286_386sx.o m_at_386dx_486.o \ - m_at_socket4_5.o m_at_socket7_s7.o + m_at_socket4_5.o m_at_socket7_s7.o \ + m_at_socket8.o -DEVOBJ := bugger.o ibm_5161.o isamem.o isartc.o lpt.o $(SERIAL) \ +DEVOBJ := bugger.o hwm.o hwm_w83781d.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ sio_acc3221.o \ sio_fdc37c66x.o sio_fdc37c669.o \ sio_fdc37c93x.o \ - sio_pc87306.o sio_w83877f.o \ + sio_pc87306.o \ + sio_w83787f.o \ + sio_w83877f.o sio_w83977f.o \ sio_um8669f.o \ + smbus.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ gameport.o \ @@ -632,7 +647,8 @@ SCSIOBJ := scsi.o scsi_device.o \ scsi_cdrom.o scsi_disk.o \ scsi_x54x.o \ scsi_aha154x.o scsi_buslogic.o \ - scsi_ncr5380.o scsi_ncr53c8xx.o + scsi_ncr5380.o scsi_ncr53c8xx.o \ + scsi_spock.o NETOBJ := network.o \ net_pcap.o \ diff --git a/src/win/resource.h b/src/win/resource.h index 8e11ed62a..c4ffc2728 100644 --- a/src/win/resource.h +++ b/src/win/resource.h @@ -175,7 +175,7 @@ #define IDC_CHECK_IDE_QUA 1127 #define IDC_BUTTON_IDE_QUA 1128 #define IDC_CHECK_BUGGER 1129 -#define IDC_CONFIGURE_BUGGER 1130 +#define IDC_CHECK_POSTCARD 1130 #define IDC_COMBO_ISARTC 1131 #define IDC_CONFIGURE_ISARTC 1132 #define IDC_GROUP_ISAMEM 1140 diff --git a/src/win/win.c b/src/win/win.c index cfbdab264..4197edd4c 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -30,18 +30,18 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../keyboard.h" -#include "../mouse.h" -#include "../video/video.h" +#include "86box.h" +#include "config.h" +#include "device.h" +#include "keyboard.h" +#include "mouse.h" +#include "video.h" #define GLOBAL -#include "../plat.h" -#include "../plat_midi.h" -#include "../ui.h" +#include "plat.h" +#include "plat_midi.h" +#include "ui.h" #ifdef USE_VNC -# include "../vnc.h" +# include "vnc.h" #endif # include "win_d2d.h" # include "win_sdl.h" diff --git a/src/win/win_about.c b/src/win/win_about.c index ae0eea162..b714cf334 100644 --- a/src/win/win_about.c +++ b/src/win/win_about.c @@ -26,8 +26,8 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" #include "win.h" diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c index b027f463f..e808ced53 100644 --- a/src/win/win_cdrom.c +++ b/src/win/win_cdrom.c @@ -27,14 +27,14 @@ #include #include #include -#include "../config.h" -#include "../disk/hdd.h" -#include "../scsi/scsi_device.h" -#include "../cdrom/cdrom.h" -#include "../disk/zip.h" -#include "../scsi/scsi_disk.h" -#include "../plat.h" -#include "../ui.h" +#include "config.h" +#include "hdd.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "zip.h" +#include "scsi_disk.h" +#include "plat.h" +#include "ui.h" #include "win.h" diff --git a/src/win/win_crashdump.c b/src/win/win_crashdump.c index 32944dbd0..cbec1b680 100644 --- a/src/win/win_crashdump.c +++ b/src/win/win_crashdump.c @@ -25,8 +25,8 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" #include "win.h" diff --git a/src/win/win_d2d.c b/src/win/win_d2d.c index 038ef739c..45ff1e83b 100644 --- a/src/win/win_d2d.c +++ b/src/win/win_d2d.c @@ -27,12 +27,12 @@ #undef BITMAP #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../video/video.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "video.h" +#include "plat.h" +#include "plat_dynld.h" +#include "ui.h" #include "win.h" #include "win_d2d.h" diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index e5e379d6c..fa925eb33 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -21,12 +21,12 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_midi.h" -#include "../ui.h" +#include "86box.h" +#include "config.h" +#include "device.h" +#include "plat.h" +#include "plat_midi.h" +#include "ui.h" #include "win.h" #include diff --git a/src/win/win_dialog.c b/src/win/win_dialog.c index bf93b474c..5d867f67f 100644 --- a/src/win/win_dialog.c +++ b/src/win/win_dialog.c @@ -27,10 +27,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "ui.h" #include "win.h" diff --git a/src/win/win_discord.c b/src/win/win_discord.c index c174413a8..04253b5b6 100644 --- a/src/win/win_discord.c +++ b/src/win/win_discord.c @@ -22,15 +22,11 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#ifdef USE_NEW_DYNAREC - #include "../cpu_new/cpu.h" -#else - #include "../cpu/cpu.h" -#endif -#include "../machine/machine.h" -#include "../plat.h" -#include "../plat_dynld.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "plat.h" +#include "plat_dynld.h" #include "win_discord.h" #include "discord_game_sdk.h" diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index e258ebe19..b5e89aaff 100644 --- a/src/win/win_dynld.c +++ b/src/win/win_dynld.c @@ -22,8 +22,8 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../plat_dynld.h" +#include "86box.h" +#include "plat_dynld.h" #ifdef ENABLE_DYNLD_LOG diff --git a/src/win/win_joystick.cpp b/src/win/win_joystick.cpp index 499f19903..437b506e6 100644 --- a/src/win/win_joystick.cpp +++ b/src/win/win_joystick.cpp @@ -23,10 +23,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../game/gameport.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "gameport.h" #include "win.h" diff --git a/src/win/win_joystick_xinput.cpp b/src/win/win_joystick_xinput.cpp index 237cab23c..5d3e2fbbb 100644 --- a/src/win/win_joystick_xinput.cpp +++ b/src/win/win_joystick_xinput.cpp @@ -24,10 +24,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../game/gameport.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "gameport.h" #include "win.h" #define XINPUT_MAX_JOYSTICKS 4 diff --git a/src/win/win_jsconf.c b/src/win/win_jsconf.c index 0d7474f59..b048afa27 100644 --- a/src/win/win_jsconf.c +++ b/src/win/win_jsconf.c @@ -7,11 +7,11 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../game/gameport.h" -#include "../plat.h" +#include "86box.h" +#include "config.h" +#include "device.h" +#include "gameport.h" +#include "plat.h" #include "win.h" diff --git a/src/win/win_keyboard.c b/src/win/win_keyboard.c index eaf4ddac4..8fb761a44 100644 --- a/src/win/win_keyboard.c +++ b/src/win/win_keyboard.c @@ -24,10 +24,10 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../keyboard.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "keyboard.h" +#include "plat.h" #include "win.h" diff --git a/src/win/win_midi.c b/src/win/win_midi.c index dace62b0e..c38f444fd 100644 --- a/src/win/win_midi.c +++ b/src/win/win_midi.c @@ -4,11 +4,11 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../sound/midi.h" -#include "../plat.h" -#include "../plat_midi.h" +#include "86box.h" +#include "config.h" +#include "midi.h" +#include "plat.h" +#include "plat_midi.h" typedef struct diff --git a/src/win/win_mouse.c b/src/win/win_mouse.c index 2ca004e9f..f58f4be82 100644 --- a/src/win/win_mouse.c +++ b/src/win/win_mouse.c @@ -22,9 +22,9 @@ #include #include #include -#include "../86box.h" -#include "../mouse.h" -#include "../plat.h" +#include "86box.h" +#include "mouse.h" +#include "plat.h" #include "win.h" int mouse_capture; diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c index 4bb7b30f9..bbae1551e 100644 --- a/src/win/win_new_floppy.c +++ b/src/win/win_new_floppy.c @@ -25,12 +25,12 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" -#include "../random.h" -#include "../ui.h" -#include "../scsi/scsi_device.h" -#include "../disk/zip.h" +#include "86box.h" +#include "plat.h" +#include "random.h" +#include "ui.h" +#include "scsi_device.h" +#include "zip.h" #include "win.h" diff --git a/src/win/win_opendir.c b/src/win/win_opendir.c index bcd683c3d..74309eb25 100644 --- a/src/win/win_opendir.c +++ b/src/win/win_opendir.c @@ -25,8 +25,8 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" #include "plat_dir.h" diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index 77b5c8a2f..f4c415d11 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -62,12 +62,12 @@ /* This #undef is needed because a SDL include header redefines HAVE_STDARG_H. */ #undef HAVE_STDARG_H #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "../video/video.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "plat_dynld.h" +#include "video.h" +#include "ui.h" #include "win.h" #include "win_sdl.h" diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 69f054acd..6d5476295 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -30,38 +30,36 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" -#include "../nvr.h" -#include "../machine/machine.h" -#include "../game/gameport.h" -#include "../isamem.h" -#include "../isartc.h" -#include "../lpt.h" -#include "../mouse.h" -#include "../scsi/scsi.h" -#include "../scsi/scsi_device.h" -#include "../cdrom/cdrom.h" -#include "../disk/hdd.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../disk/zip.h" -#include "../floppy/fdd.h" -#include "../network/network.h" -#include "../sound/sound.h" -#include "../sound/midi.h" -#include "../sound/snd_mpu401.h" -#include "../sound/snd_gus.h" -#include "../video/video.h" -#include "../video/vid_voodoo.h" -#include "../plat.h" -#include "../plat_midi.h" -#include "../ui.h" +#include "86box.h" +#include "config.h" +#include "cpu.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" +#include "nvr.h" +#include "machine.h" +#include "gameport.h" +#include "isamem.h" +#include "isartc.h" +#include "lpt.h" +#include "mouse.h" +#include "scsi.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "hdd.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "zip.h" +#include "fdd.h" +#include "network.h" +#include "sound.h" +#include "midi.h" +#include "snd_mpu401.h" +#include "video.h" +#include "plat.h" +#include "plat_midi.h" +#include "ui.h" #include "win.h" @@ -99,6 +97,7 @@ static int temp_serial[2], temp_lpt[3]; /* Other peripherals category */ static int temp_hdc, temp_scsi_card, temp_ide_ter, temp_ide_qua; static int temp_bugger; +static int temp_postcard; static int temp_isartc; static int temp_isamem[ISAMEM_MAX]; @@ -250,6 +249,7 @@ win_settings_init(void) temp_ide_ter = ide_ter_enabled; temp_ide_qua = ide_qua_enabled; temp_bugger = bugger_enabled; + temp_postcard = postcard_enabled; temp_isartc = isartc_type; /* ISA memory boards. */ @@ -358,6 +358,7 @@ win_settings_changed(void) i = i || (temp_ide_ter != ide_ter_enabled); i = i || (temp_ide_qua != ide_qua_enabled); i = i || (temp_bugger != bugger_enabled); + i = i || (temp_postcard != postcard_enabled); i = i || (temp_isartc != isartc_type); /* ISA memory boards. */ @@ -462,6 +463,7 @@ win_settings_save(void) ide_ter_enabled = temp_ide_ter; ide_qua_enabled = temp_ide_qua; bugger_enabled = temp_bugger; + postcard_enabled = temp_postcard; isartc_type = temp_isartc; /* ISA memory boards. */ @@ -1596,6 +1598,9 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa h=GetDlgItem(hdlg, IDC_CHECK_BUGGER); SendMessage(h, BM_SETCHECK, temp_bugger, 0); + h=GetDlgItem(hdlg, IDC_CHECK_POSTCARD); + SendMessage(h, BM_SETCHECK, temp_postcard, 0); + /* Populate the ISA RTC card dropdown. */ e = 0; h = GetDlgItem(hdlg, IDC_COMBO_ISARTC); @@ -1799,6 +1804,9 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa h = GetDlgItem(hdlg, IDC_CHECK_BUGGER); temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECK_POSTCARD); + temp_postcard = SendMessage(h, BM_GETCHECK, 0, 0); + free(stransi); free(lptsTemp); diff --git a/src/win/win_snd_gain.c b/src/win/win_snd_gain.c index 0dc4e5dcc..7f23a1aee 100644 --- a/src/win/win_snd_gain.c +++ b/src/win/win_snd_gain.c @@ -25,10 +25,10 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../plat.h" -#include "../sound/sound.h" +#include "86box.h" +#include "config.h" +#include "plat.h" +#include "sound.h" #include "win.h" diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index ede2cb271..43554f159 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -28,27 +28,27 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../cpu/cpu.h" -#include "../device.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../disk/hdd.h" -#include "../disk/hdc.h" -#include "../floppy/fdd.h" -#include "../floppy/fdd_86f.h" -#include "../scsi/scsi.h" -#include "../scsi/scsi_device.h" -#include "../cdrom/cdrom.h" -#include "../disk/zip.h" -#include "../cdrom/cdrom_image.h" -#include "../scsi/scsi_disk.h" -#include "../network/network.h" -#include "../video/video.h" -#include "../sound/sound.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "config.h" +#include "cpu.h" +#include "device.h" +#include "machine.h" +#include "timer.h" +#include "hdd.h" +#include "hdc.h" +#include "fdd.h" +#include "fdd_86f.h" +#include "scsi.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "zip.h" +#include "cdrom_image.h" +#include "scsi_disk.h" +#include "network.h" +#include "video.h" +#include "sound.h" +#include "plat.h" +#include "ui.h" #include "win.h" #ifndef GWL_WNDPROC diff --git a/src/win/win_thread.c b/src/win/win_thread.c index 2f885ec04..31a087cab 100644 --- a/src/win/win_thread.c +++ b/src/win/win_thread.c @@ -27,8 +27,8 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" typedef struct { diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 812e4c2cb..cfe5d37fb 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -28,16 +28,16 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../keyboard.h" -#include "../mouse.h" -#include "../video/video.h" -#include "../video/vid_ega.h" // for update_overscan -#include "../plat.h" -#include "../plat_midi.h" -#include "../ui.h" +#include "86box.h" +#include "config.h" +#include "device.h" +#include "keyboard.h" +#include "mouse.h" +#include "video.h" +#include "vid_ega.h" // for update_overscan +#include "plat.h" +#include "plat_midi.h" +#include "ui.h" #include "win.h" #ifdef USE_DISCORD # include "win_discord.h" diff --git a/src/x86.txt b/src/x86.txt new file mode 100644 index 000000000..37d6b6d8b --- /dev/null +++ b/src/x86.txt @@ -0,0 +1,785 @@ +Comparing files CPU\codegen.h and CPU_NEW\CODEGEN.H +***** CPU\codegen.h +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the code generator. + * + * Version: @(#)codegen.h 1.0.2 2018/03/14 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ +#ifndef _CODEGEN_H_ +#define _CODEGEN_H_ +***** CPU_NEW\CODEGEN.H +#ifndef _CODEGEN_H_ +#define _CODEGEN_H_ +***** + +***** CPU\codegen.h + +#include "../mem.h" +#include "../cpu_common/x86_ops.h" +***** CPU_NEW\CODEGEN.H + +#include "mem.h" +#include "../cpu_common/x86_ops.h" +***** + +***** CPU\codegen.h + +#ifdef __amd64__ +#include "codegen_x86-64.h" +#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 +#include "codegen_x86.h" +#else +#error Dynamic recompiler not implemented on your platform +#endif + +/*Handling self-modifying code (of which there is a lot on x86) : +***** CPU_NEW\CODEGEN.H + +/*Handling self-modifying code (of which there is a lot on x86) : +***** + +***** CPU\codegen.h +{ + uint64_t page_mask, page_mask2; + uint64_t *dirty_mask, *dirty_mask2; + uint64_t cmp; + + /*Previous and next pointers, for the codeblock list associated with + each physical page. Two sets of pointers, as a codeblock can be + present in two pages.*/ + struct codeblock_t *prev, *next; + struct codeblock_t *prev_2, *next_2; + + /*Pointers for codeblock tree, used to search for blocks when hash lookup +***** CPU_NEW\CODEGEN.H +{ + uint32_t pc; + uint32_t _cs; + uint32_t phys, phys_2; + uint16_t status; + uint16_t flags; + uint8_t ins; + uint8_t TOP; + + /*Pointers for codeblock tree, used to search for blocks when hash lookup +***** + +***** CPU\codegen.h + fails.*/ + struct codeblock_t *parent, *left, *right; + + int pnt; + int ins; + + int valid; + + int was_recompiled; + int TOP; + + uint32_t pc; + uint32_t _cs; + uint32_t endpc; + uint32_t phys, phys_2; + uint32_t status; + uint32_t flags; + + uint8_t data[2048]; +} codeblock_t; +***** CPU_NEW\CODEGEN.H + fails.*/ + uint16_t parent, left, right; + + uint8_t *data; + + uint64_t page_mask, page_mask2; + uint64_t *dirty_mask, *dirty_mask2; + + /*Previous and next pointers, for the codeblock list associated with + each physical page. Two sets of pointers, as a codeblock can be + present in two pages.*/ + uint16_t prev, next; + uint16_t prev_2, next_2; + + /*First mem_block_t used by this block. Any subsequent mem_block_ts + will be in the list starting at head_mem_block->next.*/ + struct mem_block_t *head_mem_block; +} codeblock_t; +***** + +***** CPU\codegen.h + +/*Code block uses FPU*/ +***** CPU_NEW\CODEGEN.H + +extern codeblock_t *codeblock; + +extern uint16_t *codeblock_hash; + +extern uint8_t *block_write_data; + +/*Code block uses FPU*/ +***** + +***** CPU\codegen.h +#define CODEBLOCK_STATIC_TOP 2 + +***** CPU_NEW\CODEGEN.H +#define CODEBLOCK_STATIC_TOP 2 +/*Code block has been compiled*/ +#define CODEBLOCK_WAS_RECOMPILED 4 +/*Code block is in free list and is not valid*/ +#define CODEBLOCK_IN_FREE_LIST 8 +/*Code block spans two pages, page_mask2 and dirty_mask2 are valid*/ +#define CODEBLOCK_HAS_PAGE2 0x10 +/*Code block is using a byte mask for code present and dirty*/ +#define CODEBLOCK_BYTE_MASK 0x20 +/*Code block is in dirty list*/ +#define CODEBLOCK_IN_DIRTY_LIST 0x40 +/*Code block is not inlining immediate parameters, parameters must be fetched from memory*/ +#define CODEBLOCK_NO_IMMEDIATES 0x80 + +#define BLOCK_PC_INVALID 0xffffffff + +#define BLOCK_INVALID 0 + +static inline int get_block_nr(codeblock_t *block) +{ + return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t); +} + +***** + +***** CPU\codegen.h +{ + codeblock_t *block = pages[phys >> 12].head; + uint64_t a = _cs | ((uint64_t)phys << 32); +***** CPU_NEW\CODEGEN.H +{ + codeblock_t *block; + uint64_t a = _cs | ((uint64_t)phys << 32); +***** + +***** CPU\codegen.h + + while (block) +***** CPU_NEW\CODEGEN.H + + if (!pages[phys >> 12].head) + return NULL; + + block = &codeblock[pages[phys >> 12].head]; + while (block) +***** + +***** CPU\codegen.h + { + if (a == block->cmp) + { +***** CPU_NEW\CODEGEN.H + { + uint64_t block_cmp = block->_cs | ((uint64_t)block->phys << 32); + if (a == block_cmp) + { +***** + +***** CPU\codegen.h + } + if (a < block->cmp) + block = block->left; + else + block = block->right; + } +***** CPU_NEW\CODEGEN.H + } + if (a < block_cmp) + block = block->left ? &codeblock[block->left] : NULL; + else + block = block->right ? &codeblock[block->right] : NULL; + } +***** + +***** CPU\codegen.h +{ + codeblock_t *block = pages[new_block->phys >> 12].head; + uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); + new_block->cmp = a; + + if (!block) + { + pages[new_block->phys >> 12].head = new_block; + new_block->parent = new_block->left = new_block->right = NULL; + } +***** CPU_NEW\CODEGEN.H +{ + codeblock_t *block = &codeblock[pages[new_block->phys >> 12].head]; + uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); + + if (!pages[new_block->phys >> 12].head) + { + pages[new_block->phys >> 12].head = get_block_nr(new_block); + new_block->parent = new_block->left = new_block->right = BLOCK_INVALID; + } +***** + +***** CPU\codegen.h + codeblock_t *old_block = NULL; + +***** CPU_NEW\CODEGEN.H + codeblock_t *old_block = NULL; + uint64_t old_block_cmp = 0; + +***** + +***** CPU\codegen.h + old_block = block; + if (a < old_block->cmp) + block = block->left; + else + block = block->right; + } +***** CPU_NEW\CODEGEN.H + old_block = block; + old_block_cmp = old_block->_cs | ((uint64_t)old_block->phys << 32); + + if (a < old_block_cmp) + block = block->left ? &codeblock[block->left] : NULL; + else + block = block->right ? &codeblock[block->right] : NULL; + } +***** + +***** CPU\codegen.h + + if (a < old_block->cmp) + old_block->left = new_block; + else + old_block->right = new_block; + + new_block->parent = old_block; + new_block->left = new_block->right = NULL; + } +***** CPU_NEW\CODEGEN.H + + 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); + new_block->left = new_block->right = BLOCK_INVALID; + } +***** + +***** CPU\codegen.h +{ + codeblock_t *parent = block->parent; + +***** CPU_NEW\CODEGEN.H +{ + uint16_t parent_nr = block->parent; + codeblock_t *parent; + + if (block->parent) + parent = &codeblock[block->parent]; + else + parent = NULL; + +***** + +***** CPU\codegen.h + if (!parent) + pages[block->phys >> 12].head = NULL; + else +***** CPU_NEW\CODEGEN.H + if (!parent) + pages[block->phys >> 12].head = BLOCK_INVALID; + else +***** + +***** CPU\codegen.h + { + if (parent->left == block) + parent->left = NULL; + if (parent->right == block) + parent->right = NULL; + } +***** CPU_NEW\CODEGEN.H + { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + parent->left = BLOCK_INVALID; + if (parent->right == block_nr) + parent->right = BLOCK_INVALID; + } +***** + +***** CPU\codegen.h + /*Only right node*/ + if (!parent) + { +***** CPU_NEW\CODEGEN.H + /*Only right node*/ + if (!parent_nr) + { +***** + +***** CPU\codegen.h + pages[block->phys >> 12].head = block->right; + pages[block->phys >> 12].head->parent = NULL; + } +***** CPU_NEW\CODEGEN.H + pages[block->phys >> 12].head = block->right; + codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; + } +***** + +***** CPU\codegen.h + { + if (parent->left == block) + { +***** CPU_NEW\CODEGEN.H + { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + { +***** + +***** CPU\codegen.h + parent->left = block->right; + parent->left->parent = parent; + } + if (parent->right == block) + { +***** CPU_NEW\CODEGEN.H + parent->left = block->right; + codeblock[parent->left].parent = parent_nr; + } + if (parent->right == block_nr) + { +***** + +***** CPU\codegen.h + parent->right = block->right; + parent->right->parent = parent; + } +***** CPU_NEW\CODEGEN.H + parent->right = block->right; + codeblock[parent->right].parent = parent_nr; + } +***** + +***** CPU\codegen.h + /*Only left node*/ + if (!parent) + { +***** CPU_NEW\CODEGEN.H + /*Only left node*/ + if (!parent_nr) + { +***** + +***** CPU\codegen.h + pages[block->phys >> 12].head = block->left; + pages[block->phys >> 12].head->parent = NULL; + } +***** CPU_NEW\CODEGEN.H + pages[block->phys >> 12].head = block->left; + codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; + } +***** + +***** CPU\codegen.h + { + if (parent->left == block) + { +***** CPU_NEW\CODEGEN.H + { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + { +***** + +***** CPU\codegen.h + parent->left = block->left; + parent->left->parent = parent; + } + if (parent->right == block) + { +***** CPU_NEW\CODEGEN.H + parent->left = block->left; + codeblock[parent->left].parent = parent_nr; + } + if (parent->right == block_nr) + { +***** + +***** CPU\codegen.h + parent->right = block->left; + parent->right->parent = parent; + } +***** CPU_NEW\CODEGEN.H + parent->right = block->left; + codeblock[parent->right].parent = parent_nr; + } +***** + +***** CPU\codegen.h + /*Difficult case - node has two children. Walk right child to find lowest node*/ + codeblock_t *lowest = block->right, *highest; + codeblock_t *old_parent; + +***** CPU_NEW\CODEGEN.H + /*Difficult case - node has two children. Walk right child to find lowest node*/ + codeblock_t *lowest = &codeblock[block->right], *highest; + codeblock_t *old_parent; + uint16_t lowest_nr; + +***** + +***** CPU\codegen.h + while (lowest->left) + lowest = lowest->left; + + old_parent = lowest->parent; + +***** CPU_NEW\CODEGEN.H + while (lowest->left) + lowest = &codeblock[lowest->left]; + lowest_nr = get_block_nr(lowest); + + old_parent = &codeblock[lowest->parent]; + +***** + +***** CPU\codegen.h + /*Replace deleted node with lowest node*/ + if (!parent) + pages[block->phys >> 12].head = lowest; + else +***** CPU_NEW\CODEGEN.H + /*Replace deleted node with lowest node*/ + if (!parent_nr) + pages[block->phys >> 12].head = lowest_nr; + else +***** + +***** CPU\codegen.h + { + if (parent->left == block) + parent->left = lowest; + if (parent->right == block) + parent->right = lowest; + } +***** CPU_NEW\CODEGEN.H + { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + parent->left = lowest_nr; + if (parent->right == block_nr) + parent->right = lowest_nr; + } +***** + +***** CPU\codegen.h + + lowest->parent = parent; + lowest->left = block->left; +***** CPU_NEW\CODEGEN.H + + lowest->parent = parent_nr; + lowest->left = block->left; +***** + +***** CPU\codegen.h + if (lowest->left) + lowest->left->parent = lowest; + + old_parent->left = NULL; + + highest = lowest->right; + if (!highest) + { + if (lowest != block->right) + { +***** CPU_NEW\CODEGEN.H + if (lowest->left) + codeblock[lowest->left].parent = lowest_nr; + + old_parent->left = BLOCK_INVALID; + + highest = &codeblock[lowest->right]; + if (!lowest->right) + { + if (lowest_nr != block->right) + { +***** + +***** CPU\codegen.h + lowest->right = block->right; + block->right->parent = lowest; + } +***** CPU_NEW\CODEGEN.H + lowest->right = block->right; + codeblock[block->right].parent = lowest_nr; + } +***** + +***** CPU\codegen.h + while (highest->right) + highest = highest->right; + + if (block->right && block->right != lowest) + { +***** CPU_NEW\CODEGEN.H + while (highest->right) + highest = &codeblock[highest->right]; + + if (block->right && block->right != lowest_nr) + { +***** + +***** CPU\codegen.h + highest->right = block->right; + block->right->parent = highest; + } +***** CPU_NEW\CODEGEN.H + highest->right = block->right; + codeblock[block->right].parent = get_block_nr(highest); + } +***** + +***** CPU\codegen.h + +#define PAGE_MASK_INDEX_MASK 3 +#define PAGE_MASK_INDEX_SHIFT 10 +#define PAGE_MASK_MASK 63 +#define PAGE_MASK_SHIFT 4 + +extern codeblock_t *codeblock; + +extern codeblock_t **codeblock_hash; + +***** CPU_NEW\CODEGEN.H + +#define PAGE_MASK_MASK 63 +#define PAGE_MASK_SHIFT 6 + +void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len); + +static inline void codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len) +{ + if (len == 1) + { + if (block->flags & CODEBLOCK_BYTE_MASK) + { + if (!((start_pc ^ block->pc) & ~0x3f)) /*Starts in second page*/ + block->page_mask |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); + else + block->page_mask2 |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); + } + else + { + if (!((start_pc ^ block->pc) & ~0xfff)) /*Starts in second page*/ + block->page_mask |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); + else + block->page_mask2 |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); + } + } + else + codegen_mark_code_present_multibyte(block, start_pc, len); +} + +***** + +***** CPU\codegen.h +void codegen_init(); +void codegen_reset(); +***** CPU_NEW\CODEGEN.H +void codegen_init(); +void codegen_close(); +void codegen_reset(); +***** + +***** CPU\codegen.h +void codegen_block_end(); +void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc); +***** CPU_NEW\CODEGEN.H +void codegen_block_end(); +void codegen_delete_block(codeblock_t *block); +void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc); +***** + +***** CPU\codegen.h +void codegen_flush(); +void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr); + +***** CPU_NEW\CODEGEN.H +void codegen_flush(); +void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr); +struct ir_data_t; +x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t + op_32, int stack_offset); +void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); +void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); + +int codegen_purge_purgable_list(); +/*Delete a random code block to free memory. This is obviously quite expensive, and + will only be called when the allocator is out of memory*/ +void codegen_delete_random_block(int required_mem_block); + +***** + +***** CPU\codegen.h +extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); +extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32); +extern void (*codegen_timing_block_start)(); +***** CPU_NEW\CODEGEN.H +extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); +extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); +extern void (*codegen_timing_block_start)(); +***** + +***** CPU\codegen.h +extern void (*codegen_timing_block_end)(); + +***** CPU_NEW\CODEGEN.H +extern void (*codegen_timing_block_end)(); +extern int (*codegen_timing_jump_cycles)(); + +***** + +***** CPU\codegen.h + void (*prefix)(uint8_t prefix, uint32_t fetchdat); + void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32); + void (*block_start)(); +***** CPU_NEW\CODEGEN.H + void (*prefix)(uint8_t prefix, uint32_t fetchdat); + void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); + void (*block_start)(); +***** + +***** CPU\codegen.h + void (*block_end)(); +} codegen_timing_t; +***** CPU_NEW\CODEGEN.H + void (*block_end)(); + int (*jump_cycles)(); +} codegen_timing_t; +***** + +***** CPU\codegen.h +extern codegen_timing_t codegen_timing_winchip; + +***** CPU_NEW\CODEGEN.H +extern codegen_timing_t codegen_timing_winchip; +extern codegen_timing_t codegen_timing_winchip2; +extern codegen_timing_t codegen_timing_k6; + +***** + +***** CPU\codegen.h + +static inline void addbyte(uint8_t val) +{ + codeblock[block_current].data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +static inline void addword(uint16_t val) +{ + uint16_t *p = (uint16_t *) &codeblock[block_current].data[block_pos]; + *p = val; + block_pos += 2; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +static inline void addlong(uint32_t val) +{ + uint32_t *p = (uint32_t *) &codeblock[block_current].data[block_pos]; + *p = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +static inline void addquad(uint64_t val) +{ + uint64_t *p = (uint64_t *) &codeblock[block_current].data[block_pos]; + *p = val; + block_pos += 8; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +/*Current physical page of block being recompiled. -1 if no recompilation taking place */ +***** CPU_NEW\CODEGEN.H + +/*Current physical page of block being recompiled. -1 if no recompilation taking place */ +***** + +***** CPU\codegen.h + +#endif +***** CPU_NEW\CODEGEN.H + +void codegen_generate_reset(); + +int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP); +void codegen_set_loop_start(struct ir_data_t *ir, int first_instruction); + +#ifdef DEBUG_EXTRA +extern uint32_t instr_counts[256*256]; +#endif +***** + +***** CPU\codegen.h +***** CPU_NEW\CODEGEN.H + +#endif +***** + diff --git a/src/x86_flags.txt b/src/x86_flags.txt new file mode 100644 index 000000000..a538f84dc --- /dev/null +++ b/src/x86_flags.txt @@ -0,0 +1,835 @@ +Comparing files CPU\x86_flags.h and CPU_NEW\X86_FLAGS.H +***** CPU\x86_flags.h +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +extern int tempc; + +***** CPU_NEW\X86_FLAGS.H +extern int tempc; + +***** + +***** CPU\x86_flags.h + + FLAGS_INC8, +***** CPU_NEW\X86_FLAGS.H + + FLAGS_ROL8, + FLAGS_ROL16, + FLAGS_ROL32, + + FLAGS_ROR8, + FLAGS_ROR16, + FLAGS_ROR32, + + FLAGS_INC8, +***** + +***** CPU\x86_flags.h + FLAGS_DEC16, + FLAGS_DEC32 +}; +***** CPU_NEW\X86_FLAGS.H + FLAGS_DEC16, + FLAGS_DEC32, + + FLAGS_ADC8, + FLAGS_ADC16, + FLAGS_ADC32, + + FLAGS_SBC8, + FLAGS_SBC16, + FLAGS_SBC32 +}; +***** + +***** CPU\x86_flags.h + +static __inline int ZF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int ZF_SET() +{ +***** + +***** CPU\x86_flags.h + case FLAGS_DEC32: + return !cpu_state.flags_res; +***** CPU_NEW\X86_FLAGS.H + case FLAGS_DEC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return !cpu_state.flags_res; +***** + +***** CPU\x86_flags.h + + case FLAGS_UNKNOWN: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: +***** + +***** CPU\x86_flags.h + return cpu_state.flags & Z_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & Z_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline int NF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int NF_SET() +{ +***** + +***** CPU\x86_flags.h + case FLAGS_DEC8: + return cpu_state.flags_res & 0x80; +***** CPU_NEW\X86_FLAGS.H + case FLAGS_DEC8: + case FLAGS_ADC8: + case FLAGS_SBC8: + return cpu_state.flags_res & 0x80; +***** + +***** CPU\x86_flags.h + case FLAGS_DEC16: + return cpu_state.flags_res & 0x8000; +***** CPU_NEW\X86_FLAGS.H + case FLAGS_DEC16: + case FLAGS_ADC16: + case FLAGS_SBC16: + return cpu_state.flags_res & 0x8000; +***** + +***** CPU\x86_flags.h + case FLAGS_DEC32: + return cpu_state.flags_res & 0x80000000; +***** CPU_NEW\X86_FLAGS.H + case FLAGS_DEC32: + case FLAGS_ADC32: + case FLAGS_SBC32: + return cpu_state.flags_res & 0x80000000; +***** + +***** CPU\x86_flags.h + + case FLAGS_UNKNOWN: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: +***** + +***** CPU\x86_flags.h + return cpu_state.flags & N_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & N_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline int PF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int PF_SET() +{ +***** + +***** CPU\x86_flags.h + case FLAGS_DEC32: + return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; +***** CPU_NEW\X86_FLAGS.H + case FLAGS_DEC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; +***** + +***** CPU\x86_flags.h + + case FLAGS_UNKNOWN: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: +***** + +***** CPU\x86_flags.h + return cpu_state.flags & P_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & P_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline int VF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int VF_SET() +{ +***** + +***** CPU\x86_flags.h + + case FLAGS_ADD8: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ADC8: + case FLAGS_ADD8: +***** + +***** CPU\x86_flags.h +0x80); + case FLAGS_ADD16: + case FLAGS_INC16: +***** CPU_NEW\X86_FLAGS.H +0x80); + case FLAGS_ADC16: + case FLAGS_ADD16: + case FLAGS_INC16: +***** + +***** CPU\x86_flags.h +& 0x8000); + case FLAGS_ADD32: + case FLAGS_INC32: +***** CPU_NEW\X86_FLAGS.H +& 0x8000); + case FLAGS_ADC32: + case FLAGS_ADD32: + case FLAGS_INC32: +***** + +***** CPU\x86_flags.h +es) & 0x80000000); + + case FLAGS_SUB8: +***** CPU_NEW\X86_FLAGS.H +es) & 0x80000000); + + case FLAGS_SBC8: + case FLAGS_SUB8: +***** + +***** CPU\x86_flags.h + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_SUB16: + case FLAGS_DEC16: +***** CPU_NEW\X86_FLAGS.H + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_SBC16: + case FLAGS_SUB16: + case FLAGS_DEC16: +***** + +***** CPU\x86_flags.h + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_SUB32: + case FLAGS_DEC32: +***** CPU_NEW\X86_FLAGS.H + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_SBC32: + case FLAGS_SUB32: + case FLAGS_DEC32: +***** + +***** CPU\x86_flags.h + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); + + case FLAGS_UNKNOWN: +***** CPU_NEW\X86_FLAGS.H + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); + + case FLAGS_ROL8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1; + case FLAGS_ROL16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1; + case FLAGS_ROL32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1; + + case FLAGS_ROR8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40; + case FLAGS_ROR16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000; + case FLAGS_ROR32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000; + + case FLAGS_UNKNOWN: +***** + +***** CPU\x86_flags.h + return cpu_state.flags & V_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & V_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline int AF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int AF_SET() +{ +***** + +***** CPU\x86_flags.h + + case FLAGS_SUB8: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ADC8: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff); + + case FLAGS_SUB8: +***** + +***** CPU\x86_flags.h + + case FLAGS_UNKNOWN: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || + ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); + + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: +***** + +***** CPU\x86_flags.h + return cpu_state.flags & A_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & A_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline int CF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int CF_SET() +{ +***** + +***** CPU\x86_flags.h + case FLAGS_ADD8: + return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100; + case FLAGS_ADD16: + return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000; + case FLAGS_ADD32: +***** CPU_NEW\X86_FLAGS.H + case FLAGS_ADD8: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100) ? 1 : 0; + case FLAGS_ADD16: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000) ? 1 : 0; + case FLAGS_ADD32: +***** + +***** CPU\x86_flags.h + + case FLAGS_SUB8: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ADC8: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff); + + case FLAGS_SUB8: +***** + +***** CPU\x86_flags.h + + case FLAGS_SHL8: + return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80; + case FLAGS_SHL16: + return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000; + case FLAGS_SHL32: + return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000; + +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return (cpu_state.flags_op1 < cpu_state.flags_op2) || + (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); + + case FLAGS_SHL8: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0; + case FLAGS_SHL16: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000) ? 1 : 0; + case FLAGS_SHL32: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000) ? 1 : 0; + +***** + +***** CPU\x86_flags.h + return 0; + +***** CPU_NEW\X86_FLAGS.H + return 0; + + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + return cpu_state.flags_res & 1; + + case FLAGS_ROR8: + return (cpu_state.flags_res & 0x80) ? 1 : 0; + case FLAGS_ROR16: + return (cpu_state.flags_res & 0x8000) ? 1 :0; + case FLAGS_ROR32: + return (cpu_state.flags_res & 0x80000000) ? 1 : 0; + +***** + +***** CPU\x86_flags.h + return cpu_state.flags & C_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & C_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline void flags_rebuild() +{ +***** CPU_NEW\X86_FLAGS.H + +//#define ZF_SET() (flags & Z_FLAG) +//#define NF_SET() (flags & N_FLAG) +//#define PF_SET() (flags & P_FLAG) +//#define VF_SET() (flags & V_FLAG) +//#define CF_SET() (flags & C_FLAG) +//#define AF_SET() (flags & A_FLAG) + +static inline void flags_rebuild() +{ +***** + +***** CPU\x86_flags.h + +static __inline void flags_extract() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline void flags_extract() +{ +***** + +***** CPU\x86_flags.h + +static __inline void flags_rebuild_c() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline void flags_rebuild_c() +{ +***** + +***** CPU\x86_flags.h + if (CF_SET()) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + } +***** CPU_NEW\X86_FLAGS.H + if (CF_SET()) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + } +***** + +***** CPU\x86_flags.h + +static __inline void setznp8(uint8_t val) +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int flags_res_valid() +{ + if (cpu_state.flags_op == FLAGS_UNKNOWN || + (cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32)) + return 0; + + return 1; +} + +static inline void setznp8(uint8_t val) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setznp16(uint16_t val) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setznp16(uint16_t val) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setznp32(uint32_t val) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setznp32(uint32_t val) +{ +***** + +***** CPU\x86_flags.h + +static __inline void setadd8(uint8_t a, uint8_t b) +{ +***** CPU_NEW\X86_FLAGS.H + +#define set_flags_rotate(op, res) \ + cpu_state.flags_op = op; \ + cpu_state.flags_res = res; + +static inline void setadd8(uint8_t a, uint8_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setadd16(uint16_t a, uint16_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setadd16(uint16_t a, uint16_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setadd32(uint32_t a, uint32_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setadd32(uint32_t a, uint32_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setadd8nc(uint8_t a, uint8_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setadd8nc(uint8_t a, uint8_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setadd16nc(uint16_t a, uint16_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setadd16nc(uint16_t a, uint16_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setadd32nc(uint32_t a, uint32_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setadd32nc(uint32_t a, uint32_t b) +{ +***** + +***** CPU\x86_flags.h + +static __inline void setsub8(uint8_t a, uint8_t b) +{ +***** CPU_NEW\X86_FLAGS.H + +static inline void setsub8(uint8_t a, uint8_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setsub16(uint16_t a, uint16_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setsub16(uint16_t a, uint16_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setsub32(uint32_t a, uint32_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setsub32(uint32_t a, uint32_t b) +{ +***** + +***** CPU\x86_flags.h + +static __inline void setsub8nc(uint8_t a, uint8_t b) +{ +***** CPU_NEW\X86_FLAGS.H + +static inline void setsub8nc(uint8_t a, uint8_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setsub16nc(uint16_t a, uint16_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setsub16nc(uint16_t a, uint16_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setsub32nc(uint32_t a, uint32_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setsub32nc(uint32_t a, uint32_t b) +{ +***** + +***** CPU\x86_flags.h + +static __inline void setadc8(uint8_t a, uint8_t b) +{ + uint16_t c=(uint16_t)a+(uint16_t)b+tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags&=~0x8D5; + cpu_state.flags|=znptable8[c&0xFF]; + if (c&0x100) cpu_state.flags|=C_FLAG; + if (!((a^b)&0x80)&&((a^c)&0x80)) cpu_state.flags|=V_FLAG; + if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; +} +static __inline void setadc16(uint16_t a, uint16_t b) +{ + uint32_t c=(uint32_t)a+(uint32_t)b+tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags&=~0x8D5; + cpu_state.flags|=znptable16[c&0xFFFF]; + if (c&0x10000) cpu_state.flags|=C_FLAG; + if (!((a^b)&0x8000)&&((a^c)&0x8000)) cpu_state.flags|=V_FLAG; + if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; +} +static __inline void setadc32(uint32_t a, uint32_t b) +{ + uint32_t c=(uint32_t)a+(uint32_t)b+tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags&=~0x8D5; + cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); + cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG); + if ((ca) || (c==a && tempc)) cpu_state.flags|=C_FLAG; + if ((a^b)&(a^c)&0x80000000) cpu_state.flags|=V_FLAG; + if (((a&0xF)-((b&0xF)+tempc))&0x10) cpu_state.flags|=A_FLAG; +} + +extern void cpu_386_flags_extract(); +***** CPU_NEW\X86_FLAGS.H + +extern void cpu_386_flags_extract(); +***** + diff --git a/src/x86_ops_arith.txt b/src/x86_ops_arith.txt new file mode 100644 index 000000000..f93451d0b --- /dev/null +++ b/src/x86_ops_arith.txt @@ -0,0 +1,11 @@ +Comparing files CPU\x86_ops_arith.h and CPU_NEW\X86_OPS_ARITH.H +***** CPU\x86_ops_arith.h + fetch_ea_16(fetchdat); + src = getlong(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ARITH.H + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getlong(); if (cpu_state.abrt) return 1; +***** + diff --git a/src/x86_ops_atomic.txt b/src/x86_ops_atomic.txt new file mode 100644 index 000000000..778fe2d38 --- /dev/null +++ b/src/x86_ops_atomic.txt @@ -0,0 +1,161 @@ +Comparing files CPU\x86_ops_atomic.h and CPU_NEW\X86_OPS_ATOMIC.H +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); +***** + +***** CPU\x86_ops_atomic.h + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; +***** CPU_NEW\X86_OPS_ATOMIC.H + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); +***** + +***** CPU\x86_ops_atomic.h + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; +***** CPU_NEW\X86_OPS_ATOMIC.H + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** + diff --git a/src/x86_ops_bcd.txt b/src/x86_ops_bcd.txt new file mode 100644 index 000000000..efbc54429 --- /dev/null +++ b/src/x86_ops_bcd.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_bcd.h and CPU_NEW\X86_OPS_BCD.H +FC: no differences encountered + diff --git a/src/x86_ops_bit.txt b/src/x86_ops_bit.txt new file mode 100644 index 000000000..47d36c9d2 --- /dev/null +++ b/src/x86_ops_bit.txt @@ -0,0 +1,157 @@ +Comparing files CPU\x86_ops_bit.h and CPU_NEW\X86_OPS_BIT.H +***** CPU\x86_ops_bit.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; +***** CPU_NEW\X86_OPS_BIT.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; +***** + +***** CPU\x86_ops_bit.h + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** CPU_NEW\X86_OPS_BIT.H + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** + +***** CPU\x86_ops_bit.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; +***** CPU_NEW\X86_OPS_BIT.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; +***** + +***** CPU\x86_ops_bit.h + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** CPU_NEW\X86_OPS_BIT.H + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** + +***** CPU\x86_ops_bit.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; +***** CPU_NEW\X86_OPS_BIT.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; +***** + +***** CPU\x86_ops_bit.h + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** CPU_NEW\X86_OPS_BIT.H + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** + +***** CPU\x86_ops_bit.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; +***** CPU_NEW\X86_OPS_BIT.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; +***** + +***** CPU\x86_ops_bit.h + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** CPU_NEW\X86_OPS_BIT.H + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** + +***** CPU\x86_ops_bit.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteaw(); +***** CPU_NEW\X86_OPS_BIT.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteaw(); +***** + +***** CPU\x86_ops_bit.h + default: + x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_BIT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_bit.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteaw(); +***** CPU_NEW\X86_OPS_BIT.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteaw(); +***** + +***** CPU\x86_ops_bit.h + default: + x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_BIT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_bit.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteal(); +***** CPU_NEW\X86_OPS_BIT.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteal(); +***** + +***** CPU\x86_ops_bit.h + default: + x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_BIT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_bit.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteal(); +***** CPU_NEW\X86_OPS_BIT.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteal(); +***** + +***** CPU\x86_ops_bit.h + default: + x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_BIT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + diff --git a/src/x86_ops_bitscan.txt b/src/x86_ops_bitscan.txt new file mode 100644 index 000000000..a620c7932 --- /dev/null +++ b/src/x86_ops_bitscan.txt @@ -0,0 +1,11 @@ +Comparing files CPU\x86_ops_bitscan.h and CPU_NEW\X86_OPS_BITSCAN.H +***** CPU\x86_ops_bitscan.h + uint32_t temp; + int instr_cycles = 0; + +***** CPU_NEW\X86_OPS_BITSCAN.H + uint32_t temp; + int instr_cycles = 0; + +***** + diff --git a/src/x86_ops_call.txt b/src/x86_ops_call.txt new file mode 100644 index 000000000..0938461ee --- /dev/null +++ b/src/x86_ops_call.txt @@ -0,0 +1,173 @@ +Comparing files CPU\x86_ops_call.h and CPU_NEW\X86_OPS_CALL.H +***** CPU\x86_ops_call.h + old_pc = cpu_state.pc; \ + oxpc = cpu_state.pc; + \ + cpu_state.pc = new_pc; \ +***** CPU_NEW\X86_OPS_CALL.H + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ +***** + +***** CPU\x86_ops_call.h + cgate16 = cgate32 = 0; \ + if (msw & 1) loadcscall(new_seg); \ + else \ +***** CPU_NEW\X86_OPS_CALL.H + cgate16 = cgate32 = 0; \ + if (msw & 1) loadcscall(new_seg, old_pc); \ + else \ +***** + +***** CPU\x86_ops_call.h + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + } \ +***** CPU_NEW\X86_OPS_CALL.H + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } + \ + PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ + } \ +***** + +***** CPU\x86_ops_call.h + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + } +***** CPU_NEW\X86_OPS_CALL.H + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } + \ + PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ + } +***** + +***** CPU\x86_ops_call.h + old_pc = cpu_state.pc; \ + oxpc = cpu_state.pc; + \ + cpu_state.pc = new_pc; \ +***** CPU_NEW\X86_OPS_CALL.H + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ +***** + +***** CPU\x86_ops_call.h + cgate16 = cgate32 = 0; \ + if (msw & 1) loadcscall(new_seg); \ + else \ +***** CPU_NEW\X86_OPS_CALL.H + cgate16 = cgate32 = 0; \ + if (msw & 1) loadcscall(new_seg, old_pc); \ + else \ +***** + +***** CPU\x86_ops_call.h + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + } \ +***** CPU_NEW\X86_OPS_CALL.H + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } + \ + PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ + } \ +***** + +***** CPU\x86_ops_call.h + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + } +***** CPU_NEW\X86_OPS_CALL.H + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } + \ + PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ + } +***** + +***** CPU\x86_ops_call.h + SEG_CHECK_READ(cpu_state.ea_seg); + oxpc = cpu_state.pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); +***** CPU_NEW\X86_OPS_CALL.H + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = cpu_state.pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); +***** + +***** CPU\x86_ops_call.h + cpu_state.pc = new_pc; + loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** CPU_NEW\X86_OPS_CALL.H + cpu_state.pc = new_pc; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** + +***** CPU\x86_ops_call.h + SEG_CHECK_READ(cpu_state.ea_seg); + oxpc = cpu_state.pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); +***** CPU_NEW\X86_OPS_CALL.H + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = cpu_state.pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); +***** + +***** CPU\x86_ops_call.h + cpu_state.pc = new_pc; + loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** CPU_NEW\X86_OPS_CALL.H + cpu_state.pc = new_pc; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** + +***** CPU\x86_ops_call.h + SEG_CHECK_READ(cpu_state.ea_seg); + oxpc = cpu_state.pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); +***** CPU_NEW\X86_OPS_CALL.H + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = cpu_state.pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); +***** + +***** CPU\x86_ops_call.h + cpu_state.pc = new_pc; + loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** CPU_NEW\X86_OPS_CALL.H + cpu_state.pc = new_pc; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** + +***** CPU\x86_ops_call.h + SEG_CHECK_READ(cpu_state.ea_seg); + oxpc = cpu_state.pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); +***** CPU_NEW\X86_OPS_CALL.H + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = cpu_state.pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); +***** + +***** CPU\x86_ops_call.h + cpu_state.pc = new_pc; + loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** CPU_NEW\X86_OPS_CALL.H + cpu_state.pc = new_pc; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** + diff --git a/src/x86_ops_flag.txt b/src/x86_ops_flag.txt new file mode 100644 index 000000000..21220f720 --- /dev/null +++ b/src/x86_ops_flag.txt @@ -0,0 +1,78 @@ +Comparing files CPU\x86_ops_flag.h and CPU_NEW\X86_OPS_FLAG.H +***** CPU\x86_ops_flag.h + { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) +***** CPU_NEW\X86_OPS_FLAG.H + { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) +***** + +***** CPU\x86_ops_flag.h + { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) +***** CPU_NEW\X86_OPS_FLAG.H + { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) +***** + +***** CPU\x86_ops_flag.h + +#if 0 + codegen_flags_changed = 0; +#endif + +***** CPU_NEW\X86_OPS_FLAG.H + + codegen_flags_changed = 0; + +***** + +***** CPU\x86_ops_flag.h + +#if 0 + codegen_flags_changed = 0; +#endif + +***** CPU_NEW\X86_OPS_FLAG.H + + codegen_flags_changed = 0; + +***** + +***** CPU\x86_ops_flag.h + { + + ESP = old_esp; +***** CPU_NEW\X86_OPS_FLAG.H + { + ESP = old_esp; +***** + +***** CPU\x86_ops_flag.h + +#if 0 + codegen_flags_changed = 0; +#endif + +***** CPU_NEW\X86_OPS_FLAG.H + + codegen_flags_changed = 0; + +***** + +***** CPU\x86_ops_flag.h + +#if 0 + codegen_flags_changed = 0; +#endif + +***** CPU_NEW\X86_OPS_FLAG.H + + codegen_flags_changed = 0; + +***** + diff --git a/src/x86_ops_fpu.txt b/src/x86_ops_fpu.txt new file mode 100644 index 000000000..6002fbaa3 --- /dev/null +++ b/src/x86_ops_fpu.txt @@ -0,0 +1,12 @@ +Comparing files CPU\x86_ops_fpu.h and CPU_NEW\X86_OPS_FPU.H +***** CPU\x86_ops_fpu.h +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +static int opESCAPE_d8_a16(uint32_t fetchdat) +{ +***** CPU_NEW\X86_OPS_FPU.H +static int opESCAPE_d8_a16(uint32_t fetchdat) +{ +***** + diff --git a/src/x86_ops_jump.txt b/src/x86_ops_jump.txt new file mode 100644 index 000000000..53885c038 --- /dev/null +++ b/src/x86_ops_jump.txt @@ -0,0 +1,21 @@ +Comparing files CPU\x86_ops_inc_dec.h and CPU_NEW\X86_OPS_INC_DEC.H +***** CPU\x86_ops_inc_dec.h + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) +***** CPU_NEW\X86_OPS_INC_DEC.H + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) +***** + +***** CPU\x86_ops_inc_dec.h + + fetch_ea_32(fetchdat); + if (cpu_mod != 3) +***** CPU_NEW\X86_OPS_INC_DEC.H + + fetch_ea_32(fetchdat); + if (cpu_mod != 3) +***** + diff --git a/src/x86_ops_misc.txt b/src/x86_ops_misc.txt new file mode 100644 index 000000000..909fbeacb --- /dev/null +++ b/src/x86_ops_misc.txt @@ -0,0 +1,10 @@ +Comparing files CPU\x86_ops_misc.h and CPU_NEW\X86_OPS_MISC.H +***** CPU\x86_ops_misc.h + if(smi_latched) enter_smm(); + CPU_BLOCK_END(); + return 0; +***** CPU_NEW\X86_OPS_MISC.H + if(smi_latched) enter_smm(); + return 0; +***** + diff --git a/src/x86_ops_mmx.txt b/src/x86_ops_mmx.txt new file mode 100644 index 000000000..9543f7eb4 --- /dev/null +++ b/src/x86_ops_mmx.txt @@ -0,0 +1,23 @@ +Comparing files CPU\x86_ops_mmx_pack.h and CPU_NEW\X86_OPS_MMX_PACK.H +***** CPU\x86_ops_mmx_pack.h + + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; +***** CPU_NEW\X86_OPS_MMX_PACK.H + + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; +***** + +***** CPU\x86_ops_mmx_pack.h + uint32_t src; + + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; +***** CPU_NEW\X86_OPS_MMX_PACK.H + uint32_t src; + + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; +***** + diff --git a/src/x86_ops_mmx_shift.txt b/src/x86_ops_mmx_shift.txt new file mode 100644 index 000000000..5e4b5653c --- /dev/null +++ b/src/x86_ops_mmx_shift.txt @@ -0,0 +1,38 @@ +Comparing files CPU\x86_ops_mmx_shift.h and CPU_NEW\X86_OPS_MMX_SHIFT.H +***** CPU\x86_ops_mmx_shift.h + { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ +***** CPU_NEW\X86_OPS_MMX_SHIFT.H + { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ +***** + +***** CPU\x86_ops_mmx_shift.h + default: + x386_dynarec_log("Bad PSxxW (0F 71) instruction %02X\n", op); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MMX_SHIFT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mmx_shift.h + default: + x386_dynarec_log("Bad PSxxD (0F 72) instruction %02X\n", op); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MMX_SHIFT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mmx_shift.h + default: + x386_dynarec_log("Bad PSxxQ (0F 73) instruction %02X\n", op); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MMX_SHIFT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + diff --git a/src/x86_ops_mov.txt b/src/x86_ops_mov.txt new file mode 100644 index 000000000..0469bd4f1 --- /dev/null +++ b/src/x86_ops_mov.txt @@ -0,0 +1,15 @@ +Comparing files CPU\x86_ops_mov.h and CPU_NEW\X86_OPS_MOV.H +***** CPU\x86_ops_mov.h + +#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#define opCMOV(condition) \ +***** CPU_NEW\X86_OPS_MOV.H + +#define opCMOV(condition) \ +***** + +***** CPU\x86_ops_mov.h +#endif +***** CPU_NEW\X86_OPS_MOV.H +***** + diff --git a/src/x86_ops_mov_ctrl.txt b/src/x86_ops_mov_ctrl.txt new file mode 100644 index 000000000..54ba5dd2e --- /dev/null +++ b/src/x86_ops_mov_ctrl.txt @@ -0,0 +1,163 @@ +Comparing files CPU\x86_ops_mov_ctrl.h and CPU_NEW\X86_OPS_MOV_CTRL.H +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from CRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + default: + x386_dynarec_log("Bad read of CR%i %i\n",rmdat&7,cpu_reg); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MOV_CTRL.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from CRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + default: + x386_dynarec_log("Bad read of CR%i %i\n",rmdat&7,cpu_reg); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MOV_CTRL.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from DRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from DRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load CRx\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_mov_ctrl.h + cpu_cache_int_enabled = 1; + else if (isibmcpu) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + cpu_cache_int_enabled = 1; + else if (isibmcpu) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); +***** + +***** CPU\x86_ops_mov_ctrl.h + default: + x386_dynarec_log("Bad load CR%i\n", cpu_reg); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MOV_CTRL.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load CRx\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_mov_ctrl.h + default: + x386_dynarec_log("Bad load CR%i\n", cpu_reg); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MOV_CTRL.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load DRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load DRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from TRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from TRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load TRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load TRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + diff --git a/src/x86_ops_mov_seg.txt b/src/x86_ops_mov_seg.txt new file mode 100644 index 000000000..494e02515 --- /dev/null +++ b/src/x86_ops_mov_seg.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_mov_seg.h and CPU_NEW\X86_OPS_MOV_SEG.H +FC: no differences encountered + diff --git a/src/x86_ops_movx.txt b/src/x86_ops_movx.txt new file mode 100644 index 000000000..e102dae1e --- /dev/null +++ b/src/x86_ops_movx.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_movx.h and CPU_NEW\X86_OPS_MOVX.H +FC: no differences encountered + diff --git a/src/x86_ops_msr.txt b/src/x86_ops_msr.txt new file mode 100644 index 000000000..12e9c0005 --- /dev/null +++ b/src/x86_ops_msr.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_msr.h and CPU_NEW\X86_OPS_MSR.H +FC: no differences encountered + diff --git a/src/x86_ops_mul.txt b/src/x86_ops_mul.txt new file mode 100644 index 000000000..9b548257d --- /dev/null +++ b/src/x86_ops_mul.txt @@ -0,0 +1,121 @@ +Comparing files CPU\x86_ops_mul.h and CPU_NEW\X86_OPS_MUL.H +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); +***** CPU_NEW\X86_OPS_MUL.H + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); +***** + +***** CPU\x86_ops_mul.h + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); +***** CPU_NEW\X86_OPS_MUL.H + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); +***** + +***** CPU\x86_ops_mul.h + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); +***** CPU_NEW\X86_OPS_MUL.H + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); +***** + diff --git a/src/x86_ops_pmode.txt b/src/x86_ops_pmode.txt new file mode 100644 index 000000000..046806f1f --- /dev/null +++ b/src/x86_ops_pmode.txt @@ -0,0 +1,206 @@ +Comparing files CPU\x86_ops_pmode.h and CPU_NEW\X86_OPS_PMODE.H +***** CPU\x86_ops_pmode.h + fetch_ea_16(fetchdat); + /* x386_dynarec_log("ARPL_a16\n"); */ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp_seg = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_PMODE.H + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp_seg = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_pmode.h + fetch_ea_32(fetchdat); + /* x386_dynarec_log("ARPL_a32\n"); */ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp_seg = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_PMODE.H + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp_seg = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_pmode.h + int valid; \ + uint16_t sel, desc = 0; \ + \ +***** CPU_NEW\X86_OPS_PMODE.H + int valid; \ + uint16_t sel, desc = 0; \ + \ +***** + +***** CPU\x86_ops_pmode.h + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); + \ + \ +***** CPU_NEW\X86_OPS_PMODE.H + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + \ +***** + +***** CPU\x86_ops_pmode.h + int valid; \ + uint16_t sel, desc = 0; \ + \ +***** CPU_NEW\X86_OPS_PMODE.H + int valid; \ + uint16_t sel, desc = 0; \ + \ +***** + +***** CPU\x86_ops_pmode.h + + /* x386_dynarec_log("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ + switch (rmdat & 0x38) +***** CPU_NEW\X86_OPS_PMODE.H + + switch (rmdat & 0x38) +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("Invalid LLDT!\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("Invalid LTR!\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_pmode.h + default: + x386_dynarec_log("Bad 0F 00 opcode %02X\n", rmdat & 0x38); + cpu_state.pc -= 3; +***** CPU_NEW\X86_OPS_PMODE.H + default: + cpu_state.pc -= 3; +***** + +***** CPU\x86_ops_pmode.h + uint16_t limit, tempw; + /* x386_dynarec_log("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ + switch (rmdat & 0x38) +***** CPU_NEW\X86_OPS_PMODE.H + uint16_t limit, tempw; + switch (rmdat & 0x38) +***** + +***** CPU\x86_ops_pmode.h + seteaw(gdt.limit); + base = gdt.base; /* is32 ? gdt.base : (gdt.base & 0xffffff); */ + if (is286) +***** CPU_NEW\X86_OPS_PMODE.H + seteaw(gdt.limit); + base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff); + if (is286) +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("Invalid LGDT!\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_pmode.h + } + /* x386_dynarec_log("LGDT %08X:%08X\n", easeg, eaaddr); */ + if (cpu_mod != 3) +***** CPU_NEW\X86_OPS_PMODE.H + } + if (cpu_mod != 3) +***** + +***** CPU\x86_ops_pmode.h + base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; + /* x386_dynarec_log(" %08X %04X\n", base, limit); */ + gdt.limit = limit; +***** CPU_NEW\X86_OPS_PMODE.H + base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; + gdt.limit = limit; +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("Invalid LIDT!\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_pmode.h + } + /* x386_dynarec_log("LIDT %08X:%08X\n", easeg, eaaddr); */ + if (cpu_mod != 3) +***** CPU_NEW\X86_OPS_PMODE.H + } + if (cpu_mod != 3) +***** + +***** CPU\x86_ops_pmode.h + base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; + /* x386_dynarec_log(" %08X %04X\n", base, limit); */ + idt.limit = limit; +***** CPU_NEW\X86_OPS_PMODE.H + base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; + idt.limit = limit; +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("LMSW - ring not zero!\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("Invalid INVLPG!\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_pmode.h + } + SEG_CHECK_READ(cpu_state.ea_seg); + mmu_invalidate(ds + cpu_state.eaaddr); +***** CPU_NEW\X86_OPS_PMODE.H + } + SEG_CHECK_READ(cpu_state.ea_seg); + mmu_invalidate(ds + cpu_state.eaaddr); +***** + +***** CPU\x86_ops_pmode.h + default: + x386_dynarec_log("Bad 0F 01 opcode %02X\n", rmdat & 0x38); + cpu_state.pc -= 3; +***** CPU_NEW\X86_OPS_PMODE.H + default: + cpu_state.pc -= 3; +***** + diff --git a/src/x86_ops_prefix.txt b/src/x86_ops_prefix.txt new file mode 100644 index 000000000..7e4233269 --- /dev/null +++ b/src/x86_ops_prefix.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_prefix.h and CPU_NEW\X86_OPS_PREFIX.H +FC: no differences encountered + diff --git a/src/x86_ops_rep.txt b/src/x86_ops_rep.txt new file mode 100644 index 000000000..e08f17803 --- /dev/null +++ b/src/x86_ops_rep.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_rep.h and CPU_NEW\X86_OPS_REP.H +FC: no differences encountered + diff --git a/src/x86_ops_ret.txt b/src/x86_ops_ret.txt new file mode 100644 index 000000000..a04382278 --- /dev/null +++ b/src/x86_ops_ret.txt @@ -0,0 +1,66 @@ +Comparing files CPU\x86_ops_ret.h and CPU_NEW\X86_OPS_RET.H +***** CPU\x86_ops_ret.h +#define RETF_a16(stack_offset) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + { \ +***** CPU_NEW\X86_OPS_RET.H +#define RETF_a16(stack_offset) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + { \ +***** + +***** CPU\x86_ops_ret.h + } \ + oxpc = cpu_state.pc; \ + if (stack32) \ +***** CPU_NEW\X86_OPS_RET.H + } \ + if (stack32) \ +***** + +***** CPU\x86_ops_ret.h +#define RETF_a32(stack_offset) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + { \ +***** CPU_NEW\X86_OPS_RET.H +#define RETF_a32(stack_offset) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + { \ +***** + +***** CPU\x86_ops_ret.h + } \ + oxpc = cpu_state.pc; \ + if (stack32) \ +***** CPU_NEW\X86_OPS_RET.H + } \ + if (stack32) \ +***** + +***** CPU\x86_ops_ret.h + uint16_t new_cs; + oxpc = cpu_state.pc; + if (stack32) +***** CPU_NEW\X86_OPS_RET.H + uint16_t new_cs; + if (stack32) +***** + +***** CPU\x86_ops_ret.h + uint16_t new_cs; + oxpc = cpu_state.pc; + if (stack32) +***** CPU_NEW\X86_OPS_RET.H + uint16_t new_cs; + if (stack32) +***** + +***** CPU\x86_ops_ret.h + uint16_t new_cs; + oxpc = cpu_state.pc; + if (stack32) +***** CPU_NEW\X86_OPS_RET.H + uint16_t new_cs; + if (stack32) +***** + diff --git a/src/x86_ops_set.txt b/src/x86_ops_set.txt new file mode 100644 index 000000000..be3a1a7ea --- /dev/null +++ b/src/x86_ops_set.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_set.h and CPU_NEW\X86_OPS_SET.H +FC: no differences encountered + diff --git a/src/x86_ops_shift.txt b/src/x86_ops_shift.txt new file mode 100644 index 000000000..670c26b78 --- /dev/null +++ b/src/x86_ops_shift.txt @@ -0,0 +1,126 @@ +Comparing files CPU\x86_ops_shift.h and CPU_NEW\X86_OPS_SHIFT.H +***** CPU\x86_ops_shift.h + seteab(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 7)) & 1) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + seteab(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROL8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ + seteab(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ + seteab(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROR8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; + \ + case 0x10: /*RCL b,CL*/ \ +***** CPU_NEW\X86_OPS_SHIFT.H + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x10: /*RCL b,CL*/ \ +***** + +***** CPU\x86_ops_shift.h + seteaw(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 15)) & 1) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + seteaw(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROL16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + seteaw(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x8000) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + seteaw(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROR16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + seteal(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 31)) & 1) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + seteal(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROL32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + seteal(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80000000) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + seteal(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROR32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + count = getbyte() & 31; \ + operation() \ + \ +***** CPU_NEW\X86_OPS_SHIFT.H + count = getbyte() & 31; \ + operation(); \ + \ +***** + +***** CPU\x86_ops_shift.h + count = CL & 31; \ + operation() \ + \ +***** CPU_NEW\X86_OPS_SHIFT.H + count = CL & 31; \ + operation(); \ + \ +***** + +***** CPU\x86_ops_shift.h + count = getbyte() & 31; \ + operation() \ + \ +***** CPU_NEW\X86_OPS_SHIFT.H + count = getbyte() & 31; \ + operation(); \ + \ +***** + +***** CPU\x86_ops_shift.h + count = CL & 31; \ + operation() \ + \ +***** CPU_NEW\X86_OPS_SHIFT.H + count = CL & 31; \ + operation(); \ + \ +***** + diff --git a/src/x86_ops_stack.txt b/src/x86_ops_stack.txt new file mode 100644 index 000000000..4c3cdabc2 --- /dev/null +++ b/src/x86_ops_stack.txt @@ -0,0 +1,65 @@ +Comparing files CPU\x86_ops_stack.h and CPU_NEW\X86_OPS_STACK.H +***** CPU\x86_ops_stack.h + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(temp); +***** CPU_NEW\X86_OPS_STACK.H + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(temp); +***** + +***** CPU\x86_ops_stack.h + +PUSH_SEG_OPS(CS) +PUSH_SEG_OPS(DS) +PUSH_SEG_OPS(ES) +PUSH_SEG_OPS(FS) +PUSH_SEG_OPS(GS) +PUSH_SEG_OPS(SS) + +POP_SEG_OPS(DS, &cpu_state.seg_ds) +POP_SEG_OPS(ES, &cpu_state.seg_es) +POP_SEG_OPS(FS, &cpu_state.seg_fs) +POP_SEG_OPS(GS, &cpu_state.seg_gs) + +***** CPU_NEW\X86_OPS_STACK.H + +PUSH_SEG_OPS(CS); +PUSH_SEG_OPS(DS); +PUSH_SEG_OPS(ES); +PUSH_SEG_OPS(FS); +PUSH_SEG_OPS(GS); +PUSH_SEG_OPS(SS); + +POP_SEG_OPS(DS, &cpu_state.seg_ds); +POP_SEG_OPS(ES, &cpu_state.seg_es); +POP_SEG_OPS(FS, &cpu_state.seg_fs); +POP_SEG_OPS(GS, &cpu_state.seg_gs); + +***** + +***** CPU\x86_ops_stack.h + temp_seg = POP_W(); if (cpu_state.abrt) return 1; + loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + CLOCK_CYCLES(is486 ? 3 : 7); +***** CPU_NEW\X86_OPS_STACK.H + temp_seg = POP_W(); if (cpu_state.abrt) return 1; + loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + CLOCK_CYCLES(is486 ? 3 : 7); +***** + +***** CPU\x86_ops_stack.h + temp_seg = POP_L(); if (cpu_state.abrt) return 1; + loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + CLOCK_CYCLES(is486 ? 3 : 7); +***** CPU_NEW\X86_OPS_STACK.H + temp_seg = POP_L(); if (cpu_state.abrt) return 1; + loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + CLOCK_CYCLES(is486 ? 3 : 7); +***** + diff --git a/src/x86_ops_string.txt b/src/x86_ops_string.txt new file mode 100644 index 000000000..d8360e622 --- /dev/null +++ b/src/x86_ops_string.txt @@ -0,0 +1,553 @@ +Comparing files CPU\x86_ops_string.h and CPU_NEW\X86_OPS_STRING.H +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } + else { EDI += 2; ESI += 2; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } + else { EDI += 2; ESI += 2; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } + else { DI += 4; SI += 4; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } + else { DI += 4; SI += 4; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } + else { EDI += 4; ESI += 4; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } + else { EDI += 4; ESI += 4; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } + else { EDI += 2; ESI += 2; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } + else { EDI += 2; ESI += 2; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } + else { DI += 4; SI += 4; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } + else { DI += 4; SI += 4; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } + else { EDI += 4; ESI += 4; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } + else { EDI += 4; ESI += 4; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememb(es, DI, AL); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememb(es, DI, AL); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememb(es, EDI, AL); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememb(es, EDI, AL); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememw(es, DI, AX); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememw(es, DI, AX); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememw(es, EDI, AX); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememw(es, EDI, AX); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememl(es, DI, EAX); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememl(es, DI, EAX); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI--; + else SI++; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI--; + else SI++; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI--; + else ESI++; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI--; + else ESI++; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI -= 2; + else ESI += 2; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI -= 2; + else ESI += 2; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI -= 4; + else SI += 4; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI -= 4; + else SI += 4; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI -= 4; + else ESI += 4; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI -= 4; + else ESI += 4; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + uint8_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint8_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + uint8_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint8_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + uint16_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint16_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + uint16_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint16_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + uint32_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint32_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + uint32_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint32_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI--; + else SI++; + outb(DX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI--; + else SI++; + outb(DX, temp); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI--; + else ESI++; + outb(DX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI--; + else ESI++; + outb(DX, temp); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; + outw(DX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; + outw(DX, temp); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI -= 2; + else ESI += 2; + outw(DX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI -= 2; + else ESI += 2; + outw(DX, temp); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI -= 4; + else SI += 4; + outl(EDX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI -= 4; + else SI += 4; + outl(EDX, temp); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI -= 4; + else ESI += 4; + outl(EDX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI -= 4; + else ESI += 4; + outl(EDX, temp); +***** + diff --git a/src/x86_ops_xchg.txt b/src/x86_ops_xchg.txt new file mode 100644 index 000000000..c290e1b1c --- /dev/null +++ b/src/x86_ops_xchg.txt @@ -0,0 +1,55 @@ +Comparing files CPU\x86_ops_xchg.h and CPU_NEW\X86_OPS_XCHG.H +***** CPU\x86_ops_xchg.h + uint8_t temp; + fetch_ea_16(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint8_t temp; + + fetch_ea_16(fetchdat); +***** + +***** CPU\x86_ops_xchg.h + uint8_t temp; + fetch_ea_32(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint8_t temp; + + fetch_ea_32(fetchdat); +***** + +***** CPU\x86_ops_xchg.h + uint16_t temp; + fetch_ea_16(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint16_t temp; + + fetch_ea_16(fetchdat); +***** + +***** CPU\x86_ops_xchg.h + uint16_t temp; + fetch_ea_32(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint16_t temp; + + fetch_ea_32(fetchdat); +***** + +***** CPU\x86_ops_xchg.h + uint32_t temp; + fetch_ea_16(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint32_t temp; + + fetch_ea_16(fetchdat); +***** + +***** CPU\x86_ops_xchg.h + uint32_t temp; + fetch_ea_32(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint32_t temp; + + fetch_ea_32(fetchdat); +***** + diff --git a/src/x86_seg.txt b/src/x86_seg.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/x86seg.txt b/src/x86seg.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/x87.txt b/src/x87.txt new file mode 100644 index 000000000..a446f0813 --- /dev/null +++ b/src/x87.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x87.c and CPU_NEW\X87.C +FC: no differences encountered + diff --git a/src/x87_bak/x87.h b/src/x87_bak/x87.h new file mode 100644 index 000000000..be30c280c --- /dev/null +++ b/src/x87_bak/x87.h @@ -0,0 +1,58 @@ +#define C0 (1<<8) +#define C1 (1<<9) +#define C2 (1<<10) +#define C3 (1<<14) + +uint32_t x87_pc_off,x87_op_off; +uint16_t x87_pc_seg,x87_op_seg; + +static inline void x87_set_mmx() +{ +#ifdef USE_NEW_DYNAREC + cpu_state.TOP = 0; + *(uint64_t *)cpu_state.tag = 0x0101010101010101ull; + cpu_state.ismmx = 1; +#else + uint64_t *p; + cpu_state.TOP = 0; + p = (uint64_t *)cpu_state.tag; + *p = 0; + cpu_state.ismmx = 1; +#endif +} + +static inline void x87_emms() +{ +#ifdef USE_NEW_DYNAREC + *(uint64_t *)cpu_state.tag = 0; + cpu_state.ismmx = 0; +#else + uint64_t *p; + p = (uint64_t *)cpu_state.tag; + *p = 0; + cpu_state.ismmx = 0; +#endif +} + + +uint16_t x87_gettag(); +void x87_settag(uint16_t new_tag); + +#ifdef USE_NEW_DYNAREC +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) +/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ +#define TAG_UINT64 (1 << 7) + +#define X87_ROUNDING_NEAREST 0 +#define X87_ROUNDING_DOWN 1 +#define X87_ROUNDING_UP 2 +#define X87_ROUNDING_CHOP 3 + +void codegen_set_rounding_mode(int mode); +#else +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) +/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ +#define TAG_UINT64 (1 << 2) +#endif diff --git a/src/x87_bak/x87_ops.h b/src/x87_bak/x87_ops.h new file mode 100644 index 000000000..57416251f --- /dev/null +++ b/src/x87_bak/x87_ops.h @@ -0,0 +1,2147 @@ +/* + * 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. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops.h 1.0.8 2019/06/11 + * + * Authors: Fred N. van Kempen, + * Sarah Walker, + * leilei, + * Miran Grca, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 leilei. + * Copyright 2016-2019 Miran Grca. + * Copyright 2018,2019 Fred N. van Kempen. + */ +#include +#include +#ifdef _MSC_VER +# include +#endif +// #include "x87_timings.h" + +#ifdef ENABLE_FPU_LOG +extern void fpu_log(const char *fmt, ...); +#else +#ifndef fpu_log +#define fpu_log(fmt, ...) +#endif +#endif + +static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO}; + +#define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)] + +#define STATUS_ZERODIVIDE 4 + +#ifdef FPU_8087 +#define x87_div(dst, src1, src2) do \ + { \ + if (((double)src2) == 0.0) \ + { \ + cpu_state.npxs |= STATUS_ZERODIVIDE; \ + if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + dst = src1 / (double)src2; \ + else \ + { \ + fpu_log("FPU : divide by zero\n"); \ + if (!(cpu_state.npxc & 0x80)) { \ + cpu_state.npxs |= 0x80; \ + nmi = 1; \ + } \ + return 1; \ + } \ + } \ + else \ + dst = src1 / (double)src2; \ + } while (0) +#else +#define x87_div(dst, src1, src2) do \ + { \ + if (((double)src2) == 0.0) \ + { \ + cpu_state.npxs |= STATUS_ZERODIVIDE; \ + if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + dst = src1 / (double)src2; \ + else \ + { \ + fpu_log("FPU : divide by zero\n"); \ + picint(1 << 13); \ + return 1; \ + } \ + } \ + else \ + dst = src1 / (double)src2; \ + } while (0) +#endif + +static __inline void x87_checkexceptions() +{ +} + +static __inline void x87_push(double i) +{ +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP&7] = i; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#else + cpu_state.TOP=(cpu_state.TOP-1)&7; + cpu_state.ST[cpu_state.TOP] = i; + cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? 1 : 0; +#endif +} + +static __inline void x87_push_u64(uint64_t i) +{ + union + { + double d; + uint64_t ll; + } td; + + td.ll = i; + +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP&7] = td.d; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#else + cpu_state.TOP=(cpu_state.TOP-1)&7; + cpu_state.ST[cpu_state.TOP] = td.d; + cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? 1 : 0; +#endif +} + +static __inline double x87_pop() +{ +#ifdef USE_NEW_DYNAREC + double t = cpu_state.ST[cpu_state.TOP&7]; + cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY; + cpu_state.TOP++; + return t; +#else + double t = cpu_state.ST[cpu_state.TOP]; + cpu_state.tag[cpu_state.TOP&7] = 3; + cpu_state.TOP=(cpu_state.TOP+1)&7; + return t; +#endif +} + +static int old_round = FE_TONEAREST; + +static __inline int64_t x87_round_save(void) +{ + old_round = fetgetround(); +} + +static __inline int64_t x87_round_set(void) +{ + old_round = fetgetround(); + + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + fesetround(FE_TONEAREST); + break; + case 1: /*Down*/ + fesetround(FE_DOWNWARD); + break; + case 2: /*Up*/ + fesetround(FE_UPWARD); + break; + case 3: /*Chop*/ + fesetround(FE_TOWARDZERO); + break; + } +} + +static __inline int64_t x87_round_restore(void) +{ + fesetround(old_round); +} + +#ifdef PCEM_CODE +static __inline int64_t x87_fround(double b) +{ +#ifdef PCEM_CODE + int64_t a, c; +#endif + + switch ((cpu_state.npxc >> 10) & 3) + { + case 0: /*Nearest*/ +#ifdef PCEM_CODE + a = (int64_t)floor(b); + c = (int64_t)floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; +#else + return (int64_t)round(b); +#endif + case 1: /*Down*/ + return (int64_t)floor(b); + case 2: /*Up*/ + return (int64_t)ceil(b); + case 3: /*Chop*/ +#ifdef PCEM_CODE + return (int64_t)b; +#else + return (int64_t)trunc(b); +#endif + } + + return 0; +} +#else +static __inline int64_t x87_fround(double b) +{ + int64_t ret; + + x87_round_set(); + ret = (int64_t) rint(b); + x87_round_restore(); +} +#endif +#define BIAS80 16383 +#define BIAS64 1023 + +static __inline double x87_ld80() +{ + int64_t exp64; + int64_t blah; + int64_t exp64final; + int64_t mant64; + int64_t sign; + + struct { + int16_t begin; + union + { + double d; + uint64_t ll; + } eind; + } test; + + test.eind.ll = readmeml(easeg,cpu_state.eaaddr); + test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32; + test.begin = readmemw(easeg,cpu_state.eaaddr+8); + + exp64 = (((test.begin&0x7fff) - BIAS80)); + blah = ((exp64 >0)?exp64:-exp64)&0x3ff; + exp64final = ((exp64 >0)?blah:-blah) +BIAS64; + + mant64 = (test.eind.ll >> 11) & (0xfffffffffffffll); + sign = (test.begin&0x8000)?1:0; + + if ((test.begin & 0x7fff) == 0x7fff) + exp64final = 0x7ff; + if ((test.begin & 0x7fff) == 0) + exp64final = 0; + if (test.eind.ll & 0x400) + mant64++; + + test.eind.ll = (sign <<63)|(exp64final << 52)| mant64; + + return test.eind.d; +} + +static __inline void x87_st80(double d) +{ + int64_t sign80; + int64_t exp80; + int64_t exp80final; + int64_t mant80; + int64_t mant80final; + + struct { + int16_t begin; + union + { + double d; + uint64_t ll; + } eind; + } test; + + test.eind.d=d; + + sign80 = (test.eind.ll&(0x8000000000000000ll))?1:0; + exp80 = test.eind.ll&(0x7ff0000000000000ll); + exp80final = (exp80>>52); + mant80 = test.eind.ll&(0x000fffffffffffffll); + mant80final = (mant80 << 11); + + if (exp80final == 0x7ff) /*Infinity / Nan*/ + { + exp80final = 0x7fff; + mant80final |= (0x8000000000000000ll); + } + else if (d != 0){ /* Zero is a special case */ + /* Elvira wants the 8 and tcalc doesn't */ + mant80final |= (0x8000000000000000ll); + /* Ca-cyber doesn't like this when result is zero. */ + exp80final += (BIAS80 - BIAS64); + } + test.begin = (((int16_t)sign80)<<15)| (int16_t)exp80final; + test.eind.ll = mant80final; + + writememl(easeg,cpu_state.eaaddr,test.eind.ll & 0xffffffff); + writememl(easeg,cpu_state.eaaddr+4,test.eind.ll>>32); + writememw(easeg,cpu_state.eaaddr+8,test.begin); +} + +static __inline void x87_st_fsave(int reg) +{ + reg = (cpu_state.TOP + reg) & 7; + + if (cpu_state.tag[reg] & TAG_UINT64) + { + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff); + writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32); + writememw(easeg, cpu_state.eaaddr + 8, 0x5555); + } + else + x87_st80(cpu_state.ST[reg]); +} + +static __inline void x87_ld_frstor(int reg) +{ + reg = (cpu_state.TOP + reg) & 7; + + cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); + cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); + +#ifdef USE_NEW_DYNAREC + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) + { + cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; + } + else + { + cpu_state.tag[reg] &= ~TAG_UINT64; + cpu_state.ST[reg] = x87_ld80(); + } +#else + if (cpu_state.MM_w4[reg] == 0x5555 && cpu_state.tag[reg] == 2) + { + cpu_state.tag[reg] = TAG_UINT64; + cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; + } + else + cpu_state.ST[reg] = x87_ld80(); +#endif +} + +static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) +{ + r->l[0] = readmeml(easeg, cpu_state.eaaddr); + r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + *w4 = readmemw(easeg, cpu_state.eaaddr + 8); +} + +static __inline void x87_stmmx(MMX_REG r) +{ + writememl(easeg, cpu_state.eaaddr, r.l[0]); + writememl(easeg, cpu_state.eaaddr + 4, r.l[1]); + writememw(easeg, cpu_state.eaaddr + 8, 0xffff); +} + +#include + +static __inline uint16_t x87_compare(double a, double b) +{ +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 + uint32_t result; + double ea = a, eb = b; + const uint64_t ia = 0x3fec1a6ff866a936ull; + const uint64_t ib = 0x3fec1a6ff866a938ull; + + /* Hack to make CHKCOP happy. */ + if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) + return C3; + + if (!is386 && !(cpu_state.npxc & 0x1000) && + ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) + eb = ea; + +#ifndef _MSC_VER + /* Memory barrier, to force GCC to write to the input parameters + * before the compare rather than after */ + __asm volatile ("" : : : "memory"); + + __asm( + "fldl %2\n" + "fldl %1\n" + "fclex\n" + "fcompp\n" + "fnstsw %0\n" + : "=m" (result) + : "m" (ea), "m" (eb) + ); +#else + _ReadWriteBarrier(); + _asm + { + fld eb + fld ea + fclex + fcompp + fnstsw result + } +#endif + + return result & (C0|C2|C3); +#else + /* Generic C version is known to give incorrect results in some + * situations, eg comparison of infinity (Unreal) */ + uint32_t result = 0; + double ea = a, eb = b; + + if (!is386 && !(cpu_state.npxc & 0x1000) && + ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) + eb = ea; + + if (ea == eb) + result |= C3; + else if (ea < eb) + result |= C0; + + return result; +#endif +} + +static __inline uint16_t x87_ucompare(double a, double b) +{ +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__ + uint32_t result; + +#ifndef _MSC_VER + /* Memory barrier, to force GCC to write to the input parameters + * before the compare rather than after */ + asm volatile ("" : : : "memory"); + + asm( + "fldl %2\n" + "fldl %1\n" + "fclex\n" + "fucompp\n" + "fnstsw %0\n" + : "=m" (result) + : "m" (a), "m" (b) + ); +#else + _ReadWriteBarrier(); + _asm + { + fld b + fld a + fclex + fcompp + fnstsw result + } +#endif + + return result & (C0|C2|C3); +#else + /* Generic C version is known to give incorrect results in some + * situations, eg comparison of infinity (Unreal) */ + uint32_t result = 0; + + if (a == b) + result |= C3; + else if (a < b) + result |= C0; + + return result; +#endif +} + +typedef union +{ + float s; + uint32_t i; +} x87_ts; + +typedef union +{ + double d; + uint64_t i; +} x87_td; + +#ifdef FPU_8087 +#define FP_ENTER() { \ + fpucount++; \ + } +#else +#define FP_ENTER() do \ + { \ + if (cr0 & 0xc) \ + { \ + x86_int(7); \ + return 1; \ + } \ + fpucount++; \ + } while (0) +#endif + +// #ifdef USE_NEW_DYNAREC +#if 1 +#define FP_TAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#define FP_FTAG() cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; +#define FP_LSTAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64; +#define FP_LSQ() cpu_state.MM[cpu_state.TOP&7].q = temp64; +#define FP_LSRETQ() temp64 = cpu_state.MM[cpu_state.TOP&7].q; +#define FP_NTAG() cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; +#ifdef USE_NEW_DYNAREC +#define FP_NNPXC() codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#else +#define FP_NNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); +#endif +#define FP_TOP(x) (x & 7) +#define FP_DTAG 0ULL +#define FP_CTAG 0x0101010101010101ull +#define FP_EMPTY TAG_EMPTY +#ifdef USE_NEW_DYNAREC +#define FP_RNPXC() codegen_set_rounding_mode(X87_ROUNDING_NEAREST); +#else +#define FP_RNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); +#endif +#define FP_ZTAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#define FP_DECTOP() cpu_state.TOP--; +#define FP_INCTOP() cpu_state.TOP++; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +#define FP_686 +#endif +#else +#define FP_TAG() cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; +#define FP_FTAG() cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; +#define FP_LSTAG() cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; +#define FP_LSQ() cpu_state.MM[cpu_state.TOP].q = temp64; +#define FP_LSRETQ() temp64 = cpu_state.MM[cpu_state.TOP].q; +#define FP_NTAG() cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; +#define FP_NNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); +#define FP_TOP(x) (x) +#define FP_DTAG 0x0303030303030303ll +#define FP_CTAG 0ULL +#define FP_EMPTY 3 +#define FP_RNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); +#define FP_ZTAG() cpu_state.tag[cpu_state.TOP&7] = 1; +#define FP_DECTOP() cpu_state.TOP = (cpu_state.TOP - 1) & 7 +#define FP_INCTOP() cpu_state.TOP = (cpu_state.TOP + 1) & 7 +#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#define FP_686 +#endif +#endif + +#include "x87_ops_arith.h" +#include "x87_ops_misc.h" +#include "x87_ops_loadstore.h" + +#ifndef FPU_8087 +static int op_nofpu_a16(uint32_t fetchdat) +{ + if (cr0 & 0xc) + { + x86_int(7); + return 1; + } + else + { + fetch_ea_16(fetchdat); + return 0; + } +} +static int op_nofpu_a32(uint32_t fetchdat) +{ + if (cr0 & 0xc) + { + x86_int(7); + return 1; + } + else + { + fetch_ea_32(fetchdat); + return 0; + } +} +#endif + +#ifdef FPU_8087 +static int FPU_ILLEGAL_a16(uint32_t fetchdat) +{ + geteaw(); + wait(timing_rr, 0); + return 0; +} +#else +static int FPU_ILLEGAL_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); + return 0; +} + +static int FPU_ILLEGAL_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); + return 0; +} +#endif + +#define ILLEGAL_a16 FPU_ILLEGAL_a16 + +#ifdef FPU_8087 +const OpFn OP_TABLE(fpu_8087_d8)[32] = +{ + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR +}; + +const OpFn OP_TABLE(fpu_8087_d9)[256] = +{ + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, ILLEGAL_a16, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, ILLEGAL_a16, opFRNDINT, opFSCALE, ILLEGAL_a16, ILLEGAL_a16 +}; + +const OpFn OP_TABLE(fpu_8087_da)[256] = +{ + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; + +const OpFn OP_TABLE(fpu_8087_db)[256] = +{ + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFI, opFI, opFCLEX, opFINIT, ILLEGAL_a16, opFNOP, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; + +const OpFn OP_TABLE(fpu_8087_dc)[32] = +{ + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; + +const OpFn OP_TABLE(fpu_8087_dd)[256] = +{ + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; + +const OpFn OP_TABLE(fpu_8087_de)[256] = +{ + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +const OpFn OP_TABLE(fpu_8087_df)[256] = +{ + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +#else +#define ILLEGAL_a32 FPU_ILLEGAL_a32 + +const OpFn OP_TABLE(fpu_d8_a16)[32] = +{ + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR +}; +const OpFn OP_TABLE(fpu_d8_a32)[32] = +{ + opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, + opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, + opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, + opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR +}; + +const OpFn OP_TABLE(fpu_287_d9_a16)[256] = +{ + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +}; + +const OpFn OP_TABLE(fpu_287_d9_a32)[256] = +{ + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +}; + +const OpFn OP_TABLE(fpu_d9_a16)[256] = +{ + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +}; + +const OpFn OP_TABLE(fpu_d9_a32)[256] = +{ + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +}; + +const OpFn OP_TABLE(fpu_287_da_a16)[256] = +{ + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_287_da_a32)[256] = +{ + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +const OpFn OP_TABLE(fpu_da_a16)[256] = +{ + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_da_a32)[256] = +{ + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +const OpFn OP_TABLE(fpu_686_da_a16)[256] = +{ + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, + opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, + opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, + opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_686_da_a32)[256] = +{ + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, + opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, + opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, + opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; +#endif + +const OpFn OP_TABLE(fpu_287_db_a16)[256] = +{ + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_287_db_a32)[256] = +{ + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +const OpFn OP_TABLE(fpu_db_a16)[256] = +{ + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_db_a32)[256] = +{ + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +const OpFn OP_TABLE(fpu_686_db_a16)[256] = +{ + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, + opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, + opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, + opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, + opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, + opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_686_db_a32)[256] = +{ + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, + opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, + opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, + opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, + opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, + opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; +#endif + +const OpFn OP_TABLE(fpu_287_dc_a16)[32] = +{ + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; +const OpFn OP_TABLE(fpu_287_dc_a32)[32] = +{ + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDr, opFMULr, ILLEGAL_a32, ILLEGAL_a32, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; + +const OpFn OP_TABLE(fpu_dc_a16)[32] = +{ + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; +const OpFn OP_TABLE(fpu_dc_a32)[32] = +{ + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; + +const OpFn OP_TABLE(fpu_287_dd_a16)[256] = +{ + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_287_dd_a32)[256] = +{ + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +const OpFn OP_TABLE(fpu_dd_a16)[256] = +{ + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, + opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_dd_a32)[256] = +{ + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, + opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +const OpFn OP_TABLE(fpu_287_de_a16)[256] = +{ + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +const OpFn OP_TABLE(fpu_287_de_a32)[256] = +{ + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, opFCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +const OpFn OP_TABLE(fpu_de_a16)[256] = +{ + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, + ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +const OpFn OP_TABLE(fpu_de_a32)[256] = +{ + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, + ILLEGAL_a32, opFCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +const OpFn OP_TABLE(fpu_287_df_a16)[256] = +{ + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_287_df_a32)[256] = +{ + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +const OpFn OP_TABLE(fpu_df_a16)[256] = +{ + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_df_a32)[256] = +{ + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +const OpFn OP_TABLE(fpu_686_df_a16)[256] = +{ + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, + opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_686_df_a32)[256] = +{ + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, + opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; +#endif + +const OpFn OP_TABLE(nofpu_a16)[256] = +{ + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, +}; +const OpFn OP_TABLE(nofpu_a32)[256] = +{ + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, +}; +#endif + +#undef ILLEGAL diff --git a/src/cpu/x87_ops_arith.h b/src/x87_bak/x87_ops_arith.h similarity index 88% rename from src/cpu/x87_ops_arith.h rename to src/x87_bak/x87_ops_arith.h index 720a5c469..133ecb689 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/x87_bak/x87_ops_arith.h @@ -11,7 +11,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ ST(0) += use_var; \ if ((cpu_state.npxc >> 10) & 3) \ fesetround(FE_TONEAREST); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(8); \ return 0; \ } \ @@ -48,7 +48,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), ST(0), use_var); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(73); \ return 0; \ } \ @@ -60,7 +60,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), use_var, ST(0)); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(73); \ return 0; \ } \ @@ -72,7 +72,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) *= use_var; \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(11); \ return 0; \ } \ @@ -84,7 +84,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) -= use_var; \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(8); \ return 0; \ } \ @@ -96,7 +96,7 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) = use_var - ST(0); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(8); \ return 0; \ } @@ -128,7 +128,7 @@ static int opFADD(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = ST(0) + ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(8); return 0; } @@ -137,7 +137,7 @@ static int opFADDr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(8); return 0; } @@ -146,7 +146,7 @@ static int opFADDP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(8); return 0; @@ -205,7 +205,7 @@ static int opFUCOMPP(uint32_t fetchdat) return 0; } -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#ifdef FP_686 static int opFCOMI(uint32_t fetchdat) { FP_ENTER(); @@ -237,7 +237,7 @@ static int opFDIV(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(0), ST(0), ST(fetchdat & 7)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(73); return 0; } @@ -246,7 +246,7 @@ static int opFDIVr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(73); return 0; } @@ -255,7 +255,7 @@ static int opFDIVP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(73); return 0; @@ -266,7 +266,7 @@ static int opFDIVR(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(0), ST(fetchdat&7), ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(73); return 0; } @@ -275,7 +275,7 @@ static int opFDIVRr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(73); return 0; } @@ -284,7 +284,7 @@ static int opFDIVRP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(73); return 0; @@ -295,7 +295,7 @@ static int opFMUL(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(16); return 0; } @@ -304,7 +304,7 @@ static int opFMULr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(16); return 0; } @@ -313,7 +313,7 @@ static int opFMULP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(16); return 0; @@ -324,7 +324,7 @@ static int opFSUB(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(8); return 0; } @@ -333,7 +333,7 @@ static int opFSUBr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(8); return 0; } @@ -342,7 +342,7 @@ static int opFSUBP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(8); return 0; @@ -353,7 +353,7 @@ static int opFSUBR(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(8); return 0; } @@ -362,7 +362,7 @@ static int opFSUBRr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(8); return 0; } @@ -371,7 +371,7 @@ static int opFSUBRP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(8); return 0; @@ -399,7 +399,7 @@ static int opFUCOMP(uint32_t fetchdat) return 0; } -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#ifdef FP_686 static int opFUCOMI(uint32_t fetchdat) { FP_ENTER(); diff --git a/src/x87_bak/x87_ops_loadstore.h b/src/x87_bak/x87_ops_loadstore.h new file mode 100644 index 000000000..b5ad491f9 --- /dev/null +++ b/src/x87_bak/x87_ops_loadstore.h @@ -0,0 +1,492 @@ +/* + * 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. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops_loadstore.h 1.0.2 2019/06/11 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + */ + +static int opFILDiw_a16(uint32_t fetchdat) +{ + int16_t temp; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; + x87_push((double)temp); + CLOCK_CYCLES(13); + return 0; +} +#ifndef FPU_8087 +static int opFILDiw_a32(uint32_t fetchdat) +{ + int16_t temp; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; + x87_push((double)temp); + CLOCK_CYCLES(13); + return 0; +} +#endif + +static int opFISTiw_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); + CLOCK_CYCLES(29); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFISTiw_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); + CLOCK_CYCLES(29); + return cpu_state.abrt; +} +#endif + +static int opFISTPiw_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(29); + return 0; +} +#ifndef FPU_8087 +static int opFISTPiw_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(29); + return 0; +} +#endif + +static int opFILDiq_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; + x87_push((double)temp64); + FP_LSQ(); + FP_LSTAG(); + + CLOCK_CYCLES(10); + return 0; +} +#ifndef FPU_8087 +static int opFILDiq_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; + x87_push((double)temp64); + FP_LSQ(); + FP_LSTAG(); + + CLOCK_CYCLES(10); + return 0; +} +#endif + +static int FBSTP_a16(uint32_t fetchdat) +{ + double tempd; + int c; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + tempd = ST(0); + if (tempd < 0.0) + tempd = -tempd; + for (c = 0; c < 9; c++) + { + uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + writememb(easeg, cpu_state.eaaddr + c, tempc); + } + tempc = (uint8_t)floor(fmod(tempd, 10.0)); + if (ST(0) < 0.0) tempc |= 0x80; + writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; + x87_pop(); + return 0; +} +#ifndef FPU_8087 +static int FBSTP_a32(uint32_t fetchdat) +{ + double tempd; + int c; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + tempd = ST(0); + if (tempd < 0.0) + tempd = -tempd; + for (c = 0; c < 9; c++) + { + uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + writememb(easeg, cpu_state.eaaddr + c, tempc); + } + tempc = (uint8_t)floor(fmod(tempd, 10.0)); + if (ST(0) < 0.0) tempc |= 0x80; + writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; + x87_pop(); + return 0; +} +#endif + +static int FISTPiq_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) + FP_LSRETQ() + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(29); + return 0; +} +#ifndef FPU_8087 +static int FISTPiq_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) + FP_LSRETQ() + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(29); + return 0; +} +#endif + +static int opFILDil_a16(uint32_t fetchdat) +{ + int32_t templ; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; + x87_push((double)templ); + CLOCK_CYCLES(9); + return 0; +} +#ifndef FPU_8087 +static int opFILDil_a32(uint32_t fetchdat) +{ + int32_t templ; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; + x87_push((double)templ); + CLOCK_CYCLES(9); + return 0; +} +#endif + +static int opFISTil_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); + CLOCK_CYCLES(28); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFISTil_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); + CLOCK_CYCLES(28); + return cpu_state.abrt; +} +#endif + +static int opFISTPil_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(28); + return 0; +} +#ifndef FPU_8087 +static int opFISTPil_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(28); + return 0; +} +#endif + +static int opFLDe_a16(uint32_t fetchdat) +{ + double t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t=x87_ld80(); if (cpu_state.abrt) return 1; + x87_push(t); + CLOCK_CYCLES(6); + return 0; +} +#ifndef FPU_8087 +static int opFLDe_a32(uint32_t fetchdat) +{ + double t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t=x87_ld80(); if (cpu_state.abrt) return 1; + x87_push(t); + CLOCK_CYCLES(6); + return 0; +} +#endif + +static int opFSTPe_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + x87_st80(ST(0)); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(6); + return 0; +} +#ifndef FPU_8087 +static int opFSTPe_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + x87_st80(ST(0)); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(6); + return 0; +} +#endif + +static int opFLDd_a16(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); if (cpu_state.abrt) return 1; + x87_push(t.d); + CLOCK_CYCLES(3); + return 0; +} +#ifndef FPU_8087 +static int opFLDd_a32(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); if (cpu_state.abrt) return 1; + x87_push(t.d); + CLOCK_CYCLES(3); + return 0; +} +#endif + +static int opFSTd_a16(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES(8); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTd_a32(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES(8); + return cpu_state.abrt; +} +#endif + +static int opFSTPd_a16(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(8); + return 0; +} +#ifndef FPU_8087 +static int opFSTPd_a32(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(8); + return 0; +} +#endif + +static int opFLDs_a16(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); if (cpu_state.abrt) return 1; + x87_push((double)ts.s); + CLOCK_CYCLES(3); + return 0; +} +#ifndef FPU_8087 +static int opFLDs_a32(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); if (cpu_state.abrt) return 1; + x87_push((double)ts.s); + CLOCK_CYCLES(3); + return 0; +} +#endif + +static int opFSTs_a16(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float)ST(0); + seteal(ts.i); + CLOCK_CYCLES(7); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTs_a32(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float)ST(0); + seteal(ts.i); + CLOCK_CYCLES(7); + return cpu_state.abrt; +} +#endif + +static int opFSTPs_a16(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float)ST(0); + seteal(ts.i); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(7); + return 0; +} +#ifndef FPU_8087 +static int opFSTPs_a32(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float)ST(0); + seteal(ts.i); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(7); + return 0; +} +#endif diff --git a/src/x87_bak/x87_ops_misc.h b/src/x87_bak/x87_ops_misc.h new file mode 100644 index 000000000..406c6c86d --- /dev/null +++ b/src/x87_bak/x87_ops_misc.h @@ -0,0 +1,877 @@ +#ifdef FPU_8087 +static int opFI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxc &= ~0x80; + if (rmdat == 0xe1) + cpu_state.npxc |= 0x80; + wait(3, 0); + return 0; +} +#else +static int opFSTSW_AX(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + AX = cpu_state.npxs; + CLOCK_CYCLES(3); + return 0; +} +#endif + + +static int opFNOP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + CLOCK_CYCLES(4); + return 0; +} + +static int opFCLEX(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= 0xff00; + CLOCK_CYCLES(4); + return 0; +} + +static int opFINIT(uint32_t fetchdat) +{ + uint64_t *p; + FP_ENTER(); + cpu_state.pc++; +#ifdef FPU_8087 + cpu_state.npxc = 0x3FF; +#else + cpu_state.npxc = 0x37F; +#endif + FP_RNPXC(); + cpu_state.npxs = 0; + p = (uint64_t *)cpu_state.tag; + *p = FP_DTAG; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + CLOCK_CYCLES(17); + CPU_BLOCK_END(); + return 0; +} + + +static int opFFREE(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY; + CLOCK_CYCLES(3); + return 0; +} + +static int opFFREEP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY; if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(3); + return 0; +} + +static int opFST(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; + CLOCK_CYCLES(3); + return 0; +} + +static int opFSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; + x87_pop(); + CLOCK_CYCLES(3); + return 0; +} + + + + +static int FSTOR() +{ + uint64_t *p; + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) + { + case 0x000: /*16-bit real mode*/ + case 0x001: /*16-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + FP_NNPXC(); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); + x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + cpu_state.eaaddr += 14; + break; + case 0x100: /*32-bit real mode*/ + case 0x101: /*32-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + FP_NNPXC(); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); + x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + cpu_state.eaaddr += 28; + break; + } + x87_ld_frstor(0); cpu_state.eaaddr += 10; + x87_ld_frstor(1); cpu_state.eaaddr += 10; + x87_ld_frstor(2); cpu_state.eaaddr += 10; + x87_ld_frstor(3); cpu_state.eaaddr += 10; + x87_ld_frstor(4); cpu_state.eaaddr += 10; + x87_ld_frstor(5); cpu_state.eaaddr += 10; + x87_ld_frstor(6); cpu_state.eaaddr += 10; + x87_ld_frstor(7); + + cpu_state.ismmx = 0; + /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times + something like this is needed*/ + p = (uint64_t *)cpu_state.tag; + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && + cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && + !cpu_state.TOP && (*p == FP_CTAG)) + cpu_state.ismmx = 1; + + CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + return cpu_state.abrt; +} +static int opFSTOR_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTOR_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; +} +#endif + +static int FSAVE() +{ + uint64_t *p; + + FP_ENTER(); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (FP_TOP(cpu_state.TOP) << 11); + + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) + { + case 0x000: /*16-bit real mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+10,x87_op_off); + cpu_state.eaaddr+=14; + if (cpu_state.ismmx) + { + x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[7]); + } + else + { + x87_st_fsave(0); cpu_state.eaaddr+=10; + x87_st_fsave(1); cpu_state.eaaddr+=10; + x87_st_fsave(2); cpu_state.eaaddr+=10; + x87_st_fsave(3); cpu_state.eaaddr+=10; + x87_st_fsave(4); cpu_state.eaaddr+=10; + x87_st_fsave(5); cpu_state.eaaddr+=10; + x87_st_fsave(6); cpu_state.eaaddr+=10; + x87_st_fsave(7); + } + break; + case 0x001: /*16-bit protected mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); + writememw(easeg,cpu_state.eaaddr+10,x87_op_off); + writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); + cpu_state.eaaddr+=14; + if (cpu_state.ismmx) + { + x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[7]); + } + else + { + x87_st_fsave(0); cpu_state.eaaddr+=10; + x87_st_fsave(1); cpu_state.eaaddr+=10; + x87_st_fsave(2); cpu_state.eaaddr+=10; + x87_st_fsave(3); cpu_state.eaaddr+=10; + x87_st_fsave(4); cpu_state.eaaddr+=10; + x87_st_fsave(5); cpu_state.eaaddr+=10; + x87_st_fsave(6); cpu_state.eaaddr+=10; + x87_st_fsave(7); + } + break; + case 0x100: /*32-bit real mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+20,x87_op_off); + writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); + cpu_state.eaaddr+=28; + if (cpu_state.ismmx) + { + x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[7]); + } + else + { + x87_st_fsave(0); cpu_state.eaaddr+=10; + x87_st_fsave(1); cpu_state.eaaddr+=10; + x87_st_fsave(2); cpu_state.eaaddr+=10; + x87_st_fsave(3); cpu_state.eaaddr+=10; + x87_st_fsave(4); cpu_state.eaaddr+=10; + x87_st_fsave(5); cpu_state.eaaddr+=10; + x87_st_fsave(6); cpu_state.eaaddr+=10; + x87_st_fsave(7); + } + break; + case 0x101: /*32-bit protected mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); + writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); + writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); + writememl(easeg,cpu_state.eaaddr+20,x87_op_off); + writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); + cpu_state.eaaddr+=28; + if (cpu_state.ismmx) + { + x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[7]); + } + else + { + x87_st_fsave(0); cpu_state.eaaddr+=10; + x87_st_fsave(1); cpu_state.eaaddr+=10; + x87_st_fsave(2); cpu_state.eaaddr+=10; + x87_st_fsave(3); cpu_state.eaaddr+=10; + x87_st_fsave(4); cpu_state.eaaddr+=10; + x87_st_fsave(5); cpu_state.eaaddr+=10; + x87_st_fsave(6); cpu_state.eaaddr+=10; + x87_st_fsave(7); + } + break; + } + + cpu_state.npxc = 0x37F; + FP_RNPXC(); + cpu_state.npxs = 0; + p = (uint64_t *)cpu_state.tag; + *p = FP_DTAG; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + return cpu_state.abrt; +} +static int opFSAVE_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSAVE_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; +} +#endif + +static int opFSTSW_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11)); + CLOCK_CYCLES(3); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTSW_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11)); + CLOCK_CYCLES(3); + return cpu_state.abrt; +} +#endif + + +static int opFLD(uint32_t fetchdat) +{ + int old_tag; + uint64_t old_i64; + + FP_ENTER(); + cpu_state.pc++; + old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + x87_push(ST(fetchdat&7)); + cpu_state.tag[FP_TOP(cpu_state.TOP)] = old_tag; + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = old_i64; + CLOCK_CYCLES(4); + return 0; +} + +static int opFXCH(uint32_t fetchdat) +{ + double td; + uint8_t old_tag; + uint64_t old_i64; + FP_ENTER(); + cpu_state.pc++; + td = ST(0); + ST(0) = ST(fetchdat&7); + ST(fetchdat&7) = td; + old_tag = cpu_state.tag[FP_TOP(cpu_state.TOP)]; + cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; + old_i64 = cpu_state.MM[FP_TOP(cpu_state.TOP)].q; + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; + + CLOCK_CYCLES(4); + return 0; +} + +static int opFCHS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = -ST(0); + FP_TAG(); + CLOCK_CYCLES(6); + return 0; +} + +static int opFABS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = fabs(ST(0)); + FP_TAG(); + CLOCK_CYCLES(3); + return 0; +} + +static int opFTST(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + if (ST(0) == 0.0) cpu_state.npxs |= C3; + else if (ST(0) < 0.0) cpu_state.npxs |= C0; + CLOCK_CYCLES(4); + return 0; +} + +static int opFXAM(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C1|C2|C3); + if (cpu_state.tag[cpu_state.TOP&7] == FP_EMPTY) cpu_state.npxs |= (C0|C3); + else if (ST(0) == 0.0) cpu_state.npxs |= C3; + else cpu_state.npxs |= C2; + if (ST(0) < 0.0) cpu_state.npxs |= C1; + CLOCK_CYCLES(8); + return 0; +} + +static int opFLD1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(1.0); + CLOCK_CYCLES(4); + return 0; +} + +static int opFLDL2T(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(3.3219280948873623); + CLOCK_CYCLES(8); + return 0; +} + +static int opFLDL2E(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(1.4426950408889634); + CLOCK_CYCLES(8); + return 0; +} + +static int opFLDPI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(3.141592653589793); + CLOCK_CYCLES(8); + return 0; +} + +static int opFLDEG2(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(0.3010299956639812); + CLOCK_CYCLES(8); + return 0; +} + +static int opFLDLN2(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push_u64(0x3fe62e42fefa39f0ull); + CLOCK_CYCLES(8); + return 0; +} + +static int opFLDZ(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(0.0); + FP_ZTAG(); + CLOCK_CYCLES(4); + return 0; +} + +static int opF2XM1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = pow(2.0, ST(0)) - 1.0; + FP_TAG(); + CLOCK_CYCLES(200); + return 0; +} + +static int opFYL2X(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = ST(1) * (log(ST(0)) / log(2.0)); + FP_NTAG(); + x87_pop(); + CLOCK_CYCLES(250); + return 0; +} + +static int opFYL2XP1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = ST(1) * (log(ST(0)+1.0) / log(2.0)); + FP_NTAG(); + x87_pop(); + CLOCK_CYCLES(250); + return 0; +} + +static int opFPTAN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = tan(ST(0)); + FP_TAG(); + x87_push(1.0); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(235); + return 0; +} + +static int opFPATAN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = atan2(ST(1), ST(0)); + FP_NTAG(); + x87_pop(); + CLOCK_CYCLES(250); + return 0; +} + +static int opFDECSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + FP_DECTOP(); + CLOCK_CYCLES(4); + return 0; +} + +static int opFINCSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + FP_INCTOP(); + CLOCK_CYCLES(4); + return 0; +} + +static int opFPREM(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t)(ST(0) / ST(1)); + ST(0) = ST(0) - (ST(1) * (double)temp64); + FP_TAG(); + cpu_state.npxs &= ~(C0|C1|C2|C3); + if (temp64 & 4) cpu_state.npxs|=C0; + if (temp64 & 2) cpu_state.npxs|=C3; + if (temp64 & 1) cpu_state.npxs|=C1; + CLOCK_CYCLES(100); + return 0; +} +#ifndef FPU_8087 +static int opFPREM1(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t)(ST(0) / ST(1)); + ST(0) = ST(0) - (ST(1) * (double)temp64); + FP_TAG(); + cpu_state.npxs &= ~(C0|C1|C2|C3); + if (temp64 & 4) cpu_state.npxs|=C0; + if (temp64 & 2) cpu_state.npxs|=C3; + if (temp64 & 1) cpu_state.npxs|=C1; + CLOCK_CYCLES(100); + return 0; +} +#endif + +static int opFSQRT(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = sqrt(ST(0)); + FP_TAG(); + CLOCK_CYCLES(83); + return 0; +} + +#ifndef FPU_8087 +static int opFSINCOS(uint32_t fetchdat) +{ + double td; + FP_ENTER(); + cpu_state.pc++; + td = ST(0); + ST(0) = sin(td); + FP_TAG(); + x87_push(cos(td)); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(330); + return 0; +} +#endif + +static int opFRNDINT(uint32_t fetchdat) +{ + double rounded; + FP_ENTER(); + cpu_state.pc++; + rounded = (double) x87_fround(ST(0)); +#ifndef PCEM_CODE + if (rounded > ST(0)) + cpu_state.npxs |= C1; + else + cpu_state.npxs &= ~C1; +#endif + ST(0) = rounded; + FP_TAG(); + CLOCK_CYCLES(21); + return 0; +} + +static int opFSCALE(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t)ST(1); + ST(0) = ST(0) * pow(2.0, (double)temp64); + FP_TAG(); + CLOCK_CYCLES(30); + return 0; +} + +#ifndef FPU_8087 +static int opFSIN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = sin(ST(0)); + FP_TAG(); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(300); + return 0; +} + +static int opFCOS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = cos(ST(0)); + FP_TAG(); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(300); + return 0; +} +#endif + + +static int FLDENV() +{ + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) + { + case 0x000: /*16-bit real mode*/ + case 0x001: /*16-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + FP_NNPXC(); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); + x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + break; + case 0x100: /*32-bit real mode*/ + case 0x101: /*32-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + FP_NNPXC(); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); + x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + break; + } + CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + return cpu_state.abrt; +} + +static int opFLDENV_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFLDENV_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; +} +#endif + +static int opFLDCW_a16(uint32_t fetchdat) +{ + uint16_t tempw; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) return 1; + cpu_state.npxc = tempw; + FP_NNPXC(); + CLOCK_CYCLES(4); + return 0; +} +#ifndef FPU_8087 +static int opFLDCW_a32(uint32_t fetchdat) +{ + uint16_t tempw; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) return 1; + cpu_state.npxc = tempw; + FP_NNPXC(); + CLOCK_CYCLES(4); + return 0; +} +#endif + +static int FSTENV() +{ + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) + { + case 0x000: /*16-bit real mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+10,x87_op_off); + break; + case 0x001: /*16-bit protected mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); + writememw(easeg,cpu_state.eaaddr+10,x87_op_off); + writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); + break; + case 0x100: /*32-bit real mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+20,x87_op_off); + writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); + break; + case 0x101: /*32-bit protected mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); + writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); + writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); + writememl(easeg,cpu_state.eaaddr+20,x87_op_off); + writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); + break; + } + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + return cpu_state.abrt; +} + +static int opFSTENV_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTENV_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; +} +#endif + +static int opFSTCW_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.npxc); + CLOCK_CYCLES(3); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTCW_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.npxc); + CLOCK_CYCLES(3); + return cpu_state.abrt; +} +#endif + +#ifndef FPU_8087 +#ifdef FP_686 +#define opFCMOV(condition) \ + static int opFCMOV ## condition(uint32_t fetchdat) \ + { \ + FP_ENTER(); \ + cpu_state.pc++; \ + if (cond_ ## condition) \ + { \ + cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ + ST(0) = ST(fetchdat & 7); \ + } \ + CLOCK_CYCLES(4); \ + return 0; \ + } + +#define cond_U ( PF_SET()) +#define cond_NU (!PF_SET()) + +opFCMOV(B) +opFCMOV(E) +opFCMOV(BE) +opFCMOV(U) +opFCMOV(NB) +opFCMOV(NE) +opFCMOV(NBE) +opFCMOV(NU) +#endif +#endif diff --git a/src/x87_ops.txt b/src/x87_ops.txt new file mode 100644 index 000000000..28a50cda5 --- /dev/null +++ b/src/x87_ops.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x87_ops.h and CPU_NEW\X87_OPS.H +FC: no differences encountered + diff --git a/src/x87_ops_arith.txt b/src/x87_ops_arith.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/x87_ops_loadstore.txt b/src/x87_ops_loadstore.txt new file mode 100644 index 000000000..ce4583037 --- /dev/null +++ b/src/x87_ops_loadstore.txt @@ -0,0 +1,241 @@ +Comparing files CPU\x87_ops_loadstore.h and CPU_NEW\X87_OPS_LOADSTORE.H +***** CPU\x87_ops_loadstore.h +/* + * 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. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops_loadstore.h 1.0.2 2019/06/11 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + */ + +static int opFILDiw_a16(uint32_t fetchdat) +{ +***** CPU_NEW\X87_OPS_LOADSTORE.H +static int opFILDiw_a16(uint32_t fetchdat) +{ +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 32767 || temp64 < -32768) + fatal("FISTw overflow %i\n", temp64);*/ + seteaw((int16_t)temp64); +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 32767 || temp64 < -32768) + fatal("FISTw overflow %i\n", temp64);*/ + seteaw((int16_t)temp64); +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 32767 || temp64 < -32768) + fatal("FISTw overflow %i\n", temp64);*/ + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 32767 || temp64 < -32768) + fatal("FISTw overflow %i\n", temp64);*/ + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + x87_push((double)temp64); + cpu_state.MM[cpu_state.TOP].q = temp64; + FP_LSTAG(); +***** CPU_NEW\X87_OPS_LOADSTORE.H + x87_push((double)temp64); + cpu_state.MM[cpu_state.TOP&7].q = temp64; + FP_LSTAG(); +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + x87_push((double)temp64); + cpu_state.MM[cpu_state.TOP].q = temp64; + FP_LSTAG(); +***** CPU_NEW\X87_OPS_LOADSTORE.H + x87_push((double)temp64); + cpu_state.MM[cpu_state.TOP&7].q = temp64; + FP_LSTAG(); +***** + +***** CPU\x87_ops_loadstore.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP].q; + else +***** CPU_NEW\X87_OPS_LOADSTORE.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP&7].q; + else +***** + +***** CPU\x87_ops_loadstore.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP].q; + else +***** CPU_NEW\X87_OPS_LOADSTORE.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP&7].q; + else +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 2147483647 || temp64 < -2147483647) + fatal("FISTl out of range! %i\n", temp64);*/ + seteal((int32_t)temp64); +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 2147483647 || temp64 < -2147483647) + fatal("FISTl out of range! %i\n", temp64);*/ + seteal((int32_t)temp64); +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 2147483647 || temp64 < -2147483647) + fatal("FISTl out of range! %i\n", temp64);*/ + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 2147483647 || temp64 < -2147483647) + fatal("FISTl out of range! %i\n", temp64);*/ + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t=x87_ld80(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t=x87_ld80(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); if (cpu_state.abrt) return 1; +***** + diff --git a/src/x87_ops_misc.txt b/src/x87_ops_misc.txt new file mode 100644 index 000000000..985e71950 --- /dev/null +++ b/src/x87_ops_misc.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x87_ops_misc.h and CPU_NEW\X87_OPS_MISC.H +FC: no differences encountered +