bsnes/higan/processor/v30mz/instructions-string.cpp

108 lines
2.2 KiB
C++

auto V30MZ::opInString(Size size) {
wait(5);
if(!repeat() || r.cx) {
auto data = in(size, r.dx);
write(size, r.es, r.di, data);
r.di += r.f.d ? -size : size;
if(!repeat() || !--r.cx) return;
state.prefix = true;
r.ip--;
}
}
auto V30MZ::opOutString(Size size) {
wait(6);
if(!repeat() || r.cx) {
auto data = read(size, segment(r.ds), r.si);
out(size, r.dx, data);
r.si += r.f.d ? -size : size;
if(!repeat() || !--r.cx) return;
state.prefix = true;
r.ip--;
}
}
auto V30MZ::opMoveString(Size size) {
wait(4);
if(!repeat() || r.cx) {
auto data = read(size, segment(r.ds), r.si);
write(size, r.es, r.di, data);
r.si += r.f.d ? -size : size;
r.di += r.f.d ? -size : size;
if(!repeat() || !--r.cx) return;
state.prefix = true;
r.ip--;
}
}
auto V30MZ::opCompareString(Size size) {
wait(5);
if(!repeat() || r.cx) {
auto x = read(size, segment(r.ds), r.si);
auto y = read(size, r.es, r.di);
r.si += r.f.d ? -size : size;
r.di += r.f.d ? -size : size;
alSub(size, x, y);
if(!repeat() || !--r.cx) return;
if(repeat() == RepeatWhileZero && r.f.z == 0) return;
if(repeat() == RepeatWhileNotZero && r.f.z == 1) return;
state.prefix = true;
r.ip--;
}
}
auto V30MZ::opStoreString(Size size) {
wait(2);
if(!repeat() || r.cx) {
write(size, r.es, r.di, getAcc(size));
r.di += r.f.d ? -size : size;
if(!repeat() || !--r.cx) return;
state.prefix = true;
r.ip--;
}
}
//ac lodsb
//ad lodsw
auto V30MZ::opLoadString(Size size) {
wait(2);
if(!repeat() || r.cx) {
setAcc(size, read(size, segment(r.ds), r.si));
r.si += r.f.d ? -size : size;
if(!repeat() || !--r.cx) return;
state.prefix = true;
r.ip--;
}
}
//ae scasb
//af scasw
auto V30MZ::opScanString(Size size) {
wait(3);
if(!repeat() || r.cx) {
auto x = getAcc(size);
auto y = read(size, r.es, r.di);
r.di += r.f.d ? -size : size;
alSub(size, x, y);
if(!repeat() || !--r.cx) return;
if(repeat() == RepeatWhileZero && r.f.z == 0) return;
if(repeat() == RepeatWhileNotZero && r.f.z == 1) return;
state.prefix = true;
r.ip--;
}
}