i386_state *cpustate = (i386_state *)opaque;
logerror(_T("I386::reset()"));
cpu_reset_generic(cpustate);
+ write_signals(&outputs_extreset, 0xffffffff);
}
int I386::run(int cycles)
cpustate->busreq = (data & mask) ? 1 : 0;
} else if(id == SIG_I386_A20) {
i386_set_a20_line(cpustate, data & mask);
+ } else if(id == SIG_I386_FORCE_RESET) {
+ write_signals(&outputs_extreset, ((data & mask == 0) ? 0x00000000 : 0xffffffff));
}
}
#include "../emu.h"
#include "device.h"
-#define SIG_I386_A20 1
-
+#define SIG_I386_A20 1
+#define SIG_I386_FORCE_RESET 2
//#ifdef USE_DEBUGGER
class DEBUGGER;
//#endif
DEBUGGER *d_debugger;
//#endif
void *opaque;
-
+ outputs_t outputs_extreset;
public:
I386(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
{
//#elif defined(HAS_PENTIUM4)
// set_device_name(_T("Pentium4 CPU"));
//#endif
+ initialize_output_signals(&outputs_extreset);
set_device_name(_T("Intel i80x86 CPU"));
}
~I386() {}
bool process_state(FILEIO* state_fio, bool loading);
// unique function
+ void set_context_extreset(DEVICE* device, int id, uint32_t mask)
+ {
+ register_output_signal(&outputs_extreset, device, id, mask);
+ }
void set_context_mem(DEVICE* device)
{
d_mem = device;
static void zero_state(i386_state *cpustate);
static void pentium_smi(i386_state* cpustate);
-#define FAULT(fault,error) {logerror("FAULT(%s , %s) PC=%08x V8086=%s PROTECTED=%s\n", #fault, #error, cpustate->pc, (cpustate->VM) ? "YES" : "NO", (PROTECTED_MODE) ? "YES" : "NO"); cpustate->ext = 1; i386_trap_with_error(cpustate,fault,0,0,error, 0); return;}
+#define FAULT(fault,error) {logerror("FAULT(%s , %s) PC=%08x V8086=%s PROTECTED=%s SP=%08X:%08X\n", #fault, #error, cpustate->pc, (cpustate->VM) ? "YES" : "NO", (PROTECTED_MODE) ? "YES" : "NO", (PROTECTED_MODE) ? cpustate->sreg[SS].base : (cpustate->sreg[SS].selector << 4), REG32(ESP)); cpustate->ext = 1; i386_trap_with_error(cpustate,fault,0,0,error, 0); return;}
#define FAULT_EXP(fault,error) {logerror("FAULT_EXP(%s , %s) PC=%08x V8086=%s PROTECTED=%s\n", #fault, #error, cpustate->pc, (cpustate->VM) ? "YES" : "NO", (PROTECTED_MODE) ? "YES" : "NO"); cpustate->ext = 1; i386_trap_with_error(cpustate,fault,0,trap_level+1,error, 0); return;}
static void cpu_reset_generic(i386_state* cpustate)
stack.selector = selector;
i386_load_protected_mode_segment(cpustate,&stack,NULL);
DPL = (stack.flags >> 5) & 0x03;
- logdebug("SReg load: SELECTOR=%04X FLAGS=%04X BASE=%08X LIMIT=%08X VALID=%s %s\n", stack.selector, stack.flags, stack.base, stack.limit, (stack.valid) ? "YES" : "NO", (stack.d == 0) ? "16bit SP" : "32bit ESP");
+ //logdebug("SReg load: SELECTOR=%04X FLAGS=%04X BASE=%08X LIMIT=%08X VALID=%s %s\n", stack.selector, stack.flags, stack.base, stack.limit, (stack.valid) ? "YES" : "NO", (stack.d == 0) ? "16bit SP" : "32bit ESP");
if((selector & ~0x0003) == 0)
{
logerror("SReg Load (%08x): Selector is null.\n",cpustate->pc);
//CPU_RESET_CALL(CPU_MODEL);
cpu_reset_generic(cpustate);
cpustate->shutdown = 1;
+ cpustate->parent_device->write_signal(SIG_I386_FORCE_RESET, 0xfffffff, 0xffffffff);
return;
}
CPL = cpustate->CPL; // current privilege level
DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level
RPL = selector & 0x03; // requested privilege level
- logerror("CALL: protected mode PC=%08X SEG=%04x OFFSET=%08x VALID=%s BASE=%08x LIMIT=%08x FLAGS=%08x INDIRECT=%s OP32=%s V8086=%s CPL=%d DPL=%d RPL=%d\n", cpustate->prev_pc, seg, off, (desc.valid) ? "YES" : "NO", desc.base, desc.limit, desc.flags, (indirect != 0) ? "YES" : "NO", (operand32 != 0) ? "YES" : "NO" ,(V8086_MODE) ? "YES" : "NO", CPL, DPL, RPL);
+ //logerror("CALL: protected mode PC=%08X SEG=%04x OFFSET=%08x VALID=%s BASE=%08x LIMIT=%08x FLAGS=%08x INDIRECT=%s OP32=%s V8086=%s CPL=%d DPL=%d RPL=%d\n", cpustate->prev_pc, seg, off, (desc.valid) ? "YES" : "NO", desc.base, desc.limit, desc.flags, (indirect != 0) ? "YES" : "NO", (operand32 != 0) ? "YES" : "NO" ,(V8086_MODE) ? "YES" : "NO", CPL, DPL, RPL);
if((desc.flags & 0x0018) == 0x18) // is a code segment
{
if(desc.flags & 0x0004)
logerror("RETF: SS segment is not present.\n");
FAULT(FAULT_GP,newSS & ~0x03)
}
- if(cpustate->CPL != (newCS & 0x03)) logerror("RETF: Change CPL from %d to %d CS=%04X PC=%08X\n", cpustate->CPL, newCS & 0x03, newCS, cpustate->pc);
+ //if(cpustate->CPL != (newCS & 0x03)) logerror("RETF: Change CPL from %d to %d CS=%04X PC=%08X\n", cpustate->CPL, newCS & 0x03, newCS, cpustate->pc);
cpustate->CPL = newCS & 0x03;
/* Load new SS:(E)SP */
REG32(ESP) = newESP;
cpustate->sreg[SS].selector = newSS & 0xffff;
}
- if(cpustate->CPL != (newCS & 0x03)) logerror("IRET: Change CPL from %d to %d PC=%08X\n", cpustate->CPL, newCS & 0x03, cpustate->pc);
+ //if(cpustate->CPL != (newCS & 0x03)) logerror("IRET: Change CPL from %d to %d PC=%08X\n", cpustate->CPL, newCS & 0x03, cpustate->pc);
cpustate->CPL = newCS & 0x03;
i386_load_segment_descriptor(cpustate,SS);
}
cpustate->gdtr.limit = READ16(cpustate,ea);
cpustate->gdtr.base = READ32(cpustate,ea + 2) & 0xffffff;
- logerror("LGDT(16) PC=%08X MODRM=%02X BASE=%08X LIMIT=%04X\n", cpustate->prev_pc, modrm, cpustate->gdtr.base, cpustate->gdtr.limit);
+ //logerror("LGDT(16) PC=%08X MODRM=%02X BASE=%08X LIMIT=%04X\n", cpustate->prev_pc, modrm, cpustate->gdtr.base, cpustate->gdtr.limit);
CYCLES(cpustate,CYCLES_LGDT);
break;
}
}
cpustate->gdtr.limit = READ16(cpustate,ea);
cpustate->gdtr.base = READ32(cpustate,ea + 2);
- logerror("LGDT(32) PC=%08X MODRM=%02X BASE=%08X LIMIT=%04X\n", cpustate->prev_pc, modrm, cpustate->gdtr.base, cpustate->gdtr.limit);
+ //logerror("LGDT(32) PC=%08X MODRM=%02X BASE=%08X LIMIT=%04X\n", cpustate->prev_pc, modrm, cpustate->gdtr.base, cpustate->gdtr.limit);
CYCLES(cpustate,CYCLES_LGDT);
break;
}
{
// compare if greater then 0xffffffff when we're passed the access size
if(offset < size) size = offset;
- if(((offset - size) <= cpustate->sreg[seg].limit) || ((cpustate->sreg[seg].d)?0:((offset + size - 1) > 0xffff)))
+ if(/*(cpustate->sreg[seg].limit != 0) && */(((offset - size) <= cpustate->sreg[seg].limit) || ((cpustate->sreg[seg].d)?0:((offset + size - 1) > 0xffff))))
{
logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x (expand-down)\n",cpustate->pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset);
return 1;
}
else
{
- if((offset + size - 1) > cpustate->sreg[seg].limit)
+ if(((offset + size - 1) > cpustate->sreg[seg].limit) /*&& (cpustate->sreg[seg].limit != 0)*/)
{
logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x\n",cpustate->pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset);
return 1;
nmi_enabled = false;
}
+void CPUREG::write_signal(int ch, uint32_t data, uint32_t mask)
+{
+ if(ch == SIG_CPU_NMI) {
+ out_debug_log("NMI\n");
+ //if(nmi_enabled) {
+ write_signals(&outputs_nmi, data);
+ //}
+ } else if(ch == SIG_CPUREG_RESET) {
+ out_debug_log("RESET FROM CPU!!!\n");
+ uint8_t reset_reg = d_pio->read_signal(SIG_I8255_PORT_C);
+ reset_reg = reset_reg & (uint8_t)(~0x20); // Reset SHUT1
+ d_pio->write_signal(SIG_I8255_PORT_C, reset_reg, 0xff);
+ d_cpu->set_address_mask(0x000fffff);
+ //d_cpu->reset();
+ }
+}
+
void CPUREG::write_io8(uint32_t addr, uint32_t data)
{
//out_debug_log(_T("I/O WRITE: %04x %04x\n"), addr, data);
#include "../../emu.h"
#include "../device.h"
+#define SIG_CPUREG_RESET 1
#if defined(SUPPORT_32BIT_ADDRESS)
-class I386;
-#else
-class I286;
+#include "../i386.h"
#endif
+//#include "../i286.h"
+class I286;
namespace PC9801 {
#else
I286 *d_cpu;
#endif
+ I286 *d_v30;
DEVICE* d_mem;
DEVICE* d_pio;
bool nmi_enabled;
+ outputs_t outputs_nmi; // NMI must route via CPUREG::
public:
CPUREG(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
{
+ initialize_output_signals(&outputs_nmi);
set_device_name(_T("CPU I/O"));
}
~CPUREG() {}
void reset();
void write_io8(uint32_t addr, uint32_t data);
uint32_t read_io8(uint32_t addr);
+ // NOTE: NMI must route CPUREG::, should not connect directly.20190502 K.O
+ void write_signal(int ch, uint32_t data, uint32_t mask);
bool process_state(FILEIO* state_fio, bool loading);
// unique function
#endif
{
d_cpu = device;
+ register_output_signal(&outputs_nmi, device, SIG_CPU_NMI, 0xffffffff, 0);
}
+ // This will be feature developing, still not implement V30 feature.20190502 K.O
+#if 0
+ void set_context_v30(I286* device)
+ {
+ d_v30 = device;
+ register_output_signal(&outputs_nmi, device, SIG_CPU_NMI, 0xffffffff);
+ }
+#endif
void set_context_membus(DEVICE* device)
{
d_mem = device;
shadow_ram_selected = true;
#endif
#if defined(SUPPORT_ITF_ROM)
- itf_selected = true;
+// itf_selected = true;
#endif
update_bios();
MEMORY::copy_table_rw(0x00ffa000, 0x000fa000, 0x000fffff);
MEMORY::copy_table_rw(0x00ee8000, 0x000e8000, 0x000fffff);
#endif
+#if defined(SUPPORT_BIOS_RAM)
+// set_memory_w(0x00100000 - sizeof(bios_ram), 0x000fffff, bios_ram);
+#endif
return;
}
#endif
}
-#if !defined(SUPPORT_HIRESO)
+
void MEMBUS::update_sound_bios()
{
if(sound_bios_selected) {
}
}
#endif
-#endif
+
#define STATE_VERSION 6
*/
// set contexts
+
+#if defined(HAS_I386) || defined(HAS_I486)
+ cpu->set_context_extreset(cpureg, SIG_CPUREG_RESET, 0xffffffff);
+#endif
event->set_context_cpu(cpu, cpu_clocks);
#if defined(SUPPORT_320KB_FDD_IF)
event->set_context_cpu(cpu_sub, 4000000);