Example #1
0
uint8 sSMP::op_read(uint16 addr) {
  add_clocks(12);
  uint8 r = op_busread(addr);
  add_clocks(12);
  tick_timers();
  return r;
}
Example #2
0
uint8 SMP::op_read(uint16 addr) {
  add_clocks(12);
  uint8 r = op_busread(addr);
  add_clocks(12);
  cycle_edge();
  return r;
}
Example #3
0
uint8 CPU::op_read(uint32 addr) {
  status.clock_count = speed(addr);
  dma_edge();
  add_clocks(status.clock_count - 4);
  regs.mdr = bus.read(addr);
  add_clocks(4);
  alu_edge();
  debugger.op_read(addr, regs.mdr);
  return regs.mdr;
}
Example #4
0
uint8 SMP::op_read(uint16 addr, eCDLog_Flags flags) {
  debugger.op_read(addr);

  add_clocks(12);
	cdlInfo.currFlags = flags;
  uint8 r = op_busread(addr);
  add_clocks(12);
  cycle_edge();
  return r;
}
Example #5
0
void CPU::dma_transfer(bool direction, uint8 bbus, uint32 abus) {
  if(direction == 0) {
    add_clocks(4);
    regs.mdr = dma_read(abus);
    add_clocks(4);
    if (dma_transfer_valid(bbus, abus)) bus.write(0x2100 | bbus, regs.mdr);
  } else {
    add_clocks(4);
    regs.mdr = dma_transfer_valid(bbus, abus) ? bus.read(0x2100 | bbus) : 0x00;
    add_clocks(4);
    if (dma_addr_valid(abus)) bus.write(abus, regs.mdr);
  }
}
Example #6
0
void sSMP::cycle_edge() {
  t0.tick();
  t1.tick();
  t2.tick();

  //TEST register S-SMP speed control
  //24 clocks have already been added for this cycle at this point
  switch(status.clock_speed) {
    case 0: break;                       //100% speed
    case 1: add_clocks(24); break;       // 50% speed
    case 2: while(true) add_clocks(24);  //  0% speed -- locks S-SMP
    case 3: add_clocks(24 * 9); break;   // 10% speed
  }
}
Example #7
0
void SMP::op_write(uint16 addr, uint8 data) {
  debugger.op_write(addr, data);

  add_clocks(24);
  op_buswrite(addr, data);
  cycle_edge();
}
Example #8
0
void CPU::queue_event(unsigned id) {
  switch(id) {
    case QueueEvent::DramRefresh: return add_clocks(40);
    case QueueEvent::HdmaRun: return hdma_run();
    case QueueEvent::ControllerLatch: return ppu.latch_counters();
  }
}
Example #9
0
void CPU::enter() {
  while(true) {
    if(scheduler.sync == Scheduler::SynchronizeMode::CPU) {
      scheduler.sync = Scheduler::SynchronizeMode::All;
      scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
    }

    if(status.interrupt_pending) {
      status.interrupt_pending = false;
      if(status.nmi_pending) {
        status.nmi_pending = false;
        status.interrupt_vector = (regs.e == false ? 0xffea : 0xfffa);
        op_irq();
      } else if(status.irq_pending) {
        status.irq_pending = false;
        status.interrupt_vector = (regs.e == false ? 0xffee : 0xfffe);
        op_irq();
      } else if(status.reset_pending) {
        status.reset_pending = false;
        add_clocks(186);
        regs.pc.l = bus.read(0xfffc);
        regs.pc.h = bus.read(0xfffd);
      }
    }

    op_step();
  }
}
Example #10
0
void PPU::enter() {
  while(true) {
    if(scheduler.sync == Scheduler::SynchronizeMode::All) {
      scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
    }

    scanline();
    if(vcounter() < display.height && vcounter()) {
      add_clocks(512);
      render_scanline();
      add_clocks(lineclocks() - 512);
    } else {
      add_clocks(lineclocks());
    }
  }
}
Example #11
0
uint8 CPU::op_read(uint16 addr) {
  if(status.oam_dma_pending) {
    status.oam_dma_pending = false;
    op_read(addr);
    oam_dma();
  }

  while(status.rdy_line == 0) {
    regs.mdr = bus.read(status.rdy_addr ? status.rdy_addr() : addr);
    add_clocks(12);
  }

  regs.mdr = bus.read(addr);
  add_clocks(12);
  return regs.mdr;
}
Example #12
0
void CPU::enter() {
  while(true) {
    if(scheduler.sync == Scheduler::SynchronizeMode::CPU) {
      // we can only stop if there's enough time for at least one more event
      // on both the PPU and the SMP
      if (smp.clock < 0 && ppu.clock < 0) {
        scheduler.sync = Scheduler::SynchronizeMode::All;
        scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
      }
    }

    if(status.interrupt_pending) {
      status.interrupt_pending = false;
      if(status.nmi_pending) {
        status.nmi_pending = false;
        regs.vector = (regs.e == false ? 0xffea : 0xfffa);
        op_irq();
        debugger.op_nmi();
      } else if(status.irq_pending) {
        status.irq_pending = false;
        regs.vector = (regs.e == false ? 0xffee : 0xfffe);
        op_irq();
        debugger.op_irq();
      } else if(status.reset_pending) {
        status.reset_pending = false;
        add_clocks(186);
        regs.pc.l = bus.read(0xfffc);
        regs.pc.h = bus.read(0xfffd);
      }
    }

    op_step();
  }
}
Example #13
0
void CPU::op_write(uint32 addr, uint8 data) {
  alu_edge();
  status.clock_count = speed(addr);
  dma_edge();
  add_clocks(status.clock_count);
  bus.write(addr, regs.mdr = data);
  debugger.op_write(addr, regs.mdr);
}
Example #14
0
void CPU::hblank() {
  if(status.dma_mode == 1 && status.dma_length && ppu.status.ly < 144) {
    for(unsigned n = 0; n < 16; n++) {
      dma_write(status.dma_target++, dma_read(status.dma_source++));
    }
    add_clocks(8 << status.speed_double);
    status.dma_length -= 16;
  }
}
Example #15
0
void CPU::hblank() {
  if(status.dma_mode == 1 && status.dma_length) {
    for(unsigned n = 0; n < 16; n++) {
      bus.write(status.dma_target++, bus.read(status.dma_source++));
      add_clocks(4);
    }
    status.dma_length -= 16;
  }
}
Example #16
0
void CPU::dma_run() {
  add_clocks(8);
  dma_edge();

  for(unsigned i = 0; i < 8; i++) {
    if(channel[i].dma_enabled == false) continue;
    
    add_clocks(8);
    dma_edge();

    unsigned index = 0;
    do {
      dma_transfer(channel[i].direction, dma_bbus(i, index++), dma_addr(i));
      dma_edge();
    } while(channel[i].dma_enabled && --channel[i].transfer_size);

    channel[i].dma_enabled = false;
  }

  status.irq_lock = true;
}
Example #17
0
void CPU::hdma_update(unsigned i) {
  add_clocks(4);
  regs.mdr = dma_read((channel[i].source_bank << 16) | channel[i].hdma_addr);
  add_clocks(4);

  if((channel[i].line_counter & 0x7f) == 0) {
    channel[i].line_counter = regs.mdr;
    channel[i].hdma_addr++;

    channel[i].hdma_completed = (channel[i].line_counter == 0);
    channel[i].hdma_do_transfer = !channel[i].hdma_completed;

    if(channel[i].indirect) {
      add_clocks(4);
      regs.mdr = dma_read(hdma_addr(i));
      add_clocks(4);
      channel[i].indirect_addr = regs.mdr << 8;

      if(!channel[i].hdma_completed || hdma_active_after(i)) {
        add_clocks(4);
        regs.mdr = dma_read(hdma_addr(i));
        add_clocks(4);
        channel[i].indirect_addr >>= 8;
        channel[i].indirect_addr |= regs.mdr << 8;
      }
Example #18
0
void bPPU::enter() {
  loop:
  //H =    0 (initialize)
  scanline();
  if(ivcounter() == 0) frame();
  add_clocks(10);

  //H =   10 (OAM address reset)
  if(ivcounter() == (!overscan() ? 225 : 240)) {
    if(regs.display_disabled == false) {
      regs.oam_addr = regs.oam_baseaddr << 1;
      regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127;
    }
  }
Example #19
0
void SuperFX::enter() {
    while(true) {
        if(scheduler.sync == Scheduler::SynchronizeMode::All) {
            scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
        }

        if(regs.sfr.g == 0) {
            add_clocks(6);
            continue;
        }

        op_exec(peekpipe());
        if(r15_modified == false) regs.r[15]++;
    }
}
Example #20
0
void SuperFX::enter() {
    while(true) {
        if(scheduler.sync.i == Scheduler::SynchronizeMode::All) {
            scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
        }

        if(regs.sfr.g == 0) {
            add_clocks(6);
            synchronize_cpu();
            continue;
        }

        (this->*opcode_table[(regs.sfr & 0x0300) + peekpipe()])();
        if(r15_modified == false) regs.r[15]++;

        if(++instruction_counter >= 128) {
            instruction_counter = 0;
            synchronize_cpu();
        }
    }
}
Example #21
0
void CPU::add_clocks(unsigned clocks) {
  status.irq_lock = false;
  unsigned ticks = clocks >> 1;
  while(ticks--) {
    tick();
    if(hcounter() & 2) {
      input.tick();
      poll_interrupts();
    }
    if(joypad_counter() == 0) {
      joypad_edge();
    }
  }

  step(clocks);

  if(status.dram_refreshed == false && hcounter() >= status.dram_refresh_position) {
    status.dram_refreshed = true;
    add_clocks(40);
  }
}
Example #22
0
void CPU::add_clocks(unsigned clocks) {
  status.irq_lock = false;
  unsigned ticks = clocks >> 1;
  while(ticks--) {
    tick();
    if(hcounter() & 2) poll_interrupts();
  }

  step(clocks);

  status.auto_joypad_clock += clocks;
  if(status.auto_joypad_clock >= 256) {
    status.auto_joypad_clock -= 256;
    step_auto_joypad_poll();
  }

  if(status.dram_refreshed == false && hcounter() >= status.dram_refresh_position) {
    status.dram_refreshed = true;
    add_clocks(40);
  }
}
Example #23
0
void sSMP::op_io() {
  add_clocks(24);
  tick_timers();
}
Example #24
0
void SuperFX::rambuffer_sync() {
  if(regs.ramcl) add_clocks(regs.ramcl);
}
Example #25
0
void CPU::op_write(unsigned addr, uint8 data) {
  add_clocks(speed(addr));
  bus.write(addr, regs.mdr = data);
}
Example #26
0
uint8 CPU::op_read(unsigned addr) {
  regs.mdr = bus.read(addr);
  add_clocks(speed(addr));
  return regs.mdr;
}
Example #27
0
void CPU::op_io() {
  add_clocks(6);
}
Example #28
0
void sCPU::dma_add_clocks(unsigned clocks) {
  status.dma_clocks += clocks;
  add_clocks(clocks);
}
Example #29
0
void sSMP::op_write(uint16 addr, uint8 data) {
  add_clocks(24);
  op_buswrite(addr, data);
  tick_timers();
}
Example #30
0
void SMP::op_io() {
  add_clocks(24);
  cycle_edge();
}