OSDN Git Service

[VM][I386][PC9801] Add MEMORY/IO WAIT feature via foo_data[8|16|32]w().(excepts ...
authorK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 24 May 2019 14:46:45 +0000 (23:46 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 24 May 2019 14:46:45 +0000 (23:46 +0900)
source/src/vm/mame/emu/cpu/i386/i386.c
source/src/vm/mame/emu/cpu/i386/i386op16.c
source/src/vm/mame/emu/cpu/i386/i386op32.c
source/src/vm/mame/emu/cpu/i386/i386priv.h
source/src/vm/pc9801/display.cpp
source/src/vm/pc9801/display.h
source/src/vm/pc9801/membus.cpp
source/src/vm/pc9801/membus.h
source/src/vm/pc9801/pc9801.cpp
source/src/vm/pc9801/pc9801.h

index a6a4a62..15dc963 100644 (file)
@@ -52,7 +52,7 @@ static void pentium_smi(i386_state* cpustate);
 #define FAULT(fault,error) {\
                logerror("FAULT(%s , %s) PC=%08x V8086=%s PROTECTED=%s SP=%08X:%08X\n", #fault, #error, cpustate->pc, (cpustate->VM) ? "YES" : "NO", (PROTECTED_MODE) ? "YES" : "NO", (PROTECTED_MODE) ? cpustate->sreg[SS].base : (cpustate->sreg[SS].selector << 4), REG32(ESP)); \
                if(cpustate->is_report_exception) {                                                             \
-                       cpustate->exception_code = ((UINT64)error << 32) | (UINT64)fault; \
+                       cpustate->exception_code = (((UINT64)error) << 32) | (UINT64)fault; \
                        cpustate->exception_pc = cpustate->prev_pc;                                     \
                        cpustate->exception_caused = 1;                                                         \
                        cpustate->ext = 1;                                                                                      \
@@ -204,9 +204,14 @@ static void cpu_reset_generic(i386_state* cpustate)
 
        addr = base + (selector & ~7) + 5;
        i386_translate_address(cpustate, TRANSLATE_READ, &addr, NULL);
-       rights = cpustate->program->read_data8(addr);
+       int wait0 = cpustate->memory_wait;
+       int wait;
+       rights = cpustate->program->read_data8w(addr, &wait);
+       wait0 += wait;
        // Should a fault be thrown if the table is read only?
-       cpustate->program->write_data8(addr, rights | 1);
+       cpustate->program->write_data8w(addr, rights | 1, &wait);
+       wait0 += wait;
+       cpustate->memory_wait += wait0;
 }
 
 /*static*/INLINE void i386_load_segment_descriptor(i386_state *cpustate, int segment )
@@ -3648,7 +3653,7 @@ static void i386_set_irq_line(i386_state *cpustate,int irqline, int state)
                }
                if ( state ) {
                        try {
-                               i386_trap(cpustate,2, 1, 0);
+                               i386_trap(cpustate,2, 1, 0); // OK?
                        } catch(UINT64 e) {
                                logdebug("EXCEPTION %08X VIA making INT02h at i386_set_irq_line() ADDR=%08X\n", e, cpustate->pc);
                        } catch(UINT32 e) {
@@ -3716,6 +3721,8 @@ static CPU_EXECUTE( i386 )
                        cpustate->total_cycles += passed_cycles;
 //#endif
                        cpu_wait_i386(cpustate, passed_cycles);
+                       cpustate->extra_cycles += cpustate->memory_wait;
+                       cpustate->memory_wait = 0;
                        return passed_cycles;
                } else {
                        cpustate->cycles += cycles;
@@ -3735,6 +3742,8 @@ static CPU_EXECUTE( i386 )
                        cpustate->total_cycles += passed_cycles;
 //#endif
                        cpu_wait_i386(cpustate, passed_cycles);
+                       cpustate->extra_cycles += cpustate->memory_wait;
+                       cpustate->memory_wait = 0;
                        return passed_cycles;
                }
        }
@@ -3748,7 +3757,7 @@ static CPU_EXECUTE( i386 )
 
        /* adjust for any interrupts that came in */
 //#ifdef USE_DEBUGGER
-       cpustate->total_cycles += cpustate->extra_cycles;
+       cpustate->total_cycles -= cpustate->extra_cycles;
 //#endif
        cpustate->cycles -= cpustate->extra_cycles;
        cpustate->extra_cycles = 0;
@@ -3951,6 +3960,8 @@ static CPU_EXECUTE( i386 )
        int passed_cycles = cpustate->base_cycles - cpustate->cycles;
        cpustate->tsc += passed_cycles;
        cpu_wait_i386(cpustate, passed_cycles);
+       cpustate->extra_cycles += cpustate->memory_wait;
+       cpustate->memory_wait = 0;
        return passed_cycles;
 }
 
index bb25a83..513d2bd 100644 (file)
@@ -3194,7 +3194,7 @@ static void I386OP(group0F00_16)(i386_state *cpustate)          // Opcode 0x0f 0
        UINT8 modrm = FETCH(cpustate);
        I386_SREG seg;
        UINT8 result;
-
+       int wait;
        switch( (modrm >> 3) & 0x7 )
        {
                case 0:         /* SLDT */
@@ -3287,8 +3287,9 @@ static void I386OP(group0F00_16)(i386_state *cpustate)          // Opcode 0x0f 0
 
                                UINT32 addr = ((seg.selector & 4) ? cpustate->ldtr.base : cpustate->gdtr.base) + (seg.selector & ~7) + 5;
                                i386_translate_address(cpustate, TRANSLATE_READ, &addr, NULL);
-                               cpustate->program->write_data16(addr, (seg.flags & 0xff) | 2);
-
+                               
+                               cpustate->program->write_data16w(addr, (seg.flags & 0xff) | 2, &wait);
+                               cpustate->memory_wait += wait;
                                cpustate->task.limit = seg.limit;
                                cpustate->task.base = seg.base;
                                cpustate->task.flags = seg.flags | 2;
index 57f0dfa..0528c9c 100644 (file)
@@ -2969,7 +2969,7 @@ static void I386OP(group0F00_32)(i386_state *cpustate)          // Opcode 0x0f 0
        UINT8 modrm = FETCH(cpustate);
        I386_SREG seg;
        UINT8 result;
-
+       int wait;
        switch( (modrm >> 3) & 0x7 )
        {
                case 0:         /* SLDT */
@@ -3058,8 +3058,8 @@ static void I386OP(group0F00_32)(i386_state *cpustate)          // Opcode 0x0f 0
 
                                UINT32 addr = ((seg.selector & 4) ? cpustate->ldtr.base : cpustate->gdtr.base) + (seg.selector & ~7) + 5;
                                i386_translate_address(cpustate, TRANSLATE_READ, &addr, NULL);
-                               cpustate->program->write_data8(addr, (seg.flags & 0xff) | 2);
-
+                               cpustate->program->write_data8w(addr, (seg.flags & 0xff) | 2, &wait);
+                               cpustate->memory_wait += wait;
                                cpustate->task.limit = seg.limit;
                                cpustate->task.base = seg.base;
                                cpustate->task.flags = seg.flags | 2;
index 3f9042d..54464be 100644 (file)
@@ -372,7 +372,6 @@ INLINE UINT8 sreg_get_flags(UINT32 high)
 
 INLINE UINT8 sreg_get_flags_from_u64(UINT64 src)
 {
-       pair32_t ret;
        pair64_t pa;
 
        pa.q = src;
@@ -675,6 +674,7 @@ struct i386_state
        bool lock;
        UINT32 waitfactor;
        UINT64 waitcount;
+       int memory_wait;
        // Below is only for debugging, no need to save/load state.
        UINT64 exception_code;
        UINT32 exception_pc;
@@ -866,6 +866,7 @@ INLINE int i386_translate_address(i386_state *cpustate, int intention, offs_t *a
        bool user = (intention & TRANSLATE_USER_MASK) ? true : false;
        bool write = (intention & TRANSLATE_WRITE) ? true : false;
        bool debug = (intention & TRANSLATE_DEBUG_MASK) ? true : false;
+       int wait;
 
        if(!(cpustate->cr[0] & I386_CR0_PG)) // paging is disabled
        {
@@ -874,7 +875,8 @@ INLINE int i386_translate_address(i386_state *cpustate, int intention, offs_t *a
                return TRUE;
        }
        // Paging is enabled
-       UINT32 page_dir = cpustate->program->read_data32(pdbr + directory * 4);
+       UINT32 page_dir = cpustate->program->read_data32w(pdbr + directory * 4, &wait);
+       cpustate->memory_wait += wait;
        if(page_dir & 1)
        {
                if ((page_dir & 0x80) && (cpustate->cr[4] & I386_CR4_PSE))
@@ -894,16 +896,21 @@ INLINE int i386_translate_address(i386_state *cpustate, int intention, offs_t *a
                        {
                                if(write)
                                        perm |= VTLB_FLAG_DIRTY;
-                               if(!(page_dir & 0x40) && write)
-                                       cpustate->program->write_data32(pdbr + directory * 4, page_dir | 0x60);
-                               else if(!(page_dir & 0x20))
-                                       cpustate->program->write_data32(pdbr + directory * 4, page_dir | 0x20);
+                               if(!(page_dir & 0x40) && write) {
+                                       cpustate->program->write_data32w(pdbr + directory * 4, page_dir | 0x60, &wait);
+                                       cpustate->memory_wait += wait;
+                               }
+                               else if(!(page_dir & 0x20)) {                                   
+                                       cpustate->program->write_data32w(pdbr + directory * 4, page_dir | 0x20, &wait);
+                                       cpustate->memory_wait += wait;
+                               }
                                ret = TRUE;
                        }
                }
                else
                {
-                       UINT32 page_entry = cpustate->program->read_data32((page_dir & 0xfffff000) + (table * 4));
+                       UINT32 page_entry = cpustate->program->read_data32w((page_dir & 0xfffff000) + (table * 4), &wait);
+                       cpustate->memory_wait += wait;
                        if(!(page_entry & 1))
                                ret = FALSE;
                        else
@@ -923,12 +930,18 @@ INLINE int i386_translate_address(i386_state *cpustate, int intention, offs_t *a
                                {
                                        if(write)
                                                perm |= VTLB_FLAG_DIRTY;
-                                       if(!(page_dir & 0x20))
-                                               cpustate->program->write_data32(pdbr + directory * 4, page_dir | 0x20);
-                                       if(!(page_entry & 0x40) && write)
-                                               cpustate->program->write_data32((page_dir & 0xfffff000) + (table * 4), page_entry | 0x60);
-                                       else if(!(page_entry & 0x20))
-                                               cpustate->program->write_data32((page_dir & 0xfffff000) + (table * 4), page_entry | 0x20);
+                                       if(!(page_dir & 0x20)) {
+                                               cpustate->program->write_data32w(pdbr + directory * 4, page_dir | 0x20, &wait);
+                                               cpustate->memory_wait += wait;
+                                       }
+                                       if(!(page_entry & 0x40) && write) {
+                                               cpustate->program->write_data32w((page_dir & 0xfffff000) + (table * 4), page_entry | 0x60, &wait);
+                                               cpustate->memory_wait += wait;
+                                       }
+                                       else if(!(page_entry & 0x20)) {
+                                               cpustate->program->write_data32w((page_dir & 0xfffff000) + (table * 4), page_entry | 0x20, &wait);
+                                               cpustate->memory_wait += wait;
+                                       }
                                        ret = TRUE;
                                }
                        }
@@ -954,6 +967,7 @@ INLINE int i386_translate_address_with_width(i386_state *cpustate, int intention
        bool user = (intention & TRANSLATE_USER_MASK) ? true : false;
        bool write = (intention & TRANSLATE_WRITE) ? true : false;
        bool debug = (intention & TRANSLATE_DEBUG_MASK) ? true : false;
+       int wait = 0;
 
        if(!(cpustate->cr[0] & I386_CR0_PG)) // paging is disabled
        {
@@ -962,7 +976,8 @@ INLINE int i386_translate_address_with_width(i386_state *cpustate, int intention
                return TRUE;
        }
        // Paging is enabled
-       UINT32 page_dir = cpustate->program->read_data32(pdbr + directory * 4);
+       UINT32 page_dir = cpustate->program->read_data32w(pdbr + directory * 4, &wait);
+       cpustate->memory_wait += wait;
        if(page_dir & 1)
        {
                if ((page_dir & 0x80) && (cpustate->cr[4] & I386_CR4_PSE))
@@ -985,16 +1000,21 @@ INLINE int i386_translate_address_with_width(i386_state *cpustate, int intention
                        {
                                if(write)
                                        perm |= VTLB_FLAG_DIRTY;
-                               if(!(page_dir & 0x40) && write)
-                                       cpustate->program->write_data32(pdbr + directory * 4, page_dir | 0x60);
-                               else if(!(page_dir & 0x20))
-                                       cpustate->program->write_data32(pdbr + directory * 4, page_dir | 0x20);
+                               if(!(page_dir & 0x40) && write) {
+                                       cpustate->program->write_data32w(pdbr + directory * 4, page_dir | 0x60, &wait);
+                                       cpustate->memory_wait += wait;
+                               }
+                               else if(!(page_dir & 0x20)) {
+                                       cpustate->program->write_data32w(pdbr + directory * 4, page_dir | 0x20, &wait);
+                                       cpustate->memory_wait += wait;
+                               }
                                ret = TRUE;
                        }
                }
                else
                {
-                       UINT32 page_entry = cpustate->program->read_data32((page_dir & 0xfffff000) + (table * 4));
+                       UINT32 page_entry = cpustate->program->read_data32w((page_dir & 0xfffff000) + (table * 4), &wait);
+                       cpustate->memory_wait += wait;
                        if(!(page_entry & 1))
                                ret = FALSE;
                        else
@@ -1018,12 +1038,18 @@ INLINE int i386_translate_address_with_width(i386_state *cpustate, int intention
                                {
                                        if(write)
                                                perm |= VTLB_FLAG_DIRTY;
-                                       if(!(page_dir & 0x20))
-                                               cpustate->program->write_data32(pdbr + directory * 4, page_dir | 0x20);
-                                       if(!(page_entry & 0x40) && write)
-                                               cpustate->program->write_data32((page_dir & 0xfffff000) + (table * 4), page_entry | 0x60);
-                                       else if(!(page_entry & 0x20))
-                                               cpustate->program->write_data32((page_dir & 0xfffff000) + (table * 4), page_entry | 0x20);
+                                       if(!(page_dir & 0x20)) {
+                                               cpustate->program->write_data32w(pdbr + directory * 4, page_dir | 0x20, &wait);
+                                               cpustate->memory_wait += wait;
+                                       }
+                                       if(!(page_entry & 0x40) && write) {
+                                               cpustate->program->write_data32w((page_dir & 0xfffff000) + (table * 4), page_entry | 0x60, &wait);
+                                               cpustate->memory_wait += wait;
+                                       }
+                                       else if(!(page_entry & 0x20)) {
+                                               cpustate->program->write_data32w((page_dir & 0xfffff000) + (table * 4), page_entry | 0x20, &wait);
+                                               cpustate->memory_wait += wait;
+                                       }
                                        ret = TRUE;
                                }
                        }
@@ -1148,11 +1174,13 @@ INLINE UINT8 FETCH(i386_state *cpustate)
 {
        UINT8 value;
        UINT32 address = cpustate->pc, error;
-
+       int wait;
        if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_FETCH,&address,&error))
                PF_THROW(error);
 
-       value = cpustate->program->read_data8(address & cpustate->a20_mask);
+       value = cpustate->program->read_data8w(address & cpustate->a20_mask, &wait);
+       cpustate->memory_wait += wait;
+
 #ifdef DEBUG_MISSING_OPCODE
        cpustate->opcode_bytes[cpustate->opcode_bytes_length] = value;
        cpustate->opcode_bytes_length = (cpustate->opcode_bytes_length + 1) & 15;
@@ -1165,15 +1193,17 @@ INLINE UINT16 FETCH16(i386_state *cpustate)
 {
        UINT16 value;
        UINT32 address = cpustate->pc, error;
-
+       int wait;
        if( !WORD_ALIGNED(address) ) {       /* Unaligned read */
                if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_FETCH,2,&address,&error)) {
                        value = (FETCH(cpustate) << 0);
                        value |= (FETCH(cpustate) << 8);
                } else {
                        UINT32 mask = cpustate->a20_mask;
-                       value  = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
-                       value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
+                       value  = ((cpustate->program->read_data8w((address + 0) & mask, &wait)) << 0);
+                       cpustate->memory_wait += wait;
+                       value |= ((cpustate->program->read_data8w((address + 1) & mask, &wait)) << 8);
+                       cpustate->memory_wait += wait;
                        cpustate->eip += 2;
                        cpustate->pc += 2;
                }
@@ -1181,7 +1211,8 @@ INLINE UINT16 FETCH16(i386_state *cpustate)
                if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_FETCH,&address,&error))
                        PF_THROW(error);
                address &= cpustate->a20_mask;
-               value = cpustate->program->read_data16(address);
+               value = cpustate->program->read_data16w(address, &wait);
+               cpustate->memory_wait += wait;
                cpustate->eip += 2;
                cpustate->pc += 2;
        }
@@ -1191,7 +1222,7 @@ INLINE UINT32 FETCH32(i386_state *cpustate)
 {
        UINT32 value;
        UINT32 address = cpustate->pc, error;
-
+       int wait;
        if( !DWORD_ALIGNED(cpustate->pc) ) {      /* Unaligned read */
                if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_FETCH,4,&address,&error)) {
                        value = (FETCH(cpustate) << 0);
@@ -1202,13 +1233,19 @@ INLINE UINT32 FETCH32(i386_state *cpustate)
                } else {
                        UINT32 mask = cpustate->a20_mask;
                        if(WORD_ALIGNED(cpustate->pc)) {
-                               value  = ((cpustate->program->read_data16((address + 0) & mask)) << 0);
-                               value |= ((cpustate->program->read_data16((address + 2) & mask)) << 16);
+                               value  = (cpustate->program->read_data16w((address + 0) & mask, &wait) << 0);
+                               cpustate->memory_wait += wait;
+                               value |= (cpustate->program->read_data16w((address + 2) & mask, &wait) << 16);
+                               cpustate->memory_wait += wait;
                        } else {
-                               value  = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
-                               value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
-                               value |= ((cpustate->program->read_data8((address + 2) & mask)) << 16);
-                               value |= ((cpustate->program->read_data8((address + 3) & mask)) << 24);
+                               value  = ((cpustate->program->read_data8w((address + 0) & mask, &wait)) << 0);
+                               cpustate->memory_wait += wait;
+                               value |= ((cpustate->program->read_data8w((address + 1) & mask, &wait)) << 8);
+                               cpustate->memory_wait += wait;
+                               value |= ((cpustate->program->read_data8w((address + 2) & mask, &wait)) << 16);
+                               cpustate->memory_wait += wait;
+                               value |= ((cpustate->program->read_data8w((address + 3) & mask, &wait)) << 24);
+                               cpustate->memory_wait += wait;
                        }
                        cpustate->eip += 4;
                        cpustate->pc += 4;
@@ -1218,7 +1255,8 @@ INLINE UINT32 FETCH32(i386_state *cpustate)
                        PF_THROW(error);
 
                address &= cpustate->a20_mask;
-               value = cpustate->program->read_data32(address);
+               value = cpustate->program->read_data32w(address, &wait);
+               cpustate->memory_wait += wait;
                cpustate->eip += 4;
                cpustate->pc += 4;
        }
@@ -1228,18 +1266,21 @@ INLINE UINT32 FETCH32(i386_state *cpustate)
 INLINE UINT8 READ8(i386_state *cpustate,UINT32 ea)
 {
        UINT32 address = ea, error;
+       int wait;
 
        if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_READ,&address, &error))
                PF_THROW(error);
 
        address &= cpustate->a20_mask;
-       return cpustate->program->read_data8(address);
+       uint32_t val = cpustate->program->read_data8w(address, &wait);
+       cpustate->memory_wait += wait;
+       return val;
 }
 INLINE UINT16 READ16(i386_state *cpustate,UINT32 ea)
 {
        UINT16 value;
        UINT32 address = ea, error;
-
+       int wait;
        if( !WORD_ALIGNED(ea) ) {        /* Unaligned read */
                if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_READ,2,&address,&error)) {
                //      PF_THROW(error);
@@ -1247,15 +1288,18 @@ INLINE UINT16 READ16(i386_state *cpustate,UINT32 ea)
                        value |= (READ8( cpustate, address+1 ) << 8);
                } else {
                        UINT32 mask = cpustate->a20_mask;
-                       value  = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
-                       value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
+                       value  = ((cpustate->program->read_data8w((address + 0) & mask, &wait)) << 0);
+                       cpustate->memory_wait += wait;
+                       value |= ((cpustate->program->read_data8w((address + 1) & mask, &wait)) << 8);
+                       cpustate->memory_wait += wait;
                }
        } else {
                if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_READ,&address,&error))
                        PF_THROW(error);
 
                address &= cpustate->a20_mask;
-               value = cpustate->program->read_data16( address );
+               value = cpustate->program->read_data16w( address , &wait);
+               cpustate->memory_wait += wait;
        }
        return value;
 }
@@ -1263,7 +1307,7 @@ INLINE UINT32 READ32(i386_state *cpustate,UINT32 ea)
 {
        UINT32 value;
        UINT32 address = ea, error;
-
+       int wait;
        if( !DWORD_ALIGNED(ea) ) {        /* Unaligned read */
                if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_READ,4,&address,&error)) {
                        value  = (READ8( cpustate, address+0 ) << 0);
@@ -1273,13 +1317,19 @@ INLINE UINT32 READ32(i386_state *cpustate,UINT32 ea)
                } else {
                        UINT32 mask = cpustate->a20_mask;
                        if(WORD_ALIGNED(ea)) {
-                               value  = ((cpustate->program->read_data16((address + 0) & mask)) << 0);
-                               value |= ((cpustate->program->read_data16((address + 2) & mask)) << 16);
+                               value  = ((cpustate->program->read_data16w((address + 0) & mask, &wait)) << 0);
+                               cpustate->memory_wait += wait;
+                               value |= ((cpustate->program->read_data16w((address + 2) & mask, &wait)) << 16);
+                               cpustate->memory_wait += wait;
                        } else {
-                               value  = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
-                               value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
-                               value |= ((cpustate->program->read_data8((address + 2) & mask)) << 16);
-                               value |= ((cpustate->program->read_data8((address + 3) & mask)) << 24);
+                               value  = ((cpustate->program->read_data8w((address + 0) & mask, &wait)) << 0);
+                               cpustate->memory_wait += wait;
+                               value |= ((cpustate->program->read_data8w((address + 1) & mask, &wait)) << 8);
+                               cpustate->memory_wait += wait;
+                               value |= ((cpustate->program->read_data8w((address + 2) & mask, &wait)) << 16);
+                               cpustate->memory_wait += wait;
+                               value |= ((cpustate->program->read_data8w((address + 3) & mask, &wait)) << 24);
+                               cpustate->memory_wait += wait;
                        }
                }
        } else {
@@ -1287,7 +1337,8 @@ INLINE UINT32 READ32(i386_state *cpustate,UINT32 ea)
                        PF_THROW(error);
 
                address &= cpustate->a20_mask;
-               value = cpustate->program->read_data32( address );
+               value = cpustate->program->read_data32w( address , &wait);
+               cpustate->memory_wait += wait;
        }
        return value;
 }
@@ -1296,7 +1347,7 @@ INLINE UINT64 READ64(i386_state *cpustate,UINT32 ea)
 {
        UINT64 value;
        UINT32 address = ea, error;
-
+       int wait;
        if( !QWORD_ALIGNED(ea) ) {        /* Unaligned read */
                if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_READ,8,&address,&error)) {
                        value = (((UINT64) READ8( cpustate, address+0 )) << 0);
@@ -1312,23 +1363,37 @@ INLINE UINT64 READ64(i386_state *cpustate,UINT32 ea)
                        UINT32 mask = cpustate->a20_mask;
                        if(!DWORD_ALIGNED(ea)) {
                                if(WORD_ALIGNED(ea)) { // Aligned by 2
-                                       value  = (((UINT64)cpustate->program->read_data16((address + 0) & mask)) << 0);
-                                       value |= (((UINT64)cpustate->program->read_data16((address + 2) & mask)) << 16);
-                                       value |= (((UINT64)cpustate->program->read_data16((address + 4) & mask)) << 32);
-                                       value |= (((UINT64)cpustate->program->read_data16((address + 6) & mask)) << 48);
+                                       value  = (((UINT64)cpustate->program->read_data16w((address + 0) & mask, &wait)) << 0);
+                                       cpustate->memory_wait += wait;
+                                       value |= (((UINT64)cpustate->program->read_data16w((address + 2) & mask, &wait)) << 16);
+                                       cpustate->memory_wait += wait;
+                                       value |= (((UINT64)cpustate->program->read_data16w((address + 4) & mask, &wait)) << 32);
+                                       cpustate->memory_wait += wait;
+                                       value |= (((UINT64)cpustate->program->read_data16w((address + 6) & mask, &wait)) << 48);
+                                       cpustate->memory_wait += wait;
                                } else { // never aligned
-                                       value  = (((UINT64)cpustate->program->read_data8((address + 0) & mask)) << 0);
-                                       value |= (((UINT64)cpustate->program->read_data8((address + 1) & mask)) << 8);
-                                       value |= (((UINT64)cpustate->program->read_data8((address + 2) & mask)) << 16);
-                                       value |= (((UINT64)cpustate->program->read_data8((address + 3) & mask)) << 24);
-                                       value |= (((UINT64)cpustate->program->read_data8((address + 4) & mask)) << 32);
-                                       value |= (((UINT64)cpustate->program->read_data8((address + 5) & mask)) << 40);
-                                       value |= (((UINT64)cpustate->program->read_data8((address + 6) & mask)) << 48);
-                                       value |= (((UINT64)cpustate->program->read_data8((address + 7) & mask)) << 56);
+                                       value  = (((UINT64)cpustate->program->read_data8w((address + 0) & mask, &wait)) << 0);
+                                       cpustate->memory_wait += wait;
+                                       value |= (((UINT64)cpustate->program->read_data8w((address + 1) & mask, &wait)) << 8);
+                                       cpustate->memory_wait += wait;
+                                       value |= (((UINT64)cpustate->program->read_data8w((address + 2) & mask, &wait)) << 16);
+                                       cpustate->memory_wait += wait;
+                                       value |= (((UINT64)cpustate->program->read_data8w((address + 3) & mask, &wait)) << 24);
+                                       cpustate->memory_wait += wait;
+                                       value |= (((UINT64)cpustate->program->read_data8w((address + 4) & mask, &wait)) << 32);
+                                       cpustate->memory_wait += wait;
+                                       value |= (((UINT64)cpustate->program->read_data8w((address + 5) & mask, &wait)) << 40);
+                                       cpustate->memory_wait += wait;
+                                       value |= (((UINT64)cpustate->program->read_data8w((address + 6) & mask, &wait)) << 48);
+                                       cpustate->memory_wait += wait;
+                                       value |= (((UINT64)cpustate->program->read_data8w((address + 7) & mask, &wait)) << 56);
+                                       cpustate->memory_wait += wait;
                                }
                        } else { // Align of 4
-                               value = (((UINT64) cpustate->program->read_data32( (address+0) & mask )) << 0);
-                               value |= (((UINT64) cpustate->program->read_data32( (address+4) & mask )) << 32);
+                               value = (((UINT64) cpustate->program->read_data32w( (address+0) & mask, &wait )) << 0);
+                               cpustate->memory_wait += wait;
+                               value |= (((UINT64) cpustate->program->read_data32w( (address+4) & mask, &wait )) << 32);
+                               cpustate->memory_wait += wait;
                        }
                }
        } else {
@@ -1336,41 +1401,48 @@ INLINE UINT64 READ64(i386_state *cpustate,UINT32 ea)
                        PF_THROW(error);
 
                address &= cpustate->a20_mask;
-               value = (((UINT64) cpustate->program->read_data32( address+0 )) << 0);
-               value |= (((UINT64) cpustate->program->read_data32( address+4 )) << 32);
+               value = (((UINT64) cpustate->program->read_data32w( address+0, &wait )) << 0);
+               cpustate->memory_wait += wait;
+               value |= (((UINT64) cpustate->program->read_data32w( address+4, &wait )) << 32);
+               cpustate->memory_wait += wait;
        }
        return value;
 }
 INLINE UINT8 READ8PL0(i386_state *cpustate,UINT32 ea)
 {
        UINT32 address = ea, error;
-
+       int wait;
        if(!translate_address(cpustate,0,TRANSLATE_READ,&address,&error))
                PF_THROW(error);
 
        address &= cpustate->a20_mask;
-       return cpustate->program->read_data8(address);
+       uint32_t val = cpustate->program->read_data8w(address, &wait);
+       cpustate->memory_wait += wait;
+       return val;
 }
 INLINE UINT16 READ16PL0(i386_state *cpustate,UINT32 ea)
 {
        UINT16 value;
        UINT32 address = ea, error;
-
+       int wait;
        if( !WORD_ALIGNED(ea) ) {        /* Unaligned read */
                UINT32 mask = cpustate->a20_mask;
                if(!translate_address_with_width(cpustate,0,TRANSLATE_READ,2,&address,&error)) {
                        value  =  READ8PL0(cpustate, ea + 0);
                        value |= (READ8PL0(cpustate, ea + 1) << 8);
                } else {                        
-                       value  = cpustate->program->read_data8((address + 0) & mask);
-                       value |= (cpustate->program->read_data8((address + 1) & mask) << 8);
+                       value  = cpustate->program->read_data8w((address + 0) & mask, &wait);
+                       cpustate->memory_wait += wait;
+                       value |= (cpustate->program->read_data8w((address + 1) & mask, &wait) << 8);
+                       cpustate->memory_wait += wait;
                }
        } else {
                if(!translate_address(cpustate,0,TRANSLATE_READ,&address,&error))
                        PF_THROW(error);
 
                address &= cpustate->a20_mask;
-               value = cpustate->program->read_data16( address );
+               value = cpustate->program->read_data16w( address, &wait );
+               cpustate->memory_wait += wait;
        }
        return value;
 }
@@ -1379,7 +1451,8 @@ INLINE UINT32 READ32PL0(i386_state *cpustate,UINT32 ea)
 {
        UINT32 value;
        UINT32 address = ea, error;
-
+       int wait;
+       
        if( !DWORD_ALIGNED(ea) ) {        /* Unaligned read */
                UINT32 mask = cpustate->a20_mask;
                if(!translate_address_with_width(cpustate,0,TRANSLATE_READ,4,&address,&error)) {
@@ -1389,13 +1462,19 @@ INLINE UINT32 READ32PL0(i386_state *cpustate,UINT32 ea)
                        value |= (READ8PL0(cpustate, ea + 3) << 24);
                } else {
                        if(WORD_ALIGNED(ea)) {
-                               value  = cpustate->program->read_data16((address + 0) & mask);
-                               value |= (cpustate->program->read_data16((address + 2) & mask) << 16);
+                               value  = cpustate->program->read_data16w((address + 0) & mask, &wait);
+                               cpustate->memory_wait += wait;
+                               value |= (cpustate->program->read_data16w((address + 2) & mask, &wait) << 16);
+                               cpustate->memory_wait += wait;
                        } else {
-                               value  = cpustate->program->read_data8((address + 0) & mask);
-                               value |= (cpustate->program->read_data8((address + 1) & mask) << 8);
-                               value |= (cpustate->program->read_data8((address + 2) & mask) << 16);
-                               value |= (cpustate->program->read_data8((address + 3) & mask) << 24);
+                               value  = cpustate->program->read_data8w((address + 0) & mask, &wait);
+                               cpustate->memory_wait += wait;
+                               value |= (cpustate->program->read_data8w((address + 1) & mask, &wait) << 8);
+                               cpustate->memory_wait += wait;
+                               value |= (cpustate->program->read_data8w((address + 2) & mask, &wait) << 16);
+                               cpustate->memory_wait += wait;
+                               value |= (cpustate->program->read_data8w((address + 3) & mask, &wait) << 24);
+                               cpustate->memory_wait += wait;
                        }
                }
        } else {
@@ -1403,7 +1482,8 @@ INLINE UINT32 READ32PL0(i386_state *cpustate,UINT32 ea)
                        PF_THROW(error);
 
                address &= cpustate->a20_mask;
-               value = cpustate->program->read_data32( address );
+               value = cpustate->program->read_data32w( address, &wait);
+               cpustate->memory_wait += wait;
        }
        return value;
 }
@@ -1421,10 +1501,12 @@ INLINE void WRITE8(i386_state *cpustate,UINT32 ea, UINT8 value)
 
        if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_WRITE,&address,&error))
                PF_THROW(error);
-
+       int wait = 0;
        address &= cpustate->a20_mask;
-       cpustate->program->write_data8(address, value);
+       cpustate->program->write_data8w(address, value, &wait);
+       cpustate->memory_wait += wait;
 }
+
 INLINE void WRITE16(i386_state *cpustate,UINT32 ea, UINT16 value)
 {
        UINT32 address = ea, error;
@@ -1435,15 +1517,21 @@ INLINE void WRITE16(i386_state *cpustate,UINT32 ea, UINT16 value)
                        WRITE8( cpustate, address+1, (value >> 8) & 0xff );
                } else {
                        uint32_t mask = cpustate->a20_mask;
-                       cpustate->program->write_data8((address + 0) & mask, value & 0xff);
-                       cpustate->program->write_data8((address + 1) & mask, (value >> 8) & 0xff);
+                       int wait;
+                       cpustate->program->write_data8w((address + 0) & mask, value & 0xff, &wait);
+                       cpustate->memory_wait += wait;
+
+                       cpustate->program->write_data8w((address + 1) & mask, (value >> 8) & 0xff, &wait);
+                       cpustate->memory_wait += wait;
+
                }
        } else {
                if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_WRITE,&address,&error))
                        PF_THROW(error);
-
+               int wait;
                address &= cpustate->a20_mask;
-               cpustate->program->write_data16(address, value);
+               cpustate->program->write_data16w(address, value, &wait);
+               cpustate->memory_wait += wait;
        }
 }
 INLINE void WRITE32(i386_state *cpustate,UINT32 ea, UINT32 value)
@@ -1457,30 +1545,38 @@ INLINE void WRITE32(i386_state *cpustate,UINT32 ea, UINT32 value)
                        WRITE8( cpustate, address+2, (value >> 16) & 0xff );
                        WRITE8( cpustate, address+3, (value >> 24) & 0xff );
                } else {
+                       int wait;
                        uint32_t mask = cpustate->a20_mask;
                        if(!WORD_ALIGNED(ea)) {
-                               cpustate->program->write_data8((address + 0) & mask, value & 0xff);
-                               cpustate->program->write_data8((address + 1) & mask, (value >> 8) & 0xff);
-                               cpustate->program->write_data8((address + 2) & mask, (value >> 16) & 0xff);
-                               cpustate->program->write_data8((address + 3) & mask, (value >> 24) & 0xff);
+                               cpustate->program->write_data8w((address + 0) & mask, value & 0xff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data8w((address + 1) & mask, (value >> 8) & 0xff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data8w((address + 2) & mask, (value >> 16) & 0xff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data8w((address + 3) & mask, (value >> 24) & 0xff, &wait);
+                               cpustate->memory_wait += wait;
                        } else { // Aligned by 2
-                               cpustate->program->write_data16((address + 0) & mask, value & 0xffff);
-                               cpustate->program->write_data16((address + 2) & mask, (value >> 16) & 0xffff);
+                               cpustate->program->write_data16w((address + 0) & mask, value & 0xffff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data16w((address + 2) & mask, (value >> 16) & 0xffff, &wait);
+                               cpustate->memory_wait += wait;
                        }
                }
        } else {
                if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_WRITE,&address,&error))
                        PF_THROW(error);
-
+               int wait;
                address &= cpustate->a20_mask;
-               cpustate->program->write_data32(address, value);
+               cpustate->program->write_data32w(address, value, &wait);
+               cpustate->memory_wait += wait;
        }
 }
 
 INLINE void WRITE64(i386_state *cpustate,UINT32 ea, UINT64 value)
 {
        UINT32 address = ea, error;
-
+       int wait;
        if( !QWORD_ALIGNED(ea) ) {        /* Unaligned write */
                if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_WRITE,8,&address,&error)) {
                        WRITE8( cpustate, address+0, value & 0xff );
@@ -1494,22 +1590,36 @@ INLINE void WRITE64(i386_state *cpustate,UINT32 ea, UINT64 value)
                } else {
                        uint32_t mask = cpustate->a20_mask;
                        if(DWORD_ALIGNED(ea)) { // Aligned by 4
-                               cpustate->program->write_data32((address + 0) & mask, value & 0xffffffff);
-                               cpustate->program->write_data32((address + 4) & mask, (value >> 32) & 0xffffffff);
+                               cpustate->program->write_data32w((address + 0) & mask, value & 0xffffffff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data32w((address + 4) & mask, (value >> 32) & 0xffffffff, &wait);
+                               cpustate->memory_wait += wait;
                        } else if(!WORD_ALIGNED(ea)) { // Never aligned
-                               cpustate->program->write_data8((address + 0) & mask, value & 0xff);
-                               cpustate->program->write_data8((address + 1) & mask, (value >> 8) & 0xff);
-                               cpustate->program->write_data8((address + 2) & mask, (value >> 16) & 0xff);
-                               cpustate->program->write_data8((address + 3) & mask, (value >> 24) & 0xff);
-                               cpustate->program->write_data8((address + 4) & mask, (value >> 32) & 0xff);
-                               cpustate->program->write_data8((address + 5) & mask, (value >> 40) & 0xff);
-                               cpustate->program->write_data8((address + 6) & mask, (value >> 48) & 0xff);
-                               cpustate->program->write_data8((address + 7) & mask, (value >> 56) & 0xff);
+                               cpustate->program->write_data8w((address + 0) & mask, value & 0xff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data8w((address + 1) & mask, (value >> 8) & 0xff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data8w((address + 2) & mask, (value >> 16) & 0xff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data8w((address + 3) & mask, (value >> 24) & 0xff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data8w((address + 4) & mask, (value >> 32) & 0xff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data8w((address + 5) & mask, (value >> 40) & 0xff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data8w((address + 6) & mask, (value >> 48) & 0xff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data8w((address + 7) & mask, (value >> 56) & 0xff, &wait);
+                               cpustate->memory_wait += wait;
                        } else { // Aligned by 2
-                               cpustate->program->write_data16((address + 0) & mask, value & 0xffff);
-                               cpustate->program->write_data16((address + 2) & mask, (value >> 16) & 0xffff);
-                               cpustate->program->write_data16((address + 4) & mask, (value >> 32) & 0xffff);
-                               cpustate->program->write_data16((address + 6) & mask, (value >> 48) & 0xffff);
+                               cpustate->program->write_data16w((address + 0) & mask, value & 0xffff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data16w((address + 2) & mask, (value >> 16) & 0xffff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data16w((address + 4) & mask, (value >> 32) & 0xffff, &wait);
+                               cpustate->memory_wait += wait;
+                               cpustate->program->write_data16w((address + 6) & mask, (value >> 48) & 0xffff, &wait);
+                               cpustate->memory_wait += wait;
                        }
                }
        } else {
@@ -1517,8 +1627,10 @@ INLINE void WRITE64(i386_state *cpustate,UINT32 ea, UINT64 value)
                        PF_THROW(error);
 
                address &= cpustate->a20_mask;
-               cpustate->program->write_data32(address+0, value & 0xffffffff);
-               cpustate->program->write_data32(address+4, (value >> 32) & 0xffffffff);
+               cpustate->program->write_data32w(address+0, value & 0xffffffff, &wait);
+               cpustate->memory_wait += wait;
+               cpustate->program->write_data32w(address+4, (value >> 32) & 0xffffffff, &wait);
+               cpustate->memory_wait += wait;
        }
 }
 
@@ -1878,13 +1990,18 @@ INLINE void check_ioperm(i386_state *cpustate, offs_t port, UINT8 mask)
 INLINE UINT8 READPORT8(i386_state *cpustate, offs_t port)
 {
        check_ioperm(cpustate, port, 1);
-       return cpustate->io->read_io8(port);
+       int wait;
+    UINT8 val = cpustate->io->read_io8w(port, &wait);
+       cpustate->memory_wait += wait;
+       return val;
 }
 
 INLINE void WRITEPORT8(i386_state *cpustate, offs_t port, UINT8 value)
 {
        check_ioperm(cpustate, port, 1);
-       cpustate->io->write_io8(port, value);
+       int wait;
+       cpustate->io->write_io8w(port, value, &wait);
+       cpustate->memory_wait += wait;
 }
 
 INLINE UINT16 READPORT16(i386_state *cpustate, offs_t port)
@@ -1897,8 +2014,11 @@ INLINE UINT16 READPORT16(i386_state *cpustate, offs_t port)
        }
        else
        {
+               int wait;
                check_ioperm(cpustate, port, 3);
-               return cpustate->io->read_io16(port);
+               UINT16 val = cpustate->io->read_io16w(port, &wait);
+               cpustate->memory_wait += wait;
+               return val;
        }
 }
 
@@ -1912,7 +2032,9 @@ INLINE void WRITEPORT16(i386_state *cpustate, offs_t port, UINT16 value)
        else
        {
                check_ioperm(cpustate, port, 3);
-               cpustate->io->write_io16(port, value);
+               int wait;
+               cpustate->io->write_io16w(port, value, &wait);
+               cpustate->memory_wait += wait;
        }
 }
 
@@ -1929,7 +2051,10 @@ INLINE UINT32 READPORT32(i386_state *cpustate, offs_t port)
        else
        {
                check_ioperm(cpustate, port, 0xf);
-               return cpustate->io->read_io32(port);
+               int wait;
+               UINT32 val = cpustate->io->read_io32w(port, &wait);
+               cpustate->memory_wait += wait;
+               return val;
        }
 }
 
@@ -1945,7 +2070,9 @@ INLINE void WRITEPORT32(i386_state *cpustate, offs_t port, UINT32 value)
        else
        {
                check_ioperm(cpustate, port, 0xf);
-               cpustate->io->write_io32(port, value);
+               int wait;
+               cpustate->io->write_io32w(port, value, &wait);
+               cpustate->memory_wait += wait;
        }
 }
 
index 68d6d16..f325e0d 100644 (file)
@@ -430,23 +430,37 @@ void DISPLAY::event_frame()
 
 void DISPLAY::write_signal(int ch, uint32_t data, uint32_t mask)
 {
-       if(ch == SIG_DISPLAY98_SET_PAGE_A0) {
-               data = data & 0x000e0000; // ToDo: Hi RESO
-               if((data < 0x000a0000) || (data >= 0x000f0000)) data = 0x80000000;
-               bank_table[0x0a] = data;
-               bank_table[0x0b] = data + 0x00010000;
-       } else if(ch == SIG_DISPLAY98_SET_PAGE_80) {
-               data = data & 0x000e0000; // ToDo: Hi RESO
-               if((data < 0x000a0000) || (data >= 0x000f0000)) data = 0x80000000;
-               bank_table[0x08] = data;
-               bank_table[0x09] = data + 0x00010000;
-       } else if(ch == SIG_DISPLAY98_SET_BANK) {
+       switch(ch) {
+       case SIG_DISPLAY98_SET_PAGE_A0:
+               {
+                       data = data & 0x000e0000; // ToDo: Hi RESO
+                       if((data < 0x000a0000) || (data >= 0x000f0000)) data = 0x80000000;
+                       bank_table[0x0a] = data;
+                       bank_table[0x0b] = data + 0x00010000;
+               }
+               break;
+       case SIG_DISPLAY98_SET_PAGE_80:
+               {
+                       data = data & 0x000e0000; // ToDo: Hi RESO
+                       if((data < 0x000a0000) || (data >= 0x000f0000)) data = 0x80000000;
+                       bank_table[0x08] = data;
+                       bank_table[0x09] = data + 0x00010000;
+               }
+               break;
+       case SIG_DISPLAY98_SET_BANK:
                // WIP: Still dummy.
                vram_bank = ((data & mask) != 0) ? 0x10000 : 0x00000;
-       } /*else if(ch == SIG_DISPLAY98_HIGH_RESOLUTION) {
-               display_high = ((data & mask) != 0);
-               printf("DISP MODE=%d\n", display_high);
-       }*/
+               break;
+       /*case SIG_DISPLAY98_HIGH_RESOLUTION:
+                 {
+                 display_high = ((data & mask) != 0);
+                 printf("DISP MODE=%d\n", display_high);
+                 }
+                 break;
+       */
+       default:
+               break;
+       }
 }
 
 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
@@ -980,7 +994,7 @@ void DISPLAY::write_memory_mapped_io16(uint32_t addr, uint32_t data)
 uint32_t DISPLAY::read_memory_mapped_io8(uint32_t addr)
 {
        uint32_t idx = (addr & 0x000f0000) >> 16;
-       if(bank_table[idx] >= 0x80000000) return;
+       if(bank_table[idx] >= 0x80000000) return 0xff;
        addr = bank_table[idx] | (addr & 0x0000ffff);
        
        addr = addr & 0x000fffff; // For 32bit
@@ -1059,7 +1073,7 @@ uint32_t DISPLAY::read_memory_mapped_io8(uint32_t addr)
 uint32_t DISPLAY::read_memory_mapped_io16(uint32_t addr)
 {
        uint32_t idx = (addr & 0x000f0000) >> 16;
-       if(bank_table[idx] >= 0x80000000) return;
+       if(bank_table[idx] >= 0x80000000) return 0xffff;
        addr = bank_table[idx] | (addr & 0x0000ffff);
        
        addr = addr & 0x000fffff; // For 32bit
@@ -2995,7 +3009,7 @@ void DISPLAY::draw_gfx_screen()
        }
 }
 
-#define STATE_VERSION  7
+#define STATE_VERSION  8
 
 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
 {
@@ -3075,11 +3089,12 @@ bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
 //     state_fio->StateValue(font_lr);
        state_fio->StateValue(b_gfx_ff);
 //     state_fio->StateValue(vram_bank);
+
        state_fio->StateArray(bank_table, sizeof(bank_table), 1);
        
        // post process
-#if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO)
        if(loading) {
+#if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO)
                if(vram_disp_sel & 1) {
                        vram_disp_b = vram + 0x28000;
                        vram_disp_r = vram + 0x30000;
@@ -3110,8 +3125,8 @@ bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
                        grcg_tile_word[i] = ((uint16_t)(grcg_tile[i]) << 8) | grcg_tile[i];
                }
        #endif
-       }
 #endif
+       }
        return true;
 }
 
index 2fdfa70..448dbc9 100644 (file)
@@ -28,6 +28,7 @@
 #define SIG_DISPLAY98_SET_PAGE_A0              2
 #define SIG_DISPLAY98_SET_BANK                 3
 //#define SIG_DISPLAY98_HIGH_RESOLUTION        4
+
 class UPD7220;
 
 namespace PC9801 {
@@ -219,6 +220,7 @@ private:
        void egc_writeb(uint32_t addr1, uint8_t value);
        void egc_writew(uint32_t addr1, uint16_t value);
 #endif
+
        void draw_chr_screen();
        void draw_gfx_screen();
        void init_memsw();
@@ -239,6 +241,10 @@ public:
        void event_frame();
        void write_io8(uint32_t addr, uint32_t data);
        uint32_t read_io8(uint32_t addr);
+//     void write_memory_mapped_io8w(uint32_t addr, uint32_t data, int* wait);
+//     void write_memory_mapped_io16w(uint32_t addr, uint32_t data, int* wait);
+//     uint32_t read_memory_mapped_io8w(uint32_t addr, int* wait);
+//     uint32_t read_memory_mapped_io16w(uint32_t addr, int* wait);
        void write_memory_mapped_io8(uint32_t addr, uint32_t data);
        void write_memory_mapped_io16(uint32_t addr, uint32_t data);
        uint32_t read_memory_mapped_io8(uint32_t addr);
index 000c98c..9249f40 100644 (file)
@@ -97,6 +97,8 @@ void MEMBUS::initialize()
        // RAM
        memset(ram, 0x00, sizeof(ram));
        // VRAM
+       gvram_wait_val = 1;
+       tvram_wait_val = 4;
        
        // BIOS
        memset(bios, 0xff, sizeof(bios));
@@ -176,6 +178,13 @@ void MEMBUS::initialize()
        last_access_is_interam = false;
        config_intram();
        update_bios();
+
+       intram_wait = 1;
+       bank08_wait = 10;
+       exmem_wait = 2;
+       slotmem_wait = 2;
+       exboards_wait = 4;
+       introm_wait = 1;
 }
 
 void MEMBUS::reset()
@@ -559,6 +568,47 @@ void MEMBUS::write_dma_data8(uint32_t addr, uint32_t data)
 }
 #endif
 
+void MEMBUS::write_signal(int ch, uint32_t data, uint32_t mask)
+{
+       switch(ch) {
+       case SIG_INTRAM_WAIT:
+               intram_wait = (int)(data & 0xff);
+               update_bios();
+               break;
+       case SIG_BANK08_WAIT:
+               bank08_wait = (int)(data & 0xff);
+               update_bios();
+               break;
+       case SIG_EXMEM_WAIT:
+               exmem_wait = (int)(data & 0xff);
+               update_bios();
+               break;
+       case SIG_SLOTMEM_WAIT:
+               slotmem_wait = (int)(data & 0xff);
+               update_bios();
+               break;
+       case SIG_EXBOARDS_WAIT:
+               exboards_wait = (int)(data & 0xff);
+               update_bios();
+               break;
+       case SIG_INTROM_WAIT:
+               introm_wait = (int)(data & 0xff);
+               update_bios();
+               break;
+       case SIG_GVRAM_WAIT:
+               gvram_wait_val = (int)(data & 0xff);
+               update_bios();
+               break;
+       case SIG_TVRAM_WAIT:
+               tvram_wait_val = (int)(data & 0xff);
+               update_bios();
+               break;
+       default:
+               break;
+       }
+}
+
+               
 uint32_t MEMBUS::read_signal(int ch)
 {
        switch(ch) {
@@ -600,8 +650,12 @@ void MEMBUS::update_bios()
        #endif
        set_memory_mapped_io_rw(0xa0000, 0xa4fff, d_display);
        set_memory_mapped_io_rw(0xa8000, 0xbffff, d_display);
+       set_wait_rw(0xa0000, 0xbffff, gvram_wait_val); // OK?
+       set_wait_r(0xa0000, 0xa4fff, tvram_wait_val);
+       set_wait_w(0xa0000, 0xa4fff, tvram_wait_val);
 #else
        unset_memory_rw(0xc0000, 0xe4fff);
+       set_wait_rw(0xc0000, 0xe4fff, intram_wait);
 #endif
 #if !defined(SUPPORT_HIRESO)
        {
@@ -613,6 +667,7 @@ void MEMBUS::update_bios()
                #endif
                #if defined(SUPPORT_16_COLORS)
                set_memory_mapped_io_rw(0xe0000, 0xe7fff, d_display);
+               set_wait_rw(0xe0000, 0xe7fff, gvram_wait_val); // OK?
                #endif
                update_sound_bios();
 
@@ -631,9 +686,11 @@ void MEMBUS::update_bios()
        #if defined(SUPPORT_BIOS_RAM) && defined(SUPPORT_32BIT_ADDRESS)
        if(shadow_ram_selected) {
                set_memory_rw(0xc0000, 0xe7fff, &(ram[0xc0000])); // OK?
+               set_wait_rw(0xc0000, 0xe7fff, intram_wait);
        }
        #endif
 #endif
+       set_wait_rw(0x00100000 - sizeof(bios), 0xfffff, introm_wait);
        {       
 #if defined(SUPPORT_BIOS_RAM)
                if(bios_ram_selected) {
@@ -671,7 +728,11 @@ void MEMBUS::update_bios()
                }
        }
        #endif
+       if(sizeof(ram) > 0x10000) {
+               set_wait_rw(0x00100000, (sizeof(ram) >= 0x00e00000) ? 0x00dfffff : (sizeof(ram) - 1), exmem_wait);
+       }
        if((page08_intram_selected) /*&& (shadow_ram_selected)*/){
+               set_wait_rw(0x80000, 0x9ffff, bank08_wait);
                if((window_80000h == 0xc0000)) {
 #if defined(UPPER_I386)  && defined(SUPPORT_BIOS_RAM)
                        if(shadow_ram_selected) {
@@ -715,6 +776,7 @@ void MEMBUS::update_bios()
        } else {
                // Internal RAM is not selected.
                // ToDo: Hi reso
+               set_wait_rw(0x80000, 0x9ffff, bank08_wait);
                if(window_80000h < 0x80000) {
                #if defined(SUPPORT_BIOS_RAM)
                        if(!(bios_ram_selected)) {
@@ -731,7 +793,12 @@ void MEMBUS::update_bios()
                        copy_table_rw(0x00080000, window_80000h, window_80000h + 0x1ffff);
                }
        }
-
+       if(shadow_ram_selected) {
+//             set_wait_rw(0xa0000, 0xbffff, bank08_wait);
+               set_wait_rw(0xa0000, 0xbffff, intram_wait);
+       } else {
+               set_wait_rw(0xa0000, 0xbffff, intram_wait);
+       }
        /*if((page08_intram_selected) )*/{
                if((window_a0000h == 0xc0000)) {
 #if defined(UPPER_I386) && defined(SUPPORT_BIOS_RAM)
@@ -814,6 +881,7 @@ void MEMBUS::update_sound_bios()
        } else {
                unset_memory_rw(0xcc000, 0xcffff);
        }
+       set_wait_rw(0xcc000, 0xcffff, exboards_wait);
 }
 
 #if defined(SUPPORT_SASI_IF)
@@ -831,6 +899,7 @@ void MEMBUS::update_sasi_bios()
        } else {
                unset_memory_rw(0xd7000, 0xd7fff);
        }
+       set_wait_rw(0xd7000, 0xd7fff, exboards_wait);
 }
 #endif
 
@@ -847,6 +916,7 @@ void MEMBUS::update_scsi_bios()
        } else {
                unset_memory_rw(0xdc000, 0xdcfff);
        }
+       set_wait_rw(0xdc000, 0xdcfff, exboards_wait);
 }
 #endif
 
@@ -861,6 +931,7 @@ void MEMBUS::update_ide_bios()
        } else {
                unset_memory_rw(0xd8000, 0xdbfff);
        }
+       set_wait_rw(0xd8000, 0xdbfff, exboards_wait);
 }
 #endif
 
@@ -874,11 +945,12 @@ void MEMBUS::update_nec_ems()
                unset_memory_rw(0xb0000, 0xbffff);
                set_memory_mapped_io_rw(0xb0000, 0xbffff, d_display);
        }
+       set_wait_rw(0xb0000, 0xbffff, slotmem_wait);
 }
 #endif
 
 
-#define STATE_VERSION  12
+#define STATE_VERSION  13
 
 bool MEMBUS::process_state(FILEIO* state_fio, bool loading)
 {
@@ -931,7 +1003,16 @@ bool MEMBUS::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(page08_intram_selected);
        state_fio->StateValue(shadow_ram_selected);
        state_fio->StateValue(last_access_is_interam);
-       
+
+       state_fio->StateValue(intram_wait);
+       state_fio->StateValue(bank08_wait);
+       state_fio->StateValue(exmem_wait);
+       state_fio->StateValue(slotmem_wait);
+       state_fio->StateValue(exboards_wait);
+       state_fio->StateValue(introm_wait);
+       state_fio->StateValue(gvram_wait_val);
+       state_fio->StateValue(tvram_wait_val);
+
        if(!MEMORY::process_state(state_fio, loading)) {
                return false;
        }
index e8808e4..c0bf15f 100644 (file)
@@ -40,7 +40,15 @@ namespace PC9801 {
 namespace PC9801 {
 
 #define SIG_LAST_ACCESS_INTERAM 1
-
+#define SIG_INTRAM_WAIT                        2
+#define SIG_BANK08_WAIT                        3
+#define SIG_EXMEM_WAIT                 4
+#define SIG_SLOTMEM_WAIT               5
+#define SIG_EXBOARDS_WAIT              6
+#define SIG_INTROM_WAIT                        7
+#define SIG_TVRAM_WAIT                 8
+#define SIG_GVRAM_WAIT                 9
+       
 class MEMBUS : public MEMORY
 {
 private:
@@ -69,6 +77,15 @@ private:
        uint8_t itf[0x8000];
        bool itf_selected;
 #endif
+
+       int intram_wait;
+       int bank08_wait;
+       int exmem_wait;
+       int slotmem_wait;
+       int exboards_wait;
+       int introm_wait;
+       int gvram_wait_val;
+       int tvram_wait_val;
        void update_bios();
        
 #if !defined(SUPPORT_HIRESO)
@@ -136,6 +153,7 @@ public:
        void initialize();
        void reset();
        uint32_t read_signal(int ch);
+       void write_signal(int ch, uint32_t data, uint32_t mask);
        void write_io8(uint32_t addr, uint32_t data);
        uint32_t read_io8(uint32_t addr);
 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
index 88f3edc..9601afe 100644 (file)
@@ -1085,6 +1085,180 @@ void VM::set_cpu_clock_with_switch(int speed_type)
        pit->set_constant_clock(2, pit_clocks);
 }
 
+void VM::set_wait(int dispmode, int clock)
+{
+       // by PC-9800 Technical Data Book (HARDWARE), ASCII, 1993.
+       int io_wait       = 8;  // I/O
+       int slotmem_wait  = 4;  // Extra RAM on extra bus.
+       int exmem_wait    = 1;  // Extra RAM on extra memory slot.
+       int exboards_wait = 8; // BANK 0C, 0D
+       int introm_wait   = 0;  // INTERNAL ROM (BIOS, ITF)
+       int bank08_wait   = 2/*8*/;
+       int intram_wait   = 0;
+       int cpuclock      = 8000000;
+       // TODO: INTA
+#if defined(_PC9801RA) || defined(_PC9801RL)
+       // PC-9801RA21
+       intram_wait = 0;
+       if(clock == 0) { // FAST CLOCK (20MHz)
+               cpuclock = 20000000;
+#if defined(_SUPPORT_HIRESO)           
+               if(dispmode != 0) { // Low RESO
+                       exboards_wait = 12;
+               } else {
+                       introm_wait = 6;
+               }
+#else
+               exboards_wait = 12;
+#endif
+               io_wait = 10;
+       } else {
+               cpuclock = 16000000;
+#if defined(_SUPPORT_HIRESO)           
+               if(dispmode != 0) { // Low RESO
+                       exboards_wait = 10;
+               } else {
+                       introm_wait = 4;
+               }
+#else
+               exboards_wait = 10;
+#endif
+               io_wait = 8;
+       }
+       
+#elif defined(_PC98XL2)
+       // ToDo: V30
+       cpuclock = 16000000;
+       if(dispmode == 0) {
+               intram_wait = 1;
+               bank08_wait = 1;
+               io_wait = 10;
+               introm_wait = 6;
+               slotmem_wait  = 6;
+               exmem_wait    = 1;
+               exboards_wait = 4;
+               // inta_wait = 14;
+       } else { // Normal
+               intram_wait = 1;
+               bank08_wait = 1;
+               io_wait = 10;
+               introm_wait = 1;
+               slotmem_wait  = 6;
+               exmem_wait    = 1;
+               exboards_wait = 12;
+               // inta_wait = 14;
+       }
+       
+#elif defined(_PC98XL)
+       if(dispmode == 0) {
+               intram_wait = 1;
+               bank08_wait = 1;
+               io_wait = 3;
+               introm_wait = 1;
+               slotmem_wait  = 1;
+               exmem_wait    = 1;
+               exboards_wait = 4;
+               cpuclock = 8000000;
+               if(clock == 0) { // FAST CLOCK (10MHz)
+                       io_wait += 1;
+                       exboards_wait = 1;
+                       cpuclock = 10000000;
+               }
+               // inta_wait = 5;
+       } else { // Normal
+               intram_wait = 0;
+               bank08_wait = 0;
+               io_wait = 3;
+               introm_wait = 0;
+               slotmem_wait  = 0;
+               exmem_wait    = 1;
+               exboards_wait = 4;
+               cpuclock = (clock == 0) ? 10000000 : 8000000;
+       }
+       
+#elif defined(_PC9801VM21) || defined(_PC9801VX)
+       // ToDo: V30
+       // They are for 80286.
+       if(clock == 0) { // FAST CLOCK (10MHz)
+               cpuclock = 10000000;
+               intram_wait = 0;
+               bank08_wait = 5;
+               io_wait = 4;
+               introm_wait = 0;
+               slotmem_wait  = 1;
+               exmem_wait    = 1;
+               exboards_wait = 5;
+       } else { // SLOW (8MHz)
+               cpuclock = 8000000;
+               intram_wait = 0;
+               io_wait = 3;
+               bank08_wait = 4;
+               introm_wait = 0;
+               slotmem_wait  = 1;
+               exmem_wait    = 1;
+               exboards_wait = 4;
+               // inta_wait = 5;
+       }               
+#elif defined(_PC9801U) || defined(_PC9801VF) || defined(_PC9801VM) || defined(_PC9801UV)
+       if(clock == 0) { // FAST CLOCK (10MHz)
+               cpuclock = 10000000;
+               intram_wait = 1;
+               io_wait = 3;
+       } else { // SLOW (8MHz)
+               cpuclock = 8000000;
+               intram_wait = 0;
+               io_wait = 2;
+       }               
+       slotmem_wait  = intram_wait;
+       exmem_wait    = intram_wait;
+       exboards_wait = intram_wait;
+       introm_wait   = intram_wait;
+       bank08_wait   = intram_wait;
+#elif defined(_PC98XA)
+       cpuclock = 8000000;
+       intram_wait = 1;
+       io_wait = 3;
+       // inta_wait = 2;
+       slotmem_wait  = intram_wait;
+       exmem_wait    = intram_wait;
+       exboards_wait = intram_wait;
+       introm_wait   = intram_wait;
+       bank08_wait   = intram_wait;
+#elif defined(_PC9801E) || defined(_PC9801F) || defined(_PC9801M) || defined(_PC9801)
+       // ToDo: Others.
+       if(clock == 0) { // FAST CLOCK (8MHz)
+               cpuclock = 8000000;
+               intram_wait = 1;
+               io_wait = 2;
+       } else {
+               cpuclock = 5000000;
+               intram_wait = 0;
+               io_wait = 1;
+       }               
+       slotmem_wait  = intram_wait;
+       exmem_wait    = intram_wait;
+       exboards_wait = intram_wait;
+       introm_wait   = intram_wait;
+       bank08_wait   = intram_wait;
+#endif
+       memory->write_signal(SIG_INTRAM_WAIT, intram_wait, 0xff);
+       memory->write_signal(SIG_BANK08_WAIT, bank08_wait, 0xff);
+       memory->write_signal(SIG_EXMEM_WAIT, exmem_wait, 0xff);
+       memory->write_signal(SIG_SLOTMEM_WAIT, slotmem_wait, 0xff);
+       memory->write_signal(SIG_EXBOARDS_WAIT, exboards_wait, 0xff);
+       memory->write_signal(SIG_INTROM_WAIT, introm_wait, 0xff);
+       // IO
+       io->set_iowait_range_r(0x0000, 0xffff, io_wait);
+       io->set_iowait_range_w(0x0000, 0xffff, io_wait);
+       // ToDo: Wait factor
+       int waitval;
+       waitval = (int)round(((double)cpuclock) / (1.0e6 / 1.6));
+       if(waitval < 1) waitval = 0;
+       memory->write_signal(SIG_TVRAM_WAIT, waitval, 0xfffff); // OK?
+       memory->write_signal(SIG_GVRAM_WAIT, intram_wait, 0xfffff); // OK?
+//     memory->write_signal(SIG_GVRAM_WAIT, waitval, 0xfffff); // OK?
+}      
+
 void VM::reset()
 {
        // Set resolution before resetting.
@@ -1095,6 +1269,7 @@ void VM::reset()
                io->set_iovalue_single_r(0x0431, 0x00);
                gdc_gfx->set_horiz_freq(24830);
                gdc_chr->set_horiz_freq(24830);
+               
        } else { // WIP
                io->set_iovalue_single_r(0x0431, 0x04); // bit2: 1 = Normal mode, 0 = Hireso mode
                gdc_gfx->set_horiz_freq(15750);
@@ -1114,6 +1289,11 @@ void VM::reset()
 #endif
        set_cpu_clock_with_switch((config.cpu_type != 0) ? 1 : 0);
        
+#if defined(USE_MONITOR_TYPE)
+       set_wait(config.monitor_type, config.cpu_type);
+#else
+       set_wait(0, config.cpu_type);
+#endif 
        port_a  = 0x00;
 //     port_a |= 0x80; // DIP SW 2-8, 1 = GDC 2.5MHz, 0 = GDC 5MHz
        port_a |= 0x40; // DIP SW 2-7, 1 = Do not control FD motor
@@ -1715,9 +1895,15 @@ bool VM::is_frame_skippable()
        return event->is_frame_skippable();
 }
 
+
 void VM::update_config()
 {
        set_cpu_clock_with_switch((config.cpu_type != 0) ? 1 : 0);
+#if defined(USE_MONITOR_TYPE)
+       set_wait(config.monitor_type, config.cpu_type);
+#else
+       set_wait(0, config.cpu_type);
+#endif 
        {
                uint8_t mouse_port_b = pio_mouse->read_signal(SIG_I8255_PORT_B);
                mouse_port_b = mouse_port_b & ~0x40;
@@ -1801,6 +1987,11 @@ bool VM::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(sound_type);
        if(loading) {
                set_cpu_clock_with_switch((config.cpu_type != 0) ? 1 : 0);
+#if defined(USE_MONITOR_TYPE)
+               set_wait(config.monitor_type, config.cpu_type);
+#else
+               set_wait(0, config.cpu_type);
+#endif 
        }
        return true;
 }
index 07dece0..b73dc98 100644 (file)
@@ -665,6 +665,7 @@ public:
        // for each device
        // ----------------------------------------
        void set_cpu_clock_with_switch(int speed_type); // 0 = High / 1 = Low / Others = (WIP)
+       void set_wait(int dispmode, int clock); // Set waitfor memories and IOs.
        
        // devices
        DEVICE* get_device(int id);