ptitSeb
Serial Porter
@dgame: ok, fixed . Will be featured in the next alpha alpha build
Why didn't you use Shenmue as a test game, if you know what I meanSoul Calibur is my test game, I test improvement / regression mainly with this one, with the objectiv to have it FullSpeed with no sound stutering ... and it should not crash
You mean for the DIV0U/DIV0S/DIV1 instructions? I could perhaps try to come up with something. (I'm pretty interested in this sort of thing and I'd love to help out wherever I can.) Any hints as to how the M/Q/T flags are stored?And calc84maniac, do you also have a good DIV algo?
In fact, Reicast is doing some hle work here. It recognize standard division function, so it's the full division function I need.You mean for the DIV0U/DIV0S/DIV1 instructions? I could perhaps try to come up with something. (I'm pretty interested in this sort of thing and I'd love to help out wherever I can.) Any hints as to how the M/Q/T flags are stored?And calc84maniac, do you also have a good DIV algo?
Most of beat'em up games uses a lot of timing routines, so it ts very accurate to use them as a test games.Why didn't you use Shenmue as a test game, if you know what I meanSoul Calibur is my test game, I test improvement / regression mainly with this one, with the objectiv to have it FullSpeed with no sound stutering ... and it should not crash
Oh, well, wouldn't any old division function work, then? What bit size are the inputs and outputs, anyway? Also, do you care about the correct Q and M flag outputs?In fact, Reicast is doing some hle work here. It recognize standard division function, so it's the full division function I need.You mean for the DIV0U/DIV0S/DIV1 instructions? I could perhaps try to come up with something. (I'm pretty interested in this sort of thing and I'd love to help out wherever I can.) Any hints as to how the M/Q/T flags are stored?And calc84maniac, do you also have a good DIV algo?
Div is 32 bits -> 32 bits, signed and not signed. I tried a function I found on the net but it doesn't work. I think one of the emiter I coded must be wrong. I will code the thing in a small assembly file amd debug it also with gdb to check algo is right (I'll put a copy here also, but my current implementation doesn't works).Oh, well, wouldn't any old division function work, then? What bit size are the inputs and outputs, anyway? Also, do you care about the correct Q and M flag outputs?In fact, Reicast is doing some hle work here. It recognize standard division function, so it's the full division function I need.You mean for the DIV0U/DIV0S/DIV1 instructions? I could perhaps try to come up with something. (I'm pretty interested in this sort of thing and I'd love to help out wherever I can.) Any hints as to how the M/Q/T flags are stored?And calc84maniac, do you also have a good DIV algo?
I edited my previous post while you were replying, but I think I came up with an 8-instruction DIV1 method, which could certainly help with division methods not recognized by HLE.
Blame Graeme for being a lazy typist, but it looks like this routine only takes positive ("+ve") inputs.On Entry: num - is a signed numerator A (but +ve)
den - is a signed denominator B (but non-zero and +ve)
// rQM is a register that contains Q==M in bit 31.
// It's up to you whether you want to flush Q and M to SR, but this particular implementation doesn't care.
// If you do care, then DIV0U should set SR.M=0 and DIV0S should set SR.M=(Rm>>31).
// In addition, when you eventually flush Q you should set SR.Q=((rQM>>31)==SR.M).
// If you want to retrieve rQM from SR, just set rQM=((SR.Q==SR.M)<<31).
/* DIV0U Rm,Rn */
// Set Q==M to 1
mov rQM,#0x80000000
// Set T to 0
mov rT,#0x00000000
/* DIV0S Rm,Rn */
// Xor bit 31 of Rm and Rn
eor rQM,Rm,Rn
// Put result in T
mov rT,rQM,lsr #31
// Put inverted result in Q==M
mvn rQM,rQM
/* DIV1 Rm,Rn */
// If Q==M, r0=~Rm and C=1; else, r0=Rm and C=0
eors r0,Rm,rQM,asr #32
// Initialize output bit as (Q==M)^(Rn>>31)
eor rQM,rQM,Rn
// Shift Rn left by 1 and add T
add rD,rT,Rn,lsl #1
// Add or subtract Rm based on r0 and C
adcs rD,rD,r0
// If C is reset, invert output bit
mvncc rQM,rQM
// Set T to output bit (which happens to be Q==M)
mov rT,rQM,lsr #31
That looks really nice! I'm not even sure I have il level opcodes for div0/div1 right now. Time to add them I guessIt looks like the problem with that routine is with this:
Blame Graeme for being a lazy typist, but it looks like this routine only takes positive ("+ve") inputs.On Entry: num - is a signed numerator A (but +ve)
den - is a signed denominator B (but non-zero and +ve)
I'll give you the DIV0/DIV1 methods after I've worked on them some more, since I'd really like to see if I can whittle DIV1 down to 7 instructions or less.
Edit: Holy crap, I got DIV1 down to 6 instructions. Though I haven't tested it, I feel like this should work. I triple-checked all the possible flag inputs/outputs in a spreadsheet (and yes, I took into account that you get carry instead of borrow when you subtract by adding the negative).
Code in the spoiler:
// rQM is a register that contains Q==M in bit 31.
// It's up to you whether you want to flush Q and M to SR, but this particular implementation doesn't care.
// If you do care, then DIV0U should set SR.M=0 and DIV0S should set SR.M=(Rm>>31).
// In addition, when you eventually flush Q you should set SR.Q=((rQM>>31)==SR.M).
// If you want to retrieve rQM from SR, just set rQM=((SR.Q==SR.M)<1).
/* DIV0U Rm,Rn */
// Set Q==M to 1
mov rQM,#0x80000000
// Set T to 0
mov rT,#0x00000000
/* DIV0S Rm,Rn */
// Xor bit 31 of Rm and Rn
eor rQM,Rm,Rn
// Put result in T
mov rT,rQM,lsr #31
// Put inverted result in Q==M
mvn rQM,rQM
/* DIV1 Rm,Rn */
// If Q==M, r0=~Rm and C=1; else, r0=Rm and C=0
eors r0,Rm,rQM,asr #32
// Initialize output bit as (Q==M)^(Rn>>31)
eor rQM,rQM,Rn
// Shift Rn left by 1 and add T
add rD,rT,Rn,lsl #1
// Add or subtract Rm based on r0 and C
adcs rD,rD,r0
// If C is reset, invert output bit
mvncc rQM,rQM
// Set T to output bit (which happens to be Q==M)
mov rT,rQM,lsr #31
u64 rv;
((u32*)&rv)[0]=(r1<<1)|r2;
((u32*)&rv)[1]=r1>>31;
return rv;
I have issue with Crazy Taxi for now too. Not sure what it is yet.I cannot get this to work on my CC unit.
I have Crazy Taxi and the BIOS files named as instructed.
The game runs fine on my phone but whichever video driver I try on the Pandora I cannot get past the 50/60hz screen refresh option.
On some drivers after selecting the 60hz option the top of the screen is corrupted but on others the screen goes black and gets no further.
Any help would be much appreciated.
Alternatively, you could reuse the ADC method, since it's functionally equivalent to ADC with the same two arguments.So i should be ? I may have some emiter to create...
ORR(reg.mapg(op->rd),reg.mapg(op->rs2),reg.mapg(op->rs1),true, S_LSL, 1); //(C,rd)= rs1<<1 + (|) rs2
MOVW(reg.mapg(op->rd2),0); //clear rd2 (for ADC/MOVCS)
ADC(reg.mapg(op->rd2),reg.mapg(op->rd2),0); //rd2=C (or MOVCS rd2, 1)
Bah, the ORR seems to works, so I'll keep it like thatAlternatively, you could reuse the ADC method, since it's functionally equivalent to ADC with the same two arguments.So i should be ? I may have some emiter to create...
ORR(reg.mapg(op->rd),reg.mapg(op->rs2),reg.mapg(op->rs1),true, S_LSL, 1); //(C,rd)= rs1<<1 + (|) rs2
MOVW(reg.mapg(op->rd2),0); //clear rd2 (for ADC/MOVCS)
ADC(reg.mapg(op->rd2),reg.mapg(op->rd2),0); //rd2=C (or MOVCS rd2, 1)
Hrfm, looks like a brain fart. Well, there are quite a few broken games ;pHmm, this code kind of bothers me:
case shop_rocl:
{
ADD(reg.mapg(op->rd),reg.mapg(op->rs2),reg.mapg(op->rs1),1,true); //(C,rd)= rs1<<1 + (|) rs2
MOVW(reg.mapg(op->rd2),0); //clear rd2 (for ADC/MOVCS)
ADC(reg.mapg(op->rd2),reg.mapg(op->rd2),0); //rd2=C (or MOVCS rd2, 1)
}
break;
The carry output from the ADD instruction is from the addition only; the carry from the shift is lost, so the carry out is always 0. This can be fixed by changing the ADD to an OR. If this is really the case, I'm surprised a lot of stuff isn't broken. Unless I'm missing something here.
Edit: Stupid quick reply box ate the stuff after the codebox