mirror of https://github.com/stella-emu/stella.git
Delete old TIA core (files are only moved for now).
This commit is contained in:
parent
f7e712386b
commit
4b5a02903e
File diff suppressed because it is too large
Load Diff
|
@ -1,645 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2016 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef TIA_DEFAULT_CORE_HXX
|
||||
#define TIA_DEFAULT_CORE_HXX
|
||||
|
||||
class Console;
|
||||
class Settings;
|
||||
class Sound;
|
||||
|
||||
#include "AbstractTIA.hxx"
|
||||
#include "bspf.hxx"
|
||||
#include "System.hxx"
|
||||
#include "TIATables.hxx"
|
||||
|
||||
namespace TIADefaultCore {
|
||||
|
||||
/**
|
||||
This class is a device that emulates the Television Interface Adaptor
|
||||
found in the Atari 2600 and 7800 consoles. The Television Interface
|
||||
Adaptor is an integrated circuit designed to interface between an
|
||||
eight bit microprocessor and a television video modulator. It converts
|
||||
eight bit parallel data into serial outputs for the color, luminosity,
|
||||
and composite sync required by a video modulator.
|
||||
|
||||
This class outputs the serial data into a frame buffer which can then
|
||||
be displayed on screen.
|
||||
|
||||
@author Bradford W. Mott
|
||||
@version $Id$
|
||||
*/
|
||||
class TIA : public AbstractTIA
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
Create a new TIA for the specified console
|
||||
|
||||
@param console The console the TIA is associated with
|
||||
@param sound The sound object the TIA is associated with
|
||||
@param settings The settings object for this TIA device
|
||||
*/
|
||||
TIA(Console& console, Sound& sound, Settings& settings);
|
||||
virtual ~TIA() = default;
|
||||
|
||||
public:
|
||||
/**
|
||||
Reset device to its power-on state
|
||||
*/
|
||||
void reset() override;
|
||||
|
||||
/**
|
||||
Reset frame to current YStart/Height properties
|
||||
*/
|
||||
void frameReset() override;
|
||||
|
||||
/**
|
||||
Notification method invoked by the system right before the
|
||||
system resets its cycle counter to zero. It may be necessary
|
||||
to override this method for devices that remember cycle counts.
|
||||
*/
|
||||
void systemCyclesReset() override;
|
||||
|
||||
/**
|
||||
Install TIA in the specified system. Invoked by the system
|
||||
when the TIA is attached to it.
|
||||
|
||||
@param system The system the device should install itself in
|
||||
*/
|
||||
void install(System& system) override;
|
||||
|
||||
/**
|
||||
Install TIA in the specified system and device. Invoked by
|
||||
the system when the TIA is attached to it. All devices
|
||||
which invoke this method take responsibility for chaining
|
||||
requests back to *this* device.
|
||||
|
||||
@param system The system the device should install itself in
|
||||
@param device The device responsible for this address space
|
||||
*/
|
||||
void installDelegate(System& system, Device& device) override;
|
||||
|
||||
/**
|
||||
Save the current state of this device to the given Serializer.
|
||||
|
||||
@param out The Serializer object to use
|
||||
@return False on any errors, else true
|
||||
*/
|
||||
bool save(Serializer& out) const override;
|
||||
|
||||
/**
|
||||
Load the current state of this device from the given Serializer.
|
||||
|
||||
@param in The Serializer object to use
|
||||
@return False on any errors, else true
|
||||
*/
|
||||
bool load(Serializer& in) override;
|
||||
|
||||
/**
|
||||
The following are very similar to save() and load(), except they
|
||||
do a 'deeper' save of the display data itself.
|
||||
|
||||
Normally, the internal framebuffer doesn't need to be saved to
|
||||
a state file, since the file already contains all the information
|
||||
needed to re-create it, starting from scanline 0. In effect, when a
|
||||
state is loaded, the framebuffer is empty, and the next call to
|
||||
update() generates valid framebuffer data.
|
||||
|
||||
However, state files saved from the debugger need more information,
|
||||
such as the exact state of the internal framebuffer itself *before*
|
||||
we call update(), including if the display was in partial frame mode.
|
||||
|
||||
Essentially, a normal state save has 'frame resolution', whereas
|
||||
the debugger state save has 'cycle resolution', and hence needs
|
||||
more information. The methods below save/load this extra info,
|
||||
and eliminate having to save approx. 50K to normal state files.
|
||||
*/
|
||||
bool saveDisplay(Serializer& out) const override;
|
||||
bool loadDisplay(Serializer& in) override;
|
||||
|
||||
/**
|
||||
Get a descriptor for the device name (used in error checking).
|
||||
|
||||
@return The name of the object
|
||||
*/
|
||||
string name() const override { return "TIA"; }
|
||||
|
||||
/**
|
||||
Get the byte at the specified address
|
||||
|
||||
@return The byte at the specified address
|
||||
*/
|
||||
uInt8 peek(uInt16 address) override;
|
||||
|
||||
/**
|
||||
Change the byte at the specified address to the given value
|
||||
|
||||
@param address The address where the value should be stored
|
||||
@param value The value to be stored at the address
|
||||
|
||||
@return True if the poke changed the device address space, else false
|
||||
*/
|
||||
bool poke(uInt16 address, uInt8 value) override;
|
||||
|
||||
/**
|
||||
This method should be called at an interval corresponding to the
|
||||
desired frame rate to update the TIA. Invoking this method will update
|
||||
the graphics buffer and generate the corresponding audio samples.
|
||||
*/
|
||||
void update() override;
|
||||
|
||||
/**
|
||||
Answers the current frame buffer
|
||||
|
||||
@return Pointer to the current frame buffer
|
||||
*/
|
||||
uInt8* currentFrameBuffer() const override
|
||||
{ return myCurrentFrameBuffer.get() + myFramePointerOffset + myCurrentFrameJitter; }
|
||||
|
||||
/**
|
||||
Answers the previous frame buffer
|
||||
|
||||
@return Pointer to the previous frame buffer
|
||||
*/
|
||||
uInt8* previousFrameBuffer() const override
|
||||
{ return myPreviousFrameBuffer.get() + myFramePointerOffset; }
|
||||
|
||||
/**
|
||||
Answers the height of the frame buffer
|
||||
*/
|
||||
inline uInt32 height() const override { return myFrameHeight; }
|
||||
inline uInt32 ystart() const override { return myFrameYStart; }
|
||||
|
||||
/**
|
||||
Changes the current Height/YStart properties.
|
||||
Note that calls to these method(s) must be eventually followed by
|
||||
::frameReset() for the changes to take effect.
|
||||
*/
|
||||
void setHeight(uInt32 height) override { myFrameHeight = height; }
|
||||
void setYStart(uInt32 ystart) override { myFrameYStart = ystart; }
|
||||
|
||||
/**
|
||||
Enables/disables auto-frame calculation. If enabled, the TIA
|
||||
re-adjusts the framerate at regular intervals.
|
||||
|
||||
@param mode Whether to enable or disable all auto-frame calculation
|
||||
*/
|
||||
void enableAutoFrame(bool mode) override { myAutoFrameEnabled = mode; }
|
||||
|
||||
/**
|
||||
Enables/disables color-loss for PAL modes only.
|
||||
|
||||
@param mode Whether to enable or disable PAL color-loss mode
|
||||
*/
|
||||
void enableColorLoss(bool mode) override
|
||||
{ myColorLossEnabled = myFramerate <= 55 ? mode : false; }
|
||||
|
||||
/**
|
||||
Answers whether this TIA runs at NTSC or PAL scanrates,
|
||||
based on how many frames of out the total count are PAL frames.
|
||||
*/
|
||||
bool isPAL() const override
|
||||
{ return double(myPALFrameCounter) / myFrameCounter >= (25.0/60.0); }
|
||||
|
||||
/**
|
||||
Answers the current color clock we've gotten to on this scanline.
|
||||
|
||||
@return The current color clock
|
||||
*/
|
||||
uInt32 clocksThisLine() const override
|
||||
{ return ((mySystem->cycles() * 3) - myClockWhenFrameStarted) % 228; }
|
||||
|
||||
/**
|
||||
Answers the total number of scanlines the TIA generated in producing
|
||||
the current frame buffer. For partial frames, this will be the
|
||||
current scanline.
|
||||
|
||||
@return The total number of scanlines generated
|
||||
*/
|
||||
uInt32 scanlines() const override
|
||||
{ return ((mySystem->cycles() * 3) - myClockWhenFrameStarted) / 228; }
|
||||
|
||||
/**
|
||||
Answers whether the TIA is currently in 'partial frame' mode
|
||||
(we're in between a call of startFrame and endFrame).
|
||||
|
||||
@return If we're in partial frame mode
|
||||
*/
|
||||
bool partialFrame() const override { return myPartialFrameFlag; }
|
||||
|
||||
/**
|
||||
Answers the first scanline at which drawing occured in the last frame.
|
||||
|
||||
@return The starting scanline
|
||||
*/
|
||||
uInt32 startScanline() const override { return myStartScanline; }
|
||||
|
||||
/**
|
||||
Answers the current position of the virtual 'electron beam' used to
|
||||
draw the TIA image. If not in partial frame mode, the position is
|
||||
defined to be in the lower right corner (@ width/height of the screen).
|
||||
Note that the coordinates are with respect to currentFrameBuffer(),
|
||||
taking any YStart values into account.
|
||||
|
||||
@return The x/y coordinates of the scanline electron beam, and whether
|
||||
it is in the visible/viewable area of the screen
|
||||
*/
|
||||
bool scanlinePos(uInt16& x, uInt16& y) const override;
|
||||
|
||||
/**
|
||||
Enables/disable/toggle the specified (or all) TIA bit(s). Note that
|
||||
disabling a graphical object also disables its collisions.
|
||||
|
||||
@param mode 1/0 indicates on/off, and values greater than 1 mean
|
||||
flip the bit from its current state
|
||||
|
||||
@return Whether the bit was enabled or disabled
|
||||
*/
|
||||
bool toggleBit(TIABit b, uInt8 mode = 2) override;
|
||||
bool toggleBits() override;
|
||||
|
||||
/**
|
||||
Enables/disable/toggle the specified (or all) TIA bit collision(s).
|
||||
|
||||
@param mode 1/0 indicates on/off, and values greater than 1 mean
|
||||
flip the collision from its current state
|
||||
|
||||
@return Whether the collision was enabled or disabled
|
||||
*/
|
||||
bool toggleCollision(TIABit b, uInt8 mode = 2) override;
|
||||
bool toggleCollisions() override;
|
||||
|
||||
/**
|
||||
Enables/disable/toggle 'fixed debug colors' mode.
|
||||
|
||||
@param mode 1/0 indicates on/off, otherwise flip from
|
||||
its current state
|
||||
|
||||
@return Whether the mode was enabled or disabled
|
||||
*/
|
||||
bool toggleFixedColors(uInt8 mode = 2) override;
|
||||
|
||||
/**
|
||||
Enable/disable/query state of 'undriven/floating TIA pins'.
|
||||
|
||||
@param mode 1/0 indicates on/off, otherwise return the current state
|
||||
|
||||
@return Whether the mode was enabled or disabled
|
||||
*/
|
||||
bool driveUnusedPinsRandom(uInt8 mode = 2) override;
|
||||
|
||||
/**
|
||||
Enables/disable/toggle 'scanline jittering' mode, and set the
|
||||
recovery 'factor'.
|
||||
|
||||
@param mode 1/0 indicates on/off, otherwise flip from
|
||||
its current state
|
||||
|
||||
@return Whether the mode was enabled or disabled
|
||||
*/
|
||||
bool toggleJitter(uInt8 mode = 2) override;
|
||||
void setJitterRecoveryFactor(Int32 f) override { myJitterRecoveryFactor = f; }
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
/**
|
||||
This method should be called to update the TIA with a new scanline.
|
||||
*/
|
||||
void updateScanline() override;
|
||||
|
||||
/**
|
||||
This method should be called to update the TIA with a new partial
|
||||
scanline by stepping one CPU instruction.
|
||||
*/
|
||||
void updateScanlineByStep() override;
|
||||
|
||||
/**
|
||||
This method should be called to update the TIA with a new partial
|
||||
scanline by tracing to target address.
|
||||
*/
|
||||
void updateScanlineByTrace(int target) override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
/**
|
||||
Enables/disables all TIABit bits. Note that disabling a graphical
|
||||
object also disables its collisions.
|
||||
|
||||
@param mode Whether to enable or disable all bits
|
||||
*/
|
||||
void enableBits(bool mode);
|
||||
|
||||
/**
|
||||
Enables/disables all TIABit collisions.
|
||||
|
||||
@param mode Whether to enable or disable all collisions
|
||||
*/
|
||||
void enableCollisions(bool mode);
|
||||
|
||||
// Reset all instance variables to the initial state
|
||||
void initialize();
|
||||
|
||||
// Update the current frame buffer to the specified color clock
|
||||
void updateFrame(Int32 clock);
|
||||
|
||||
// Waste cycles until the current scanline is finished
|
||||
void waitHorizontalSync();
|
||||
|
||||
// Reset horizontal sync counter
|
||||
void waitHorizontalRSync();
|
||||
|
||||
// Clear both internal TIA buffers to black (palette color 0)
|
||||
void clearBuffers();
|
||||
|
||||
// Set up bookkeeping for the next frame
|
||||
void startFrame();
|
||||
|
||||
// Update bookkeeping at end of frame
|
||||
void endFrame();
|
||||
|
||||
// Convert resistance from ports to dumped value
|
||||
uInt8 dumpedInputPort(int resistance);
|
||||
|
||||
// Write the specified value to the HMOVE registers at the given clock
|
||||
void pokeHMP0(uInt8 value, Int32 clock);
|
||||
void pokeHMP1(uInt8 value, Int32 clock);
|
||||
void pokeHMM0(uInt8 value, Int32 clock);
|
||||
void pokeHMM1(uInt8 value, Int32 clock);
|
||||
void pokeHMBL(uInt8 value, Int32 clock);
|
||||
|
||||
// Apply motion to registers when HMOVE is currently active
|
||||
void applyActiveHMOVEMotion(int hpos, Int16& pos, Int32 motionClock);
|
||||
|
||||
// Apply motion to registers when HMOVE was previously active
|
||||
void applyPreviousHMOVEMotion(int hpos, Int16& pos, uInt8 motion);
|
||||
|
||||
private:
|
||||
// Console the TIA is associated with
|
||||
Console& myConsole;
|
||||
|
||||
// Sound object the TIA is associated with
|
||||
Sound& mySound;
|
||||
|
||||
// Settings object the TIA is associated with
|
||||
Settings& mySettings;
|
||||
|
||||
// Pointer to the current frame buffer
|
||||
BytePtr myCurrentFrameBuffer;
|
||||
|
||||
// Pointer to the previous frame buffer
|
||||
BytePtr myPreviousFrameBuffer;
|
||||
|
||||
// Pointer to the next pixel that will be drawn in the current frame buffer
|
||||
uInt8* myFramePointer;
|
||||
|
||||
// Indicates offset used by the exported frame buffer
|
||||
// (the exported frame buffer is a vertical 'sliding window' of the actual buffer)
|
||||
uInt32 myFramePointerOffset;
|
||||
|
||||
// Indicates the number of 'colour clocks' offset from the base
|
||||
// frame buffer pointer
|
||||
// (this is used when loading state files with a 'partial' frame)
|
||||
uInt32 myFramePointerClocks;
|
||||
|
||||
// Indicated what scanline the frame should start being drawn at
|
||||
uInt32 myFrameYStart;
|
||||
|
||||
// Indicates the height of the frame in scanlines
|
||||
uInt32 myFrameHeight;
|
||||
|
||||
// Indicates offset in color clocks when display should stop
|
||||
uInt32 myStopDisplayOffset;
|
||||
|
||||
// Indicates color clocks when the current frame began
|
||||
Int32 myClockWhenFrameStarted;
|
||||
|
||||
// Indicates color clocks when frame should begin to be drawn
|
||||
Int32 myClockStartDisplay;
|
||||
|
||||
// Indicates color clocks when frame should stop being drawn
|
||||
Int32 myClockStopDisplay;
|
||||
|
||||
// Indicates color clocks when the frame was last updated
|
||||
Int32 myClockAtLastUpdate;
|
||||
|
||||
// Indicates how many color clocks remain until the end of
|
||||
// current scanline. This value is valid during the
|
||||
// displayed portion of the frame.
|
||||
Int32 myClocksToEndOfScanLine;
|
||||
|
||||
// Indicates the total number of scanlines generated by the last frame
|
||||
uInt32 myScanlineCountForLastFrame;
|
||||
|
||||
// Indicates the maximum number of scanlines to be generated for a frame
|
||||
uInt32 myMaximumNumberOfScanlines;
|
||||
|
||||
// Indicates potentially the first scanline at which drawing occurs
|
||||
uInt32 myStartScanline;
|
||||
|
||||
// Color clock when VSYNC ending causes a new frame to be started
|
||||
Int32 myVSYNCFinishClock;
|
||||
|
||||
uInt8 myVSYNC; // Holds the VSYNC register value
|
||||
uInt8 myVBLANK; // Holds the VBLANK register value
|
||||
|
||||
uInt8 myNUSIZ0; // Number and size of player 0 and missle 0
|
||||
uInt8 myNUSIZ1; // Number and size of player 1 and missle 1
|
||||
|
||||
uInt8 myPlayfieldPriorityAndScore;
|
||||
uInt8 myPriorityEncoder[2][256];
|
||||
uInt8 myColor[8];
|
||||
uInt8 myFixedColor[8];
|
||||
uInt8* myColorPtr;
|
||||
|
||||
uInt8 myCTRLPF; // Playfield control register
|
||||
|
||||
bool myREFP0; // Indicates if player 0 is being reflected
|
||||
bool myREFP1; // Indicates if player 1 is being reflected
|
||||
|
||||
uInt32 myPF; // Playfield graphics (19-12:PF2 11-4:PF1 3-0:PF0)
|
||||
|
||||
uInt8 myGRP0; // Player 0 graphics register
|
||||
uInt8 myGRP1; // Player 1 graphics register
|
||||
|
||||
uInt8 myDGRP0; // Player 0 delayed graphics register
|
||||
uInt8 myDGRP1; // Player 1 delayed graphics register
|
||||
|
||||
bool myENAM0; // Indicates if missle 0 is enabled
|
||||
bool myENAM1; // Indicates if missle 1 is enabled
|
||||
|
||||
bool myENABL; // Indicates if the ball is enabled
|
||||
bool myDENABL; // Indicates if the vertically delayed ball is enabled
|
||||
|
||||
uInt8 myHMP0; // Player 0 horizontal motion register
|
||||
uInt8 myHMP1; // Player 1 horizontal motion register
|
||||
uInt8 myHMM0; // Missle 0 horizontal motion register
|
||||
uInt8 myHMM1; // Missle 1 horizontal motion register
|
||||
uInt8 myHMBL; // Ball horizontal motion register
|
||||
|
||||
bool myVDELP0; // Indicates if player 0 is being vertically delayed
|
||||
bool myVDELP1; // Indicates if player 1 is being vertically delayed
|
||||
bool myVDELBL; // Indicates if the ball is being vertically delayed
|
||||
|
||||
bool myRESMP0; // Indicates if missle 0 is reset to player 0
|
||||
bool myRESMP1; // Indicates if missle 1 is reset to player 1
|
||||
|
||||
uInt16 myCollision; // Collision register
|
||||
|
||||
// Determines whether specified collisions are enabled or disabled
|
||||
// The lower 16 bits are and'ed with the collision register to mask out
|
||||
// any collisions we don't want to be processed
|
||||
// The upper 16 bits are used to store which objects is currently
|
||||
// enabled or disabled
|
||||
// This is necessary since there are 15 collision combinations which
|
||||
// are controlled by 6 objects
|
||||
uInt32 myCollisionEnabledMask;
|
||||
|
||||
// Note that these position registers contain the color clock
|
||||
// on which the object's serial output should begin (0 to 159)
|
||||
Int16 myPOSP0; // Player 0 position register
|
||||
Int16 myPOSP1; // Player 1 position register
|
||||
Int16 myPOSM0; // Missle 0 position register
|
||||
Int16 myPOSM1; // Missle 1 position register
|
||||
Int16 myPOSBL; // Ball position register
|
||||
|
||||
// The color clocks elapsed so far for each of the graphical objects,
|
||||
// as denoted by 'MOTCK' line described in A. Towers TIA Hardware Notes
|
||||
Int32 myMotionClockP0;
|
||||
Int32 myMotionClockP1;
|
||||
Int32 myMotionClockM0;
|
||||
Int32 myMotionClockM1;
|
||||
Int32 myMotionClockBL;
|
||||
|
||||
// Indicates 'start' signal for each of the graphical objects as
|
||||
// described in A. Towers TIA Hardware Notes
|
||||
Int32 myStartP0;
|
||||
Int32 myStartP1;
|
||||
Int32 myStartM0;
|
||||
Int32 myStartM1;
|
||||
|
||||
// Index into the player mask arrays indicating whether display
|
||||
// of the first copy should be suppressed
|
||||
uInt8 mySuppressP0;
|
||||
uInt8 mySuppressP1;
|
||||
|
||||
// Latches for 'more motion required' as described in A. Towers TIA
|
||||
// Hardware Notes
|
||||
bool myHMP0mmr;
|
||||
bool myHMP1mmr;
|
||||
bool myHMM0mmr;
|
||||
bool myHMM1mmr;
|
||||
bool myHMBLmmr;
|
||||
|
||||
// Graphics for Player 0 that should be displayed. This will be
|
||||
// reflected if the player is being reflected.
|
||||
uInt8 myCurrentGRP0;
|
||||
|
||||
// Graphics for Player 1 that should be displayed. This will be
|
||||
// reflected if the player is being reflected.
|
||||
uInt8 myCurrentGRP1;
|
||||
|
||||
// It's VERY important that the BL, M0, M1, P0 and P1 current
|
||||
// mask pointers are always on a uInt32 boundary. Otherwise,
|
||||
// the TIA code will fail on a good number of CPUs.
|
||||
const uInt8* myP0Mask;
|
||||
const uInt8* myM0Mask;
|
||||
const uInt8* myM1Mask;
|
||||
const uInt8* myP1Mask;
|
||||
const uInt8* myBLMask;
|
||||
const uInt32* myPFMask;
|
||||
|
||||
// Audio values; only used by TIADebug
|
||||
uInt8 myAUDV0, myAUDV1, myAUDC0, myAUDC1, myAUDF0, myAUDF1;
|
||||
|
||||
// Indicates when the dump for paddles was last set
|
||||
Int32 myDumpDisabledCycle;
|
||||
|
||||
// Indicates if the dump is current enabled for the paddles
|
||||
bool myDumpEnabled;
|
||||
|
||||
// Latches for INPT4 and INPT5
|
||||
uInt8 myINPT4, myINPT5;
|
||||
|
||||
// Indicates if HMOVE blanks are currently or previously enabled,
|
||||
// and at which horizontal position the HMOVE was initiated
|
||||
Int32 myCurrentHMOVEPos;
|
||||
Int32 myPreviousHMOVEPos;
|
||||
bool myHMOVEBlankEnabled;
|
||||
|
||||
// Indicates if unused TIA pins are randomly driven high or low
|
||||
// Otherwise, they take on the value previously on the databus
|
||||
bool myTIAPinsDriven;
|
||||
|
||||
// Bitmap of the objects that should be considered while drawing
|
||||
uInt8 myEnabledObjects;
|
||||
|
||||
// Determines whether specified bits (from TIABit) are enabled or disabled
|
||||
// This is and'ed with the enabled objects each scanline to mask out any
|
||||
// objects we don't want to be processed
|
||||
uInt8 myDisabledObjects;
|
||||
|
||||
// Indicates if color loss should be enabled or disabled. Color loss
|
||||
// occurs on PAL (and maybe SECAM) systems when the previous frame
|
||||
// contains an odd number of scanlines.
|
||||
bool myColorLossEnabled;
|
||||
|
||||
// Indicates whether we're done with the current frame. poke() clears this
|
||||
// when VSYNC is strobed or the max scanlines/frame limit is hit.
|
||||
bool myPartialFrameFlag;
|
||||
|
||||
// Automatic framerate correction based on number of scanlines
|
||||
bool myAutoFrameEnabled;
|
||||
|
||||
// Number of total frames displayed by this TIA
|
||||
uInt32 myFrameCounter;
|
||||
|
||||
// Number of PAL frames displayed by this TIA
|
||||
uInt32 myPALFrameCounter;
|
||||
|
||||
// The framerate currently in use by the Console
|
||||
float myFramerate;
|
||||
|
||||
// Whether TIA bits/collisions are currently enabled/disabled
|
||||
bool myBitsEnabled, myCollisionsEnabled;
|
||||
|
||||
// Whether to enable jitter emulation
|
||||
bool myJitterEnabled;
|
||||
|
||||
// Derived from the difference between the scanline counts of the
|
||||
// current and prior frames. If non-zero the next frame should jitter.
|
||||
Int32 myNextFrameJitter;
|
||||
|
||||
// Jitter amount for the current frame
|
||||
Int32 myCurrentFrameJitter;
|
||||
|
||||
// Large jitter values will take multiple frames to recover from
|
||||
Int32 myJitterRecovery, myJitterRecoveryFactor;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
TIA() = delete;
|
||||
TIA(const TIA&) = delete;
|
||||
TIA(TIA&&) = delete;
|
||||
TIA& operator=(const TIA&) = delete;
|
||||
TIA& operator=(TIA&&) = delete;
|
||||
};
|
||||
|
||||
} // namespace TIADefaultCore
|
||||
|
||||
#endif
|
|
@ -1,730 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2016 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "TIATables.hxx"
|
||||
|
||||
namespace TIADefaultCore {
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TIATables::computeAllTables()
|
||||
{
|
||||
memset(DisabledMask, 0, 640);
|
||||
buildCollisionMaskTable();
|
||||
buildPxMaskTable();
|
||||
buildMxMaskTable();
|
||||
buildBLMaskTable();
|
||||
buildPFMaskTable();
|
||||
buildGRPReflectTable();
|
||||
buildPxPosResetWhenTable();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TIATables::buildCollisionMaskTable()
|
||||
{
|
||||
for(uInt8 i = 0; i < 64; ++i)
|
||||
{
|
||||
CollisionMask[i] = 0;
|
||||
|
||||
if((i & M0Bit) && (i & P1Bit)) // M0-P1
|
||||
CollisionMask[i] |= Cx_M0P1;
|
||||
|
||||
if((i & M0Bit) && (i & P0Bit)) // M0-P0
|
||||
CollisionMask[i] |= Cx_M0P0;
|
||||
|
||||
if((i & M1Bit) && (i & P0Bit)) // M1-P0
|
||||
CollisionMask[i] |= Cx_M1P0;
|
||||
|
||||
if((i & M1Bit) && (i & P1Bit)) // M1-P1
|
||||
CollisionMask[i] |= Cx_M1P1;
|
||||
|
||||
if((i & P0Bit) && (i & PFBit)) // P0-PF
|
||||
CollisionMask[i] |= Cx_P0PF;
|
||||
|
||||
if((i & P0Bit) && (i & BLBit)) // P0-BL
|
||||
CollisionMask[i] |= Cx_P0BL;
|
||||
|
||||
if((i & P1Bit) && (i & PFBit)) // P1-PF
|
||||
CollisionMask[i] |= Cx_P1PF;
|
||||
|
||||
if((i & P1Bit) && (i & BLBit)) // P1-BL
|
||||
CollisionMask[i] |= Cx_P1BL;
|
||||
|
||||
if((i & M0Bit) && (i & PFBit)) // M0-PF
|
||||
CollisionMask[i] |= Cx_M0PF;
|
||||
|
||||
if((i & M0Bit) && (i & BLBit)) // M0-BL
|
||||
CollisionMask[i] |= Cx_M0BL;
|
||||
|
||||
if((i & M1Bit) && (i & PFBit)) // M1-PF
|
||||
CollisionMask[i] |= Cx_M1PF;
|
||||
|
||||
if((i & M1Bit) && (i & BLBit)) // M1-BL
|
||||
CollisionMask[i] |= Cx_M1BL;
|
||||
|
||||
if((i & BLBit) && (i & PFBit)) // BL-PF
|
||||
CollisionMask[i] |= Cx_BLPF;
|
||||
|
||||
if((i & P0Bit) && (i & P1Bit)) // P0-P1
|
||||
CollisionMask[i] |= Cx_P0P1;
|
||||
|
||||
if((i & M0Bit) && (i & M1Bit)) // M0-M1
|
||||
CollisionMask[i] |= Cx_M0M1;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// [suppress mode:2][nusiz:8][pixel:320]
|
||||
// suppress=1: suppress on
|
||||
// suppress=0: suppress off
|
||||
void TIATables::buildPxMaskTable()
|
||||
{
|
||||
Int32 x, suppress, nusiz;
|
||||
|
||||
// Set the player mask table to all zeros
|
||||
for(nusiz = 0; nusiz < 8; ++nusiz)
|
||||
for(x = 0; x < 160; ++x)
|
||||
PxMask[0][nusiz][x] = PxMask[1][nusiz][x] = 0x00;
|
||||
|
||||
// Now, compute the player mask table
|
||||
for(suppress = 0; suppress < 2; ++suppress)
|
||||
{
|
||||
for(nusiz = 0; nusiz < 8; ++nusiz)
|
||||
{
|
||||
for(x = 0; x < 160 + 72; ++x)
|
||||
{
|
||||
// nusiz:
|
||||
// 0: one copy
|
||||
// 1: two copies-close
|
||||
// 2: two copies-med
|
||||
// 3: three copies-close
|
||||
// 4: two copies-wide
|
||||
// 5: double size player
|
||||
// 6: 3 copies medium
|
||||
// 7: quad sized player
|
||||
switch(nusiz)
|
||||
{
|
||||
case 0x00:
|
||||
if((suppress == 0) && (x >= 0) && (x < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
if((suppress == 0) && (x >= 0) && (x < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
|
||||
else if(((x - 16) >= 0) && ((x - 16) < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 16);
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
if((suppress == 0) && (x >= 0) && (x < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
|
||||
else if(((x - 32) >= 0) && ((x - 32) < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 32);
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
if((suppress == 0) && (x >= 0) && (x < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
|
||||
else if(((x - 16) >= 0) && ((x - 16) < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 16);
|
||||
else if(((x - 32) >= 0) && ((x - 32) < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 32);
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
if((suppress == 0) && (x >= 0) && (x < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
|
||||
else if(((x - 64) >= 0) && ((x - 64) < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 64);
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
// For some reason in double size nusiz the player's output
|
||||
// is delayed by one pixel thus we use > instead of >=
|
||||
if((suppress == 0) && (x > 0) && (x <= 16))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> ((x - 1)/2);
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
if((suppress == 0) && (x >= 0) && (x < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
|
||||
else if(((x - 32) >= 0) && ((x - 32) < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 32);
|
||||
else if(((x - 64) >= 0) && ((x - 64) < 8))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 64);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
// For some reason in quad size nusiz the player's output
|
||||
// is delayed by one pixel thus we use > instead of >=
|
||||
if((suppress == 0) && (x > 0) && (x <= 32))
|
||||
PxMask[suppress][nusiz][x % 160] = 0x80 >> ((x - 1)/4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy data into wrap-around area
|
||||
for(x = 0; x < 160; ++x)
|
||||
PxMask[suppress][nusiz][x + 160] = PxMask[suppress][nusiz][x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// [number:8][size:5][pixel:320]
|
||||
void TIATables::buildMxMaskTable()
|
||||
{
|
||||
Int32 x, size, number;
|
||||
|
||||
// Clear the missle table to start with
|
||||
for(number = 0; number < 8; ++number)
|
||||
for(size = 0; size < 5; ++size)
|
||||
for(x = 0; x < 160; ++x)
|
||||
MxMask[number][size][x] = false;
|
||||
|
||||
for(number = 0; number < 8; ++number)
|
||||
{
|
||||
for(size = 0; size < 5; ++size)
|
||||
{
|
||||
for(x = 0; x < 160 + 72; ++x)
|
||||
{
|
||||
// For the following, size index = 4 is almost exactly the same as
|
||||
// index = 2; that is, 1 << 2, or 4 colour clocks wide
|
||||
// To simulate the weirdness in the Cosmic Ark starfield effect,
|
||||
// each group of 4 pixels has its 3rd pixel blanked
|
||||
switch(number)
|
||||
{
|
||||
// Only one copy of the missle
|
||||
case 0x00:
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Two copies - close
|
||||
case 0x01:
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
else if(((x - 16) >= 0) && ((x - 16) < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 16) >= 0) && ((x - 16) < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Two copies - medium
|
||||
case 0x02:
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Three copies - close
|
||||
case 0x03:
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
else if(((x - 16) >= 0) && ((x - 16) < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 16) >= 0) && ((x - 16) < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Two copies - wide
|
||||
case 0x04:
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
else if(((x - 64) >= 0) && ((x - 64) < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 64) >= 0) && ((x - 64) < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Three copies - medium
|
||||
case 0x06:
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
else if(((x - 64) >= 0) && ((x - 64) < (1 << size)))
|
||||
MxMask[number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 64) >= 0) && ((x - 64) < (1 << 2)))
|
||||
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy data into wrap-around area
|
||||
for(x = 0; x < 160; ++x)
|
||||
MxMask[number][size][x + 160] =
|
||||
MxMask[number][size][x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// [size:4][pixel:320]
|
||||
void TIATables::buildBLMaskTable()
|
||||
{
|
||||
for(Int32 size = 0; size < 4; ++size)
|
||||
{
|
||||
Int32 x;
|
||||
|
||||
// Set all of the masks to false to start with
|
||||
for(x = 0; x < 160; ++x)
|
||||
BLMask[size][x] = false;
|
||||
|
||||
// Set the necessary fields true
|
||||
for(x = 0; x < 160 + 8; ++x)
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
BLMask[size][x % 160] = true;
|
||||
|
||||
// Copy fields into the wrap-around area of the mask
|
||||
for(x = 0; x < 160; ++x)
|
||||
BLMask[size][x + 160] = BLMask[size][x];
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// [reflect:2][pixel:160]
|
||||
// reflect=1: reflection on
|
||||
// reflect=0: reflection off
|
||||
void TIATables::buildPFMaskTable()
|
||||
{
|
||||
Int32 x;
|
||||
|
||||
// Compute playfield mask table for non-reflected mode
|
||||
for(x = 0; x < 160; ++x)
|
||||
{
|
||||
if(x < 16)
|
||||
PFMask[0][x] = 0x00001 << (x >> 2);
|
||||
else if(x < 48)
|
||||
PFMask[0][x] = 0x00800 >> ((x - 16) >> 2);
|
||||
else if(x < 80)
|
||||
PFMask[0][x] = 0x01000 << ((x - 48) >> 2);
|
||||
else if(x < 96)
|
||||
PFMask[0][x] = 0x00001 << ((x - 80) >> 2);
|
||||
else if(x < 128)
|
||||
PFMask[0][x] = 0x00800 >> ((x - 96) >> 2);
|
||||
else if(x < 160)
|
||||
PFMask[0][x] = 0x01000 << ((x - 128) >> 2);
|
||||
}
|
||||
|
||||
// Compute playfield mask table for reflected mode
|
||||
for(x = 0; x < 160; ++x)
|
||||
{
|
||||
if(x < 16)
|
||||
PFMask[1][x] = 0x00001 << (x >> 2);
|
||||
else if(x < 48)
|
||||
PFMask[1][x] = 0x00800 >> ((x - 16) >> 2);
|
||||
else if(x < 80)
|
||||
PFMask[1][x] = 0x01000 << ((x - 48) >> 2);
|
||||
else if(x < 112)
|
||||
PFMask[1][x] = 0x80000 >> ((x - 80) >> 2);
|
||||
else if(x < 144)
|
||||
PFMask[1][x] = 0x00010 << ((x - 112) >> 2);
|
||||
else if(x < 160)
|
||||
PFMask[1][x] = 0x00008 >> ((x - 144) >> 2);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TIATables::buildGRPReflectTable()
|
||||
{
|
||||
for(uInt16 i = 0; i < 256; ++i)
|
||||
{
|
||||
uInt8 r = 0;
|
||||
|
||||
for(uInt16 t = 1; t <= 128; t <<= 1)
|
||||
r = (r << 1) | ((i & t) ? 0x01 : 0x00);
|
||||
|
||||
GRPReflect[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// [nusiz:8][old pixel:160][new pixel:160]
|
||||
void TIATables::buildPxPosResetWhenTable()
|
||||
{
|
||||
uInt32 nusiz, oldx, newx;
|
||||
|
||||
// Loop through all player nusizs, all old player positions, and all new
|
||||
// player positions and determine where the new position is located:
|
||||
// 1 means the new position is within the display of an old copy of the
|
||||
// player, -1 means the new position is within the delay portion of an
|
||||
// old copy of the player, and 0 means it's neither of these two
|
||||
for(nusiz = 0; nusiz < 8; ++nusiz)
|
||||
{
|
||||
for(oldx = 0; oldx < 160; ++oldx)
|
||||
{
|
||||
// Set everything to 0 for non-delay/non-display section
|
||||
for(newx = 0; newx < 160; ++newx)
|
||||
PxPosResetWhen[nusiz][oldx][newx] = 0;
|
||||
|
||||
// Now, we'll set the entries for non-delay/non-display section
|
||||
for(newx = 0; newx < 160 + 72 + 5; ++newx)
|
||||
{
|
||||
// nusiz:
|
||||
// 0: one copy
|
||||
// 1: two copies-close
|
||||
// 2: two copies-med
|
||||
// 3: three copies-close
|
||||
// 4: two copies-wide
|
||||
// 5: double size player
|
||||
// 6: 3 copies medium
|
||||
// 7: quad sized player
|
||||
switch(nusiz)
|
||||
{
|
||||
case 0x00:
|
||||
if((newx >= oldx) && (newx < (oldx + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
|
||||
else if((newx >= oldx + 4) && (newx < (oldx + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
if((newx >= oldx) && (newx < (oldx + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
else if((newx >= (oldx + 16)) && (newx < (oldx + 16 + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
|
||||
else if((newx >= oldx + 4) && (newx < (oldx + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
else if((newx >= oldx + 16 + 4) && (newx < (oldx + 16 + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
if((newx >= oldx) && (newx < (oldx + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
else if((newx >= (oldx + 32)) && (newx < (oldx + 32 + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
|
||||
else if((newx >= oldx + 4) && (newx < (oldx + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
else if((newx >= oldx + 32 + 4) && (newx < (oldx + 32 + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
if((newx >= oldx) && (newx < (oldx + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
else if((newx >= (oldx + 16)) && (newx < (oldx + 16 + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
else if((newx >= (oldx + 32)) && (newx < (oldx + 32 + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
|
||||
else if((newx >= oldx + 4) && (newx < (oldx + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
else if((newx >= oldx + 16 + 4) && (newx < (oldx + 16 + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
else if((newx >= oldx + 32 + 4) && (newx < (oldx + 32 + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
if((newx >= oldx) && (newx < (oldx + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
else if((newx >= (oldx + 64)) && (newx < (oldx + 64 + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
|
||||
else if((newx >= oldx + 4) && (newx < (oldx + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
else if((newx >= oldx + 64 + 4) && (newx < (oldx + 64 + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
if((newx >= oldx) && (newx < (oldx + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
|
||||
else if((newx >= oldx + 4) && (newx < (oldx + 4 + 16)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
if((newx >= oldx) && (newx < (oldx + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
else if((newx >= (oldx + 32)) && (newx < (oldx + 32 + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
else if((newx >= (oldx + 64)) && (newx < (oldx + 64 + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
|
||||
else if((newx >= oldx + 4) && (newx < (oldx + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
else if((newx >= oldx + 32 + 4) && (newx < (oldx + 32 + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
else if((newx >= oldx + 64 + 4) && (newx < (oldx + 64 + 4 + 8)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
if((newx >= oldx) && (newx < (oldx + 4)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = -1;
|
||||
|
||||
else if((newx >= oldx + 4) && (newx < (oldx + 4 + 32)))
|
||||
PxPosResetWhen[nusiz][oldx][newx % 160] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Let's do a sanity check on table entries
|
||||
uInt32 s1 = 0, s2 = 0;
|
||||
for(newx = 0; newx < 160; ++newx)
|
||||
{
|
||||
if(PxPosResetWhen[nusiz][oldx][newx] == -1)
|
||||
++s1;
|
||||
if(PxPosResetWhen[nusiz][oldx][newx] == 1)
|
||||
++s2;
|
||||
}
|
||||
assert((s1 % 4 == 0) && (s2 % 8 == 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const Int16 TIATables::PokeDelay[64] = {
|
||||
0, // VSYNC
|
||||
1, // VBLANK (0) / 1
|
||||
0, // WSYNC
|
||||
0, // RSYNC
|
||||
0, // NUSIZ0
|
||||
0, // NUSIZ1
|
||||
0, // COLUP0
|
||||
0, // COLUP1
|
||||
0, // COLUPF
|
||||
0, // COLUBK
|
||||
0, // CTRLPF
|
||||
1, // REFP0
|
||||
1, // REFP1
|
||||
-1, // PF0 (4) / -1
|
||||
-1, // PF1 (4) / -1
|
||||
-1, // PF2 (4) / -1
|
||||
0, // RESP0
|
||||
0, // RESP1
|
||||
8, // RESM0 (0) / 8
|
||||
8, // RESM1 (0) / 8
|
||||
0, // RESBL
|
||||
0, // AUDC0 (-1) / 0
|
||||
0, // AUDC1 (-1) / 0
|
||||
0, // AUDF0 (-1) / 0
|
||||
0, // AUDF1 (-1) / 0
|
||||
0, // AUDV0 (-1) / 0
|
||||
0, // AUDV1 (-1) / 0
|
||||
1, // GRP0
|
||||
1, // GRP1
|
||||
1, // ENAM0
|
||||
1, // ENAM1
|
||||
1, // ENABL
|
||||
0, // HMP0
|
||||
0, // HMP1
|
||||
0, // HMM0
|
||||
0, // HMM1
|
||||
0, // HMBL
|
||||
0, // VDELP0
|
||||
0, // VDELP1
|
||||
0, // VDELBL
|
||||
0, // RESMP0
|
||||
0, // RESMP1
|
||||
3, // HMOVE
|
||||
0, // HMCLR
|
||||
0, // CXCLR
|
||||
// remaining values are undefined TIA write locations
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const bool TIATables::HMOVEBlankEnableCycles[76] = {
|
||||
true, true, true, true, true, true, true, true, true, true, // 00
|
||||
true, true, true, true, true, true, true, true, true, true, // 10
|
||||
true, false, false, false, false, false, false, false, false, false, // 20
|
||||
false, false, false, false, false, false, false, false, false, false, // 30
|
||||
false, false, false, false, false, false, false, false, false, false, // 40
|
||||
false, false, false, false, false, false, false, false, false, false, // 50
|
||||
false, false, false, false, false, false, false, false, false, false, // 60
|
||||
false, false, false, false, false, true // 70
|
||||
};
|
||||
|
||||
#if 0
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const Int32 TIATables::CompleteMotion[76][16] = {
|
||||
{ 0, -1, -2, -3, -4, -5, -6, -7, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, -1, -2, -3, -4, -5, -6, -7, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, -1, -2, -3, -4, -5, -6, -7, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, -1, -2, -3, -4, -5, -6, -7, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, -1, -2, -3, -4, -5, -6, -6, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, -1, -2, -3, -4, -5, -5, -5, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, -1, -2, -3, -4, -5, -5, -5, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, -1, -2, -3, -4, -4, -4, -4, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, -1, -2, -3, -3, -3, -3, -3, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, -1, -2, -2, -2, -2, -2, -2, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, -1, -2, -2, -2, -2, -2, -2, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, -1, -1, -1, -1, -1, -1, -1, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1, 8, 7, 6, 5, 4, 3, 2, 1}, // HBLANK
|
||||
{ 2, 2, 2, 2, 2, 2, 2, 2, 8, 7, 6, 5, 4, 3, 2, 2}, // HBLANK
|
||||
{ 3, 3, 3, 3, 3, 3, 3, 3, 8, 7, 6, 5, 4, 3, 3, 3}, // HBLANK
|
||||
{ 4, 4, 4, 4, 4, 4, 4, 4, 8, 7, 6, 5, 4, 4, 4, 4}, // HBLANK
|
||||
{ 4, 4, 4, 4, 4, 4, 4, 4, 8, 7, 6, 5, 4, 4, 4, 4}, // HBLANK
|
||||
{ 5, 5, 5, 5, 5, 5, 5, 5, 8, 7, 6, 5, 5, 5, 5, 5}, // HBLANK
|
||||
{ 6, 6, 6, 6, 6, 6, 6, 6, 8, 7, 6, 6, 6, 6, 6, 6}, // HBLANK
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, -1, -2, -3, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, -1, -2, -3, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, -1, -2, -3, -4, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, -1, -2, -3, -4, -5, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, -1, -2, -3, -4, -5, -6, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, -1, -2, -3, -4, -5, -6, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, -1, -2, -3, -4, -5, -6, -7, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{-1, -2, -3, -4, -5, -6, -7, -8, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{-2, -3, -4, -5, -6, -7, -8, -9, 0, 0, 0, 0, 0, 0, 0, -1},
|
||||
{-2, -3, -4, -5, -6, -7, -8, -9, 0, 0, 0, 0, 0, 0, 0, -1},
|
||||
{-3, -4, -5, -6, -7, -8, -9,-10, 0, 0, 0, 0, 0, 0, -1, -2},
|
||||
{-4, -5, -6, -7, -8, -9,-10,-11, 0, 0, 0, 0, 0, -1, -2, -3},
|
||||
{-5, -6, -7, -8, -9,-10,-11,-12, 0, 0, 0, 0, -1, -2, -3, -4},
|
||||
{-5, -6, -7, -8, -9,-10,-11,-12, 0, 0, 0, 0, -1, -2, -3, -4},
|
||||
{-6, -7, -8, -9,-10,-11,-12,-13, 0, 0, 0, -1, -2, -3, -4, -5},
|
||||
{-7, -8, -9,-10,-11,-12,-13,-14, 0, 0, -1, -2, -3, -4, -5, -6},
|
||||
{-8, -9,-10,-11,-12,-13,-14,-15, 0, -1, -2, -3, -4, -5, -6, -7},
|
||||
{-8, -9,-10,-11,-12,-13,-14,-15, 0, -1, -2, -3, -4, -5, -6, -7},
|
||||
{ 0, -1, -2, -3, -4, -5, -6, -7, 8, 7, 6, 5, 4, 3, 2, 1} // HBLANK
|
||||
};
|
||||
#endif
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 TIATables::PxMask[2][8][320];
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 TIATables::MxMask[8][5][320];
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 TIATables::BLMask[4][320];
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 TIATables::PFMask[2][160];
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 TIATables::GRPReflect[256];
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 TIATables::CollisionMask[64];
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 TIATables::DisabledMask[640];
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Int8 TIATables::PxPosResetWhen[8][160][160];
|
||||
|
||||
} // namespace TIADefaultCore
|
|
@ -1,122 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2016 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef TIA_DEFAULT_CORE_TABLES_HXX
|
||||
#define TIA_DEFAULT_CORE_TABLES_HXX
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "TIATypes.hxx"
|
||||
|
||||
/**
|
||||
The TIA class uses some static tables that aren't dependent on the actual
|
||||
TIA state. For code organization, it's better to place that functionality
|
||||
here.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id$
|
||||
*/
|
||||
|
||||
namespace TIADefaultCore {
|
||||
|
||||
class TIATables
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Compute all static tables used by the TIA
|
||||
*/
|
||||
static void computeAllTables();
|
||||
|
||||
// Player mask table
|
||||
// [suppress mode][nusiz][pixel]
|
||||
static uInt8 PxMask[2][8][320];
|
||||
|
||||
// Missle mask table (entries are true or false)
|
||||
// [number][size][pixel]
|
||||
// There are actually only 4 possible size combinations on a real system
|
||||
// The fifth size is used for simulating the starfield effect in
|
||||
// Cosmic Ark and Stay Frosty
|
||||
static uInt8 MxMask[8][5][320];
|
||||
|
||||
// Ball mask table (entries are true or false)
|
||||
// [size][pixel]
|
||||
static uInt8 BLMask[4][320];
|
||||
|
||||
// Playfield mask table for reflected and non-reflected playfields
|
||||
// [reflect, pixel]
|
||||
static uInt32 PFMask[2][160];
|
||||
|
||||
// A mask table which can be used when an object is disabled
|
||||
static uInt8 DisabledMask[640];
|
||||
|
||||
// Used to set the collision register to the correct value
|
||||
static uInt16 CollisionMask[64];
|
||||
|
||||
// Indicates the update delay associated with poking at a TIA address
|
||||
static const Int16 PokeDelay[64];
|
||||
|
||||
#if 0
|
||||
// Used to convert value written in a motion register into
|
||||
// its internal representation
|
||||
static const Int32 CompleteMotion[76][16];
|
||||
#endif
|
||||
|
||||
// Indicates if HMOVE blanks should occur for the corresponding cycle
|
||||
static const bool HMOVEBlankEnableCycles[76];
|
||||
|
||||
// Used to reflect a players graphics
|
||||
static uInt8 GRPReflect[256];
|
||||
|
||||
// Indicates if player is being reset during delay, display or other times
|
||||
// [nusiz][old pixel][new pixel]
|
||||
static Int8 PxPosResetWhen[8][160][160];
|
||||
|
||||
private:
|
||||
// Compute the collision decode table
|
||||
static void buildCollisionMaskTable();
|
||||
|
||||
// Compute the player mask table
|
||||
static void buildPxMaskTable();
|
||||
|
||||
// Compute the missle mask table
|
||||
static void buildMxMaskTable();
|
||||
|
||||
// Compute the ball mask table
|
||||
static void buildBLMaskTable();
|
||||
|
||||
// Compute playfield mask table
|
||||
static void buildPFMaskTable();
|
||||
|
||||
// Compute the player reflect table
|
||||
static void buildGRPReflectTable();
|
||||
|
||||
// Compute the player position reset when table
|
||||
static void buildPxPosResetWhenTable();
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
TIATables() = delete;
|
||||
TIATables(const TIATables&) = delete;
|
||||
TIATables(TIATables&&) = delete;
|
||||
TIATables& operator=(const TIATables&) = delete;
|
||||
TIATables& operator=(TIATables&&) = delete;
|
||||
};
|
||||
|
||||
} // namespace TIADefaultCore
|
||||
|
||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||
MODULE := src/emucore/tia/core_default
|
||||
|
||||
MODULE_OBJS := \
|
||||
src/emucore/tia/core_default/TIA.o \
|
||||
src/emucore/tia/core_default/TIATables.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
src/emucore/tia/core_default
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/common.rules
|
Loading…
Reference in New Issue