2016-02-02 10:51:17 +00:00
|
|
|
//ModRM functions
|
|
|
|
//d7-d6 => mod
|
|
|
|
//d5-d3 => reg
|
|
|
|
//d2-d0 => mem
|
|
|
|
|
|
|
|
auto V30MZ::getReg(Size size, uint8 modRM) -> uint16 {
|
2016-02-03 10:24:58 +00:00
|
|
|
return size == Byte ? r.byte(modRM >> 3) : r.word(modRM >> 3);
|
2016-02-02 10:51:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-02-03 10:24:58 +00:00
|
|
|
return segment(s) << 16 | a;
|
2016-02-02 10:51:17 +00:00
|
|
|
}
|
|
|
|
|
2016-02-03 10:24:58 +00:00
|
|
|
auto V30MZ::getMem(Size size, uint8 modRM) -> uint32 {
|
2016-02-02 10:51:17 +00:00
|
|
|
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);
|
|
|
|
}
|