TIA documentation.

This commit is contained in:
Christian Speckner 2017-09-01 00:47:53 +02:00
parent 4440aabc56
commit cd390bcc5a
1 changed files with 102 additions and 0 deletions

View File

@ -55,12 +55,19 @@
class TIA : public Device
{
public:
/**
* These dummy register addresses are used to represent the delayed
* old / new register swap on writing GRPx and ENABL in the DelayQueue (see below).
*/
enum DummyRegisters: uInt8 {
shuffleP0 = 0xF0,
shuffleP1 = 0xF1,
shuffleBL = 0xF2
};
/**
* Possible palette entries for objects in "fixed debug color mode".
*/
enum FixedColor {
NTSC_RED = 0x30,
NTSC_ORANGE = 0x38,
@ -408,48 +415,116 @@ class TIA : public Device
string name() const override { return "TIA"; }
private:
/**
* During each line, the TIA cycles through these two states
*/
enum HState {blank, frame};
/**
* The three different modes of the priority encoder. Check TIA::renderPixel
* for a precise definition.
*/
enum Priority {pfp, score, normal};
/**
* Palette and indices for fixed debug colors.
*/
enum FixedObject { P0, M0, P1, M1, PF, BL };
FixedColor myFixedColorPalette[2][6];
private:
/**
* This callback is invoked by FrameManager when a new frame starts
*/
void onFrameStart();
/**
* This callback is invoked by FrameManager when the visible range of the
* current frame starts
*/
void onRenderingStart();
/**
* This callback is invoked by FrameManager when the current frame completes.
*/
void onFrameComplete();
/**
* Called when the CPU enters halt state (RDY pulled low). Execution continues
* immediatelly afterwards, so we have to adjust the system clock to account
* for the cycles the 6502 spent in halt state.
*/
void onHalt();
/**
* Run and forward TIA emulation to the current system clock.
*/
void updateEmulation();
/**
* Execute colorClocks cycles of TIA simulation
*/
void cycle(uInt32 colorClocks);
/**
* Advance the movement logic by a single clock.
*/
void tickMovement();
/**
* Advance a single clock during hblank.
*/
void tickHblank();
/**
* Advance a single clock duing the visible part of the scanline.
*/
void tickHframe();
/**
* Execute a RSYNC
*/
void applyRsync();
/**
* Update the collision bitfield.
*/
void updateCollision();
/**
* Render the current pixel into the framebuffer
*/
void renderPixel(uInt32 x, uInt32 y);
/**
* Clear the first 8 pixels of a scanline with black if we are in hblank (called during HMOVE)
*/
void clearHmoveComb();
/**
* Advance a line and update our state accordingly.
*/
void nextLine();
/**
* Clone the last line. Called in nextLine if TIA state was unchanged.
*/
void cloneLastLine();
/**
* Execute a delayed write. Called when the DelayQueue is pumped.
*/
void delayedWrite(uInt8 address, uInt8 value);
/**
* Update all paddle readout circuits to the current controller state.
*/
void updatePaddle(uInt8 idx);
/**
* Get the target counter value during a RESx. This exentially depends on the position
* in the current scanline.
uInt8 resxCounter();
/**
@ -470,12 +545,32 @@ class TIA : public Device
Sound& mySound;
Settings& mySettings;
/**
* The length of the delay queue (maximum number of clocks delay)
*/
static constexpr unsigned delayQueueLength = 16;
/**
* The size of the delay queue (maximum number of writes scheduled in a single slot).
*/
static constexpr unsigned delayQueueSize = 16;
/**
* A list of delayed writes that are queued up for future execution. Delayed
* writes can be both actual writes whose effect is delayed by one or more clocs
* on real hardware and delayed side effects of certain operations (GRPx!).
*/
DelayQueue<delayQueueLength, delayQueueSize> myDelayQueue;
/**
* The frame manager is responsible for detecting frame boundaries and the visible
* region of each frame.
*/
FrameManager myFrameManager;
/**
* The various TIA objects.
*/
Background myBackground;
Playfield myPlayfield;
Missile myMissile0;
@ -483,8 +578,15 @@ class TIA : public Device
Player myPlayer0;
Player myPlayer1;
Ball myBall;
/**
* The paddle readout circuits.
*/
PaddleReader myPaddleReaders[4];
/**
* Circuits for the "latched inputs".
*/
LatchedInput myInput0;
LatchedInput myInput1;