+ if(mmc5_wram_protect0 == 0x02 && mmc5_wram_protect1 == 0x01) {
+ if(mmc5_wram_bank[3] < 8) {
+ bank_ptr[3][addr & 0x1fff] = data;
+ }
+ }
+}
+
+void FAMILYBASIC_MEMORY::mmc5_hi_write(uint32_t addr, uint32_t data)
+{
+ if(mmc5_wram_protect0 == 0x02 && mmc5_wram_protect1 == 0x01) {
+ if(addr < 0xa000) {
+ if(mmc5_wram_bank[4] < 8) {
+ bank_ptr[4][addr & 0x1fff] = data;
+ }
+ } else if(addr < 0xc000) {
+ if(mmc5_wram_bank[5] < 8) {
+ bank_ptr[5][addr & 0x1fff] = data;
+ }
+ } else if(addr < 0xe000) {
+ if(mmc5_wram_bank[6] < 8) {
+ bank_ptr[6][addr & 0x1fff] = data;
+ }
+ } else {
+ if(mmc5_wram_bank[7] < 8) {
+ bank_ptr[7][addr & 0x1fff] = data;
+ }
+ }
+ }
+}
+
+void FAMILYBASIC_MEMORY::mmc5_hsync(int v)
+{
+ if(v <= 240) {
+ if(v == mmc5_irq_line) {
+ if(d_ppu->spr_enabled() && d_ppu->bg_enabled()) {
+ mmc5_irq_status |= 0x80;
+ }
+ }
+ if((mmc5_irq_status & 0x80) && (mmc5_irq_enabled & 0x80)) {
+ d_cpu->write_signal(SIG_CPU_IRQ, 1, 1);
+ }
+ } else {
+ mmc5_irq_status |= 0x40;
+ }
+}
+
+void FAMILYBASIC_MEMORY::mmc5_set_cpu_bank(uint8_t bank, uint32_t bank_num)
+{
+ if(bank_num & 0x80) {
+ if(mmc5_prg_size == 0) {
+ if(bank == 7) {
+ set_rom_bank(4, (bank_num & 0x7c) + 0);
+ set_rom_bank(5, (bank_num & 0x7c) + 1);
+ set_rom_bank(6, (bank_num & 0x7c) + 2);
+ set_rom_bank(7, (bank_num & 0x7c) + 3);
+ }
+ } else if(mmc5_prg_size == 1) {
+ if(bank == 5) {
+ set_rom_bank(4, (bank_num & 0x7e) + 0);
+ set_rom_bank(5, (bank_num & 0x7e) + 1);
+ } else if(bank == 7) {
+ set_rom_bank(6, (bank_num & 0x7e) + 0);
+ set_rom_bank(7, (bank_num & 0x7e) + 1);
+ }
+ } else if(mmc5_prg_size == 2) {
+ if(bank == 5) {
+ set_rom_bank(4, (bank_num & 0x7e) + 0);
+ set_rom_bank(5, (bank_num & 0x7e) + 1);
+ } else if(bank == 6) {
+ set_rom_bank(6, bank_num & 0x7f);
+ } else if(bank == 7) {
+ set_rom_bank(7, bank_num & 0x7f);
+ }
+ } else if(mmc5_prg_size == 3) {
+ if(bank == 4) {
+ set_rom_bank(4, bank_num & 0x7f);
+ } else if(bank == 5) {
+ set_rom_bank(5, bank_num & 0x7f);
+ } else if(bank == 6) {
+ set_rom_bank(6, bank_num & 0x7f);
+ } else if(bank == 7) {
+ set_rom_bank(7, bank_num & 0x7f);
+ }
+ }
+ } else {
+ if(mmc5_prg_size == 1) {
+ if(bank == 5) {
+ mmc5_set_wram_bank(4, (bank_num & 0x06)+0);
+ mmc5_set_wram_bank(5, (bank_num & 0x06)+1);
+ }
+ } else if(mmc5_prg_size == 2) {
+ if(bank == 5) {
+ mmc5_set_wram_bank(4, (bank_num & 0x06)+0);
+ mmc5_set_wram_bank(5, (bank_num & 0x06)+1);
+ } else if(bank == 6)
+ {
+ mmc5_set_wram_bank(6, bank_num & 0x07);
+ }
+ } else if(mmc5_prg_size == 3) {
+ if(bank == 4) {
+ mmc5_set_wram_bank(4, bank_num & 0x07);
+ } else if(bank == 5) {
+ mmc5_set_wram_bank(5, bank_num & 0x07);
+ } else if(bank == 6) {
+ mmc5_set_wram_bank(6, bank_num & 0x07);
+ }
+ }
+ }
+}
+
+void FAMILYBASIC_MEMORY::mmc5_set_wram_bank(uint8_t bank, uint32_t bank_num)
+{
+ if(bank_num < 8) {
+ bank_ptr[bank] = save_ram + 0x2000 * bank_num;
+ mmc5_wram_bank[bank] = bank_num;
+ } else {
+ set_rom_bank(bank, banks[bank]);
+ }
+}
+
+void FAMILYBASIC_MEMORY::mmc5_set_ppu_bank(uint8_t mode)
+{
+ if(mmc5_chr_size == 0) {
+ d_ppu->set_ppu_bank(0, mmc5_chr_reg[7][mode] * 8 + 0);
+ d_ppu->set_ppu_bank(1, mmc5_chr_reg[7][mode] * 8 + 1);
+ d_ppu->set_ppu_bank(2, mmc5_chr_reg[7][mode] * 8 + 2);
+ d_ppu->set_ppu_bank(3, mmc5_chr_reg[7][mode] * 8 + 3);
+ d_ppu->set_ppu_bank(4, mmc5_chr_reg[7][mode] * 8 + 4);
+ d_ppu->set_ppu_bank(5, mmc5_chr_reg[7][mode] * 8 + 5);
+ d_ppu->set_ppu_bank(6, mmc5_chr_reg[7][mode] * 8 + 6);
+ d_ppu->set_ppu_bank(7, mmc5_chr_reg[7][mode] * 8 + 7);
+ } else if(mmc5_chr_size == 1) {
+ d_ppu->set_ppu_bank(0, mmc5_chr_reg[3][mode] * 4 + 0);
+ d_ppu->set_ppu_bank(1, mmc5_chr_reg[3][mode] * 4 + 1);
+ d_ppu->set_ppu_bank(2, mmc5_chr_reg[3][mode] * 4 + 2);
+ d_ppu->set_ppu_bank(3, mmc5_chr_reg[3][mode] * 4 + 3);
+ d_ppu->set_ppu_bank(4, mmc5_chr_reg[7][mode] * 4 + 0);
+ d_ppu->set_ppu_bank(5, mmc5_chr_reg[7][mode] * 4 + 1);
+ d_ppu->set_ppu_bank(6, mmc5_chr_reg[7][mode] * 4 + 2);
+ d_ppu->set_ppu_bank(7, mmc5_chr_reg[7][mode] * 4 + 3);
+ } else if(mmc5_chr_size == 2) {
+ d_ppu->set_ppu_bank(0, mmc5_chr_reg[1][mode] * 2 + 0);
+ d_ppu->set_ppu_bank(1, mmc5_chr_reg[1][mode] * 2 + 1);
+ d_ppu->set_ppu_bank(2, mmc5_chr_reg[3][mode] * 2 + 0);
+ d_ppu->set_ppu_bank(3, mmc5_chr_reg[3][mode] * 2 + 1);
+ d_ppu->set_ppu_bank(4, mmc5_chr_reg[5][mode] * 2 + 0);
+ d_ppu->set_ppu_bank(5, mmc5_chr_reg[5][mode] * 2 + 1);
+ d_ppu->set_ppu_bank(6, mmc5_chr_reg[7][mode] * 2 + 0);
+ d_ppu->set_ppu_bank(7, mmc5_chr_reg[7][mode] * 2 + 1);
+ } else {
+ d_ppu->set_ppu_bank(0, mmc5_chr_reg[0][mode]);
+ d_ppu->set_ppu_bank(1, mmc5_chr_reg[1][mode]);
+ d_ppu->set_ppu_bank(2, mmc5_chr_reg[2][mode]);
+ d_ppu->set_ppu_bank(3, mmc5_chr_reg[3][mode]);
+ d_ppu->set_ppu_bank(4, mmc5_chr_reg[4][mode]);
+ d_ppu->set_ppu_bank(5, mmc5_chr_reg[5][mode]);
+ d_ppu->set_ppu_bank(6, mmc5_chr_reg[6][mode]);
+ d_ppu->set_ppu_bank(7, mmc5_chr_reg[7][mode]);
+ }
+}
+
+uint8_t FAMILYBASIC_MEMORY::mmc5_ppu_latch_render(uint8_t mode, uint32_t addr)
+{
+ uint8_t data = 0;
+
+ if(mmc5_gfx_mode == 1 && mode == 1) {
+ // ex gfx mode
+ uint32_t bank_num = ((d_ppu->get_name_tables() + 0x800)[addr] & 0x3f) << 2;
+ d_ppu->set_ppu_bank(0, bank_num + 0);
+ d_ppu->set_ppu_bank(1, bank_num + 1);
+ d_ppu->set_ppu_bank(2, bank_num + 2);
+ d_ppu->set_ppu_bank(3, bank_num + 3);
+ d_ppu->set_ppu_bank(4, bank_num + 0);
+ d_ppu->set_ppu_bank(5, bank_num + 1);
+ d_ppu->set_ppu_bank(6, bank_num + 2);
+ d_ppu->set_ppu_bank(7, bank_num + 3);
+ data = (((d_ppu->get_name_tables() + 0x800)[addr] & 0xc0) >> 4) | 0x01;
+ } else {
+ // normal
+ mmc5_set_ppu_bank(mode);
+ }
+ return data;
+}
+
+// vrc7
+
+void FAMILYBASIC_MEMORY::vrc7_reset()
+{
+ if(header.mapper() == 85) {
+ vrc7_irq_enabled = 0;
+ vrc7_irq_counter = 0;
+ vrc7_irq_latch = 0;
+ d_opll->write_signal(SIG_YM2413_MUTE, 0, 0);
+ set_rom_bank(4, 0);
+ set_rom_bank(5, 1);
+ set_rom_bank(6, header.num_8k_rom_banks() - 2);
+ set_rom_bank(7, header.num_8k_rom_banks() - 1);
+ } else {
+ d_opll->write_signal(SIG_YM2413_MUTE, 1, 1);
+ }
+}
+
+//uint32_t FAMILYBASIC_MEMORY::vrc7_lo_read(uint32_t addr)
+//{
+// return 0xff;
+//}
+
+//void FAMILYBASIC_MEMORY::vrc7_lo_write(uint32_t addr, uint32_t data)
+//{
+//}
+
+//uint32_t FAMILYBASIC_MEMORY::vrc7_save_read(uint32_t addr)
+//{
+// return bank_ptr[3][addr & 0x1fff];
+//}
+
+//void FAMILYBASIC_MEMORY::vrc7_save_write(uint32_t addr, uint32_t data)
+//{
+// bank_ptr[3][addr & 0x1fff] = data;
+//}
+
+void FAMILYBASIC_MEMORY::vrc7_hi_write(uint32_t addr, uint32_t data)
+{
+ switch(addr & 0xf038) {
+ case 0x8000:
+ set_rom_bank(4, data);
+ break;
+ case 0x8008:
+ case 0x8010:
+ set_rom_bank(5, data);
+ break;
+ case 0x9000:
+ set_rom_bank(6, data);
+ break;
+ case 0x9010:
+ case 0x9030:
+ d_opll->write_io8(addr >> 5, data);
+ break;
+ case 0xa000:
+ d_ppu->set_ppu_bank(0, data);
+ break;
+ case 0xa008:
+ case 0xa010:
+ d_ppu->set_ppu_bank(1, data);
+ break;
+ case 0xb000:
+ d_ppu->set_ppu_bank(2, data);
+ break;
+ case 0xb008:
+ case 0xb010:
+ d_ppu->set_ppu_bank(3, data);
+ break;
+ case 0xc000:
+ d_ppu->set_ppu_bank(4, data);
+ break;
+ case 0xc008:
+ case 0xc010:
+ d_ppu->set_ppu_bank(5, data);
+ break;
+ case 0xd000:
+ d_ppu->set_ppu_bank(6, data);
+ break;
+ case 0xd008:
+ case 0xd010:
+ d_ppu->set_ppu_bank(7, data);
+ break;
+ case 0xe000:
+ switch(data & 0x03) {
+ case 0x00:
+ d_ppu->set_mirroring(MIRROR_VERT);
+ break;
+ case 0x01:
+ d_ppu->set_mirroring(MIRROR_HORIZ);
+ break;
+ case 0x02:
+ d_ppu->set_mirroring(0, 0, 0, 0);
+ break;
+ case 0x03:
+ d_ppu->set_mirroring(1, 1, 1, 1);
+ break;
+ }
+ break;
+ case 0xe008:
+ case 0xe010:
+ vrc7_irq_latch = data;
+ break;
+ case 0xf000:
+ if(data & 0x02) {
+ vrc7_irq_counter = vrc7_irq_latch;
+ }
+ vrc7_irq_enabled = data & 0x03;
+ break;
+ case 0xf008:
+ case 0xf010:
+ vrc7_irq_enabled = (vrc7_irq_enabled & 0x01) * 3;
+ break;
+ }
+}
+
+void FAMILYBASIC_MEMORY::vrc7_hsync(int v)
+{
+ if(vrc7_irq_enabled & 0x02) {
+ if(vrc7_irq_counter == 0xff) {
+ d_cpu->write_signal(SIG_CPU_IRQ, 1, 1);
+ vrc7_irq_counter = vrc7_irq_latch;
+ } else {
+ vrc7_irq_counter++;
+ }
+ }
+}
+
+#define STATE_VERSION 2
+
+bool FAMILYBASIC_MEMORY::process_state(FILEIO* state_fio, bool loading)
+{
+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {