32x: split sh2 code, compiler stub

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@810 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2009-10-08 19:47:31 +00:00
parent 1d29444dfc
commit 4139770121
16 changed files with 227 additions and 205 deletions

36
cpu/drc/cmn.c Normal file
View file

@ -0,0 +1,36 @@
#include <stdio.h>
#if defined(__linux__) && defined(ARM)
#include <sys/mman.h>
#endif
#include "cmn.h"
#ifndef ARM
unsigned int tcache[SSP_TCACHE_SIZE/4];
unsigned int *ssp_block_table[0x5090/2];
unsigned int *ssp_block_table_iram[15][0x800/2];
char ssp_align[SSP_BLOCKTAB_ALIGN_SIZE];
#endif
void drc_cmn_init(void)
{
#if defined(__linux__) && defined(ARM)
void *tmp;
tmp = mmap(tcache, SSP_DRC_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
printf("mmap tcache: %p, asked %p\n", tmp, tcache);
#endif
}
// TODO: add calls in core, possibly to cart.c?
void drc_cmn_cleanup(void)
{
#if defined(__linux__) && defined(ARM)
int ret;
ret = munmap(tcache, SSP_DRC_SIZE);
printf("munmap tcache: %i\n", ret);
#endif
}

13
cpu/drc/cmn.h Normal file
View file

@ -0,0 +1,13 @@
#define SSP_TCACHE_SIZE (512*1024)
#define SSP_BLOCKTAB_SIZE (0x5090/2*4)
#define SSP_BLOCKTAB_IRAM_SIZE (15*0x800/2*4)
#define SSP_BLOCKTAB_ALIGN_SIZE 3808
#define SSP_DRC_SIZE (SSP_TCACHE_SIZE + SSP_BLOCKTAB_SIZE + SSP_BLOCKTAB_IRAM_SIZE + SSP_BLOCKTAB_ALIGN_SIZE)
extern unsigned int tcache[SSP_TCACHE_SIZE/4];
extern unsigned int *ssp_block_table[SSP_BLOCKTAB_SIZE/4];
extern unsigned int *ssp_block_table_iram[15][0x800/2];
void drc_cmn_init(void);
void drc_cmn_cleanup(void);

25
cpu/drc/cmn_arm.S Normal file
View file

@ -0,0 +1,25 @@
@ vim:filetype=armasm
.if 0
#include "cmn.h"
.endif
.global tcache
.global ssp_block_table
.global ssp_block_table_iram
@ translation cache buffer + pointer table
.data
.align 12 @ 4096
@.size tcache, SSP_TCACHE_SIZE
@.size ssp_block_table, SSP_BLOCKTAB_SIZE
@.size ssp_block_table_iram, SSP_BLOCKTAB_IRAM_SIZE
tcache:
.space SSP_TCACHE_SIZE
ssp_block_table:
.space SSP_BLOCKTAB_SIZE
ssp_block_table_iram:
.space SSP_BLOCKTAB_IRAM_SIZE
.space SSP_BLOCKTAB_ALIGN_SIZE

10
cpu/sh2/compiler.c Normal file
View file

@ -0,0 +1,10 @@
#include "../sh2.h"
void sh2_execute(SH2 *sh2, int cycles)
{
unsigned int pc = sh2->pc;
int op;
op = p32x_sh2_read16(pc);
}

View file

@ -100,7 +100,7 @@
*****************************************************************************/
//#include "debugger.h"
#include "sh2.h"
//#include "sh2.h"
//#include "sh2comn.h"
#define INLINE static
@ -115,7 +115,7 @@
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
int sh2_icount;
//int sh2_icount;
SH2 *sh2;
#if 0

View file

@ -1,4 +1,4 @@
#include <string.h>
#include "../sh2.h"
// MAME types
typedef signed char INT8;
@ -8,14 +8,6 @@ typedef unsigned int UINT32;
typedef unsigned short UINT16;
typedef unsigned char UINT8;
// pico memhandlers
unsigned int p32x_sh2_read8(unsigned int a, int id);
unsigned int p32x_sh2_read16(unsigned int a, int id);
unsigned int p32x_sh2_read32(unsigned int a, int id);
void p32x_sh2_write8(unsigned int a, unsigned int d, int id);
void p32x_sh2_write16(unsigned int a, unsigned int d, int id);
void p32x_sh2_write32(unsigned int a, unsigned int d, int id);
#define RB(a) p32x_sh2_read8(a,sh2->is_slave)
#define RW(a) p32x_sh2_read16(a,sh2->is_slave)
#define RL(a) p32x_sh2_read32(a,sh2->is_slave)
@ -37,42 +29,18 @@ void p32x_sh2_write32(unsigned int a, unsigned int d, int id);
#define Rn ((opcode>>8)&15)
#define Rm ((opcode>>4)&15)
#define sh2_icount sh2->icount
#include "sh2.c"
void sh2_reset(SH2 *sh2)
{
sh2->pc = RL(0);
sh2->r[15] = RL(4);
sh2->sr = I;
sh2->vbr = 0;
sh2->pending_int_irq = 0;
}
static void sh2_do_irq(SH2 *sh2, int level, int vector)
{
sh2->irq_callback(sh2->is_slave, level);
sh2->r[15] -= 4;
WL(sh2->r[15], sh2->sr); /* push SR onto stack */
sh2->r[15] -= 4;
WL(sh2->r[15], sh2->pc); /* push PC onto stack */
/* set I flags in SR */
sh2->sr = (sh2->sr & ~I) | (level << 4);
/* fetch PC */
sh2->pc = RL(sh2->vbr + vector * 4);
/* 13 cycles at best */
sh2_icount -= 13;
}
/* Execute cycles - returns number of cycles actually run */
int sh2_execute(SH2 *sh2_, int cycles)
void sh2_execute(SH2 *sh2_, int cycles)
{
sh2 = sh2_;
sh2_icount = cycles;
sh2->cycles_aim += cycles;
sh2->icount = cycles = sh2->cycles_aim - sh2->cycles_done;
if (sh2->icount <= 0)
return;
do
{
@ -121,36 +89,10 @@ int sh2_execute(SH2 *sh2_, int cycles)
sh2_internal_irq(sh2, sh2->pending_int_irq, sh2->pending_int_vector);
sh2->test_irq = 0;
}
sh2_icount--;
sh2->icount--;
}
while (sh2_icount > 0 || sh2->delay); /* can't interrupt before delay */
while (sh2->icount > 0 || sh2->delay); /* can't interrupt before delay */
return cycles - sh2_icount;
}
void sh2_init(SH2 *sh2, int is_slave)
{
memset(sh2, 0, sizeof(*sh2));
sh2->is_slave = is_slave;
}
void sh2_irl_irq(SH2 *sh2, int level)
{
sh2->pending_irl = level;
if (level <= ((sh2->sr >> 4) & 0x0f))
return;
sh2_do_irq(sh2, level, 64 + level/2);
}
void sh2_internal_irq(SH2 *sh2, int level, int vector)
{
sh2->pending_int_irq = level;
sh2->pending_int_vector = vector;
if (level <= ((sh2->sr >> 4) & 0x0f))
return;
sh2_do_irq(sh2, level, vector);
sh2->pending_int_irq = 0; // auto-clear
sh2->cycles_done += cycles - sh2->icount;
}

60
cpu/sh2/sh2.c Normal file
View file

@ -0,0 +1,60 @@
#include <string.h>
#include "sh2.h"
#define I 0xf0
void sh2_init(SH2 *sh2, int is_slave)
{
memset(sh2, 0, sizeof(*sh2));
sh2->is_slave = is_slave;
}
void sh2_reset(SH2 *sh2)
{
sh2->pc = p32x_sh2_read32(0, sh2->is_slave);
sh2->r[15] = p32x_sh2_read32(4, sh2->is_slave);
sh2->sr = I;
sh2->vbr = 0;
sh2->pending_int_irq = 0;
}
static void sh2_do_irq(SH2 *sh2, int level, int vector)
{
sh2->irq_callback(sh2->is_slave, level);
sh2->r[15] -= 4;
p32x_sh2_write32(sh2->r[15], sh2->sr, sh2->is_slave); /* push SR onto stack */
sh2->r[15] -= 4;
p32x_sh2_write32(sh2->r[15], sh2->pc, sh2->is_slave); /* push PC onto stack */
/* set I flags in SR */
sh2->sr = (sh2->sr & ~I) | (level << 4);
/* fetch PC */
sh2->pc = p32x_sh2_read32(sh2->vbr + vector * 4, sh2->is_slave);
/* 13 cycles at best */
sh2->cycles_done += 13;
// sh2->icount -= 13;
}
void sh2_irl_irq(SH2 *sh2, int level)
{
sh2->pending_irl = level;
if (level <= ((sh2->sr >> 4) & 0x0f))
return;
sh2_do_irq(sh2, level, 64 + level/2);
}
void sh2_internal_irq(SH2 *sh2, int level, int vector)
{
sh2->pending_int_irq = level;
sh2->pending_int_vector = vector;
if (level <= ((sh2->sr >> 4) & 0x0f))
return;
sh2_do_irq(sh2, level, vector);
sh2->pending_int_irq = 0; // auto-clear
}

48
cpu/sh2/sh2.h Normal file
View file

@ -0,0 +1,48 @@
#ifndef __SH2_H__
#define __SH2_H__
// pico memhandlers
// XXX: move somewhere else
unsigned int p32x_sh2_read8(unsigned int a, int id);
unsigned int p32x_sh2_read16(unsigned int a, int id);
unsigned int p32x_sh2_read32(unsigned int a, int id);
void p32x_sh2_write8(unsigned int a, unsigned int d, int id);
void p32x_sh2_write16(unsigned int a, unsigned int d, int id);
void p32x_sh2_write32(unsigned int a, unsigned int d, int id);
typedef struct
{
unsigned int r[16];
unsigned int ppc;
unsigned int pc;
unsigned int pr;
unsigned int sr;
unsigned int gbr, vbr;
unsigned int mach, macl;
unsigned int ea;
unsigned int delay;
unsigned int test_irq;
int pending_irl;
int pending_int_irq; // internal irq
int pending_int_vector;
void (*irq_callback)(int id, int level);
int is_slave;
int icount; // cycles left in current timeslice
unsigned int cycles_aim; // subtract sh2_icount to get global counter
unsigned int cycles_done;
} SH2;
extern SH2 *sh2; // active sh2
void sh2_init(SH2 *sh2, int is_slave);
void sh2_reset(SH2 *sh2);
void sh2_irl_irq(SH2 *sh2, int level);
void sh2_internal_irq(SH2 *sh2, int level, int vector);
void sh2_execute(SH2 *sh2, int cycles);
#endif /* __SH2_H__ */

View file

@ -1,65 +0,0 @@
/*****************************************************************************
*
* sh2.h
* Portable Hitachi SH-2 (SH7600 family) emulator interface
*
* Copyright Juergen Buchmueller <pullmoll@t-online.de>,
* all rights reserved.
*
* - This source code is released as freeware for non-commercial purposes.
* - You are free to use and redistribute this code in modified or
* unmodified form, provided you list me in the credits.
* - If you modify this source code, you must add a notice to each modified
* source file that it has been changed. If you're a nice person, you
* will clearly mark each change too. :)
* - If you wish to use this for commercial purposes, please contact me at
* pullmoll@t-online.de
* - The author of this copywritten work reserves the right to change the
* terms of its usage and license at any time, including retroactively
* - This entire notice must remain in the source code.
*
* This work is based on <tiraniddo@hotmail.com> C/C++ implementation of
* the SH-2 CPU core and was heavily changed to the MAME CPU requirements.
* Thanks also go to Chuck Mason <chukjr@sundail.net> and Olivier Galibert
* <galibert@pobox.com> for letting me peek into their SEMU code :-)
*
*****************************************************************************/
#pragma once
#ifndef __SH2_H__
#define __SH2_H__
typedef struct
{
unsigned int r[16];
unsigned int ppc;
unsigned int pc;
unsigned int pr;
unsigned int sr;
unsigned int gbr, vbr;
unsigned int mach, macl;
unsigned int ea;
unsigned int delay;
unsigned int test_irq;
int pending_irl;
int pending_int_irq; // internal irq
int pending_int_vector;
void (*irq_callback)(int id, int level);
int is_slave;
unsigned int cycles_aim; // subtract sh2_icount to get global counter
} SH2;
SH2 *sh2; // active sh2
extern int sh2_icount;
void sh2_init(SH2 *sh2, int is_slave);
void sh2_reset(SH2 *sh2);
int sh2_execute(SH2 *sh2_, int cycles);
void sh2_irl_irq(SH2 *sh2, int level);
void sh2_internal_irq(SH2 *sh2, int level, int vector);
#endif /* __SH2_H__ */