mirror of
https://github.com/libretro/Mu.git
synced 2026-02-13 21:24:19 +00:00
Compare commits
1 Commits
armCpu
...
fameExperi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e0fdfa53d |
@@ -27,6 +27,7 @@ UART1 USTCNT1
|
||||
PLLFSR has a hack that makes busy wait loops finish faster by toggling the CLK32 bit on read, for power button issue
|
||||
should also not transfer data to SD card when MOSI, MISO or SPICLK1 are disabled
|
||||
port d data register INT* bits seem to have there data bits cleared when an edge triggered interrupt is cleared(according to MC68VZ328UM.pdf Page 10-15)
|
||||
Cyclone will cause SIGSEGVs, don't know why yet(seems to have been caused by compressed jumptable)
|
||||
|
||||
Memory:
|
||||
SD card can't be read or written to by Palm OS
|
||||
@@ -57,13 +58,11 @@ edge triggered INT* don't clear on write to ISR when masked in IMR(I needed to u
|
||||
PDKBEN also has a hack for power on(its been removed)
|
||||
On hardware PDIRQEG seems not to actually work at all(CPUID:0x57000000)(it does)
|
||||
may need to trigger an interrupt if a IMR masked interrupt becomes unmasked and its bit is still set in IPR(already doing that)
|
||||
Cyclone will cause SIGSEGVs, don't know why yet(seems to have been caused by compressed jumptable)
|
||||
power button must be pushed twice to turn the CPU back on(when debugging it works the first time, then must be pushed twice to turn off instead of on)(this also occurs in the RetroArch build)
|
||||
the power button double press issue may be because the button map I am using was taken from POSE source, the power button may be mapped to other locations on the button matrix than expected
|
||||
if a sound interrupt is triggered while the button interrupt is disabled the button interrupt will still trigger(in galax game)(seems to be an issue with FIFOAV always = true hack and how INT_PWM1 needed to be cleared on read or write)
|
||||
SED1376 16 bpp mode is broken and crushed to the top of the screen
|
||||
audio can max out the resampler buffer, the max 1 FIFO sample can play is around 2.16 minutes(CLK32 / period(257) / clockDivider(16) / prescaler(128) / repeat(8))(257 * 16 * 128 * 8 / 32768=128.5 seconds)(safety check added, >= 1 second duty cycle is useless and will just make annoying cracks anyway)
|
||||
Cyclone CPU emulator is not working
|
||||
PWM1 output value is not a direct range cast of 0<->255 to 0<->32767, its additive, see properPwmSineWave.png
|
||||
inductor dosent properly drain when PWM1 gets disabled
|
||||
PWM1 FIFOAV is always set true
|
||||
|
||||
@@ -7,6 +7,7 @@ INCFLAGS := -I$(LIBRETRO_COMM_DIR)/include
|
||||
ifeq ($(DEBUG), 1)
|
||||
COREDEFINES += -DEMU_DEBUG -DEMU_SANDBOX
|
||||
else
|
||||
EMU_FAST_CPU = 1
|
||||
COREDEFINES += -DEMU_NO_SAFETY
|
||||
endif
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@ android{
|
||||
QMAKE_CXXFLAGS += -fopenmp
|
||||
QMAKE_LFLAGS += -fopenmp
|
||||
DEFINES += EMU_MULTITHREADED
|
||||
# CONFIG += optimize_for_arm32 # for now, later this will check if building for ARMv4<->7
|
||||
}
|
||||
|
||||
ios{
|
||||
@@ -63,7 +62,8 @@ ios{
|
||||
CONFIG(debug, debug|release){
|
||||
# debug build, be accurate, fail hard, and add logging
|
||||
DEFINES += EMU_DEBUG EMU_CUSTOM_DEBUG_LOG_HANDLER
|
||||
!optimize_for_arm32:DEFINES += EMU_SANDBOX
|
||||
# EMU_SANDBOX
|
||||
CONFIG += emu_fast_cpu
|
||||
macx|linux-g++{
|
||||
# DEFINES += EMU_SANDBOX_OPCODE_LEVEL_DEBUG
|
||||
# DEFINES += EMU_SANDBOX_LOG_APIS
|
||||
@@ -75,6 +75,7 @@ CONFIG(debug, debug|release){
|
||||
}
|
||||
}else{
|
||||
# release build, go fast
|
||||
CONFIG += emu_fast_cpu
|
||||
DEFINES += EMU_NO_SAFETY
|
||||
}
|
||||
|
||||
@@ -82,10 +83,15 @@ CONFIG += c++11
|
||||
|
||||
INCLUDEPATH += $$PWD/qt-common/include
|
||||
|
||||
# only use with ARMv4<->7, ARMv8 is its own architecture
|
||||
optimize_for_arm32{
|
||||
DEFINES += EMU_OPTIMIZE_FOR_ARM32
|
||||
SOURCES += ../../src/m68k/cyclone/CycloneNew.S
|
||||
emu_fast_cpu{
|
||||
DEFINES += EMU_FAST_CPU
|
||||
optimize_for_arm32{
|
||||
# only use with ARMv4<->7, ARMv8 is its own architecture
|
||||
DEFINES += EMU_OPTIMIZE_FOR_ARM32
|
||||
SOURCES += ../../src/m68k/cyclone/CycloneNew.S
|
||||
}else{
|
||||
SOURCES += ../../src/m68k/fame/famec.c
|
||||
}
|
||||
}else{
|
||||
SOURCES += ../../src/m68k/musashi/m68kcpu.c \
|
||||
../../src/m68k/musashi/m68kdasm.c \
|
||||
@@ -147,7 +153,9 @@ HEADERS += \
|
||||
../../src/specs/sed1376RegisterSpec.h \
|
||||
../../src/specs/pdiUsbD12CommandSpec.h \
|
||||
../../src/specs/emuFeatureRegisterSpec.h \
|
||||
../../src/specs/sdCardCommandSpec.h
|
||||
../../src/specs/sdCardCommandSpec.h \
|
||||
../../src/m68k/fame/fame.h \
|
||||
../../src/m68k/fame/famec_opcodes.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui \
|
||||
|
||||
@@ -17,7 +17,8 @@ extern "C" {
|
||||
|
||||
//DEFINE INFO!!!
|
||||
//define EMU_MULTITHREADED to speed up long loops
|
||||
//define EMU_OPTIMIZE_FOR_ARM32 to use ASM CPU core
|
||||
//define EMU_FAST_CPU to use fast CPU cores
|
||||
//define EMU_OPTIMIZE_FOR_ARM32 to use ASM CPU core, EMU_FAST_CPU must be on too
|
||||
//define EMU_NO_SAFETY to remove all safety checks
|
||||
//define EMU_BIG_ENDIAN on big endian systems
|
||||
//to enable degguging define EMU_DEBUG, all options below do nothing unless EMU_DEBUG is defined
|
||||
|
||||
117
src/flx68000.c
117
src/flx68000.c
@@ -1,19 +1,24 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "emulator.h"
|
||||
#include "portability.h"
|
||||
#include "hardwareRegisters.h"
|
||||
#include "memoryAccess.h"
|
||||
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
#include <stdlib.h>//for exit(1)
|
||||
#include "m68k/cyclone/Cyclone.h"
|
||||
#else
|
||||
#include "m68k/fame/fame.h"
|
||||
#endif
|
||||
#else
|
||||
#include "m68k/musashi/m68kcpu.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
static struct Cyclone cycloneCpu;
|
||||
|
||||
@@ -25,7 +30,7 @@ extern void m68k_write_memory_8(unsigned int address, unsigned char value);
|
||||
extern void m68k_write_memory_16(unsigned int address, unsigned short value);
|
||||
extern void m68k_write_memory_32(unsigned int address, unsigned int value);
|
||||
|
||||
unsigned int checkPc(unsigned int pc){
|
||||
unsigned int flx68000CheckPc(unsigned int pc){
|
||||
unsigned int dataBufferHost;
|
||||
unsigned int dataBufferGuest;
|
||||
unsigned int windowSize;
|
||||
@@ -51,12 +56,31 @@ unsigned int checkPc(unsigned int pc){
|
||||
|
||||
return cycloneCpu.membase + pc;//new program counter
|
||||
}
|
||||
#else
|
||||
static M68K_CONTEXT fameCpu;
|
||||
|
||||
|
||||
extern unsigned int m68k_read_memory_8(unsigned int address);
|
||||
extern unsigned int m68k_read_memory_16(unsigned int address);
|
||||
extern unsigned int m68k_read_memory_32(unsigned int address);
|
||||
extern void m68k_write_memory_8(unsigned int address, unsigned char value);
|
||||
extern void m68k_write_memory_16(unsigned int address, unsigned short value);
|
||||
extern void m68k_write_memory_32(unsigned int address, unsigned int value);
|
||||
|
||||
void flx68000InterruptAcknowledge(unsigned level){
|
||||
int vector = interruptAcknowledge(level);
|
||||
|
||||
fameCpu.interrupts[0] = level;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void flx68000Init(void){
|
||||
static bool inited = false;
|
||||
|
||||
if(!inited){
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
CycloneInit();
|
||||
cycloneCpu.read8 = m68k_read_memory_8;
|
||||
@@ -68,9 +92,20 @@ void flx68000Init(void){
|
||||
cycloneCpu.write8 = m68k_write_memory_8;
|
||||
cycloneCpu.write16 = m68k_write_memory_16;
|
||||
cycloneCpu.write32 = m68k_write_memory_32;
|
||||
cycloneCpu.checkpc = checkPc;
|
||||
cycloneCpu.checkpc = flx68000CheckPc;
|
||||
cycloneCpu.IrqCallback = interruptAcknowledge;
|
||||
cycloneCpu.ResetCallback = emulatorSoftReset;
|
||||
#else
|
||||
fm68k_init();
|
||||
fameCpu.read_byte = m68k_read_memory_8;
|
||||
fameCpu.read_word = m68k_read_memory_16;
|
||||
fameCpu.read_long = m68k_read_memory_32;
|
||||
fameCpu.write_byte = m68k_write_memory_8;
|
||||
fameCpu.write_word = m68k_write_memory_16;
|
||||
fameCpu.write_long = m68k_write_memory_32;
|
||||
fameCpu.iack_handler = flx68000InterruptAcknowledge;
|
||||
fameCpu.reset_handler = emulatorSoftReset;
|
||||
#endif
|
||||
#else
|
||||
m68k_init();
|
||||
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
|
||||
@@ -87,8 +122,12 @@ void flx68000Init(void){
|
||||
void flx68000Reset(void){
|
||||
resetHwRegisters();
|
||||
resetAddressSpace();//address space must be reset after hardware registers because it is dependent on them
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
CycloneReset(&cycloneCpu);
|
||||
#else
|
||||
fm68k_reset(&fameCpu);
|
||||
#endif
|
||||
#else
|
||||
m68k_pulse_reset();
|
||||
#endif
|
||||
@@ -97,8 +136,12 @@ void flx68000Reset(void){
|
||||
uint64_t flx68000StateSize(void){
|
||||
uint64_t size = 0;
|
||||
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
size += 0x80;//specified in Cyclone.h, line 82
|
||||
#else
|
||||
size += sizeof(fameCpu);
|
||||
#endif
|
||||
#else
|
||||
size += sizeof(uint32_t) * 50;//m68ki_cpu
|
||||
#endif
|
||||
@@ -108,9 +151,14 @@ uint64_t flx68000StateSize(void){
|
||||
|
||||
void flx68000SaveState(uint8_t* data){
|
||||
uint64_t offset = 0;
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
CyclonePack(&cycloneCpu, data + offset);
|
||||
offset += 0x80;//specified in Cyclone.h, line 82
|
||||
#else
|
||||
memcpy(data + offset, &fameCpu, sizeof(fameCpu));
|
||||
offset += sizeof(fameCpu);
|
||||
#endif
|
||||
#else
|
||||
uint8_t index;
|
||||
|
||||
@@ -182,9 +230,14 @@ void flx68000SaveState(uint8_t* data){
|
||||
void flx68000LoadState(uint8_t* data){
|
||||
uint64_t offset = 0;
|
||||
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
CycloneUnpack(&cycloneCpu, data + offset);
|
||||
offset += 0x80;//specified in Cyclone.h, line 82
|
||||
#else
|
||||
memcpy(&fameCpu, data + offset, sizeof(fameCpu));
|
||||
offset += sizeof(fameCpu);
|
||||
#endif
|
||||
#else
|
||||
uint8_t index;
|
||||
|
||||
@@ -263,9 +316,13 @@ void flx68000Execute(void){
|
||||
int32_t cpuCycles = sysclks * pctlrCpuClockDivider * palmClockMultiplier;
|
||||
|
||||
if(cpuCycles > 0){
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
cycloneCpu.cycles = cpuCycles;
|
||||
CycloneRun(&cycloneCpu);
|
||||
#else
|
||||
fm68k_emulate(&fameCpu, cpuCycles, fm68k_reason_emulate);
|
||||
#endif
|
||||
#else
|
||||
m68k_execute(cpuCycles);
|
||||
#endif
|
||||
@@ -279,32 +336,46 @@ void flx68000Execute(void){
|
||||
}
|
||||
|
||||
void flx68000SetIrq(uint8_t irqLevel){
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
cycloneCpu.irq = irqLevel;
|
||||
CycloneFlushIrq(&cycloneCpu);
|
||||
#else
|
||||
//fameCpu.interrupts[0] = irqLevel;
|
||||
//fm68k_would_interrupt(&fameCpu);
|
||||
#endif
|
||||
#else
|
||||
m68k_set_irq(irqLevel);
|
||||
#endif
|
||||
}
|
||||
|
||||
void flx68000RefreshAddressing(void){
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
//cycloneCpu.pc = cycloneCpu.checkpc(cycloneCpu.pc);
|
||||
#else
|
||||
//C implementation doesnt cache address information
|
||||
#if defined(EMU_FAST_CPU) && !defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
uint32_t bank;
|
||||
|
||||
MULTITHREAD_LOOP(bank) for(bank = 0; bank < TOTAL_MEMORY_BANKS; bank++){
|
||||
if(bankType[bank] == CHIP_A0_ROM)
|
||||
fameCpu.Fetch[bank] = &palmRom + BANK_ADDRESS(bank) - chips[CHIP_A0_ROM].start;
|
||||
else if(bankType[bank] == CHIP_DX_RAM)
|
||||
fameCpu.Fetch[bank] = &palmRam + BANK_ADDRESS(bank) - chips[CHIP_DX_RAM].start;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool flx68000IsSupervisor(void){
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
return CycloneGetSr(&cycloneCpu) & 0x2000;
|
||||
return !!(CycloneGetSr(&cycloneCpu) & 0x2000);
|
||||
#else
|
||||
return !!(fameCpu.sr & 0x2000);
|
||||
#endif
|
||||
#else
|
||||
return !!(m68k_get_reg(NULL, M68K_REG_SR) & 0x2000);
|
||||
#endif
|
||||
}
|
||||
|
||||
void flx68000BusError(uint32_t address, bool isWrite){
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
#if defined(EMU_FAST_CPU) || defined(EMU_NO_SAFETY)
|
||||
//no bus error callback
|
||||
#else
|
||||
//never call outsize of a 68k opcode, behavior is undefined due to longjmp
|
||||
@@ -334,7 +405,7 @@ uint32_t flx68000GetRegister(uint8_t reg){
|
||||
M68K_REG_PC,
|
||||
M68K_REG_SR
|
||||
*/
|
||||
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
if(reg < 8)
|
||||
return cycloneCpu.d[reg];
|
||||
@@ -346,22 +417,38 @@ uint32_t flx68000GetRegister(uint8_t reg){
|
||||
return CycloneGetSr(&cycloneCpu);
|
||||
|
||||
return 0x00000000;
|
||||
#else
|
||||
if(reg < 8)
|
||||
return fameCpu.dreg[reg].D;
|
||||
else if(reg < 16)
|
||||
return fameCpu.areg[reg - 8].D;
|
||||
else if(reg == 16)
|
||||
return fm68k_get_pc(&fameCpu);
|
||||
else if(reg == 17)
|
||||
return fameCpu.sr;
|
||||
|
||||
return 0x00000000;
|
||||
#endif
|
||||
#else
|
||||
return m68k_get_reg(NULL, reg);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t flx68000GetPc(void){
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
return cycloneCpu.prev_pc;
|
||||
return cycloneCpu.pc;
|
||||
#else
|
||||
return m68k_get_reg(NULL, M68K_REG_PPC);
|
||||
return fm68k_get_pc(&fameCpu);
|
||||
#endif
|
||||
#else
|
||||
return m68k_get_reg(NULL, M68K_REG_PC);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t flx68000ReadArbitraryMemory(uint32_t address, uint8_t size){
|
||||
uint64_t data = UINT64_MAX;//invalid access
|
||||
|
||||
#if defined(EMU_FAST_CPU)
|
||||
#if defined(EMU_OPTIMIZE_FOR_ARM32)
|
||||
//reading from a hardware register FIFO will corrupt it!
|
||||
if(bankType[START_BANK(address)] != CHIP_NONE){
|
||||
@@ -382,6 +469,10 @@ uint64_t flx68000ReadArbitraryMemory(uint32_t address, uint8_t size){
|
||||
}
|
||||
CycloneSetSr(&cycloneCpu, m68kSr);
|
||||
}
|
||||
#else
|
||||
//FAME here
|
||||
|
||||
#endif
|
||||
#else
|
||||
//reading from a hardware register FIFO will corrupt it!
|
||||
if(bankType[START_BANK(address)] != CHIP_NONE){
|
||||
|
||||
180
src/m68k/fame/fame.h
Normal file
180
src/m68k/fame/fame.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/*****************************************************************************/
|
||||
/* FAME Fast and Accurate Motorola 68000 Emulation Core */
|
||||
/* (c) 2005 Oscar Orallo Pelaez */
|
||||
/* Version: 1.24 */
|
||||
/* Date: 08-20-2005 */
|
||||
/* See FAME.HTML for documentation and license information */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __FAME_H__
|
||||
#define __FAME_H__
|
||||
|
||||
// uintptr_t
|
||||
#include <stdlib.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// PicoDrive hacks
|
||||
#define FAMEC_FETCHBITS (32 - 14)//BANK_SCOOT, was 8 for picodrive
|
||||
#define M68K_FETCHBANK1 (1 << FAMEC_FETCHBITS)
|
||||
|
||||
//#define M68K_RUNNING 0x01
|
||||
#define FM68K_HALTED 0x80
|
||||
//#define M68K_WAITING 0x04
|
||||
//#define M68K_DISABLE 0x20
|
||||
//#define M68K_FAULTED 0x40
|
||||
#define FM68K_EMULATE_GROUP_0 0x02
|
||||
#define FM68K_EMULATE_TRACE 0x08
|
||||
#define FM68K_DO_TRACE 0x10
|
||||
|
||||
|
||||
/************************************/
|
||||
/* General library defines */
|
||||
/************************************/
|
||||
|
||||
#ifndef M68K_OK
|
||||
#define M68K_OK 0
|
||||
#endif
|
||||
#ifndef M68K_RUNNING
|
||||
#define M68K_RUNNING 1
|
||||
#endif
|
||||
#ifndef M68K_NO_SUP_ADDR_SPACE
|
||||
#define M68K_NO_SUP_ADDR_SPACE 2
|
||||
#endif
|
||||
#ifndef M68K_DOUBLE_BUS_FAULT
|
||||
#define M68K_DOUBLE_BUS_FAULT -1
|
||||
#endif
|
||||
#ifndef M68K_INV_REG
|
||||
#define M68K_INV_REG -1
|
||||
#endif
|
||||
|
||||
/* Hardware interrupt state */
|
||||
|
||||
#ifndef M68K_IRQ_LEVEL_ERROR
|
||||
#define M68K_IRQ_LEVEL_ERROR -1
|
||||
#endif
|
||||
#ifndef M68K_IRQ_INV_PARAMS
|
||||
#define M68K_IRQ_INV_PARAMS -2
|
||||
#endif
|
||||
|
||||
/* Defines to specify hardware interrupt type */
|
||||
|
||||
#ifndef M68K_AUTOVECTORED_IRQ
|
||||
#define M68K_AUTOVECTORED_IRQ -1
|
||||
#endif
|
||||
#ifndef M68K_SPURIOUS_IRQ
|
||||
#define M68K_SPURIOUS_IRQ -2
|
||||
#endif
|
||||
|
||||
#ifndef M68K_AUTO_LOWER_IRQ
|
||||
#define M68K_AUTO_LOWER_IRQ 1
|
||||
#endif
|
||||
#ifndef M68K_MANUAL_LOWER_IRQ
|
||||
#define M68K_MANUAL_LOWER_IRQ 0
|
||||
#endif
|
||||
|
||||
/* Defines to specify address space */
|
||||
|
||||
#ifndef M68K_SUP_ADDR_SPACE
|
||||
#define M68K_SUP_ADDR_SPACE 0
|
||||
#endif
|
||||
#ifndef M68K_USER_ADDR_SPACE
|
||||
#define M68K_USER_ADDR_SPACE 2
|
||||
#endif
|
||||
#ifndef M68K_PROG_ADDR_SPACE
|
||||
#define M68K_PROG_ADDR_SPACE 0
|
||||
#endif
|
||||
#ifndef M68K_DATA_ADDR_SPACE
|
||||
#define M68K_DATA_ADDR_SPACE 1
|
||||
#endif
|
||||
|
||||
|
||||
/*******************/
|
||||
/* Data definition */
|
||||
/*******************/
|
||||
|
||||
typedef union
|
||||
{
|
||||
unsigned char B;
|
||||
signed char SB;
|
||||
unsigned short W;
|
||||
signed short SW;
|
||||
unsigned int D;
|
||||
signed int SD;
|
||||
} famec_union32;
|
||||
|
||||
/* M68K CPU CONTEXT */
|
||||
typedef struct
|
||||
{
|
||||
unsigned int (*read_byte )(unsigned int a);
|
||||
unsigned int (*read_word )(unsigned int a);
|
||||
unsigned int (*read_long )(unsigned int a);
|
||||
void (*write_byte)(unsigned int a,unsigned char d);
|
||||
void (*write_word)(unsigned int a,unsigned short d);
|
||||
void (*write_long)(unsigned int a,unsigned int d);
|
||||
void (*reset_handler)(void);
|
||||
void (*iack_handler)(unsigned level);
|
||||
famec_union32 dreg[8];
|
||||
famec_union32 areg[8];
|
||||
unsigned asp;
|
||||
unsigned pc;
|
||||
unsigned char interrupts[8];
|
||||
unsigned short sr;
|
||||
unsigned short execinfo;
|
||||
// PD extension
|
||||
int io_cycle_counter; // cycles left
|
||||
|
||||
unsigned int Opcode;
|
||||
signed int cycles_needed;
|
||||
|
||||
unsigned short *PC;
|
||||
uintptr_t BasePC;
|
||||
unsigned int flag_C;
|
||||
unsigned int flag_V;
|
||||
unsigned int flag_NotZ;
|
||||
unsigned int flag_N;
|
||||
unsigned int flag_X;
|
||||
unsigned int flag_T;
|
||||
unsigned int flag_S;
|
||||
unsigned int flag_I;
|
||||
|
||||
unsigned char not_polling;
|
||||
unsigned char pad[3];
|
||||
|
||||
uintptr_t Fetch[M68K_FETCHBANK1];
|
||||
} M68K_CONTEXT;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
fm68k_reason_emulate = 0,
|
||||
fm68k_reason_init,
|
||||
fm68k_reason_idle_install,
|
||||
fm68k_reason_idle_remove,
|
||||
} fm68k_call_reason;
|
||||
|
||||
/************************/
|
||||
/* Function definition */
|
||||
/************************/
|
||||
|
||||
/* General purpose functions */
|
||||
void fm68k_init(void);
|
||||
int fm68k_reset(M68K_CONTEXT *ctx);
|
||||
int fm68k_emulate(M68K_CONTEXT *ctx, int n, fm68k_call_reason reason);
|
||||
int fm68k_would_interrupt(M68K_CONTEXT *ctx); // to be called from fm68k_emulate()
|
||||
|
||||
unsigned int fm68k_get_pc(const M68K_CONTEXT *ctx);
|
||||
|
||||
// PICODRIVE_HACK
|
||||
int fm68k_idle_install(void);
|
||||
int fm68k_idle_remove(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
5077
src/m68k/fame/famec.c
Normal file
5077
src/m68k/fame/famec.c
Normal file
File diff suppressed because it is too large
Load Diff
40136
src/m68k/fame/famec_opcodes.h
Normal file
40136
src/m68k/fame/famec_opcodes.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -176,8 +176,8 @@ unsigned int m68k_read_disassembler_16 (unsigned int address);
|
||||
unsigned int m68k_read_disassembler_32 (unsigned int address);
|
||||
|
||||
/* Write to anywhere */
|
||||
void m68k_write_memory_8(unsigned int address, unsigned int value);
|
||||
void m68k_write_memory_16(unsigned int address, unsigned int value);
|
||||
void m68k_write_memory_8(unsigned int address, unsigned char value);
|
||||
void m68k_write_memory_16(unsigned int address, unsigned short value);
|
||||
void m68k_write_memory_32(unsigned int address, unsigned int value);
|
||||
|
||||
/* Special call to simulate undocumented 68k behavior when move.l with a
|
||||
|
||||
@@ -13,12 +13,17 @@ EMU_SOURCES_C := $(EMU_PATH)/emulator.c \
|
||||
$(EMU_PATH)/debug/sandbox.c
|
||||
|
||||
#only use with ARMv4<->7, ARMv8 is its own architecture
|
||||
ifeq ($(EMU_OPTIMIZE_FOR_ARM32), 1)
|
||||
EMU_DEFINES += -DEMU_OPTIMIZE_FOR_ARM32
|
||||
ifeq ($(EMU_NEW_ASM_SYNTAX), 1)
|
||||
EMU_SOURCES_ASM += $(EMU_PATH)/m68k/cyclone/CycloneNew.S
|
||||
ifeq ($(EMU_FAST_CPU), 1)
|
||||
EMU_DEFINES += -DEMU_FAST_CPU
|
||||
ifeq ($(EMU_OPTIMIZE_FOR_ARM32), 1)
|
||||
EMU_DEFINES += -DEMU_OPTIMIZE_FOR_ARM32
|
||||
ifeq ($(EMU_NEW_ASM_SYNTAX), 1)
|
||||
EMU_SOURCES_ASM += $(EMU_PATH)/m68k/cyclone/CycloneNew.S
|
||||
else
|
||||
EMU_SOURCES_ASM += $(EMU_PATH)/m68k/cyclone/CycloneOld.S
|
||||
endif
|
||||
else
|
||||
EMU_SOURCES_ASM += $(EMU_PATH)/m68k/cyclone/CycloneOld.S
|
||||
EMU_SOURCES_C += $(EMU_PATH)/m68k/fame/famec.c
|
||||
endif
|
||||
else
|
||||
EMU_SOURCES_C += $(EMU_PATH)/m68k/musashi/m68kops.c \
|
||||
|
||||
Reference in New Issue
Block a user