void NES_mapper230::MemoryWrite(uint32 addr, uint8 data) { if(rom_switch) { set_CPU_bank4((data & 0x07)*2+0); set_CPU_bank5((data & 0x07)*2+1); } else { if(data & 0x40) { set_mirroring(NES_PPU::MIRROR_VERT); } else { set_mirroring(NES_PPU::MIRROR_HORIZ); } if(data & 0x20) { set_CPU_bank4((data & 0x1F)*2+16); set_CPU_bank5((data & 0x1F)*2+17); set_CPU_bank6((data & 0x1F)*2+16); set_CPU_bank7((data & 0x1F)*2+17); } else { set_CPU_bank4((data & 0x1E)*2+16); set_CPU_bank5((data & 0x1E)*2+17); set_CPU_bank6((data & 0x1E)*2+18); set_CPU_bank7((data & 0x1E)*2+19); } } }
static WRITE8_HANDLER(multigm3_switch_gfx_rom) { multigam_state *state = space->machine().driver_data<multigam_state>(); set_videorom_bank(space->machine(), 0, 8, data & 0x3f, 8); set_mirroring(state, data & 0x40 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); state->m_game_gfx_bank = data; };
PPU::PPU(Machine *mach, wxWindow* wind) { this->mach = mach; this->wind = wind; screen.Create(256, 240); screen_data = screen.GetData(); vaddr = 0; taddr = next_taddr = false; obj_addr = 0; mem = new byte[0x4000]; obj_mem = new byte[0x100]; cycle_count = 0; odd_frame = false; last_nmi = 0; vbl_off = 0; nmi_occurred = false; a12high = false; horiz_scroll = vert_scroll = false; sl = -2; cyc = 0; pmask = 0; pctrl = 0; pstat = 0; last_vblank_end = last_vblank_start = 0; memset(mem, 0xff, 0x4000); memset(obj_mem, 0xff, 0x100); mirror_table = new word[0x4000]; for(int i = 0; i < 0x4000; i++) mirror_table[i] = i; set_mirror(0x3000, 0x2000, 0xf00); if(mach->rom->flags6 & 8) { cout << "4 screen!!!!" << endl; } current_mirroring = FOUR_SCREEN; set_mirroring(mach->rom->mirror); }
static WRITE8_HANDLER(multigam_switch_gfx_rom) { multigam_state *state = space->machine().driver_data<multigam_state>(); memory_set_bankptr(space->machine(), "bank1", space->machine().region("gfx1")->base() + (0x2000 * (data & 0x3f))); set_mirroring(state, data & 0x40 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); state->m_game_gfx_bank = data; };
Mapper::Mapper(u8* rom) : rom(rom) { // Read infos from header: prgSize = rom[4] * 0x4000; chrSize = rom[5] * 0x2000; prgRamSize = rom[8] ? rom[8] * 0x2000 : 0x2000; set_mirroring((rom[6] & 1) ? PPU::VERTICAL : PPU::HORIZONTAL); this->prg = rom + 16; this->prgRam = new u8[prgRamSize]; // CHR ROM: if (chrSize) this->chr = rom + 16 + prgSize; // CHR RAM: else { chrRam = true; chrSize = 0x2000; this->chr = new u8[chrSize]; } }
void NES_mapper16::MemoryWrite2(uint32 addr, uint8 data) { switch(addr & 0x000F) { case 0x0000: { set_PPU_bank0(data); } break; case 0x0001: { set_PPU_bank1(data); } break; case 0x0002: { set_PPU_bank2(data); } break; case 0x0003: { set_PPU_bank3(data); } break; case 0x0004: { set_PPU_bank4(data); } break; case 0x0005: { set_PPU_bank5(data); } break; case 0x0006: { set_PPU_bank6(data); } break; case 0x0007: { set_PPU_bank7(data); } break; case 0x0008: { set_CPU_bank4(data*2+0); set_CPU_bank5(data*2+1); } break; case 0x0009: { data &= 0x03; if(data == 0) { set_mirroring(NES_PPU::MIRROR_VERT); } else if(data == 1) { set_mirroring(NES_PPU::MIRROR_HORIZ); } else if(data == 2) { set_mirroring(0,0,0,0); } else { set_mirroring(1,1,1,1); } } break; case 0x000A: { irq_enabled = data & 0x01; irq_counter = irq_latch; } break; case 0x000B: { irq_latch = (irq_latch & 0xFF00) | data; } break; case 0x000C: { irq_latch = ((uint32)data << 8) | (irq_latch & 0x00FF); } break; case 0x000D: { if(data == 0x80) { // reset eeprom_addr = 0x00; eeprom_mode = 0x00; eeprom_wbit = 0x00; eeprom_rbit = 0x00; } else if(eeprom_cmd[3] == 0x00 && eeprom_cmd[2] == 0x20 && eeprom_cmd[1] == 0x60 && eeprom_cmd[0] == 0x40 && data == 0x00) { // reset ? } else if(eeprom_cmd[3] == 0x00 && eeprom_cmd[2] == 0x40 && eeprom_cmd[1] == 0x60 && eeprom_cmd[0] == 0x20 && data == 0x00) { // start eeprom_wbit = 0x01; eeprom_rbit = 0x01; eeprom_data = 0; eeprom_mode = 0; } else if (eeprom_cmd[0] == 0x60 && data == 0xE0) { if(!eeprom_mode) { // sync eeprom_wbit = 0x01; eeprom_rbit = 0x01; eeprom_data = 0; eeprom_mode = 1; eeprom_status = 0x00; //memset(serial_out, eeprom_status | barcode_status, 0x2000); serial_out[0] = eeprom_status | barcode_status; } else { // read eeprom_data = parent_NES->ReadSaveRAM(eeprom_addr); if(eeprom_data & eeprom_rbit) { eeprom_status = 0x10; //memset(serial_out, eeprom_status | barcode_status, 0x2000); serial_out[0] = eeprom_status | barcode_status; } else { eeprom_status = 0x00; //memset(serial_out, eeprom_status | barcode_status, 0x2000); serial_out[0] = eeprom_status | barcode_status; } eeprom_rbit <<= 1; eeprom_wbit = 0x00; } } else if(eeprom_cmd[1] == 0x00 && eeprom_cmd[0] == 0x20 && data == 0x00) { // write 0 eeprom_data &= 0xFF - eeprom_wbit; if(eeprom_wbit == 0x80) { if(eeprom_mode) { parent_NES->WriteSaveRAM(eeprom_addr, eeprom_data); } else { eeprom_addr = eeprom_data & 0x7F; } eeprom_wbit = 0x00; } else { eeprom_wbit <<= 1; } eeprom_rbit = 0x00; } else if(eeprom_cmd[3] == 0x00 && eeprom_cmd[2] == 0x40 && eeprom_cmd[1] == 0x60 && eeprom_cmd[0] == 0x40 && data == 0x00) { // write 1 eeprom_data |= eeprom_wbit; if(eeprom_wbit == 0x80) { if(eeprom_mode) { parent_NES->WriteSaveRAM(eeprom_addr, eeprom_data); } else { eeprom_addr = eeprom_data & 0x7F; } eeprom_wbit = 0x00; } else { eeprom_wbit <<= 1; } eeprom_rbit = 0x00; } eeprom_cmd[3] = eeprom_cmd[2]; eeprom_cmd[2] = eeprom_cmd[1]; eeprom_cmd[1] = eeprom_cmd[0]; eeprom_cmd[0] = data; } break; } }
static WRITE8_HANDLER( multigam3_mmc3_rom_switch_w ) { multigam_state *state = space->machine().driver_data<multigam_state>(); device_t *ppu = space->machine().device("ppu"); /* basically, a MMC3 mapper from the nes */ int bankmask = state->m_multigam3_mmc3_prg_size == 0x40000 ? 0x1f : 0x0f; switch(offset & 0x7001) { case 0x0000: state->m_multigam3_mmc3_command = data; if (state->m_multigam3_mmc3_last_bank != (data & 0xc0)) { int bank; UINT8 *prg = space->machine().region("maincpu")->base(); /* reset the banks */ if (state->m_multigam3_mmc3_command & 0x40) { /* high bank */ bank = (state->m_multigam3_mmc3_banks[0] & bankmask) * 0x2000; memcpy(&prg[0x0c000], &state->m_multigam3_mmc3_prg_base[bank], 0x2000); memcpy(&prg[0x08000], &state->m_multigam3_mmc3_prg_base[state->m_multigam3_mmc3_prg_size - 0x4000], 0x2000); } else { /* low bank */ bank = (state->m_multigam3_mmc3_banks[0] & bankmask) * 0x2000; memcpy(&prg[0x08000], &state->m_multigam3_mmc3_prg_base[bank], 0x2000); memcpy(&prg[0x0c000], &state->m_multigam3_mmc3_prg_base[state->m_multigam3_mmc3_prg_size - 0x4000], 0x2000); } /* mid bank */ bank = (state->m_multigam3_mmc3_banks[1] & bankmask) * 0x2000; memcpy(&prg[0x0a000], &state->m_multigam3_mmc3_prg_base[bank], 0x2000); state->m_multigam3_mmc3_last_bank = data & 0xc0; } break; case 0x0001: { UINT8 cmd = state->m_multigam3_mmc3_command & 0x07; int page = (state->m_multigam3_mmc3_command & 0x80) >> 5; int bank; switch (cmd) { case 0: /* char banking */ case 1: /* char banking */ data &= 0xfe; page ^= (cmd << 1); set_videorom_bank(space->machine(), page, 2, state->m_multigam3_mmc3_chr_bank_base + data, 1); break; case 2: /* char banking */ case 3: /* char banking */ case 4: /* char banking */ case 5: /* char banking */ page ^= cmd + 2; set_videorom_bank(space->machine(), page, 1, state->m_multigam3_mmc3_chr_bank_base + data, 1); break; case 6: /* program banking */ { UINT8 *prg = space->machine().region("maincpu")->base(); if (state->m_multigam3_mmc3_command & 0x40) { /* high bank */ state->m_multigam3_mmc3_banks[0] = data & bankmask; bank = (state->m_multigam3_mmc3_banks[0]) * 0x2000; memcpy(&prg[0x0c000], &state->m_multigam3_mmc3_prg_base[bank], 0x2000); memcpy(&prg[0x08000], &state->m_multigam3_mmc3_prg_base[state->m_multigam3_mmc3_prg_size - 0x4000], 0x2000); } else { /* low bank */ state->m_multigam3_mmc3_banks[0] = data & bankmask; bank = (state->m_multigam3_mmc3_banks[0]) * 0x2000; memcpy(&prg[0x08000], &state->m_multigam3_mmc3_prg_base[bank], 0x2000); memcpy(&prg[0x0c000], &state->m_multigam3_mmc3_prg_base[state->m_multigam3_mmc3_prg_size - 0x4000], 0x2000); } } break; case 7: /* program banking */ { /* mid bank */ UINT8 *prg = space->machine().region("maincpu")->base(); state->m_multigam3_mmc3_banks[1] = data & bankmask; bank = state->m_multigam3_mmc3_banks[1] * 0x2000; memcpy(&prg[0x0a000], &state->m_multigam3_mmc3_prg_base[bank], 0x2000); } break; } } break; case 0x2000: /* mirroring */ if (!state->m_multigam3_mmc3_4screen) { if (data & 0x40) set_mirroring(state, PPU_MIRROR_HIGH); else set_mirroring(state, (data & 1) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); } break; case 0x2001: /* enable ram at $6000 */ if (data & 0x80) { memory_set_bankptr(space->machine(), "bank10", state->m_multigmc_mmc3_6000_ram); } else { memory_set_bankptr(space->machine(), "bank10", space->machine().region("maincpu")->base() + 0x6000); } if (data & 0x40) { logerror("Write protect for 6000 enabled\n"); } break; case 0x4000: /* scanline counter */ state->m_multigam3_mmc3_scanline_counter = data; break; case 0x4001: /* scanline latch */ state->m_multigam3_mmc3_scanline_latch = data; break; case 0x6000: /* disable irqs */ ppu2c0x_set_scanline_callback(ppu, 0); break; case 0x6001: /* enable irqs */ ppu2c0x_set_scanline_callback(ppu, multigam3_mmc3_scanline_cb); break; } }
void NES_mapper17::MemoryWriteLow(uint32 addr, uint8 data) { switch(addr) { case 0x42FE: { if((data & 0x10) == 0) { set_mirroring(0,0,0,0); } else { set_mirroring(1,1,1,1); } } break; case 0x42FF: { if((data & 0x10) == 0) { set_mirroring(NES_PPU::MIRROR_VERT); } else { set_mirroring(NES_PPU::MIRROR_HORIZ); } } break; case 0x4501: { irq_enabled = 0; } break; case 0x4502: { irq_latch = (irq_latch & 0xFF00) | data; } break; case 0x4503: { irq_latch = (irq_latch & 0x00FF) | ((uint32)data << 8); irq_counter = irq_latch; irq_enabled = 1; } break; case 0x4504: { set_CPU_bank4(data); } break; case 0x4505: { set_CPU_bank5(data); } break; case 0x4506: { set_CPU_bank6(data); } break; case 0x4507: { set_CPU_bank7(data); } break; case 0x4510: { set_PPU_bank0(data); } break; case 0x4511: { set_PPU_bank1(data); } break; case 0x4512: { set_PPU_bank2(data); } break; case 0x4513: { set_PPU_bank3(data); } break; case 0x4514: { set_PPU_bank4(data); } break; case 0x4515: { set_PPU_bank5(data); } break; case 0x4516: { set_PPU_bank6(data); } break; case 0x4517: { set_PPU_bank7(data); } break; } }
void NES_mapper24::MemoryWrite(uint32 addr, uint8 data) { switch(addr & 0xF003) { case 0x8000: { set_CPU_bank4(data*2+0); set_CPU_bank5(data*2+1); } break; //DCR case 0x9000: case 0x9001: case 0x9002: case 0xA000: case 0xA001: case 0xA002: case 0xB000: case 0xB001: case 0xB002: parent_NES->apu->Write(addr, data); break; case 0xB003: { data = data & 0x0C; if(data == 0x00) { set_mirroring(NES_PPU::MIRROR_VERT); } else if(data == 0x04) { set_mirroring(NES_PPU::MIRROR_HORIZ); } else if(data == 0x08) { set_mirroring(0,0,0,0); } else if(data == 0x0C) { set_mirroring(1,1,1,1); } } break; case 0xC000: { set_CPU_bank6(data); } break; case 0xD000: { set_PPU_bank0(data); } break; case 0xD001: { set_PPU_bank1(data); } break; case 0xD002: { set_PPU_bank2(data); } break; case 0xD003: { set_PPU_bank3(data); } break; case 0xE000: { set_PPU_bank4(data); } break; case 0xE001: { set_PPU_bank5(data); } break; case 0xE002: { set_PPU_bank6(data); } break; case 0xE003: { set_PPU_bank7(data); } break; case 0xF000: { irq_latch = data; } break; case 0xF001: { irq_enabled = data & 0x03; if(irq_enabled & 0x02) { irq_counter = irq_latch; } } break; case 0xF002: { if(irq_enabled & 0x01) { irq_enabled |= 0x02; } else { irq_enabled &= 0x01; } } break; } }
static WRITE8_HANDLER(multigm3_switch_gfx_rom) { set_videorom_bank(space->machine, 0, 8, data & 0x3f, 8); set_mirroring(data & 0x40 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); multigam_game_gfx_bank = data; };
static WRITE8_HANDLER(multigam_switch_gfx_rom) { memory_set_bankptr(space->machine, "bank1", space->machine->region("gfx1")->base() + (0x2000 * (data & 0x3f))); set_mirroring(data & 0x40 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); multigam_game_gfx_bank = data; };
void NES_mapper69::MemoryWrite(uint32 addr, uint8 data) { switch(addr & 0xE000) { case 0x8000: { regs[0] = data; } break; case 0xA000: { switch(regs[0] & 0x0F) { case 0x00: { set_PPU_bank0(data); } break; case 0x01: { set_PPU_bank1(data); } break; case 0x02: { set_PPU_bank2(data); } break; case 0x03: { set_PPU_bank3(data); } break; case 0x04: { set_PPU_bank4(data); } break; case 0x05: { set_PPU_bank5(data); } break; case 0x06: { set_PPU_bank6(data); } break; case 0x07: { set_PPU_bank7(data); } break; case 0x08: { if(!patch) { if(!(data & 0x40)) { set_CPU_bank3(data); } } } break; case 0x09: { set_CPU_bank4(data); } break; case 0x0A: { set_CPU_bank5(data); } break; case 0x0B: { set_CPU_bank6(data); } break; case 0x0C: { data &= 0x03; if(data == 0) { set_mirroring(NES_PPU::MIRROR_VERT); } else if(data == 1) { set_mirroring(NES_PPU::MIRROR_HORIZ); } else if(data == 2) { set_mirroring(0,0,0,0); } else { set_mirroring(1,1,1,1); } } break; case 0x0D: { irq_enabled = data; } break; case 0x0E: { irq_counter = (irq_counter & 0xFF00) | data; } break; case 0x0F: { irq_counter = (irq_counter & 0x00FF) | (data << 8); } break; } } break; case 0xC000: case 0xE000: { parent_NES->apu->ExWrite(addr, data); } break; } }
void NES_mapper1::MemoryWrite(uint32 addr, uint8 data) { if(patch && addr == 0xBFFF) { wram_count++; wram_flag += data & 0x01; if(wram_count == 5) { if(wram_flag) { wram_bank = 1; (nes6502_get_current_context())->mem_page[3] = wram + 0x2000; nes6502_setcontext(); } else { wram_bank = 0; (nes6502_get_current_context())->mem_page[3] = wram; nes6502_setcontext(); } wram_flag = 0; wram_count = 0; } } uint32 reg_num; // if write is to a different reg, reset if((addr & 0x6000) != (last_write_addr & 0x6000)) { write_count = 0; bits = 0x00; } last_write_addr = addr; // if bit 7 set, reset and return if(data & 0x80) { write_count = 0; bits = 0x00; return; } bits |= (data & 0x01) << write_count; if (++write_count < 5) return; reg_num = (addr & 0x7FFF) >> 13; regs[reg_num] = bits; write_count = 0; bits = 0x00; // LOG("MAP1 REG" << reg_num << ": " << HEX(regs[reg_num],2) << endl); switch(reg_num) { case 0: { // LOG("REG0: " << HEX(reg[0],2) << endl); // set mirroring if(regs[0] & 0x02) { if(regs[0] & 0x01) { set_mirroring(NES_PPU::MIRROR_HORIZ); } else { set_mirroring(NES_PPU::MIRROR_VERT); } } else { // one-screen mirroring if(regs[0] & 0x01) { set_mirroring(1,1,1,1); } else { set_mirroring(0,0,0,0); } } } break; case 1: { uint8 bank_num = regs[1]; // LOG("REG1: " << HEX(reg[1],2) << endl); if(MMC1_Size == MMC1_1024K) { if(regs[0] & 0x10) { if(MMC1_swap) { MMC1_256K_base = (regs[1] & 0x10) >> 4; if(regs[0] & 0x08) { MMC1_256K_base |= ((regs[2] & 0x10) >> 3); } MMC1_set_CPU_banks(); MMC1_swap = 0; } else { MMC1_swap = 1; } } else { // use 1st or 4th 256K banks MMC1_256K_base = (regs[1] & 0x10) ? 3 : 0; MMC1_set_CPU_banks(); } }
void NES_mapper20::MemoryWriteLow(uint32 addr, uint8 data) { switch (addr) { case 0x4020: { irq_latch = (irq_latch & 0xFF00) | data; } break; case 0x4021: { irq_latch = (irq_latch & 0x00FF) | ((uint32)data << 8); } break; case 0x4022: { irq_counter = irq_latch; irq_enabled = data & 0x03; } break; case 0x4023: { disk_enabled = data & 0x01; } break; case 0x4024: { if((current_side != 0) && (current_side == last_side)) { if(disk_enabled && !(write_reg & 0x04) && head_position < 65000) { if(write_skip) { write_skip--; } else if(head_position >= 2) { disk[(current_side-1)*0x10000+head_position-2] = data; access_flag = 1; } } } } break; case 0x4025: { if(data & 0x08) { set_mirroring(NES_PPU::MIRROR_HORIZ); } else { set_mirroring(NES_PPU::MIRROR_VERT); } if((current_side != 0) && (current_side == last_side)) { if((write_reg & 0x40) && !(data & 0x10) && !(data & 0x40)) { head_position = (head_position < 2) ? 0 : head_position - 2; } if(!(data & 0x04)) { write_skip = 2; } if(data & 0x02) { head_position = 0; irq_wait = 2; } if(data & 0x80) { irq_wait = 2; } } write_reg = data; } break; default: { parent_NES->apu->ExWrite(addr, data); } break; } }
void NES_mapper65::MemoryWrite(uint32 addr, uint8 data) { switch(addr) { case 0x8000: { set_CPU_bank4(data); } break; case 0x9000: { if(!patch) { if(data & 0x40) { set_mirroring(NES_PPU::MIRROR_VERT); } else { set_mirroring(NES_PPU::MIRROR_HORIZ); } } } break; case 0x9001: { if(patch) { if(data & 0x80) { set_mirroring(NES_PPU::MIRROR_HORIZ); } else { set_mirroring(NES_PPU::MIRROR_VERT); } } } break; case 0x9003: { if(!patch) { irq_enabled = data & 0x80; } } break; case 0x9004: { if(!patch) { irq_counter = irq_latch; } } break; case 0x9005: { if(patch) { irq_counter = (uint8)(data << 1); irq_enabled = data; } else { irq_latch = (irq_latch & 0x00FF) | ((uint32)data << 8); } } break; case 0x9006: { if(patch) { irq_enabled = 1; } else { irq_latch = (irq_latch & 0xFF00) | data; } } break; case 0xB000: { set_PPU_bank0(data); } break; case 0xB001: { set_PPU_bank1(data); } break; case 0xB002: { set_PPU_bank2(data); } break; case 0xB003: { set_PPU_bank3(data); } break; case 0xB004: { set_PPU_bank4(data); } break; case 0xB005: { set_PPU_bank5(data); } break; case 0xB006: { set_PPU_bank6(data); } break; case 0xB007: { set_PPU_bank7(data); } break; case 0xA000: { set_CPU_bank5(data); } break; case 0xC000: { set_CPU_bank6(data); } break; } }
void NES_mapper21::MemoryWrite(uint32 addr, uint8 data) { // regs[0] ... 1K VROM bank at PPU $0000 // regs[1] ... 1K VROM bank at PPU $0400 // regs[2] ... 1K VROM bank at PPU $0800 // regs[3] ... 1K VROM bank at PPU $0C00 // regs[4] ... 1K VROM bank at PPU $1000 // regs[5] ... 1K VROM bank at PPU $1400 // regs[6] ... 1K VROM bank at PPU $1800 // regs[7] ... 1K VROM bank at PPU $1C00 // regs[8] ... $8000 Switching Mode switch (addr & 0xF0CF) { case 0x8000: { if(regs[8] & 0x02) { set_CPU_bank6(data); } else { set_CPU_bank4(data); } } break; case 0xA000: { set_CPU_bank5(data); } break; case 0x9000: { data &= 0x03; if(data == 0) { set_mirroring(NES_PPU::MIRROR_VERT); } else if(data == 1) { set_mirroring(NES_PPU::MIRROR_HORIZ); } else if(data == 2) { set_mirroring(0,0,0,0); } else { set_mirroring(1,1,1,1); } } break; case 0x9002: case 0x9080: { regs[8] = data; } break; case 0xB000: { regs[0] = (regs[0] & 0xF0) | (data & 0x0F); set_PPU_bank0(regs[0]); } break; case 0xB002: case 0xB040: { regs[0] = (regs[0] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank0(regs[0]); } break; case 0xB001: case 0xB004: case 0xB080: { regs[1] = (regs[1] & 0xF0) | (data & 0x0F); set_PPU_bank1(regs[1]); } break; case 0xB003: case 0xB006: case 0xB0C0: { regs[1] = (regs[1] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank1(regs[1]); } break; case 0xC000: { regs[2] = (regs[2] & 0xF0) | (data & 0x0F); set_PPU_bank2(regs[2]); } break; case 0xC002: case 0xC040: { regs[2] = (regs[2] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank2(regs[2]); } break; case 0xC001: case 0xC004: case 0xC080: { regs[3] = (regs[3] & 0xF0) | (data & 0x0F); set_PPU_bank3(regs[3]); } break; case 0xC003: case 0xC006: case 0xC0C0: { regs[3] = (regs[3] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank3(regs[3]); } break; case 0xD000: { regs[4] = (regs[4] & 0xF0) | (data & 0x0F); set_PPU_bank4(regs[4]); } break; case 0xD002: case 0xD040: { regs[4] = (regs[4] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank4(regs[4]); } break; case 0xD001: case 0xD004: case 0xD080: { regs[5] = (regs[5] & 0xF0) | (data & 0x0F); set_PPU_bank5(regs[5]); } break; case 0xD003: case 0xD006: case 0xD0C0: { regs[5] = (regs[5] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank5(regs[5]); } break; case 0xE000: { regs[6] = (regs[6] & 0xF0) | (data & 0x0F); set_PPU_bank6(regs[6]); } break; case 0xE002: case 0xE040: { regs[6] = (regs[6] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank6(regs[6]); } break; case 0xE001: case 0xE004: case 0xE080: { regs[7] = (regs[7] & 0xF0) | (data & 0x0F); set_PPU_bank7(regs[7]); } break; case 0xE003: case 0xE006: case 0xE0C0: { regs[7] = (regs[7] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank7(regs[7]); } break; case 0xF000: { irq_latch = (irq_latch & 0xF0) | (data & 0x0F); } break; case 0xF002: case 0xF040: { irq_latch = (irq_latch & 0x0F) | ((data & 0x0F) << 4); } break; case 0xF003: case 0xF0C0: { irq_enabled = (irq_enabled & 0x01) * 3; } break; case 0xF004: case 0xF080: { irq_enabled = data & 0x03; if(irq_enabled & 0x02) { irq_counter = irq_latch; } } break; } }
void NES_mapper64::MemoryWrite(uint32 addr, uint8 data) { switch(addr & 0xF003) { case 0x8000: { regs[0] = data & 0x0F; regs[1] = data & 0x40; regs[2] = data & 0x80; } break; case 0x8001: { switch(regs[0]) { case 0x00: { if(regs[2]) { set_PPU_bank4(data+0); set_PPU_bank5(data+1); } else { set_PPU_bank0(data+0); set_PPU_bank1(data+1); } } break; case 0x01: { if(regs[2]) { set_PPU_bank6(data+0); set_PPU_bank7(data+1); } else { set_PPU_bank2(data+0); set_PPU_bank3(data+1); } } break; case 0x02: { if(regs[2]) { set_PPU_bank0(data); } else { set_PPU_bank4(data); } } break; case 0x03: { if(regs[2]) { set_PPU_bank1(data); } else { set_PPU_bank5(data); } } break; case 0x04: { if(regs[2]) { set_PPU_bank2(data); } else { set_PPU_bank6(data); } } break; case 0x05: { if(regs[2]) { set_PPU_bank3(data); } else { set_PPU_bank7(data); } } break; case 0x06: { if(regs[1]) { set_CPU_bank5(data); } else { set_CPU_bank4(data); } } break; case 0x07: { if(regs[1]) { set_CPU_bank6(data); } else { set_CPU_bank5(data); } } break; case 0x08: { //if(regs[2]) //{ // set_PPU_bank5(data); //} //else { set_PPU_bank1(data); } } break; case 0x09: { //if(regs[2]) //{ // set_PPU_bank7(data); //} //else { set_PPU_bank3(data); } } break; case 0x0F: { if(regs[1]) { set_CPU_bank4(data); } else { set_CPU_bank6(data); } } break; } } break; case 0xA000: { if(!(data & 0x01)) { set_mirroring(NES_PPU::MIRROR_VERT); } else { set_mirroring(NES_PPU::MIRROR_HORIZ); } } break; case 0xC000: { irq_latch = data; irq_counter = irq_latch; } break; case 0xC001: { irq_counter = irq_latch; } break; case 0xE000: { irq_enabled = 0; irq_counter = irq_latch; } break; case 0xE001: { irq_enabled = 1; irq_counter = irq_latch; } break; } }
void NES_mapper248::MemoryWrite(uint32 addr, uint8 data) { switch(addr & 0xE001) { case 0x8000: { regs[0] = data; MMC3_set_PPU_banks(); MMC3_set_CPU_banks(); } break; case 0x8001: { uint32 bank_num; regs[1] = data; bank_num = regs[1]; switch(regs[0] & 0x07) { case 0x00: { //if(num_1k_VROM_banks) { bank_num &= 0xfe; chr01 = bank_num; MMC3_set_PPU_banks(); } } break; case 0x01: { //if(num_1k_VROM_banks) { bank_num &= 0xfe; chr23 = bank_num; MMC3_set_PPU_banks(); } } break; case 0x02: { //if(num_1k_VROM_banks) { chr4 = bank_num; MMC3_set_PPU_banks(); } } break; case 0x03: { //if(num_1k_VROM_banks) { chr5 = bank_num; MMC3_set_PPU_banks(); } } break; case 0x04: { //if(num_1k_VROM_banks) { chr6 = bank_num; MMC3_set_PPU_banks(); } } break; case 0x05: { //if(num_1k_VROM_banks) { chr7 = bank_num; MMC3_set_PPU_banks(); } } break; case 0x06: { prg0 = bank_num; MMC3_set_CPU_banks(); } break; case 0x07: { prg1 = bank_num; MMC3_set_CPU_banks(); } break; } } break; case 0xA000: { regs[2] = data; if(parent_NES->ROM->get_mirroring() != NES_PPU::MIRROR_FOUR_SCREEN) { if(data & 0x01) { set_mirroring(NES_PPU::MIRROR_HORIZ); } else { set_mirroring(NES_PPU::MIRROR_VERT); } } } break; case 0xA001: { if(data & 0x80) { // enable save RAM $6000-$7FFF } else { // disable save RAM $6000-$7FFF } } break; case 0xC000: { irq_counter = irq_latch = 0xbe; irq_enabled = 0; } break; case 0xC001: { irq_counter = irq_latch = 0xbe; irq_enabled = 1; } break; case 0xE000: { irq_enabled = 0; } break; case 0xE001: { irq_enabled = 1; } break; } }
void NES_mapper237::MemoryWrite(uint32 addr, uint8 data) { if(addr & 0x4000) { if((addr & 0x0030) == 0x00) { set_CPU_bank4((addr&0x07)*2+0); set_CPU_bank5((addr&0x07)*2+1); set_CPU_bank6(num_8k_ROM_banks-2); set_CPU_bank7(num_8k_ROM_banks-1); } else if((addr & 0x0030) == 0x10) { for(uint32 i = 0; i < 0x2000; i++) { wram[i+0x0000] = ROM_banks[((addr&0x07)*2+0)*0x2000+(i&0x1ff0)+0x0d]; // 0x0b? wram[i+0x2000] = ROM_banks[((addr&0x07)*2+1)*0x2000+(i&0x1ff0)+0x0d]; // 0x0b? wram[i+0x4000] = ROM_banks[(num_8k_ROM_banks-2)*0x2000+(i&0x1ff0)+0x0d]; // 0x0b? wram[i+0x6000] = ROM_banks[(num_8k_ROM_banks-1)*0x2000+(i&0x1ff0)+0x0d]; // 0x0b? } nes6502_context *context; context = nes6502_get_current_context (); context->mem_page[4] = wram + 0x0000; context->mem_page[5] = wram + 0x2000; context->mem_page[6] = wram + 0x4000; context->mem_page[7] = wram + 0x6000; nes6502_setcontext(); } else if((addr & 0x0030) == 0x20) { set_CPU_bank4((addr&0x06)*2+0); set_CPU_bank5((addr&0x06)*2+1); set_CPU_bank6((addr&0x06)*2+2); set_CPU_bank7((addr&0x06)*2+3); } else if((addr & 0x0030) == 0x30) { set_CPU_bank4((addr&0x07)*2+0); set_CPU_bank5((addr&0x07)*2+1); set_CPU_bank6((addr&0x07)*2+0); set_CPU_bank7((addr&0x07)*2+1); } } else { if(addr & 0x0020) { set_mirroring(NES_PPU::MIRROR_VERT); } else { set_mirroring(NES_PPU::MIRROR_HORIZ); } set_PPU_bank0((addr&0x07)*8+0); set_PPU_bank1((addr&0x07)*8+1); set_PPU_bank2((addr&0x07)*8+2); set_PPU_bank3((addr&0x07)*8+3); set_PPU_bank4((addr&0x07)*8+4); set_PPU_bank5((addr&0x07)*8+5); set_PPU_bank6((addr&0x07)*8+6); set_PPU_bank7((addr&0x07)*8+7); } }
void NES_mapper16::MemoryWrite3(uint32 addr, uint8 data) { switch(addr) { case 0x8000: case 0x8001: case 0x8002: case 0x8003: { regs[0] = data & 0x01; set_CPU_bank4(regs[0]*0x20+regs[2]*2+0); set_CPU_bank5(regs[0]*0x20+regs[2]*2+1); } break; case 0x8004: case 0x8005: case 0x8006: case 0x8007: { regs[1] = data & 0x01; set_CPU_bank6(regs[1]*0x20+0x1E); set_CPU_bank7(regs[1]*0x20+0x1F); } break; case 0x8008: { regs[2] = data; set_CPU_bank4(regs[0]*0x20+regs[2]*2+0); set_CPU_bank5(regs[0]*0x20+regs[2]*2+1); set_CPU_bank6(regs[1]*0x20+0x1E); set_CPU_bank7(regs[1]*0x20+0x1F); } break; case 0x8009: { data &= 0x03; if(data == 0) { set_mirroring(NES_PPU::MIRROR_VERT); } else if(data == 1) { set_mirroring(NES_PPU::MIRROR_HORIZ); } else if(data == 2) { set_mirroring(0,0,0,0); } else { set_mirroring(1,1,1,1); } } break; case 0x800A: { irq_enabled = data & 0x01; irq_counter = irq_latch; } break; case 0x800B: { irq_latch = (irq_latch & 0xFF00) | data; } break; case 0x800C: { irq_latch = ((uint32)data << 8) | (irq_latch & 0x00FF); } break; case 0x800D: { //write protect } break; } }
void NES_mapper25::MemoryWrite(uint32 addr, uint8 data) { // regs[0] ... 1K VROM bank at PPU $0000 // regs[1] ... 1K VROM bank at PPU $0400 // regs[2] ... 1K VROM bank at PPU $0800 // regs[3] ... 1K VROM bank at PPU $0C00 // regs[4] ... 1K VROM bank at PPU $1000 // regs[5] ... 1K VROM bank at PPU $1400 // regs[6] ... 1K VROM bank at PPU $1800 // regs[7] ... 1K VROM bank at PPU $1C00 // regs[8] ... 8K ROM bank at CPU $8000 // regs[9] ... 8K ROM bank at CPU $C000 // regs[10] .. ROM Swap flag switch(addr & 0xF000) { case 0x8000: { if(regs[10] & 0x02) { regs[9] = data; set_CPU_bank6(data); } else { regs[8] = data; set_CPU_bank4(data); } } break; case 0xA000: { set_CPU_bank5(data); } break; } switch(addr & 0xF00F) { case 0x9000: { data &= 0x03; if(data == 0) { set_mirroring(NES_PPU::MIRROR_VERT); } else if(data == 1) { set_mirroring(NES_PPU::MIRROR_HORIZ); } else if(data == 2) { set_mirroring(0,0,0,0); } else { set_mirroring(1,1,1,1); } } break; case 0x9001: case 0x9004: { if((regs[10] & 0x02) != (data & 0x02)) { uint8 swap = regs[8]; regs[8] = regs[9]; regs[9] = swap; set_CPU_bank4(regs[8]); set_CPU_bank6(regs[9]); } regs[10] = data; } break; case 0xB000: { regs[0] = (regs[0] & 0xF0) | (data & 0x0F); set_PPU_bank0(regs[0]); } break; case 0xB001: case 0xB004: { regs[1] = (regs[1] & 0xF0) | (data & 0x0F); set_PPU_bank1(regs[1]); } break; case 0xB002: case 0xB008: { regs[0] = (regs[0] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank0(regs[0]); } break; case 0xB003: case 0xB00C: { regs[1] = (regs[1] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank1(regs[1]); } break; case 0xC000: { regs[2] = (regs[2] & 0xF0) | (data & 0x0F); set_PPU_bank2(regs[2]); } break; case 0xC001: case 0xC004: { regs[3] = (regs[3] & 0xF0) | (data & 0x0F); set_PPU_bank3(regs[3]); } break; case 0xC002: case 0xC008: { regs[2] = (regs[2] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank2(regs[2]); } break; case 0xC003: case 0xC00C: { regs[3] = (regs[3] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank3(regs[3]); } break; case 0xD000: { regs[4] = (regs[4] & 0xF0) | (data & 0x0F); set_PPU_bank4(regs[4]); } break; case 0xD001: case 0xD004: { regs[5] = (regs[5] & 0xF0) | (data & 0x0F); set_PPU_bank5(regs[5]); } break; case 0xD002: case 0xD008: { regs[4] = (regs[4] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank4(regs[4]); } break; case 0xD003: case 0xD00C: { regs[5] = (regs[5] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank5(regs[5]); } break; case 0xE000: { regs[6] = (regs[6] & 0xF0) | (data & 0x0F); set_PPU_bank6(regs[6]); } break; case 0xE001: case 0xE004: { regs[7] = (regs[7] & 0xF0) | (data & 0x0F); set_PPU_bank7(regs[7]); } break; case 0xE002: case 0xE008: { regs[6] = (regs[6] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank6(regs[6]); } break; case 0xE003: case 0xE00C: { regs[7] = (regs[7] & 0x0F) | ((data & 0x0F) << 4); set_PPU_bank7(regs[7]); } break; case 0xF000: { irq_latch = (irq_latch & 0xF0) | (data & 0x0F); } break; case 0xF001: case 0xF004: { irq_enabled = data & 0x03; if(irq_enabled & 0x02) { irq_counter = irq_latch; } } break; case 0xF002: case 0xF008: { irq_latch = (irq_latch & 0x0F) | ((data & 0x0F) << 4); } break; case 0xF003: case 0xF00C: { irq_enabled = (irq_enabled & 0x01) * 3; } break; } }