38 void powerUp(EmuTime::param time)
override;
39 void reset(EmuTime::param time)
override;
40 [[nodiscard]]
byte readIO(
word port, EmuTime::param time)
override;
41 [[nodiscard]]
byte peekIO(
word port, EmuTime::param time)
const override;
42 void writeIO(
word port,
byte value, EmuTime::param time)
override;
67 return (regs[SCREEN_MODE_1] & 0x04) != 0;
74 return (status & 0x02) != 0;
83 return isDisplayArea && displayEnabled;
90 return !(regs[CONTROL] & 0x40);
99 return (regs[PALETTE_CONTROL] & 0x0F);
144 return superimposing;
149 externalVideoSource = enable;
175 case P1:
x = ticks / 8;
break;
176 case P2:
x = ticks / 4;
break;
177 case B0:
x = ticks /12;
break;
178 case B1:
x = ticks / 8;
break;
179 case B2:
x = ticks / 6;
break;
180 case B3:
x = ticks / 4;
break;
181 case B4:
x = ticks / 3;
break;
182 case B5:
x = 1;
break;
183 case B6:
x = 1;
break;
184 case B7:
x = ticks / 2;
break;
208 return regs[SCREEN_MODE_0] & 0x03;
215 return regs[BACK_DROP_COLOR];
221 return regs[SCROLL_CONTROL_AX0] + 8 * regs[SCROLL_CONTROL_AX1];
227 return regs[SCROLL_CONTROL_AY0] + 256 * scrollAYHigh;
233 return regs[SCROLL_CONTROL_BX0] + 8 * regs[SCROLL_CONTROL_BX1];
239 return regs[SCROLL_CONTROL_BY0] + 256 * scrollBYHigh;
244 [[nodiscard]]
inline unsigned getRollMask(
unsigned maxMask)
const {
245 static unsigned rollMasks[4] = {
251 unsigned t = regs[SCROLL_CONTROL_AY1] >> 6;
252 return t ? rollMasks[
t] : maxMask;
258 switch (regs[SCREEN_MODE_0] & 0xC0) {
265 return (256 << ((regs[SCREEN_MODE_0] & 0x0C) >> 2));
273 case P1:
case B1:
return 320;
275 case P2:
case B3:
return 640;
277 case B5:
case B6:
return 1;
278 case B7:
return 1280;
295 return (
int(regs[SPRITE_PATTERN_ADDRESS] & 0x0E) << 14);
297 return (
int(regs[SPRITE_PATTERN_ADDRESS] & 0x0F) << 15);
306 return regs[SPRITE_PALETTE_CONTROL] << 2;
320 (((regs[DISPLAY_ADJUST] & 0x0F) ^ 7) - 8) * 8;
337 (((regs[DISPLAY_ADJUST] >> 4) ^ 7) - 8);
344 unsigned t = regs[PRIORITY_CONTROL] & 0x03;
345 return (
t == 0) ? 256 :
t << 6;
348 unsigned t = regs[PRIORITY_CONTROL] & 0x0C;
349 return (
t == 0) ? 256 :
t << 4;
352 template<
typename Archive>
353 void serialize(Archive& ar,
unsigned version);
357 void preVideoSystemChange() noexcept override;
358 void postVideoSystemChange() noexcept override;
366 ~SyncBase() =
default;
369 struct SyncVSync final : SyncBase {
370 explicit SyncVSync(
V9990& v9990) : SyncBase(v9990) {}
371 void executeUntil(EmuTime::param time)
override {
373 v9990.execVSync(time);
377 struct SyncDisplayStart final : SyncBase {
378 explicit SyncDisplayStart(
V9990& v9990) : SyncBase(v9990) {}
379 void executeUntil(EmuTime::param time)
override {
381 v9990.execDisplayStart(time);
385 struct SyncVScan final : SyncBase {
386 explicit SyncVScan(
V9990& v9990) : SyncBase(v9990) {}
387 void executeUntil(EmuTime::param time)
override {
389 v9990.execVScan(time);
393 struct SyncHScan final : SyncBase {
394 explicit SyncHScan(
V9990& v9990) : SyncBase(v9990) {}
395 void executeUntil(EmuTime::param )
override {
401 struct SyncSetMode final : SyncBase {
402 explicit SyncSetMode(
V9990& v9990) : SyncBase(v9990) {}
403 void executeUntil(EmuTime::param time)
override {
405 v9990.execSetMode(time);
409 struct SyncCmdEnd final : SyncBase {
410 explicit SyncCmdEnd(
V9990& v9990) : SyncBase(v9990) {}
411 void executeUntil(EmuTime::param time)
override {
413 v9990.execCheckCmdEnd(time);
417 void execVSync(EmuTime::param time);
418 void execDisplayStart(EmuTime::param time);
419 void execVScan(EmuTime::param time);
421 void execSetMode(EmuTime::param time);
422 void execCheckCmdEnd(EmuTime::param time);
458 VRAM_WRITE_ADDRESS_0 = 0,
459 VRAM_WRITE_ADDRESS_1,
460 VRAM_WRITE_ADDRESS_2,
483 SPRITE_PATTERN_ADDRESS,
486 SPRITE_PALETTE_CONTROL,
487 CMD_PARAM_SRC_ADDRESS_0 = 32,
488 CMD_PARAM_SRC_ADDRESS_1,
489 CMD_PARAM_SRC_ADDRESS_2,
490 CMD_PARAM_SRC_ADDRESS_3,
491 CMD_PARAM_DEST_ADDRESS_0,
492 CMD_PARAM_DEST_ADDRESS_1,
493 CMD_PARAM_DEST_ADDRESS_2,
494 CMD_PARAM_DEST_ADDRESS_3,
501 CMD_PARAM_WRITE_MASK_0,
502 CMD_PARAM_WRITE_MASK_1,
503 CMD_PARAM_FONT_COLOR_FC0,
504 CMD_PARAM_FONT_COLOR_FC1,
505 CMD_PARAM_FONT_COLOR_BC0,
506 CMD_PARAM_FONT_COLOR_BC1,
508 CMD_PARAM_BORDER_X_0,
514 struct RegDebug final : SimpleDebuggable {
515 explicit RegDebug(
V9990& v9990);
516 [[nodiscard]]
byte read(
unsigned address)
override;
517 void write(
unsigned address,
byte value, EmuTime::param time)
override;
520 struct PalDebug final : SimpleDebuggable {
521 explicit PalDebug(
V9990& v9990);
522 [[nodiscard]]
byte read(
unsigned address)
override;
523 void write(
unsigned address,
byte value, EmuTime::param time)
override;
533 unsigned vramReadPtr, vramWritePtr;
542 std::unique_ptr<V9990Renderer> renderer;
546 Clock<V9990DisplayTiming::UC_TICKS_PER_SECOND> frameStartTime;
550 EmuTime hScanSyncTime;
554 const V9990DisplayPeriod* horTiming;
555 const V9990DisplayPeriod* verTiming;
619 bool externalVideoSource;
628 void setHorizontalTiming();
629 void setVerticalTiming();
637 [[nodiscard]]
inline unsigned getVRAMAddr(RegisterId base)
const;
643 inline void setVRAMAddr(RegisterId base,
unsigned addr);
650 [[nodiscard]]
byte readRegister(
byte reg, EmuTime::param time)
const;
657 void writeRegister(
byte reg,
byte val, EmuTime::param time);
664 void writePaletteRegister(
byte reg,
byte val, EmuTime::param time);
668 void syncAtNextLine(SyncBase& type, EmuTime::param time);
673 void createRenderer(EmuTime::param time);
678 void frameStart(EmuTime::param time);
683 void raiseIRQ(IRQType irqType);
694 void scheduleHscan(EmuTime::param time);
698 void scheduleCmdEnd(EmuTime::param time);
constexpr unsigned getTicksTill_fast(EmuTime::param e) const
Same as above, only faster, Though the time interval may not be too large.
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Scheduler & getScheduler() const
Abstract base class for post processors.
Every class that wants to get scheduled at some point must inherit from this class.
void setSyncPoint(EmuTime::param timestamp)
virtual byte read(unsigned address, EmuTime::param time)
void write(unsigned address, byte value) override
static constexpr int UC_TICKS_PER_LINE
The number of clockticks per line is independent of the crystal used or the display mode (NTSC/PAL)
static constexpr auto displayNTSC_MCLK
NTSC display timing, when using MCLK: Normal display mode with borders.
static constexpr auto displayPAL_MCLK
PAL display timing, when using MCLK: Normal display mode with borders.
Implementation of the Yamaha V9990 VDP as used in the GFX9000 cartridge by Sunrise.
void reset(EmuTime::param time) override
This method is called on reset.
unsigned getCursorYOffset() const
In overscan mode the cursor position is still specified with 'normal' (non-overscan) y-coordinates.
void powerUp(EmuTime::param time) override
This method is called when MSX is powered up.
void serialize(Archive &ar, unsigned version)
bool isPalTiming() const
Is PAL timing active? This setting is fixed at start of frame.
int getSpritePatternAddress(V9990DisplayMode m) const
Return the sprite pattern table base address.
bool isSuperimposing() const
Should this frame be superimposed? This is a combination of bit 5 (YSE) in R#8 and the presence of an...
void cmdReady()
Command execution ready.
byte getPaletteOffset() const
Get palette offset.
byte getBackDropColor() const
Return the current back drop color.
const V9990DisplayPeriod & getVerticalTiming() const
Get vertical display timings.
int getUCTicksThisFrame(EmuTime::param time) const
Get the number of elapsed UC ticks in this frame.
bool isInterlaced() const
Get interlace status.
unsigned getLineWidth() const
Return the display width.
bool isEvenOddEnabled() const
Get even/odd page alternation status.
unsigned getScrollBX() const
Returns the X scroll offset for screen B of P1 mode.
V9990DisplayMode getDisplayMode() const
Return the current display mode.
unsigned getImageWidth() const
Return the image width.
V9990VRAM & getVRAM()
Obtain a reference to the V9990's VRAM.
const V9990DisplayPeriod & getHorizontalTiming() const
Get horizontal display timings.
unsigned getPriorityControlX() const
bool spritesEnabled() const
Are sprites (cursors) enabled?
unsigned getColorDepth() const
Return the amount of bits per pixels.
void setExternalVideoSource(bool enable)
Is there an external video source available to superimpose on.
GetPaletteResult getPalette(int index) const
byte getSpritePaletteOffset() const
return sprite palette offset
static int UCtoX(int ticks, V9990DisplayMode mode)
Convert UC ticks to V9990 pixel position on a line.
unsigned getPriorityControlY() const
int getBottomBorder() const
unsigned getScrollAX() const
Returns the X scroll offset for screen A of P1 and other modes.
int getLeftBorder() const
Get the number of VDP clockticks between the start of the line and the end of the left border.
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.
PostProcessor * getPostProcessor() const
Used by Video9000 to be able to couple the VDP and V9990 output.
bool isDisplayEnabled() const
Is the display enabled? Note this is simpler than the V99x8 version.
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
unsigned getScrollBY() const
Returns the Y scroll offset for screen B of P1 mode.
unsigned getScrollAY() const
Returns the Y scroll offset for screen A of P1 and other modes.
unsigned getRollMask(unsigned maxMask) const
Returns the vertical roll mask.
V9990ColorMode getColorMode() const
Return the current color mode.
V9990(const DeviceConfig &config)
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
int getRightBorder() const
Get the number of VDP clockticks between the start of the line and the end of the right border.
bool isOverScan() const
Returns true iff in overscan mode.
bool getEvenOdd() const
Is the even or odd field being displayed?
This file implemented 3 utility functions:
uint16_t word
16 bit unsigned integer
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
constexpr KeyMatrixPosition x
Keyboard bindings.
IntHelper< IRQSource > IRQHelper
#define OUTER(type, member)
A period, either horizontal or vertical, starts with a synchronisation pulse followed by a blank peri...