mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-02-24 07:02:27 +01:00
byuu says: Changelog: - WS: fixed a major CPU bug where I was using the wrong bits for ModR/M's memory mode - WS: added grayscale PPU emulation (exceptionally buggy) GunPey now runs, as long as you add: eeprom name=save.ram size=0x800 to the manifest after importing with icarus. Right now, you can't control the game due to missing keypad polling. There's also a lot of glitchiness with the sprites. Seems like they're not getting properly cleared sometimes or something. Also, the PPU emulation is totally unrealistic bullshit. I decode and evaluate every single tile and sprite on every single pixel of output. No way in hell the hardware could ever come close to that. The speed's around 500fps without the insane sprite evaluations, and around 90fps with it. Obviously, I'll fix this in time. Nothing else seems to run that I've tried. Not even far enough to display any output whatsoever. Tried Langrisser Millenium, Rockman & Forte and Riviera. I really need to update icarus to try and encode eeprom/sram sizes, because that's going to break a lot of stuff if it's missing.
63 lines
1.9 KiB
C++
63 lines
1.9 KiB
C++
auto V30MZ::modRM() -> void {
|
|
auto data = fetch();
|
|
modrm.mem = data.bits(0,2);
|
|
modrm.reg = data.bits(3,5);
|
|
modrm.mod = data.bits(6,7);
|
|
|
|
if(modrm.mod == 0 && modrm.mem == 6) {
|
|
modrm.segment = segment(r.ds);
|
|
modrm.address = fetch(Word);
|
|
} else {
|
|
switch(modrm.mem) {
|
|
case 0: modrm.segment = segment(r.ds); modrm.address = r.bx + r.si; break;
|
|
case 1: modrm.segment = segment(r.ds); modrm.address = r.bx + r.di; break;
|
|
case 2: modrm.segment = segment(r.ss); modrm.address = r.bp + r.si; break;
|
|
case 3: modrm.segment = segment(r.ss); modrm.address = r.bp + r.di; break;
|
|
case 4: modrm.segment = segment(r.ds); modrm.address = r.si; break;
|
|
case 5: modrm.segment = segment(r.ds); modrm.address = r.di; break;
|
|
case 6: modrm.segment = segment(r.ss); modrm.address = r.bp; break;
|
|
case 7: modrm.segment = segment(r.ds); modrm.address = r.bx; break;
|
|
}
|
|
if(modrm.mod == 1) modrm.address += (int8)fetch(Byte);
|
|
if(modrm.mod == 2) modrm.address += (int16)fetch(Word);
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
auto V30MZ::getMem(Size size, uint offset) -> uint16 {
|
|
if(modrm.mod != 3) return read(size, modrm.segment, modrm.address + offset);
|
|
if(size == Byte) return *r.b[modrm.mem];
|
|
if(size == Word) return *r.w[modrm.mem];
|
|
unreachable;
|
|
}
|
|
|
|
auto V30MZ::setMem(Size size, uint16 data) -> void {
|
|
if(modrm.mod != 3) return write(size, modrm.segment, modrm.address, data);
|
|
if(size == Byte) *r.b[modrm.mem] = data;
|
|
if(size == Word) *r.w[modrm.mem] = data;
|
|
}
|
|
|
|
//
|
|
|
|
auto V30MZ::getReg(Size size) -> uint16 {
|
|
if(size == Byte) return *r.b[modrm.reg];
|
|
if(size == Word) return *r.w[modrm.reg];
|
|
unreachable;
|
|
}
|
|
|
|
auto V30MZ::setReg(Size size, uint16 data) -> void {
|
|
if(size == Byte) *r.b[modrm.reg] = data;
|
|
if(size == Word) *r.w[modrm.reg] = data;
|
|
}
|
|
|
|
//
|
|
|
|
auto V30MZ::getSeg() -> uint16 {
|
|
return *r.s[modrm.reg];
|
|
}
|
|
|
|
auto V30MZ::setSeg(uint16 data) -> void {
|
|
*r.s[modrm.reg] = data;
|
|
}
|