예제 #1
0
파일: memory.c 프로젝트: TASVideos/BizHawk
static void bank_switch(int b)
{
  unsigned int rs, bank;

  if (Pico.m.ncart_in)
    return;

  bank = b << 20;
  if ((Pico.m.sram_reg & SRR_MAPPED) && bank == SRam.start) {
    bank_map_handler();
    return;
  }

  if (bank >= Pico.romsize) {
    elprintf(EL_32X|EL_ANOMALY, "missing bank @ %06x", bank);
    bank_map_handler();
    return;
  }

  // 32X ROM (unbanked, XXX: consider mirroring?)
  rs = (Pico.romsize + M68K_BANK_MASK) & ~M68K_BANK_MASK;
  rs -= bank;
  if (rs > 0x100000)
    rs = 0x100000;
  cpu68k_map_set(m68k_read8_map,   0x900000, 0x900000 + rs - 1, Pico.rom + bank, 0);
  cpu68k_map_set(m68k_read16_map,  0x900000, 0x900000 + rs - 1, Pico.rom + bank, 0);

  elprintf(EL_32X, "bank %06x-%06x -> %06x", 0x900000, 0x900000 + rs - 1, bank);

#ifdef EMU_F68K
  // setup FAME fetchmap
  for (rs = 0x90; rs < 0xa0; rs++)
    PicoCpuFM68k.Fetch[rs] = (unsigned long)Pico.rom + bank - 0x900000;
#endif
}
예제 #2
0
파일: cmn.c 프로젝트: 133794m3r/picodrive
void drc_cmn_init(void)
{
  int ret = plat_mem_set_exec(tcache, sizeof(tcache));
  elprintf(EL_STATUS, "drc_cmn_init: %p, %zd bytes: %d",
    tcache, sizeof(tcache), ret);

#ifdef __arm__
  if (PicoOpt & POPT_EN_DRC)
  {
    static int test_done;
    if (!test_done)
    {
      int *test_out = (void *)tcache;
      int (*testfunc)(void) = (void *)tcache;

      elprintf(EL_STATUS, "testing if we can run recompiled code..");
      *test_out++ = 0xe3a000dd; // mov r0, 0xdd
      *test_out++ = 0xe12fff1e; // bx lr
      cache_flush_d_inval_i(tcache, test_out);

      // we'll usually crash on broken platforms or bad ports,
      // but do a value check too just in case
      ret = testfunc();
      elprintf(EL_STATUS, "test %s.", ret == 0xdd ? "passed" : "failed");
      test_done = 1;
    }
  }
#endif
}
예제 #3
0
파일: memory.c 프로젝트: TASVideos/BizHawk
void PicoWrite8_32x(u32 a, u32 d)
{
  if ((a & 0xffc0) == 0x5100) { // a15100
    u16 *r = Pico32x.regs;

    elprintf(EL_32X, "m68k 32x w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);
    a &= 0x3f;
    if (a == 1) {
      if ((d ^ r[0]) & d & P32XS_ADEN) {
        Pico32xStartup();
        r[0] &= ~P32XS_nRES; // causes reset if specified by this write
        r[0] |= P32XS_ADEN;
        p32x_reg_write8(a, d); // forward for reset processing
      }
      return;
    }

    // allow only COMM for now
    if ((a & 0x30) == 0x20) {
      u8 *r8 = (u8 *)r;
      r8[a ^ 1] = d;
    }
    return;
  }

  elprintf(EL_UIO, "m68k unmapped w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);
}
예제 #4
0
파일: memory.c 프로젝트: TASVideos/BizHawk
static void PicoWrite16_32x_on(u32 a, u32 d)
{
  if ((a & 0xfc00) == 0x5000)
    elprintf(EL_32X, "m68k 32x w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);

  if ((a & 0xffc0) == 0x5100) { // a15100
    p32x_reg_write16(a, d);
    return;
  }

  if ((a & 0xfc00) != 0x5000) {
    if (PicoAHW & PAHW_MCD)
      PicoWrite16_mcd_io(a, d);
    else
      PicoWrite16_io(a, d);
    if (a == 0xa130f0)
      bank_switch(Pico32x.regs[4 / 2]);
    return;
  }

  if (!(Pico32x.regs[0] & P32XS_FM)) {
    if ((a & 0xfff0) == 0x5180) { // a15180
      p32x_vdp_write16(a, d, NULL); // FIXME?
      return;
    }

    if ((a & 0xfe00) == 0x5200) { // a15200
      Pico32xMem->pal[(a & 0x1ff) / 2] = d;
      Pico32x.dirty_pal = 1;
      return;
    }
  }

  elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
}
예제 #5
0
static int SekIntAckM68K(int level)
{
  if     (level == 4) { Pico.video.pending_ints  =  0;    elprintf(EL_INTS, "hack: @ %06x [%i]", SekPc, SekCycleCnt); }
  else if(level == 6) { Pico.video.pending_ints &= ~0x20; elprintf(EL_INTS, "vack: @ %06x [%i]", SekPc, SekCycleCnt); }
  CPU_INT_LEVEL = 0;
  return M68K_INT_ACK_AUTOVECTOR;
}
예제 #6
0
// interrupt acknowledgment
static int SekIntAck(int level)
{
  // try to emulate VDP's reaction to 68000 int ack
  if     (level == 4) { Pico.video.pending_ints  =  0;    elprintf(EL_INTS, "hack: @ %06x [%i]", SekPc, SekCycleCnt); }
  else if(level == 6) { Pico.video.pending_ints &= ~0x20; elprintf(EL_INTS, "vack: @ %06x [%i]", SekPc, SekCycleCnt); }
  PicoCpuCM68k.irq = 0;
  return CYCLONE_INT_ACK_AUTOVECTOR;
}
예제 #7
0
static void SekIntAckF68K(unsigned level)
{
  if     (level == 4) {
    Pico.video.pending_ints = 0;
    elprintf(EL_INTS, "hack: @ %06x [%i]", SekPc, SekCyclesDone());
  }
  else if(level == 6) {
    Pico.video.pending_ints &= ~0x20;
    elprintf(EL_INTS, "vack: @ %06x [%i]", SekPc, SekCyclesDone());
  }
  PicoCpuFM68k.interrupts[0] = 0;
}
예제 #8
0
파일: memory.c 프로젝트: TASVideos/BizHawk
static void PicoWrite16_cart(u32 a, u32 d)
{
  elprintf(EL_UIO, "m68k w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);

  a &= 0xfffff;
  m68k_write16(a, d);
}
예제 #9
0
// 0-4, 13
static u32 read_unknown(void)
{
#ifdef LOG_SVP
  elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME: unknown read @ %04x", GET_PPC_OFFS());
#endif
  return 0;
}
예제 #10
0
파일: cd_sys.c 프로젝트: pcercuei/picodrive
PICO_INTERNAL int Open_Tray_CDD_cD(void)
{
	CHECK_TRAY_OPEN

	Pico_mcd->scd.Status_CDC &= ~1;			// Stop CDC read

	elprintf(EL_STATUS, "tray open\n");

	Unload_ISO();
	CD_Present = 0;

	if (PicoMCDopenTray != NULL)
		PicoMCDopenTray();

	Pico_mcd->scd.Status_CDD = TRAY_OPEN;
	Pico_mcd->cdd.Status = 0x0E00;

	Pico_mcd->cdd.Minute = 0;
	Pico_mcd->cdd.Seconde = 0;
	Pico_mcd->cdd.Frame = 0;
	Pico_mcd->cdd.Ext = 0;

	Pico_mcd->scd.CDD_Complete = 1;

	return 0;
}
예제 #11
0
파일: memory.c 프로젝트: TASVideos/BizHawk
static int m68k_poll_detect(u32 a, u32 cycles, u32 flags)
{
  int ret = 0;

  if (a - 2 <= m68k_poll.addr && m68k_poll.addr <= a + 2
    && cycles - m68k_poll.cycles <= 64 && !SekNotPolling)
  {
    if (m68k_poll.cnt++ > POLL_THRESHOLD) {
      if (!(Pico32x.emu_flags & flags)) {
        elprintf(EL_32X, "m68k poll addr %08x, cyc %u",
          a, cycles - m68k_poll.cycles);
        ret = 1;
      }
      Pico32x.emu_flags |= flags;
    }
  }
  else {
    m68k_poll.cnt = 0;
    m68k_poll.addr = a;
    SekNotPolling = 0;
  }
  m68k_poll.cycles = cycles;

  return ret;
}
예제 #12
0
파일: pwm.c 프로젝트: OpenEmu/picodrive
unsigned int p32x_pwm_read16(unsigned int a, SH2 *sh2,
  unsigned int m68k_cycles)
{
  unsigned int d = 0;

  consume_fifo(sh2, m68k_cycles);

  a &= 0x0e;
  switch (a) {
    case 0: // control
    case 2: // cycle
      d = Pico32x.regs[(0x30 + a) / 2];
      break;

    case 4: // L ch
      if (Pico32x.pwm_p[0] == 3)
        d |= P32XP_FULL;
      else if (Pico32x.pwm_p[0] == 0)
        d |= P32XP_EMPTY;
      break;

    case 6: // R ch
    case 8: // MONO
      if (Pico32x.pwm_p[1] == 3)
        d |= P32XP_FULL;
      else if (Pico32x.pwm_p[1] == 0)
        d |= P32XP_EMPTY;
      break;
  }

  elprintf(EL_PWM, "pwm: %u: r16 %02x %04x (p %d %d)",
    m68k_cycles, a, d, Pico32x.pwm_p[0], Pico32x.pwm_p[1]);
  return d;
}
예제 #13
0
파일: memory.c 프로젝트: TASVideos/BizHawk
static void p32x_vdp_write8(u32 a, u32 d)
{
  u16 *r = Pico32x.vdp_regs;
  a &= 0x0f;

  // TODO: verify what's writeable
  switch (a) {
    case 0x01:
      // priority inversion is handled in palette
      if ((r[0] ^ d) & P32XV_PRI)
        Pico32x.dirty_pal = 1;
      r[0] = (r[0] & P32XV_nPAL) | (d & 0xff);
      break;
    case 0x03: // shift (for pp mode)
      r[2 / 2] = d & 1;
      break;
    case 0x05: // fill len
      r[4 / 2] = d & 0xff;
      break;
    case 0x0b:
      d &= 1;
      Pico32x.pending_fb = d;
      // if we are blanking and FS bit is changing
      if (((r[0x0a/2] & P32XV_VBLK) || (r[0] & P32XV_Mx) == 0) && ((r[0x0a/2] ^ d) & P32XV_FS)) {
        r[0x0a/2] ^= P32XV_FS;
        Pico32xSwapDRAM(d ^ 1);
        elprintf(EL_32X, "VDP FS: %d", r[0x0a/2] & P32XV_FS);
      }
      break;
  }
}
예제 #14
0
// 4
static void write_ST(u32 d)
{
  //if ((rST ^ d) & 0x0007) elprintf(EL_SVP, "ssp RPL %i -> %i @ %04x", rST&7, d&7, GET_PPC_OFFS());
#ifdef LOG_SVP
  if ((rST ^ d) & 0x0f98) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME ST %04x -> %04x @ %04x", rST, d, GET_PPC_OFFS());
#endif
  rST = d;
}
예제 #15
0
void PicoCDBufferFree(void)
{
	if (cd_buffer) {
		free(cd_buffer);
		cd_buffer = NULL;
	}
	if (reads)
		elprintf(EL_STATUS, "CD buffer hits: %i/%i (%i%%)\n", hits, reads, hits * 100 / reads);
}
예제 #16
0
파일: memory.c 프로젝트: TASVideos/BizHawk
static void PicoWrite16_bank(u32 a, u32 d)
{
  if (!(Pico.m.sram_reg & SRR_MAPPED))
    elprintf(EL_UIO, "m68k w16 [%06x] %04x @%06x",
      a, d & 0xffff, SekPc);

  a = (Pico32x.regs[4 / 2] << 20) | (a & 0xfffff);
  m68k_write16(a, d);
}
예제 #17
0
파일: memory.c 프로젝트: TASVideos/BizHawk
// hint vector is writeable
static void PicoWrite8_hint(u32 a, u32 d)
{
  if ((a & 0xfffc) == 0x0070) {
    Pico32xMem->m68k_rom[a ^ 1] = d;
    return;
  }

  elprintf(EL_UIO, "m68k unmapped w8  [%06x]   %02x @%06x",
    a, d & 0xff, SekPc);
}
예제 #18
0
파일: memory.c 프로젝트: TASVideos/BizHawk
void p32x_m68k_poll_event(u32 flags)
{
  if (Pico32x.emu_flags & flags) {
    elprintf(EL_32X, "m68k poll %02x -> %02x", Pico32x.emu_flags,
      Pico32x.emu_flags & ~flags);
    Pico32x.emu_flags &= ~flags;
    SekSetStop(0);
  }
  m68k_poll.addr = m68k_poll.cnt = 0;
}
예제 #19
0
파일: memory.c 프로젝트: TASVideos/BizHawk
// after ADEN
static u32 PicoRead8_32x_on(u32 a)
{
  u32 d = 0;
  if ((a & 0xffc0) == 0x5100) { // a15100
    d = p32x_reg_read16(a);
    goto out_16to8;
  }

  if ((a & 0xfc00) != 0x5000) {
    if (PicoAHW & PAHW_MCD)
      return PicoRead8_mcd_io(a);
    else
      return PicoRead8_io(a);
  }

  if ((a & 0xfff0) == 0x5180) { // a15180
    d = p32x_vdp_read16(a);
    goto out_16to8;
  }

  if ((a & 0xfe00) == 0x5200) { // a15200
    d = Pico32xMem->pal[(a & 0x1ff) / 2];
    goto out_16to8;
  }

  if ((a & 0xfffc) == 0x30ec) { // a130ec
    d = str_mars[a & 3];
    goto out;
  }

  elprintf(EL_UIO, "m68k unmapped r8  [%06x] @%06x", a, SekPc);
  return d;

out_16to8:
  if (a & 1)
    d &= 0xff;
  else
    d >>= 8;

out:
  elprintf(EL_32X, "m68k 32x r8  [%06x]   %02x @%06x", a, d, SekPc);
  return d;
}
예제 #20
0
파일: memory.c 프로젝트: TASVideos/BizHawk
static void PicoWrite16_hint(u32 a, u32 d)
{
  if ((a & 0xfffc) == 0x0070) {
    ((u16 *)Pico32xMem->m68k_rom)[a/2] = d;
    return;
  }

  elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x",
    a, d & 0xffff, SekPc);
}
예제 #21
0
static void write_STACK(u32 d)
{
  if (rSTACK >= 6) {
#ifdef LOG_SVP
    elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME: stack overflow! (%i) @ %04x", rSTACK, GET_PPC_OFFS());
#endif
  rSTACK = 0;
  }
  ssp->stack[rSTACK++] = d;
}
예제 #22
0
// 5
static u32 read_STACK(void)
{
  --rSTACK;
  if ((short)rSTACK < 0) {
    rSTACK = 5;
#ifdef LOG_SVP
    elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME: stack underflow! (%i) @ %04x", rSTACK, GET_PPC_OFFS());
#endif
  }
  return ssp->stack[rSTACK];
}
예제 #23
0
파일: memory.c 프로젝트: TASVideos/BizHawk
u32 PicoRead16_32x(u32 a)
{
  u32 d = 0;
  if ((a & 0xffc0) == 0x5100) { // a15100
    d = Pico32x.regs[(a & 0x3f) / 2];
    goto out;
  }

  if ((a & 0xfffc) == 0x30ec) { // a130ec
    d = !(a & 2) ? ('M'<<8)|'A' : ('R'<<8)|'S';
    goto out;
  }

  elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc);
  return d;

out:
  elprintf(EL_32X, "m68k 32x r16 [%06x] %04x @%06x", a, d, SekPc);
  return d;
}
예제 #24
0
static int SekUnrecognizedOpcode()
{
  unsigned int pc;
  pc = SekPc;
  elprintf(EL_ANOMALY, "Unrecognized Opcode @ %06x", pc);
  // see if we are still in a mapped region
  pc &= 0x00ffffff;
  if (map_flag_set(m68k_read16_map[pc >> M68K_MEM_SHIFT])) {
    elprintf(EL_STATUS|EL_ANOMALY, "m68k crash @%06x", pc);
    PicoCpuCM68k.cycles = 0;
    PicoCpuCM68k.state_flags |= 1;
    return 1;
  }
#ifdef EMU_M68K // debugging cyclone
  {
    extern int have_illegal;
    have_illegal = 1;
  }
#endif
  return 0;
}
예제 #25
0
파일: memory.c 프로젝트: TASVideos/BizHawk
static void z80_md_bank_write_32x(unsigned int a, unsigned char d)
{
  unsigned int addr68k;

  addr68k = Pico.m.z80_bank68k << 15;
  addr68k += a & 0x7fff;
  if ((addr68k & 0xfff000) == 0xa15000)
    Pico32x.emu_flags |= P32XF_Z80_32X_IO;

  elprintf(EL_Z80BNK, "z80->68k w8 [%06x] %02x", addr68k, d);
  m68k_write8(addr68k, d);
}
예제 #26
0
파일: sek.c 프로젝트: notaz/picodrive
static int do_ack(int level)
{
  struct PicoVideo *pv = &Pico.video;

  elprintf(EL_INTS, "%cack: @ %06x [%u], p=%02x",
    level == 6 ? 'v' : 'h', SekPc, SekCyclesDone(), pv->pending_ints);
  // the VDP doesn't look at the 68k level
  if (pv->pending_ints & pv->reg[1] & 0x20) {
    pv->pending_ints &= ~0x20;
    pv->status &= ~SR_F;
    return (pv->reg[0] & pv->pending_ints & 0x10) >> 2;
  }
예제 #27
0
파일: memory.c 프로젝트: TASVideos/BizHawk
// before ADEN
u32 PicoRead8_32x(u32 a)
{
  u32 d = 0;
  if ((a & 0xffc0) == 0x5100) { // a15100
    // regs are always readable
    d = ((u8 *)Pico32x.regs)[(a & 0x3f) ^ 1];
    goto out;
  }

  if ((a & 0xfffc) == 0x30ec) { // a130ec
    d = str_mars[a & 3];
    goto out;
  }

  elprintf(EL_UIO, "m68k unmapped r8  [%06x] @%06x", a, SekPc);
  return d;

out:
  elprintf(EL_32X, "m68k 32x r8  [%06x]   %02x @%06x", a, d, SekPc);
  return d;
}
예제 #28
0
파일: pwm.c 프로젝트: OpenEmu/picodrive
static void consume_fifo_do(SH2 *sh2, unsigned int m68k_cycles,
  int sh2_cycles_diff)
{
  struct Pico32xMem *mem = Pico32xMem;
  unsigned short *fifo_l = mem->pwm_fifo[0];
  unsigned short *fifo_r = mem->pwm_fifo[1];
  int sum = 0;

  if (pwm_cycles == 0 || pwm_doing_fifo)
    return;

  elprintf(EL_PWM, "pwm: %u: consume %d/%d, %d,%d ptr %d",
    m68k_cycles, sh2_cycles_diff, sh2_cycles_diff / pwm_cycles,
    Pico32x.pwm_p[0], Pico32x.pwm_p[1], pwm_ptr);

  // this is for recursion from dreq1 writes
  pwm_doing_fifo = 1;

  for (; sh2_cycles_diff >= pwm_cycles; sh2_cycles_diff -= pwm_cycles)
  {
    if (Pico32x.pwm_p[0] > 0) {
      fifo_l[0] = fifo_l[1];
      fifo_l[1] = fifo_l[2];
      fifo_l[2] = fifo_l[3];
      Pico32x.pwm_p[0]--;
      mem->pwm_current[0] = convert_sample(fifo_l[0]);
      sum += mem->pwm_current[0];
    }
    if (Pico32x.pwm_p[1] > 0) {
      fifo_r[0] = fifo_r[1];
      fifo_r[1] = fifo_r[2];
      fifo_r[2] = fifo_r[3];
      Pico32x.pwm_p[1]--;
      mem->pwm_current[1] = convert_sample(fifo_r[0]);
      sum += mem->pwm_current[1];
    }

    mem->pwm[pwm_ptr * 2    ] = mem->pwm_current[0];
    mem->pwm[pwm_ptr * 2 + 1] = mem->pwm_current[1];
    pwm_ptr = (pwm_ptr + 1) & (PWM_BUFF_LEN - 1);

    if (--Pico32x.pwm_irq_cnt == 0) {
      Pico32x.pwm_irq_cnt = pwm_irq_reload;
      do_pwm_irq(sh2, m68k_cycles);
    }
  }
  Pico32x.pwm_cycle_p = m68k_cycles * 3 - sh2_cycles_diff;
  pwm_doing_fifo = 0;
  if (sum != 0)
    pwm_silent = 0;
}
예제 #29
0
파일: memory.c 프로젝트: TASVideos/BizHawk
static u32 PicoRead16_32x_on(u32 a)
{
  u32 d = 0;
  if ((a & 0xffc0) == 0x5100) { // a15100
    d = p32x_reg_read16(a);
    goto out;
  }

  if ((a & 0xfc00) != 0x5000) {
    if (PicoAHW & PAHW_MCD)
      return PicoRead16_mcd_io(a);
    else
      return PicoRead16_io(a);
  }

  if ((a & 0xfff0) == 0x5180) { // a15180
    d = p32x_vdp_read16(a);
    goto out;
  }

  if ((a & 0xfe00) == 0x5200) { // a15200
    d = Pico32xMem->pal[(a & 0x1ff) / 2];
    goto out;
  }

  if ((a & 0xfffc) == 0x30ec) { // a130ec
    d = !(a & 2) ? ('M'<<8)|'A' : ('R'<<8)|'S';
    goto out;
  }

  elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc);
  return d;

out:
  elprintf(EL_32X, "m68k 32x r16 [%06x] %04x @%06x", a, d, SekPc);
  return d;
}
예제 #30
0
파일: memory.c 프로젝트: TASVideos/BizHawk
static void PicoWrite8_32x_on(u32 a, u32 d)
{
  if ((a & 0xfc00) == 0x5000)
    elprintf(EL_32X, "m68k 32x w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);

  if ((a & 0xffc0) == 0x5100) { // a15100
    p32x_reg_write8(a, d);
    return;
  }

  if ((a & 0xfc00) != 0x5000) {
    if (PicoAHW & PAHW_MCD)
      PicoWrite8_mcd_io(a, d);
    else
      PicoWrite8_io(a, d);
    if (a == 0xa130f1)
      bank_switch(Pico32x.regs[4 / 2]);
    return;
  }

  if (!(Pico32x.regs[0] & P32XS_FM)) {
    if ((a & 0xfff0) == 0x5180) { // a15180
      p32x_vdp_write8(a, d);
      return;
    }

    // TODO: verify
    if ((a & 0xfe00) == 0x5200) { // a15200
      elprintf(EL_32X|EL_ANOMALY, "m68k 32x PAL w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);
      ((u8 *)Pico32xMem->pal)[(a & 0x1ff) ^ 1] = d;
      Pico32x.dirty_pal = 1;
      return;
    }
  }

  elprintf(EL_UIO, "m68k unmapped w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);
}