mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-10-26 16:29:37 -04:00
svp compiler direct calls
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@360 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
259ed0ea66
commit
e807ac752b
13 changed files with 238 additions and 126 deletions
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
static char *rom_exts[] = { "bin", "gen", "smd", "iso" };
|
static char *rom_exts[] = { "bin", "gen", "smd", "iso" };
|
||||||
|
|
||||||
|
void (*PicoCartUnloadHook)(void) = NULL;
|
||||||
|
|
||||||
void (*PicoCartLoadProgressCB)(int percent) = NULL;
|
void (*PicoCartLoadProgressCB)(int percent) = NULL;
|
||||||
void (*PicoCDLoadProgressCB)(int percent) = NULL; // handled in Pico/cd/cd_file.c
|
void (*PicoCDLoadProgressCB)(int percent) = NULL; // handled in Pico/cd/cd_file.c
|
||||||
|
|
||||||
|
|
@ -493,6 +495,11 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
|
||||||
Pico.rom=rom;
|
Pico.rom=rom;
|
||||||
Pico.romsize=romsize;
|
Pico.romsize=romsize;
|
||||||
|
|
||||||
|
if (PicoCartUnloadHook != NULL) {
|
||||||
|
PicoCartUnloadHook();
|
||||||
|
PicoCartUnloadHook = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
PicoMemResetHooks();
|
PicoMemResetHooks();
|
||||||
PicoDmaHook = NULL;
|
PicoDmaHook = NULL;
|
||||||
PicoResetHook = NULL;
|
PicoResetHook = NULL;
|
||||||
|
|
@ -646,7 +653,7 @@ void PicoCartDetect(void)
|
||||||
if (name_cmp("Virtua Racing") == 0 ||
|
if (name_cmp("Virtua Racing") == 0 ||
|
||||||
name_cmp("VIRTUA RACING") == 0)
|
name_cmp("VIRTUA RACING") == 0)
|
||||||
{
|
{
|
||||||
PicoSVPInit();
|
PicoSVPStartup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ int PicoInit(void)
|
||||||
z80_init(); // init even if we aren't going to use it
|
z80_init(); // init even if we aren't going to use it
|
||||||
|
|
||||||
PicoInitMCD();
|
PicoInitMCD();
|
||||||
|
PicoSVPInit();
|
||||||
|
|
||||||
SRam.data=0;
|
SRam.data=0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -377,6 +377,7 @@ extern carthw_state_chunk *carthw_chunks;
|
||||||
|
|
||||||
// Cart.c
|
// Cart.c
|
||||||
PICO_INTERNAL void PicoCartDetect(void);
|
PICO_INTERNAL void PicoCartDetect(void);
|
||||||
|
extern void (*PicoCartUnloadHook)(void);
|
||||||
|
|
||||||
// Debug.c
|
// Debug.c
|
||||||
int CM_compareRun(int cyc, int is_sub);
|
int CM_compareRun(int cyc, int is_sub);
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ typedef struct {
|
||||||
extern svp_t *svp;
|
extern svp_t *svp;
|
||||||
|
|
||||||
void PicoSVPInit(void);
|
void PicoSVPInit(void);
|
||||||
|
void PicoSVPStartup(void);
|
||||||
|
|
||||||
unsigned int PicoSVPRead16(unsigned int a, int realsize);
|
unsigned int PicoSVPRead16(unsigned int a, int realsize);
|
||||||
void PicoSVPWrite8 (unsigned int a, unsigned int d, int realsize);
|
void PicoSVPWrite8 (unsigned int a, unsigned int d, int realsize);
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,10 @@
|
||||||
// 14 IRAM blocks
|
// 14 IRAM blocks
|
||||||
|
|
||||||
#include "../../PicoInt.h"
|
#include "../../PicoInt.h"
|
||||||
|
#include "compiler.h"
|
||||||
|
|
||||||
#define TCACHE_SIZE (1024*1024)
|
|
||||||
static unsigned int *block_table[0x5090/2];
|
static unsigned int *block_table[0x5090/2];
|
||||||
static unsigned int *block_table_iram[15][0x800/2];
|
static unsigned int *block_table_iram[15][0x800/2];
|
||||||
static unsigned int *tcache = NULL;
|
|
||||||
static unsigned int *tcache_ptr = NULL;
|
static unsigned int *tcache_ptr = NULL;
|
||||||
|
|
||||||
static int had_jump = 0;
|
static int had_jump = 0;
|
||||||
|
|
@ -517,44 +516,64 @@ static int get_iram_context(void)
|
||||||
|
|
||||||
#define PROGRAM(x) ((unsigned short *)svp->iram_rom)[x]
|
#define PROGRAM(x) ((unsigned short *)svp->iram_rom)[x]
|
||||||
|
|
||||||
|
static int translate_op(unsigned int op, int *pc)
|
||||||
|
{
|
||||||
|
switch (op >> 9)
|
||||||
|
{
|
||||||
|
// ld d, s
|
||||||
|
case 0x00: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static void *translate_block(int pc)
|
static void *translate_block(int pc)
|
||||||
{
|
{
|
||||||
unsigned int op, op1, icount = 0;
|
unsigned int op, op1, imm, ccount = 0;
|
||||||
unsigned int *block_start;
|
unsigned int *block_start;
|
||||||
|
int ret;
|
||||||
|
|
||||||
// create .pool
|
// create .pool
|
||||||
*tcache_ptr++ = (u32) &g_cycles; // -3 g_cycles
|
//*tcache_ptr++ = (u32) in_funcs; // -1 func pool
|
||||||
*tcache_ptr++ = (u32) &ssp->gr[SSP_PC].v; // -2 ptr to rPC
|
|
||||||
*tcache_ptr++ = (u32) in_funcs; // -1 func pool
|
|
||||||
|
|
||||||
printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<2);
|
printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<2);
|
||||||
block_start = tcache_ptr;
|
block_start = tcache_ptr;
|
||||||
|
|
||||||
emit_block_prologue();
|
emit_block_prologue();
|
||||||
|
|
||||||
for (; icount < 100;)
|
for (; ccount < 100;)
|
||||||
{
|
{
|
||||||
icount++;
|
|
||||||
//printf(" insn #%i\n", icount);
|
//printf(" insn #%i\n", icount);
|
||||||
op = PROGRAM(pc++);
|
op = PROGRAM(pc++);
|
||||||
op1 = op >> 9;
|
op1 = op >> 9;
|
||||||
|
imm = (u32)-1;
|
||||||
|
|
||||||
emit_mov_const(0, op);
|
if ((op1 & 0xf) == 4 || (op1 & 0xf) == 6)
|
||||||
|
imm = PROGRAM(pc++); // immediate
|
||||||
|
|
||||||
// need immediate?
|
ret = translate_op(op, &pc);
|
||||||
if ((op1 & 0xf) == 4 || (op1 & 0xf) == 6) {
|
if (ret <= 0)
|
||||||
emit_mov_const(1, PROGRAM(pc++)); // immediate
|
{
|
||||||
|
emit_mov_const(0, op);
|
||||||
|
|
||||||
|
// need immediate?
|
||||||
|
if (imm != (u32)-1)
|
||||||
|
emit_mov_const(1, imm);
|
||||||
|
|
||||||
|
// dump PC
|
||||||
|
emit_pc_dump(pc);
|
||||||
|
|
||||||
|
emit_interpreter_call(in_funcs[op1]);
|
||||||
|
|
||||||
|
if (in_funcs[op1] == NULL) {
|
||||||
|
printf("NULL func! op=%08x (%02x)\n", op, op1);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
ccount++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
ccount += ret;
|
||||||
|
|
||||||
// dump PC
|
|
||||||
emit_pc_inc(block_start, pc);
|
|
||||||
|
|
||||||
emit_call(block_start, op1);
|
|
||||||
|
|
||||||
if (in_funcs[op1] == NULL) {
|
|
||||||
printf("NULL func! op=%08x (%02x)\n", op, op1);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (op1 == 0x24 || op1 == 0x26 || // call, bra
|
if (op1 == 0x24 || op1 == 0x26 || // call, bra
|
||||||
((op1 == 0 || op1 == 1 || op1 == 4 || op1 == 5 || op1 == 9 || op1 == 0x25) &&
|
((op1 == 0 || op1 == 1 || op1 == 4 || op1 == 5 || op1 == 9 || op1 == 0x25) &&
|
||||||
(op & 0xf0) == 0x60)) { // ld PC
|
(op & 0xf0) == 0x60)) { // ld PC
|
||||||
|
|
@ -562,7 +581,7 @@ static void *translate_block(int pc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_block_epilogue(block_start, icount + 1);
|
emit_block_epilogue(ccount + 1);
|
||||||
*tcache_ptr++ = 0xffffffff; // end of block
|
*tcache_ptr++ = 0xffffffff; // end of block
|
||||||
//printf(" %i inst\n", icount);
|
//printf(" %i inst\n", icount);
|
||||||
|
|
||||||
|
|
@ -596,16 +615,12 @@ static void *translate_block(int pc)
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
|
|
||||||
int ssp1601_dyn_init(void)
|
int ssp1601_dyn_startup(void)
|
||||||
{
|
{
|
||||||
tcache = tcache_ptr = malloc(TCACHE_SIZE);
|
memset(tcache, 0, TCACHE_SIZE);
|
||||||
if (tcache == NULL) {
|
|
||||||
printf("oom\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
memset(tcache, 0, sizeof(TCACHE_SIZE));
|
|
||||||
memset(block_table, 0, sizeof(block_table));
|
memset(block_table, 0, sizeof(block_table));
|
||||||
memset(block_table_iram, 0, sizeof(block_table_iram));
|
memset(block_table_iram, 0, sizeof(block_table_iram));
|
||||||
|
tcache_ptr = tcache;
|
||||||
*tcache_ptr++ = 0xffffffff;
|
*tcache_ptr++ = 0xffffffff;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -621,7 +636,7 @@ void ssp1601_dyn_run(int cycles)
|
||||||
{
|
{
|
||||||
while (cycles > 0)
|
while (cycles > 0)
|
||||||
{
|
{
|
||||||
void (*trans_entry)(void);
|
int (*trans_entry)(void);
|
||||||
if (rPC < 0x800/2)
|
if (rPC < 0x800/2)
|
||||||
{
|
{
|
||||||
if (iram_dirty) {
|
if (iram_dirty) {
|
||||||
|
|
@ -641,45 +656,9 @@ void ssp1601_dyn_run(int cycles)
|
||||||
|
|
||||||
had_jump = 0;
|
had_jump = 0;
|
||||||
|
|
||||||
//printf("enter @ %04x, PC=%04x\n", (PC - tcache)<<1, rPC<<1);
|
//printf("enter %04x\n", rPC<<1);
|
||||||
g_cycles = 0;
|
cycles -= trans_entry();
|
||||||
//printf("enter %04x\n", rPC);
|
//printf("leave %04x\n", rPC<<1);
|
||||||
trans_entry();
|
|
||||||
//printf("leave %04x\n", rPC);
|
|
||||||
cycles -= g_cycles;
|
|
||||||
/*
|
|
||||||
if (!had_jump) {
|
|
||||||
// no jumps
|
|
||||||
if (pc_old < 0x800/2)
|
|
||||||
rPC += (PC - block_table_iram[iram_context][pc_old]) - 1;
|
|
||||||
else
|
|
||||||
rPC += (PC - block_table[pc_old]) - 1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//printf("end @ %04x, PC=%04x\n", (PC - tcache)<<1, rPC<<1);
|
|
||||||
/*
|
|
||||||
if (pc_old < 0x400) {
|
|
||||||
// flush IRAM cache
|
|
||||||
tcache_ptr = block_table[pc_old];
|
|
||||||
block_table[pc_old] = NULL;
|
|
||||||
nblocks--;
|
|
||||||
}
|
|
||||||
if (pc_old >= 0x400 && rPC < 0x400)
|
|
||||||
{
|
|
||||||
int i, crc = chksum_crc32(svp->iram_rom, 0x800);
|
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
if (iram_crcs[i] == crc) break;
|
|
||||||
if (i == 32) {
|
|
||||||
char name[32];
|
|
||||||
for (i = 0; i < 32 && iram_crcs[i]; i++);
|
|
||||||
iram_crcs[i] = crc;
|
|
||||||
printf("%i IRAMs\n", i+1);
|
|
||||||
sprintf(name, "ir%08x.bin", crc);
|
|
||||||
debug_dump2file(name, svp->iram_rom, 0x800);
|
|
||||||
}
|
|
||||||
printf("CRC %08x %08x\n", crc, iram_id);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
// debug_dump2file("tcache.bin", tcache, (tcache_ptr - tcache) << 1);
|
// debug_dump2file("tcache.bin", tcache, (tcache_ptr - tcache) << 1);
|
||||||
// exit(1);
|
// exit(1);
|
||||||
|
|
|
||||||
11
Pico/carthw/svp/compiler.h
Normal file
11
Pico/carthw/svp/compiler.h
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#define TCACHE_SIZE (1024*1024)
|
||||||
|
|
||||||
|
extern unsigned int tcache[];
|
||||||
|
|
||||||
|
void regfile_load(void);
|
||||||
|
void regfile_store(void);
|
||||||
|
|
||||||
|
int ssp1601_dyn_startup(void);
|
||||||
|
void ssp1601_dyn_reset(ssp1601_t *ssp);
|
||||||
|
void ssp1601_dyn_run(int cycles);
|
||||||
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
#define EMIT(x) *tcache_ptr++ = x
|
#define EMIT(x) *tcache_ptr++ = x
|
||||||
|
|
||||||
|
#define A_R4M (1 << 4)
|
||||||
|
#define A_R5M (1 << 5)
|
||||||
|
#define A_R6M (1 << 6)
|
||||||
|
#define A_R7M (1 << 7)
|
||||||
|
#define A_R8M (1 << 8)
|
||||||
|
#define A_R9M (1 << 9)
|
||||||
|
#define A_R10M (1 << 10)
|
||||||
|
#define A_R11M (1 << 11)
|
||||||
#define A_R14M (1 << 14)
|
#define A_R14M (1 << 14)
|
||||||
|
|
||||||
#define A_COND_AL 0xe
|
#define A_COND_AL 0xe
|
||||||
|
|
@ -37,6 +45,7 @@
|
||||||
#define EOP_LDR_IMM( rd,rn,offset_12) EOP_C_XXR_IMM(A_COND_AL,1,0,1,rn,rd,offset_12)
|
#define EOP_LDR_IMM( rd,rn,offset_12) EOP_C_XXR_IMM(A_COND_AL,1,0,1,rn,rd,offset_12)
|
||||||
#define EOP_LDR_NEGIMM(rd,rn,offset_12) EOP_C_XXR_IMM(A_COND_AL,0,0,1,rn,rd,offset_12)
|
#define EOP_LDR_NEGIMM(rd,rn,offset_12) EOP_C_XXR_IMM(A_COND_AL,0,0,1,rn,rd,offset_12)
|
||||||
#define EOP_LDR_SIMPLE(rd,rn) EOP_C_XXR_IMM(A_COND_AL,1,0,1,rn,rd,0)
|
#define EOP_LDR_SIMPLE(rd,rn) EOP_C_XXR_IMM(A_COND_AL,1,0,1,rn,rd,0)
|
||||||
|
#define EOP_STR_IMM( rd,rn,offset_12) EOP_C_XXR_IMM(A_COND_AL,1,0,0,rn,rd,offset_12)
|
||||||
#define EOP_STR_SIMPLE(rd,rn) EOP_C_XXR_IMM(A_COND_AL,1,0,0,rn,rd,0)
|
#define EOP_STR_SIMPLE(rd,rn) EOP_C_XXR_IMM(A_COND_AL,1,0,0,rn,rd,0)
|
||||||
|
|
||||||
/* ldm and stm */
|
/* ldm and stm */
|
||||||
|
|
@ -52,6 +61,12 @@
|
||||||
|
|
||||||
#define EOP_BX(rm) EOP_C_BX(A_COND_AL,rm)
|
#define EOP_BX(rm) EOP_C_BX(A_COND_AL,rm)
|
||||||
|
|
||||||
|
#define EOP_C_B(cond,l,signed_immed_24) \
|
||||||
|
EMIT(((cond)<<28) | 0x0a000000 | ((l)<<24) | (signed_immed_24))
|
||||||
|
|
||||||
|
#define EOP_B( signed_immed_24) EOP_C_B(A_COND_AL,0,signed_immed_24)
|
||||||
|
#define EOP_BL(signed_immed_24) EOP_C_B(A_COND_AL,1,signed_immed_24)
|
||||||
|
|
||||||
|
|
||||||
static void emit_mov_const(int d, unsigned int val)
|
static void emit_mov_const(int d, unsigned int val)
|
||||||
{
|
{
|
||||||
|
|
@ -72,53 +87,56 @@ static void emit_mov_const(int d, unsigned int val)
|
||||||
EOP_C_DOP_IMM(A_COND_AL,need_or ? A_OP_ORR : A_OP_MOV, 0, need_or ? d : 0, d, 0, val&0xff);
|
EOP_C_DOP_IMM(A_COND_AL,need_or ? A_OP_ORR : A_OP_MOV, 0, need_or ? d : 0, d, 0, val&0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
static void check_offset_12(unsigned int val)
|
static void check_offset_12(unsigned int val)
|
||||||
{
|
{
|
||||||
if (!(val & ~0xfff)) return;
|
if (!(val & ~0xfff)) return;
|
||||||
printf("offset_12 overflow %04x\n", val);
|
printf("offset_12 overflow %04x\n", val);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void check_offset_24(int val)
|
||||||
|
{
|
||||||
|
if (val >= (int)0xff000000 && val <= 0x00ffffff) return;
|
||||||
|
printf("offset_24 overflow %08x\n", val);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emit_call(void *target)
|
||||||
|
{
|
||||||
|
int val = (unsigned int *)target - tcache_ptr - 2;
|
||||||
|
check_offset_24(val);
|
||||||
|
|
||||||
|
EOP_BL(val & 0xffffff); // bl target
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_block_prologue(void)
|
static void emit_block_prologue(void)
|
||||||
{
|
{
|
||||||
// stack LR
|
// stack regs
|
||||||
EOP_STMFD_ST(A_R14M); // stmfd r13!, {r14}
|
EOP_STMFD_ST(A_R4M|A_R5M|A_R6M|A_R7M|A_R8M|A_R9M|A_R10M|A_R11M|A_R14M); // stmfd r13!, {r4-r11,lr}
|
||||||
|
emit_call(regfile_load);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_block_epilogue(unsigned int *block_start, int icount)
|
static void emit_block_epilogue(int icount)
|
||||||
{
|
{
|
||||||
int back = (tcache_ptr - block_start) + 2;
|
emit_call(regfile_store);
|
||||||
back += 3; // g_cycles
|
EOP_LDMFD_ST(A_R4M|A_R5M|A_R6M|A_R7M|A_R8M|A_R9M|A_R10M|A_R11M|A_R14M); // ldmfd r13!, {r4-r11,lr}
|
||||||
check_offset_12(back<<2);
|
emit_mov_const(0, icount);
|
||||||
|
|
||||||
EOP_LDR_NEGIMM(2,15,back<<2); // ldr r2,[pc,#back]
|
|
||||||
emit_mov_const(3, icount);
|
|
||||||
EOP_STR_SIMPLE(3,2); // str r3,[r2]
|
|
||||||
|
|
||||||
EOP_LDMFD_ST(A_R14M); // ldmfd r13!, {r14}
|
|
||||||
EOP_BX(14); // bx r14
|
EOP_BX(14); // bx r14
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_pc_inc(unsigned int *block_start, int pc)
|
static void emit_pc_dump(int pc)
|
||||||
{
|
{
|
||||||
int back = (tcache_ptr - block_start) + 2;
|
|
||||||
back += 2; // rPC ptr
|
|
||||||
check_offset_12(back<<2);
|
|
||||||
|
|
||||||
EOP_LDR_NEGIMM(2,15,back<<2); // ldr r2,[pc,#back]
|
|
||||||
emit_mov_const(3, pc<<16);
|
emit_mov_const(3, pc<<16);
|
||||||
EOP_STR_SIMPLE(3,2); // str r3,[r2]
|
EOP_STR_IMM(3,7,0x400+6*4); // str r3, [r7, #(0x400+6*8)]
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_call(unsigned int *block_start, unsigned int op1)
|
static void emit_interpreter_call(void *target)
|
||||||
{
|
{
|
||||||
int back = (tcache_ptr - block_start) + 2;
|
emit_call(regfile_store);
|
||||||
back += 1; // func table
|
emit_call(target);
|
||||||
check_offset_12(back<<2);
|
emit_call(regfile_load);
|
||||||
|
|
||||||
EOP_LDR_NEGIMM(2,15,back<<2); // ldr r2,[pc,#back]
|
|
||||||
EOP_MOV_REG_SIMPLE(14,15); // mov lr,pc
|
|
||||||
EOP_LDR_IMM(15,2,op1<<2); // ldr pc,[r2,#op1]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_caches()
|
static void handle_caches()
|
||||||
|
|
|
||||||
|
|
@ -332,7 +332,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ssp1601_t *ssp = NULL;
|
#ifndef EMBED_INTERPRETER
|
||||||
|
static
|
||||||
|
#endif
|
||||||
|
ssp1601_t *ssp = NULL;
|
||||||
static unsigned short *PC;
|
static unsigned short *PC;
|
||||||
static int g_cycles;
|
static int g_cycles;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,3 @@ typedef struct
|
||||||
void ssp1601_reset(ssp1601_t *ssp);
|
void ssp1601_reset(ssp1601_t *ssp);
|
||||||
void ssp1601_run(int cycles);
|
void ssp1601_run(int cycles);
|
||||||
|
|
||||||
int ssp1601_dyn_init(void);
|
|
||||||
void ssp1601_dyn_reset(ssp1601_t *ssp);
|
|
||||||
void ssp1601_dyn_run(int cycles);
|
|
||||||
|
|
||||||
|
|
|
||||||
81
Pico/carthw/svp/stub_arm.S
Normal file
81
Pico/carthw/svp/stub_arm.S
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
@ vim:filetype=armasm
|
||||||
|
|
||||||
|
.if 0
|
||||||
|
#include "compiler.h"
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.global tcache
|
||||||
|
|
||||||
|
.global flush_inval_caches
|
||||||
|
.global regfile_load
|
||||||
|
.global regfile_store
|
||||||
|
|
||||||
|
@ translation cache buffer
|
||||||
|
.text
|
||||||
|
.align 12 @ 4096
|
||||||
|
.size tcache, TCACHE_SIZE
|
||||||
|
tcache:
|
||||||
|
.space TCACHE_SIZE
|
||||||
|
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
|
||||||
|
flush_inval_caches:
|
||||||
|
mov r2, #0x0 @ must be 0
|
||||||
|
swi 0x9f0002
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
@ SSP_GR0, SSP_X, SSP_Y, SSP_A,
|
||||||
|
@ SSP_ST, SSP_STACK, SSP_PC, SSP_P,
|
||||||
|
@ SSP_PM0, SSP_PM1, SSP_PM2, SSP_XST,
|
||||||
|
@ SSP_PM4, SSP_gr13, SSP_PMC, SSP_AL
|
||||||
|
|
||||||
|
@ register map:
|
||||||
|
@ r4: XXYY
|
||||||
|
@ r5: A
|
||||||
|
@ r6: STACK and emu flags
|
||||||
|
@ r7: SSP context
|
||||||
|
@ r8: r0-r2
|
||||||
|
@ r9: r4-r6
|
||||||
|
@ r10: P
|
||||||
|
@ r11: cycles
|
||||||
|
|
||||||
|
@ trashes r2,r3
|
||||||
|
|
||||||
|
regfile_load:
|
||||||
|
ldr r7, =ssp
|
||||||
|
ldr r7, [r7]
|
||||||
|
add r2, r7, #0x400
|
||||||
|
add r2, r2, #4
|
||||||
|
ldmia r2, {r3,r4,r5,r6,r8}
|
||||||
|
mov r3, r3, lsr #16
|
||||||
|
mov r3, r3, lsl #16
|
||||||
|
orr r4, r3, r4, lsr #16 @ XXYY
|
||||||
|
bic r6, r6, #0xff
|
||||||
|
orr r6, r6, r8, lsr #16 @ flags + STACK
|
||||||
|
ldr r8, [r7, #0x440] @ r0-r2
|
||||||
|
ldr r9, [r7, #0x444] @ r4-r6
|
||||||
|
ldr r10,[r7, #(0x400+7*4)] @ P
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
regfile_store:
|
||||||
|
str r10,[r7, #(0x400+7*4)] @ P
|
||||||
|
str r8, [r7, #0x440] @ r0-r2
|
||||||
|
str r9, [r7, #0x444] @ r4-r6
|
||||||
|
mov r9, r6, lsl #16
|
||||||
|
and r9, r9, #(7<<16) @ STACK
|
||||||
|
bic r6, r6, #0xff @ ST
|
||||||
|
mov r3, r4, lsl #16 @ Y
|
||||||
|
mov r2, r4, lsr #16
|
||||||
|
mov r2, r2, lsl #16 @ X
|
||||||
|
add r8, r7, #0x400
|
||||||
|
add r8, r8, #4
|
||||||
|
stmia r8, {r2,r3,r5,r6,r9}
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
@ vim:filetype=armasm
|
|
||||||
|
|
||||||
|
|
||||||
@ register map:
|
|
||||||
@ r4: XXYY
|
|
||||||
@ r5: A
|
|
||||||
@ r6: STACK and emu flags
|
|
||||||
@ r7: SSP context
|
|
||||||
@ r8: r0-r2
|
|
||||||
@ r9: r4-r6
|
|
||||||
@ r10: P
|
|
||||||
|
|
||||||
.global flush_inval_caches
|
|
||||||
|
|
||||||
.text
|
|
||||||
.align 4
|
|
||||||
|
|
||||||
flush_inval_caches:
|
|
||||||
mov r2, #0x0 @ must be 0
|
|
||||||
swi 0x9f0002
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
|
|
||||||
#include "../../PicoInt.h"
|
#include "../../PicoInt.h"
|
||||||
|
#include "compiler.h"
|
||||||
|
#ifdef __GP2X__
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
svp_t *svp = NULL;
|
svp_t *svp = NULL;
|
||||||
int PicoSVPCycles = 1000; // cycles/line
|
int PicoSVPCycles = 1000; // cycles/line
|
||||||
|
|
@ -40,6 +44,10 @@ static void PicoSVPReset(void)
|
||||||
|
|
||||||
static void PicoSVPLine(int count)
|
static void PicoSVPLine(int count)
|
||||||
{
|
{
|
||||||
|
static int inited = 0;
|
||||||
|
if (!(svp->ssp1601.gr[SSP_PM0].h & 2) && !inited) return;
|
||||||
|
inited = 1;
|
||||||
|
|
||||||
// ???
|
// ???
|
||||||
if (PicoOpt&0x20000)
|
if (PicoOpt&0x20000)
|
||||||
ssp1601_run(PicoSVPCycles * count);
|
ssp1601_run(PicoSVPCycles * count);
|
||||||
|
|
@ -77,6 +85,25 @@ static int PicoSVPDma(unsigned int source, int len, unsigned short **srcp, unsig
|
||||||
|
|
||||||
|
|
||||||
void PicoSVPInit(void)
|
void PicoSVPInit(void)
|
||||||
|
{
|
||||||
|
#ifdef __GP2X__
|
||||||
|
int ret;
|
||||||
|
ret = munmap(tcache, TCACHE_SIZE);
|
||||||
|
printf("munmap tcache: %i\n", ret);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void PicoSVPShutdown(void)
|
||||||
|
{
|
||||||
|
#ifdef __GP2X__
|
||||||
|
// also unmap tcache
|
||||||
|
PicoSVPInit();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PicoSVPStartup(void)
|
||||||
{
|
{
|
||||||
void *tmp;
|
void *tmp;
|
||||||
|
|
||||||
|
|
@ -93,9 +120,14 @@ void PicoSVPInit(void)
|
||||||
svp = (void *) ((char *)tmp + 0x200000);
|
svp = (void *) ((char *)tmp + 0x200000);
|
||||||
memset(svp, 0, sizeof(*svp));
|
memset(svp, 0, sizeof(*svp));
|
||||||
|
|
||||||
|
#ifdef __GP2X__
|
||||||
|
tmp = mmap(tcache, TCACHE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
|
||||||
|
printf("mmap tcache: %p, asked %p\n", tmp, tcache);
|
||||||
|
#endif
|
||||||
|
|
||||||
// init SVP compiler
|
// init SVP compiler
|
||||||
if (!(PicoOpt&0x20000)) {
|
if (!(PicoOpt&0x20000)) {
|
||||||
if (ssp1601_dyn_init()) return;
|
if (ssp1601_dyn_startup()) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// init ok, setup hooks..
|
// init ok, setup hooks..
|
||||||
|
|
@ -105,6 +137,7 @@ void PicoSVPInit(void)
|
||||||
PicoDmaHook = PicoSVPDma;
|
PicoDmaHook = PicoSVPDma;
|
||||||
PicoResetHook = PicoSVPReset;
|
PicoResetHook = PicoSVPReset;
|
||||||
PicoLineHook = PicoSVPLine;
|
PicoLineHook = PicoSVPLine;
|
||||||
|
PicoCartUnloadHook = PicoSVPShutdown;
|
||||||
|
|
||||||
// save state stuff
|
// save state stuff
|
||||||
svp_states[0].ptr = svp->iram_rom;
|
svp_states[0].ptr = svp->iram_rom;
|
||||||
|
|
@ -113,3 +146,4 @@ void PicoSVPInit(void)
|
||||||
carthw_chunks = svp_states;
|
carthw_chunks = svp_states;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,9 @@ up: PicoDrive.gpe
|
||||||
.s.o:
|
.s.o:
|
||||||
@echo ">>>" $<
|
@echo ">>>" $<
|
||||||
$(GCC) $(COPT) $(DEFINC) -c $< -o $@
|
$(GCC) $(COPT) $(DEFINC) -c $< -o $@
|
||||||
|
.S.o:
|
||||||
|
@echo ">>>" $<
|
||||||
|
$(GCC) $(COPT) $(DEFINC) -c $< -o $@
|
||||||
|
|
||||||
../../Pico/carthw/svp/compiler.o : ../../Pico/carthw/svp/ssp16.o ../../Pico/carthw/svp/gen_arm.c
|
../../Pico/carthw/svp/compiler.o : ../../Pico/carthw/svp/ssp16.o ../../Pico/carthw/svp/gen_arm.c
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue