openMSX
DisplayMode.hh
Go to the documentation of this file.
1#ifndef DISPLAYMODE_HH
2#define DISPLAYMODE_HH
3
4#include "openmsx.hh"
5#include "one_of.hh"
6
7namespace openmsx {
8
16{
17private:
18 constexpr explicit DisplayMode(byte mode_) : mode(mode_) {}
23 byte mode = 0;
24
25public:
26 static constexpr uint8_t GRAPHIC1 = 0x00; // Graphic 1
27 static constexpr uint8_t TEXT1 = 0x01; // Text 1
28 static constexpr uint8_t MULTICOLOR = 0x02; // Multicolor
29 static constexpr uint8_t GRAPHIC2 = 0x04; // Graphic 2
30 static constexpr uint8_t TEXT1Q = 0x05; // !!
31 static constexpr uint8_t MULTIQ = 0x06; // !!
32 static constexpr uint8_t GRAPHIC3 = 0x08; // Graphic 3
33 static constexpr uint8_t TEXT2 = 0x09; // Text 2
34 static constexpr uint8_t GRAPHIC4 = 0x0C; // Graphic 4
35 static constexpr uint8_t GRAPHIC5 = 0x10; // Graphic 5
36 static constexpr uint8_t GRAPHIC6 = 0x14; // Graphic 6
37 static constexpr uint8_t GRAPHIC7 = 0x1C; // Graphic 7
38
40 static constexpr byte REG0_MASK = 0x0E;
41
43 static constexpr byte REG1_MASK = 0x18;
44
46 static constexpr byte REG25_MASK = 0x18;
47
49 static constexpr byte YJK = 0x20;
50
52 static constexpr byte YAE = 0x40;
53
56 constexpr DisplayMode() = default;
57
64 constexpr DisplayMode(byte reg0, byte reg1, byte reg25) {
65 if ((reg25 & 0x08) == 0) reg25 = 0; // If YJK is off, ignore YAE.
66 mode = byte(
67 ((reg25 & 0x18) << 2) | // YAE YJK
68 ((reg0 & 0x0E) << 1) | // M5..M3
69 ((reg1 & 0x08) >> 2) | // M2
70 ((reg1 & 0x10) >> 4)); // M1
71 }
72
73 [[nodiscard]] constexpr DisplayMode updateReg25(byte reg25) const {
74 if ((reg25 & 0x08) == 0) reg25 = 0; // If YJK is off, ignore YAE.
75 return DisplayMode(byte(getBase() | ((reg25 & 0x18) << 2)));
76 }
77
80 constexpr void reset() {
81 *this = DisplayMode();
82 }
83
86 [[nodiscard]] constexpr bool operator==(const DisplayMode&) const = default;
87
92 [[nodiscard]] constexpr byte getByte() const {
93 return mode;
94 }
95
97 constexpr void setByte(byte mode_) {
98 mode = mode_;
99 }
100
106 [[nodiscard]] constexpr byte getBase() const {
107 return mode & 0x1F;
108 }
109
113 [[nodiscard]] constexpr bool isV9938Mode() const {
114 return (mode & 0x18) != 0;
115 }
116
121 [[nodiscard]] constexpr bool isTextMode() const {
122 return getBase() == one_of(TEXT1, TEXT2, TEXT1Q);
123 }
124
129 [[nodiscard]] constexpr bool isBitmapMode() const {
130 return getBase() >= 0x0C;
131 }
132
139 [[nodiscard]] constexpr bool isPlanar() const {
140 // TODO: Is the display mode check OK? Profile undefined modes.
141 return (mode & 0x14) == 0x14;
142 }
143
146 [[nodiscard]] constexpr bool isSpriteNarrow() const {
147 // TODO: Check what happens to sprites in Graphic5 + YJK/YAE.
148 return mode == GRAPHIC5;
149 }
150
157 [[nodiscard]] constexpr int getSpriteMode(bool isMSX1) const {
158 switch (getBase()) {
159 case GRAPHIC1: case MULTICOLOR: case GRAPHIC2:
160 return 1;
161 case MULTIQ: // depends on VDP type
162 return isMSX1 ? 1 : 0;
163 case GRAPHIC3: case GRAPHIC4: case GRAPHIC5:
164 case GRAPHIC6: case GRAPHIC7:
165 return 2;
166 case TEXT1: case TEXT1Q: case TEXT2:
167 default: // and all other (bogus) modes
168 // Verified on real V9958: none of the bogus modes
169 // show sprites.
170 // TODO check on TMSxxxx
171 return 0;
172 }
173 }
174
179 [[nodiscard]] constexpr unsigned getLineWidth() const {
180 // Note: Testing "mode" instead of "base mode" ensures that YJK
181 // modes are treated as 256 pixels wide.
182 return mode == one_of(TEXT2, GRAPHIC5, GRAPHIC6)
183 ? 512
184 : 256;
185 }
186};
187
188} // namespace openmsx
189
190#endif
Represents a VDP display mode.
constexpr bool isSpriteNarrow() const
Are sprite pixels narrow?
constexpr DisplayMode updateReg25(byte reg25) const
constexpr byte getBase() const
Get the base display mode as an integer: M5..M1 combined.
constexpr void setByte(byte mode_)
Used for de-serialization.
static constexpr uint8_t GRAPHIC3
static constexpr uint8_t MULTIQ
static constexpr uint8_t MULTICOLOR
static constexpr uint8_t TEXT1Q
static constexpr uint8_t GRAPHIC4
constexpr bool isPlanar() const
Is VRAM "planar" in the current display mode? Graphic 6 and 7 spread their bytes over two VRAM ICs,...
static constexpr uint8_t GRAPHIC5
static constexpr uint8_t GRAPHIC1
constexpr unsigned getLineWidth() const
Get number of pixels on a display line in this mode.
static constexpr uint8_t GRAPHIC7
constexpr bool operator==(const DisplayMode &) const =default
Equals operator.
static constexpr uint8_t TEXT2
constexpr bool isBitmapMode() const
Is the current mode a bitmap mode? Graphic4 and higher are bitmap modes.
constexpr DisplayMode()=default
Create the initial display mode.
static constexpr byte REG25_MASK
Bits of VDP register 25 that encode part of the display mode.
constexpr bool isV9938Mode() const
Was this mode introduced by the V9938?
static constexpr byte YAE
Encoding of YAE flag.
constexpr DisplayMode(byte reg0, byte reg1, byte reg25)
Create a specific display mode.
static constexpr uint8_t GRAPHIC6
constexpr void reset()
Bring the display mode to its initial state.
static constexpr byte REG1_MASK
Bits of VDP register 1 that encode part of the display mode.
constexpr bool isTextMode() const
Is the current mode a text mode? Text1 and Text2 are text modes.
static constexpr byte YJK
Encoding of YJK flag.
static constexpr uint8_t GRAPHIC2
constexpr byte getByte() const
Get the display mode as a byte: YAE YJK M5..M1 combined.
static constexpr uint8_t TEXT1
constexpr int getSpriteMode(bool isMSX1) const
Get the sprite mode of this display mode.
static constexpr byte REG0_MASK
Bits of VDP register 0 that encode part of the display mode.
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint8_t byte
8 bit unsigned integer
Definition openmsx.hh:26