#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
+}