From: <m97...@us...> - 2010-06-22 18:24:59
|
Revision: 11541 http://openmsx.svn.sourceforge.net/openmsx/?rev=11541&view=rev Author: m9710797 Date: 2010-06-22 18:24:52 +0000 (Tue, 22 Jun 2010) Log Message: ----------- Added various VDP timing related info topics: - VDP_frame_count - VDP_cycle_in_frame - VDP_line_in_frame - VDP_cycle_in_line - VDP_msx_y_pos - VDP_msx_x256_pos - VDP_msx_x512_pos Most important is 'VDP_frame_count'. Before this patch we estimated frame count by dividing current time by the duration of one frame, but this doesn't work if the framerate can be switched (PAL/NTSC). The other info topics can be used to query the current scanline position. It can be queried in absolute numbers (in lines and cycles) or sometimes more convenient in 'MSX coordinates'. Modified Paths: -------------- openmsx/trunk/share/scripts/tas_tools.tcl openmsx/trunk/src/video/VDP.cc openmsx/trunk/src/video/VDP.hh Modified: openmsx/trunk/share/scripts/tas_tools.tcl =================================================================== --- openmsx/trunk/share/scripts/tas_tools.tcl 2010-06-21 01:16:50 UTC (rev 11540) +++ openmsx/trunk/share/scripts/tas_tools.tcl 2010-06-22 18:24:52 UTC (rev 11541) @@ -25,7 +25,7 @@ } proc framecount_current {} { - return [expr int([machine_info time] / [get_frame_time])] + return [machine_info VDP_frame_count] } proc framecount_update {} { Modified: openmsx/trunk/src/video/VDP.cc =================================================================== --- openmsx/trunk/src/video/VDP.cc 2010-06-21 01:16:50 UTC (rev 11540) +++ openmsx/trunk/src/video/VDP.cc 2010-06-22 18:24:52 UTC (rev 11541) @@ -28,6 +28,8 @@ #include "RendererFactory.hh" #include "Renderer.hh" #include "SimpleDebuggable.hh" +#include "InfoTopic.hh" +#include "TclObject.hh" #include "MSXMotherBoard.hh" #include "Reactor.hh" #include "MSXException.hh" @@ -37,6 +39,9 @@ #include <cstring> #include <cassert> +using std::string; +using std::vector; + namespace openmsx { class VDPRegDebug : public SimpleDebuggable @@ -79,6 +84,143 @@ }; +class VDPInfo : public InfoTopic +{ +public: + virtual void execute(const vector<TclObject*>& /*tokens*/, + TclObject& result) const + { + const Schedulable& schedulable = vdp; // resolve ambiguity + result.setInt(calc(schedulable.getCurrentTime())); + } + virtual string help(const vector<string>& /*tokens*/) const + { + return helpText; + } + virtual int calc(const EmuTime& time) const = 0; + +protected: + VDPInfo(VDP& vdp_, const string& name, const string& helpText_) + : InfoTopic(vdp_.getMotherBoard().getMachineInfoCommand(), + vdp_.getName() + '_' + name) + , vdp(vdp_) + , helpText(helpText_) {} + + VDP& vdp; + const string helpText; +}; + +class FrameCountInfo : public VDPInfo +{ +public: + FrameCountInfo(VDP& vdp) + : VDPInfo(vdp, "frame_count", + "The current frame number, starts counting at 0 " + "when MSX is powered up or reset.") {} + virtual int calc(const EmuTime& /*time*/) const + { + return vdp.frameCount; + } +}; + +class CycleInFrameInfo : public VDPInfo +{ +public: + CycleInFrameInfo(VDP& vdp) + : VDPInfo(vdp, "cycle_in_frame", + "The number of VDP cycles since the beginning of " + "the current frame. The VDP runs at 6 times the Z80 " + "clock frequency, so at approximately 21.5MHz.") {} + virtual int calc(const EmuTime& time) const + { + return vdp.getTicksThisFrame(time); + } +}; + +class LineInFrameInfo : public VDPInfo +{ +public: + LineInFrameInfo(VDP& vdp) + : VDPInfo(vdp, "line_in_frame", + "The absolute line number since the beginning of " + "the current frame. Goes from 0 till 262 (NTSC) or " + "313 (PAL). Note that this number includes the " + "border lines, use 'msx_y_pos' to get MSX " + "coordinates.") {} + virtual int calc(const EmuTime& time) const + { + return vdp.getTicksThisFrame(time) / VDP::TICKS_PER_LINE; + } +}; + +class CycleInLineInfo : public VDPInfo +{ +public: + CycleInLineInfo(VDP& vdp) + : VDPInfo(vdp, "cycle_in_line", + "The number of VDP cycles since the beginning of " + "the current line. See also 'cycle_in_frame'." + "Note that this includes the cycles in the border, " + "use 'msx_x256_pos' or 'msx_x512_pos' to get MSX " + "coordinates.") {} + virtual int calc(const EmuTime& time) const + { + return vdp.getTicksThisFrame(time) % VDP::TICKS_PER_LINE; + } +}; + +class MsxYPosInfo : public VDPInfo +{ +public: + MsxYPosInfo(VDP& vdp) + : VDPInfo(vdp, "msx_y_pos", + "Similar to 'line_in_frame', but expressed in MSX " + "coordinates. So lines in the top border have " + "negative coordinates, lines in the bottom border " + "have coordinates bigger or equal to 192 or 212.") {} + virtual int calc(const EmuTime& time) const + { + return (vdp.getTicksThisFrame(time) / VDP::TICKS_PER_LINE) - + vdp.getLineZero(); + } +}; + +class MsxX256PosInfo : public VDPInfo +{ +public: + MsxX256PosInfo(VDP& vdp) + : VDPInfo(vdp, "msx_x256_pos", + "Similar to 'cycle_in_frame', but expressed in MSX " + "coordinates. So a position in the left border has " + "a negative coordinate and a position in the right " + "border has a coordinated bigger or equal to 256. " + "See also 'msx_x512_pos'.") {} + virtual int calc(const EmuTime& time) const + { + return ((vdp.getTicksThisFrame(time) % VDP::TICKS_PER_LINE) - + vdp.getLeftSprites()) / 4; + } +}; + +class MsxX512PosInfo : public VDPInfo +{ +public: + MsxX512PosInfo(VDP& vdp) + : VDPInfo(vdp, "msx_x512_pos", + "Similar to 'cycle_in_frame', but expressed in " + "'narrow' (screen 7) MSX coordinates. So a position " + "in the left border has a negative coordinate and " + "a position in the right border has a coordinated " + "bigger or equal to 512. See also 'msx_x256_pos'.") {} + virtual int calc(const EmuTime& time) const + { + return ((vdp.getTicksThisFrame(time) % VDP::TICKS_PER_LINE) - + vdp.getLeftSprites()) / 2; + } +}; + + + VDP::VDP(MSXMotherBoard& motherBoard, const XMLElement& config) : MSXDevice(motherBoard, config) , Schedulable(motherBoard.getScheduler()) @@ -88,6 +230,13 @@ , vdpStatusRegDebug(new VDPStatusRegDebug(*this)) , vdpPaletteDebug (new VDPPaletteDebug (*this)) , vramPointerDebug (new VRAMPointerDebug (*this)) + , frameCountInfo (new FrameCountInfo (*this)) + , cycleInFrameInfo (new CycleInFrameInfo (*this)) + , lineInFrameInfo (new LineInFrameInfo (*this)) + , cycleInLineInfo (new CycleInLineInfo (*this)) + , msxYPosInfo (new MsxYPosInfo (*this)) + , msxX256PosInfo (new MsxX256PosInfo (*this)) + , msxX512PosInfo (new MsxX512PosInfo (*this)) , frameStartTime(Schedulable::getCurrentTime()) , irqVertical (motherBoard, getName() + ".IRQvertical") , irqHorizontal(motherBoard, getName() + ".IRQhorizontal") @@ -279,7 +428,9 @@ resetMasks(time); // Init scheduling. + frameCount = -1; frameStart(time); + assert(frameCount == 0); } void VDP::executeUntil(EmuTime::param time, int userData) @@ -493,6 +644,8 @@ // influences the frequency at which E/O toggles). void VDP::frameStart(EmuTime::param time) { + ++frameCount; + //cerr << "VDP::frameStart @ " << time << "\n"; // Toggle E/O. @@ -1280,8 +1433,10 @@ } +// version 1: initial version +// version 2: added frameCount template<typename Archive> -void VDP::serialize(Archive& ar, unsigned /*version*/) +void VDP::serialize(Archive& ar, unsigned version) { ar.template serializeBase<MSXDevice>(*this); ar.template serializeBase<Schedulable>(*this); @@ -1329,6 +1484,16 @@ ar.serialize("spriteChecker", *spriteChecker); // must come after displayMode ar.serialize("vram", *vram); // must come after controlRegs and after spriteChecker + if (ar.versionAtLeast(version, 2)) { + ar.serialize("frameCount", frameCount); + } else { + assert(ar.isLoader()); + // We could estimate the frameCount (assume framerate was + // constant the whole time). But I think it's better to have + // an obviously wrong value than an almost correct value. + frameCount = 0; + } + // externalVideo does not need serializing. It is set on load by the // external video source (e.g. PioneerLDControl). // Modified: openmsx/trunk/src/video/VDP.hh =================================================================== --- openmsx/trunk/src/video/VDP.hh 2010-06-21 01:16:50 UTC (rev 11540) +++ openmsx/trunk/src/video/VDP.hh 2010-06-22 18:24:52 UTC (rev 11541) @@ -22,6 +22,13 @@ class VDPStatusRegDebug; class VDPPaletteDebug; class VRAMPointerDebug; +class FrameCountInfo; +class CycleInFrameInfo; +class LineInFrameInfo; +class CycleInLineInfo; +class MsxYPosInfo; +class MsxX256PosInfo; +class MsxX512PosInfo; class CliComm; class Display; class RawFrame; @@ -77,7 +84,7 @@ /** Number of VDP clock ticks per second. */ - static const int TICKS_PER_SECOND = 21477270; + static const int TICKS_PER_SECOND = 3579545 * 6; // 21.5MHz; /** Number of VDP clock ticks per line. */ @@ -680,10 +687,18 @@ friend class VDPStatusRegDebug; friend class VDPPaletteDebug; friend class VRAMPointerDebug; + friend class FrameCountInfo; const std::auto_ptr<VDPRegDebug> vdpRegDebug; const std::auto_ptr<VDPStatusRegDebug> vdpStatusRegDebug; const std::auto_ptr<VDPPaletteDebug> vdpPaletteDebug; const std::auto_ptr<VRAMPointerDebug> vramPointerDebug; + const std::auto_ptr<FrameCountInfo> frameCountInfo; + const std::auto_ptr<CycleInFrameInfo> cycleInFrameInfo; + const std::auto_ptr<LineInFrameInfo> lineInFrameInfo; + const std::auto_ptr<CycleInLineInfo> cycleInLineInfo; + const std::auto_ptr<MsxYPosInfo> msxYPosInfo; + const std::auto_ptr<MsxX256PosInfo> msxX256PosInfo; + const std::auto_ptr<MsxX512PosInfo> msxX512PosInfo; /** Renderer that converts this VDP's state into an image. */ @@ -741,6 +756,13 @@ */ VdpVersion version; + /** The number of already fully rendered frames. + * Not used for actual emulation, only for 'frame_count' info topic. + * This value cannot be calculated from EmuTime because framerate is + * not constant (PAL/NTSC). + */ + int frameCount; + /** VDP ticks between start of frame and start of display. */ int displayStart; @@ -881,6 +903,7 @@ * is printed. */ bool warningPrinted; }; +SERIALIZE_CLASS_VERSION(VDP, 2); } // namespace openmsx This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |