Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cyclone and DrZ80 support #766

Merged
merged 4 commits into from
Jan 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,8 @@ else ifeq ($(platform), vita)
TARGET = $(TARGET_NAME)_libretro_$(platform).a
CC = arm-vita-eabi-gcc$(EXE_EXT)
AR = arm-vita-eabi-ar$(EXE_EXT)
PLATCFLAGS += -DVITA
CFLAGS += -mthumb -mfloat-abi=hard -fsingle-precision-constant
PLATCFLAGS += -DVITA -marm
CFLAGS += -mfloat-abi=hard -fsingle-precision-constant
CFLAGS += -Wall -mword-relocations
CFLAGS += -fomit-frame-pointer -ffast-math
CFLAGS += -fno-unwind-tables -fno-asynchronous-unwind-tables
Expand All @@ -341,7 +341,9 @@ else ifeq ($(platform), vita)
HAVE_RZLIB := 1
ARM = 1
STATIC_LINKING := 1

USE_CYCLONE := 1
USE_DRZ80 := 1

else ifneq (,$(findstring armv,$(platform)))
TARGET = $(TARGET_NAME)_libretro.so
CFLAGS += -fPIC
Expand Down Expand Up @@ -627,7 +629,7 @@ CFLAGS += $(INCFLAGS) $(INCFLAGS_PLATFORM)
# combine the various definitions to one
CDEFS = $(DEFS) $(COREDEFS) $(CPUDEFS) $(SOUNDDEFS) $(ASMDEFS) $(DBGDEFS)

OBJECTS := $(SOURCES_C:.c=.o)
OBJECTS := $(SOURCES_C:.c=.o) $(SOURCES_ASM:.s=.o)

OBJOUT = -o
LINKOUT = -o
Expand Down Expand Up @@ -678,6 +680,9 @@ CFLAGS += $(PLATCFLAGS) $(CDEFS)
@echo Compiling $<...
$(HIDE)$(CC) -c $(OBJOUT)$@ $< $(CFLAGS)

%.o: %.s
$(CC) -c $(OBJOUT)$@ $< $(CFLAGS)

$(OBJ)/%.a:
@echo Archiving $@...
@$(RM) $@
Expand Down
12 changes: 12 additions & 0 deletions Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -2702,3 +2702,15 @@ SOURCES_C += \
$(CORE_DIR)/lib/zlib/unzip.c \
$(CORE_DIR)/lib/zlib/zutil.c
endif

ifeq ($(USE_CYCLONE), 1)
CPUDEFS += -DHAS_CYCLONE=1
SOURCES_ASM += $(CORE_DIR)/cpu/m68000_cyclone/cyclone.s
SOURCES_C += $(CORE_DIR)/cpu/m68000_cyclone/c68000.c
endif

ifeq ($(USE_DRZ80), 1)
CPUDEFS += -DHAS_DRZ80=1
SOURCES_ASM += $(CORE_DIR)/cpu/z80_drz80/drz80.s
SOURCES_C += $(CORE_DIR)/cpu/z80_drz80/drz80_z80.c
endif
282 changes: 282 additions & 0 deletions src/cpu/m68000_cyclone/c68000.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
#include "c68000.h"
#include "driver.h"
#include "cpuintrf.h"
#include "cyclone.h"
#include "memory.h"


typedef struct
{
struct Cyclone regs;
int pending_interrupts;
int (*MAMEIrqCallback)(int int_level);
} Cyclone_Regs;

static Cyclone_Regs cyclone;
int cyclone_ICount;

static unsigned int MyCheckPc(unsigned int pc)
{
pc = (pc-cyclone.regs.membase) & 0xffffff; /* Get the real program counter */
change_pc24bew(pc);
cyclone.regs.membase=(unsigned int)OP_ROM;
return cyclone.regs.membase+pc; /* New program counter */
}

static void update_irq_line(void)
{
if (cyclone.pending_interrupts & 0xff000000)
{
int level, mask = 0x80000000;
for (level = 7; level; level--, mask >>= 1)
if (cyclone.pending_interrupts & mask)
break;
cyclone.regs.irq = level;
}
else
{
cyclone.regs.irq = 0;
}
}

static int MyIrqCallback(int irq)
{
cyclone.pending_interrupts &= ~(1 << (24 + irq));
if (cyclone.MAMEIrqCallback)
cyclone.MAMEIrqCallback(irq);
update_irq_line();
return CYCLONE_INT_ACK_AUTOVECTOR;
}

static void cyclone_Cause_Interrupt(int level)
{
if (level >= 1 && level <= 7)
cyclone.pending_interrupts |= 1 << (24 + level);
update_irq_line();
}

static void cyclone_Clear_Interrupt (int level)
{
if (level >= 1 && level <= 7)
cyclone.pending_interrupts &= ~(1 << (24 + level));
update_irq_line();
}

static data32_t cpu_readmem24bew_dword(offs_t address)
{
data32_t result = cpu_readmem24bew_word(address) << 16;
return result | cpu_readmem24bew_word(address + 2);
}

static void cpu_writemem24bew_dword(offs_t address, data32_t data)
{
cpu_writemem24bew_word(address, data >> 16);
cpu_writemem24bew_word(address + 2, data);
}

void cyclone_init(void)
{
CycloneInit();
}

void cyclone_reset(void *param)
{
memset(&cyclone, 0,sizeof(Cyclone_Regs));
cyclone.regs.checkpc=MyCheckPc;
cyclone.regs.read8 = (unsigned int (*)(unsigned int)) cpu_readmem24bew;
cyclone.regs.read16 = (unsigned int (*)(unsigned int)) cpu_readmem24bew_word;
cyclone.regs.read32 = (unsigned int (*)(unsigned int)) cpu_readmem24bew_dword;
cyclone.regs.write8 = (void (*)(unsigned int, unsigned char)) cpu_writemem24bew;
cyclone.regs.write16= (void (*)(unsigned int, unsigned short)) cpu_writemem24bew_word;
cyclone.regs.write32= (void (*)(unsigned int, unsigned int)) cpu_writemem24bew_dword;
cyclone.regs.fetch8 = (unsigned int (*)(unsigned int)) cpu_readmem24bew;
cyclone.regs.fetch16 = (unsigned int (*)(unsigned int)) cpu_readmem24bew_word;
cyclone.regs.fetch32 = (unsigned int (*)(unsigned int)) cpu_readmem24bew_dword;
cyclone.regs.IrqCallback=MyIrqCallback; /* 0 */
cyclone.regs.srh=0x27; /* Set supervisor mode */
cyclone.regs.a[7]=cyclone.regs.read32(0); /* Get Stack Pointer */
cyclone.regs.membase=0;
cyclone.regs.pc=cyclone.regs.checkpc(cyclone.regs.read32(4)); /* Get Program Counter */
cyclone.regs.state_flags = 0; /* not stopped or tracing */
cyclone.pending_interrupts = 0;
CycloneReset(&cyclone.regs);
}

unsigned int cyclone_get_pc(void)
{
return (cyclone.regs.pc - cyclone.regs.membase) & 0xffffff;
}

void cyclone_set_context(void *src)
{
if (src)
{
memcpy(&cyclone,src,sizeof(Cyclone_Regs));
}
update_irq_line();
}

unsigned cyclone_get_context(void *dst)
{
if (dst)
{
memcpy(dst,&cyclone,sizeof(Cyclone_Regs));
}
return sizeof(Cyclone_Regs);

}

int cyclone_execute(int cycles)
{
cyclone.regs.cycles = cycles;
cyclone_ICount = cyclone.regs.cycles;
CycloneRun(&cyclone.regs);
cyclone_ICount = cyclone.regs.cycles;
return (cycles - cyclone.regs.cycles);
}

void cyclone_exit(void)
{
}

void cyclone_set_pc(unsigned val)
{
cyclone.regs.pc=MyCheckPc(val);
}
unsigned cyclone_get_sp(void)
{
return cyclone.regs.a[7];
}

void cyclone_set_sp(unsigned val)
{
cyclone.regs.a[7] = val;
}

enum
{
/* NOTE: M68K_SP fetches the current SP, be it USP, ISP, or MSP */
M68K_PC=1, M68K_SP, M68K_ISP, M68K_USP, M68K_MSP, M68K_SR, M68K_VBR,
M68K_SFC, M68K_DFC, M68K_CACR, M68K_CAAR, M68K_PREF_ADDR, M68K_PREF_DATA,
M68K_D0, M68K_D1, M68K_D2, M68K_D3, M68K_D4, M68K_D5, M68K_D6, M68K_D7,
M68K_A0, M68K_A1, M68K_A2, M68K_A3, M68K_A4, M68K_A5, M68K_A6, M68K_A7
};

unsigned cyclone_get_reg(int regnum)
{
switch( regnum )
{
case REG_PC:
case M68K_PC: return cyclone_get_pc();
case REG_SP:
case M68K_SP: return cyclone_get_sp();
case M68K_ISP: return cyclone.regs.osp;
case M68K_USP: return cyclone.regs.osp;
case M68K_SR: return CycloneGetSr(&cyclone.regs);
case M68K_D0: return cyclone.regs.d[0];
case M68K_D1: return cyclone.regs.d[1];
case M68K_D2: return cyclone.regs.d[2];
case M68K_D3: return cyclone.regs.d[3];
case M68K_D4: return cyclone.regs.d[4];
case M68K_D5: return cyclone.regs.d[5];
case M68K_D6: return cyclone.regs.d[6];
case M68K_D7: return cyclone.regs.d[7];
case M68K_A0: return cyclone.regs.a[0];
case M68K_A1: return cyclone.regs.a[1];
case M68K_A2: return cyclone.regs.a[2];
case M68K_A3: return cyclone.regs.a[3];
case M68K_A4: return cyclone.regs.a[4];
case M68K_A5: return cyclone.regs.a[5];
case M68K_A6: return cyclone.regs.a[6];
case M68K_A7: return cyclone.regs.a[7];
case REG_PREVIOUSPC: return (cyclone.regs.prev_pc - cyclone.regs.membase - 2) & 0xffffff;
default:
if( regnum < REG_SP_CONTENTS )
{
unsigned offset = cyclone_get_sp() + 4 * (REG_SP_CONTENTS - regnum);
if( offset < 0xfffffd )
return cpu_readmem24bew_dword( offset );
}
}
return 0;
}

void cyclone_set_reg(int regnum, unsigned val)
{
switch( regnum )
{
case REG_PC:
case M68K_PC: cyclone_set_pc(val); break;
case REG_SP:
case M68K_SP: cyclone_set_sp(val); break;
case M68K_ISP: cyclone.regs.osp = val; break;
case M68K_USP: cyclone.regs.osp = val; break;
case M68K_SR: CycloneSetSr (&cyclone.regs,val); break;
case M68K_D0: cyclone.regs.d[0] = val; break;
case M68K_D1: cyclone.regs.d[1] = val; break;
case M68K_D2: cyclone.regs.d[2] = val; break;
case M68K_D3: cyclone.regs.d[3] = val; break;
case M68K_D4: cyclone.regs.d[4] = val; break;
case M68K_D5: cyclone.regs.d[5] = val; break;
case M68K_D6: cyclone.regs.d[6] = val; break;
case M68K_D7: cyclone.regs.d[7] = val; break;
case M68K_A0: cyclone.regs.a[0] = val; break;
case M68K_A1: cyclone.regs.a[1] = val; break;
case M68K_A2: cyclone.regs.a[2] = val; break;
case M68K_A3: cyclone.regs.a[3] = val; break;
case M68K_A4: cyclone.regs.a[4] = val; break;
case M68K_A5: cyclone.regs.a[5] = val; break;
case M68K_A6: cyclone.regs.a[6] = val; break;
case M68K_A7: cyclone.regs.a[7] = val; break;
default:
if( regnum < REG_SP_CONTENTS )
{
unsigned offset = cyclone_get_sp() + 4 * (REG_SP_CONTENTS - regnum);
if( offset < 0xfffffd )
cpu_writemem24bew_word( offset, val );
}
}
}

void cyclone_set_irq_line(int irqline, int state)
{
if (irqline == IRQ_LINE_NMI)
irqline = 7;
switch(state)
{
case CLEAR_LINE:
cyclone_Clear_Interrupt(irqline);
return;
case ASSERT_LINE:
cyclone_Cause_Interrupt(irqline);
return;
default:
cyclone_Cause_Interrupt(irqline);
return;
}
}

void cyclone_set_irq_callback(int (*callback)(int irqline))
{
cyclone.MAMEIrqCallback = callback;
}

const char *cyclone_info(void *context, int regnum)
{
switch( regnum )
{
case CPU_INFO_NAME: return "Cyclone 68000";
case CPU_INFO_FAMILY: return "Motorola 68K";
case CPU_INFO_VERSION: return "v0.0088";
case CPU_INFO_FILE: return __FILE__;
case CPU_INFO_CREDITS: return "Copyright Copyright 2004-2007 Dave, Reesy and Notaz. All rights reserved";
}
return "";
}

unsigned cyclone_dasm(char *buffer, unsigned pc)
{
change_pc24(pc);
sprintf(buffer, "$%04X", cpu_readop16(pc) );
return 2;
}
30 changes: 30 additions & 0 deletions src/cpu/m68000_cyclone/c68000.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef C68000_H
#define C68000_H

extern int cyclone_ICount;

#define cyclone_INT_NONE 0
#define cyclone_IRQ_1 1
#define cyclone_IRQ_2 2
#define cyclone_IRQ_3 3
#define cyclone_IRQ_4 4
#define cyclone_IRQ_5 5
#define cyclone_IRQ_6 6
#define cyclone_IRQ_7 7
#define cyclone_INT_ACK_AUTOVECTOR -1
#define cyclone_STOP 0x10

extern void cyclone_init(void);
extern void cyclone_reset(void *param);
extern void cyclone_exit(void);
extern int cyclone_execute(int cycles);
extern unsigned cyclone_get_context(void *dst);
extern void cyclone_set_context(void *src);
extern unsigned cyclone_get_reg(int regnum);
extern void cyclone_set_reg(int regnum, unsigned val);
extern void cyclone_set_irq_line(int irqline, int state);
extern void cyclone_set_irq_callback(int (*callback)(int irqline));
extern const char *cyclone_info(void *context, int regnum);
extern unsigned cyclone_dasm(char *buffer, unsigned pc);

#endif
Loading