2022-02-20 02:26:27 -05:00
|
|
|
/*
|
2022-11-13 16:37:58 -05:00
|
|
|
* 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.
|
2021-04-10 07:22:49 +02:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* This file is part of the 86Box distribution.
|
2021-04-10 07:22:49 +02:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* Functions common to all emulated x86 CPU's.
|
2021-04-10 07:22:49 +02:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* Authors: Andrew Jenner, <https://www.reenigne.org>
|
|
|
|
|
* Miran Grca, <mgrca8@gmail.com>
|
2021-04-10 07:22:49 +02:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* Copyright 2015-2020 Andrew Jenner.
|
|
|
|
|
* Copyright 2016-2020 Miran Grca.
|
2021-04-10 07:22:49 +02:00
|
|
|
*/
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <wchar.h>
|
|
|
|
|
|
|
|
|
|
#define HAVE_STDARG_H
|
|
|
|
|
#include <86box/86box.h>
|
|
|
|
|
#include "cpu.h"
|
|
|
|
|
#include "x86.h"
|
2023-08-21 02:56:33 +02:00
|
|
|
#include "x86seg_common.h"
|
|
|
|
|
#include "x86seg.h"
|
2021-04-10 07:22:49 +02:00
|
|
|
#include <86box/machine.h>
|
2021-09-17 02:55:43 +02:00
|
|
|
#include <86box/device.h>
|
|
|
|
|
#include <86box/dma.h>
|
2021-04-10 07:22:49 +02:00
|
|
|
#include <86box/io.h>
|
2023-04-09 19:44:15 +02:00
|
|
|
#include <86box/keyboard.h>
|
2021-04-10 07:22:49 +02:00
|
|
|
#include <86box/mem.h>
|
|
|
|
|
#include <86box/rom.h>
|
|
|
|
|
#include <86box/nmi.h>
|
|
|
|
|
#include <86box/pic.h>
|
2021-06-07 00:06:17 +02:00
|
|
|
#include <86box/pci.h>
|
2021-04-10 07:22:49 +02:00
|
|
|
#include <86box/ppi.h>
|
|
|
|
|
#include <86box/timer.h>
|
2022-05-19 20:07:06 +02:00
|
|
|
#include <86box/video.h>
|
|
|
|
|
#include <86box/vid_svga.h>
|
2021-04-10 07:22:49 +02:00
|
|
|
|
|
|
|
|
/* The opcode of the instruction currently being executed. */
|
|
|
|
|
uint8_t opcode;
|
|
|
|
|
|
|
|
|
|
/* The tables to speed up the setting of the Z, N, and P cpu_state.flags. */
|
2022-11-19 10:40:32 -05:00
|
|
|
uint8_t znptable8[256];
|
2021-04-10 07:22:49 +02:00
|
|
|
uint16_t znptable16[65536];
|
|
|
|
|
|
|
|
|
|
/* A 16-bit zero, needed because some speed-up arrays contain pointers to it. */
|
|
|
|
|
uint16_t zero = 0;
|
|
|
|
|
|
|
|
|
|
/* MOD and R/M stuff. */
|
|
|
|
|
uint16_t *mod1add[2][8];
|
|
|
|
|
uint32_t *mod1seg[8];
|
2022-11-19 10:40:32 -05:00
|
|
|
uint32_t rmdat;
|
2021-04-10 07:22:49 +02:00
|
|
|
|
|
|
|
|
/* XT CPU multiplier. */
|
|
|
|
|
uint64_t xt_cpu_multi;
|
|
|
|
|
|
|
|
|
|
/* Variables for handling the non-maskable interrupts. */
|
2023-08-11 13:00:04 -04:00
|
|
|
int nmi = 0;
|
2023-08-10 15:43:16 -04:00
|
|
|
int nmi_auto_clear = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
|
|
|
|
|
/* Was the CPU ever reset? */
|
2023-08-11 13:00:04 -04:00
|
|
|
int x86_was_reset = 0;
|
2023-08-10 15:43:16 -04:00
|
|
|
int soft_reset_pci = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
|
|
|
|
|
/* Is the TRAP flag on? */
|
|
|
|
|
int trap = 0;
|
|
|
|
|
|
|
|
|
|
/* The current effective address's segment. */
|
|
|
|
|
uint32_t easeg;
|
|
|
|
|
|
2021-06-07 00:06:17 +02:00
|
|
|
/* This is for the OPTI 283 special reset handling mode. */
|
2023-08-10 15:43:16 -04:00
|
|
|
int reset_on_hlt;
|
|
|
|
|
int hlt_reset_pending;
|
2021-06-07 00:06:17 +02:00
|
|
|
|
2023-08-25 02:28:51 +02:00
|
|
|
int fpu_cycles = 0;
|
|
|
|
|
|
2024-02-23 07:10:15 +01:00
|
|
|
int in_lock = 0;
|
|
|
|
|
|
2021-04-10 07:22:49 +02:00
|
|
|
#ifdef ENABLE_X86_LOG
|
2024-08-07 00:14:53 -04:00
|
|
|
#if 0
|
2022-11-19 10:40:32 -05:00
|
|
|
void dumpregs(int);
|
2024-08-07 00:14:53 -04:00
|
|
|
#endif
|
2021-04-10 07:22:49 +02:00
|
|
|
|
|
|
|
|
int x86_do_log = ENABLE_X86_LOG;
|
2022-11-19 10:40:32 -05:00
|
|
|
int indump = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
|
|
|
|
|
static void
|
2023-08-25 03:49:06 +02:00
|
|
|
x86_log(const char *fmt, ...)
|
2021-04-10 07:22:49 +02:00
|
|
|
{
|
|
|
|
|
va_list ap;
|
|
|
|
|
|
2024-08-07 00:14:53 -04:00
|
|
|
if (x86_do_log) {
|
2022-11-19 10:40:32 -05:00
|
|
|
va_start(ap, fmt);
|
|
|
|
|
pclog_ex(fmt, ap);
|
|
|
|
|
va_end(ap);
|
2021-04-10 07:22:49 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-07 00:14:53 -04:00
|
|
|
#if 0
|
2021-04-10 07:22:49 +02:00
|
|
|
void
|
|
|
|
|
dumpregs(int force)
|
|
|
|
|
{
|
2022-11-19 10:40:32 -05:00
|
|
|
int c;
|
2021-04-10 07:22:49 +02:00
|
|
|
char *seg_names[4] = { "ES", "CS", "SS", "DS" };
|
|
|
|
|
|
|
|
|
|
/* Only dump when needed, and only once.. */
|
|
|
|
|
if (indump || (!force && !dump_on_exit))
|
2022-11-19 10:40:32 -05:00
|
|
|
return;
|
2021-04-10 07:22:49 +02:00
|
|
|
|
2023-08-25 03:49:06 +02:00
|
|
|
x86_log("EIP=%08X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",
|
|
|
|
|
cpu_state.pc, CS, DS, ES, SS, cpu_state.flags);
|
|
|
|
|
x85_log("Old CS:EIP: %04X:%08X; %i ins\n", oldcs, cpu_state.oldpc, ins);
|
2021-04-10 07:22:49 +02:00
|
|
|
for (c = 0; c < 4; c++) {
|
2023-08-25 03:49:06 +02:00
|
|
|
x86_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",
|
|
|
|
|
seg_names[c], _opseg[c]->base, _opseg[c]->limit,
|
|
|
|
|
_opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high);
|
2021-04-10 07:22:49 +02:00
|
|
|
}
|
|
|
|
|
if (is386) {
|
2023-08-25 03:49:06 +02:00
|
|
|
x86_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",
|
|
|
|
|
seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low,
|
|
|
|
|
cpu_state.seg_fs.limit_high);
|
|
|
|
|
x86_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",
|
|
|
|
|
gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low,
|
|
|
|
|
cpu_state.seg_gs.limit_high);
|
|
|
|
|
x86_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit);
|
|
|
|
|
x86_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit);
|
|
|
|
|
x86_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit);
|
|
|
|
|
x86_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit);
|
|
|
|
|
x86_log("386 in %s mode: %i-bit data, %-i-bit stack\n",
|
|
|
|
|
(msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real",
|
|
|
|
|
(use32) ? 32 : 16, (stack32) ? 32 : 16);
|
|
|
|
|
x86_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4);
|
|
|
|
|
x86_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",
|
|
|
|
|
EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP);
|
2021-04-10 07:22:49 +02:00
|
|
|
} else {
|
2023-08-25 03:49:06 +02:00
|
|
|
x86_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real");
|
|
|
|
|
x86_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",
|
|
|
|
|
AX, BX, CX, DX, DI, SI, BP, SP);
|
2021-04-10 07:22:49 +02:00
|
|
|
}
|
2023-08-25 03:49:06 +02:00
|
|
|
x86_log("Entries in readlookup : %i writelookup : %i\n", readlnum, writelnum);
|
2021-04-10 07:22:49 +02:00
|
|
|
x87_dumpregs();
|
|
|
|
|
indump = 0;
|
|
|
|
|
}
|
2024-08-07 00:14:53 -04:00
|
|
|
#endif
|
2021-04-10 07:22:49 +02:00
|
|
|
#else
|
2023-08-25 03:49:06 +02:00
|
|
|
# define x86_log(fmt, ...)
|
2021-04-10 07:22:49 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Preparation of the various arrays needed to speed up the MOD and R/M work. */
|
|
|
|
|
static void
|
|
|
|
|
makemod1table(void)
|
|
|
|
|
{
|
|
|
|
|
mod1add[0][0] = &BX;
|
|
|
|
|
mod1add[0][1] = &BX;
|
|
|
|
|
mod1add[0][2] = &BP;
|
|
|
|
|
mod1add[0][3] = &BP;
|
|
|
|
|
mod1add[0][4] = &SI;
|
|
|
|
|
mod1add[0][5] = &DI;
|
|
|
|
|
mod1add[0][6] = &BP;
|
|
|
|
|
mod1add[0][7] = &BX;
|
|
|
|
|
mod1add[1][0] = &SI;
|
|
|
|
|
mod1add[1][1] = &DI;
|
|
|
|
|
mod1add[1][2] = &SI;
|
|
|
|
|
mod1add[1][3] = &DI;
|
|
|
|
|
mod1add[1][4] = &zero;
|
|
|
|
|
mod1add[1][5] = &zero;
|
|
|
|
|
mod1add[1][6] = &zero;
|
|
|
|
|
mod1add[1][7] = &zero;
|
2022-11-19 10:40:32 -05:00
|
|
|
mod1seg[0] = &ds;
|
|
|
|
|
mod1seg[1] = &ds;
|
|
|
|
|
mod1seg[2] = &ss;
|
|
|
|
|
mod1seg[3] = &ss;
|
|
|
|
|
mod1seg[4] = &ds;
|
|
|
|
|
mod1seg[5] = &ds;
|
|
|
|
|
mod1seg[6] = &ss;
|
|
|
|
|
mod1seg[7] = &ds;
|
2021-04-10 07:22:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Prepare the ZNP table needed to speed up the setting of the Z, N, and P cpu_state.flags. */
|
|
|
|
|
static void
|
|
|
|
|
makeznptable(void)
|
|
|
|
|
{
|
2023-08-10 15:43:16 -04:00
|
|
|
int c;
|
|
|
|
|
int d;
|
|
|
|
|
int e;
|
|
|
|
|
|
2021-04-10 07:22:49 +02:00
|
|
|
for (c = 0; c < 256; c++) {
|
2022-11-19 10:40:32 -05:00
|
|
|
d = 0;
|
|
|
|
|
for (e = 0; e < 8; e++) {
|
|
|
|
|
if (c & (1 << e))
|
|
|
|
|
d++;
|
|
|
|
|
}
|
|
|
|
|
if (d & 1)
|
|
|
|
|
znptable8[c] = 0;
|
|
|
|
|
else
|
|
|
|
|
znptable8[c] = P_FLAG;
|
2023-08-25 03:49:06 +02:00
|
|
|
#ifdef ENABLE_X86_LOG
|
2022-11-19 10:40:32 -05:00
|
|
|
if (c == 0xb1)
|
2023-08-25 03:49:06 +02:00
|
|
|
x86_log("znp8 b1 = %i %02X\n", d, znptable8[c]);
|
2021-04-10 07:22:49 +02:00
|
|
|
#endif
|
2022-11-19 10:40:32 -05:00
|
|
|
if (!c)
|
|
|
|
|
znptable8[c] |= Z_FLAG;
|
|
|
|
|
if (c & 0x80)
|
|
|
|
|
znptable8[c] |= N_FLAG;
|
2021-04-10 07:22:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (c = 0; c < 65536; c++) {
|
2022-11-19 10:40:32 -05:00
|
|
|
d = 0;
|
|
|
|
|
for (e = 0; e < 8; e++) {
|
|
|
|
|
if (c & (1 << e))
|
|
|
|
|
d++;
|
|
|
|
|
}
|
|
|
|
|
if (d & 1)
|
|
|
|
|
znptable16[c] = 0;
|
|
|
|
|
else
|
|
|
|
|
znptable16[c] = P_FLAG;
|
2023-08-25 03:49:06 +02:00
|
|
|
#ifdef ENABLE_X86_LOG
|
2022-11-19 10:40:32 -05:00
|
|
|
if (c == 0xb1)
|
2023-08-25 03:49:06 +02:00
|
|
|
x86_log("znp16 b1 = %i %02X\n", d, znptable16[c]);
|
2022-11-19 10:40:32 -05:00
|
|
|
if (c == 0x65b1)
|
2023-08-25 03:49:06 +02:00
|
|
|
x86_log("znp16 65b1 = %i %02X\n", d, znptable16[c]);
|
2021-04-10 07:22:49 +02:00
|
|
|
#endif
|
2022-11-19 10:40:32 -05:00
|
|
|
if (!c)
|
|
|
|
|
znptable16[c] |= Z_FLAG;
|
|
|
|
|
if (c & 0x8000)
|
|
|
|
|
znptable16[c] |= N_FLAG;
|
2021-04-10 07:22:49 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Common reset function. */
|
|
|
|
|
static void
|
|
|
|
|
reset_common(int hard)
|
|
|
|
|
{
|
2023-08-25 03:49:06 +02:00
|
|
|
#ifdef ENABLE_X86_LOG
|
2021-04-10 07:22:49 +02:00
|
|
|
if (hard)
|
2023-08-25 03:49:06 +02:00
|
|
|
x86_log("x86 reset\n");
|
2021-04-10 07:22:49 +02:00
|
|
|
#endif
|
|
|
|
|
|
2021-06-07 00:06:17 +02:00
|
|
|
if (!hard && reset_on_hlt) {
|
2022-11-19 10:40:32 -05:00
|
|
|
hlt_reset_pending++;
|
|
|
|
|
if (hlt_reset_pending == 2)
|
|
|
|
|
hlt_reset_pending = 0;
|
|
|
|
|
else
|
|
|
|
|
return;
|
2021-06-07 00:06:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make sure to gracefully leave SMM. */
|
|
|
|
|
if (in_smm)
|
2022-11-19 10:40:32 -05:00
|
|
|
leave_smm();
|
2021-06-07 00:06:17 +02:00
|
|
|
|
|
|
|
|
/* Needed for the ALi M1533. */
|
2021-09-25 15:30:06 +02:00
|
|
|
if (is486 && (hard || soft_reset_pci)) {
|
2022-11-19 10:40:32 -05:00
|
|
|
pci_reset();
|
|
|
|
|
if (!hard && soft_reset_pci) {
|
|
|
|
|
dma_reset();
|
|
|
|
|
/* TODO: Hack, but will do for time being, because all AT machines currently are 286+,
|
|
|
|
|
and vice-versa. */
|
|
|
|
|
dma_set_at(is286);
|
2023-04-19 23:34:32 +02:00
|
|
|
device_reset_all(DEVICE_ALL);
|
2022-11-19 10:40:32 -05:00
|
|
|
}
|
2021-09-25 15:30:06 +02:00
|
|
|
}
|
2021-06-07 00:06:17 +02:00
|
|
|
|
2022-11-19 10:40:32 -05:00
|
|
|
use32 = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
cpu_cur_status = 0;
|
2022-11-19 10:40:32 -05:00
|
|
|
stack32 = 0;
|
|
|
|
|
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
|
|
|
|
msw = 0;
|
2025-01-19 09:06:39 +01:00
|
|
|
new_ne = 0;
|
2025-04-26 23:17:32 +06:00
|
|
|
x87_op = 0;
|
Implement Cyrix EMMI extensions and 4 FPU instructions
PADDSIW, PSUBSIW, PMULHRW (named PMULHRWC in the code as recognized by some assemblers), PMULHRIW, PDISTIB, PMACHRIW, PAVEB, PMAGW, PMVZB, PMVNZB, PMVLZB, PMVGEZB, FTSTP, FRINT2, FRINEAR, FRICHOP are implemented for Cyrix 6x86MX. Cyrix 6x86(L) only has the last 4 instructions.
2025-03-06 00:54:28 +06:00
|
|
|
|
|
|
|
|
ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = ccr7 = 0;
|
|
|
|
|
ccr4 = 0x85;
|
2025-03-06 02:09:23 +06:00
|
|
|
cyrix.arr[3].base = 0x30000;
|
|
|
|
|
cyrix.arr[3].size = 65536;
|
Implement Cyrix EMMI extensions and 4 FPU instructions
PADDSIW, PSUBSIW, PMULHRW (named PMULHRWC in the code as recognized by some assemblers), PMULHRIW, PDISTIB, PMACHRIW, PAVEB, PMAGW, PMVZB, PMVNZB, PMVLZB, PMVGEZB, FTSTP, FRINT2, FRINEAR, FRICHOP are implemented for Cyrix 6x86MX. Cyrix 6x86(L) only has the last 4 instructions.
2025-03-06 00:54:28 +06:00
|
|
|
|
2021-04-10 07:22:49 +02:00
|
|
|
if (hascache)
|
2022-11-19 10:40:32 -05:00
|
|
|
cr0 = 1 << 30;
|
2021-04-10 07:22:49 +02:00
|
|
|
else
|
2022-11-19 10:40:32 -05:00
|
|
|
cr0 = 0;
|
2024-02-09 18:02:33 +01:00
|
|
|
if (is386 && !is486 && (fpu_type == FPU_387))
|
|
|
|
|
cr0 |= 0x10;
|
2024-08-27 02:34:59 +02:00
|
|
|
cpu_cache_int_enabled = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
cpu_update_waitstates();
|
2022-11-19 10:40:32 -05:00
|
|
|
cr4 = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
cpu_state.eflags = 0;
|
2022-11-19 10:40:32 -05:00
|
|
|
cgate32 = 0;
|
2024-01-15 06:22:38 +05:00
|
|
|
#ifdef USE_DEBUG_REGS_486
|
|
|
|
|
if (is386) {
|
|
|
|
|
#else
|
2024-02-09 12:14:35 +01:00
|
|
|
if (is386 && !is486) {
|
2024-01-15 06:22:38 +05:00
|
|
|
#endif
|
2024-02-09 12:14:35 +01:00
|
|
|
for (uint8_t i = 0; i < 4; i++)
|
|
|
|
|
dr[i] = 0x00000000;
|
|
|
|
|
dr[6] = 0xffff1ff0;
|
|
|
|
|
dr[7] = 0x00000400;
|
|
|
|
|
}
|
2021-04-10 07:22:49 +02:00
|
|
|
if (is286) {
|
2023-08-21 02:56:33 +02:00
|
|
|
if (is486)
|
|
|
|
|
loadcs(0xF000);
|
|
|
|
|
else
|
|
|
|
|
loadcs_2386(0xF000);
|
2022-11-19 10:40:32 -05:00
|
|
|
cpu_state.pc = 0xFFF0;
|
2023-04-09 19:44:15 +02:00
|
|
|
if (hard) {
|
2023-08-11 13:00:04 -04:00
|
|
|
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
|
2023-04-09 19:44:15 +02:00
|
|
|
if (is6117)
|
|
|
|
|
rammask |= 0x03000000;
|
|
|
|
|
mem_a20_key = mem_a20_alt = mem_a20_state = 0;
|
|
|
|
|
}
|
2021-04-10 07:22:49 +02:00
|
|
|
}
|
2022-11-19 10:40:32 -05:00
|
|
|
idt.base = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
cpu_state.flags = 2;
|
2022-11-19 10:40:32 -05:00
|
|
|
trap = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
|
2021-04-27 04:10:59 +02:00
|
|
|
idt.limit = is386 ? 0x03ff : 0xffff;
|
|
|
|
|
if (is386 || hard)
|
2022-11-19 10:40:32 -05:00
|
|
|
EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
|
2021-10-09 17:37:09 +02:00
|
|
|
if (hard) {
|
2022-11-19 10:40:32 -05:00
|
|
|
makeznptable();
|
|
|
|
|
resetreadlookup();
|
|
|
|
|
makemod1table();
|
|
|
|
|
cpu_set_edx();
|
2021-10-09 17:37:09 +02:00
|
|
|
}
|
2021-04-10 07:22:49 +02:00
|
|
|
x86seg_reset();
|
|
|
|
|
#ifdef USE_DYNAREC
|
|
|
|
|
if (hard)
|
2022-11-19 10:40:32 -05:00
|
|
|
codegen_reset();
|
2021-04-10 07:22:49 +02:00
|
|
|
#endif
|
2024-08-27 02:34:59 +02:00
|
|
|
cpu_flush_pending = 0;
|
2024-08-29 01:57:22 +02:00
|
|
|
cpu_old_paging = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
if (!hard)
|
2022-11-19 10:40:32 -05:00
|
|
|
flushmmucache();
|
2021-04-10 07:22:49 +02:00
|
|
|
x86_was_reset = 1;
|
|
|
|
|
cpu_alt_reset = 0;
|
|
|
|
|
|
|
|
|
|
cpu_ven_reset();
|
|
|
|
|
|
|
|
|
|
in_smm = smi_latched = 0;
|
|
|
|
|
smi_line = smm_in_hlt = 0;
|
2022-11-19 10:40:32 -05:00
|
|
|
smi_block = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
|
|
|
|
|
if (hard) {
|
2022-11-19 10:40:32 -05:00
|
|
|
if (is486)
|
|
|
|
|
smbase = is_am486dxl ? 0x00060000 : 0x00030000;
|
|
|
|
|
ppi_reset();
|
2021-04-10 07:22:49 +02:00
|
|
|
}
|
|
|
|
|
in_sys = 0;
|
|
|
|
|
|
|
|
|
|
shadowbios = shadowbios_write = 0;
|
|
|
|
|
alt_access = cpu_end_block_after_ins = 0;
|
|
|
|
|
|
2021-10-09 17:37:09 +02:00
|
|
|
if (hard) {
|
2022-11-19 10:40:32 -05:00
|
|
|
reset_on_hlt = hlt_reset_pending = 0;
|
|
|
|
|
cache_index = 0;
|
|
|
|
|
memset(_tr, 0x00, sizeof(_tr));
|
|
|
|
|
memset(_cache, 0x00, sizeof(_cache));
|
2023-04-09 19:44:15 +02:00
|
|
|
|
|
|
|
|
/* If we have an AT or PS/2 keyboard controller, make sure the A20 state
|
|
|
|
|
is correct. */
|
2023-04-19 23:34:32 +02:00
|
|
|
device_reset_all(DEVICE_KBC);
|
2024-07-22 18:26:10 +02:00
|
|
|
} else
|
|
|
|
|
device_reset_all(DEVICE_SOFTRESET);
|
2021-06-07 00:06:17 +02:00
|
|
|
|
2021-04-10 07:22:49 +02:00
|
|
|
if (!is286)
|
2022-11-19 10:40:32 -05:00
|
|
|
reset_808x(hard);
|
2024-01-06 01:51:20 +01:00
|
|
|
|
2024-02-23 07:10:15 +01:00
|
|
|
in_lock = 0;
|
|
|
|
|
|
2024-01-06 01:51:20 +01:00
|
|
|
cpu_cpurst_on_sr = 0;
|
2021-04-10 07:22:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Hard reset. */
|
|
|
|
|
void
|
|
|
|
|
resetx86(void)
|
|
|
|
|
{
|
|
|
|
|
reset_common(1);
|
|
|
|
|
|
|
|
|
|
soft_reset_mask = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Soft reset. */
|
|
|
|
|
void
|
|
|
|
|
softresetx86(void)
|
|
|
|
|
{
|
|
|
|
|
if (soft_reset_mask)
|
2022-11-19 10:40:32 -05:00
|
|
|
return;
|
2021-04-10 07:22:49 +02:00
|
|
|
|
|
|
|
|
reset_common(0);
|
|
|
|
|
}
|
2021-09-17 02:55:43 +02:00
|
|
|
|
|
|
|
|
/* Actual hard reset. */
|
|
|
|
|
void
|
|
|
|
|
hardresetx86(void)
|
|
|
|
|
{
|
|
|
|
|
dma_reset();
|
2021-12-19 20:00:27 +01:00
|
|
|
/* TODO: Hack, but will do for time being, because all AT machines currently are 286+,
|
|
|
|
|
and vice-versa. */
|
|
|
|
|
dma_set_at(is286);
|
2023-04-19 23:34:32 +02:00
|
|
|
device_reset_all(DEVICE_ALL);
|
2021-09-17 02:55:43 +02:00
|
|
|
|
|
|
|
|
cpu_alt_reset = 0;
|
|
|
|
|
|
|
|
|
|
mem_a20_alt = 0;
|
|
|
|
|
mem_a20_recalc();
|
|
|
|
|
|
|
|
|
|
flushmmucache();
|
|
|
|
|
|
|
|
|
|
resetx86();
|
|
|
|
|
}
|