openMSX
DisplayMode.hh
Go to the documentation of this file.
1 #ifndef DISPLAYMODE_HH
2 #define DISPLAYMODE_HH
3 
4 #include "openmsx.hh"
5 
6 namespace openmsx {
7 
15 {
16 private:
17  constexpr explicit DisplayMode(byte mode_) : mode(mode_) {}
22  byte mode = 0;
23 
24 public:
25  enum {
26  GRAPHIC1 = 0x00, // Graphic 1
27  TEXT1 = 0x01, // Text 1
28  MULTICOLOR = 0x02, // Multicolor
29  GRAPHIC2 = 0x04, // Graphic 2
30  TEXT1Q = 0x05, // !!
31  MULTIQ = 0x06, // !!
32  GRAPHIC3 = 0x08, // Graphic 3
33  TEXT2 = 0x09, // Text 2
34  GRAPHIC4 = 0x0C, // Graphic 4
35  GRAPHIC5 = 0x10, // Graphic 5
36  GRAPHIC6 = 0x14, // Graphic 6
37  GRAPHIC7 = 0x1C // Graphic 7
38  };
39 
41  static constexpr byte REG0_MASK = 0x0E;
42 
44  static constexpr byte REG1_MASK = 0x18;
45 
47  static constexpr byte REG25_MASK = 0x18;
48 
50  static constexpr byte YJK = 0x20;
51 
53  static constexpr byte YAE = 0x40;
54 
57  constexpr DisplayMode() = default;
58 
65  constexpr DisplayMode(byte reg0, byte reg1, byte reg25) {
66  if ((reg25 & 0x08) == 0) reg25 = 0; // If YJK is off, ignore YAE.
67  mode = ((reg25 & 0x18) << 2) // YAE YJK
68  | ((reg0 & 0x0E) << 1) // M5..M3
69  | ((reg1 & 0x08) >> 2) // M2
70  | ((reg1 & 0x10) >> 4); // M1
71  }
72 
73  constexpr DisplayMode updateReg25(byte reg25) const {
74  if ((reg25 & 0x08) == 0) reg25 = 0; // If YJK is off, ignore YAE.
75  return DisplayMode(getBase() | ((reg25 & 0x18) << 2));
76  }
77 
80  constexpr void reset() {
81  *this = DisplayMode();
82  }
83 
86  constexpr bool operator==(const DisplayMode& otherMode) const {
87  return mode == otherMode.mode;
88  }
89 
92  constexpr bool operator!=(const DisplayMode& otherMode) const {
93  return mode != otherMode.mode;
94  }
95 
100  constexpr byte getByte() const {
101  return mode;
102  }
103 
105  constexpr void setByte(byte mode_) {
106  mode = mode_;
107  }
108 
114  constexpr byte getBase() const {
115  return mode & 0x1F;
116  }
117 
121  constexpr bool isV9938Mode() const {
122  return (mode & 0x18) != 0;
123  }
124 
129  constexpr bool isTextMode() const {
130  byte base = getBase();
131  return (base == TEXT1) ||
132  (base == TEXT2) ||
133  (base == TEXT1Q);
134  }
135 
140  constexpr bool isBitmapMode() const {
141  return getBase() >= 0x0C;
142  }
143 
150  constexpr bool isPlanar() const {
151  // TODO: Is the display mode check OK? Profile undefined modes.
152  return (mode & 0x14) == 0x14;
153  }
154 
157  constexpr bool isSpriteNarrow() const {
158  // TODO: Check what happens to sprites in Graphic5 + YJK/YAE.
159  return mode == GRAPHIC5;
160  }
161 
168  constexpr int getSpriteMode(bool isMSX1) const {
169  switch (getBase()) {
170  case GRAPHIC1: case MULTICOLOR: case GRAPHIC2:
171  return 1;
172  case MULTIQ: // depends on VDP type
173  return isMSX1 ? 1 : 0;
174  case GRAPHIC3: case GRAPHIC4: case GRAPHIC5:
175  case GRAPHIC6: case GRAPHIC7:
176  return 2;
177  case TEXT1: case TEXT1Q: case TEXT2:
178  default: // and all other (bogus) modes
179  // Verified on real V9958: none of the bogus modes
180  // show sprites.
181  // TODO check on TMSxxxx
182  return 0;
183  }
184  }
185 
190  constexpr unsigned getLineWidth() const {
191  // Note: Testing "mode" instead of "base mode" ensures that YJK
192  // modes are treated as 256 pixels wide.
193  return mode == TEXT2 || mode == GRAPHIC5 || mode == GRAPHIC6
194  ? 512
195  : 256;
196  }
197 };
198 
199 } // namespace openmsx
200 
201 #endif
constexpr bool operator==(const DisplayMode &otherMode) const
Equals operator.
Definition: DisplayMode.hh:86
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
constexpr bool isTextMode() const
Is the current mode a text mode? Text1 and Text2 are text modes.
Definition: DisplayMode.hh:129
Represents a VDP display mode.
Definition: DisplayMode.hh:14
constexpr DisplayMode(byte reg0, byte reg1, byte reg25)
Create a specific display mode.
Definition: DisplayMode.hh:65
static constexpr byte YAE
Encoding of YAE flag.
Definition: DisplayMode.hh:53
static constexpr byte REG25_MASK
Bits of VDP register 25 that encode part of the display mode.
Definition: DisplayMode.hh:47
constexpr int getSpriteMode(bool isMSX1) const
Get the sprite mode of this display mode.
Definition: DisplayMode.hh:168
constexpr bool isV9938Mode() const
Was this mode introduced by the V9938?
Definition: DisplayMode.hh:121
constexpr bool isBitmapMode() const
Is the current mode a bitmap mode? Graphic4 and higher are bitmap modes.
Definition: DisplayMode.hh:140
constexpr bool operator!=(const DisplayMode &otherMode) const
Does-not-equal operator.
Definition: DisplayMode.hh:92
constexpr byte getByte() const
Get the dispay mode as a byte: YAE YJK M5..M1 combined.
Definition: DisplayMode.hh:100
constexpr void setByte(byte mode_)
Used for de-serialization.
Definition: DisplayMode.hh:105
constexpr DisplayMode updateReg25(byte reg25) const
Definition: DisplayMode.hh:73
static constexpr byte REG0_MASK
Bits of VDP register 0 that encode part of the display mode.
Definition: DisplayMode.hh:41
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
constexpr unsigned getLineWidth() const
Get number of pixels on a display line in this mode.
Definition: DisplayMode.hh:190
static constexpr byte REG1_MASK
Bits of VDP register 1 that encode part of the display mode.
Definition: DisplayMode.hh:44
constexpr bool isPlanar() const
Is VRAM "planar" in the current display mode? Graphic 6 and 7 spread their bytes over two VRAM ICs...
Definition: DisplayMode.hh:150
constexpr byte getBase() const
Get the base dispay mode as an integer: M5..M1 combined.
Definition: DisplayMode.hh:114
constexpr bool isSpriteNarrow() const
Are sprite pixels narrow?
Definition: DisplayMode.hh:157
constexpr void reset()
Bring the display mode to its initial state.
Definition: DisplayMode.hh:80
static constexpr byte YJK
Encoding of YJK flag.
Definition: DisplayMode.hh:50
constexpr DisplayMode()=default
Create the initial display mode.