2016-02-04 10:29:08 +00:00
|
|
|
auto V30MZ::modRM() -> void {
|
2016-03-01 12:23:18 +00:00
|
|
|
auto data = fetch();
|
|
|
|
modrm.mem = data.bits(0,2);
|
|
|
|
modrm.reg = data.bits(3,5);
|
|
|
|
modrm.mod = data.bits(6,7);
|
2016-02-02 10:51:17 +00:00
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
if(modrm.mod == 0 && modrm.mem == 6) {
|
|
|
|
modrm.segment = segment(r.ds);
|
|
|
|
modrm.address = fetch(Word);
|
|
|
|
} else {
|
2016-03-01 12:23:18 +00:00
|
|
|
switch(modrm.mem) {
|
2016-02-04 10:29:08 +00:00
|
|
|
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;
|
2016-02-04 21:18:06 +00:00
|
|
|
case 6: modrm.segment = segment(r.ss); modrm.address = r.bp; break;
|
2016-02-04 10:29:08 +00:00
|
|
|
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);
|
|
|
|
}
|
2016-02-02 10:51:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
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;
|
2016-02-02 10:51:17 +00:00
|
|
|
}
|
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
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;
|
2016-02-02 10:51:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
auto V30MZ::getReg(Size size) -> uint16 {
|
|
|
|
if(size == Byte) return *r.b[modrm.reg];
|
|
|
|
if(size == Word) return *r.w[modrm.reg];
|
|
|
|
unreachable;
|
|
|
|
}
|
2016-02-02 10:51:17 +00:00
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
auto V30MZ::setReg(Size size, uint16 data) -> void {
|
|
|
|
if(size == Byte) *r.b[modrm.reg] = data;
|
|
|
|
if(size == Word) *r.w[modrm.reg] = data;
|
2016-02-02 10:51:17 +00:00
|
|
|
}
|
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
auto V30MZ::getSeg() -> uint16 {
|
|
|
|
return *r.s[modrm.reg];
|
2016-02-02 10:51:17 +00:00
|
|
|
}
|
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
auto V30MZ::setSeg(uint16 data) -> void {
|
|
|
|
*r.s[modrm.reg] = data;
|
2016-02-02 10:51:17 +00:00
|
|
|
}
|