41 void powerUp(EmuTime::param time)
override;
42 void reset(EmuTime::param time)
override;
43 [[nodiscard]]
byte readIO(
word port, EmuTime::param time)
override;
44 [[nodiscard]]
byte peekIO(
word port, EmuTime::param time)
const override;
45 void writeIO(
word port,
byte value, EmuTime::param time)
override;
70 return (regs[SCREEN_MODE_1] & 0x04) != 0;
77 return (status & 0x02) != 0;
86 return isDisplayArea && displayEnabled;
93 return !(regs[CONTROL] & 0x40);
102 return (regs[PALETTE_CONTROL] & 0x0F);
147 return superimposing;
152 externalVideoSource = enable;
179 case P1: x = ticks / 8;
break;
180 case P2: x = ticks / 4;
break;
181 case B0: x = ticks /12;
break;
182 case B1: x = ticks / 8;
break;
183 case B2: x = ticks / 6;
break;
184 case B3: x = ticks / 4;
break;
185 case B4: x = ticks / 3;
break;
186 case B5: x = 1;
break;
187 case B6: x = 1;
break;
188 case B7: x = ticks / 2;
break;
212 return regs[SCREEN_MODE_0] & 0x03;
219 return regs[BACK_DROP_COLOR];
225 return regs[SCROLL_CONTROL_AX0] + 8 * regs[SCROLL_CONTROL_AX1];
231 return regs[SCROLL_CONTROL_AY0] + 256 * scrollAYHigh;
237 return regs[SCROLL_CONTROL_BX0] + 8 * regs[SCROLL_CONTROL_BX1];
243 return regs[SCROLL_CONTROL_BY0] + 256 * scrollBYHigh;
248 [[nodiscard]]
inline unsigned getRollMask(
unsigned maxMask)
const {
249 static std::array<unsigned, 4> rollMasks = {
255 unsigned t = regs[SCROLL_CONTROL_AY1] >> 6;
256 return t ? rollMasks[
t] : maxMask;
262 switch (regs[SCREEN_MODE_0] & 0xC0) {
269 return (256 << ((regs[SCREEN_MODE_0] & 0x0C) >> 2));
278 case P1:
case B1:
return 320;
280 case P2:
case B3:
return 640;
282 case B5:
case B6:
return 1;
283 case B7:
return 1280;
300 return (
int(regs[SPRITE_PATTERN_ADDRESS] & 0x0E) << 14);
302 return (
int(regs[SPRITE_PATTERN_ADDRESS] & 0x0F) << 15);
311 return narrow_cast<byte>(regs[SPRITE_PALETTE_CONTROL] << 2);
325 (((regs[DISPLAY_ADJUST] & 0x0F) ^ 7) - 8) * 8;
342 (((regs[DISPLAY_ADJUST] >> 4) ^ 7) - 8);
349 unsigned t = regs[PRIORITY_CONTROL] & 0x03;
350 return (
t == 0) ? 256 :
t << 6;
353 unsigned t = regs[PRIORITY_CONTROL] & 0x0C;
354 return (
t == 0) ? 256 :
t << 4;
357 template<
typename Archive>
358 void serialize(Archive& ar,
unsigned version);
362 void preVideoSystemChange() noexcept override;
363 void postVideoSystemChange() noexcept override;
371 ~SyncBase() =
default;
374 struct SyncVSync final : SyncBase {
375 using SyncBase::SyncBase;
376 void executeUntil(EmuTime::param time)
override {
377 auto& v9990 =
OUTER(V9990, syncVSync);
378 v9990.execVSync(time);
382 struct SyncDisplayStart final : SyncBase {
383 using SyncBase::SyncBase;
384 void executeUntil(EmuTime::param time)
override {
385 auto& v9990 =
OUTER(V9990, syncDisplayStart);
386 v9990.execDisplayStart(time);
390 struct SyncVScan final : SyncBase {
391 using SyncBase::SyncBase;
392 void executeUntil(EmuTime::param time)
override {
393 auto& v9990 =
OUTER(V9990, syncVScan);
394 v9990.execVScan(time);
398 struct SyncHScan final : SyncBase {
399 using SyncBase::SyncBase;
400 void executeUntil(EmuTime::param )
override {
401 auto& v9990 =
OUTER(V9990, syncHScan);
406 struct SyncSetMode final : SyncBase {
407 using SyncBase::SyncBase;
408 void executeUntil(EmuTime::param time)
override {
409 auto& v9990 =
OUTER(V9990, syncSetMode);
410 v9990.execSetMode(time);
414 struct SyncCmdEnd final : SyncBase {
415 using SyncBase::SyncBase;
416 void executeUntil(EmuTime::param time)
override {
417 auto& v9990 =
OUTER(V9990, syncCmdEnd);
418 v9990.execCheckCmdEnd(time);
422 void execVSync(EmuTime::param time);
423 void execDisplayStart(EmuTime::param time);
424 void execVScan(EmuTime::param time);
426 void execSetMode(EmuTime::param time);
427 void execCheckCmdEnd(EmuTime::param time);
433 enum IRQType :
byte {
463 VRAM_WRITE_ADDRESS_0 = 0,
464 VRAM_WRITE_ADDRESS_1,
465 VRAM_WRITE_ADDRESS_2,
488 SPRITE_PATTERN_ADDRESS,
491 SPRITE_PALETTE_CONTROL,
492 CMD_PARAM_SRC_ADDRESS_0 = 32,
493 CMD_PARAM_SRC_ADDRESS_1,
494 CMD_PARAM_SRC_ADDRESS_2,
495 CMD_PARAM_SRC_ADDRESS_3,
496 CMD_PARAM_DEST_ADDRESS_0,
497 CMD_PARAM_DEST_ADDRESS_1,
498 CMD_PARAM_DEST_ADDRESS_2,
499 CMD_PARAM_DEST_ADDRESS_3,
506 CMD_PARAM_WRITE_MASK_0,
507 CMD_PARAM_WRITE_MASK_1,
508 CMD_PARAM_FONT_COLOR_FC0,
509 CMD_PARAM_FONT_COLOR_FC1,
510 CMD_PARAM_FONT_COLOR_BC0,
511 CMD_PARAM_FONT_COLOR_BC1,
513 CMD_PARAM_BORDER_X_0,
519 struct RegDebug final : SimpleDebuggable {
520 explicit RegDebug(
const V9990& v9990);
521 [[nodiscard]]
byte read(
unsigned address)
override;
522 void write(
unsigned address,
byte value, EmuTime::param time)
override;
525 struct PalDebug final : SimpleDebuggable {
526 explicit PalDebug(
const V9990& v9990);
527 [[nodiscard]]
byte read(
unsigned address)
override;
528 void write(
unsigned address,
byte value, EmuTime::param time)
override;
535 TclCallback invalidRegisterReadCallback;
536 TclCallback invalidRegisterWriteCallback;
541 unsigned vramReadPtr, vramWritePtr;
550 std::unique_ptr<V9990Renderer> renderer;
554 Clock<V9990DisplayTiming::UC_TICKS_PER_SECOND> frameStartTime;
558 EmuTime hScanSyncTime;
562 const V9990DisplayPeriod* horTiming;
563 const V9990DisplayPeriod* verTiming;
571 std::array<byte, 0x100> palette;
579 byte pendingIRQs = 0;
583 std::array<byte, 0x40> regs = {};
588 bool palTiming{
false};
593 bool interlaced{
false};
597 bool isDisplayArea{
false};
604 bool displayEnabled{
false};
627 bool externalVideoSource{
false};
632 bool superimposing{
false};
636 void setHorizontalTiming();
637 void setVerticalTiming();
645 [[nodiscard]]
inline unsigned getVRAMAddr(RegisterId base)
const;
651 inline void setVRAMAddr(RegisterId base,
unsigned addr);
658 [[nodiscard]]
byte readRegister(
byte reg, EmuTime::param time)
const;
665 void writeRegister(
byte reg,
byte val, EmuTime::param time);
672 void writePaletteRegister(
byte reg,
byte val, EmuTime::param time);
676 void syncAtNextLine(SyncBase& type, EmuTime::param time)
const;
681 void createRenderer(EmuTime::param time);
686 void frameStart(EmuTime::param time);
691 void raiseIRQ(IRQType irqType);
702 void scheduleHscan(EmuTime::param time);
706 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
A post processor builds the frame that is displayed from the MSX frame, while applying effects such a...
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 clock ticks 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.
int getUCTicksThisFrame(EmuTime::param time) const
Get the number of elapsed UC ticks in this frame.
V9990VRAM & getVRAM()
Obtain a reference to the V9990's VRAM.
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.
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 clock-ticks 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.
const V9990DisplayPeriod & getVerticalTiming() const
Get vertical display timings.
V9990ColorMode getColorMode() const
Return the current color mode.
const V9990DisplayPeriod & getHorizontalTiming() const
Get horizontal display timings.
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 clock-ticks 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
IntHelper< IRQSource > IRQHelper
#define OUTER(type, member)
A period, either horizontal or vertical, starts with a synchronisation pulse followed by a blank peri...