kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
319 wiersze
8.0 KiB
C++
319 wiersze
8.0 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <Arduino.h>
|
|
|
|
#include "dcastaway.h"
|
|
#include "mem.h"
|
|
#include "st.h"
|
|
|
|
#include "m68k_intrf.h"
|
|
#ifdef DEBUG_FAME
|
|
FILE *fame_debug_file=stdout;
|
|
unsigned fame_debug_count=0;
|
|
#ifdef DEBUG_FAME_START
|
|
int fame_debug_output=0;
|
|
#else
|
|
int fame_debug_output=1;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#ifdef DEBUG_FAME
|
|
#include "dis.h"
|
|
#endif
|
|
|
|
char GetMemB(unsigned long address);
|
|
short GetMemW(unsigned long address);
|
|
long GetMemL(unsigned long address);
|
|
void SetMemB(unsigned long address, unsigned char value);
|
|
void SetMemW(unsigned long address, unsigned short value);
|
|
void SetMemL(unsigned long address, unsigned long value);
|
|
|
|
|
|
#if defined(FAME_SINGLE_MEMORY) && defined(DEBUG_FAME)
|
|
|
|
static char MyGetMemB(unsigned long address)
|
|
{
|
|
char ret;
|
|
|
|
if (fame_debug_output)
|
|
{ fprintf(fame_debug_file,"GetMemB(0x%.6X)",address); DEBUG_FAME_FFLUSH; }
|
|
|
|
ret=GetMemB(address);
|
|
|
|
if (fame_debug_output)
|
|
{ fprintf(fame_debug_file," = 0x%.2X\n",ret); DEBUG_FAME_FFLUSH; }
|
|
|
|
return ret;
|
|
}
|
|
|
|
static short MyGetMemW(unsigned long address)
|
|
{
|
|
short ret;
|
|
|
|
if (fame_debug_output)
|
|
{ fprintf(fame_debug_file,"GetMemW(0x%.6X)",address); DEBUG_FAME_FFLUSH; }
|
|
|
|
ret=GetMemW(address);
|
|
|
|
if (fame_debug_output)
|
|
{ fprintf(fame_debug_file," = 0x%.4X\n",ret); DEBUG_FAME_FFLUSH; }
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void MySetMemB(unsigned long address, unsigned value)
|
|
{
|
|
value&=0xff;
|
|
if (fame_debug_output)
|
|
{ fprintf(fame_debug_file,"SetMemB(0x%.6X,0x%.2X)",address,value); DEBUG_FAME_FFLUSH; }
|
|
|
|
SetMemB(address,value);
|
|
|
|
if (fame_debug_output)
|
|
{ fputs(fame_debug_file,"."); DEBUG_FAME_FFLUSH; }
|
|
}
|
|
|
|
static void MySetMemW(unsigned long address, unsigned value)
|
|
{
|
|
value&=0xffff;
|
|
if (fame_debug_output)
|
|
{ fprintf(fame_debug_file,"SetMemW(0x%.6X,0x%.4X)",address,value); DEBUG_FAME_FFLUSH; }
|
|
|
|
SetMemW(address,value);
|
|
|
|
if (fame_debug_output)
|
|
{ fputs(".",fame_debug_file); DEBUG_FAME_FFLUSH; }
|
|
}
|
|
|
|
#else
|
|
|
|
#define MyGetMemW GetMemW
|
|
#define MyGetMemB GetMemB
|
|
#define MySetMemW SetMemW
|
|
#define MySetMemB SetMemB
|
|
|
|
#endif
|
|
|
|
#ifndef USE_FAME_CORE
|
|
int recalc_int=1; //0;
|
|
#endif
|
|
int in_fame_core=0;
|
|
int number_exg0_fame=0;
|
|
static unsigned addr_exg0_fame=0;
|
|
static unsigned pc_exg0_fame=0;
|
|
static unsigned sr_exg0_fame=0;
|
|
static int rw_exg0_fame=0;
|
|
static unsigned long exaddress=0x12345678;
|
|
|
|
void HWReset(void)
|
|
{
|
|
m68k_reset();
|
|
exaddress=0x12345678;
|
|
}
|
|
|
|
static int inexec=0;
|
|
|
|
void ExceptionGroup0_execute(void)
|
|
{
|
|
short context = 0;
|
|
|
|
#ifdef DEBUG_FAME
|
|
if (fame_debug_output)
|
|
{ fputs("ExceptionGroup0_execute",fame_debug_file); DEBUG_FAME_FFLUSH; }
|
|
#endif
|
|
|
|
M68KCONTEXT.execinfo&=0x7F;
|
|
|
|
if ((!((exaddress+1!=addr_exg0_fame)&&(exaddress+2!=addr_exg0_fame)&&(exaddress+3!=addr_exg0_fame))) || (!inexec))
|
|
{
|
|
if (!inexec)
|
|
m68k_reset();
|
|
return;
|
|
}
|
|
inexec=0;
|
|
|
|
context |= 0x8;
|
|
if (rw_exg0_fame)
|
|
context |= 0x10;
|
|
if (GetS())
|
|
context |= 0x4;
|
|
if (rw_exg0_fame && addr_exg0_fame == pc_exg0_fame)
|
|
context |= 0x2;
|
|
else
|
|
context |= 0x1;
|
|
|
|
M68KCONTEXT.sr |= (1<<13);
|
|
M68KCONTEXT.sr &= ~(1<<15);
|
|
|
|
M68KCONTEXT.areg[7]-=14;
|
|
SetMemW(M68KCONTEXT.areg[7], context);
|
|
SetMemL(M68KCONTEXT.areg[7] + 2, addr_exg0_fame);
|
|
SetMemW(M68KCONTEXT.areg[7] + 6, GetMemW(pc_exg0_fame));
|
|
SetMemW(M68KCONTEXT.areg[7] + 8, sr_exg0_fame);
|
|
SetMemL(M68KCONTEXT.areg[7] + 10, pc_exg0_fame);
|
|
|
|
M68KCONTEXT.pc=GetMemL((long)number_exg0_fame * 4);
|
|
|
|
exaddress=addr_exg0_fame;
|
|
number_exg0_fame=0;
|
|
}
|
|
|
|
void ExceptionGroup0(
|
|
int number, /* trap number */
|
|
unsigned long address, /* fault address */
|
|
int rw) /* read = true, write = false */
|
|
{
|
|
#ifdef DEBUG_FAME
|
|
if (fame_debug_output)
|
|
{ fprintf(fame_debug_file,"ExceptionGroup0(%i,0x%X,%i)\n",number,address,rw); DEBUG_FAME_FFLUSH; }
|
|
#endif
|
|
if ((exaddress+1!=address)&&(exaddress+2!=address)&&(exaddress+3!=address)&&(!inexec)){
|
|
inexec=1;
|
|
number_exg0_fame=number;
|
|
addr_exg0_fame=address;
|
|
rw_exg0_fame=rw;
|
|
pc_exg0_fame=M68KCONTEXT.pc;
|
|
sr_exg0_fame=M68KCONTEXT.sr;
|
|
if (!in_fame_core)
|
|
ExceptionGroup0_execute();
|
|
else
|
|
IO_CYCLE=0;
|
|
}
|
|
}
|
|
|
|
|
|
static M68K_CONTEXT context;
|
|
|
|
static M68K_PROGRAM program[]= {
|
|
{0, MEMSIZE-1, (unsigned)membase},
|
|
{MEMSIZE, (MEMSIZE*2)-1, ((unsigned)membase)-MEMSIZE},
|
|
{MEMSIZE*2, (MEMSIZE*3)-1, ((unsigned)membase)-(MEMSIZE*2)},
|
|
#if MEMSIZE*4 <= ROMBASE2
|
|
{MEMSIZE*3, (MEMSIZE*4)-1, ((unsigned)membase)-(MEMSIZE*3)},
|
|
#if MEMSIZE*5 <= ROMBASE2
|
|
{MEMSIZE*4, (MEMSIZE*5)-1, ((unsigned)membase)-(MEMSIZE*4)},
|
|
#if MEMSIZE*6 <= ROMBASE2
|
|
{MEMSIZE*5, (MEMSIZE*6)-1, ((unsigned)membase)-(MEMSIZE*5)},
|
|
#if MEMSIZE*7 <= ROMBASE2
|
|
{MEMSIZE*6, (MEMSIZE*7)-1, ((unsigned)membase)-(MEMSIZE*6)},
|
|
#if MEMSIZE*8 <= ROMBASE2
|
|
{MEMSIZE*7, (MEMSIZE*8)-1, ((unsigned)membase)-(MEMSIZE*7)},
|
|
#if MEMSIZE*9 <= ROMBASE2
|
|
{MEMSIZE*8, (MEMSIZE*9)-1, ((unsigned)membase)-(MEMSIZE*8)},
|
|
#if MEMSIZE*10 <= ROMBASE2
|
|
{MEMSIZE*9, (MEMSIZE*10)-1, ((unsigned)membase)-(MEMSIZE*9)},
|
|
#if MEMSIZE*11 <= ROMBASE2
|
|
{MEMSIZE*10, (MEMSIZE*11)-1, ((unsigned)membase)-(MEMSIZE*10)},
|
|
#if MEMSIZE*12 <= ROMBASE2
|
|
{MEMSIZE*11, (MEMSIZE*12)-1, ((unsigned)membase)-(MEMSIZE*11)},
|
|
#if MEMSIZE*13 <= ROMBASE2
|
|
{MEMSIZE*12, (MEMSIZE*13)-1, ((unsigned)membase)-(MEMSIZE*12)},
|
|
#if MEMSIZE*14 <= ROMBASE2
|
|
{MEMSIZE*13, (MEMSIZE*14)-1, ((unsigned)membase)-(MEMSIZE*13)},
|
|
#if MEMSIZE*15 <= ROMBASE2
|
|
{MEMSIZE*14, (MEMSIZE*15)-1, ((unsigned)membase)-(MEMSIZE*14)},
|
|
#if MEMSIZE*16 <= ROMBASE2
|
|
{MEMSIZE*15, (MEMSIZE*16)-1, ((unsigned)membase)-(MEMSIZE*15)},
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
{ROMBASE2, (IOBASE-1), (unsigned)rombase},
|
|
{IOBASE, 0x00FFFFFF, (unsigned)rombase},
|
|
{(unsigned)-1,(unsigned)-1,(unsigned)NULL}
|
|
};
|
|
|
|
#ifndef FAME_SINGLE_MEMORY
|
|
static M68K_DATA read8[] = {
|
|
{0, MEMSIZE-1, NULL, (void *)membase},
|
|
{MEMSIZE, (ROMBASE2)-1, (void *)GetMemB, NULL},
|
|
{ROMBASE2, IOBASE-1, NULL, (void *)rombase},
|
|
{IOBASE, 0x00FFFFFF, (void *)DoIORB, NULL},
|
|
{(unsigned)-1,(unsigned)-1,NULL,NULL}
|
|
};
|
|
|
|
static M68K_DATA read16[] = {
|
|
{0, MEMSIZE-1, NULL, (void *)membase},
|
|
{MEMSIZE, (ROMBASE2)-1, (void *)GetMemW, NULL},
|
|
{ROMBASE2, IOBASE-1, NULL, (void *)rombase},
|
|
{IOBASE, 0x00FFFFFF, (void *)DoIORW, NULL},
|
|
{(unsigned)-1,(unsigned)-1,NULL,NULL}
|
|
};
|
|
|
|
static M68K_DATA write8[] = {
|
|
{0, MEMSIZE-1, NULL, (void *)membase},
|
|
{MEMSIZE, (IOBASE)-1, (void *)SetMemB, NULL},
|
|
{IOBASE, 0x00FFFFFF, (void *)DoIOWB, NULL},
|
|
{(unsigned)-1,(unsigned)-1,NULL,NULL}
|
|
};
|
|
|
|
static M68K_DATA write16[] = {
|
|
{0, MEMSIZE-1, NULL, (void *)membase},
|
|
{MEMSIZE, (IOBASE)-1, (void *)SetMemW, NULL},
|
|
{IOBASE, 0x00FFFFFF, (void *)DoIOWW, NULL},
|
|
{(unsigned)-1,(unsigned)-1,NULL,NULL}
|
|
};
|
|
|
|
#else
|
|
|
|
static M68K_DATA read8[] = {
|
|
{ 0, 0xFFFFFF, (void *)MyGetMemB, NULL },
|
|
{(unsigned)-1,(unsigned)-1,NULL,NULL}
|
|
};
|
|
|
|
static M68K_DATA read16[] = {
|
|
{ 0, 0xFFFFFF, (void *)MyGetMemW, NULL },
|
|
{(unsigned)-1,(unsigned)-1,NULL,NULL}
|
|
};
|
|
|
|
static M68K_DATA write8[] = {
|
|
{ 0, 0xFFFFFF, (void *)MySetMemB, NULL },
|
|
{(unsigned)-1,(unsigned)-1,NULL,NULL}
|
|
};
|
|
|
|
static M68K_DATA write16[] = {
|
|
{ 0, 0xFFFFFF, (void *)MySetMemW, NULL },
|
|
{(unsigned)-1,(unsigned)-1,NULL,NULL}
|
|
};
|
|
|
|
#endif
|
|
|
|
void initialize_memmap(void)
|
|
{
|
|
int i;
|
|
memset(&context,0,sizeof(M68K_CONTEXT));
|
|
context.fetch=context.sv_fetch=context.user_fetch=(M68K_PROGRAM*)&program;
|
|
context.read_byte=context.sv_read_byte=context.user_read_byte=(M68K_DATA*)&read8;
|
|
context.read_word=context.sv_read_word=context.user_read_word=(M68K_DATA*)&read16;
|
|
context.write_byte=context.sv_write_byte=context.user_write_byte=(M68K_DATA*)&write8;
|
|
context.write_word=context.sv_write_word=context.user_write_word=(M68K_DATA*)&write16;
|
|
for(i=0;program[i].low_addr != ((unsigned)-1);i++)
|
|
{
|
|
if (program[i].low_addr >= ROMBASE2)
|
|
program[i].offset= (((unsigned)rombase)+ROMBASE2)-program[i].low_addr;
|
|
else
|
|
program[i].offset= ((unsigned)membase) - (i*MEMSIZE);
|
|
}
|
|
|
|
#ifndef FAME_SINGLE_MEMORY
|
|
read8[0].data=read16[0].data=write8[0].data=write16[0].data=(void *)((unsigned)membase);
|
|
read8[2].data=read16[2].data=(void *)((unsigned)rombase);
|
|
#endif
|
|
|
|
m68k_init();
|
|
m68k_set_context(&context);
|
|
m68k_reset();
|
|
}
|