bsnes/sfc/coprocessor/spc7110/alu.cpp

84 lines
1.9 KiB
C++
Raw Normal View History

auto SPC7110::alu_multiply() -> void {
add_clocks(30);
Update to v089r03 release. byuu says: Substantial improvements to SPC7110 emulation. Added all of the findings from http://byuu.org/temp/spc7110-mmio.txt that I understood. I also completely rewrote the RTC. We only had about ~40% of the chip emulated before. Turns out there's cool stuff like spare RAM, calendar disable, 12-hour mode, IRQs, IRQ masking, duty cycles, etc. So I went ahead and emulated all of it. The upper bits on hour+ don't work as nocash described though, not sure what doc he was reading. The Epson RTC-4513 manual I have doesn't explain any of the registers. The new RTC core also ticks seconds based on the emulated clock, and not on the system clock. This is going to suck for people wanting to keep the in-game clock synced with their computer, who also abuse fast forward and save states. Fast forward makes the clock run faster, and save states will jump the clock to the time it was at when you took the save state. (It will keep track of the number of seconds between unloading the game and loading it again, so time passes normally there.) This is required, however, and how I'm going to rearrange all of the RTCs for all systems. Any other method can be detected by the game, and is thus not faithful emulation. To help with this, I'll probably make an RTC time tool so that you can adjust the time when the emulator isn't running, but I don't intend to bundle that into bsnes. New state format bit-packs the RTCRAM values, and it also uses a 64-bit timestamp. So it's 16 bytes now instead of 20 bytes. S-RTC will drop from 16 to 12 when it's done. The RTC busy flag timing needs to be refined with more hardware tests, there's a slim chance of the game hanging on save at the moment. The SPC7110 ALU delays are emulated now, too. They may not be perfectly accurate, but they get the basic gist down. The only hack that needs to be removed now is the decompression busy flag. That's ... not going to be fun. I also redid the mouse emulation. I was polling the mouse position multiple times per latch. So it should be a bit more precise now, I hope. I read it regardless of latch state, dunno if that's good or not.
2012-05-16 00:27:34 +00:00
if(r482e & 1) {
//signed 16-bit x 16-bit multiplication
int16 r0 = (int16)(r4824 | r4825 << 8);
int16 r1 = (int16)(r4820 | r4821 << 8);
int result = r0 * r1;
Update to v089r03 release. byuu says: Substantial improvements to SPC7110 emulation. Added all of the findings from http://byuu.org/temp/spc7110-mmio.txt that I understood. I also completely rewrote the RTC. We only had about ~40% of the chip emulated before. Turns out there's cool stuff like spare RAM, calendar disable, 12-hour mode, IRQs, IRQ masking, duty cycles, etc. So I went ahead and emulated all of it. The upper bits on hour+ don't work as nocash described though, not sure what doc he was reading. The Epson RTC-4513 manual I have doesn't explain any of the registers. The new RTC core also ticks seconds based on the emulated clock, and not on the system clock. This is going to suck for people wanting to keep the in-game clock synced with their computer, who also abuse fast forward and save states. Fast forward makes the clock run faster, and save states will jump the clock to the time it was at when you took the save state. (It will keep track of the number of seconds between unloading the game and loading it again, so time passes normally there.) This is required, however, and how I'm going to rearrange all of the RTCs for all systems. Any other method can be detected by the game, and is thus not faithful emulation. To help with this, I'll probably make an RTC time tool so that you can adjust the time when the emulator isn't running, but I don't intend to bundle that into bsnes. New state format bit-packs the RTCRAM values, and it also uses a 64-bit timestamp. So it's 16 bytes now instead of 20 bytes. S-RTC will drop from 16 to 12 when it's done. The RTC busy flag timing needs to be refined with more hardware tests, there's a slim chance of the game hanging on save at the moment. The SPC7110 ALU delays are emulated now, too. They may not be perfectly accurate, but they get the basic gist down. The only hack that needs to be removed now is the decompression busy flag. That's ... not going to be fun. I also redid the mouse emulation. I was polling the mouse position multiple times per latch. So it should be a bit more precise now, I hope. I read it regardless of latch state, dunno if that's good or not.
2012-05-16 00:27:34 +00:00
r4828 = result;
r4829 = result >> 8;
r482a = result >> 16;
r482b = result >> 24;
} else {
//unsigned 16-bit x 16-bit multiplication
uint16 r0 = (uint16)(r4824 | r4825 << 8);
uint16 r1 = (uint16)(r4820 | r4821 << 8);
uint result = r0 * r1;
Update to v089r03 release. byuu says: Substantial improvements to SPC7110 emulation. Added all of the findings from http://byuu.org/temp/spc7110-mmio.txt that I understood. I also completely rewrote the RTC. We only had about ~40% of the chip emulated before. Turns out there's cool stuff like spare RAM, calendar disable, 12-hour mode, IRQs, IRQ masking, duty cycles, etc. So I went ahead and emulated all of it. The upper bits on hour+ don't work as nocash described though, not sure what doc he was reading. The Epson RTC-4513 manual I have doesn't explain any of the registers. The new RTC core also ticks seconds based on the emulated clock, and not on the system clock. This is going to suck for people wanting to keep the in-game clock synced with their computer, who also abuse fast forward and save states. Fast forward makes the clock run faster, and save states will jump the clock to the time it was at when you took the save state. (It will keep track of the number of seconds between unloading the game and loading it again, so time passes normally there.) This is required, however, and how I'm going to rearrange all of the RTCs for all systems. Any other method can be detected by the game, and is thus not faithful emulation. To help with this, I'll probably make an RTC time tool so that you can adjust the time when the emulator isn't running, but I don't intend to bundle that into bsnes. New state format bit-packs the RTCRAM values, and it also uses a 64-bit timestamp. So it's 16 bytes now instead of 20 bytes. S-RTC will drop from 16 to 12 when it's done. The RTC busy flag timing needs to be refined with more hardware tests, there's a slim chance of the game hanging on save at the moment. The SPC7110 ALU delays are emulated now, too. They may not be perfectly accurate, but they get the basic gist down. The only hack that needs to be removed now is the decompression busy flag. That's ... not going to be fun. I also redid the mouse emulation. I was polling the mouse position multiple times per latch. So it should be a bit more precise now, I hope. I read it regardless of latch state, dunno if that's good or not.
2012-05-16 00:27:34 +00:00
r4828 = result;
r4829 = result >> 8;
r482a = result >> 16;
r482b = result >> 24;
}
r482f &= 0x7f;
}
auto SPC7110::alu_divide() -> void {
add_clocks(40);
Update to v089r03 release. byuu says: Substantial improvements to SPC7110 emulation. Added all of the findings from http://byuu.org/temp/spc7110-mmio.txt that I understood. I also completely rewrote the RTC. We only had about ~40% of the chip emulated before. Turns out there's cool stuff like spare RAM, calendar disable, 12-hour mode, IRQs, IRQ masking, duty cycles, etc. So I went ahead and emulated all of it. The upper bits on hour+ don't work as nocash described though, not sure what doc he was reading. The Epson RTC-4513 manual I have doesn't explain any of the registers. The new RTC core also ticks seconds based on the emulated clock, and not on the system clock. This is going to suck for people wanting to keep the in-game clock synced with their computer, who also abuse fast forward and save states. Fast forward makes the clock run faster, and save states will jump the clock to the time it was at when you took the save state. (It will keep track of the number of seconds between unloading the game and loading it again, so time passes normally there.) This is required, however, and how I'm going to rearrange all of the RTCs for all systems. Any other method can be detected by the game, and is thus not faithful emulation. To help with this, I'll probably make an RTC time tool so that you can adjust the time when the emulator isn't running, but I don't intend to bundle that into bsnes. New state format bit-packs the RTCRAM values, and it also uses a 64-bit timestamp. So it's 16 bytes now instead of 20 bytes. S-RTC will drop from 16 to 12 when it's done. The RTC busy flag timing needs to be refined with more hardware tests, there's a slim chance of the game hanging on save at the moment. The SPC7110 ALU delays are emulated now, too. They may not be perfectly accurate, but they get the basic gist down. The only hack that needs to be removed now is the decompression busy flag. That's ... not going to be fun. I also redid the mouse emulation. I was polling the mouse position multiple times per latch. So it should be a bit more precise now, I hope. I read it regardless of latch state, dunno if that's good or not.
2012-05-16 00:27:34 +00:00
if(r482e & 1) {
//signed 32-bit x 16-bit division
int32 dividend = (int32)(r4820 | r4821 << 8 | r4822 << 16 | r4823 << 24);
int16 divisor = (int16)(r4826 | r4827 << 8);
int32 quotient;
int16 remainder;
if(divisor) {
quotient = (int32)(dividend / divisor);
remainder = (int32)(dividend % divisor);
} else {
//illegal division by zero
quotient = 0;
remainder = dividend;
}
r4828 = quotient;
r4829 = quotient >> 8;
r482a = quotient >> 16;
r482b = quotient >> 24;
r482c = remainder;
r482d = remainder >> 8;
} else {
//unsigned 32-bit x 16-bit division
uint32 dividend = (uint32)(r4820 | r4821 << 8 | r4822 << 16 | r4823 << 24);
uint16 divisor = (uint16)(r4826 | r4827 << 8);
uint32 quotient;
uint16 remainder;
if(divisor) {
quotient = (uint32)(dividend / divisor);
remainder = (uint16)(dividend % divisor);
} else {
//illegal division by zero
quotient = 0;
remainder = dividend;
}
r4828 = quotient;
r4829 = quotient >> 8;
r482a = quotient >> 16;
r482b = quotient >> 24;
r482c = remainder;
r482d = remainder >> 8;
}
r482f &= 0x7f;
}