Modified the TIA emulation so that it supports the PAL color loss

effect.  Color loss occurs when the previous frame contains an odd
number of scanlines.

The color loss effect is implemented using an idea from Eckhard
Stolberg: "I thought you could have each colour twice in the palette.
In the PAL palette the second colour would only be a shade of
grey. Then when something gets written to the TIA colour registers,
you could set bit0 of the colour according to bit0 of the
scanline counter for the last frame. That way an odd number of lines
would select the grey tones, while an even number would select the
normal colours."


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@57 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
bwmott 2002-03-28 05:10:17 +00:00
parent 669c93e662
commit c3aa637f8a
2 changed files with 144 additions and 61 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: TIA.cxx,v 1.9 2002-03-28 02:02:24 bwmott Exp $
// $Id: TIA.cxx,v 1.10 2002-03-28 05:10:17 bwmott Exp $
//============================================================================
#include <assert.h>
@ -35,6 +35,7 @@ TIA::TIA(const Console& console, Sound& sound)
mySound(sound),
myPauseState(false),
myLastSoundUpdateCycle(0),
myColorLossEnabled(false),
myCOLUBK(myColor[0]),
myCOLUPF(myColor[1]),
myCOLUP0(myColor[2]),
@ -137,7 +138,7 @@ void TIA::reset()
myClockAtLastUpdate = myClockWhenFrameStarted;
myClocksToEndOfScanLine = 228;
myVSYNCFinishClock = 0x7FFFFFFF;
myScanlineCountForFrame = 0;
myScanlineCountForLastFrame = 0;
// Currently no objects are enabled
myEnabledObjects = 0;
@ -215,6 +216,15 @@ void TIA::reset()
myFrameXStart = 0;
myFrameWidth = 160;
}
if(myConsole.properties().get("Display.Format") == "PAL")
{
myColorLossEnabled = true;
}
else
{
myColorLossEnabled = false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -299,6 +309,26 @@ void TIA::update()
// Reset frame buffer pointer
myFramePointer = myCurrentFrameBuffer;
// If color loss is enabled then update the color registers based on
// the number of scanlines in the last frame that was generated
if(myColorLossEnabled)
{
if(myScanlineCountForLastFrame & 0x01)
{
myCOLUP0 |= 0x01010101;
myCOLUP1 |= 0x01010101;
myCOLUPF |= 0x01010101;
myCOLUBK |= 0x01010101;
}
else
{
myCOLUP0 &= 0xfefefefe;
myCOLUP1 &= 0xfefefefe;
myCOLUPF &= 0xfefefefe;
myCOLUBK &= 0xfefefefe;
}
}
// Execute instructions until frame is finished
mySystem->m6502().execute(25000);
@ -306,7 +336,7 @@ void TIA::update()
// Compute the number of scanlines in the frame
uInt32 totalClocks = (mySystem->cycles() * 3) - myClockWhenFrameStarted;
myScanlineCountForFrame = totalClocks / 228;
myScanlineCountForLastFrame = totalClocks / 228;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -357,7 +387,7 @@ uInt32 TIA::height() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TIA::scanlines() const
{
return (uInt32)myScanlineCountForFrame;
return (uInt32)myScanlineCountForLastFrame;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1857,28 +1887,44 @@ void TIA::poke(uInt16 addr, uInt8 value)
case 0x06: // Color-Luminance Player 0
{
uInt32 color = (uInt32)value;
uInt32 color = (uInt32)(value & 0xfe);
if(myColorLossEnabled && (myScanlineCountForLastFrame & 0x01))
{
color |= 0x01;
}
myCOLUP0 = (((((color << 8) | color) << 8) | color) << 8) | color;
break;
}
case 0x07: // Color-Luminance Player 1
{
uInt32 color = (uInt32)value;
uInt32 color = (uInt32)(value & 0xfe);
if(myColorLossEnabled && (myScanlineCountForLastFrame & 0x01))
{
color |= 0x01;
}
myCOLUP1 = (((((color << 8) | color) << 8) | color) << 8) | color;
break;
}
case 0x08: // Color-Luminance Playfield
{
uInt32 color = (uInt32)value;
uInt32 color = (uInt32)(value & 0xfe);
if(myColorLossEnabled && (myScanlineCountForLastFrame & 0x01))
{
color |= 0x01;
}
myCOLUPF = (((((color << 8) | color) << 8) | color) << 8) | color;
break;
}
case 0x09: // Color-Luminance Background
{
uInt32 color = (uInt32)value;
uInt32 color = (uInt32)(value & 0xfe);
if(myColorLossEnabled && (myScanlineCountForLastFrame & 0x01))
{
color |= 0x01;
}
myCOLUBK = (((((color << 8) | color) << 8) | color) << 8) | color;
break;
}
@ -2593,62 +2639,77 @@ const uInt32 TIA::ourNTSCPalette[256] = {
0x6f6f6f, 0x6f6f6f, 0x8e8e8e, 0x8e8e8e,
0xaaaaaa, 0xaaaaaa, 0xc0c0c0, 0xc0c0c0,
0xd6d6d6, 0xd6d6d6, 0xececec, 0xececec,
0x484800, 0x484800, 0x69690f, 0x69690f,
0x86861d, 0x86861d, 0xa2a22a, 0xa2a22a,
0xbbbb35, 0xbbbb35, 0xd2d240, 0xd2d240,
0xe8e84a, 0xe8e84a, 0xfcfc54, 0xfcfc54,
0x7c2c00, 0x7c2c00, 0x904811, 0x904811,
0xa26221, 0xa26221, 0xb47a30, 0xb47a30,
0xc3903d, 0xc3903d, 0xd2a44a, 0xd2a44a,
0xdfb755, 0xdfb755, 0xecc860, 0xecc860,
0x901c00, 0x901c00, 0xa33915, 0xa33915,
0xb55328, 0xb55328, 0xc66c3a, 0xc66c3a,
0xd5824a, 0xd5824a, 0xe39759, 0xe39759,
0xf0aa67, 0xf0aa67, 0xfcbc74, 0xfcbc74,
0x940000, 0x940000, 0xa71a1a, 0xa71a1a,
0xb83232, 0xb83232, 0xc84848, 0xc84848,
0xd65c5c, 0xd65c5c, 0xe46f6f, 0xe46f6f,
0xf08080, 0xf08080, 0xfc9090, 0xfc9090,
0x840064, 0x840064, 0x97197a, 0x97197a,
0xa8308f, 0xa8308f, 0xb846a2, 0xb846a2,
0xc659b3, 0xc659b3, 0xd46cc3, 0xd46cc3,
0xe07cd2, 0xe07cd2, 0xec8ce0, 0xec8ce0,
0x500084, 0x500084, 0x68199a, 0x68199a,
0x7d30ad, 0x7d30ad, 0x9246c0, 0x9246c0,
0xa459d0, 0xa459d0, 0xb56ce0, 0xb56ce0,
0xc57cee, 0xc57cee, 0xd48cfc, 0xd48cfc,
0x140090, 0x140090, 0x331aa3, 0x331aa3,
0x4e32b5, 0x4e32b5, 0x6848c6, 0x6848c6,
0x7f5cd5, 0x7f5cd5, 0x956fe3, 0x956fe3,
0xa980f0, 0xa980f0, 0xbc90fc, 0xbc90fc,
0x000094, 0x000094, 0x181aa7, 0x181aa7,
0x2d32b8, 0x2d32b8, 0x4248c8, 0x4248c8,
0x545cd6, 0x545cd6, 0x656fe4, 0x656fe4,
0x7580f0, 0x7580f0, 0x8490fc, 0x8490fc,
0x001c88, 0x001c88, 0x183b9d, 0x183b9d,
0x2d57b0, 0x2d57b0, 0x4272c2, 0x4272c2,
0x548ad2, 0x548ad2, 0x65a0e1, 0x65a0e1,
0x75b5ef, 0x75b5ef, 0x84c8fc, 0x84c8fc,
0x003064, 0x003064, 0x185080, 0x185080,
0x2d6d98, 0x2d6d98, 0x4288b0, 0x4288b0,
0x54a0c5, 0x54a0c5, 0x65b7d9, 0x65b7d9,
0x75cceb, 0x75cceb, 0x84e0fc, 0x84e0fc,
0x004030, 0x004030, 0x18624e, 0x18624e,
0x2d8169, 0x2d8169, 0x429e82, 0x429e82,
0x54b899, 0x54b899, 0x65d1ae, 0x65d1ae,
0x75e7c2, 0x75e7c2, 0x84fcd4, 0x84fcd4,
0x004400, 0x004400, 0x1a661a, 0x1a661a,
0x328432, 0x328432, 0x48a048, 0x48a048,
0x5cba5c, 0x5cba5c, 0x6fd26f, 0x6fd26f,
0x80e880, 0x80e880, 0x90fc90, 0x90fc90,
0x143c00, 0x143c00, 0x355f18, 0x355f18,
0x527e2d, 0x527e2d, 0x6e9c42, 0x6e9c42,
0x87b754, 0x87b754, 0x9ed065, 0x9ed065,
0xb4e775, 0xb4e775, 0xc8fc84, 0xc8fc84,
0x303800, 0x303800, 0x505916, 0x505916,
0x6d762b, 0x6d762b, 0x88923e, 0x88923e,
0xa0ab4f, 0xa0ab4f, 0xb7c25f, 0xb7c25f,
0xccd86e, 0xccd86e, 0xe0ec7c, 0xe0ec7c,
0x482c00, 0x482c00, 0x694d14, 0x694d14,
0x866a26, 0x866a26, 0xa28638, 0xa28638,
0xbb9f47, 0xbb9f47, 0xd2b656, 0xd2b656,
@ -2661,62 +2722,77 @@ const uInt32 TIA::ourPALPalette[256] = {
0x525252, 0x525252, 0x767676, 0x767676,
0x979797, 0x979797, 0xb6b6b6, 0xb6b6b6,
0xd2d2d2, 0xd2d2d2, 0xececec, 0xececec,
0x000000, 0x000000, 0x2b2b2b, 0x2b2b2b,
0x525252, 0x525252, 0x767676, 0x767676,
0x979797, 0x979797, 0xb6b6b6, 0xb6b6b6,
0xd2d2d2, 0xd2d2d2, 0xececec, 0xececec,
0x805800, 0x805800, 0x96711a, 0x96711a,
0xab8732, 0xab8732, 0xbe9c48, 0xbe9c48,
0xcfaf5c, 0xcfaf5c, 0xdfc06f, 0xdfc06f,
0xeed180, 0xeed180, 0xfce090, 0xfce090,
0x445c00, 0x445c00, 0x5e791a, 0x5e791a,
0x769332, 0x769332, 0x8cac48, 0x8cac48,
0xa0c25c, 0xa0c25c, 0xb3d76f, 0xb3d76f,
0xc4ea80, 0xc4ea80, 0xd4fc90, 0xd4fc90,
0x703400, 0x703400, 0x89511a, 0x89511a,
0xa06b32, 0xa06b32, 0xb68448, 0xb68448,
0xc99a5c, 0xc99a5c, 0xdcaf6f, 0xdcaf6f,
0xecc280, 0xecc280, 0xfcd490, 0xfcd490,
0x006414, 0x006414, 0x1a8035, 0x1a8035,
0x329852, 0x329852, 0x48b06e, 0x48b06e,
0x5cc587, 0x5cc587, 0x6fd99e, 0x6fd99e,
0x80ebb4, 0x80ebb4, 0x90fcc8, 0x90fcc8,
0x700014, 0x700014, 0x891a35, 0x891a35,
0xa03252, 0xa03252, 0xb6486e, 0xb6486e,
0xc95c87, 0xc95c87, 0xdc6f9e, 0xdc6f9e,
0xec80b4, 0xec80b4, 0xfc90c8, 0xfc90c8,
0x005c5c, 0x005c5c, 0x1a7676, 0x1a7676,
0x328e8e, 0x328e8e, 0x48a4a4, 0x48a4a4,
0x5cb8b8, 0x5cb8b8, 0x6fcbcb, 0x6fcbcb,
0x80dcdc, 0x80dcdc, 0x90ecec, 0x90ecec,
0x70005c, 0x70005c, 0x841a74, 0x841a74,
0x963289, 0x963289, 0xa8489e, 0xa8489e,
0xb75cb0, 0xb75cb0, 0xc66fc1, 0xc66fc1,
0xd380d1, 0xd380d1, 0xe090e0, 0xe090e0,
0x003c70, 0x003c70, 0x195a89, 0x195a89,
0x2f75a0, 0x2f75a0, 0x448eb6, 0x448eb6,
0x57a5c9, 0x57a5c9, 0x68badc, 0x68badc,
0x79ceec, 0x79ceec, 0x88e0fc, 0x88e0fc,
0x580070, 0x580070, 0x6e1a89, 0x6e1a89,
0x8332a0, 0x8332a0, 0x9648b6, 0x9648b6,
0xa75cc9, 0xa75cc9, 0xb76fdc, 0xb76fdc,
0xc680ec, 0xc680ec, 0xd490fc, 0xd490fc,
0x002070, 0x002070, 0x193f89, 0x193f89,
0x2f5aa0, 0x2f5aa0, 0x4474b6, 0x4474b6,
0x578bc9, 0x578bc9, 0x68a1dc, 0x68a1dc,
0x79b5ec, 0x79b5ec, 0x88c8fc, 0x88c8fc,
0x340080, 0x340080, 0x4a1a96, 0x4a1a96,
0x5f32ab, 0x5f32ab, 0x7248be, 0x7248be,
0x835ccf, 0x835ccf, 0x936fdf, 0x936fdf,
0xa280ee, 0xa280ee, 0xb090fc, 0xb090fc,
0x000088, 0x000088, 0x1a1a9d, 0x1a1a9d,
0x3232b0, 0x3232b0, 0x4848c2, 0x4848c2,
0x5c5cd2, 0x5c5cd2, 0x6f6fe1, 0x6f6fe1,
0x8080ef, 0x8080ef, 0x9090fc, 0x9090fc,
0x805800, 0x000000, 0x96711a, 0x2b2b2b,
0xab8732, 0x525252, 0xbe9c48, 0x767676,
0xcfaf5c, 0x979797, 0xdfc06f, 0xb6b6b6,
0xeed180, 0xd2d2d2, 0xfce090, 0xececec,
0x445c00, 0x000000, 0x5e791a, 0x2b2b2b,
0x769332, 0x525252, 0x8cac48, 0x767676,
0xa0c25c, 0x979797, 0xb3d76f, 0xb6b6b6,
0xc4ea80, 0xd2d2d2, 0xd4fc90, 0xececec,
0x703400, 0x000000, 0x89511a, 0x2b2b2b,
0xa06b32, 0x525252, 0xb68448, 0x767676,
0xc99a5c, 0x979797, 0xdcaf6f, 0xb6b6b6,
0xecc280, 0xd2d2d2, 0xfcd490, 0xececec,
0x006414, 0x000000, 0x1a8035, 0x2b2b2b,
0x329852, 0x525252, 0x48b06e, 0x767676,
0x5cc587, 0x979797, 0x6fd99e, 0xb6b6b6,
0x80ebb4, 0xd2d2d2, 0x90fcc8, 0xececec,
0x700014, 0x000000, 0x891a35, 0x2b2b2b,
0xa03252, 0x525252, 0xb6486e, 0x767676,
0xc95c87, 0x979797, 0xdc6f9e, 0xb6b6b6,
0xec80b4, 0xd2d2d2, 0xfc90c8, 0xececec,
0x005c5c, 0x000000, 0x1a7676, 0x2b2b2b,
0x328e8e, 0x525252, 0x48a4a4, 0x767676,
0x5cb8b8, 0x979797, 0x6fcbcb, 0xb6b6b6,
0x80dcdc, 0xd2d2d2, 0x90ecec, 0xececec,
0x70005c, 0x000000, 0x841a74, 0x2b2b2b,
0x963289, 0x525252, 0xa8489e, 0x767676,
0xb75cb0, 0x979797, 0xc66fc1, 0xb6b6b6,
0xd380d1, 0xd2d2d2, 0xe090e0, 0xececec,
0x003c70, 0x000000, 0x195a89, 0x2b2b2b,
0x2f75a0, 0x525252, 0x448eb6, 0x767676,
0x57a5c9, 0x979797, 0x68badc, 0xb6b6b6,
0x79ceec, 0xd2d2d2, 0x88e0fc, 0xececec,
0x580070, 0x000000, 0x6e1a89, 0x2b2b2b,
0x8332a0, 0x525252, 0x9648b6, 0x767676,
0xa75cc9, 0x979797, 0xb76fdc, 0xb6b6b6,
0xc680ec, 0xd2d2d2, 0xd490fc, 0xececec,
0x002070, 0x000000, 0x193f89, 0x2b2b2b,
0x2f5aa0, 0x525252, 0x4474b6, 0x767676,
0x578bc9, 0x979797, 0x68a1dc, 0xb6b6b6,
0x79b5ec, 0xd2d2d2, 0x88c8fc, 0xececec,
0x340080, 0x000000, 0x4a1a96, 0x2b2b2b,
0x5f32ab, 0x525252, 0x7248be, 0x767676,
0x835ccf, 0x979797, 0x936fdf, 0xb6b6b6,
0xa280ee, 0xd2d2d2, 0xb090fc, 0xececec,
0x000088, 0x000000, 0x1a1a9d, 0x2b2b2b,
0x3232b0, 0x525252, 0x4848c2, 0x767676,
0x5c5cd2, 0x979797, 0x6f6fe1, 0xb6b6b6,
0x8080ef, 0xd2d2d2, 0x9090fc, 0xececec,
0x000000, 0x000000, 0x2b2b2b, 0x2b2b2b,
0x525252, 0x525252, 0x767676, 0x767676,
0x979797, 0x979797, 0xb6b6b6, 0xb6b6b6,
0xd2d2d2, 0xd2d2d2, 0xececec, 0xececec,
0x000000, 0x000000, 0x2b2b2b, 0x2b2b2b,
0x525252, 0x525252, 0x767676, 0x767676,
0x979797, 0x979797, 0xb6b6b6, 0xb6b6b6,

View File

@ -8,12 +8,12 @@
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-1998 by Bradford W. Mott
// Copyright (c) 1995-2002 by Bradford W. Mott
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: TIA.hxx,v 1.3 2002-03-28 02:02:24 bwmott Exp $
// $Id: TIA.hxx,v 1.4 2002-03-28 05:10:17 bwmott Exp $
//============================================================================
#ifndef TIA_HXX
@ -38,7 +38,7 @@ class System;
be displayed on screen.
@author Bradford W. Mott
@version $Id: TIA.hxx,v 1.3 2002-03-28 02:02:24 bwmott Exp $
@version $Id: TIA.hxx,v 1.4 2002-03-28 05:10:17 bwmott Exp $
*/
class TIA : public Device , public MediaSource
{
@ -204,6 +204,11 @@ class TIA : public Device , public MediaSource
// Indicates the CPU cycle when a TIA sound register was last updated
Int32 myLastSoundUpdateCycle;
// 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;
private:
// Pointer to the current frame buffer
uInt8* myCurrentFrameBuffer;
@ -252,7 +257,7 @@ class TIA : public Device , public MediaSource
Int32 myClocksToEndOfScanLine;
// Indicates the total number of scanlines generated by the last frame
Int32 myScanlineCountForFrame;
Int32 myScanlineCountForLastFrame;
private:
// Color clock when VSYNC ending causes a new frame to be started
@ -424,7 +429,9 @@ class TIA : public Device , public MediaSource
// Table of RGB values for NTSC
static const uInt32 ourNTSCPalette[256];
// Table of RGB values for PAL
// Table of RGB values for PAL. NOTE: The odd numbered entries in
// this array are always shades of grey. This is used to implement
// the PAL color loss effect.
static const uInt32 ourPALPalette[256];
private: