Skip to content

Commit

Permalink
Multicolor Text Mode error sorted out.
Browse files Browse the repository at this point in the history
When an interrupt is launched the reason is now part of the invocation (and also in the debug line when active).
Reading the register 19 of the VICII now is improved. The bits are active when the condition is get not when additionaly the IRQ for that reason was active. Escept the bit 7 that is active when the IRQ condition happens.
  • Loading branch information
Neolucas committed Oct 7, 2023
1 parent 5dbcda4 commit b72cd87
Show file tree
Hide file tree
Showing 35 changed files with 168 additions and 91 deletions.
Binary file modified compilers/C64Compiler/C64Compiler.exe
Binary file not shown.
Binary file modified compilers/C64Compiler/C64CompilerD.exe
Binary file not shown.
Binary file modified docs/No/html.zip
Binary file not shown.
Binary file modified emulators/C64Emulator/C64Emulator.exe
Binary file not shown.
Binary file modified emulators/C64Emulator/C64EmulatorD.exe
Binary file not shown.
Binary file modified emulators/C64EmulatorC/C64EmulatorC.exe
Binary file not shown.
Binary file modified emulators/C64EmulatorC/C64EmulatorCD.exe
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
13 changes: 13 additions & 0 deletions include/COMMODORE/CIARegisters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ namespace COMMODORE

/** To know whether the interruption has or not to be launched. */
inline bool launchInterruption () const;
/** Just to have a code with the reason of the interrupt when happens. */
inline unsigned int reasonIRQCode () const;

/** The value to reflect at the bit 6 or 7 of the port B. */
/** To know first whether the timer A is affecting or not to the bit 6. */
Expand Down Expand Up @@ -196,6 +198,17 @@ namespace COMMODORE
_serialPort -> interruptRequested () ||
launchFlagLineInterruption ());
}

// ---
inline unsigned int CIARegisters::reasonIRQCode () const
{
return ((_timerA -> launchInterruption () ? 1 : 0) +
(_timerB -> launchInterruption () ? 2 : 0) +
(_clock -> launchInterruption () ? 4 : 0) +
(_serialPort -> interruptRequested () ? 8 : 0) +
(launchFlagLineInterruption () ? 16 : 0));
}

}

#endif
Expand Down
48 changes: 33 additions & 15 deletions include/COMMODORE/VICII.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,17 @@ namespace COMMODORE
* blk = When the graphical mode is inavlid and nothing has to be drawn.
*/
DrawResult drawMonoColorChar (int cb);
/** Draws a multicolor char. */
DrawResult drawMultiColorChar (int cb);
/** Draws a multicolor char. \n
The mode can be used also as an invalid mode. */
DrawResult drawMultiColorChar (int cb, bool inv = false);
/** Draws an enhaced multicolor char. */
DrawResult drawMultiColorExtendedChar (int cb);
/** Draws a monocolor bitmap. */
DrawResult drawMonoColorBitMap (int cb);
/** Draws a multicolor bitmap. */
DrawResult drawMultiColorBitMap (int cb);
/** Draws a monocolor bitmap. \n
The mode can be used also as an invalid mode. */
DrawResult drawMonoColorBitMap (int cb, bool inv = false);
/** Draws a multicolor bitmap. \n
The mode can be used as an invalid mode. */
DrawResult drawMultiColorBitMap (int cb, bool inv = false);

// Draw the sprites in detail...
/**
Expand Down Expand Up @@ -373,13 +376,15 @@ namespace COMMODORE

VICSpriteInfo (bool a, unsigned char l, bool e)
: _active (a), _line (l), _expansionY (e),
_spriteBaseAddress ({ 0x00, 0x00 }, true), // it is the same than using false and quicker...
_graphicsLineSprites (MCHEmul::UBytes::_E),
_ff (false)
{ }

bool _active; // True when the sprite is active in the current raster line
unsigned char _line; // Line of the sprite to be drawn (from 0 to 21)
bool _expansionY; // True when the sprite is expanded in the Y axis
mutable MCHEmul::Address _spriteBaseAddress;
mutable MCHEmul::UBytes _graphicsLineSprites; // 3 bytes line info each

// Implementation
Expand All @@ -395,17 +400,20 @@ namespace COMMODORE
inline void VICII::readVideoMatrixAndColorRAM ()
{
memoryRef () -> setActiveView (_VICIIView);

_vicGraphicInfo._screenCodeData [_vicGraphicInfo._VLMI] =
memoryRef () -> value (_VICIIRegisters -> screenMemory () + (size_t) _vicGraphicInfo._VC);
_vicGraphicInfo._colorData [_vicGraphicInfo._VLMI] =
memoryRef () -> value (_COLORMEMORY + (size_t) _vicGraphicInfo._VC);

memoryRef () -> setCPUView ();
}

// ---
inline void VICII::readGraphicalInfo ()
{
memoryRef () -> setActiveView (_VICIIView);

if (_vicGraphicInfo._idleState) // In this state the info is read from a specific place of the memory...
_vicGraphicInfo._graphicData [_vicGraphicInfo._VLMI] =
_VICIIRegisters -> graphicExtendedColorTextModeActive ()
Expand All @@ -418,6 +426,7 @@ namespace COMMODORE
/** In the extended graphics mode there is only 64 chars possible. */ << 3) + _vicGraphicInfo._RC)
: memoryRef () -> value (_VICIIRegisters -> bitmapMemory () +
(_vicGraphicInfo._VC << 3) + _vicGraphicInfo._RC);

memoryRef () -> setCPUView ();
}

Expand All @@ -436,20 +445,29 @@ namespace COMMODORE
// ---
inline bool VICII::readSpriteData (size_t nS)
{
if (!_vicSpriteInfo [nS]._active)
return (false);
bool result = false;

memoryRef () -> setActiveView (_VICIIView);
_vicSpriteInfo [nS]._graphicsLineSprites = std::move (
MCHEmul::UBytes (
memoryRef () -> bytes (_VICIIRegisters -> initAddressBank () +
((size_t) memoryRef () -> value
(_VICIIRegisters -> spritePointersMemory () /** Depnds on where the escreen is located. */ + nS).value () << 6) /** 64 bytes block. */ +
/** If sprite is double-height, the data line read must be half. */

// The pointer is always read, whether it is active or not...
_vicSpriteInfo [nS]._spriteBaseAddress = _VICIIRegisters -> initAddressBank () +
((size_t) memoryRef () -> value (_VICIIRegisters -> spritePointersMemory ()
/** Depends on where the screen is located. */ + nS).value () << 6); /** 64 bytes block. */

if (_vicSpriteInfo [nS]._active)
{
_vicSpriteInfo [nS]._graphicsLineSprites =
std::move (MCHEmul::UBytes (memoryRef () -> bytes (_vicSpriteInfo [nS]._spriteBaseAddress +
(_vicSpriteInfo [nS]._line * 3) /** bytes per line. */, 3)));

result = true;
}
else
_vicSpriteInfo [nS]._graphicsLineSprites = MCHEmul::UBytes::_E;

memoryRef () -> setCPUView ();

return (true);
return (result);
}

/** The version para NTSC systems. */
Expand Down
12 changes: 12 additions & 0 deletions include/COMMODORE/VICIIRegisters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ namespace COMMODORE
/** To know whether the VICII might launch a IRQ (from its internal perspective only).
The IRQ will be or not actually launched depending on other elements like whether the IRQ flag is or not active. */
inline bool launchIRQ () const;
/** To have a code for the reason of the interruption.
There might be several reasons defined within the code. */
inline unsigned int reasonIRQCode () const;

// Temporal variables to know, when an raster or lightpen IRQ happened, where was the element that generated that.
// This temporal variables are set from the VICII directly...
Expand Down Expand Up @@ -308,6 +311,15 @@ namespace COMMODORE
(_lightPenIRQHappened && _lightPenIRQActive));
}

// ---
inline unsigned int VICIIRegisters::reasonIRQCode () const
{
return (((_rasterIRQHappened && _rasterIRQActive) ? 1 : 0) +
((_spriteCollisionWithDataIRQHappened && _spriteCollisionWithDataIRQActive) ? 2 : 0) +
((_spriteCollisionsIRQHappened && _spriteCollisionsIRQActive) ? 4 : 0) +
((_lightPenIRQHappened && _lightPenIRQActive) ? 8 : 0));
}

// ---
inline void VICIIRegisters::calculateMemoryPositions ()
{
Expand Down
4 changes: 2 additions & 2 deletions include/CORE/CPU.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ namespace MCHEmul
void removeInterrrupt (int id);
/** And to request an interrupt. \n
Receives the id of the interruption requested, the clockCycle where it has happened,
and the sender (optional). \n
the sender (optional), and a code for the reason (also optional, -1 = not defined. \n
It can be overloaded, but by default just only one interruption at the same time can be invoked. */
virtual void requestInterrupt (int id, unsigned int nC, Chip* src = nullptr);
virtual void requestInterrupt (int id, unsigned int nC, Chip* src = nullptr, int cR = -1);

/**
* The real CORE of the class. \n
Expand Down
Binary file modified monitors/R64Console/R64Console.exe
Binary file not shown.
Binary file modified monitors/R64Console/R64ConsoleD.exe
Binary file not shown.
Binary file modified monitors/RConsole/RConsole.exe
Binary file not shown.
Binary file modified monitors/RConsole/RConsoleD.exe
Binary file not shown.
Binary file modified setups/C64/C64Compiler.exe
Binary file not shown.
Binary file modified setups/C64/C64Emulator.exe
Binary file not shown.
Binary file modified setups/C64/C64EmulatorC.exe
Binary file not shown.
Binary file modified setups/C64/R64Console.exe
Binary file not shown.
Binary file modified setups/C64/Test6500.exe
Binary file not shown.
Binary file modified setups/C64/output/C64Emulator.exe
Binary file not shown.
9 changes: 7 additions & 2 deletions src/COMMODORE/CIA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,13 @@ bool COMMODORE::CIA::simulate (MCHEmul::CPU* cpu)
_serialPort.simulate (cpu, &_timerA);

// Any reason to launch an interruption?...
if (_CIARegisters -> launchInterruption ())
cpu -> requestInterrupt (_interruptId, cpu -> clockCycles () - i, this);
int cI = -1;
if ((cI = (int) _CIARegisters -> reasonIRQCode ()) != 0)
cpu -> requestInterrupt (
_interruptId,
cpu -> clockCycles () - i,
this,
cI);
}

_lastClockCycles = cpu -> clockCycles ();
Expand Down
Loading

0 comments on commit b72cd87

Please sign in to comment.