[VM][Ix86][I386] Implement wait by memory-wait-factor.
[VM][Ix86][I386] Add SIG_CPU_HALTREQ.
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
d_debugger->set_context_mem(d_mem);
d_debugger->set_context_io(d_io);
}
- cpustate->waitfactor = 0;
- cpustate->waitcount = 0;
}
void I80286::release()
{
cpu_state *cpustate = (cpu_state *)opaque;
int busreq = cpustate->busreq;
+ int haltreq = cpustate->haltreq;
CPU_RESET_CALL(i80286);
cpustate->program_stored = d_mem;
cpustate->io_stored = d_io;
cpustate->busreq = busreq;
+ cpustate->haltreq = haltreq;
}
int I80286::run(int icount)
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) {
return cpustate->shutdown;
}
-#define STATE_VERSION 7
+#define STATE_VERSION 8
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);
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->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()
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) {
return cpustate->shutdown;
}
-#define STATE_VERSION 7
+#define STATE_VERSION 8
void process_state_SREG(I386_SREG* val, FILEIO* state_fio)
{
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);
d_debugger->set_context_mem(d_mem);
d_debugger->set_context_io(d_io);
//#endif
- cpustate->waitfactor = 0;
- cpustate->waitcount = 0;
}
void I80286::release()
return cpustate->shutdown;
}
-#define STATE_VERSION 6
+#define STATE_VERSION 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;
d_debugger->set_context_mem(d_mem);
d_debugger->set_context_io(d_io);
}
- cpustate->waitfactor = 0;
- cpustate->waitcount = 0;
}
void I8086::release()
{
cpu_state *cpustate = (cpu_state *)opaque;
int busreq = cpustate->busreq;
+ int haltreq = cpustate->haltreq;
cpu_reset_generic();
cpustate->io_stored = d_io;
//#endif
cpustate->busreq = busreq;
+ cpustate->haltreq = haltreq;
}
int I8086::run(int icount)
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) {
}
-#define STATE_VERSION 7
+#define STATE_VERSION 8
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
d_debugger->set_context_mem(d_mem);
d_debugger->set_context_io(d_io);
#endif
- cpustate->waitfactor = 0;
- cpustate->waitcount = 0;
}
void I286::release()
{
cpu_state *cpustate = (cpu_state *)opaque;
int busreq = cpustate->busreq;
+ int haltreq = cpustate->haltreq;
CPU_RESET_CALL(CPU_MODEL);
cpustate->io_stored = d_io;
#endif
cpustate->busreq = busreq;
+ cpustate->haltreq = haltreq;
}
int I286::run(int icount)
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
}
#endif
-#define STATE_VERSION 6
+#define STATE_VERSION 8
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
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
zero_state(cpustate);
cpustate->halted = 0;
+ cpustate->haltreq = 0;
cpustate->busreq = 0;
-
+ cpustate->waitfactor = 65536;
return 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;
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;
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;
//#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 */
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 */
}
/* 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
int halted;
int busreq;
+ int haltreq;
int shutdown;
int operand_size;
//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) { \
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;
int halted = cpustate->halted;
int busreq = cpustate->busreq;
+ int haltreq = cpustate->haltreq;
memset(&cpustate->regs, 0, sizeof(i80286basicregs));
cpustate->sregs[CS] = 0xf000;
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;
}
/****************************************************************************/
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)
{
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;
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;
}
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) {
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
}
/* 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
cpustate->amask = 0xfffff;
i80286_urinit();
-
+ cpustate->waitfactor = 65536;
return cpustate;
}
//#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);
INT32 extra_cycles; /* extra cycles for interrupts */
int halted; /* Is the CPU halted ? */
+ int haltreq;
int busreq;
UINT16 ip;
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 */
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"
Mod_RM.RM.w[i] = (WREGS) (i & 7);
Mod_RM.RM.b[i] = (BREGS) reg_name[i & 7];
}
+ cpustate->waitfactor = 65536;
return cpustate;
}
int extra_cycles = cpustate->extra_cycles;
int halted = cpustate->halted;
int busreq = cpustate->busreq;
+ int haltreq = cpustate->haltreq;
memset(cpustate, 0, sizeof(*cpustate));
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 )
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)
{
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;
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;
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) {
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
}
/* 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
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;
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;
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) {
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
}
/* 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
#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))
/************************************************************************/
#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++))
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;
}
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;
}
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 */
}
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 */
}
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;
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;
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;
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;
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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...*/
//#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);
INT32 extra_cycles; /* extra cycles for interrupts */
int halted; /* Is the CPU halted ? */
+ int haltreq;
int busreq;
UINT16 ip;
int icount;
uint32_t waitfactor;
uint32_t waitcount;
+ int32_t memory_wait;
//char seg_prefix; /* prefix segment indicator */
UINT8 seg_prefix; /* prefix segment indicator */
UINT8 ea_seg; /* effective segment of the address */
};
+#undef I80286
+#include "i86priv.h"
#include "i86time.c"
/***************************************************************************/
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;
}
int extra_cycles = cpustate->extra_cycles;
int halted = cpustate->halted;
int busreq = cpustate->busreq;
+ int haltreq = cpustate->haltreq;
memset(cpustate, 0, sizeof(*cpustate));
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 )
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)
{
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;
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;
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) {
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
}
/* 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
}
#ifdef MEMORY_DISABLE_DMA_MMIO
+
uint32_t MEMORY::read_dma_data8(uint32_t addr)
{
int bank = (addr & ADDR_MASK) >> addr_shift;
d_debugger->set_context_mem(d_mem);
d_debugger->set_context_io(d_io);
}
- cpustate->waitfactor = 0;
- cpustate->waitcount = 0;
}
void V30::release()
{
cpu_state *cpustate = (cpu_state *)opaque;
int busreq = cpustate->busreq;
+ int haltreq = cpustate->haltreq;
CPU_RESET_CALL( v30 );
cpustate->io_stored = d_io;
//#endif
cpustate->busreq = busreq;
+ cpustate->haltreq = haltreq;
}
int V30::run(int icount)