mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -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" };
|
||||
|
||||
void (*PicoCartUnloadHook)(void) = NULL;
|
||||
|
||||
void (*PicoCartLoadProgressCB)(int percent) = NULL;
|
||||
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.romsize=romsize;
|
||||
|
||||
if (PicoCartUnloadHook != NULL) {
|
||||
PicoCartUnloadHook();
|
||||
PicoCartUnloadHook = NULL;
|
||||
}
|
||||
|
||||
PicoMemResetHooks();
|
||||
PicoDmaHook = NULL;
|
||||
PicoResetHook = NULL;
|
||||
|
@ -646,7 +653,7 @@ void PicoCartDetect(void)
|
|||
if (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
|
||||
|
||||
PicoInitMCD();
|
||||
PicoSVPInit();
|
||||
|
||||
SRam.data=0;
|
||||
|
||||
|
|
|
@ -377,6 +377,7 @@ extern carthw_state_chunk *carthw_chunks;
|
|||
|
||||
// Cart.c
|
||||
PICO_INTERNAL void PicoCartDetect(void);
|
||||
extern void (*PicoCartUnloadHook)(void);
|
||||
|
||||
// Debug.c
|
||||
int CM_compareRun(int cyc, int is_sub);
|
||||
|
|
|
@ -11,6 +11,7 @@ typedef struct {
|
|||
extern svp_t *svp;
|
||||
|
||||
void PicoSVPInit(void);
|
||||
void PicoSVPStartup(void);
|
||||
|
||||
unsigned int PicoSVPRead16(unsigned int a, int realsize);
|
||||
void PicoSVPWrite8 (unsigned int a, unsigned int d, int realsize);
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
// 14 IRAM blocks
|
||||
|
||||
#include "../../PicoInt.h"
|
||||
#include "compiler.h"
|
||||
|
||||
#define TCACHE_SIZE (1024*1024)
|
||||
static unsigned int *block_table[0x5090/2];
|
||||
static unsigned int *block_table_iram[15][0x800/2];
|
||||
static unsigned int *tcache = NULL;
|
||||
static unsigned int *tcache_ptr = NULL;
|
||||
|
||||
static int had_jump = 0;
|
||||
|
@ -517,44 +516,64 @@ static int get_iram_context(void)
|
|||
|
||||
#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)
|
||||
{
|
||||
unsigned int op, op1, icount = 0;
|
||||
unsigned int op, op1, imm, ccount = 0;
|
||||
unsigned int *block_start;
|
||||
int ret;
|
||||
|
||||
// create .pool
|
||||
*tcache_ptr++ = (u32) &g_cycles; // -3 g_cycles
|
||||
*tcache_ptr++ = (u32) &ssp->gr[SSP_PC].v; // -2 ptr to rPC
|
||||
*tcache_ptr++ = (u32) in_funcs; // -1 func pool
|
||||
//*tcache_ptr++ = (u32) in_funcs; // -1 func pool
|
||||
|
||||
printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<2);
|
||||
block_start = tcache_ptr;
|
||||
|
||||
emit_block_prologue();
|
||||
|
||||
for (; icount < 100;)
|
||||
for (; ccount < 100;)
|
||||
{
|
||||
icount++;
|
||||
//printf(" insn #%i\n", icount);
|
||||
op = PROGRAM(pc++);
|
||||
op1 = op >> 9;
|
||||
imm = (u32)-1;
|
||||
|
||||
emit_mov_const(0, op);
|
||||
if ((op1 & 0xf) == 4 || (op1 & 0xf) == 6)
|
||||
imm = PROGRAM(pc++); // immediate
|
||||
|
||||
// need immediate?
|
||||
if ((op1 & 0xf) == 4 || (op1 & 0xf) == 6) {
|
||||
emit_mov_const(1, PROGRAM(pc++)); // immediate
|
||||
ret = translate_op(op, &pc);
|
||||
if (ret <= 0)
|
||||
{
|
||||
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
|
||||
((op1 == 0 || op1 == 1 || op1 == 4 || op1 == 5 || op1 == 9 || op1 == 0x25) &&
|
||||
(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
|
||||
//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);
|
||||
if (tcache == NULL) {
|
||||
printf("oom\n");
|
||||
exit(1);
|
||||
}
|
||||
memset(tcache, 0, sizeof(TCACHE_SIZE));
|
||||
memset(tcache, 0, TCACHE_SIZE);
|
||||
memset(block_table, 0, sizeof(block_table));
|
||||
memset(block_table_iram, 0, sizeof(block_table_iram));
|
||||
tcache_ptr = tcache;
|
||||
*tcache_ptr++ = 0xffffffff;
|
||||
|
||||
return 0;
|
||||
|
@ -621,7 +636,7 @@ void ssp1601_dyn_run(int cycles)
|
|||
{
|
||||
while (cycles > 0)
|
||||
{
|
||||
void (*trans_entry)(void);
|
||||
int (*trans_entry)(void);
|
||||
if (rPC < 0x800/2)
|
||||
{
|
||||
if (iram_dirty) {
|
||||
|
@ -641,45 +656,9 @@ void ssp1601_dyn_run(int cycles)
|
|||
|
||||
had_jump = 0;
|
||||
|
||||
//printf("enter @ %04x, PC=%04x\n", (PC - tcache)<<1, rPC<<1);
|
||||
g_cycles = 0;
|
||||
//printf("enter %04x\n", rPC);
|
||||
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);
|
||||
}
|
||||
*/
|
||||
//printf("enter %04x\n", rPC<<1);
|
||||
cycles -= trans_entry();
|
||||
//printf("leave %04x\n", rPC<<1);
|
||||
}
|
||||
// debug_dump2file("tcache.bin", tcache, (tcache_ptr - tcache) << 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 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_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_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_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)
|
||||
|
||||
/* ldm and stm */
|
||||
|
@ -52,6 +61,12 @@
|
|||
|
||||
#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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
static void check_offset_12(unsigned int val)
|
||||
{
|
||||
if (!(val & ~0xfff)) return;
|
||||
printf("offset_12 overflow %04x\n", val);
|
||||
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)
|
||||
{
|
||||
// stack LR
|
||||
EOP_STMFD_ST(A_R14M); // stmfd r13!, {r14}
|
||||
// stack regs
|
||||
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;
|
||||
back += 3; // g_cycles
|
||||
check_offset_12(back<<2);
|
||||
|
||||
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}
|
||||
emit_call(regfile_store);
|
||||
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}
|
||||
emit_mov_const(0, icount);
|
||||
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);
|
||||
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;
|
||||
back += 1; // func table
|
||||
check_offset_12(back<<2);
|
||||
|
||||
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]
|
||||
emit_call(regfile_store);
|
||||
emit_call(target);
|
||||
emit_call(regfile_load);
|
||||
}
|
||||
|
||||
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 int g_cycles;
|
||||
|
||||
|
|
|
@ -58,7 +58,3 @@ typedef struct
|
|||
void ssp1601_reset(ssp1601_t *ssp);
|
||||
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 "compiler.h"
|
||||
#ifdef __GP2X__
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
svp_t *svp = NULL;
|
||||
int PicoSVPCycles = 1000; // cycles/line
|
||||
|
@ -40,6 +44,10 @@ static void PicoSVPReset(void)
|
|||
|
||||
static void PicoSVPLine(int count)
|
||||
{
|
||||
static int inited = 0;
|
||||
if (!(svp->ssp1601.gr[SSP_PM0].h & 2) && !inited) return;
|
||||
inited = 1;
|
||||
|
||||
// ???
|
||||
if (PicoOpt&0x20000)
|
||||
ssp1601_run(PicoSVPCycles * count);
|
||||
|
@ -77,6 +85,25 @@ static int PicoSVPDma(unsigned int source, int len, unsigned short **srcp, unsig
|
|||
|
||||
|
||||
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;
|
||||
|
||||
|
@ -93,9 +120,14 @@ void PicoSVPInit(void)
|
|||
svp = (void *) ((char *)tmp + 0x200000);
|
||||
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
|
||||
if (!(PicoOpt&0x20000)) {
|
||||
if (ssp1601_dyn_init()) return;
|
||||
if (ssp1601_dyn_startup()) return;
|
||||
}
|
||||
|
||||
// init ok, setup hooks..
|
||||
|
@ -105,6 +137,7 @@ void PicoSVPInit(void)
|
|||
PicoDmaHook = PicoSVPDma;
|
||||
PicoResetHook = PicoSVPReset;
|
||||
PicoLineHook = PicoSVPLine;
|
||||
PicoCartUnloadHook = PicoSVPShutdown;
|
||||
|
||||
// save state stuff
|
||||
svp_states[0].ptr = svp->iram_rom;
|
||||
|
@ -113,3 +146,4 @@ void PicoSVPInit(void)
|
|||
carthw_chunks = svp_states;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -159,6 +159,9 @@ up: PicoDrive.gpe
|
|||
.s.o:
|
||||
@echo ">>>" $<
|
||||
$(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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue