mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00

- PicoDrive was originally released by fDave with simple "free for non-commercial use / For commercial use, separate licencing terms must be obtained" license and I kept it in my releases. - in 2011, fDave re-released his code (same that I used as base many years ago) dual licensed with GPLv2 and MAME licenses: https://code.google.com/p/cyclone68000/ Based on the above I now proclaim that the whole source code is licensed under the MAME license as more elaborate form of "for non-commercial use". If that raises any doubt, I announce that all my modifications (which is the vast majority of code by now) is licensed under the MAME license, as it reads in COPYING file in this commit. This does not affect ym2612.c/sn76496.c that were MAME licensed already from the beginning.
191 lines
3.8 KiB
C
191 lines
3.8 KiB
C
/*
|
|
* PicoDrive
|
|
* (C) notaz, 2007
|
|
*
|
|
* This work is licensed under the terms of MAME license.
|
|
* See COPYING file in the top-level directory.
|
|
*/
|
|
|
|
#include "../pico_int.h"
|
|
|
|
|
|
int SekCycleCntS68k=0; // cycles done in this frame
|
|
int SekCycleAimS68k=0; // cycle aim
|
|
|
|
|
|
/* context */
|
|
// Cyclone 68000
|
|
#ifdef EMU_C68K
|
|
struct Cyclone PicoCpuCS68k;
|
|
#endif
|
|
// MUSASHI 68000
|
|
#ifdef EMU_M68K
|
|
m68ki_cpu_core PicoCpuMS68k;
|
|
#endif
|
|
// FAME 68000
|
|
#ifdef EMU_F68K
|
|
M68K_CONTEXT PicoCpuFS68k;
|
|
#endif
|
|
|
|
|
|
static int new_irq_level(int level)
|
|
{
|
|
int level_new = 0, irqs;
|
|
Pico_mcd->m.s68k_pend_ints &= ~(1 << level);
|
|
irqs = Pico_mcd->m.s68k_pend_ints;
|
|
irqs &= Pico_mcd->s68k_regs[0x33];
|
|
while ((irqs >>= 1)) level_new++;
|
|
|
|
return level_new;
|
|
}
|
|
|
|
#ifdef EMU_C68K
|
|
// interrupt acknowledgement
|
|
static int SekIntAckS68k(int level)
|
|
{
|
|
int level_new = new_irq_level(level);
|
|
|
|
elprintf(EL_INTS, "s68kACK %i -> %i", level, level_new);
|
|
PicoCpuCS68k.irq = level_new;
|
|
return CYCLONE_INT_ACK_AUTOVECTOR;
|
|
}
|
|
|
|
static void SekResetAckS68k(void)
|
|
{
|
|
elprintf(EL_ANOMALY, "s68k: Reset encountered @ %06x", SekPcS68k);
|
|
}
|
|
|
|
static int SekUnrecognizedOpcodeS68k(void)
|
|
{
|
|
elprintf(EL_ANOMALY, "Unrecognized Opcode @ %06x", SekPcS68k);
|
|
//exit(1);
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef EMU_M68K
|
|
static int SekIntAckMS68k(int level)
|
|
{
|
|
#ifndef EMU_CORE_DEBUG
|
|
int level_new = new_irq_level(level);
|
|
elprintf(EL_INTS, "s68kACK %i -> %i", level, level_new);
|
|
CPU_INT_LEVEL = level_new << 8;
|
|
#else
|
|
CPU_INT_LEVEL = 0;
|
|
#endif
|
|
return M68K_INT_ACK_AUTOVECTOR;
|
|
}
|
|
#endif
|
|
|
|
#ifdef EMU_F68K
|
|
static void SekIntAckFS68k(unsigned level)
|
|
{
|
|
int level_new = new_irq_level(level);
|
|
elprintf(EL_INTS, "s68kACK %i -> %i", level, level_new);
|
|
#ifndef EMU_CORE_DEBUG
|
|
PicoCpuFS68k.interrupts[0] = level_new;
|
|
#else
|
|
{
|
|
extern int dbg_irq_level_sub;
|
|
dbg_irq_level_sub = level_new;
|
|
PicoCpuFS68k.interrupts[0] = 0;
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
|
|
PICO_INTERNAL void SekInitS68k(void)
|
|
{
|
|
#ifdef EMU_C68K
|
|
// CycloneInit();
|
|
memset(&PicoCpuCS68k,0,sizeof(PicoCpuCS68k));
|
|
PicoCpuCS68k.IrqCallback=SekIntAckS68k;
|
|
PicoCpuCS68k.ResetCallback=SekResetAckS68k;
|
|
PicoCpuCS68k.UnrecognizedCallback=SekUnrecognizedOpcodeS68k;
|
|
#endif
|
|
#ifdef EMU_M68K
|
|
{
|
|
// Musashi is not very context friendly..
|
|
void *oldcontext = m68ki_cpu_p;
|
|
m68k_set_context(&PicoCpuMS68k);
|
|
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
|
|
m68k_init();
|
|
m68k_set_int_ack_callback(SekIntAckMS68k);
|
|
// m68k_pulse_reset(); // not yet, memmap is not set up
|
|
m68k_set_context(oldcontext);
|
|
}
|
|
#endif
|
|
#ifdef EMU_F68K
|
|
{
|
|
void *oldcontext = g_m68kcontext;
|
|
g_m68kcontext = &PicoCpuFS68k;
|
|
memset(&PicoCpuFS68k, 0, sizeof(PicoCpuFS68k));
|
|
fm68k_init();
|
|
PicoCpuFS68k.iack_handler = SekIntAckFS68k;
|
|
PicoCpuFS68k.sr = 0x2704; // Z flag
|
|
g_m68kcontext = oldcontext;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// Reset the 68000:
|
|
PICO_INTERNAL int SekResetS68k(void)
|
|
{
|
|
if (Pico.rom==NULL) return 1;
|
|
|
|
#ifdef EMU_C68K
|
|
CycloneReset(&PicoCpuCS68k);
|
|
#endif
|
|
#ifdef EMU_M68K
|
|
{
|
|
void *oldcontext = m68ki_cpu_p;
|
|
|
|
m68k_set_context(&PicoCpuMS68k);
|
|
m68ki_cpu.sp[0]=0;
|
|
m68k_set_irq(0);
|
|
m68k_pulse_reset();
|
|
m68k_set_context(oldcontext);
|
|
}
|
|
#endif
|
|
#ifdef EMU_F68K
|
|
{
|
|
void *oldcontext = g_m68kcontext;
|
|
g_m68kcontext = &PicoCpuFS68k;
|
|
fm68k_reset();
|
|
g_m68kcontext = oldcontext;
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
PICO_INTERNAL int SekInterruptS68k(int irq)
|
|
{
|
|
int irqs, real_irq = 1;
|
|
Pico_mcd->m.s68k_pend_ints |= 1 << irq;
|
|
irqs = Pico_mcd->m.s68k_pend_ints >> 1;
|
|
while ((irqs >>= 1)) real_irq++;
|
|
|
|
#ifdef EMU_CORE_DEBUG
|
|
{
|
|
extern int dbg_irq_level_sub;
|
|
dbg_irq_level_sub=real_irq;
|
|
return 0;
|
|
}
|
|
#endif
|
|
#ifdef EMU_C68K
|
|
PicoCpuCS68k.irq=real_irq;
|
|
#endif
|
|
#ifdef EMU_M68K
|
|
void *oldcontext = m68ki_cpu_p;
|
|
m68k_set_context(&PicoCpuMS68k);
|
|
m68k_set_irq(real_irq);
|
|
m68k_set_context(oldcontext);
|
|
#endif
|
|
#ifdef EMU_F68K
|
|
PicoCpuFS68k.interrupts[0]=real_irq;
|
|
#endif
|
|
return 0;
|
|
}
|
|
|