OSDN Git Service

[VM][FM7][MAINMEM] MMR: Use jump tables.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Sat, 1 Apr 2017 18:21:56 +0000 (03:21 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Sat, 1 Apr 2017 18:21:56 +0000 (03:21 +0900)
source/src/vm/fm7/fm7_mainmem.cpp
source/src/vm/fm7/fm7_mainmem.h
source/src/vm/fm7/mainmem_mmr.cpp
source/src/vm/fm7/mainmem_readseq.cpp
source/src/vm/fm7/mainmem_utils.cpp
source/src/vm/fm7/mainmem_writeseq.cpp

index dc42c7c..7ec2741 100644 (file)
@@ -84,6 +84,7 @@ void FM7_MAINMEM::reset()
        is_basicrom = ((bootmode & 0x03) == 0) ? true : false;
        setclock(clockmode ? 0 : 1);
        init_data_table();
+       update_all_mmr_jumptable();
        maincpu->reset();
 }
 
@@ -415,10 +416,12 @@ void FM7_MAINMEM::write_data8(uint32_t addr, uint32_t data)
                        } else {
                                mmr_segment = data & 0x03;
                        }
+                       update_all_mmr_jumptable();
                        break;
                default:
                        if((addr >= FM7_MAINIO_MMR_BANK) && (addr < (FM7_MAINIO_MMR_BANK + 0x80))){
                                mmr_map_data[addr - FM7_MAINIO_MMR_BANK] = (uint8_t)data;
+                               update_mmr_jumptable(addr - FM7_MAINIO_MMR_BANK);
                        }
                        break;
                }
@@ -701,6 +704,7 @@ bool FM7_MAINMEM::load_state(FILEIO *state_fio)
 #endif
        }
        init_data_table();
+       update_all_mmr_jumptable();
        if(version != STATE_VERSION) return false;
        return true;
 }
index 211dc05..6a4e262 100644 (file)
@@ -36,6 +36,15 @@ class FM7_MAINMEM : public DEVICE
        } data_func_table_t;
        
        data_func_table_t data_table[ADDRESS_SPACE / 0x80];
+#if defined(HAS_MMR)
+# if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)        
+       data_func_table_t mmr_update_table_ext[(0x80 * 0x1000) / 0x80];
+       uint32_t mmr_baseaddr_table_ext[(0x80 * 0x1000) / 0x80];
+# endif
+       data_func_table_t mmr_update_table_nor[(0x80 * 0x1000) / 0x80];
+       uint32_t mmr_bank_table[(0x80 * 0x1000) / 0x80];
+       uint32_t mmr_baseaddr_table_nor[(0x80 * 0x1000) / 0x80];
+#endif
        bool ioaccess_wait;
        int waitfactor;
        int waitcount;
@@ -155,6 +164,13 @@ class FM7_MAINMEM : public DEVICE
        uint8_t read_data_tbl(uint32_t addr, bool dmamode);
        void write_data_tbl(uint32_t addr, uint32_t data, bool dmamode);
 
+       void update_mmr_jumptable(uint32_t pos);
+       void update_all_mmr_jumptable(void);
+       uint8_t read_segment_3f(uint32_t addr, bool dmamode);
+       void write_segment_3f(uint32_t addr, uint32_t data, bool dmamode);
+       uint8_t read_with_mmr(uint32_t addr, uint32_t segment, uint32_t dmamode);
+       void write_with_mmr(uint32_t addr, uint32_t segment, uint32_t data, uint32_t dmamode);
+
  public:
        FM7_MAINMEM(VM* parent_vm, EMU* parent_emu);
        ~FM7_MAINMEM();
@@ -187,7 +203,6 @@ class FM7_MAINMEM : public DEVICE
        bool load_state(FILEIO *state_fio);
 
        void set_context_display(DEVICE *p){
-               int i;  
                display = p;
        }
        void set_context_maincpu(MC6809 *p){
index 190ca21..10ac9d4 100644 (file)
@@ -28,3 +28,246 @@ int FM7_MAINMEM::window_convert(uint32_t addr, uint32_t *realaddr)
 #endif
        return -1;
 }
+
+void FM7_MAINMEM::update_mmr_jumptable(uint32_t pos)
+{
+#if defined(HAS_MMR)
+# if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)        
+       if(pos >= 0x80) return;
+# else
+       if(pos >= 0x40) return;
+# endif
+       uint32_t n_pos = pos * (0x1000 / 0x80);
+       uint32_t i;
+       uint8_t  mmr_index = mmr_map_data[pos];
+# if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)        
+       uint32_t r_pos_ext = mmr_index * (0x1000 / 0x80);
+# endif
+       uint32_t r_pos_nor = (mmr_index & 0x3f) * (0x1000 / 0x80);
+       uint32_t raddr_nor;
+       uint32_t raddr_ext;
+       raddr_ext = (mmr_index << 12);
+       raddr_nor = ((mmr_index & 0x3f) << 12);
+       
+       for(i = 0; i < (0x1000 / 0x80); i++) {
+# if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)        
+               mmr_bank_table[n_pos] = mmr_index;
+               mmr_baseaddr_table_ext[i + n_pos] = raddr_ext;
+               if(mmr_index != 0x3f) {
+                       mmr_update_table_ext[i + n_pos].read_data = data_table[r_pos_ext + i].read_data;
+                       mmr_update_table_ext[i + n_pos].write_data = data_table[r_pos_ext + i].write_data;
+                       mmr_update_table_ext[i + n_pos].read_func = data_table[r_pos_ext + i].read_func;
+                       mmr_update_table_ext[i + n_pos].write_func = data_table[r_pos_ext + i].write_func;
+               } else {
+                       mmr_update_table_ext[i + n_pos].read_data = NULL;
+                       mmr_update_table_ext[i + n_pos].write_data = NULL;
+                       mmr_update_table_ext[i + n_pos].read_func = &FM7_MAINMEM::read_segment_3f;
+                       mmr_update_table_ext[i + n_pos].write_func = &FM7_MAINMEM::write_segment_3f;
+               }
+# endif
+               mmr_baseaddr_table_nor[i + n_pos] = raddr_nor;
+               if(mmr_index != 0x3f) {
+                       mmr_update_table_nor[i + n_pos].read_data = data_table[r_pos_nor + i].read_data;
+                       mmr_update_table_nor[i + n_pos].write_data = data_table[r_pos_nor + i].write_data;
+                       mmr_update_table_nor[i + n_pos].read_func = data_table[r_pos_nor + i].read_func;
+                       mmr_update_table_nor[i + n_pos].write_func = data_table[r_pos_nor + i].write_func;
+               } else {
+                       mmr_update_table_nor[i + n_pos].read_data = NULL;
+                       mmr_update_table_nor[i + n_pos].write_data = NULL;
+                       mmr_update_table_nor[i + n_pos].read_func = &FM7_MAINMEM::read_segment_3f;
+                       mmr_update_table_nor[i + n_pos].write_func = &FM7_MAINMEM::write_segment_3f;
+               }
+       }
+#endif
+}
+
+void FM7_MAINMEM::update_all_mmr_jumptable(void)
+{
+#if defined(HAS_MMR)
+       uint32_t i;
+# if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)        
+       for(i = 0; i < 0x80; i++) {
+               update_mmr_jumptable(i);
+       }
+# else
+       for(i = 0; i < 0x40; i++) {
+               update_mmr_jumptable(i);
+       }
+# endif
+#endif
+}
+
+uint8_t FM7_MAINMEM::read_segment_3f(uint32_t addr, bool dmamode)
+{
+#if defined(HAS_MMR)
+       uint32_t raddr = addr & 0x0fff;
+# ifdef _FM77AV_VARIANTS
+       if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
+               return 0xff;
+       } else {
+               raddr = raddr | 0x3f000;
+               return read_data_tbl(raddr, dmamode);
+       }
+# elif defined(_FM77_VARIANTS)
+       if((raddr >= 0xc00) && (raddr < 0xe00)) {
+               if(is_basicrom) {
+                       return 0x00;
+               } else {
+                       raddr = raddr - 0xc00;
+                       return fm77_shadowram[raddr];
+               }
+       } else if(raddr >= 0xe00) {
+               raddr = raddr - 0x0e00;
+               if(is_basicrom) {
+                       if(diag_load_bootrom_mmr) {
+                               return fm7_bootroms[2][raddr];
+                       } else {
+                               return fm7_bootroms[0][raddr];
+                       }
+               } else {
+                       return fm7_bootram[raddr];
+               }
+       } else {
+               raddr = raddr | 0x3f000;
+               return read_data_tbl(raddr, dmamode);
+       } 
+# endif
+#else
+       return 0xff;
+#endif
+}
+
+void FM7_MAINMEM::write_segment_3f(uint32_t addr, uint32_t data, bool dmamode)
+{
+#if defined(HAS_MMR)
+       uint32_t raddr = addr & 0x0fff;
+# ifdef _FM77AV_VARIANTS
+       if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
+               return;
+       } else {
+               raddr = raddr | 0x3f000;
+               write_data_tbl(raddr, data, dmamode);
+               return;
+       }
+# elif defined(_FM77_VARIANTS)
+       if((raddr >= 0xc00) && (raddr < 0xe00)) {
+               if(is_basicrom) {
+                       return;
+               } else {
+                       raddr = raddr - 0xc00;
+                       fm77_shadowram[raddr] = (uint8_t)data;
+                       return;
+               }
+       } else if(raddr >= 0xe00) {
+               raddr = raddr - 0x0e00;
+               if(!is_basicrom) {
+                       fm7_bootram[raddr] = (uint8_t)data;
+               }
+       } else {
+               raddr = raddr | 0x3f000;
+               write_data_tbl(raddr, data, dmamode);
+       } 
+# endif
+#else
+       return;
+#endif
+}
+
+uint8_t FM7_MAINMEM::read_with_mmr(uint32_t addr, uint32_t segment, uint32_t dmamode)
+{
+#if defined(HAS_MMR)
+# if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+       uint32_t raddr;
+       uint32_t n_pos;
+       if(!mmr_extend) {
+               n_pos = (segment & 0x03) * (0x10 * 0x1000 / 0x80) + ((addr & 0xffff) >> 7); 
+               if(mmr_update_table_nor[n_pos].read_data != NULL) {
+                       return mmr_update_table_nor[n_pos].read_data[addr & 0x7f];
+               } else if(mmr_update_table_nor[n_pos].read_func != NULL) {
+                       uint8_t (FM7_MAINMEM::*read_func)(uint32_t, bool);
+                       read_func = this->mmr_update_table_nor[n_pos].read_func;
+                       raddr = mmr_baseaddr_table_nor[n_pos] | (addr & 0xfff);
+                       return (this->*read_func)(raddr, dmamode);
+               }
+               return 0xff;
+       } else {
+               n_pos = (segment & 0x0f) * (0x10 * 0x1000 / 0x80) + ((addr & 0xffff) >> 7); 
+               if(mmr_update_table_ext[n_pos].read_data != NULL) {
+                       return mmr_update_table_ext[n_pos].read_data[addr & 0x7f];
+               } else if(mmr_update_table_ext[n_pos].read_func != NULL) {
+                       uint8_t (FM7_MAINMEM::*read_func)(uint32_t, bool);
+                       raddr = mmr_baseaddr_table_ext[n_pos] | (addr & 0xfff);
+                       read_func = this->mmr_update_table_ext[n_pos].read_func;
+                       return (this->*read_func)(raddr, dmamode);
+               }
+               return 0xff;
+       }               
+# else
+       uint32_t n_pos;
+       uint32_t raddr;
+       n_pos = (segment & 0x03) * (0x10 * 0x1000 / 0x80) + ((addr & 0xffff) >> 7); 
+       //n_pos = (((segment & 0x03) * 0x10) | ((addr >> 12) & 0x0f)) * (0x1000 / 0x80) + ((addr & 0xfff) >> 7);  
+       if(mmr_update_table_nor[n_pos].read_data != NULL) {
+               return mmr_update_table_nor[n_pos].read_data[addr & 0x7f];
+       } else if(mmr_update_table_nor[n_pos].read_func != NULL) {
+               uint8_t (FM7_MAINMEM::*read_func)(uint32_t, bool);
+               read_func = this->mmr_update_table_nor[n_pos].read_func;
+               raddr = mmr_baseaddr_table_nor[n_pos] | (addr & 0xfff);
+               return (this->*read_func)(raddr, dmamode);
+       }
+       return 0xff;
+# endif
+#else
+       return 0xff;
+#endif
+}
+
+void FM7_MAINMEM::write_with_mmr(uint32_t addr, uint32_t segment, uint32_t data, uint32_t dmamode)
+{
+#if defined(HAS_MMR)
+# if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+       uint32_t n_pos;
+       uint32_t raddr;
+       if(!mmr_extend) {
+               n_pos = (segment & 0x03) * (0x10 * 0x1000 / 0x80) + ((addr & 0xffff) >> 7); 
+               if(mmr_update_table_nor[n_pos].write_data != NULL) {
+                       mmr_update_table_nor[n_pos].write_data[addr & 0x7f] = (uint8_t)data;
+               } else if(mmr_update_table_nor[n_pos].write_func != NULL) {
+                       void (FM7_MAINMEM::*write_func)(uint32_t, uint32_t, bool);
+                       write_func = this->mmr_update_table_nor[n_pos].write_func;
+                       raddr = mmr_baseaddr_table_nor[n_pos] | (addr & 0xfff);
+                       (this->*write_func)(raddr, data, dmamode);
+               }
+               return;
+       } else {
+               n_pos = (segment & 0x0f) * (0x10 * 0x1000 / 0x80) + ((addr & 0xffff) >> 7); 
+               if(mmr_update_table_ext[n_pos].write_data != NULL) {
+                       mmr_update_table_ext[n_pos].write_data[addr & 0x7f] = (uint8_t)data;
+               } else if(mmr_update_table_ext[n_pos].write_func != NULL) {
+                       void (FM7_MAINMEM::*write_func)(uint32_t, uint32_t, bool);
+                       write_func = this->mmr_update_table_ext[n_pos].write_func;
+                       raddr = mmr_baseaddr_table_ext[n_pos] | (addr & 0xfff);
+                       (this->*write_func)(raddr, data, dmamode);
+               }
+               return;
+       }               
+# else
+       uint32_t n_pos;
+       uint32_t raddr;
+       n_pos = (segment & 0x03) * (0x10 * 0x1000 / 0x80) + ((addr & 0xffff) >> 7);
+       //n_pos = (((segment & 0x03) * 0x10) | ((addr >> 12) & 0x0f)) * (0x1000 / 0x80) + ((addr & 0xfff) >> 7);  
+       if(mmr_update_table_nor[n_pos].write_data != NULL) {
+               mmr_update_table_nor[n_pos].write_data[addr & 0x7f] = (uint8_t)data;
+       } else if(mmr_update_table_nor[n_pos].read_func != NULL) {
+               void (FM7_MAINMEM::*write_func)(uint32_t, uint32_t, bool);
+               write_func = this->mmr_update_table_nor[n_pos].write_func;
+               raddr = mmr_baseaddr_table_nor[n_pos] | (addr & 0xfff);
+               //printf("%08x %08x %08x\n", addr, raddr, n_pos);
+               (this->*write_func)(raddr, data, dmamode);
+       }
+       return;
+# endif
+#else
+       return;
+#endif
+}
index b1e185e..972acb2 100644 (file)
@@ -49,6 +49,9 @@ uint8_t FM7_MAINMEM::read_data(uint32_t addr, bool dmamode)
                uint32_t mmr_bank;
                if(addr < 0xfc00) {
                        if(!dmamode) segment = mmr_segment;
+#if 1
+                       return read_with_mmr(addr, segment, dmamode);
+#else
                        if(!mmr_extend) {
                                mmr_bank = mmr_map_data[(addr >> 12) & 0x000f | ((segment & 0x03) << 4)] & 0x003f;
                        } else {
@@ -94,6 +97,7 @@ uint8_t FM7_MAINMEM::read_data(uint32_t addr, bool dmamode)
                                        return read_data_tbl(raddr, dmamode);
                                } 
                        }
+# endif
 #endif
                } else {
                        raddr = 0x30000 | (addr & 0xffff);
@@ -101,6 +105,7 @@ uint8_t FM7_MAINMEM::read_data(uint32_t addr, bool dmamode)
                }
        }
 #endif
+       
 #if !defined(_FM77AV_VARIANTS) && !defined(_FM77_VARIANTS)
        uint32_t raddr = (addr & 0xffff);
        return read_data_tbl(raddr, dmamode);
index 69693f2..3c4d148 100644 (file)
@@ -213,6 +213,7 @@ void FM7_MAINMEM::initialize(void)
        this->out_debug_log(_T("AV40SX/EX EXTRA ROM READING : %s"), diag_load_extrarom ? "OK" : "NG");
 #endif
        init_data_table();
+       update_all_mmr_jumptable();
 }
 
 void FM7_MAINMEM::release()
index fbd4f44..0b3ca96 100644 (file)
@@ -124,6 +124,10 @@ void FM7_MAINMEM::write_data(uint32_t addr, uint32_t data, bool dmamode)
                uint32_t mmr_bank;
                if(addr < 0xfc00) {
                        if(!dmamode) segment = mmr_segment;
+#if 1
+                       write_with_mmr(addr, segment, data, dmamode);
+                       return;
+#else
                        if(!mmr_extend) {
                                mmr_bank = mmr_map_data[(addr >> 12) & 0x000f | ((segment & 0x03) << 4)] & 0x003f;
                        } else {
@@ -170,6 +174,7 @@ void FM7_MAINMEM::write_data(uint32_t addr, uint32_t data, bool dmamode)
                                        return;
                                } 
                        }
+# endif
 #endif
                } else {
                        raddr = 0x30000 | (addr & 0xffff);