2017-08-10 11:26:02 +00:00
|
|
|
auto V30MZ::instructionGroup1MemImm(Size size, bool sign) -> void {
|
2016-02-04 10:29:08 +00:00
|
|
|
modRM();
|
|
|
|
auto mem = getMem(size);
|
2016-02-16 09:27:55 +00:00
|
|
|
uint16 imm = 0;
|
|
|
|
if(sign) imm = (int8)fetch();
|
|
|
|
else if(size == Byte) imm = fetch();
|
|
|
|
else imm = fetch(Word);
|
2016-02-04 10:29:08 +00:00
|
|
|
switch(modrm.reg) {
|
2017-08-10 11:26:02 +00:00
|
|
|
case 0: setMem(size, ADD(size, mem, imm)); break;
|
|
|
|
case 1: setMem(size, OR (size, mem, imm)); break;
|
|
|
|
case 2: setMem(size, ADC(size, mem, imm)); break;
|
|
|
|
case 3: setMem(size, SBB(size, mem, imm)); break;
|
|
|
|
case 4: setMem(size, AND(size, mem, imm)); break;
|
|
|
|
case 5: setMem(size, SUB(size, mem, imm)); break;
|
|
|
|
case 6: setMem(size, XOR(size, mem, imm)); break;
|
|
|
|
case 7: SUB(size, mem, imm); break;
|
2016-02-04 10:29:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-10 11:26:02 +00:00
|
|
|
auto V30MZ::instructionGroup2MemImm(Size size, maybe<uint8> imm) -> void {
|
2016-02-04 10:29:08 +00:00
|
|
|
modRM();
|
|
|
|
auto mem = getMem(size);
|
|
|
|
if(!imm) {
|
|
|
|
wait(2);
|
|
|
|
imm = fetch();
|
|
|
|
}
|
|
|
|
switch(modrm.reg) {
|
2017-08-10 11:26:02 +00:00
|
|
|
case 0: setMem(size, ROL(size, mem, *imm)); break;
|
|
|
|
case 1: setMem(size, ROR(size, mem, *imm)); break;
|
|
|
|
case 2: setMem(size, RCL(size, mem, *imm)); break;
|
|
|
|
case 3: setMem(size, RCR(size, mem, *imm)); break;
|
|
|
|
case 4: setMem(size, SHL(size, mem, *imm)); break;
|
|
|
|
case 5: setMem(size, SHR(size, mem, *imm)); break;
|
|
|
|
case 6: setMem(size, SAL(size, mem, *imm)); break;
|
|
|
|
case 7: setMem(size, SAR(size, mem, *imm)); break;
|
2016-02-04 10:29:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-10 11:26:02 +00:00
|
|
|
auto V30MZ::instructionGroup3MemImm(Size size) -> void {
|
2016-02-04 10:29:08 +00:00
|
|
|
modRM();
|
|
|
|
auto mem = getMem(size);
|
|
|
|
switch(modrm.reg) {
|
2017-08-10 11:26:02 +00:00
|
|
|
case 0: AND(size, mem, fetch(size)); break;
|
2016-07-08 12:23:46 +00:00
|
|
|
case 1: warning("[V30MZ] GRP3.1"); break;
|
2017-08-10 11:26:02 +00:00
|
|
|
case 2: wait(2); setMem(size, NOT(size, mem)); break;
|
|
|
|
case 3: wait(2); setMem(size, NEG(size, mem)); break;
|
|
|
|
case 4: wait(2); setAcc(size * 2, MUL(size, getAcc(size), mem)); break;
|
|
|
|
case 5: wait(2); setAcc(size * 2, MULI(size, getAcc(size), mem)); break; break;
|
|
|
|
case 6: wait(size == Byte ? 15 : 23); setAcc(size * 2, DIV(size, getAcc(size * 2), mem)); break;
|
|
|
|
case 7: wait(size == Byte ? 17 : 24); setAcc(size * 2, DIVI(size, getAcc(size * 2), mem)); break;
|
2016-02-04 10:29:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-10 11:26:02 +00:00
|
|
|
auto V30MZ::instructionGroup4MemImm(Size size) -> void {
|
2016-02-04 10:29:08 +00:00
|
|
|
modRM();
|
|
|
|
switch(modrm.reg) {
|
2016-03-08 11:34:00 +00:00
|
|
|
case 0:
|
|
|
|
wait(2);
|
2017-08-10 11:26:02 +00:00
|
|
|
setMem(size, INC(size, getMem(size)));
|
2016-03-08 11:34:00 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
wait(2);
|
2017-08-10 11:26:02 +00:00
|
|
|
setMem(size, DEC(size, getMem(size)));
|
2016-03-08 11:34:00 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2016-07-08 12:23:46 +00:00
|
|
|
if(size == Byte) { warning("[V30MZ] GRP4.2"); break; }
|
2016-03-08 11:34:00 +00:00
|
|
|
wait(5);
|
|
|
|
push(r.ip);
|
|
|
|
r.ip = getMem(Word);
|
|
|
|
break;
|
|
|
|
case 3:
|
2016-07-08 12:23:46 +00:00
|
|
|
if(size == Byte) { warning("[V30MZ] GRP4.3"); break; }
|
2016-03-08 11:34:00 +00:00
|
|
|
wait(11);
|
|
|
|
push(r.cs);
|
|
|
|
push(r.ip);
|
|
|
|
r.ip = getMem(Word, 0);
|
|
|
|
r.cs = getMem(Word, 2);
|
|
|
|
break;
|
|
|
|
case 4:
|
2016-07-08 12:23:46 +00:00
|
|
|
if(size == Byte) { warning("[V30MZ] GRP4.4"); break; }
|
2016-03-08 11:34:00 +00:00
|
|
|
wait(4);
|
|
|
|
r.ip = getMem(Word);
|
|
|
|
break;
|
|
|
|
case 5:
|
2016-07-08 12:23:46 +00:00
|
|
|
if(size == Byte) { warning("[V30MZ] GRP4.5"); break; }
|
2016-03-08 11:34:00 +00:00
|
|
|
wait(9);
|
|
|
|
r.ip = getMem(Word, 0);
|
|
|
|
r.cs = getMem(Word, 2);
|
|
|
|
break;
|
|
|
|
case 6:
|
2016-07-08 12:23:46 +00:00
|
|
|
if(size == Byte) { warning("[V30MZ] GRP4.6"); break; }
|
2016-03-08 11:34:00 +00:00
|
|
|
wait(1);
|
|
|
|
push(getMem(Word));
|
|
|
|
break;
|
|
|
|
case 7:
|
2016-07-08 12:23:46 +00:00
|
|
|
warning("[V30MZ] GRP4.7");
|
2016-03-08 11:34:00 +00:00
|
|
|
break;
|
2016-02-04 10:29:08 +00:00
|
|
|
}
|
|
|
|
}
|