OSDN Git Service

[VM][I286][PC9801] Add SIG_I386_FORCE_RESET to notify resetting to external devices...
authorK.Ohta <whatisthis.sowhat@gmail.com>
Thu, 2 May 2019 09:02:55 +0000 (18:02 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Thu, 2 May 2019 09:02:55 +0000 (18:02 +0900)
source/src/vm/i386.cpp
source/src/vm/i386.h
source/src/vm/mame/emu/cpu/i386/i386.c
source/src/vm/mame/emu/cpu/i386/i386op16.c
source/src/vm/mame/emu/cpu/i386/i386op32.c
source/src/vm/mame/emu/cpu/i386/i386priv.h
source/src/vm/pc9801/cpureg.cpp
source/src/vm/pc9801/cpureg.h
source/src/vm/pc9801/membus.cpp
source/src/vm/pc9801/pc9801.cpp

index 2ba5fd7..d8230df 100644 (file)
@@ -423,6 +423,7 @@ void I386::reset()
        i386_state *cpustate = (i386_state *)opaque;
        logerror(_T("I386::reset()"));
        cpu_reset_generic(cpustate);
+       write_signals(&outputs_extreset, 0xffffffff);
 }
 
 int I386::run(int cycles)
@@ -443,6 +444,8 @@ void I386::write_signal(int id, uint32_t data, uint32_t mask)
                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));
        }
 }
 
index f8a0572..0d09d8c 100644 (file)
@@ -18,8 +18,8 @@
 #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
@@ -38,7 +38,7 @@ private:
        DEBUGGER *d_debugger;
 //#endif
        void *opaque;
-       
+       outputs_t outputs_extreset;
 public:
        I386(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
        {
@@ -67,6 +67,7 @@ public:
 //#elif defined(HAS_PENTIUM4)
 //             set_device_name(_T("Pentium4 CPU"));
 //#endif
+               initialize_output_signals(&outputs_extreset);
                set_device_name(_T("Intel i80x86 CPU"));
        }
        ~I386() {}
@@ -125,6 +126,10 @@ public:
        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;
index 24975c7..04a1c89 100644 (file)
@@ -49,7 +49,7 @@ static void build_opcode_table(i386_state *cpustate, UINT32 features);
 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)
@@ -575,7 +575,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                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);
@@ -765,6 +765,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                        //CPU_RESET_CALL(CPU_MODEL);
                        cpu_reset_generic(cpustate);
                        cpustate->shutdown = 1;
+                       cpustate->parent_device->write_signal(SIG_I386_FORCE_RESET, 0xfffffff, 0xffffffff);
                        return;
                }
 
@@ -1784,7 +1785,7 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
        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)
@@ -2460,7 +2461,7 @@ static void i386_protected_mode_retf(i386_state* cpustate, UINT8 count, UINT8 op
                        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 */
@@ -2947,7 +2948,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                                        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);
 
index 886143e..4f35a54 100644 (file)
@@ -3444,7 +3444,7 @@ static void I386OP(group0F01_16)(i386_state *cpustate)      // Opcode 0x0f 01
                                }
                                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;
                        }
index cb06a50..53f0f80 100644 (file)
@@ -3212,7 +3212,7 @@ static void I386OP(group0F01_32)(i386_state *cpustate)      // Opcode 0x0f 01
                                }
                                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;
                        }
index daa8f87..d3b6ffe 100644 (file)
@@ -678,7 +678,7 @@ INLINE int i386_limit_check(i386_state *cpustate, int seg, UINT32 offset, UINT32
                {
                        // 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;
@@ -686,7 +686,7 @@ INLINE int i386_limit_check(i386_state *cpustate, int seg, UINT32 offset, UINT32
                }
                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;
index b1987e0..5be0598 100644 (file)
@@ -28,6 +28,23 @@ void CPUREG::reset()
        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);
index 3b0d8bd..2a14171 100644 (file)
 #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 {
 
@@ -34,13 +35,16 @@ private:
 #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() {}
@@ -49,6 +53,8 @@ public:
        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
@@ -59,7 +65,16 @@ public:
 #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;
index b37a475..6f83fb5 100644 (file)
@@ -169,7 +169,7 @@ void MEMBUS::reset()
        shadow_ram_selected = true;
 #endif
 #if defined(SUPPORT_ITF_ROM)
-       itf_selected = true;
+//     itf_selected = true;
 #endif
        update_bios();
        
@@ -822,6 +822,9 @@ void MEMBUS::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
@@ -844,7 +847,7 @@ void MEMBUS::update_bios()
 
 }
 
-#if !defined(SUPPORT_HIRESO)
+
 void MEMBUS::update_sound_bios()
 {
        if(sound_bios_selected) {
@@ -921,7 +924,7 @@ void MEMBUS::update_nec_ems()
        }
 }
 #endif
-#endif
+
 
 #define STATE_VERSION  6
 
index 0dea000..a17e4a2 100644 (file)
@@ -364,6 +364,10 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
        */
        
        // 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);