[VM][DEVICE][I386][I286] Add total_icount via read_signal().To implement PC-9801's clock counter.
[VM][PC9801][I386][I286] Add variable (main) CPU clock via CPU's write_signal().Add cpu_wait_foo() with CPU_EXECUTE(foo) .
[VM][PC9801][MEMORY] Fix wrong copy_table_[r|w]().
[VM][PC9801][SASI_BIOS] Remove redirection.
[VM][PC9801][MEMBUS] Remove read_data8() and write_data8() for i286 VMs.
message("* vm/common_vm")
-SET(THIS_LIB_VERSION 2.13.0)
+SET(THIS_LIB_VERSION 2.14.0)
#include(cotire)
set(s_vm_common_vm_srcs
#define SIG_CPU_HALTREQ 105
#define SIG_CPU_DEBUG 106
#define SIG_CPU_ADDRESS_DIRTY 107
+#define SIG_CPU_TOTAL_CYCLE_LO 108
+#define SIG_CPU_TOTAL_CYCLE_HI 109
+#define SIG_CPU_WAIT_FACTOR 110
#define SIG_PRINTER_DATA 201
#define SIG_PRINTER_STROBE 202
d_debugger->set_context_mem(d_mem);
d_debugger->set_context_io(d_io);
#endif
+ cpustate->waitfactor = 0;
+ cpustate->waitcount = 0;
}
void I286::release()
return CPU_EXECUTE_CALL(CPU_MODEL);
}
+uint32_t I286::read_signal(int id)
+{
+ if((id == SIG_CPU_TOTAL_CYCLE_HI) || (id == SIG_CPU_TOTAL_CYCLE_LO)) {
+ cpu_state *cpustate = (cpu_state *)opaque;
+ pair64_t n;
+ if(cpustate != NULL) {
+ n.q = cpustate->total_icount;
+ } else {
+ n.q = 0;
+ }
+ if(id == SIG_CPU_TOTAL_CYCLE_HI) {
+ return n.d.h;
+ } else {
+ return n.d.l;
+ }
+ }
+ return 0;
+}
+
void I286::write_signal(int id, uint32_t data, uint32_t mask)
{
cpu_state *cpustate = (cpu_state *)opaque;
} else if(id == SIG_I286_A20) {
i80286_set_a20_line(cpustate, data & mask);
#endif
+ } else if(id == SIG_CPU_WAIT_FACTOR) {
+ cpustate->waitfactor = data; // 65536.
+ cpustate->waitcount = 0; // 65536.
}
}
}
#endif
-#define STATE_VERSION 5
+#define STATE_VERSION 6
bool I286::process_state(FILEIO* state_fio, bool loading)
{
state_fio->StateValue(cpustate->ea);
state_fio->StateValue(cpustate->eo);
state_fio->StateValue(cpustate->ea_seg);
+ state_fio->StateValue(cpustate->waitfactor);
+ state_fio->StateValue(cpustate->waitcount);
#elif defined(HAS_I286)
state_fio->StateArray(cpustate->regs.w, sizeof(cpustate->regs.w), 1);
state_fio->StateValue(cpustate->amask);
state_fio->StateValue(cpustate->ea);
state_fio->StateValue(cpustate->eo);
state_fio->StateValue(cpustate->ea_seg);
+ state_fio->StateValue(cpustate->waitfactor);
+ state_fio->StateValue(cpustate->waitcount);
#endif
#ifdef USE_DEBUGGER
void release();
void reset();
int run(int icount);
+ uint32_t read_signal(int id);
void write_signal(int id, uint32_t data, uint32_t mask);
void set_intr_line(bool line, bool pending, uint32_t bit);
void set_extra_clock(int icount);
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()
}
int I386::run(int cycles)
-{
- i386_state *cpustate = (i386_state *)opaque;
+{ i386_state *cpustate = (i386_state *)opaque;
return CPU_EXECUTE_CALL(i386); // OK?
}
+uint32_t I386::read_signal(int id)
+{
+ if((id == SIG_CPU_TOTAL_CYCLE_HI) || (id == SIG_CPU_TOTAL_CYCLE_LO)) {
+ i386_state *cpustate = (i386_state *)opaque;
+ pair64_t n;
+ if(cpustate != NULL) {
+ n.q = cpustate->total_cycles;
+ } else {
+ n.q = 0;
+ }
+ if(id == SIG_CPU_TOTAL_CYCLE_HI) {
+ return n.d.h;
+ } else {
+ return n.d.l;
+ }
+ }
+ return 0;
+}
+
void I386::write_signal(int id, uint32_t data, uint32_t mask)
{
i386_state *cpustate = (i386_state *)opaque;
i386_set_a20_line(cpustate, data & mask);
} else if(id == SIG_I386_NOTIFY_RESET) {
write_signals(&outputs_extreset, ((data & mask == 0) ? 0x00000000 : 0xffffffff));
+ } else if(id == SIG_CPU_WAIT_FACTOR) {
+ cpustate->waitfactor = data; // 65536.
+ cpustate->waitcount = 0; // 65536.
}
}
return cpustate->shutdown;
}
-#define STATE_VERSION 5
+#define STATE_VERSION 6
void process_state_SREG(I386_SREG* val, FILEIO* state_fio)
{
state_fio->StateValue(cpustate->smbase);
// state_fio->StateValue(cpustate->smiact);
state_fio->StateValue(cpustate->lock);
+
+ state_fio->StateValue(cpustate->waitcount);
+ state_fio->StateValue(cpustate->waitfactor);
#ifdef DEBUG_MISSING_OPCODE
state_fio->StateArray(cpustate->opcode_bytes, sizeof(cpustate->opcode_bytes), 1);
state_fio->StateValue(cpustate->opcode_pc);
void release();
void reset();
int run(int cycles);
+ uint32_t read_signal(int id);
void write_signal(int id, uint32_t data, uint32_t mask);
void set_intr_line(bool line, bool pending, uint32_t bit);
void set_extra_clock(int cycles);
#define SIG_CPU_HALTREQ 105
#define SIG_CPU_DEBUG 106
#define SIG_CPU_ADDRESS_DIRTY 107
+#define SIG_CPU_TOTAL_CYCLE_LO 108
+#define SIG_CPU_TOTAL_CYCLE_HI 109
+#define SIG_CPU_WAIT_FACTOR 110
#define SIG_PRINTER_DATA 201
#define SIG_PRINTER_STROBE 202
int entry = irq * (PROTECTED_MODE ? 8 : 4);
int SetRPL = 0;
cpustate->lock = false;
- if( !PROTECTED_MODE /*|| (V8086_MODE)*/)
+ if( !(PROTECTED_MODE) /*|| (V8086_MODE)*/)
{
/* 16-bit */
//try {
UINT8 CPL = cpustate->CPL, DPL; //, RPL = 0;
/* 32-bit */
- //try {
- v1 = READ32PL0(cpustate, cpustate->idtr.base + entry );
- v2 = READ32PL0(cpustate, cpustate->idtr.base + entry + 4 );
- //} catch(UINT64 e) {
- // logerror("Irregular exception happened %08x for protected mode.\n", e);
- //} catch(UINT32 e) {
- // logerror("Irregular exception happened %08x for protected mode.\n", e);
- //}
+ v1 = READ32PL0(cpustate, cpustate->idtr.base + entry );
+ v2 = READ32PL0(cpustate, cpustate->idtr.base + entry + 4 );
offset = (v2 & 0xffff0000) | (v1 & 0xffff);
segment = (v1 >> 16) & 0xffff;
type = (v2>>8) & 0x1F;
cpustate->sreg[DS].selector = 0;
cpustate->sreg[ES].selector = 0;
cpustate->VM = 0;
- //cpustate->eflags = get_flags(cpustate);
- //cpustate->eflags &= ~I386_EFLAGS_VM; // Clear VM flag
- //set_flags(cpustate, cpustate->eflags);
+ cpustate->eflags = get_flags(cpustate);
i386_load_segment_descriptor(cpustate,GS);
i386_load_segment_descriptor(cpustate,FS);
i386_load_segment_descriptor(cpustate,DS);
try
{
// this is ugly but the alternative is worse
- if(/*type != 0x0e && type != 0x0f */(type & 0x08) == 0) // if not 386 interrupt or trap gate
+ //if(/*type != 0x0e && type != 0x0f */(type & 0x08) == 0) // if not 386 interrupt or trap gate
+ if(type != 0x0e && type != 0x0f) // if not 386 interrupt or trap gate
{
PUSH16(cpustate, oldflags & 0xffff );
PUSH16(cpustate, cpustate->sreg[CS].selector );
}
else
{
- PUSH32(cpustate, oldflags /*& 0x00ffffff */);
+ //PUSH32(cpustate, oldflags /*& 0x00ffffff */);
+ PUSH32(cpustate, oldflags & 0x00ffffff);
PUSH32SEG(cpustate, cpustate->sreg[CS].selector );
if(irq == 3 || irq == 4 || irq == 9 || irq_gate == 1)
PUSH32(cpustate, cpustate->eip );
CHANGE_PC(cpustate,cpustate->eip);
cpustate->CPL = (cpustate->sreg[SS].flags >> 5) & 3;
UINT32 _newCPL = cpustate->CPL;
- //if(_oldCPL != _newCPL) logerror("I286 TASK SWITCH: Privilege changed from %d to %d at ADDR %08X to %08X\n", _oldCPL, _newCPL, _oldPC, cpustate->pc);
+ //if(_oldCPL != _newCPL) logerror("I286 TASK SWITCH: Privilege changed from %d to %d at ADDR %08X to %08X\n", _oldCPL, _newCPL, _oldPC, cpustate->prev_pc);
logerror("80286 Task Switch from selector %04x to %04x\n",old_task,selector);
}
cpustate->CPL = (cpustate->sreg[SS].flags >> 5) & 3;
UINT32 _newCPL = cpustate->CPL;
- if(_oldCPL != _newCPL) logerror("I80386 TASK SWITCH: Privilege changed from %d to %d at ADDR %08X to %08X\n", _oldCPL, _newCPL, _oldPC, cpustate->pc);
+ //if(_oldCPL != _newCPL) logerror("I80386 TASK SWITCH: Privilege changed from %d to %d at ADDR %08X to %08X\n", _oldCPL, _newCPL, _oldPC, cpustate->prev_pc);
logerror("i386 Task Switch from selector %04x to %04x\n",old_task,selector);
}
UINT32 _oldCPL = cpustate->CPL;
cpustate->CPL = (stack.flags >> 5) & 0x03;
UINT32 _newCPL = cpustate->CPL;
- if(_oldCPL != _newCPL) logerror("Privilege changed by protected mode call from %d to %d ADDR %08X\n", _oldCPL, _newCPL, cpustate->pc);
+ //if(_oldCPL != _newCPL) logerror("Privilege changed by protected mode call from %d to %d ADDR %08X\n", _oldCPL, _newCPL, cpustate->pc);
/* check for page fault at new stack */
WRITE_TEST(cpustate, stack.base+newESP-1);
/* switch to new stack */
UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
UINT32 stack_size = 6;
CPL = cpustate->CPL;
- //UINT32 ea = i386_translate(cpustate, SS, (STACK_32BIT)?REG32(ESP):REG16(SP), 0, (operand32)?12:6);
- UINT32 ea = i386_translate(cpustate, SS, (STACK_32BIT)?REG32(ESP):REG16(SP), 0, 1);
+ UINT32 ea = i386_translate(cpustate, SS, (STACK_32BIT)?REG32(ESP):REG16(SP), 0, (operand32)?12:6);
+ //UINT32 ea = i386_translate(cpustate, SS, (STACK_32BIT)?REG32(ESP):REG16(SP), 0, 1);
if(operand32 == 0)
{
newEIP = READ16(cpustate, ea) & 0xffff;
}
if(operand32 == 0)
{
- //if((newEIP & 0xffff) > cpustate->sreg[CS].limit) {
- // FAULT(FAULT_GP, 0);
- //}
cpustate->eip = newEIP & 0xffff;
cpustate->sreg[CS].selector = newCS & 0xffff;
//i386_load_segment_descriptor(cpustate,CS);
newflags &= ~I386_EFLAGS_IOPL; // IOPL cannot be changed in V86 mode
newflags |= (oldflags & I386_EFLAGS_IOPL);
set_flags(cpustate,(newflags & 0xffff) | (oldflags & ~0xffff));
- //if(STACK_32BIT) {
- //REG32(ESP) += stack_size;
- //} else {
- // REG16(SP) += stack_size;
REG16(SP) += 6;
- //}
}
else
{
- cpustate->sreg[CS].selector = newCS & 0xffff;
- //i386_load_segment_descriptor(cpustate,CS);
- //if(newEIP > cpustate->sreg[CS].limit) {
- // FAULT(FAULT_GP, 0);
- //}
cpustate->eip = newEIP;
+ cpustate->sreg[CS].selector = newCS & 0xffff;
//newflags &= ~(3<<12);
//newflags |= 0x20000 | (((oldflags>>12)&3)<<12); // IOPL and VM cannot be changed in V86 mode
newflags &= ~I386_EFLAGS_IOPL; // IOPL and VM cannot be changed in V86 mode
newflags |= (oldflags & I386_EFLAGS_IOPL) | I386_EFLAGS_VM;
set_flags(cpustate,newflags);
- //if(STACK_32BIT) {
- //REG32(ESP) += stack_size;
- //} else {
- // REG16(SP) += stack_size;
- //}
REG32(ESP) += 12;
-
}
-
}
else if(NESTED_TASK)
{
//logerror("IRET (%08x): Returning to Virtual 8086 mode.\n",cpustate->pc);
if(CPL != 0)
{
- UINT32 oldflags = get_flags(cpustate);
//newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000);
newflags = (newflags & ~I386_EFLAGS_IOPL) | (oldflags & I386_EFLAGS_IOPL);
if(CPL > IOPL) {
cpustate->sreg[DS].selector = POP32(cpustate) & 0xffff;
cpustate->sreg[FS].selector = POP32(cpustate) & 0xffff;
cpustate->sreg[GS].selector = POP32(cpustate) & 0xffff;
+ UINT32 __oldESP = REG32(ESP);
+ UINT32 __oldSS = cpustate->sreg[SS].selector ;
+
REG32(ESP) = newESP; // all 32 bits are loaded
cpustate->sreg[SS].selector = newSS;
i386_load_segment_descriptor(cpustate,ES);
i386_load_segment_descriptor(cpustate,FS);
i386_load_segment_descriptor(cpustate,GS);
i386_load_segment_descriptor(cpustate,SS);
+ UINT8 oldCPL = cpustate->CPL;
cpustate->CPL = 3; // Virtual 8086 tasks are always run at CPL 3
+// if(oldCPL != 3) {
+// I386_SREG desc2, stack2;
+// memset(&desc2, 0x00, sizeof(desc2));
+// memset(&stack2, 0x00, sizeof(stack2));
+// desc2.selector = newCS & 0xffff;
+// i386_load_protected_mode_segment(cpustate,&desc2,NULL);
+// stack2.selector = __oldSS;
+// i386_load_protected_mode_segment(cpustate,&stack2,NULL);
+// logerror("Enter to V8086 mode via IRET() at %08X to %08X NEWFLAGS=%08X FLAGS(CS)%08X SP=%08X:%08X\n", cpustate->prev_pc, cpustate->sreg[CS].base + cpustate->eip, newflags, desc2.flags, stack2.base , __oldESP);
+// }
}
else
{
cpustate->opcode_pc = 0;
cpustate->opcode_bytes_length = 0;
#endif
+ cpustate->waitcount = 0;
+
}
static CPU_RESET( i386 )
vtlb_flush_dynamic(cpustate->vtlb);
}
+static INLINE void cpu_wait_i386(i386_state *cpustate,int clocks)
+{
+ uint64_t ncount = 0;
+ if(clocks <= 0) return;
+ if(cpustate->waitfactor == 0) return;
+ uint64_t wcount = cpustate->waitcount;
+ wcount += (uint64_t)(cpustate->waitfactor * (uint32_t)clocks);
+ if(wcount >= 65536) {
+ ncount = wcount >> 16;
+ wcount = wcount - (ncount << 16);
+ }
+ cpustate->extra_cycles += (int)ncount;
+ cpustate->waitcount = wcount;
+}
+
static CPU_EXECUTE( i386 )
{
CHANGE_PC(cpustate,cpustate->eip);
//#ifdef USE_DEBUGGER
cpustate->total_cycles += passed_cycles;
//#endif
+ cpu_wait_i386(cpustate, passed_cycles);
return passed_cycles;
} else {
cpustate->cycles += cycles;
//#ifdef USE_DEBUGGER
cpustate->total_cycles += passed_cycles;
//#endif
+ cpu_wait_i386(cpustate, passed_cycles);
return passed_cycles;
}
}
}
int passed_cycles = cpustate->base_cycles - cpustate->cycles;
cpustate->tsc += passed_cycles;
+ cpu_wait_i386(cpustate, passed_cycles);
return passed_cycles;
}
static void I386OP(mov_r32_cr)(i386_state *cpustate) // Opcode 0x0f 20
{
#if 1
- UINT32 oldpc = cpustate->pc;
+ UINT32 oldpc = cpustate->prev_pc;
+ if((PROTECTED_MODE && ((V8086_MODE) || (cpustate->CPL != 0)))) {
+ logerror("Call from non-supervisor privilege: I386OP(mov_r32_cr) at %08X", oldpc);
+ FAULT(FAULT_GP, 0);
+ //return;
+ }
UINT8 modrm = FETCH(cpustate);
//if(modrm < 0xc0) {
// FAULT(FAULT_UD, 0);
// return;
//}
UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
- if((PROTECTED_MODE && ((V8086_MODE) || (cpustate->CPL != 0)))) {
- logerror("Call from non-supervisor privilege: I386OP(mov_r32_cr) at %08X", oldpc);
- FAULT(FAULT_GP, 0);
- //return;
- }
UINT8 cr = (modrm >> 3) & 0x7;
//logdebug("MOV r32 CR%d VAL=(%08X)\n", cr, cpustate->cr[cr], oldpc);
// if(cr < 5) {
static void I386OP(mov_cr_r32)(i386_state *cpustate) // Opcode 0x0f 22
{
#if 1
- UINT32 oldpc = cpustate->pc;
+ UINT32 oldpc = cpustate->prev_pc;
+ if(PROTECTED_MODE && ((V8086_MODE) || (cpustate->CPL != 0))) {
+ logerror("Call from non-supervisor privilege: I386OP(mov_cr_r32) at %08X", oldpc);
+ FAULT(FAULT_GP, 0);
+ return;
+ }
UINT8 modrm = FETCH(cpustate);
if(modrm < 0xc0) {
FAULT(FAULT_UD, 0);
return;
}
UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
- if(PROTECTED_MODE && ((V8086_MODE) || (cpustate->CPL != 0))) {
- logerror("Call from non-supervisor privilege: I386OP(mov_cr_r32) at %08X", oldpc);
- FAULT(FAULT_GP, 0);
- return;
- }
UINT8 cr = (modrm >> 3) & 0x7;
UINT32 data = LOAD_RM32(modrm);
{
case 0:
CYCLES(cpustate,CYCLES_MOV_REG_CR0);
-// if (PROTECTED_MODE != BIT(data, 0))
-// debugger_privilege_hook();
+ //if (PROTECTED_MODE != BIT(data, 0))
+ // debugger_privilege_hook();
if((data & (I386_CR0_PE | I386_CR0_PG)) == (UINT32)I386_CR0_PG) {
FAULT(FAULT_GP, 0);
}
UINT32 smbase;
// devcb_resolved_write_line smiact;
bool lock;
+ UINT32 waitfactor;
+ UINT64 waitcount;
// bytes in current opcode, debug only
#ifdef DEBUG_MISSING_OPCODE
if((cpustate->sreg[seg].flags & 0x0018) == 0x0010 && cpustate->sreg[seg].flags & 0x0004) // if expand-down data segment
{
// compare if greater then 0xffffffff when we're passed the access size
- if(offset < size) size = offset;
- if(/*(cpustate->sreg[seg].limit != 0) && */(((offset - size) <= cpustate->sreg[seg].limit) || ((cpustate->sreg[seg].d)?0:((offset + size - 1) > 0xffff))))
+ //if(offset < size) size = offset;
+ if(/*(cpustate->sreg[seg].limit != 0) && */(((offset - (size - 1)) <= 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->prev_pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset);
return 1;
int busreq;
int trap_level;
int shutdown;
+ uint32_t waitfactor;
+ uint32_t waitcount;
#ifdef USE_DEBUGGER
uint64_t total_icount;
cpustate->ldtr.sel=cpustate->tr.sel=0;
cpustate->rep_in_progress = FALSE;
cpustate->seg_prefix = FALSE;
+ cpustate->waitcount = 0;
CHANGE_PC(cpustate->pc);
cpustate->icount = first_icount;
}
+static void 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(wcount >= 65536) {
+ ncount = wcount >> 16;
+ wcount = wcount - (ncount << 16);
+ }
+ cpustate->extra_cycles += ncount;
+ cpustate->waitcount = wcount;
+}
+
static CPU_EXECUTE( i80286 )
{
if (cpustate->halted || cpustate->busreq)
#ifdef USE_DEBUGGER
cpustate->total_icount += passed_icount;
#endif
+ cpu_wait_i286(cpustate,passed_icount);
return passed_icount;
} else {
cpustate->icount += icount;
#ifdef USE_DEBUGGER
cpustate->total_icount += base_icount - cpustate->icount;
#endif
+ cpu_wait_i286(cpustate, base_icount - cpustate->icount);
return base_icount - cpustate->icount;
}
}
#endif
cpustate->icount = 0;
}
+ cpu_wait_i286(cpustate, base_icount - cpustate->icount);
return base_icount - cpustate->icount;
}
uint64_t prev_total_icount;
#endif
int icount;
+ uint32_t waitfactor;
+ uint32_t waitcount;
//char seg_prefix; /* prefix segment indicator */
UINT8 seg_prefix; /* prefix segment indicator */
cpustate->total_icount = total_icount;
cpustate->prev_total_icount = prev_total_icount;
#endif
+ cpustate->waitcount = 0;
cpustate->icount = icount;
cpustate->extra_cycles = extra_cycles;
cpustate->halted = 0;
cpustate->test_state = !state;
}
+static void 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(wcount >= 65536) {
+ ncount = wcount >> 16;
+ wcount = wcount - (ncount << 16);
+ }
+ cpustate->extra_cycles += ncount;
+ cpustate->waitcount = wcount;
+}
+
CPU_EXECUTE( i8086 )
{
if (cpustate->halted || cpustate->busreq)
#ifdef USE_DEBUGGER
cpustate->total_icount += passed_icount;
#endif
+ cpu_wait_i86(cpustate, passed_icount);
return passed_icount;
} else {
cpustate->icount += icount;
#ifdef USE_DEBUGGER
cpustate->total_icount += base_icount - cpustate->icount;
#endif
+ cpu_wait_i86(cpustate, base_icount - cpustate->icount);
return base_icount - cpustate->icount;
}
}
#endif
cpustate->icount = 0;
}
+ cpu_wait_i86(cpustate, base_icount - cpustate->icount);
return base_icount - cpustate->icount;
}
#include "instr186.c"
#undef I80186
+static void cpu_wait_i186(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(wcount >= 65536) {
+ ncount = wcount >> 16;
+ wcount = wcount - (ncount << 16);
+ }
+ cpustate->extra_cycles += ncount;
+ cpustate->waitcount = wcount;
+}
+
CPU_EXECUTE( i80186 )
{
if (cpustate->halted || cpustate->busreq)
#ifdef USE_DEBUGGER
cpustate->total_icount += passed_icount;
#endif
+ cpu_wait_i186(cpustate, passed_icount);
return passed_icount;
} else {
cpustate->icount += icount;
#ifdef USE_DEBUGGER
cpustate->total_icount += base_icount - cpustate->icount;
#endif
+ cpu_wait_i186(cpustate, base_icount - cpustate->icount);
return base_icount - cpustate->icount;
}
}
#endif
cpustate->icount = 0;
}
+ cpu_wait_i186(cpustate, base_icount - cpustate->icount);
return base_icount - cpustate->icount;
}
#include "instrv30.c"
#undef I80186
+static void cpu_wait_v30(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(wcount >= 65536) {
+ ncount = wcount >> 16;
+ wcount = wcount - (ncount << 16);
+ }
+ cpustate->extra_cycles += ncount;
+ cpustate->waitcount = wcount;
+}
+
CPU_EXECUTE( v30 )
{
if (cpustate->halted || cpustate->busreq)
#ifdef USE_DEBUGGER
cpustate->total_icount += passed_icount;
#endif
+ cpu_wait_v30(cpustate, passed_icount);
return passed_icount;
} else {
cpustate->icount += icount;
#ifdef USE_DEBUGGER
cpustate->total_icount += base_icount - cpustate->icount;
#endif
+ cpu_wait_v30(cpustate, base_icount - cpustate->icount);
return base_icount - cpustate->icount;
}
}
#endif
cpustate->icount = 0;
}
+ cpu_wait_v30(cpustate, base_icount - cpustate->icount);
return base_icount - cpustate->icount;
}
#define SIG_CPU_HALTREQ 0x8000 + SIG_CPU_BUSREQ
// Note: Below is ugly hack cause of CPU#0 cannot modify clock.
-#define SIG_CPU_WAIT_FACTOR 0x8001 + SIG_CPU_BUSREQ
class VM;
class EMU;
class DEBUGGER;
{
MEMORY::initialize();
- uint32_t to_bank = to >> addr_shift;
uint32_t start_bank = start >> addr_shift;
uint32_t end_bank = end >> addr_shift;
-
+ uint32_t to_bank = to >> addr_shift;
+ int blocks = (int)(addr_max / bank_size);
+
for(uint32_t i = start_bank; i <= end_bank; i++) {
- if(to_bank >= bank_size) break;
- if(i >= bank_size) break;
+ if(to_bank >= blocks) break;
wr_table[to_bank].dev = wr_table[i].dev;
wr_table[to_bank].memory = wr_table[i].memory;
+ wr_table[to_bank].wait = wr_table[i].wait;
to_bank++;
}
}
{
MEMORY::initialize();
- uint32_t to_bank = to >> addr_shift;
uint32_t start_bank = start >> addr_shift;
uint32_t end_bank = end >> addr_shift;
+ uint32_t to_bank = to >> addr_shift;
+ int blocks = (int)(addr_max / bank_size);
for(uint32_t i = start_bank; i <= end_bank; i++) {
- if(to_bank >= bank_size) break;
- if(i >= bank_size) break;
+ if(to_bank >= blocks) break;
rd_table[to_bank].dev = rd_table[i].dev;
rd_table[to_bank].memory = rd_table[i].memory;
+ rd_table[to_bank].wait = rd_table[i].wait;
to_bank++;
}
}
//out_debug_log(_T("I/O READ: %04x \n"), addr);
switch(addr) {
+ case 0x005c:
+ case 0x005d:
+ case 0x005e:
+ case 0x005f:
+ {
+ // Timestamp register (from MAME 0.208)
+ pair32_t n;
+ uint8_t nn;
+ n.d = d_cpu->read_signal(SIG_CPU_TOTAL_CYCLE_LO);
+ switch(addr & 0x03) {
+ case 0:
+ nn = n.b.l;
+ break;
+ case 1:
+ nn = n.b.h;
+ break;
+ case 2:
+ nn = n.b.h2;
+ break;
+ case 3:
+ nn = n.b.h3;
+ break;
+ }
+ return (uint32_t)nn;
+ }
+ break;
case 0x00f0:
value = 0x00;
// value |= 0x80; // 1 = PC-9801NA, 0 = PC-9801NA/C
//#endif
}
break;
+ case 0x00bc: // OK?
case 0x00be:
#if !defined(SUPPORT_HIRESO)
if(!(modereg & 2) && (data & 2)) {
#endif
break;
#if !defined(SUPPORT_HIRESO)
+ case 0x00bc: // OK?
case 0x00be:
- return 0xf8 | (modereg & 3);
+ //return 0xf8 | (modereg & 3);
+ return 0xfc | (modereg & 3);
case 0x00cc:
case 0x00ce:
if(!(modereg & 1)) {
memset(ide_bios, 0xff, sizeof(ide_bios));
memset(ide_bios_ram, 0x00, sizeof(ide_bios_ram));
ide_bios_selected = (read_bios(_T("IDE.ROM"), ide_bios, sizeof(ide_bios)) != 0);
- ide_bios_ram_selected = false;
+ ide_bios_bank = 0;
#endif
// page08_intram_selected = false;
page08_intram_selected = true;
// SASI
#if defined(SUPPORT_SASI_IF)
-// sasi_bios_selected = true;
- sasi_bios_selected = false;
+ sasi_bios_selected = true;
+// sasi_bios_selected = false;
sasi_bios_ram_selected = false; // OK?
#endif
// SASI
scsi_bios_ram_selected = false; // OK?
#endif
// ToDo: IDE
+#if defined(SUPPORT_IDE_IF)
+ ide_bios_bank = 0; // ToDo: BANK
+#endif
#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
#if !defined(SUPPORT_HIRESO)
dma_access_ctrl = 0xfe; // bit2 = 1, bit0 = 0
}
break;
#endif
+#if 1
case 0x0461:
// http://www.webtech.co.jp/company/doc/undocumented_mem/io_mem.txt
// ToDo: Cache flush for i486 or later.
}
}
break;
+#endif
#if defined(SUPPORT_HIRESO)
case 0x0093:
#if defined(_PC98XA)
}
break;
#endif
+#if 1
case 0x0463:
// http://www.webtech.co.jp/company/doc/undocumented_mem/io_mem.txt
// ToDo: Cache flush for i486 or later.
}
break;
#endif
+#endif
#if defined(SUPPORT_32BIT_ADDRESS)
case 0x053d:
{
}
return 0xff;
}
-#if defined(SUPPORT_24BIT_ADDRESS)
-// WIP: Temporally re-add read_data8() and write_data8() for SUPPORT_24BIT_ADDRESS.20190510 K.O
-uint32_t MEMBUS::read_data8(uint32_t addr)
-{
- if((addr >= 0x80000) && (addr < 0xc0000)) {
- // ToDo: External banked memory.
- if(addr < 0xa0000){
- // ToDo: Correctness extra ram emulation.
- if(!page08_intram_selected) {
- last_access_is_interam = false;
- return 0xff;
- }
- // Unable to access lower than 07ffffh via WINDOW.20190425 K.O
- if(window_80000h >= 0x80000) {
- addr = (addr & 0x1ffff) | window_80000h;
- }
- } else {
- // Unable to access lower than 07ffffh via WINDOW.20190425 K.O
- if(window_a0000h >= 0x80000) { // a0000 - bffff
- addr = (addr & 0x1ffff) | window_a0000h;
- }
- }
- }
- if(addr < 0x10000) {
- last_access_is_interam = false;
- }
- if(addr < UPPER_MEMORY_24BIT) {
- last_access_is_interam = true;
- return MEMORY::read_data8(addr);
- }
- return MEMORY::read_data8(addr & 0xfffff);
-}
-
-void MEMBUS::write_data8(uint32_t addr, uint32_t data)
-{
- if((addr >= 0x80000) && (addr < 0xc0000)) {
- if(addr < 0xa0000) {
- // ToDo: Correctness extra ram emulation.
- if(!page08_intram_selected) {
- last_access_is_interam = false;
- return;
- }
- if(window_80000h >= 0x80000) {
- addr = (addr & 0x1ffff) | window_80000h;
- }
- } else { // a0000 - bffff
- if(window_a0000h >= 0x80000) { // a0000 - bffff
- addr = (addr & 0x1ffff) | window_a0000h;
- }
- }
- }
- if(addr < 0x10000) {
- last_access_is_interam = false;
- }
- if(addr < UPPER_MEMORY_24BIT) {
- last_access_is_interam = true;
- MEMORY::write_data8(addr, data);
- return;
- }
- MEMORY::write_data8(addr & 0xfffff, data);
-}
-
-
-uint32_t MEMBUS::read_dma_data8(uint32_t addr)
-{
- if(!(dma_access_a20)) {
- addr &= 0x000fffff;
- }
- return read_data8(addr);
-}
-
-void MEMBUS::write_dma_data8(uint32_t addr, uint32_t data)
-{
- if(!(dma_access_a20)) {
- addr &= 0x000fffff;
- }
- write_data8(addr, data);
-}
-#elif defined(SUPPORT_32BIT_ADDRESS)
+#if defined(SUPPORT_32BIT_ADDRESS) || defined(SUPPORT_24BIT_ADDRESS)
uint32_t MEMBUS::read_dma_data8(uint32_t addr)
{
if(!(dma_access_a20)) {
#if defined(SUPPORT_32BIT_ADDRESS)
set_memory_rw(0x00000, (sizeof(ram) >= 0x80000) ? 0x7ffff : (sizeof(ram) - 1), ram);
#elif defined(SUPPORT_24BIT_ADDRESS)
- set_memory_rw(0x00000, 0x9ffff, ram);
+ set_memory_rw(0x00000, (sizeof(ram) >= 0x80000) ? 0x7ffff : (sizeof(ram) - 1), ram);
#else
set_memory_rw(0x00000, (sizeof(ram) >= 0xc0000) ? 0xbffff : (sizeof(ram) - 1), ram);
#endif
void MEMBUS::update_bios()
{
#if !defined(SUPPORT_HIRESO)
- #if defined(SUPPORT_32BIT_ADDRESS)/* || defined(SUPPORT_24BIT_ADDRESS)*/
+ #if defined(SUPPORT_32BIT_ADDRESS)|| defined(SUPPORT_24BIT_ADDRESS)
unset_memory_rw(0x80000, 0xbffff);
#endif
set_memory_mapped_io_rw(0xa0000, 0xa4fff, d_display);
}
#else // HIRESO
set_memory_mapped_io_rw(0xc0000, 0xe4fff, d_display);
- #if defined(SUPPORT_BIOS_RAM)
+ #if defined(SUPPORT_BIOS_RAM) && defined(SUPPORT_32BIT_ADDRESS)
if(shadow_ram_selected) {
set_memory_rw(0xc0000, 0xe7fff, &(ram[0xc0000])); // OK?
}
} //else
#endif
-#if defined(SUPPORT_32BIT_ADDRESS) /*|| defined(SUPPORT_24BIT_ADDRESS)*/
+#if defined(SUPPORT_32BIT_ADDRESS) || defined(SUPPORT_24BIT_ADDRESS)
if((page08_intram_selected) /*&& (shadow_ram_selected)*/){
if((window_80000h == 0xc0000)) {
+#if defined(SUPPORT_32BIT_ADDRESS) && defined(SUPPORT_BIOS_RAM)
if(shadow_ram_selected) {
set_memory_rw(0x80000, 0x9ffff, &(ram[window_80000h]));
} else {
copy_table_rw(0x80000, 0xc0000, 0xdffff);
}
+#else
+ copy_table_rw(0x80000, 0xc0000, 0xdffff);
+#endif
} else if(window_80000h == 0xe0000) {
+#if defined(SUPPORT_32BIT_ADDRESS) && defined(SUPPORT_BIOS_RAM)
if(shadow_ram_selected) {
-#if defined(SUPPORT_BIOS_RAM)
#if !defined(SUPPORT_HIRESO)
+ //copy_table_rw(0x80000, 0xe0000, 0xe7fff);
set_memory_rw(0x80000, 0x87fff, &(ram[window_80000h]));
set_memory_rw(0x88000, 0x9ffff, bios_ram);
#else
+ //copy_table_rw(0x80000, 0xe0000, 0xeffff);
set_memory_rw(0x80000, 0x8ffff, &(ram[window_80000h]));
set_memory_rw(0x90000, 0x9ffff, bios_ram);
#endif
-#else
- set_memory_rw(0x80000, 0x9ffff, &(ram[window_80000h]));
-#endif
} else {
copy_table_rw(0x80000, 0xe0000, 0xfffff);
- }
+ }
+#else
+ copy_table_rw(0x80000, 0xe0000, 0xfffff);
+#endif
} else if((window_80000h == 0x80000) || (((window_80000h + 0x1ffff) < sizeof(ram)) && !((window_80000h >= 0xa0000) && (window_80000h <= 0xfffff)))) { // ToDo: Extra RAM
set_memory_rw(0x80000, 0x9ffff, &(ram[window_80000h]));
- }
- else if(window_80000h >= 0x800000) {
- MEMORY::copy_table_rw(0x00080000, window_80000h, window_80000h + 0x1ffff);
+ } else if(window_80000h >= 0xa0000) {
+ copy_table_rw(0x00080000, window_80000h, window_80000h + 0x1ffff);
} else {
#if defined(SUPPORT_24BIT_ADDRESS)
set_memory_rw(0x80000, 0x9ffff, &(ram[0x80000]));
// ToDo: External BUS
unset_memory_rw(0x00080000, 0x0009ffff);
} else {
- MEMORY::copy_table_rw(0x00080000, window_80000h, window_80000h + 0x1ffff);
+ copy_table_rw(0x00080000, window_80000h, window_80000h + 0x1ffff);
}
}
/*if((page08_intram_selected) )*/{
if((window_a0000h == 0xc0000)) {
+#if defined(SUPPORT_32BIT_ADDRESS) && defined(SUPPORT_BIOS_RAM)
if(shadow_ram_selected) {
+ //copy_table_rw(0xa0000, 0xc0000, 0xdffff);
set_memory_rw(0xa0000, 0xbffff, &(ram[window_a0000h]));
} else {
copy_table_rw(0xa0000, 0xc0000, 0xdffff);
- //unset_memory_rw(0xa0000, 0xbffff);
}
+#else
+ copy_table_rw(0xa0000, 0xc0000, 0xdffff);
+#endif
} else if(window_a0000h == 0xe0000) {
+#if defined(SUPPORT_32BIT_ADDRESS) && defined(SUPPORT_BIOS_RAM)
if(shadow_ram_selected) {
-#if defined(SUPPORT_BIOS_RAM)
#if !defined(SUPPORT_HIRESO)
+ //copy_table_rw(0xa0000, 0xe0000, 0xe7fff);
set_memory_rw(0xa0000, 0xa7fff, &(ram[window_a0000h]));
set_memory_rw(0xa8000, 0xbffff, bios_ram);
#else
+ //copy_table_rw(0xa0000, 0xe0000, 0xeffff);
set_memory_rw(0xa0000, 0xaffff, &(ram[window_a0000h]));
set_memory_rw(0xb0000, 0xbffff, bios_ram);
#endif
-#else
- set_memory_rw(0xa0000, 0xbffff, &(ram[window_a0000h]));
-#endif
} else {
copy_table_rw(0xa0000, 0xe0000, 0xfffff);
}
+#else
+ copy_table_rw(0xa0000, 0xe0000, 0xfffff);
+#endif
} else if((window_a0000h >= 0x80000) && ((window_a0000h + 0x1ffff) < sizeof(ram)) && !((window_a0000h >= 0xa0000) && (window_a0000h <= 0xfffff))) {
set_memory_rw(0xa0000, 0xbffff, &(ram[window_a0000h]));
} else {
if(window_a0000h >= 0x80000) {
- MEMORY::copy_table_rw(0x000a0000, window_a0000h, window_a0000h + 0x1ffff);
+ copy_table_rw(0x000a0000, window_a0000h, window_a0000h + 0x1ffff);
} else {
unset_memory_rw(0xa0000, 0xbffff);
}
// ToDo: PC9821
#if defined(SUPPORT_32BIT_ADDRESS)
- //MEMORY::unset_memory_rw(0x00f00000, 0x00fbffff);
- //MEMORY::copy_table_rw(0x00fc0000, 0x000c0000, 0x000fffff);
- MEMORY::unset_memory_rw(0x00f00000, (UPPER_MEMORY_32BIT & 0x00ffffff) - 1);
- MEMORY::copy_table_rw((UPPER_MEMORY_32BIT & 0x00ffffff), (UPPER_MEMORY_32BIT & 0x000fffff), 0x000fffff);
+ unset_memory_rw(0x00f00000, (UPPER_MEMORY_32BIT & 0x00ffffff) - 1);
+ #if !defined(SUPPORT_HIRESO)
+ copy_table_rw(0x00ee8000, 0x000e8000, 0x000fffff);
+ copy_table_rw(0x00fe8000, 0x000e8000, 0x000fffff);
+ #endif
+ copy_table_rw(UPPER_MEMORY_32BIT, (UPPER_MEMORY_32BIT & 0x000fffff), 0x000fffff);
+ copy_table_rw((UPPER_MEMORY_32BIT & 0x00ffffff), (UPPER_MEMORY_32BIT & 0x000fffff), 0x000fffff);
#elif defined(SUPPORT_24BIT_ADDRESS)
- MEMORY::unset_memory_rw(0x00f00000, UPPER_MEMORY_24BIT - 1);
- MEMORY::copy_table_rw(UPPER_MEMORY_24BIT, UPPER_MEMORY_24BIT & 0xfffff, 0x000fffff);
-// MEMORY::copy_table_rw(0x00ee8000, 0x000e8000, 0x000fffff);
-// MEMORY::copy_table_rw(0x00fc0000, 0x000c0000, 0x000fffff);
+ unset_memory_rw(0x00f00000, UPPER_MEMORY_24BIT - 1);
+ copy_table_rw(UPPER_MEMORY_24BIT, UPPER_MEMORY_24BIT & 0x000fffff, 0x000fffff);
#endif
#endif
}
void MEMBUS::update_ide_bios()
{
if(ide_bios_selected) {
- if(ide_bios_selected) {
- set_memory_r(0xd8000, 0xdbfff, ide_bios_ram);
- } else {
- set_memory_r(0xd8000, 0xdbfff, ide_bios);
- unset_memory_w(0xd8000, 0xdbfff);
- }
+ set_memory_r(0xd8000, 0xd9fff, &(ide_bios[ide_bios_bank * 0x2000]));
+ unset_memory_w(0xd8000, 0xdbfff);
+ set_memory_rw(0xda000, 0xdbfff, ide_bios_ram);
+// }
} else {
unset_memory_rw(0xd8000, 0xdbfff);
}
#endif
-#define STATE_VERSION 9
+#define STATE_VERSION 10
bool MEMBUS::process_state(FILEIO* state_fio, bool loading)
{
state_fio->StateValue(scsi_bios_ram_selected);
#endif
#if defined(SUPPORT_IDE_IF)
- state_fio->StateBool(ide_bios_ram_selected);
+ state_fio->StateValue(ide_bios_bank);
state_fio->StateArray(ide_bios_ram, sizeof(ide_bios_ram), 1);
state_fio->StateValue(ide_bios_selected);
#endif
#endif
#if defined(SUPPORT_IDE_IF)
uint8_t ide_bios[0x4000];
-// uint8_t ide_bios_ram[0x4000];
+ uint8_t ide_bios_ram[0x2000];
bool ide_bios_selected;
-// bool ide_bios_ram_selected;
+ bool ide_bios_bank;
void update_ide_bios();
#endif
// EMS
uint32_t read_signal(int ch);
void write_io8(uint32_t addr, uint32_t data);
uint32_t read_io8(uint32_t addr);
-// WIP: Temporally re-add read_data8() and write_data8() for SUPPORT_24BIT_ADDRESS.20190510 K.O
-#if defined(SUPPORT_24BIT_ADDRESS)
- uint32_t read_data8(uint32_t addr);
- void write_data8(uint32_t addr, uint32_t data);
-#endif
#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
uint32_t read_dma_data8(uint32_t addr);
void write_dma_data8(uint32_t addr, uint32_t data);
#else
pit_clock_8mhz = false;
#endif
-#if defined(_PC9801E)
- if(config.cpu_type != 0) {
- // 8MHz -> 5MHz
- cpu_clocks = 4992030;
- pit_clock_8mhz = false;
- }
-#elif defined(_PC9801VM) || defined(_PC98DO) || defined(_PC98DOPLUS) || defined(_PC9801VX) || defined(_PC98XL)
- if(config.cpu_type != 0) {
- // 10MHz/16MHz -> 8MHz
- cpu_clocks = 7987248;
- pit_clock_8mhz = true;
- }
-#elif defined(_PC9801RA) || defined(_PC98RL)
- if(config.cpu_type != 0) {
- // 20MHz -> 16MHz
- cpu_clocks = 15974496;
- pit_clock_8mhz = true;
- }
-#endif
int pit_clocks = pit_clock_8mhz ? 1996812 : 2457600;
sound_type = config.sound_type;
io->set_iomap_alias_rw(0x0055, pio_fdd, 2);
io->set_iomap_alias_w (0x0057, pio_fdd, 3);
#endif
-
+#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
+ io->set_iomap_range_r(0x005c, 0x005f, cpureg); // TimeStamp
+#endif
+
io->set_iomap_alias_rw(0x0060, gdc_chr, 0);
io->set_iomap_alias_rw(0x0062, gdc_chr, 1);
io->set_iomap_single_rw(0x0096, floppy);
#if defined(SUPPORT_2HD_2DD_FDD_IF)
#if !defined(SUPPORT_HIRESO)
+ io->set_iomap_single_rw(0x00bc, floppy);
io->set_iomap_single_rw(0x00be, floppy);
#else
//#if !defined(_PC98XA) && !defined(_PC98XL)
for(DEVICE* device = first_device; device; device = device->next_device) {
device->initialize();
}
-
+ setclock();
+
#if defined(_PC9801) || defined(_PC9801E)
fdc_2hd->get_disk_handler(0)->drive_num = 0;
fdc_2hd->get_disk_handler(1)->drive_num = 1;
// ----------------------------------------------------------------------------
// drive virtual machine
// ----------------------------------------------------------------------------
+void VM::setclock()
+{
+ uint32_t cpu_clocks = CPU_CLOCKS;
+#if defined(_PC9801E)
+ if(config.cpu_type != 0) {
+ // 8MHz -> 5MHz
+ cpu_clocks = 4992030;
+ pit_clock_8mhz = false;
+ } else {
+ pit_clock_8mhz = true;
+ }
+#elif defined(_PC9801VM) || defined(_PC98DO) || defined(_PC98DOPLUS) || defined(_PC9801VX) || defined(_PC98XL)
+ if(config.cpu_type != 0) {
+ // 10MHz/16MHz -> 8MHz
+ cpu_clocks = 7987248;
+ pit_clock_8mhz = true;
+ } else {
+ pit_clock_8mhz = false;
+ }
+#elif defined(_PC9801RA) || defined(_PC98RL)
+ if(config.cpu_type != 0) {
+ // 20MHz -> 16MHz
+ cpu_clocks = 15974496;
+ pit_clock_8mhz = true;
+ } else {
+ pit_clock_8mhz = false;
+ }
+#endif
+ uint32_t waitfactor;
+ if(CPU_CLOCKS > cpu_clocks) {
+ waitfactor = (uint32_t)(65536.0 * ((1.0 - (double)cpu_clocks / (double)CPU_CLOCKS)));
+ //out_debug_log(_T("CLOCK=%d WAIT FACTOR=%d"), cpu_clocks, waitfactor);
+ } else {
+ waitfactor = 0;
+ //out_debug_log(_T("CLOCK=%d WAIT FACTOR=%d"), cpu_clocks, waitfactor);
+ }
+ cpu->write_signal(SIG_CPU_WAIT_FACTOR, waitfactor, 0xffffffff);
+
+ uint8_t prn_port_b = pio_prn->read_signal(SIG_I8255_PORT_B);
+ prn_port_b &= (uint8_t)(~0x20);
+ if(pit_clock_8mhz) {
+ prn_port_b |= 0x20; // MOD, 1 = System clock 8MHz, 0 = 5/10MHz
+ }
+ pio_prn->write_signal(SIG_I8255_PORT_B, prn_port_b, 0xff);
+ int pit_clocks = pit_clock_8mhz ? 1996812 : 2457600;
+ // pit ch.2: rs-232c
+ pit->set_constant_clock(0, pit_clocks);
+ pit->set_constant_clock(1, pit_clocks);
+ pit->set_constant_clock(2, pit_clocks);
+}
void VM::reset()
{
device->reset();
}
#endif
+ setclock();
// initial device settings
uint8_t port_a, port_b, port_c;
pc88pio->write_signal(SIG_I8255_PORT_C, 0, 0xff);
pc88pio_sub->write_signal(SIG_I8255_PORT_C, 0, 0xff);
#endif
+
}
void VM::run()
void VM::update_config()
{
+ setclock();
{
uint8_t mouse_port_b = pio_mouse->read_signal(SIG_I8255_PORT_B);
mouse_port_b = mouse_port_b & ~0x40;
}
pio_sys->write_signal(SIG_I8255_PORT_A, sys_port_a, 0xff);
}
-#if defined(SUPPORT_EGC)
+
{
uint8_t prn_port_b = pio_prn->read_signal(SIG_I8255_PORT_B);
+#if defined(SUPPORT_EGC)
prn_port_b = prn_port_b & ~0x08;
if((config.dipswitch & (1 << DIPSW_POSITION_EGC)) == 0) {
prn_port_b = prn_port_b | 0x08;
}
+#endif
pio_prn->write_signal(SIG_I8255_PORT_B, prn_port_b, 0xff);
}
-#endif
#if defined(_PC98DO) || defined(_PC98DOPLUS)
if(boot_mode != config.boot_mode) {
#define SUPPORT_PC98_OPNA
#endif
#if defined(SUPPORT_24BIT_ADDRESS)
- #define MEMORY_ADDR_MAX 0x1000000 // 16MB
+ #define MEMORY_ADDR_MAX 0x01000000 // 16MB
#elif defined(SUPPORT_32BIT_ADDRESS)
- #define MEMORY_ADDR_MAX 0x10000000 // 256MB
+ #define MEMORY_ADDR_MAX 0x100000000 // 4GiB
#else
- #define MEMORY_ADDR_MAX 0x100000 // 1MB
+ #define MEMORY_ADDR_MAX 0x000100000 // 1MB
#endif
//#if defined(SUPPORT_32BIT_ADDRESS)
// #define SUPPORT_SYSTEM_16MB
int boot_mode;
#endif
+ void setclock();
// drives
UPD765A *get_floppy_disk_controller(int drv);
if(d_mem->is_sasi_bios_load()) return false;
// Check ADDRESS: This pseudo-bios acts only $fffc4 ($1B) or $00ffffc4:
if((PC != 0xfffc4) && (PC != 0x00ffffc4)) return false; // INT 1Bh
-#if 1
static const int elapsed_cycle = 200; // From NP2 0.86+trunk/ OK?
+#if 0
+
/* if((((AL & 0xf0) != 0x00) && ((AL & 0xf0) != 0x80))) */ {
uint8_t seg = d_mem->read_data8(0x004b0 + (AL >> 4));
- uint32_t sp, ss;
+ uint32_t sp, ss;
if ((seg != 0) && ((seg >= 0xd8) && (seg < 0xd7))) {
#ifdef _PSEUDO_BIOS_DEBUG
this->out_debug_log(_T("%6x\tDISK BIOS: AH=%2x,AL=%2x,CX=%4x,DX=%4x,BX=%4x,DS=%2x,DI=%2x\n"), get_cpu_pc(0), AH,AL,CX,DX,BX,DS,DI);
ss = (uint32_t)SS;
ss = ss << 4;
ss = ss & 0xfffff0;
-#ifdef _PSEUDO_BIOS_DEBUG
+//#ifdef _PSEUDO_BIOS_DEBUG
out_debug_log("call by %.4x:%.4x",
d_mem->read_data16(ss + sp + 2),
d_mem->read_data16(ss + sp + 0));
out_debug_log("From AX=%04x BX=%04x %02x:%02x:%02x:%02x ES=%04x BP=%04x",
AX, BX, CL, DH, DL, CH,
ES, BP);
-#endif
+//#endif
d_mem->write_data16(ss + sp - 2, DS);
d_mem->write_data16(ss + sp - 4, SI);
d_mem->write_data16(ss + sp - 6, DI);