A bit of bad news for DOSBox - the dynarec is configured only for MIPS32R2 and the Dingoo A320 only supports MIPS32.
This is a pity as there are only a few changes required but I don't really have the depth of knowledge with dynarecs to make the changes.
The simple/normal cores work but I think we really want the dynarec working to get decent speed from this.
Could anyone have a look at this?
We need code for:
and
in the code below.
From risc_mipsel32.h:
Code:
// convert an 8bit word to a 32bit dword
// the register is zero-extended (sign==false) or sign-extended (sign==true)
static void gen_extend_byte(bool sign,HostReg reg) {
if (sign) {
#if (_MIPS_ISA==MIPS32R2) || defined(PSP)
cache_addw((reg<<11)+0x420); // seb reg, reg
cache_addw(0x7c00+reg);
#else
arch that lacks seb
#endif
} else {
cache_addw(0xff); // andi reg, reg, 0xff
cache_addw(0x3000+(reg<<5)+reg);
}
}
// convert a 16bit word to a 32bit dword
// the register is zero-extended (sign==false) or sign-extended (sign==true)
static void gen_extend_word(bool sign,HostReg reg) {
if (sign) {
#if (_MIPS_ISA==MIPS32R2) || defined(PSP)
cache_addw((reg<<11)+0x620); // seh reg, reg
cache_addw(0x7c00+reg);
#else
arch that lacks seh
#endif
} else {
cache_addw(0xffff); // andi reg, reg, 0xffff
cache_addw(0x3000+(reg<<5)+reg);
}
}
EDIT:
For reference, here are SEB and SEH macros from gpSP (GBA emu).
Code:
.macro m_seb dest,src
sw t0,-4($sp)
andi \dest,\src,0xff
xori \dest,0x80
ori t0,zero,0x80
sub \dest,t0
lw t0,-4($sp)
.endm
.macro m_seh dest,src
sw t0,-4($sp)
andi \dest,\src,0xffff
xori \dest,0x8000
ori t0,zero,0x8000
sub \dest,t0
lw t0,-4($sp)
.endm
EDIT1:
Am I missing something here or could you duplicate SEB and SEH in the following manner?
gpSP's method seems overly complicated.
Code:
.macro SEB
SLL dest,src,24
SRA dest,dest,24
.endm
.macro SEH
SLL dest,src,16
SRA dest,dest,16
.endm
EDIT2; Actually I just tried this in gpSP and it seems to work okay. Should be faster too!
Now just need to do the DOSBox version...
EDIT3: I gave it a go myself.
Here's my solution:
Code:
// convert an 8bit word to a 32bit dword
// the register is zero-extended (sign==false) or sign-extended (sign==true)
static void gen_extend_byte(bool sign,HostReg reg) {
if (sign) {
#if (_MIPS_ISA==MIPS32R2) || defined(PSP)
cache_addw((reg<<11)+0x420); // seb reg, reg
cache_addw(0x7c00+reg);
#else
cache_addw((reg<<11)+(24<<6)+0); // sll reg,reg,24
cache_addw(reg);
cache_addw((reg<<11)+(24<<6)+3); // sra reg,reg,24
cache_addw(reg);
#endif
} else {
cache_addw(0xff); // andi reg, reg, 0xff
cache_addw(0x3000+(reg<<5)+reg);
}
}
// convert a 16bit word to a 32bit dword
// the register is zero-extended (sign==false) or sign-extended (sign==true)
static void gen_extend_word(bool sign,HostReg reg) {
if (sign) {
#if (_MIPS_ISA==MIPS32R2) || defined(PSP)
cache_addw((reg<<11)+0x620); // seh reg, reg
cache_addw(0x7c00+reg);
#else
cache_addw((reg<<11)+(16<<6)+0); // sll reg,reg,16
cache_addw(reg);
cache_addw((reg<<11)+(16<<6)+3); // sra reg,reg,16
cache_addw(reg);
#endif
} else {
cache_addw(0xffff); // andi reg, reg, 0xffff
cache_addw(0x3000+(reg<<5)+reg);
}
}
However there's still a problem... somewhere. I get an illegal instruction error. Blah.
Can someone else check the above code to make sure it's all good?
There are other three other instances of #if (_MIPS_ISA==MIPS32R2) || defined(PSP).
One seems to be complete, the other two are:
Code:
static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type)
...
...
#if (_MIPS_ISA==MIPS32R2) || defined(PSP)
case t_RORd:
*(Bit32u*)pos=0x00a41046; // rotr $v0, $a0, $a1
break;
#endif
Code:
static void cache_block_closing(Bit8u* block_start,Bitu block_size) {
#ifdef PSP
// writeback dcache and invalidate icache
Bit32u inval_start = ((Bit32u)block_start) & ~63;
Bit32u inval_end = (((Bit32u)block_start) + block_size + 64) & ~63;
for (;inval_start < inval_end; inval_start+=64) {
__builtin_allegrex_cache(0x1a, inval_start);
__builtin_allegrex_cache(0x08, inval_start);
}
#else
#ifdef A320
// cacheflush() is limited on MIPS32 Linux
// Although we specifiy start and size,
// the entire ICACHE/DCACHE is flushed :(
cacheflush(block_start, block_size, BCACHE);
#endif //A320
#endif
}
I think the first one may be okay.
The second one probably needs attention.
EDIT4: I've just added some cacheflush code but have not tested yet.
Well still not working but it's segmentation faulting now instead of illegal instruction
EDIT5: I've made the fixes to SRA instruction. I gave it an initial test but there's still a problem somewhere. :-(