32namespace VDPAccessSlots {
78 void powerUp(EmuTime::param time)
override;
79 void reset(EmuTime::param time)
override;
80 [[nodiscard]]
byte readIO(
word port, EmuTime::param time)
override;
81 [[nodiscard]]
byte peekIO(
word port, EmuTime::param time)
const override;
82 void writeIO(
word port,
byte value, EmuTime::param time)
override;
88 [[nodiscard]]
byte peekStatusReg(
byte reg, EmuTime::param time)
const;
106 return (version & VM_MSX1) != 0;
113 return (version & VM_PAL) != 0;
120 return (version & VM_NO_MIRRORING) != 0;
127 return (version & VM_PALCOL_MIRRORING) != 0;
134 return (version & VM_VRAM_REMAPPING) != 0;
140 [[nodiscard]]
inline bool hasYJK()
const {
141 return (version & VM_YJK) != 0;
148 [[nodiscard]] std::array<std::array<uint8_t, 3>, 16>
getMSX1Palette()
const;
174 return superimposing;
180 return *spriteChecker;
187 return (controlRegs[8] & 0x20) == 0;
205 return controlRegs[7] >> 4;
217 byte reg7 = controlRegs[7];
229 return controlRegs[12] >> 4;
236 return controlRegs[12] & 0x0F;
248 return controlRegs[4] << 11;
252 return (controlRegs[10] << 14) | (controlRegs[3] << 6);
256 return controlRegs[2] << 10;
260 return controlRegs[6] << 11;
264 return (controlRegs[11] << 15) | (controlRegs[5] << 7);
272 [[nodiscard]]
inline uint16_t
getPalette(
unsigned index)
const {
273 return palette[index];
275 [[nodiscard]]
inline std::span<const uint16_t, 16>
getPalette()
const {
293 return isDisplayArea && displayEnabled;
301 return displayEnabled &&
311 return displayEnabled && spriteEnabled;
318 return spriteEnabled;
325 return controlRegs[23];
334 return controlRegs[27];
343 return controlRegs[26];
352 return (controlRegs[25] & 0x02) != 0;
362 return (controlRegs[25] & 0x01) && (controlRegs[2] & 0x20);
369 return (controlRegs[2] >> 5) & 3;
410 return (controlRegs[1] & 4) != 0;
426 return (controlRegs[9] & 4) != 0;
433 return (statusReg2 & 2) != 0;
450 return (((~controlRegs[9] & 4) << 6) | ((statusReg2 & 2) << 7)) &
464 return (!p.state) << 8;
481 if (blinkCount == 0) {
482 return {blinkState, blinkCount};
485 unsigned evenLen = ((controlRegs[13] >> 4) & 0x0F) * 10;
486 unsigned oddLen = ((controlRegs[13] >> 0) & 0x0F) * 10;
487 unsigned totalLen = evenLen + oddLen;
488 assert(totalLen != 0);
491 bool resultState = blinkState;
499 int newCount = blinkCount - narrow<int>(line);
502 resultState = !resultState;
503 newCount += narrow<int>(oddLen);
506 resultState = !resultState;
507 newCount += narrow<int>(evenLen);
508 assert(newCount > 0);
511 return {resultState, newCount};
522 return frameStartTime.
getTime();
528 return ((controlRegs[1] & 2) << 2) + 8;
534 return controlRegs[1] & 1;
541 return (controlRegs[25] & 0x40) != 0;
547 return palTiming ? 313 : 262;
554 return controlRegs[9] & 0x80 ? 212 : 192;
573 return time >= frameStartTime.
getTime() &&
581 return horizontalAdjust;
592 return 100 + 102 + 56
593 + (horizontalAdjust - 7) * 4
638 statusReg0 = (statusReg0 & 0x80) | (value & 0x7F);
645 return (controlRegs[8] & 8) != 0;
651 externalVideo = externalSource;
657 return brokenCmdTiming;
674 EmuTime::param time, EmuTime::param limit)
const;
701 int LARGEST_STALL = 184 + 2 * 70;
705 syncCmdDone.setSyncPoint(
t);
708 template<
typename Archive>
709 void serialize(Archive& ar,
unsigned version);
715 static constexpr unsigned VM_MSX1 = 1;
716 static constexpr unsigned VM_PAL = 2;
717 static constexpr unsigned VM_NO_MIRRORING = 4;
718 static constexpr unsigned VM_PALCOL_MIRRORING = 8;
719 static constexpr unsigned VM_VRAM_REMAPPING = 16;
720 static constexpr unsigned VM_TOSHIBA_PALETTE = 32;
721 static constexpr unsigned VM_YJK = 64;
722 static constexpr unsigned VM_YM2220_PALETTE = 128;
730 TMS99X8A = VM_MSX1 | VM_PALCOL_MIRRORING | VM_VRAM_REMAPPING,
733 TMS9929A = VM_MSX1 | VM_PALCOL_MIRRORING | VM_VRAM_REMAPPING | VM_PAL,
736 TMS9129 = VM_MSX1 | VM_PAL,
742 T6950PAL = VM_MSX1 | VM_TOSHIBA_PALETTE | VM_NO_MIRRORING | VM_PAL,
745 T6950NTSC = VM_MSX1 | VM_TOSHIBA_PALETTE | VM_NO_MIRRORING,
748 T7937APAL = VM_MSX1 | VM_TOSHIBA_PALETTE | VM_PAL,
751 T7937ANTSC = VM_MSX1 | VM_TOSHIBA_PALETTE,
754 YM2220PAL = VM_MSX1 | VM_YM2220_PALETTE | VM_PALCOL_MIRRORING | VM_PAL,
757 YM2220NTSC = VM_MSX1 | VM_YM2220_PALETTE | VM_PALCOL_MIRRORING,
772 ~SyncBase() =
default;
775 struct SyncVSync final :
public SyncBase {
776 explicit SyncVSync(
VDP& vdp) : SyncBase(vdp) {}
777 void executeUntil(EmuTime::param time)
override {
783 struct SyncDisplayStart final :
public SyncBase {
784 explicit SyncDisplayStart(
VDP& vdp) : SyncBase(vdp) {}
785 void executeUntil(EmuTime::param time)
override {
786 auto& vdp =
OUTER(
VDP, syncDisplayStart);
787 vdp.execDisplayStart(time);
791 struct SyncVScan final :
public SyncBase {
792 explicit SyncVScan(
VDP& vdp) : SyncBase(vdp) {}
793 void executeUntil(EmuTime::param time)
override {
799 struct SyncHScan final :
public SyncBase {
800 explicit SyncHScan(
VDP& vdp) : SyncBase(vdp) {}
801 void executeUntil(EmuTime::param )
override {
807 struct SyncHorAdjust final :
public SyncBase {
808 explicit SyncHorAdjust(
VDP& vdp) : SyncBase(vdp) {}
809 void executeUntil(EmuTime::param time)
override {
810 auto& vdp =
OUTER(
VDP, syncHorAdjust);
811 vdp.execHorAdjust(time);
815 struct SyncSetMode final :
public SyncBase {
816 explicit SyncSetMode(
VDP& vdp) : SyncBase(vdp) {}
817 void executeUntil(EmuTime::param time)
override {
818 auto& vdp =
OUTER(
VDP, syncSetMode);
819 vdp.execSetMode(time);
823 struct SyncSetBlank final :
public SyncBase {
824 explicit SyncSetBlank(
VDP& vdp) : SyncBase(vdp) {}
825 void executeUntil(EmuTime::param time)
override {
826 auto& vdp =
OUTER(
VDP, syncSetBlank);
827 vdp.execSetBlank(time);
831 struct SyncSetSprites final :
public SyncBase {
832 explicit SyncSetSprites(
VDP& vdp) : SyncBase(vdp) {}
833 void executeUntil(EmuTime::param time)
override {
834 auto& vdp =
OUTER(
VDP, syncSetSprites);
835 vdp.execSetSprites(time);
839 struct SyncCpuVramAccess final :
public SyncBase {
840 explicit SyncCpuVramAccess(
VDP& vdp) : SyncBase(vdp) {}
841 void executeUntil(EmuTime::param time)
override {
842 auto& vdp =
OUTER(
VDP, syncCpuVramAccess);
843 vdp.execCpuVramAccess(time);
847 struct SyncCmdDone final :
public SyncBase {
848 explicit SyncCmdDone(
VDP& vdp) : SyncBase(vdp) {}
849 void executeUntil(EmuTime::param time)
override {
850 auto& vdp =
OUTER(
VDP, syncCmdDone);
851 vdp.execSyncCmdDone(time);
855 void execVSync(EmuTime::param time);
856 void execDisplayStart(EmuTime::param time);
857 void execVScan(EmuTime::param time);
859 void execHorAdjust(EmuTime::param time);
860 void execSetMode(EmuTime::param time);
861 void execSetBlank(EmuTime::param time);
862 void execSetSprites(EmuTime::param time);
863 void execCpuVramAccess(EmuTime::param time);
864 void execSyncCmdDone(EmuTime::param time);
869 [[nodiscard]]
int getVerticalAdjust()
const {
870 return (controlRegs[18] >> 4) ^ 0x07;
882 [[nodiscard]]
inline bool getHR(
int ticksThisFrame)
const {
888 static constexpr int HBLANK_LEN_TXT = 404;
892 static constexpr int HBLANK_LEN_GFX = 312;
894 < (displayMode.
isTextMode() ? HBLANK_LEN_TXT : HBLANK_LEN_GFX);
898 void preVideoSystemChange() noexcept override;
899 void postVideoSystemChange() noexcept override;
911 void resetMasks(EmuTime::param time);
916 void frameStart(EmuTime::param time);
925 void scheduleDisplayStart(EmuTime::param time);
932 void scheduleVScan(EmuTime::param time);
939 void scheduleHScan(EmuTime::param time);
943 void vramWrite(
byte value, EmuTime::param time);
947 [[nodiscard]]
byte vramRead(EmuTime::param time);
950 void scheduleCpuVramAccess(
bool isRead,
byte write, EmuTime::param time);
951 void executeCpuVramAccess(EmuTime::param time);
955 [[nodiscard]]
byte readStatusReg(
byte reg, EmuTime::param time);
959 void syncAtNextLine(SyncBase& type, EmuTime::param time);
963 void createRenderer();
968 void updateNameBase(EmuTime::param time);
973 void updateColorBase(EmuTime::param time);
978 void updatePatternBase(EmuTime::param time);
983 void updateSpriteAttributeBase(EmuTime::param time);
988 void updateSpritePatternBase(EmuTime::param time);
993 void updateDisplayMode(DisplayMode newMode,
bool cmdBit, EmuTime::param time);
996 void update(const Setting&
setting) noexcept override;
1000 EnumSetting<
bool>& cmdTiming;
1001 EnumSetting<
bool>& tooFastAccess;
1003 struct RegDebug final : SimpleDebuggable {
1004 explicit RegDebug(
VDP& vdp);
1005 [[nodiscard]]
byte read(
unsigned address)
override;
1006 void write(
unsigned address,
byte value, EmuTime::param time)
override;
1009 struct StatusRegDebug final : SimpleDebuggable {
1010 explicit StatusRegDebug(
VDP& vdp);
1011 [[nodiscard]]
byte read(
unsigned address, EmuTime::param time)
override;
1012 } vdpStatusRegDebug;
1014 struct PaletteDebug final : SimpleDebuggable {
1015 explicit PaletteDebug(
VDP& vdp);
1016 [[nodiscard]]
byte read(
unsigned address)
override;
1017 void write(
unsigned address,
byte value, EmuTime::param time)
override;
1020 struct VRAMPointerDebug final : SimpleDebuggable {
1021 explicit VRAMPointerDebug(
VDP& vdp);
1022 [[nodiscard]]
byte read(
unsigned address)
override;
1023 void write(
unsigned address,
byte value, EmuTime::param time)
override;
1026 struct RegisterLatchStatusDebug final : SimpleDebuggable {
1027 explicit RegisterLatchStatusDebug(
VDP& vdp);
1028 [[nodiscard]]
byte read(
unsigned address)
override;
1029 } registerLatchStatusDebug;
1031 struct VramAccessStatusDebug final : SimpleDebuggable {
1032 explicit VramAccessStatusDebug(
VDP& vdp);
1033 [[nodiscard]]
byte read(
unsigned address)
override;
1034 } vramAccessStatusDebug;
1036 struct PaletteLatchStatusDebug final : SimpleDebuggable {
1037 explicit PaletteLatchStatusDebug(
VDP& vdp);
1038 [[nodiscard]]
byte read(
unsigned address)
override;
1039 } paletteLatchStatusDebug;
1041 struct DataLatchDebug final : SimpleDebuggable {
1042 explicit DataLatchDebug(
VDP& vdp);
1043 [[nodiscard]]
byte read(
unsigned address)
override;
1046 class Info :
public InfoTopic {
1048 void execute(std::span<const TclObject> tokens,
1049 TclObject& result)
const override;
1050 [[nodiscard]] std::string help(std::span<const TclObject> tokens)
const override;
1051 [[nodiscard]]
virtual int calc(
const EmuTime& time)
const = 0;
1053 Info(
VDP& vdp_,
const std::string& name, std::string helpText_);
1056 const std::string helpText;
1059 struct FrameCountInfo final :
Info {
1060 explicit FrameCountInfo(
VDP& vdp);
1061 [[nodiscard]]
int calc(
const EmuTime& time)
const override;
1064 struct CycleInFrameInfo final :
Info {
1065 explicit CycleInFrameInfo(
VDP& vdp);
1066 [[nodiscard]]
int calc(
const EmuTime& time)
const override;
1069 struct LineInFrameInfo final :
Info {
1070 explicit LineInFrameInfo(
VDP& vdp);
1071 [[nodiscard]]
int calc(
const EmuTime& time)
const override;
1074 struct CycleInLineInfo final :
Info {
1075 explicit CycleInLineInfo(
VDP& vdp);
1076 [[nodiscard]]
int calc(
const EmuTime& time)
const override;
1079 struct MsxYPosInfo final :
Info {
1080 explicit MsxYPosInfo(
VDP& vdp);
1081 [[nodiscard]]
int calc(
const EmuTime& time)
const override;
1084 struct MsxX256PosInfo final :
Info {
1085 explicit MsxX256PosInfo(
VDP& vdp);
1086 [[nodiscard]]
int calc(
const EmuTime& time)
const override;
1089 struct MsxX512PosInfo final :
Info {
1090 explicit MsxX512PosInfo(
VDP& vdp);
1091 [[nodiscard]]
int calc(
const EmuTime& time)
const override;
1096 std::unique_ptr<Renderer> renderer;
1100 std::unique_ptr<VDPCmdEngine> cmdEngine;
1104 std::unique_ptr<SpriteChecker> spriteChecker;
1108 std::unique_ptr<VDPVRAM> vram;
1113 const RawFrame* externalVideo;
1120 const RawFrame* superimposing;
1136 EmuTime displayStartSyncTime;
1140 EmuTime vScanSyncTime;
1144 EmuTime hScanSyncTime;
1146 TclCallback tooFastCallback;
1178 int horizontalScanOffset;
1183 int horizontalAdjust;
1187 std::array<byte, 32> controlRegs;
1193 byte controlRegMask;
1201 std::array<byte, 32> controlValueMasks;
1215 std::array<uint16_t, 16> palette;
1231 bool interlaced =
false;
1270 bool registerDataStored;
1274 bool paletteDataStored;
1288 bool cpuVramReqIsRead;
1289 bool pendingCpuAccess;
1294 bool cpuExtendedVram;
1301 DisplayMode displayMode;
1307 bool displayEnabled;
1319 bool warningPrinted =
false;
1322 bool brokenCmdTiming;
1323 bool allowTooFastAccess;
1327 const byte fixedVDPIOdelayCycles;
static constexpr EmuDuration duration(unsigned ticks)
Calculates the duration of the given number of ticks at this clock's frequency.
constexpr unsigned getTicksTill_fast(EmuTime::param e) const
Same as above, only faster, Though the time interval may not be too large.
constexpr EmuTime::param getTime() const
Gets the time at which the last clock tick occurred.
Represents a VDP display mode.
constexpr bool isTextMode() const
Is the current mode a text mode? Text1 and Text2 are text modes.
constexpr byte getByte() const
Get the display mode as a byte: YAE YJK M5..M1 combined.
constexpr int getSpriteMode(bool isMSX1) const
Get the sprite mode of this display mode.
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Scheduler & getScheduler() const
EmuTime::param getCurrentTime() const
Generic Gang-of-Four Observer class, templatized edition.
A post processor builds the frame that is displayed from the MSX frame, while applying effects such a...
A video frame as output by the VDP scanline conversion unit, before any postprocessing filters are ap...
void setSyncPoint(EmuTime::param timestamp)
bool pendingSyncPoint() const
virtual byte read(unsigned address, EmuTime::param time)
byte read(unsigned address) override
void write(unsigned address, byte value) override
VDP-VRAM access slot calculator, meant to be used in the inner loops of the VDPCmdEngine commands.
Manages VRAM contents and synchronizes the various users of the VRAM.
Unified implementation of MSX Video Display Processors (VDPs).
int getHorizontalAdjust() const
This is a combination of the (horizontal) set adjust register and the YJK-mode bit.
bool getEvenOdd() const
Is the even or odd field being displayed?
int getLinesPerFrame() const
Gets the number of lines per frame.
int getNumberOfLines() const
Gets the number of display lines per screen.
unsigned getEvenOddMask() const
Expresses the state of even/odd page interchange in a mask on the line number.
bool spritesEnabled() const
Are sprites enabled?
int getSpriteSize() const
Gets the sprite size in pixels (8/16).
int getLeftBackground() const
Gets the number of VDP clock ticks between start of line and the time when the background pixel with ...
SpriteChecker & getSpriteChecker()
Get the sprite checker for this VDP.
bool getBrokenCmdTiming() const
Value of the cmdTiming setting, true means commands have infinite speed.
int getNameTableBase() const
Get address of name table (only for debugger)
bool isEvenOddEnabled() const
Get even/odd page alternation status.
void writeIO(word port, byte value, EmuTime::param time) override
Write a byte to a given IO port at a certain time to this device.
void changeRegister(byte reg, byte val, EmuTime::param time)
VDP control register has changed, work out the consequences.
void scheduleCmdSync(EmuTime t)
Only used when there are commandExecuting-probe listeners.
byte peekRegister(unsigned address) const
bool spritesEnabledRegister() const
Still faster variant (just looks at the sprite-enabled-bit).
BlinkStateCount calculateLineBlinkState(unsigned line) const
static constexpr int TICKS_PER_SECOND
Number of VDP clock ticks per second.
VDPVRAM & getVRAM()
Get the VRAM object for this VDP.
bool isFastBlinkEnabled() const
Get 'fast-blink' status.
std::array< std::array< uint8_t, 3 >, 16 > getMSX1Palette() const
Get the (fixed) palette for this MSX1 VDP.
PostProcessor * getPostProcessor() const
Used by Video9000 to be able to couple the VDP and V9990 output.
int getSpritePatternTableBase() const
Get address of pattern table (only for debugger)
bool isVDPwithPALonly() const
Is this a VDP only capable of PAL?
const RawFrame * isSuperimposing() const
Are we currently superimposing? In case of superimpose, returns a pointer to the to-be-superimposed f...
void getExtraDeviceInfo(TclObject &result) const override
bool getCmdBit() const
Are commands possible in non Graphic modes? (V9958 only)
VDPAccessSlots::Calculator getAccessSlotCalculator(EmuTime::param time, EmuTime::param limit) const
Same as getAccessSlot(), but it can be much faster for repeated calls, e.g.
void reset(EmuTime::param time) override
This method is called on reset.
void setPalette(unsigned index, word grb, EmuTime::param time)
Sets a palette entry.
bool isBorderMasked() const
Gets the current border mask setting.
byte getStatusReg0() const
Should only be used by SpriteChecker.
bool spritesEnabledFast() const
Same as spritesEnabled(), but may only be called in sprite mode 1 or 2.
int getForegroundColor() const
Gets the current foreground color.
static constexpr int TICKS_PER_LINE
Number of VDP clock ticks per line.
int getBlinkBackgroundColor() const
Gets the current blinking color for blinking text.
int getTicksPerFrame() const
Gets the number of VDP clock ticks (21MHz) per frame.
bool isInsideFrame(EmuTime::param time) const
Is the given timestamp inside the current frame? Mainly useful for debugging, because relevant timest...
void serialize(Archive &ar, unsigned version)
unsigned getEvenOddMask(int line) const
Similar to the above getEvenOddMask() method, but can also be called when 'isFastBlinkEnabled() == tr...
void setSpriteStatus(byte value)
Should only be used by SpriteChecker.
Clock< TICKS_PER_SECOND > VDPClock
uint16_t getPalette(unsigned index) const
Gets a palette entry.
byte getHorizontalScrollHigh() const
Gets the current horizontal scroll higher bits.
int getRightBorder() const
Gets the number of VDP clock ticks between start of line and the start of the right border.
DisplayMode getDisplayMode() const
Get the display mode the VDP is in.
int getPatternTableBase() const
Get address of pattern table (only for debugger)
int getDisplayPage() const
Only used by debugger.
bool getBlinkState() const
Gets the current blink state.
int getColorTableBase() const
Get address of color table (only for debugger)
int getLineZero() const
Get the absolute line number of display line zero.
int getBlinkForegroundColor() const
Gets the current blinking color for blinking text.
void setExternalVideoSource(const RawFrame *externalSource)
Enable superimposing.
bool isMSX1VDP() const
Is this an MSX1 VDP?
byte getBackgroundColor() const
Gets the current background color.
byte getVerticalScroll() const
Gets the current vertical scroll (line displayed at Y=0).
bool isVDPwithVRAMremapping() const
Does this VDP have VRAM remapping when switching from 4k to 8/16k mode?
bool hasYJK() const
Does this VDP support YJK display?
EmuTime::param getFrameStartTime() const
bool canSpriteColor0Collide() const
Can a sprite which has color=0 collide with some other sprite?
bool isMultiPageScrolling() const
Is multi page scrolling enabled? It is considered enabled if both the multi page scrolling flag is en...
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
int getLeftBorder() const
Gets the number of VDP clock ticks between start of line and the end of the left border.
EmuTime getAccessSlot(EmuTime::param time, VDPAccessSlots::Delta delta) const
Get the earliest access slot that is at least 'delta' cycles in the future.
bool isSpriteMag() const
Are sprites magnified?
bool vdpHasPatColMirroring() const
Is this a VDP that has pattern/color table mirroring?
bool isPalTiming() const
Is PAL timing active? This setting is fixed at start of frame.
bool isInterlaced() const
Get interlace status.
bool getTransparency() const
Gets the current transparency setting.
int getSpriteAttributeTableBase() const
Get address of color table (only for debugger)
bool getVRMode() const
Returns current VR mode.
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
std::string_view getVersionString() const
bool isDisplayEnabled() const
Is the display enabled? Both the regular border and forced blanking by clearing the display enable bi...
int getTicksThisFrame(EmuTime::param time) const
Gets the number of VDP clock ticks (21MHz) elapsed between a given time and the start of this frame.
bool vdpLacksMirroring() const
Is this a VDP that lacks mirroring?
byte getHorizontalScrollLow() const
Gets the current horizontal scroll lower bits.
VDP(const DeviceConfig &config)
byte peekStatusReg(byte reg, EmuTime::param time) const
void powerUp(EmuTime::param time) override
This method is called when MSX is powered up.
int getLeftSprites() const
Gets the number of VDP clock ticks between start of line and the start of the sprite plane.
std::span< const uint16_t, 16 > getPalette() const
This file implemented 3 utility functions:
IntHelper< OptionalIRQ > OptionalIRQHelper
AmdFlash::SectorInfo Info
uint16_t word
16 bit unsigned integer
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
void swap(openmsx::MemBuffer< T > &l, openmsx::MemBuffer< T > &r) noexcept
#define OUTER(type, member)
Calculates what 'blinkState' and 'blinkCount' would be at a specific line.