OSDN Git Service

[VM][Ix86][I386] More correctness wait.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 13 Sep 2019 15:20:57 +0000 (00:20 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 13 Sep 2019 15:20:57 +0000 (00:20 +0900)
[VM][Ix86][I386] Implement wait by memory-wait-factor.
[VM][Ix86][I386] Add SIG_CPU_HALTREQ.

16 files changed:
source/src/vm/common_vm/CMakeLists.txt
source/src/vm/i286.cpp
source/src/vm/i386.cpp
source/src/vm/i80286.cpp
source/src/vm/i86.cpp
source/src/vm/jx/i286.cpp
source/src/vm/mame/emu/cpu/i386/i386.c
source/src/vm/mame/emu/cpu/i386/i386priv.h
source/src/vm/mame/emu/cpu/i86/i286.c
source/src/vm/mame/emu/cpu/i86/i86.c
source/src/vm/mame/emu/cpu/i86/i86priv.h
source/src/vm/mame/emu/cpu/i86/instr186.c
source/src/vm/mame/emu/cpu/i86/instr86.c
source/src/vm/mame/emu/cpu/i86/v30.c
source/src/vm/memory.cpp
source/src/vm/v30.cpp

index f55b39a..4348344 100644 (file)
@@ -1,6 +1,6 @@
 message("* vm/common_vm")
 
-SET(THIS_LIB_VERSION 2.19.0)
+SET(THIS_LIB_VERSION 2.19.1)
 
 #include(cotire)
 set(s_vm_common_vm_srcs
index 63cc4e9..d4cbd95 100644 (file)
@@ -44,8 +44,6 @@ void I80286::initialize()
                d_debugger->set_context_mem(d_mem);
                d_debugger->set_context_io(d_io);
        }
-       cpustate->waitfactor = 0;
-       cpustate->waitcount = 0;
 }
 
 void I80286::release()
@@ -57,6 +55,7 @@ void I80286::reset()
 {
        cpu_state *cpustate = (cpu_state *)opaque;
        int busreq = cpustate->busreq;
+       int haltreq = cpustate->haltreq;
        
        CPU_RESET_CALL(i80286);
        
@@ -70,6 +69,7 @@ void I80286::reset()
        cpustate->program_stored = d_mem;
        cpustate->io_stored = d_io;
        cpustate->busreq = busreq;
+       cpustate->haltreq = haltreq;
 }
 
 int I80286::run(int icount)
@@ -110,6 +110,8 @@ void I80286::write_signal(int id, uint32_t data, uint32_t mask)
                set_irq_line(cpustate, INPUT_LINE_IRQ, (data & mask) ? HOLD_LINE : CLEAR_LINE);
        } else if(id == SIG_CPU_BUSREQ) {
                cpustate->busreq = (data & mask) ? 1 : 0;
+       } else if(id == SIG_CPU_HALTREQ) {
+               cpustate->haltreq = (data & mask) ? 1 : 0;
        } else if(id == SIG_I86_TEST) {
                cpustate->test_state = (data & mask) ? 1 : 0;
        } else if(id == SIG_I286_A20) {
@@ -343,7 +345,7 @@ int I80286::get_shutdown_flag()
        return cpustate->shutdown;
 }
 
-#define STATE_VERSION  7
+#define STATE_VERSION  8
 
 bool I80286::process_state(FILEIO* state_fio, bool loading)
 {
@@ -395,6 +397,7 @@ bool I80286::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(cpustate->extra_cycles);
        state_fio->StateValue(cpustate->halted);
        state_fio->StateValue(cpustate->busreq);
+       state_fio->StateValue(cpustate->haltreq);
        state_fio->StateValue(cpustate->trap_level);
        state_fio->StateValue(cpustate->shutdown);
        state_fio->StateValue(cpustate->total_icount);
@@ -406,6 +409,7 @@ bool I80286::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(cpustate->ea_seg);
        state_fio->StateValue(cpustate->waitfactor);
        state_fio->StateValue(cpustate->waitcount);
+       state_fio->StateValue(cpustate->memory_wait);
        
        // post process
        if(loading) {
index 5341dea..b545f90 100644 (file)
@@ -434,8 +434,6 @@ void I386::initialize()
        cpustate->parent_device = this; // This aims to log.
        cpustate->cpu_type = n_cpu_type; // check cpu type
        cpustate->shutdown = 0;
-       cpustate->waitcount = 0;
-       cpustate->waitfactor = 0;
 }
 
 void I386::release()
@@ -491,6 +489,8 @@ void I386::write_signal(int id, uint32_t data, uint32_t mask)
                i386_set_irq_line(cpustate, INPUT_LINE_IRQ, (data & mask) ? HOLD_LINE : CLEAR_LINE);
        } else if(id == SIG_CPU_BUSREQ) {
                cpustate->busreq = (data & mask) ? 1 : 0;
+       } else if(id == SIG_CPU_HALTREQ) {
+               cpustate->haltreq = (data & mask) ? 1 : 0;
        } else if(id == SIG_I386_A20) {
                i386_set_a20_line(cpustate, data & mask);
        } else if(id == SIG_I386_NOTIFY_RESET) {
@@ -854,7 +854,7 @@ int I386::get_shutdown_flag()
        return cpustate->shutdown;
 }
 
-#define STATE_VERSION  7
+#define STATE_VERSION  8
 
 void process_state_SREG(I386_SREG* val, FILEIO* state_fio)
 {
@@ -976,6 +976,7 @@ bool I386::process_state(FILEIO* state_fio, bool loading)
        process_state_SEG_DESC(&cpustate->ldtr, state_fio);
        state_fio->StateValue(cpustate->ext);
        state_fio->StateValue(cpustate->halted);
+       state_fio->StateValue(cpustate->haltreq);
        state_fio->StateValue(cpustate->busreq);
        state_fio->StateValue(cpustate->shutdown);
        state_fio->StateValue(cpustate->operand_size);
index cf6ee35..2fb97ad 100644 (file)
@@ -164,8 +164,6 @@ void I8086::initialize()
        d_debugger->set_context_mem(d_mem);
        d_debugger->set_context_io(d_io);
 //#endif
-       cpustate->waitfactor = 0;
-       cpustate->waitcount = 0;
 }
 
 void I80286::release()
@@ -480,7 +478,7 @@ int I80286::get_shutdown_flag()
        return cpustate->shutdown;
 }
 
-#define STATE_VERSION  6
+#define STATE_VERSION  7
 
 bool I80286::process_state(FILEIO* state_fio, bool loading)
 {
@@ -545,6 +543,7 @@ bool I80286::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(cpustate->ea_seg);
        state_fio->StateValue(cpustate->waitfactor);
        state_fio->StateValue(cpustate->waitcount);
+       state_fio->StateValue(cpustate->memory_wait);
        // post process
        if(loading) {
                cpustate->prev_total_icount = cpustate->total_icount;
index 5a74c09..dfbb3ff 100644 (file)
@@ -88,8 +88,6 @@ void I8086::initialize()
                d_debugger->set_context_mem(d_mem);
                d_debugger->set_context_io(d_io);
        }
-       cpustate->waitfactor = 0;
-       cpustate->waitcount = 0;
 }
 
 void I8086::release()
@@ -116,6 +114,7 @@ void I8086::reset()
 {
        cpu_state *cpustate = (cpu_state *)opaque;
        int busreq = cpustate->busreq;
+       int haltreq = cpustate->haltreq;
 
        cpu_reset_generic();
        
@@ -135,6 +134,7 @@ void I8086::reset()
        cpustate->io_stored = d_io;
 //#endif
        cpustate->busreq = busreq;
+       cpustate->haltreq = haltreq;
 }
 
 int I8086::run(int icount)
@@ -182,6 +182,8 @@ void I8086::write_signal(int id, uint32_t data, uint32_t mask)
                set_irq_line(cpustate, INPUT_LINE_IRQ, (data & mask) ? HOLD_LINE : CLEAR_LINE);
        } else if(id == SIG_CPU_BUSREQ) {
                cpustate->busreq = (data & mask) ? 1 : 0;
+       } else if(id == SIG_CPU_HALTREQ) {
+               cpustate->haltreq = (data & mask) ? 1 : 0;
        } else if(id == SIG_I86_TEST) {
                cpustate->test_state = (data & mask) ? 1 : 0;
        } else if(id == SIG_CPU_WAIT_FACTOR) {
@@ -389,7 +391,7 @@ int I8086::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_l
 }
 
 
-#define STATE_VERSION  7
+#define STATE_VERSION  8
 
 bool I8086::process_state(FILEIO* state_fio, bool loading)
 {
@@ -439,6 +441,7 @@ bool I8086::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(cpustate->ea_seg);
        state_fio->StateValue(cpustate->waitfactor);
        state_fio->StateValue(cpustate->waitcount);
+       state_fio->StateValue(cpustate->memory_wait);
 //#endif
        
        // post process
index 7448bd6..b1f2019 100644 (file)
@@ -169,8 +169,6 @@ void I286::initialize()
        d_debugger->set_context_mem(d_mem);
        d_debugger->set_context_io(d_io);
 #endif
-       cpustate->waitfactor = 0;
-       cpustate->waitcount = 0;
 }
 
 void I286::release()
@@ -182,6 +180,7 @@ void I286::reset()
 {
        cpu_state *cpustate = (cpu_state *)opaque;
        int busreq = cpustate->busreq;
+       int haltreq = cpustate->haltreq;
        
        CPU_RESET_CALL(CPU_MODEL);
        
@@ -201,6 +200,7 @@ void I286::reset()
        cpustate->io_stored = d_io;
 #endif
        cpustate->busreq = busreq;
+       cpustate->haltreq = haltreq;
 }
 
 int I286::run(int icount)
@@ -249,6 +249,8 @@ void I286::write_signal(int id, uint32_t data, uint32_t mask)
                set_irq_line(cpustate, INPUT_LINE_IRQ, (data & mask) ? HOLD_LINE : CLEAR_LINE);
        } else if(id == SIG_CPU_BUSREQ) {
                cpustate->busreq = (data & mask) ? 1 : 0;
+       } else if(id == SIG_CPU_HALTREQ) {
+               cpustate->haltreq = (data & mask) ? 1 : 0;
        } else if(id == SIG_I86_TEST) {
                cpustate->test_state = (data & mask) ? 1 : 0;
 #ifdef HAS_I286
@@ -450,7 +452,7 @@ int I286::get_shutdown_flag()
 }
 #endif
 
-#define STATE_VERSION  6
+#define STATE_VERSION  8
 
 bool I286::process_state(FILEIO* state_fio, bool loading)
 {
@@ -486,6 +488,7 @@ bool I286::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(cpustate->extra_cycles);
        state_fio->StateValue(cpustate->halted);
        state_fio->StateValue(cpustate->busreq);
+       state_fio->StateValue(cpustate->haltreq);
        state_fio->StateValue(cpustate->ip);
        state_fio->StateValue(cpustate->sp);
 //#ifdef USE_DEBUGGER
@@ -499,6 +502,7 @@ bool I286::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(cpustate->ea_seg);
        state_fio->StateValue(cpustate->waitfactor);
        state_fio->StateValue(cpustate->waitcount);
+       state_fio->StateValue(cpustate->memory_wait);
        
 //#ifdef USE_DEBUGGER
        // post process
index 70431bf..e4fb610 100644 (file)
@@ -3269,8 +3269,9 @@ static i386_state *i386_common_init(int tlbsize)
 
        zero_state(cpustate);
        cpustate->halted = 0;
+       cpustate->haltreq = 0;
        cpustate->busreq = 0;
-
+       cpustate->waitfactor = 65536;
        return cpustate;
 }
 
@@ -3619,7 +3620,11 @@ static void pentium_smi(i386_state *cpustate)
 static void i386_set_irq_line(i386_state *cpustate,int irqline, int state)
 {
        int first_cycles = cpustate->cycles;
-
+       if (cpustate->haltreq != 0) {
+               cpustate->extra_cycles += first_cycles - cpustate->cycles;
+               cpustate->cycles = first_cycles;
+               return;
+       }
        if (state != CLEAR_LINE && cpustate->halted)
        {
                cpustate->prev_pc = cpustate->pc;
@@ -3673,32 +3678,38 @@ static void i386_set_a20_line(i386_state *cpustate,int state)
 
 static INLINE __FASTCALL void cpu_wait_i386(i386_state *cpustate,int clocks)
 {
-       if(clocks <= 0) return;
-       if(cpustate->waitfactor == 0) return;
-       uint32_t wcount = cpustate->waitcount;
-       wcount += (uint32_t)(cpustate->waitfactor * (uint32_t)clocks);
+       if(clocks <= 0) clocks = 1;
+       int64_t wfactor = cpustate->waitfactor;
+       int64_t wcount = cpustate->waitcount;
+       int64_t mwait = cpustate->memory_wait;
+       int64_t ncount;
+
+       if(wfactor > 65536) {
+               wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock.
+       }
+       wcount += (wfactor * mwait);  // memory wait
        if(wcount >= 65536) {
-               uint32_t ncount;
                ncount = wcount >> 16;
                wcount = wcount - (ncount << 16);
-               //wcount = wcount & 0x0000ffff;
                cpustate->extra_cycles += (int)ncount;
+       } else if(wcount < 0) {
+               wcount = 0;
        }
-//     if(cpustate->memory_wait > 0) ncount += cpustate->memory_wait; // Temporally disable memory wait.
-//     cpustate->memory_wait = 0;
-//     cpustate->extra_cycles += (int)ncount;
        cpustate->waitcount = wcount;
+       cpustate->memory_wait = 0;
 }
 
 static CPU_EXECUTE( i386 )
 {
        CHANGE_PC(cpustate,cpustate->eip);
 
-       if (cpustate->halted || cpustate->busreq)
+       if (cpustate->halted || cpustate->busreq || cpustate->haltreq)
        {
 //#ifdef SINGLE_MODE_DMA
-               if(cpustate->dma != NULL) {
-                       cpustate->dma->do_dma();
+               if(!(cpustate->haltreq)) {
+                       if(cpustate->dma != NULL) {
+                               cpustate->dma->do_dma();
+                       }
                }
 //#endif
                bool now_debugging = false;
@@ -3783,7 +3794,7 @@ static CPU_EXECUTE( i386 )
        bool exception_caused = false;
        UINT32 exception_pc = 0;
        UINT64 exception_code = 0;
-       while( cpustate->cycles > 0 && !cpustate->busreq )
+       while( cpustate->cycles > 0 && !cpustate->busreq && !cpustate->haltreq) 
        {
 //#ifdef USE_DEBUGGER
                bool now_debugging = false;
@@ -3883,8 +3894,10 @@ static CPU_EXECUTE( i386 )
                        
                        
 //#ifdef SINGLE_MODE_DMA
-                       if(cpustate->dma != NULL) {
-                               cpustate->dma->do_dma();
+                       if(!(cpustate->haltreq)) {
+                               if(cpustate->dma != NULL) {
+                                       cpustate->dma->do_dma();
+                               }
                        }
 //#endif
                        /* adjust for any interrupts that came in */
@@ -3962,8 +3975,10 @@ static CPU_EXECUTE( i386 )
                                cpustate->cycles = 0;
                        }
 //#ifdef SINGLE_MODE_DMA
-                       if(cpustate->dma != NULL) {
-                               cpustate->dma->do_dma();
+                       if(!(cpustate->haltreq)) {
+                               if(cpustate->dma != NULL) {
+                                       cpustate->dma->do_dma();
+                               }
                        }
 //#endif
                        /* adjust for any interrupts that came in */
@@ -3976,7 +3991,7 @@ static CPU_EXECUTE( i386 )
        }
 
        /* if busreq is raised, spin cpu while remained clock */
-       if (cpustate->cycles > 0 && cpustate->busreq) {
+       if (cpustate->cycles > 0 && (cpustate->busreq || cpustate->haltreq)) {
 //#ifdef USE_DEBUGGER
                cpustate->total_cycles += cpustate->cycles;
 //#endif
index e068740..d5fbc09 100644 (file)
@@ -563,6 +563,7 @@ struct i386_state
 
        int halted;
        int busreq;
+       int haltreq;
        int shutdown;
 
        int operand_size;
@@ -695,53 +696,53 @@ extern int i386_parity_table[256];
 //static int i386_limit_check(i386_state *cpustate, int seg, UINT32 offset, UINT32 size);
 INLINE UINT8 __FASTCALL read_data8_with_wait(i386_state* cpustate, UINT32 addr)
 {
-//     int wait = 0;
-//     UINT8 val = cpustate->program->read_data8w(addr, &wait);
-//     if(wait > 0) cpustate->memory_wait += wait;
-       UINT8 val = cpustate->program->read_data8(addr);
+       int wait = 0;
+       UINT8 val = cpustate->program->read_data8w(addr, &wait);
+       if(wait > 0) cpustate->memory_wait += wait;
+//     UINT8 val = cpustate->program->read_data8(addr);
        return val;
 }
 
 INLINE UINT16 __FASTCALL read_data16_with_wait(i386_state* cpustate, UINT32 addr)
 {
-//     int wait = 0;
-//     UINT16 val = cpustate->program->read_data16w(addr, &wait);
-//     if(wait > 0) cpustate->memory_wait += wait;
-       UINT16 val = cpustate->program->read_data16(addr);
+       int wait = 0;
+       UINT16 val = cpustate->program->read_data16w(addr, &wait);
+       if(wait > 0) cpustate->memory_wait += wait;
+//     UINT16 val = cpustate->program->read_data16(addr);
        return val;
 }
 
 INLINE UINT32 __FASTCALL read_data32_with_wait(i386_state* cpustate, UINT32 addr)
 {
-//     int wait = 0;
-//     UINT32 val = cpustate->program->read_data32w(addr, &wait);
-//     if(wait > 0) cpustate->memory_wait += wait;
-       UINT32 val = cpustate->program->read_data32(addr);
+       int wait = 0;
+       UINT32 val = cpustate->program->read_data32w(addr, &wait);
+       if(wait > 0) cpustate->memory_wait += wait;
+//     UINT32 val = cpustate->program->read_data32(addr);
        return val;
 }
 
 INLINE void __FASTCALL write_data8_with_wait(i386_state* cpustate, UINT32 addr, UINT32 data)
 {
-//     int wait = 0;
-//     cpustate->program->write_data8w(addr, data, &wait);
-//     if(wait > 0) cpustate->memory_wait += wait;
-       cpustate->program->write_data8(addr, data);
+       int wait = 0;
+       cpustate->program->write_data8w(addr, data, &wait);
+       if(wait > 0) cpustate->memory_wait += wait;
+//     cpustate->program->write_data8(addr, data);
 }
 
 INLINE void __FASTCALL write_data16_with_wait(i386_state* cpustate, UINT32 addr, UINT32 data)
 {
-//     int wait = 0;
-//     cpustate->program->write_data16w(addr, data, &wait);
-//     if(wait > 0) cpustate->memory_wait += wait;
-       cpustate->program->write_data16(addr, data);
+       int wait = 0;
+       cpustate->program->write_data16w(addr, data, &wait);
+       if(wait > 0) cpustate->memory_wait += wait;
+//     cpustate->program->write_data16(addr, data);
 }
 
 INLINE void __FASTCALL write_data32_with_wait(i386_state* cpustate, UINT32 addr, UINT32 data)
 {
-//     int wait = 0;
-//     cpustate->program->write_data32w(addr, data, &wait);
-//     if(wait > 0) cpustate->memory_wait += wait;
-       cpustate->program->write_data32(addr, data);
+       int wait = 0;
+       cpustate->program->write_data32w(addr, data, &wait);
+       if(wait > 0) cpustate->memory_wait += wait;
+//     cpustate->program->write_data32(addr, data);
 }
 
 #define FAULT_THROW(fault,error) {                                                                             \
index b854bb9..9f484b9 100644 (file)
@@ -88,10 +88,12 @@ struct i80286_state
 
        int halted;         /* Is the CPU halted ? */
        int busreq;
+       int haltreq;
        int trap_level;
        int shutdown;
        uint32_t waitfactor;
        uint32_t waitcount;
+       int32_t memory_wait;
 
 //#ifdef USE_DEBUGGER
        uint64_t total_icount;
@@ -186,6 +188,7 @@ static CPU_RESET( i80286 )
        
        int halted = cpustate->halted;
        int busreq = cpustate->busreq;
+       int haltreq = cpustate->haltreq;
        
        memset(&cpustate->regs, 0, sizeof(i80286basicregs));
        cpustate->sregs[CS] = 0xf000;
@@ -211,12 +214,14 @@ static CPU_RESET( i80286 )
        cpustate->rep_in_progress = FALSE;
        cpustate->seg_prefix = FALSE;
        cpustate->waitcount = 0;
+       cpustate->memory_wait = 0;
 
        CHANGE_PC(cpustate->pc);
 
 //     cpustate->icount = cpustate->extra_cycles = 0;
        cpustate->halted = halted;
        cpustate->busreq = busreq;
+       cpustate->haltreq = haltreq;
 }
 
 /****************************************************************************/
@@ -226,6 +231,11 @@ static CPU_RESET( i80286 )
 static void set_irq_line(i80286_state *cpustate, int irqline, int state)
 {
        int first_icount = cpustate->icount;
+       if (cpustate->haltreq != 0) {
+               cpustate->extra_cycles += first_icount - cpustate->icount;
+               cpustate->icount = first_icount;
+               return;
+       }
 
        if (state != CLEAR_LINE && cpustate->halted)
        {
@@ -266,26 +276,35 @@ static void set_irq_line(i80286_state *cpustate, int irqline, int state)
 
 static void __FASTCALL cpu_wait_i286(cpu_state *cpustate,int clocks)
 {
-       uint32_t ncount = 0;
-       if(clocks < 0) return;
-       if(cpustate->waitfactor == 0) return;
-       uint32_t wcount = cpustate->waitcount;
-       wcount += (cpustate->waitfactor * (uint32_t)clocks);
+       if(clocks <= 0) clocks = 1;
+       int64_t wfactor = cpustate->waitfactor;
+       int64_t wcount = cpustate->waitcount;
+       int64_t mwait = cpustate->memory_wait;
+       int64_t ncount;
+       if(cpustate->waitfactor >= 65536) {
+               wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock.
+       }
+       wcount += (wfactor * mwait);  // memory wait
        if(wcount >= 65536) {
                ncount = wcount >> 16;
                wcount = wcount - (ncount << 16);
-               cpustate->extra_cycles += ncount;
+               cpustate->extra_cycles += (int)ncount;
+       } else if(wcount < 0) {
+               wcount = 0;
        }
        cpustate->waitcount = wcount;
+       cpustate->memory_wait = 0;
 }
 
 static CPU_EXECUTE( i80286 )
 {
-       if (cpustate->halted || cpustate->busreq)
+       if (cpustate->halted || cpustate->busreq || cpustate->haltreq)
        {
 //#ifdef SINGLE_MODE_DMA
-               if (cpustate->dma != NULL) {
-                       cpustate->dma->do_dma();
+               if(!cpustate->haltreq) {
+                       if (cpustate->dma != NULL) {
+                               cpustate->dma->do_dma();
+                       }
                }
 //#endif
                bool now_debugging = false;
@@ -367,7 +386,7 @@ static CPU_EXECUTE( i80286 )
        cpustate->extra_cycles = 0;
 
        /* run until we're out */
-       while(cpustate->icount > 0 && !cpustate->busreq)
+       while(cpustate->icount > 0 && !cpustate->busreq && !cpustate->haltreq)
        {
 //#ifdef USE_DEBUGGER
                bool now_debugging = false;
@@ -407,8 +426,10 @@ static CPU_EXECUTE( i80286 )
                        }
                        cpustate->total_icount += first_icount - cpustate->icount;
 //#ifdef SINGLE_MODE_DMA
-                       if (cpustate->dma != NULL) {
-                               cpustate->dma->do_dma();
+                       if(!cpustate->haltreq) {
+                               if (cpustate->dma != NULL) {
+                                       cpustate->dma->do_dma();
+                               }
                        }
 //#endif
                        if(now_debugging) {
@@ -441,8 +462,10 @@ static CPU_EXECUTE( i80286 )
                        cpustate->total_icount += first_icount - cpustate->icount;
 //#endif
 //#ifdef SINGLE_MODE_DMA
-                       if (cpustate->dma != NULL) {
-                               cpustate->dma->do_dma();
+                       if(!cpustate->haltreq) {
+                               if (cpustate->dma != NULL) {
+                                       cpustate->dma->do_dma();
+                               }
                        }
 //#endif
 //#ifdef USE_DEBUGGER
@@ -457,7 +480,7 @@ static CPU_EXECUTE( i80286 )
        }
 
        /* if busreq is raised, spin cpu while remained clock */
-       if (cpustate->icount > 0 && cpustate->busreq) {
+       if (cpustate->icount > 0 && (cpustate->busreq || cpustate->haltreq)) {
 //#ifdef USE_DEBUGGER
                cpustate->total_icount += cpustate->icount;
 //#endif
@@ -477,7 +500,7 @@ static CPU_INIT( i80286 )
        cpustate->amask = 0xfffff;
 
        i80286_urinit();
-
+       cpustate->waitfactor = 65536;
        return cpustate;
 }
 
index 4815cb2..cdeb3ea 100644 (file)
@@ -8,7 +8,7 @@
 //#include "debugger.h"
 
 //#include "host.h"
-#include "i86priv.h"
+//#include "i86priv.h"
 #include "i86.h"
 //#include "i86basic.h"
 static int i386_dasm_one(_TCHAR *buffer, UINT32 eip, const UINT8 *oprom, int mode);
@@ -48,6 +48,7 @@ struct i8086_state
        INT32 extra_cycles;       /* extra cycles for interrupts */
 
        int halted;         /* Is the CPU halted ? */
+          int haltreq;
        int busreq;
 
        UINT16 ip;
@@ -73,8 +74,9 @@ struct i8086_state
 
        int icount;
        uint32_t waitfactor;
-       uint32_t waitcount;
-
+          uint32_t waitcount;
+          int32_t memory_wait;
+       
        //char seg_prefix;                   /* prefix segment indicator */
        UINT8 seg_prefix;                   /* prefix segment indicator */
        UINT8   prefix_seg;                 /* The prefixed segment */
@@ -82,6 +84,8 @@ struct i8086_state
        UINT16 eo; /* HJB 12/13/98 effective offset of the address (before segment is added) */
        UINT8 ea_seg;   /* effective segment of the address */
 };
+#undef I80286
+#include "i86priv.h"
 
 #include "i86time.c"
 
@@ -149,6 +153,7 @@ static CPU_INIT( i8086 )
                Mod_RM.RM.w[i] = (WREGS) (i & 7);
                Mod_RM.RM.b[i] = (BREGS) reg_name[i & 7];
        }
+       cpustate->waitfactor = 65536;
        return cpustate;
 }
 
@@ -174,6 +179,7 @@ static CPU_RESET( i8086 )
        int extra_cycles = cpustate->extra_cycles;
        int halted = cpustate->halted;
        int busreq = cpustate->busreq;
+       int haltreq = cpustate->haltreq;
 
        memset(cpustate, 0, sizeof(*cpustate));
 
@@ -186,11 +192,13 @@ static CPU_RESET( i8086 )
        cpustate->total_icount = total_icount;
        cpustate->prev_total_icount = prev_total_icount;
 //#endif
+       cpustate->memory_wait = 0;;
        cpustate->waitcount = 0;
        cpustate->icount = icount;
        cpustate->extra_cycles = extra_cycles;
        cpustate->halted = halted;
        cpustate->busreq = busreq;
+       cpustate->haltreq = haltreq;
 }
 
 static CPU_RESET( i8088 )
@@ -209,6 +217,11 @@ static CPU_RESET( i80186 )
 static void set_irq_line(i8086_state *cpustate, int irqline, int state)
 {
        int first_icount = cpustate->icount;
+       if (cpustate->haltreq != 0) {
+               cpustate->extra_cycles += first_icount - cpustate->icount;
+               cpustate->icount = first_icount;
+               return;
+       }
 
        if (state != CLEAR_LINE && cpustate->halted)
        {
@@ -260,26 +273,35 @@ static void set_test_line(i8086_state *cpustate, int state)
 
 static void __FASTCALL cpu_wait_i86(i8086_state *cpustate,int clocks)
 {
-       uint32_t ncount = 0;
-       if(clocks < 0) return;
-       if(cpustate->waitfactor == 0) return;
-       uint32_t wcount = cpustate->waitcount;
-       wcount += (cpustate->waitfactor * (uint32_t)clocks);
+       if(clocks <= 0) clocks = 1;
+       int64_t wfactor = cpustate->waitfactor;
+       int64_t wcount = cpustate->waitcount;
+       int64_t mwait = cpustate->memory_wait;
+       int64_t ncount;
+       if(cpustate->waitfactor >= 65536) {
+               wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock.
+       }
+       wcount += (wfactor * mwait);  // memory wait
        if(wcount >= 65536) {
                ncount = wcount >> 16;
                wcount = wcount - (ncount << 16);
-               cpustate->extra_cycles += ncount;
+               cpustate->extra_cycles += (int)ncount;
+       } else if(wcount < 0) {
+               wcount = 0;
        }
        cpustate->waitcount = wcount;
+       cpustate->memory_wait = 0;
 }
 
 CPU_EXECUTE( i8086 )
 {
-       if (cpustate->halted || cpustate->busreq)
+       if (cpustate->halted || cpustate->busreq || cpustate->haltreq)
        {
 //#ifdef SINGLE_MODE_DMA
-               if(cpustate->dma != NULL) {
-                       cpustate->dma->do_dma();
+               if(!cpustate->haltreq) {
+                       if(cpustate->dma != NULL) {
+                               cpustate->dma->do_dma();
+                       }
                }
 //#endif
                bool now_debugging = false;
@@ -360,7 +382,7 @@ CPU_EXECUTE( i8086 )
        cpustate->extra_cycles = 0;
 
        /* run until we're out */
-       while (cpustate->icount > 0 && !cpustate->busreq)
+       while (cpustate->icount > 0 && !cpustate->busreq && !cpustate->haltreq)
        {
 //#ifdef USE_DEBUGGER
                bool now_debugging = false;
@@ -390,8 +412,10 @@ CPU_EXECUTE( i8086 )
                        TABLE86;
                        cpustate->total_icount += first_icount - cpustate->icount;
 //#ifdef SINGLE_MODE_DMA
-                       if(cpustate->dma != NULL) {
-                               cpustate->dma->do_dma();
+                       if(!cpustate->haltreq) {
+                               if(cpustate->dma != NULL) {
+                                       cpustate->dma->do_dma();
+                               }
                        }
 //#endif
                        if(now_debugging) {
@@ -414,8 +438,10 @@ CPU_EXECUTE( i8086 )
                        cpustate->total_icount += first_icount - cpustate->icount;
 //#endif
 //#ifdef SINGLE_MODE_DMA
-                       if(cpustate->dma != NULL) {
-                               cpustate->dma->do_dma();
+                       if(!cpustate->haltreq) {
+                               if(cpustate->dma != NULL) {
+                                       cpustate->dma->do_dma();
+                               }
                        }
 //#endif
 //#ifdef USE_DEBUGGER
@@ -430,7 +456,7 @@ CPU_EXECUTE( i8086 )
        }
 
        /* if busreq is raised, spin cpu while remained clock */
-       if (cpustate->icount > 0 && cpustate->busreq) {
+       if (cpustate->icount > 0 && (cpustate->busreq || cpustate->haltreq)) {
 //#ifdef USE_DEBUGGER
                cpustate->total_icount += cpustate->icount;
 //#endif
@@ -458,26 +484,35 @@ CPU_EXECUTE( i8086 )
 
 static void __FASTCALL cpu_wait_i186(cpu_state *cpustate,int clocks)
 {
-       if(clocks < 0) return;
-       if(cpustate->waitfactor == 0) return;
-       uint32_t wcount = cpustate->waitcount;
-       wcount += (cpustate->waitfactor * (uint32_t)clocks);
+       if(clocks <= 0) clocks = 1;
+       int64_t wfactor = cpustate->waitfactor;
+       int64_t wcount = cpustate->waitcount;
+       int64_t mwait = cpustate->memory_wait;
+       int64_t ncount;
+       if(cpustate->waitfactor >= 65536) {
+               wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock.
+       }
+       wcount += (wfactor * mwait);  // memory wait
        if(wcount >= 65536) {
-               uint32_t ncount;
                ncount = wcount >> 16;
                wcount = wcount - (ncount << 16);
-               cpustate->extra_cycles += ncount;
+               cpustate->extra_cycles += (int)ncount;
+       } else if(wcount < 0) {
+               wcount = 0;
        }
        cpustate->waitcount = wcount;
+       cpustate->memory_wait = 0;
 }
 
 CPU_EXECUTE( i80186 )
 {
-       if (cpustate->halted || cpustate->busreq)
+       if (cpustate->halted || cpustate->busreq || cpustate->haltreq)
        {
 //#ifdef SINGLE_MODE_DMA
-               if (cpustate->dma != NULL) {
-                       cpustate->dma->do_dma();
+               if(!cpustate->haltreq) {
+                       if (cpustate->dma != NULL) {
+                               cpustate->dma->do_dma();
+                       }
                }
 //#endif
                bool now_debugging = false;
@@ -558,7 +593,7 @@ CPU_EXECUTE( i80186 )
        cpustate->extra_cycles = 0;
 
        /* run until we're out */
-       while (cpustate->icount > 0 && !cpustate->busreq)
+       while (cpustate->icount > 0 && !cpustate->busreq && !cpustate->haltreq)
        {
 //#ifdef USE_DEBUGGER
                bool now_debugging = false;
@@ -588,8 +623,10 @@ CPU_EXECUTE( i80186 )
                        TABLE186;
                        cpustate->total_icount += first_icount - cpustate->icount;
 //#ifdef SINGLE_MODE_DMA
-                       if (cpustate->dma != NULL) {
-                               cpustate->dma->do_dma();
+                       if(!cpustate->haltreq) {
+                               if (cpustate->dma != NULL) {
+                                       cpustate->dma->do_dma();
+                               }
                        }
 //#endif
                        if(now_debugging) {
@@ -612,8 +649,10 @@ CPU_EXECUTE( i80186 )
                        cpustate->total_icount += first_icount - cpustate->icount;
 //#endif
 //#ifdef SINGLE_MODE_DMA
-                       if (cpustate->dma != NULL) {
-                               cpustate->dma->do_dma();
+                       if(!cpustate->haltreq) {
+                               if (cpustate->dma != NULL) {
+                                       cpustate->dma->do_dma();
+                               }
                        }
 //#endif
 //#ifdef USE_DEBUGGER
@@ -628,7 +667,7 @@ CPU_EXECUTE( i80186 )
        }
 
        /* if busreq is raised, spin cpu while remained clock */
-       if (cpustate->icount > 0 && cpustate->busreq) {
+       if (cpustate->icount > 0 && (cpustate->busreq || cpustate->haltreq)) {
 //#ifdef USE_DEBUGGER
                cpustate->total_icount += cpustate->icount;
 //#endif
index cd9b257..f03bdf3 100644 (file)
@@ -91,16 +91,99 @@ enum BREGS {
 #define DF                  (int)(cpustate->DirVal < 0)
 
 /************************************************************************/
+#ifdef I80286
+inline __FASTCALL uint32_t read_mem_byte(i80286_state *cpustate, uint32_t a)
+#else
+inline __FASTCALL uint32_t read_mem_byte(i8086_state *cpustate, uint32_t a)
+#endif
+{
+       int w;
+       uint32_t r = cpustate->program->read_data8w(a, &w);
+       cpustate->memory_wait += w;
+       return r;
+}
+
+#ifdef I80286
+inline __FASTCALL uint32_t read_mem_word(i80286_state *cpustate, uint32_t a)
+#else
+inline __FASTCALL uint32_t read_mem_word(i8086_state *cpustate, uint32_t a)
+#endif
+{
+       int w;
+       uint32_t r = cpustate->program->read_data16w(a, &w);
+       cpustate->memory_wait += w;
+       return r;
+}
+
+#ifdef I80286
+inline __FASTCALL void write_mem_byte(i80286_state *cpustate, uint32_t a, uint32_t b)
+#else
+inline __FASTCALL void write_mem_byte(i8086_state *cpustate, uint32_t a, uint32_t b)
+#endif 
+{
+       int w;
+       cpustate->program->write_data8w(a, b, &w);
+       cpustate->memory_wait += w;
+}
+
+#ifdef I80286
+inline __FASTCALL void write_mem_word(i80286_state *cpustate, uint32_t a, uint32_t b)
+#else
+inline __FASTCALL void write_mem_word(i8086_state *cpustate, uint32_t a, uint32_t b)
+#endif 
+{
+       int w;
+       cpustate->program->write_data16w(a, b, &w);
+       cpustate->memory_wait += w;
+}
+
+#ifdef I80286
+inline __FASTCALL uint32_t read_port_byte(i80286_state *cpustate, uint32_t a)
+#else
+inline __FASTCALL uint32_t read_port_byte(i8086_state *cpustate, uint32_t a)
+#endif
+{
+       int w;
+       uint32_t r = cpustate->io->read_io8w(a, &w);
+       cpustate->memory_wait += w;
+       return r;
+}
+
+#ifdef I80286
+inline __FASTCALL uint32_t read_port_word(i80286_state *cpustate, uint32_t a)
+#else
+inline __FASTCALL uint32_t read_port_word(i8086_state *cpustate, uint32_t a)
+#endif
+{
+       int w;
+       uint32_t r = cpustate->io->read_io16w(a, &w);
+       cpustate->memory_wait += w;
+       return r;
+}
+
+#ifdef I80286
+inline __FASTCALL void write_port_byte(i80286_state *cpustate, uint32_t a, uint32_t b)
+#else
+inline __FASTCALL void write_port_byte(i8086_state *cpustate, uint32_t a, uint32_t b)
+#endif
+{
+       int w;
+       cpustate->io->write_io8w(a, b, &w);
+       cpustate->memory_wait += w;
+}
+
+#ifdef I80286
+inline __FASTCALL void write_port_word(i80286_state *cpustate, uint32_t a, uint32_t b)
+#else
+inline __FASTCALL void write_port_word(i8086_state *cpustate, uint32_t a, uint32_t b)
+#endif
+{
+       int w;
+       cpustate->io->write_io16w(a, b, &w);
+       cpustate->memory_wait += w;
+}
 
-#define read_mem_byte(a)            cpustate->program->read_data8(a)
-#define read_mem_word(a)            cpustate->program->read_data16(a)
-#define write_mem_byte(a,d)         cpustate->program->write_data8((a),(d))
-#define write_mem_word(a,d)         cpustate->program->write_data16((a),(d))
 
-#define read_port_byte(a)       cpustate->io->read_io8(a)
-#define read_port_word(a)       cpustate->io->read_io16(a)
-#define write_port_byte(a,d)    cpustate->io->write_io8((a),(d))
-#define write_port_word(a,d)    cpustate->io->write_io16((a),(d))
 
 /************************************************************************/
 
@@ -110,22 +193,22 @@ enum BREGS {
 #define DefaultBase(Seg)        ((cpustate->seg_prefix && (Seg == DS || Seg == SS)) ? cpustate->base[cpustate->prefix_seg] : cpustate->base[Seg])
 
 #ifdef I80286
-#define GetMemB(Seg,Off)        (read_mem_byte(GetMemAddr(cpustate,Seg,Off,1,I80286_READ)))
-#define GetMemW(Seg,Off)        (read_mem_word(GetMemAddr(cpustate,Seg,Off,2,I80286_READ)))
-#define PutMemB(Seg,Off,x)      write_mem_byte(GetMemAddr(cpustate,Seg,Off,1,I80286_WRITE), (x))
-#define PutMemW(Seg,Off,x)      write_mem_word(GetMemAddr(cpustate,Seg,Off,2,I80286_WRITE), (x))
+#define GetMemB(Seg,Off)        (read_mem_byte(cpustate, GetMemAddr(cpustate,Seg,Off,1,I80286_READ)))
+#define GetMemW(Seg,Off)        (read_mem_word(cpustate, GetMemAddr(cpustate,Seg,Off,2,I80286_READ)))
+#define PutMemB(Seg,Off,x)      write_mem_byte(cpustate, GetMemAddr(cpustate,Seg,Off,1,I80286_WRITE), (x))
+#define PutMemW(Seg,Off,x)      write_mem_word(cpustate, GetMemAddr(cpustate,Seg,Off,2,I80286_WRITE), (x))
 #else
-#define GetMemB(Seg,Off)        (read_mem_byte((DefaultBase(Seg) + (Off)) & AMASK))
-#define GetMemW(Seg,Off)        (read_mem_word((DefaultBase(Seg) + (Off)) & AMASK))
-#define PutMemB(Seg,Off,x)      write_mem_byte((DefaultBase(Seg) + (Off)) & AMASK, (x))
-#define PutMemW(Seg,Off,x)      write_mem_word((DefaultBase(Seg) + (Off)) & AMASK, (x))
+#define GetMemB(Seg,Off)        (read_mem_byte(cpustate, (DefaultBase(Seg) + (Off)) & AMASK))
+#define GetMemW(Seg,Off)        (read_mem_word(cpustate, (DefaultBase(Seg) + (Off)) & AMASK))
+#define PutMemB(Seg,Off,x)      write_mem_byte(cpustate, (DefaultBase(Seg) + (Off)) & AMASK, (x))
+#define PutMemW(Seg,Off,x)      write_mem_word(cpustate, (DefaultBase(Seg) + (Off)) & AMASK, (x))
 #endif
 
-#define PEEKBYTE(ea)            (read_mem_byte((ea) & AMASK))
-#define ReadByte(ea)            (read_mem_byte((ea) & AMASK))
-#define ReadWord(ea)            (read_mem_word((ea) & AMASK))
-#define WriteByte(ea,val)       write_mem_byte((ea) & AMASK, val);
-#define WriteWord(ea,val)       write_mem_word((ea) & AMASK, val);
+#define PEEKBYTE(ea)            (read_mem_byte(cpustate, (ea) & AMASK))
+#define ReadByte(ea)            (read_mem_byte(cpustate, (ea) & AMASK))
+#define ReadWord(ea)            (read_mem_word(cpustate, (ea) & AMASK))
+#define WriteByte(ea,val)       write_mem_byte(cpustate, (ea) & AMASK, val);
+#define WriteWord(ea,val)       write_mem_word(cpustate, (ea) & AMASK, val);
 
 #define FETCH                   (cpustate->program->read_data8(cpustate->pc++))
 #define FETCHOP                 (cpustate->program->read_data8(cpustate->pc++))
index aa3cfe9..a81dd0d 100644 (file)
@@ -110,7 +110,7 @@ static void PREFIX186(_insb)(i8086_state *cpustate)    /* Opcode 0x6c */
        if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
 #endif
        ICOUNT -= timing.ins8;
-       PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
+       PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate, cpustate->regs.w[DX]));
        cpustate->regs.w[DI] += cpustate->DirVal;
 }
 
@@ -120,7 +120,7 @@ static void PREFIX186(_insw)(i8086_state *cpustate)    /* Opcode 0x6d */
        if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
 #endif
        ICOUNT -= timing.ins16;
-       PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
+       PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate, cpustate->regs.w[DX]));
        cpustate->regs.w[DI] += 2 * cpustate->DirVal;
 }
 
@@ -130,7 +130,7 @@ static void PREFIX186(_outsb)(i8086_state *cpustate)    /* Opcode 0x6e */
        if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
 #endif
        ICOUNT -= timing.outs8;
-       write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
+       write_port_byte(cpustate, cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
        cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
 }
 
@@ -140,7 +140,7 @@ static void PREFIX186(_outsw)(i8086_state *cpustate)    /* Opcode 0x6f */
        if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
 #endif
        ICOUNT -= timing.outs16;
-       write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
+       write_port_word(cpustate, cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
        cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
 }
 
index f0669e0..5043ee2 100644 (file)
@@ -456,7 +456,7 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
                while(cpustate->regs.w[CX])
                {
 //                     if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
-                       PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
+                       PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate, cpustate->regs.w[DX]));
                        cpustate->regs.w[CX]--;
                        cpustate->regs.w[DI] += cpustate->DirVal;
                        ICOUNT -= timing.rep_ins8_count;
@@ -472,7 +472,7 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
                while(cpustate->regs.w[CX])
                {
 //                     if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
-                       PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
+                       PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate, cpustate->regs.w[DX]));
                        cpustate->regs.w[CX]--;
                        cpustate->regs.w[DI] += 2 * cpustate->DirVal;
                        ICOUNT -= timing.rep_ins16_count;
@@ -488,7 +488,7 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
                while(cpustate->regs.w[CX])
                {
 //                     if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
-                       write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
+                       write_port_byte(cpustate, cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
                        cpustate->regs.w[CX]--;
                        cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
                        ICOUNT -= timing.rep_outs8_count;
@@ -504,7 +504,7 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
                while(cpustate->regs.w[CX])
                {
 //                     if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
-                       write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
+                       write_port_word(cpustate, cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
                        cpustate->regs.w[CX]--;
                        cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
                        ICOUNT -= timing.rep_outs16_count;
@@ -2623,7 +2623,7 @@ static void PREFIX86(_inal)(i8086_state *cpustate)    /* Opcode 0xe4 */
        port = FETCH;
 
        ICOUNT -= timing.in_imm8;
-       cpustate->regs.b[AL] = read_port_byte(port);
+       cpustate->regs.b[AL] = read_port_byte(cpustate, port);
 }
 
 static void PREFIX86(_inax)(i8086_state *cpustate)    /* Opcode 0xe5 */
@@ -2635,7 +2635,7 @@ static void PREFIX86(_inax)(i8086_state *cpustate)    /* Opcode 0xe5 */
        port = FETCH;
 
        ICOUNT -= timing.in_imm16;
-       cpustate->regs.w[AX] = read_port_word(port);
+       cpustate->regs.w[AX] = read_port_word(cpustate, port);
 }
 
 static void PREFIX86(_outal)(i8086_state *cpustate)    /* Opcode 0xe6 */
@@ -2647,7 +2647,7 @@ static void PREFIX86(_outal)(i8086_state *cpustate)    /* Opcode 0xe6 */
        port = FETCH;
 
        ICOUNT -= timing.out_imm8;
-       write_port_byte(port, cpustate->regs.b[AL]);
+       write_port_byte(cpustate, port, cpustate->regs.b[AL]);
 }
 
 static void PREFIX86(_outax)(i8086_state *cpustate)    /* Opcode 0xe7 */
@@ -2659,7 +2659,7 @@ static void PREFIX86(_outax)(i8086_state *cpustate)    /* Opcode 0xe7 */
        port = FETCH;
 
        ICOUNT -= timing.out_imm16;
-       write_port_word(port, cpustate->regs.w[AX]);
+       write_port_word(cpustate, port, cpustate->regs.w[AX]);
 }
 
 static void PREFIX86(_call_d16)(i8086_state *cpustate)    /* Opcode 0xe8 */
@@ -2722,7 +2722,7 @@ static void PREFIX86(_inaldx)(i8086_state *cpustate)    /* Opcode 0xec */
        if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
 #endif
        ICOUNT -= timing.in_dx8;
-       cpustate->regs.b[AL] = read_port_byte(cpustate->regs.w[DX]);
+       cpustate->regs.b[AL] = read_port_byte(cpustate, cpustate->regs.w[DX]);
 }
 
 static void PREFIX86(_inaxdx)(i8086_state *cpustate)    /* Opcode 0xed */
@@ -2732,7 +2732,7 @@ static void PREFIX86(_inaxdx)(i8086_state *cpustate)    /* Opcode 0xed */
        if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
 #endif
        ICOUNT -= timing.in_dx16;
-       cpustate->regs.w[AX] = read_port_word(port);
+       cpustate->regs.w[AX] = read_port_word(cpustate, port);
 }
 
 static void PREFIX86(_outdxal)(i8086_state *cpustate)    /* Opcode 0xee */
@@ -2741,7 +2741,7 @@ static void PREFIX86(_outdxal)(i8086_state *cpustate)    /* Opcode 0xee */
        if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
 #endif
        ICOUNT -= timing.out_dx8;
-       write_port_byte(cpustate->regs.w[DX], cpustate->regs.b[AL]);
+       write_port_byte(cpustate, cpustate->regs.w[DX], cpustate->regs.b[AL]);
 }
 
 static void PREFIX86(_outdxax)(i8086_state *cpustate)    /* Opcode 0xef */
@@ -2751,7 +2751,7 @@ static void PREFIX86(_outdxax)(i8086_state *cpustate)    /* Opcode 0xef */
        if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
 #endif
        ICOUNT -= timing.out_dx16;
-       write_port_word(port, cpustate->regs.w[AX]);
+       write_port_word(cpustate, port, cpustate->regs.w[AX]);
 }
 
 /* I think thats not a V20 instruction...*/
index 47573c9..151fa54 100644 (file)
@@ -8,7 +8,7 @@
 //#include "debugger.h"
 
 //#include "host.h"
-#include "i86priv.h"
+//#include "i86priv.h"
 #include "i86.h"
 
 static int i386_dasm_one(_TCHAR *buffer, UINT32 eip, const UINT8 *oprom, int mode);
@@ -49,6 +49,7 @@ struct i8086_state
        INT32 extra_cycles;       /* extra cycles for interrupts */
 
        int halted;         /* Is the CPU halted ? */
+       int haltreq;
        int busreq;
 
        UINT16 ip;
@@ -75,6 +76,7 @@ struct i8086_state
        int icount;
        uint32_t waitfactor;
        uint32_t waitcount;
+       int32_t memory_wait;
        
        //char seg_prefix;                   /* prefix segment indicator */
        UINT8 seg_prefix;                   /* prefix segment indicator */
@@ -84,6 +86,8 @@ struct i8086_state
        UINT8 ea_seg;   /* effective segment of the address */
 };
 
+#undef I80286
+#include "i86priv.h"
 #include "i86time.c"
 
 /***************************************************************************/
@@ -182,6 +186,8 @@ static CPU_INIT( i8086 )
                Mod_RM.RM.w[i] = (WREGS) (i & 7);
                Mod_RM.RM.b[i] = (BREGS) reg_name[i & 7];
        }
+       cpustate->waitfactor = 65536;
+       cpustate->haltreq = 0;
        return cpustate;
 }
 
@@ -201,6 +207,7 @@ static CPU_RESET( i8086 )
        int extra_cycles = cpustate->extra_cycles;
        int halted = cpustate->halted;
        int busreq = cpustate->busreq;
+       int haltreq = cpustate->haltreq;
        
        memset(cpustate, 0, sizeof(*cpustate));
 
@@ -214,10 +221,12 @@ static CPU_RESET( i8086 )
        cpustate->prev_total_icount = prev_total_icount;
 //#endif
        cpustate->waitcount = 0;
+       cpustate->memory_wait = 0;
        cpustate->icount = icount;
        cpustate->extra_cycles = extra_cycles;
        cpustate->halted = halted;
        cpustate->busreq = busreq;
+       cpustate->haltreq = haltreq;
 }
 
 static CPU_RESET( v30 )
@@ -231,6 +240,11 @@ static CPU_RESET( v30 )
 static void set_irq_line(i8086_state *cpustate, int irqline, int state)
 {
        int first_icount = cpustate->icount;
+       if (cpustate->haltreq != 0) {
+               cpustate->extra_cycles += first_icount - cpustate->icount;
+               cpustate->icount = first_icount;
+               return;
+       }
 
        if (state != CLEAR_LINE && cpustate->halted)
        {
@@ -282,26 +296,35 @@ static void set_test_line(i8086_state *cpustate, int state)
 
 static void __FASTCALL cpu_wait_v30(cpu_state *cpustate,int clocks)
 {
-       if(clocks < 0) return;
-       if(cpustate->waitfactor == 0) return;
-       uint32_t wcount = cpustate->waitcount;
-       wcount += (cpustate->waitfactor * (uint32_t)clocks);
+       if(clocks <= 0) clocks = 1;
+       int64_t wfactor = cpustate->waitfactor;
+       int64_t wcount = cpustate->waitcount;
+       int64_t mwait = cpustate->memory_wait;
+       int64_t ncount;
+       if(cpustate->waitfactor >= 65536) {
+               wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock.
+       }
+       wcount += (wfactor * mwait);  // memory wait
        if(wcount >= 65536) {
-               uint32_t ncount;
                ncount = wcount >> 16;
                wcount = wcount - (ncount << 16);
-               cpustate->extra_cycles += ncount;
+               cpustate->extra_cycles += (int)ncount;
+       } else if(wcount < 0) {
+               wcount = 0;
        }
        cpustate->waitcount = wcount;
+       cpustate->memory_wait = 0;
 }
 
 CPU_EXECUTE( v30 )
 {
-       if (cpustate->halted || cpustate->busreq)
+       if (cpustate->halted || cpustate->busreq || cpustate->haltreq)
        {
 //#ifdef SINGLE_MODE_DMA
-               if (cpustate->dma != NULL){
-                       cpustate->dma->do_dma();
+               if(!cpustate->haltreq) {
+                       if (cpustate->dma != NULL){
+                               cpustate->dma->do_dma();
+                       }
                }
 //#endif
                bool now_debugging = false;
@@ -379,7 +402,7 @@ CPU_EXECUTE( v30 )
        cpustate->extra_cycles = 0;
 
        /* run until we're out */
-       while (cpustate->icount > 0 && !cpustate->busreq)
+       while (cpustate->icount > 0 && !cpustate->busreq && !cpustate->haltreq)
        {
 //#ifdef USE_DEBUGGER
                bool now_debugging = false;
@@ -409,8 +432,10 @@ CPU_EXECUTE( v30 )
                        TABLEV30;
                        cpustate->total_icount += first_icount - cpustate->icount;
 //#ifdef SINGLE_MODE_DMA
-                       if (cpustate->dma != NULL) {
-                               cpustate->dma->do_dma();
+                       if(!cpustate->haltreq) {
+                               if (cpustate->dma != NULL) {
+                                       cpustate->dma->do_dma();
+                               }
                        }
 //#endif
                        if(now_debugging) {
@@ -433,8 +458,10 @@ CPU_EXECUTE( v30 )
                        cpustate->total_icount += first_icount - cpustate->icount;
 //#endif
 //#ifdef SINGLE_MODE_DMA
-                       if (cpustate->dma != NULL) {
-                               cpustate->dma->do_dma();
+                       if(!cpustate->haltreq) {
+                               if (cpustate->dma != NULL) {
+                                       cpustate->dma->do_dma();
+                               }
                        }
 //#endif
 //#ifdef USE_DEBUGGER
@@ -449,7 +476,7 @@ CPU_EXECUTE( v30 )
        }
 
        /* if busreq is raised, spin cpu while remained clock */
-       if (cpustate->icount > 0 && cpustate->busreq) {
+       if (cpustate->icount > 0 && (cpustate->busreq || cpustate->haltreq)) {
 //#ifdef USE_DEBUGGER
                cpustate->total_icount += cpustate->icount;
 //#endif
index 656f280..2c5b3be 100644 (file)
@@ -235,6 +235,7 @@ void MEMORY::write_data32w(uint32_t addr, uint32_t data, int* wait)
 }
 
 #ifdef MEMORY_DISABLE_DMA_MMIO
+
 uint32_t MEMORY::read_dma_data8(uint32_t addr)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
index 74e858e..024ba80 100644 (file)
@@ -55,8 +55,6 @@ void V30::initialize()
                d_debugger->set_context_mem(d_mem);
                d_debugger->set_context_io(d_io);
        }
-       cpustate->waitfactor = 0;
-       cpustate->waitcount = 0;
 }
 
 void V30::release()
@@ -67,6 +65,7 @@ void V30::reset()
 {
        cpu_state *cpustate = (cpu_state *)opaque;
        int busreq = cpustate->busreq;
+       int haltreq = cpustate->haltreq;
 
        CPU_RESET_CALL( v30 );
        
@@ -86,6 +85,7 @@ void V30::reset()
        cpustate->io_stored = d_io;
 //#endif
        cpustate->busreq = busreq;
+       cpustate->haltreq = haltreq;
 }
 
 int V30::run(int icount)