Path: blob/master/libsnes/bsnes/gameboy/cpu/mmio/mmio.cpp
2 views
#ifdef CPU_CPP12unsigned CPU::wram_addr(uint16 addr) const {3addr &= 0x1fff;4if(addr < 0x1000) return addr;5auto bank = status.wram_bank + (status.wram_bank == 0);6return (bank * 0x1000) + (addr & 0x0fff);7}89void CPU::mmio_joyp_poll() {10unsigned button = 0, dpad = 0;1112button |= interface->inputPoll((unsigned)Input::Start) << 3;13button |= interface->inputPoll((unsigned)Input::Select) << 2;14button |= interface->inputPoll((unsigned)Input::B) << 1;15button |= interface->inputPoll((unsigned)Input::A) << 0;1617dpad |= interface->inputPoll((unsigned)Input::Down) << 3;18dpad |= interface->inputPoll((unsigned)Input::Up) << 2;19dpad |= interface->inputPoll((unsigned)Input::Left) << 1;20dpad |= interface->inputPoll((unsigned)Input::Right) << 0;2122status.joyp = 0x0f;23if(status.p15 == 1 && status.p14 == 1) status.joyp -= status.mlt_req;24if(status.p15 == 0) status.joyp &= button ^ 0x0f;25if(status.p14 == 0) status.joyp &= dpad ^ 0x0f;26if(status.joyp != 0x0f) interrupt_raise(Interrupt::Joypad);27}2829uint8 CPU::mmio_read(uint16 addr) {30if(addr >= 0xc000 && addr <= 0xfdff) return wram[wram_addr(addr)];31if(addr >= 0xff80 && addr <= 0xfffe) return hram[addr & 0x7f];3233if(addr == 0xff00) { //JOYP34return (status.p15 << 5)35| (status.p14 << 4)36| (status.joyp << 0);37}3839if(addr == 0xff01) { //SB40return 0xff;41}4243if(addr == 0xff02) { //SC44return (status.serial_transfer << 7)45| (status.serial_clock << 0);46}4748if(addr == 0xff04) { //DIV49return status.div;50}5152if(addr == 0xff05) { //TIMA53return status.tima;54}5556if(addr == 0xff06) { //TMA57return status.tma;58}5960if(addr == 0xff07) { //TAC61return (status.timer_enable << 2)62| (status.timer_clock << 0);63}6465if(addr == 0xff0f) { //IF66return (status.interrupt_request_joypad << 4)67| (status.interrupt_request_serial << 3)68| (status.interrupt_request_timer << 2)69| (status.interrupt_request_stat << 1)70| (status.interrupt_request_vblank << 0);71}7273if(addr == 0xff4d) { //KEY174return (status.speed_double << 7);75}7677if(addr == 0xff55) { //HDMA578return (status.dma_length / 16) - 1;79}8081if(addr == 0xff56) { //RP82return 0x02;83}8485if(addr == 0xff6c) { //???86return 0xfe | status.ff6c;87}8889if(addr == 0xff70) { //SVBK90return status.wram_bank;91}9293if(addr == 0xff72) { //???94return status.ff72;95}9697if(addr == 0xff73) { //???98return status.ff73;99}100101if(addr == 0xff74) { //???102return status.ff74;103}104105if(addr == 0xff75) { //???106return 0x8f | status.ff75;107}108109if(addr == 0xff76) { //???110return 0x00;111}112113if(addr == 0xff77) { //???114return 0x00;115}116117if(addr == 0xffff) { //IE118return (status.interrupt_enable_joypad << 4)119| (status.interrupt_enable_serial << 3)120| (status.interrupt_enable_timer << 2)121| (status.interrupt_enable_stat << 1)122| (status.interrupt_enable_vblank << 0);123}124125return 0x00;126}127128void CPU::mmio_write(uint16 addr, uint8 data) {129if(addr >= 0xc000 && addr <= 0xfdff) { wram[wram_addr(addr)] = data; return; }130if(addr >= 0xff80 && addr <= 0xfffe) { hram[addr & 0x7f] = data; return; }131132if(addr == 0xff00) { //JOYP133status.p15 = data & 0x20;134status.p14 = data & 0x10;135interface->joypWrite(status.p15, status.p14);136mmio_joyp_poll();137return;138}139140if(addr == 0xff01) { //SB141status.serial_data = data;142return;143}144145if(addr == 0xff02) { //SC146status.serial_transfer = data & 0x80;147status.serial_clock = data & 0x01;148if(status.serial_transfer) status.serial_bits = 8;149return;150}151152if(addr == 0xff04) { //DIV153status.div = 0;154return;155}156157if(addr == 0xff05) { //TIMA158status.tima = data;159return;160}161162if(addr == 0xff06) { //TMA163status.tma = data;164return;165}166167if(addr == 0xff07) { //TAC168status.timer_enable = data & 0x04;169status.timer_clock = data & 0x03;170return;171}172173if(addr == 0xff0f) { //IF174status.interrupt_request_joypad = data & 0x10;175status.interrupt_request_serial = data & 0x08;176status.interrupt_request_timer = data & 0x04;177status.interrupt_request_stat = data & 0x02;178status.interrupt_request_vblank = data & 0x01;179return;180}181182if(addr == 0xff46) { //DMA183for(unsigned n = 0x00; n <= 0x9f; n++) {184bus.write(0xfe00 + n, bus.read((data << 8) + n));185add_clocks(4);186}187return;188}189190if(addr == 0xff4d) { //KEY1191status.speed_switch = data & 0x01;192return;193}194195if(addr == 0xff51) { //HDMA1196status.dma_source = (status.dma_source & 0x00ff) | (data << 8);197return;198}199200if(addr == 0xff52) { //HDMA2201status.dma_source = (status.dma_source & 0xff00) | (data << 0);202return;203}204205if(addr == 0xff53) { //HDMA3206status.dma_target = (status.dma_target & 0x00ff) | (data << 8);207return;208}209210if(addr == 0xff54) { //HDMA4211status.dma_target = (status.dma_target & 0xff00) | (data << 0);212return;213}214215if(addr == 0xff55) { //HDMA5216status.dma_mode = data & 0x80;217status.dma_length = ((data & 0x7f) + 1) * 16;218219if(status.dma_mode == 0) do {220bus.write(status.dma_target++, bus.read(status.dma_source++));221add_clocks(4 << status.speed_double);222} while(--status.dma_length);223return;224}225226if(addr == 0xff56) { //RP227return;228}229230if(addr == 0xff6c) { //???231status.ff6c = data & 0x01;232return;233}234235if(addr == 0xff72) { //???236status.ff72 = data;237return;238}239240if(addr == 0xff73) { //???241status.ff73 = data;242return;243}244245if(addr == 0xff74) { //???246status.ff74 = data;247return;248}249250if(addr == 0xff75) { //???251status.ff75 = data & 0x70;252return;253}254255if(addr == 0xff70) { //SVBK256status.wram_bank = data & 0x07;257return;258}259260if(addr == 0xffff) { //IE261status.interrupt_enable_joypad = data & 0x10;262status.interrupt_enable_serial = data & 0x08;263status.interrupt_enable_timer = data & 0x04;264status.interrupt_enable_stat = data & 0x02;265status.interrupt_enable_vblank = data & 0x01;266return;267}268}269270#endif271272273