OSDN Git Service

[VM][DEVICE] Add CPU pseudo SIGNALS, 108 to 110.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Sun, 12 May 2019 19:03:29 +0000 (04:03 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Sun, 12 May 2019 19:03:29 +0000 (04:03 +0900)
[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.

21 files changed:
source/src/vm/common_vm/CMakeLists.txt
source/src/vm/device.h
source/src/vm/i286.cpp
source/src/vm/i286.h
source/src/vm/i386.cpp
source/src/vm/i386.h
source/src/vm/libcpu_newdev/device.h
source/src/vm/mame/emu/cpu/i386/i386.c
source/src/vm/mame/emu/cpu/i386/i386ops.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/mc6809.h
source/src/vm/memory.cpp
source/src/vm/pc9801/cpureg.cpp
source/src/vm/pc9801/floppy.cpp
source/src/vm/pc9801/membus.cpp
source/src/vm/pc9801/membus.h
source/src/vm/pc9801/pc9801.cpp
source/src/vm/pc9801/pc9801.h
source/src/vm/pc9801/sasi_bios.cpp

index c348387..f1d1a4c 100644 (file)
@@ -1,6 +1,6 @@
 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
index 6e47bbb..d0287ca 100644 (file)
@@ -34,6 +34,9 @@
 #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
index 196c848..64bd0ac 100644 (file)
@@ -176,6 +176,8 @@ 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()
@@ -214,6 +216,25 @@ int I286::run(int icount)
        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;
@@ -230,6 +251,9 @@ void I286::write_signal(int id, uint32_t data, uint32_t mask)
        } 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.
        }
 }
 
@@ -463,7 +487,7 @@ int I286::get_shutdown_flag()
 }
 #endif
 
-#define STATE_VERSION  5
+#define STATE_VERSION  6
 
 bool I286::process_state(FILEIO* state_fio, bool loading)
 {
@@ -511,6 +535,8 @@ 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);
@@ -563,6 +589,8 @@ 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);
 #endif
        
 #ifdef USE_DEBUGGER
index 0c9fdbf..406c3ee 100644 (file)
@@ -68,6 +68,7 @@ public:
        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);
index 60495d3..f210245 100644 (file)
@@ -434,6 +434,8 @@ 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()
@@ -452,11 +454,29 @@ void I386::reset()
 }
 
 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;
@@ -471,6 +491,9 @@ void I386::write_signal(int id, uint32_t data, uint32_t mask)
                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.
        }
 }
 
@@ -828,7 +851,7 @@ int I386::get_shutdown_flag()
        return cpustate->shutdown;
 }
 
-#define STATE_VERSION  5
+#define STATE_VERSION  6
 
 void process_state_SREG(I386_SREG* val, FILEIO* state_fio)
 {
@@ -1001,6 +1024,9 @@ bool I386::process_state(FILEIO* state_fio, bool loading)
        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);
index e0f46ab..1e9017f 100644 (file)
@@ -77,6 +77,7 @@ public:
        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);
index 112069c..3c808ec 100644 (file)
@@ -29,6 +29,9 @@
 #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
index c9bbcd6..7743986 100644 (file)
@@ -708,7 +708,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
        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 {
@@ -741,14 +741,8 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                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;
@@ -1002,9 +996,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                                        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);
@@ -1063,7 +1055,8 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                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 );
@@ -1074,7 +1067,8 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                        }
                        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 );
@@ -1317,7 +1311,7 @@ static void i286_task_switch(i386_state *cpustate, UINT16 selector, UINT8 nested
        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);
 }
@@ -1441,7 +1435,7 @@ static void i386_task_switch(i386_state *cpustate, UINT16 selector, UINT8 nested
 
        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);
 }
 
@@ -2034,7 +2028,7 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
                                        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 */
@@ -2499,8 +2493,8 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
        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;
@@ -2526,9 +2520,6 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                }
                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);
@@ -2537,35 +2528,19 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                        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)
        {
@@ -2614,7 +2589,6 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                        //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) {
@@ -2633,6 +2607,9 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                        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);
@@ -2640,7 +2617,18 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                        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
                {
@@ -3469,6 +3457,8 @@ static void zero_state(i386_state *cpustate)
        cpustate->opcode_pc = 0;
        cpustate->opcode_bytes_length = 0;
 #endif
+       cpustate->waitcount = 0;
+
 }
 
 static CPU_RESET( i386 )
@@ -3658,6 +3648,21 @@ static void i386_set_a20_line(i386_state *cpustate,int state)
        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);
@@ -3677,6 +3682,7 @@ static CPU_EXECUTE( i386 )
 //#ifdef USE_DEBUGGER
                        cpustate->total_cycles += passed_cycles;
 //#endif
+                       cpu_wait_i386(cpustate, passed_cycles);
                        return passed_cycles;
                } else {
                        cpustate->cycles += cycles;
@@ -3695,6 +3701,7 @@ static CPU_EXECUTE( i386 )
 //#ifdef USE_DEBUGGER
                        cpustate->total_cycles += passed_cycles;
 //#endif
+                       cpu_wait_i386(cpustate, passed_cycles);
                        return passed_cycles;
                }
        }
@@ -3888,6 +3895,7 @@ static CPU_EXECUTE( i386 )
        }
        int passed_cycles = cpustate->base_cycles - cpustate->cycles;
        cpustate->tsc += passed_cycles;
+       cpu_wait_i386(cpustate, passed_cycles);
        return passed_cycles;
 }
 
index fa09574..3c8be1e 100644 (file)
@@ -658,18 +658,18 @@ static void I386OP(mov_rm8_i8)(i386_state *cpustate)        // Opcode 0xc6
 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) {
@@ -773,18 +773,18 @@ static void I386OP(mov_r32_dr)(i386_state *cpustate)        // Opcode 0x0f 21
 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);
@@ -794,8 +794,8 @@ static void I386OP(mov_cr_r32)(i386_state *cpustate)        // Opcode 0x0f 22
        {
                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);
                        }
index bc6881d..8993814 100644 (file)
@@ -556,6 +556,8 @@ struct i386_state
        UINT32 smbase;
 //     devcb_resolved_write_line smiact;
        bool lock;
+       UINT32 waitfactor;
+       UINT64 waitcount;
 
        // bytes in current opcode, debug only
 #ifdef DEBUG_MISSING_OPCODE
@@ -677,8 +679,8 @@ INLINE int i386_limit_check(i386_state *cpustate, int seg, UINT32 offset, UINT32
                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;
index 1f3e158..b6fa9b5 100644 (file)
@@ -85,6 +85,8 @@ struct i80286_state
        int busreq;
        int trap_level;
        int shutdown;
+       uint32_t waitfactor;
+       uint32_t waitcount;
 
 #ifdef USE_DEBUGGER
        uint64_t total_icount;
@@ -213,6 +215,7 @@ static CPU_RESET( i80286 )
        cpustate->ldtr.sel=cpustate->tr.sel=0;
        cpustate->rep_in_progress = FALSE;
        cpustate->seg_prefix = FALSE;
+       cpustate->waitcount = 0;
 
        CHANGE_PC(cpustate->pc);
 
@@ -265,6 +268,21 @@ static void set_irq_line(i80286_state *cpustate, int irqline, int state)
        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)
@@ -281,6 +299,7 @@ static CPU_EXECUTE( i80286 )
 #ifdef USE_DEBUGGER
                        cpustate->total_icount += passed_icount;
 #endif
+                       cpu_wait_i286(cpustate,passed_icount);
                        return passed_icount;
                } else {
                        cpustate->icount += icount;
@@ -297,6 +316,7 @@ static CPU_EXECUTE( i80286 )
 #ifdef USE_DEBUGGER
                        cpustate->total_icount += base_icount - cpustate->icount;
 #endif
+                       cpu_wait_i286(cpustate, base_icount - cpustate->icount);
                        return base_icount - cpustate->icount;
                }
        }
@@ -411,6 +431,7 @@ static CPU_EXECUTE( i80286 )
 #endif
                cpustate->icount = 0;
        }
+       cpu_wait_i286(cpustate, base_icount - cpustate->icount);
        return base_icount - cpustate->icount;
 }
 
index 70829b9..5b746cc 100644 (file)
@@ -72,6 +72,8 @@ struct i8086_state
        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 */
@@ -204,6 +206,7 @@ static CPU_RESET( i8086 )
        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;
@@ -279,6 +282,21 @@ static void set_test_line(i8086_state *cpustate, int state)
        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)
@@ -295,6 +313,7 @@ CPU_EXECUTE( i8086 )
 #ifdef USE_DEBUGGER
                        cpustate->total_icount += passed_icount;
 #endif
+                       cpu_wait_i86(cpustate, passed_icount);
                        return passed_icount;
                } else {
                        cpustate->icount += icount;
@@ -311,6 +330,7 @@ CPU_EXECUTE( i8086 )
 #ifdef USE_DEBUGGER
                        cpustate->total_icount += base_icount - cpustate->icount;
 #endif
+                       cpu_wait_i86(cpustate, base_icount - cpustate->icount);
                        return base_icount - cpustate->icount;
                }
        }
@@ -405,6 +425,7 @@ CPU_EXECUTE( i8086 )
 #endif
                cpustate->icount = 0;
        }
+       cpu_wait_i86(cpustate, base_icount - cpustate->icount);
        return base_icount - cpustate->icount;
 }
 
@@ -427,6 +448,21 @@ CPU_EXECUTE( i8088 )
 #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)
@@ -443,6 +479,7 @@ CPU_EXECUTE( i80186 )
 #ifdef USE_DEBUGGER
                        cpustate->total_icount += passed_icount;
 #endif
+                       cpu_wait_i186(cpustate, passed_icount);
                        return passed_icount;
                } else {
                        cpustate->icount += icount;
@@ -459,6 +496,7 @@ CPU_EXECUTE( i80186 )
 #ifdef USE_DEBUGGER
                        cpustate->total_icount += base_icount - cpustate->icount;
 #endif
+                       cpu_wait_i186(cpustate, base_icount - cpustate->icount);
                        return base_icount - cpustate->icount;
                }
        }
@@ -553,6 +591,7 @@ CPU_EXECUTE( i80186 )
 #endif
                cpustate->icount = 0;
        }
+       cpu_wait_i186(cpustate, base_icount - cpustate->icount);
        return base_icount - cpustate->icount;
 }
 
@@ -570,6 +609,21 @@ CPU_EXECUTE( i80186 )
 #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)
@@ -586,6 +640,7 @@ CPU_EXECUTE( v30 )
 #ifdef USE_DEBUGGER
                        cpustate->total_icount += passed_icount;
 #endif
+                       cpu_wait_v30(cpustate, passed_icount);
                        return passed_icount;
                } else {
                        cpustate->icount += icount;
@@ -602,6 +657,7 @@ CPU_EXECUTE( v30 )
 #ifdef USE_DEBUGGER
                        cpustate->total_icount += base_icount - cpustate->icount;
 #endif
+                       cpu_wait_v30(cpustate, base_icount - cpustate->icount);
                        return base_icount - cpustate->icount;
                }
        }
@@ -696,5 +752,6 @@ CPU_EXECUTE( v30 )
 #endif
                cpustate->icount = 0;
        }
+       cpu_wait_v30(cpustate, base_icount - cpustate->icount);
        return base_icount - cpustate->icount;
 }
index 7588844..b9ca4c7 100644 (file)
@@ -33,7 +33,6 @@ enum {
 
 #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;
index 1e8c7df..6f30e6d 100644 (file)
@@ -417,15 +417,16 @@ void MEMORY::copy_table_w(uint32_t to, uint32_t start, uint32_t end)
 {
        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++;
        }
 }
@@ -434,15 +435,16 @@ void MEMORY::copy_table_r(uint32_t to, uint32_t start, uint32_t end)
 {
        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++;
        }
 }
index 10eaa86..c6c85ae 100644 (file)
@@ -93,6 +93,32 @@ uint32_t CPUREG::read_io8(uint32_t addr)
        //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
index 026846b..3181eb5 100644 (file)
@@ -151,6 +151,7 @@ void FLOPPY::write_io8(uint32_t addr, uint32_t data)
 //#endif
                }
                break;
+       case 0x00bc: // OK?
        case 0x00be:
 #if !defined(SUPPORT_HIRESO)
                if(!(modereg & 2) && (data & 2)) {
@@ -236,8 +237,10 @@ uint32_t FLOPPY::read_io8(uint32_t addr)
 #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)) {
index 8aa8de8..c70877f 100644 (file)
@@ -156,7 +156,7 @@ void MEMBUS::initialize()
        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;  
@@ -191,8 +191,8 @@ void MEMBUS::reset()
 
        // 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
@@ -201,6 +201,9 @@ void MEMBUS::reset()
        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
@@ -349,6 +352,7 @@ void MEMBUS::write_io8(uint32_t addr, uint32_t data)
                }
                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.
@@ -360,6 +364,7 @@ void MEMBUS::write_io8(uint32_t addr, uint32_t data)
                        }
                }
                break;
+#endif
 #if defined(SUPPORT_HIRESO)
        case 0x0093:
 #if defined(_PC98XA)
@@ -377,6 +382,7 @@ void MEMBUS::write_io8(uint32_t addr, uint32_t data)
                }
                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.
@@ -389,6 +395,7 @@ void MEMBUS::write_io8(uint32_t addr, uint32_t data)
                }
                break;
 #endif
+#endif
 #if defined(SUPPORT_32BIT_ADDRESS)
        case 0x053d:
                {
@@ -475,85 +482,7 @@ uint32_t MEMBUS::read_io8(uint32_t addr)
        }
        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)) {
@@ -587,7 +516,7 @@ void MEMBUS::config_intram()
        #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  
@@ -605,7 +534,7 @@ void MEMBUS::config_intram()
 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);
@@ -638,7 +567,7 @@ void MEMBUS::update_bios()
        }
 #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?
        }
@@ -663,35 +592,40 @@ void MEMBUS::update_bios()
        } //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]));
@@ -713,39 +647,45 @@ void MEMBUS::update_bios()
                        // 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);
                        }
@@ -763,15 +703,16 @@ void MEMBUS::update_bios()
 
        // 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
 }
@@ -829,12 +770,10 @@ void MEMBUS::update_scsi_bios()
 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);
        }
@@ -855,7 +794,7 @@ void MEMBUS::update_nec_ems()
 #endif
 
 
-#define STATE_VERSION  9
+#define STATE_VERSION  10
 
 bool MEMBUS::process_state(FILEIO* state_fio, bool loading)
 {
@@ -889,7 +828,7 @@ 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
index a59b20d..a91d186 100644 (file)
@@ -96,9 +96,9 @@ private:
 #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
@@ -131,11 +131,6 @@ public:
        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);
index 14fb24d..9699d35 100644 (file)
@@ -145,25 +145,6 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
 #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;
@@ -663,7 +644,10 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
        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);
        
@@ -748,6 +732,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
        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)
@@ -978,7 +963,8 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
        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;
@@ -1039,6 +1025,56 @@ DEVICE* VM::get_device(int id)
 // ----------------------------------------------------------------------------
 // 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()
 {
@@ -1051,6 +1087,7 @@ void VM::reset()
                device->reset();
        }
 #endif
+       setclock();
        
        // initial device settings
        uint8_t port_a, port_b, port_c;
@@ -1195,6 +1232,7 @@ void VM::reset()
        pc88pio->write_signal(SIG_I8255_PORT_C, 0, 0xff);
        pc88pio_sub->write_signal(SIG_I8255_PORT_C, 0, 0xff);
 #endif
+
 }
 
 void VM::run()
@@ -1655,6 +1693,7 @@ bool VM::is_frame_skippable()
 
 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;
@@ -1675,16 +1714,17 @@ void VM::update_config()
                }
                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) {
index 929bd90..c8cfd90 100644 (file)
        #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
@@ -587,6 +587,7 @@ protected:
        
        int boot_mode;
 #endif
+       void setclock();
        
        // drives
        UPD765A *get_floppy_disk_controller(int drv);
index 8aae4a7..c6f0199 100644 (file)
@@ -170,11 +170,12 @@ bool BIOS::bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], in
        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);
@@ -183,7 +184,7 @@ bool BIOS::bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], in
                                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));
@@ -191,7 +192,7 @@ bool BIOS::bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], in
                                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);