I'd provide some source but I'm not entirely certain where the problem is. I'd like to try PSPLink's gdb capabilities to narrow things down but I'm using 2.6 firmware. I'm actually not even 100% sure where this thing's crashing since I can't make use of an exception handler.
I'm attempting to write a dynamic recompiling/threaded interpreting SNES emulator (I'm not really clear on the distinction). My current problem is that when I comment out the code to dump blocks from the instruction cache-- the emulator's, not the PSP's, obviously-- to the memstick, the program seems to crash upon attempting to execute the generated code. If I leave the logging in there, I don't get any problems unless I completely comment out all of the other printf stuff that's hanging around there.
I'll post what I think could be relevant code:
from compileBlock():
Code: Select all
// ... some stuff ...
/* Pass 2
* emit proper translated code
*/
skip = 0;
//createDebugFile( "ms0:/exec.dump" );
tempPtr = bankTable[ startPC >> 16 ] + ( startPC & 0xFFFF );
*tempPtr = emitCode;
/** Reset flag considerations for second pass **/
if( tempFlags != P ) setAll( P );
for(; j <= i; ++j ) {
tempFlags = P | CFLAG | VFLAG | ZFLAG | NFLAG; /* Select flags later */
cc += emitInstr( &emitCode, ( byte * )realPC + skip, tempFlags );
switch( *( realPC + skip ) ) {
case SEP:
P |= *( realPC + skip + 1 );
if( P & MFLAG ) sepM();
if( P & XFLAG ) sepX();
break;
case REP:
P &= ~( *( realPC + skip + 1 ) );
if( !( P & MFLAG ) ) repM();
if( !( P & XFLAG ) ) repX();
break;
}
skip += sizeTable[ *( realPC + skip ) ];
}
emitUpdatePC( &emitCode, skip );
emitUpdateCycles( &emitCode, cc );
emitReturn( &emitCode );
//writeDebugFile( romCache, ( byte * )emitCode - ( byte * )romCache );
//closeDebugFile();
// ... more stuff ...
And here's the code to either call the above or execute the code generated by the above (a good lot of the MIPS regs are statically allocated to represent 65c816 registers, please forgive the mess):
Code: Select all
dynarec:
la A0, bankTable # Get the value for bankTable[ bank ]
srl A1, PC, 16 # Get PC bank
sll A1, A1, 2 # word alignment
addu A0, A0, A1
lw V0, 0( A0 )
bne V0, ZERO, bankActive
nop
la TEMPREG1, activeBanks # bankTable[ bank ] = cacheEntries + 0xFFFF * activeBanks
lw TEMPREG2, 0( TEMPREG1 ) # if activeBanks < 2
addi A1, TEMPREG2, -2
beq A1, ZERO, reset
nop
li TEMPREG3, 0xFFFF
la V0, cacheEntries
mul TEMPREG3, TEMPREG3, TEMPREG2
sll TEMPREG3, TEMPREG3, 2 # word alignment
addu V1, V0, TEMPREG3
sw V1, 0( A0 )
addi TEMPREG2, TEMPREG2, 1 # ++bankCount;
sw TEMPREG2, 0( TEMPREG1 )
j bankActive
nop
reset:
SAVEREGS flushCache, ZERO, ZERO, ZERO
sw V0, 0( A0 )
bankActive:
andi TEMPREG1, PC, 0xFFFF
sll TEMPREG1, TEMPREG1, 2 # word alignment
addu TEMPREG1, TEMPREG1, V0
lw TEMPREG2, 0( TEMPREG1 )
bne TEMPREG2, ZERO, runCode
nop
SAVEREGS compileBlock, PC, P, ZERO
lw TEMPREG2, 0( TEMPREG1 )
runCode:
jal TEMPREG2
nop
j dynarec
nop
I've considered downgrading to 1.5 or 1.0 but I'm not sure I want to risk a brick. If anyone has any suggestions for step-debugging/memory monitoring tools available to 2.6 those of us with firmware, that would be appreciated as well.