コード例 #1
0
ファイル: timing.cpp プロジェクト: Optiroc/bsnes-plus
//called by ppu.tick() when Hcounter=0
void CPU::scanline() {
  status.lineclocks = lineclocks();

  //forcefully sync S-CPU to other processors, in case chips are not communicating
  synchronize_ppu();
  synchronize_smp();
  synchronize_coprocessor();
  system.scanline();

  if(vcounter() == 0) {
    //HDMA init triggers once every frame
    status.hdma_init_position = (cpu_version == 1 ? 12 + 8 - dma_counter() : 12 + dma_counter());
    status.hdma_init_triggered = false;
    
    status.auto_joypad_counter = 0;
  }

  //DRAM refresh occurs once every scanline
  if(cpu_version == 2) status.dram_refresh_position = 530 + 8 - dma_counter();
  status.dram_refreshed = false;

  //HDMA triggers once every visible scanline
  if(vcounter() <= (ppu.overscan() == false ? 224 : 239)) {
    status.hdma_position = 1104;
    status.hdma_triggered = false;
  }
}
コード例 #2
0
ファイル: timing.cpp プロジェクト: gilligan/bsnes
void CPU::scanline() {
  synchronize_smp();
  synchronize_ppu();
  synchronize_coprocessor();
  system.scanline();

  if(vcounter() == 0) hdma_init();

  queue.enqueue(534, QueueEvent::DramRefresh);

  if(vcounter() <= (ppu.overscan() == false ? 224 : 239)) {
    queue.enqueue(1104 + 8, QueueEvent::HdmaRun);
  }

  if(vcounter() == input.latchy) {
    queue.enqueue(input.latchx, QueueEvent::ControllerLatch);
  }

  bool nmi_valid = status.nmi_valid;
  status.nmi_valid = vcounter() >= (ppu.overscan() == false ? 225 : 240);
  if(!nmi_valid && status.nmi_valid) {
    status.nmi_line = true;
    if(status.nmi_enabled) status.nmi_transition = true;
  } else if(nmi_valid && !status.nmi_valid) {
    status.nmi_line = false;
  }

  if(status.auto_joypad_poll_enabled && vcounter() == (ppu.overscan() == false ? 227 : 242)) {
    input.poll();
    run_auto_joypad_poll();
  }
}
コード例 #3
0
ファイル: debugger.cpp プロジェクト: devinacker/bsnes-plus
void CPUDebugger::op_step() {
  bool break_event = false;

  usage[regs.pc] &= ~(UsageFlagM | UsageFlagX);
  usage[regs.pc] |= UsageOpcode | (regs.p.m << 1) | (regs.p.x << 0);
  opcode_pc = regs.pc;

  if(debugger.step_cpu &&
      (debugger.step_type == Debugger::StepType::StepInto ||
       (debugger.step_type >= Debugger::StepType::StepOver && debugger.call_count < 0))) {
      
    debugger.break_event = Debugger::BreakEvent::CPUStep;
    debugger.step_type = Debugger::StepType::None;
    scheduler.exit(Scheduler::ExitReason::DebuggerEvent);
  } else {
      
    if (debugger.break_on_wdm) {
      uint8 opcode = disassembler_read(opcode_pc);
      if (opcode == 0x42) {
        debugger.breakpoint_hit = Debugger::SoftBreakCPU;
        debugger.break_event = Debugger::BreakEvent::BreakpointHit;
        scheduler.exit(Scheduler::ExitReason::DebuggerEvent);
      }
    }
    debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Exec, regs.pc, 0x00);
  }
  if(step_event) step_event();

  // adjust call count if this is a call or return
  // (or if we're stepping over and no call occurred)
  // (TODO: track interrupts as well?)
  if (debugger.step_cpu) {
    if (debugger.step_over_new && debugger.call_count == 0) {
      debugger.call_count = -1;
      debugger.step_over_new = false;
    }
  
    uint8 opcode = disassembler_read(opcode_pc);
    if (opcode == 0x20 || opcode == 0x22 || opcode == 0xfc) {
      debugger.call_count++;
    } else if (opcode == 0x60 || opcode == 0x6b) {
      debugger.call_count--;
    }
  }

  CPU::op_step();
  synchronize_smp();
}
コード例 #4
0
ファイル: debugger.cpp プロジェクト: gilligan/bsnes
void CPUDebugger::op_step() {
  bool break_event = false;

  usage[regs.pc] &= ~(UsageFlagM | UsageFlagX);
  usage[regs.pc] |= UsageExec | (regs.p.m << 1) | (regs.p.x << 0);
  opcode_pc = regs.pc;

  if(debugger.step_cpu) {
    debugger.break_event = Debugger::BreakEvent::CPUStep;
    scheduler.exit(Scheduler::ExitReason::DebuggerEvent);
  } else {
    debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Exec, regs.pc, 0x00);
  }

  if(step_event) step_event();
  CPU::op_step();
  synchronize_smp();
}
コード例 #5
0
ファイル: mmio.cpp プロジェクト: CadeLaRen/BizHawk
uint8 CPU::mmio_read(unsigned addr) {
  if((addr & 0xffc0) == 0x2140) {
    synchronize_smp();
    return smp.port_read(addr & 3);
  }

  switch(addr & 0xffff) {
    case 0x2180: {
      uint8 result = bus.read(0x7e0000 | status.wram_addr);
      status.wram_addr = (status.wram_addr + 1) & 0x01ffff;
      return result;
    }

    case 0x4016: {
      uint8 result = regs.mdr & 0xfc;
      result |= input.port1->data() & 3;
      return result;
    }

    case 0x4017: {
      uint8 result = (regs.mdr & 0xe0) | 0x1c;
      result |= input.port2->data() & 3;
			if (!status.auto_joypad_poll_enabled) interface()->inputNotify(0x4017);
      return result;
    }

    case 0x4210: {
      uint8 result = (regs.mdr & 0x70);
      result |= status.nmi_line << 7;
      result |= 0x02;  //CPU revision
      status.nmi_line = false;
      return result;
    }

    case 0x4211: {
      uint8 result = (regs.mdr & 0x7f);
      result |= status.irq_line << 7;
      status.irq_line = false;
      return result;
    }

    case 0x4212: {
      uint8 result = (regs.mdr & 0x3e);
      unsigned vbstart = ppu.overscan() == false ? 225 : 240;

      if(vcounter() >= vbstart && vcounter() <= vbstart + 2) result |= 0x01;
      if(hcounter() <= 2 || hcounter() >= 1096) result |= 0x40;
      if(vcounter() >= vbstart) result |= 0x80;

      return result;
    }

    case 0x4213: 
			// interface()->inputNotify(0x4213); // if there are lag counter issues with super scope, uncomment this
			return status.pio;

    case 0x4214: return status.rddiv >> 0;
    case 0x4215: return status.rddiv >> 8;
    case 0x4216: return status.rdmpy >> 0;
    case 0x4217: return status.rdmpy >> 8;

    case 0x4218: interface()->inputNotify(0x4218); return status.joy1l;
    case 0x4219: interface()->inputNotify(0x4219); return status.joy1h;
    case 0x421a: interface()->inputNotify(0x421a); return status.joy2l;
    case 0x421b: interface()->inputNotify(0x421b); return status.joy2h;
    case 0x421c: interface()->inputNotify(0x421c); return status.joy3l;
    case 0x421d: interface()->inputNotify(0x421d); return status.joy3h;
    case 0x421e: interface()->inputNotify(0x421e); return status.joy4l;
    case 0x421f: interface()->inputNotify(0x421f); return status.joy4h;
  }

  if((addr & 0xff80) == 0x4300) {
    unsigned i = (addr >> 4) & 7;
    switch(addr & 0xff8f) {
      case 0x4300: {
        return (channel[i].direction << 7)
             | (channel[i].indirect << 6)
             | (channel[i].unused << 5)
             | (channel[i].reverse_transfer << 4)
             | (channel[i].fixed_transfer << 3)
             | (channel[i].transfer_mode << 0);
      }

      case 0x4301: return channel[i].dest_addr;
      case 0x4302: return channel[i].source_addr >> 0;
      case 0x4303: return channel[i].source_addr >> 8;
      case 0x4304: return channel[i].source_bank;
      case 0x4305: return channel[i].transfer_size >> 0;
      case 0x4306: return channel[i].transfer_size >> 8;
      case 0x4307: return channel[i].indirect_bank;
      case 0x4308: return channel[i].hdma_addr >> 0;
      case 0x4309: return channel[i].hdma_addr >> 8;
      case 0x430a: return channel[i].line_counter;
      case 0x430b: case 0x430f: return channel[i].unknown;
    }
  }
コード例 #6
0
void DSP::tick() {
  step(3 * 8);
  synchronize_smp();
}