auto V9938::serialize(serializer& s) -> void {
  s(vram);
  s(xram);
  s(pram);
  s(background);
  s(sprite);
  s(dac);
  s(op.counter);
  s(op.executing);
  s(op.ready);
  s(op.command);
  s(op.mxs);
  s(op.sx);
  s(op.sy);
  s(op.mxd);
  s(op.dx);
  s(op.dy);
  s(op.nx);
  s(op.ny);
  s(op.dix);
  s(op.diy);
  s(op.cr);
  s(op.match);
  s(op.found);
  s(op.eq);
  s(op.maj);
  s(op.logic);
  s(op.lgm);
  s(op.lsx);
  s(op.ldx);
  s(op.lnx);
  s(virq.enable);
  s(virq.pending);
  s(hirq.enable);
  s(hirq.pending);
  s(hirq.coincidence);
  s(lirq.enable);
  s(lirq.pending);
  s(io.vcounter);
  s(io.hcounter);
  s(io.controlLatch);
  s(io.controlValue);
  s(io.videoMode);
  s(io.timing);
  s(io.interlace);
  s(io.overscan);
  s(io.colorBackground);
  s(io.colorForeground);
  s(io.blinkColorBackground);
  s(io.blinkColorForeground);
  s(io.blinkPeriodBackground);
  s(io.blinkPeriodForeground);
  s(io.statusIndex);
  s(io.paletteIndex);
  s(io.paletteLatch);
  s(io.paletteValue);
  s(io.registerIndex);
  s(io.registerFixed);
  s(io.ramSelect);
  s(io.ramBank);
  s(io.ramLatch);
  s(io.vscroll);
  s(latch.timing);
  s(latch.interlace);
  s(latch.overscan);
  s(latch.field);
  s(latch.vscroll);
}

auto V9938::Background::serialize(serializer& s) -> void {
  s(io.nameTableAddress);
  s(io.patternTableAddress);
  s(io.colorTableAddress);
  s(io.hadjust);
  s(io.vadjust);
  s(latch.hadjust);
  s(latch.vadjust);
  s(output.color);
}

auto V9938::Sprite::serialize(serializer& s) -> void {
  for(auto& object : objects) {
    s(object.x);
    s(object.y);
    s(object.pattern);
    s(object.color);
    s(object.collision);
    s(object.priority);
  }
  s(io.nameTableAddress);
  s(io.patternTableAddress);
  s(io.zoom);
  s(io.size);
  s(io.disable);
  s(io.overflowIndex);
  s(io.overflow);
  s(io.collision);
  s(output.color);
}

auto V9938::DAC::serialize(serializer& s) -> void {
  s(io.enable);
  s(io.digitize);
  s(io.grayscale);
}
