mirror of https://github.com/bsnes-emu/bsnes.git
61 lines
1.6 KiB
C++
61 lines
1.6 KiB
C++
|
//ModRM functions
|
||
|
//d7-d6 => mod
|
||
|
//d5-d3 => reg
|
||
|
//d2-d0 => mem
|
||
|
|
||
|
auto V30MZ::getReg(Size size, uint8 modRM) -> uint16 {
|
||
|
if(size == Byte) return r.byte(modRM >> 3);
|
||
|
if(size == Word) return r.word(modRM >> 3);
|
||
|
unreachable;
|
||
|
}
|
||
|
|
||
|
auto V30MZ::setReg(Size size, uint8 modRM, uint16 data) -> void {
|
||
|
if(size == Byte) r.byte(modRM >> 3) = data;
|
||
|
if(size == Word) r.word(modRM >> 3) = data;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
|
||
|
auto V30MZ::getSeg(uint8 modRM) -> uint16 {
|
||
|
return r.segment(modRM >> 3);
|
||
|
}
|
||
|
|
||
|
auto V30MZ::setSeg(uint8 modRM, uint16 data) -> void {
|
||
|
r.segment(modRM >> 3) = data;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
|
||
|
auto V30MZ::getMemAddress(uint8 modRM) -> uint32 {
|
||
|
if((modRM & 0xc7) == 0x06) return r.ds << 16 | fetch(Word);
|
||
|
|
||
|
uint16 s = 0, a = 0;
|
||
|
if((modRM & 0xc0) == 0x40) a = (int8)fetch(Byte);
|
||
|
if((modRM & 0xc0) == 0x80) a = (int16)fetch(Word);
|
||
|
|
||
|
switch(modRM & 7) {
|
||
|
case 0: s = r.ds; a += r.bx + r.si; break;
|
||
|
case 1: s = r.ds; a += r.bx + r.di; break;
|
||
|
case 2: s = r.ss; a += r.bp + r.si; break;
|
||
|
case 3: s = r.ss; a += r.bp + r.di; break;
|
||
|
case 4: s = r.ds; a += r.si; break;
|
||
|
case 5: s = r.ds; a += r.di; break;
|
||
|
case 6: s = r.ss; a += r.bp; break;
|
||
|
case 7: s = r.ds; a += r.bx; break;
|
||
|
}
|
||
|
|
||
|
return s << 16 | a;
|
||
|
}
|
||
|
|
||
|
auto V30MZ::getMem(Size size, uint8 modRM) -> uint16 {
|
||
|
if(modRM >= 0xc0) return getReg(size, modRM << 3);
|
||
|
auto addr = getMemAddress(modRM);
|
||
|
return read(size, addr >> 16, addr);
|
||
|
}
|
||
|
|
||
|
auto V30MZ::setMem(Size size, uint8 modRM, uint16 data) -> void {
|
||
|
if(modRM >= 0xc0) return setReg(size, modRM << 3, data);
|
||
|
auto addr = getMemAddress(modRM);
|
||
|
return write(size, addr >> 16, addr, data);
|
||
|
}
|