MSXE6Timer.cc 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #include "MSXE6Timer.hh"
  2. #include "serialize.hh"
  3. namespace openmsx {
  4. MSXE6Timer::MSXE6Timer(const DeviceConfig& config)
  5. : MSXDevice(config)
  6. , reference(getCurrentTime())
  7. {
  8. }
  9. void MSXE6Timer::reset(EmuTime::param time)
  10. {
  11. reference.reset(time);
  12. }
  13. void MSXE6Timer::writeIO(word /*port*/, byte /*value*/, EmuTime::param time)
  14. {
  15. /*
  16. The Clock class rounds down time to its clock resolution.
  17. This is correct for the E6 timer, verified by running the following
  18. program in R800 mode:
  19. org &HC000
  20. di
  21. ld c,&HE6
  22. loop:
  23. out (&HE6),a
  24. in d,(c)
  25. jp z,loop
  26. ei
  27. ret
  28. It returns with D=1.
  29. */
  30. reference.advance(time);
  31. }
  32. byte MSXE6Timer::readIO(word port, EmuTime::param time)
  33. {
  34. return peekIO(port, time);
  35. }
  36. byte MSXE6Timer::peekIO(word port, EmuTime::param time) const
  37. {
  38. int counter = reference.getTicksTill(time);
  39. return (port & 1) ? ((counter >> 8) & 0xFF) : (counter & 0xFF);
  40. }
  41. template<typename Archive>
  42. void MSXE6Timer::serialize(Archive& ar, unsigned /*version*/)
  43. {
  44. ar.template serializeBase<MSXDevice>(*this);
  45. ar.serialize("reference", reference);
  46. }
  47. INSTANTIATE_SERIALIZE_METHODS(MSXE6Timer);
  48. REGISTER_MSXDEVICE(MSXE6Timer, "E6Timer");
  49. } // namespace openmsx