1 //============================================================================ 2 // 3 // SSSS tt lll lll 4 // SS SS tt ll ll 5 // SS tttttt eeee ll ll aaaa 6 // SSSS tt ee ee ll ll aa 7 // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" 8 // SS SS tt ee ll ll aa aa 9 // SSSS ttt eeeee llll llll aaaaa 10 // 11 // Copyright (c) 1995-2014 by Bradford W. Mott, Stephen Anthony 12 // and the Stella Team 13 // 14 // See the file "License.txt" for information on usage and redistribution of 15 // this file, and for a DISCLAIMER OF ALL WARRANTIES. 16 // 17 // $Id: TIATables.hxx 2838 2014-01-17 23:34:03Z stephena $ 18 //============================================================================ 19 20 #ifndef TIA_TABLES_HXX 21 #define TIA_TABLES_HXX 22 23 #include "bspf.hxx" 24 25 enum TIABit { 26 P0Bit = 0x01, // Bit for Player 0 27 M0Bit = 0x02, // Bit for Missle 0 28 P1Bit = 0x04, // Bit for Player 1 29 M1Bit = 0x08, // Bit for Missle 1 30 BLBit = 0x10, // Bit for Ball 31 PFBit = 0x20, // Bit for Playfield 32 ScoreBit = 0x40, // Bit for Playfield score mode 33 PriorityBit = 0x80 // Bit for Playfield priority 34 }; 35 36 enum TIAColor { 37 BKColor = 0, // Color index for Background 38 PFColor = 1, // Color index for Playfield 39 P0Color = 2, // Color index for Player 0 40 P1Color = 3, // Color index for Player 1 41 M0Color = 4, // Color index for Missle 0 42 M1Color = 5, // Color index for Missle 1 43 BLColor = 6, // Color index for Ball 44 HBLANKColor = 7 // Color index for HMove blank area 45 }; 46 47 enum CollisionBit 48 { 49 Cx_M0P1 = 1 << 0, // Missle0 - Player1 collision 50 Cx_M0P0 = 1 << 1, // Missle0 - Player0 collision 51 Cx_M1P0 = 1 << 2, // Missle1 - Player0 collision 52 Cx_M1P1 = 1 << 3, // Missle1 - Player1 collision 53 Cx_P0PF = 1 << 4, // Player0 - Playfield collision 54 Cx_P0BL = 1 << 5, // Player0 - Ball collision 55 Cx_P1PF = 1 << 6, // Player1 - Playfield collision 56 Cx_P1BL = 1 << 7, // Player1 - Ball collision 57 Cx_M0PF = 1 << 8, // Missle0 - Playfield collision 58 Cx_M0BL = 1 << 9, // Missle0 - Ball collision 59 Cx_M1PF = 1 << 10, // Missle1 - Playfield collision 60 Cx_M1BL = 1 << 11, // Missle1 - Ball collision 61 Cx_BLPF = 1 << 12, // Ball - Playfield collision 62 Cx_P0P1 = 1 << 13, // Player0 - Player1 collision 63 Cx_M0M1 = 1 << 14 // Missle0 - Missle1 collision 64 }; 65 66 // TIA Write/Read register names 67 enum TIARegister { 68 VSYNC = 0x00, // Write: vertical sync set-clear (D1) 69 VBLANK = 0x01, // Write: vertical blank set-clear (D7-6,D1) 70 WSYNC = 0x02, // Write: wait for leading edge of hrz. blank (strobe) 71 RSYNC = 0x03, // Write: reset hrz. sync counter (strobe) 72 NUSIZ0 = 0x04, // Write: number-size player-missle 0 (D5-0) 73 NUSIZ1 = 0x05, // Write: number-size player-missle 1 (D5-0) 74 COLUP0 = 0x06, // Write: color-lum player 0 (D7-1) 75 COLUP1 = 0x07, // Write: color-lum player 1 (D7-1) 76 COLUPF = 0x08, // Write: color-lum playfield (D7-1) 77 COLUBK = 0x09, // Write: color-lum background (D7-1) 78 CTRLPF = 0x0a, // Write: cntrl playfield ballsize & coll. (D5-4,D2-0) 79 REFP0 = 0x0b, // Write: reflect player 0 (D3) 80 REFP1 = 0x0c, // Write: reflect player 1 (D3) 81 PF0 = 0x0d, // Write: playfield register byte 0 (D7-4) 82 PF1 = 0x0e, // Write: playfield register byte 1 (D7-0) 83 PF2 = 0x0f, // Write: playfield register byte 2 (D7-0) 84 RESP0 = 0x10, // Write: reset player 0 (strobe) 85 RESP1 = 0x11, // Write: reset player 1 (strobe) 86 RESM0 = 0x12, // Write: reset missle 0 (strobe) 87 RESM1 = 0x13, // Write: reset missle 1 (strobe) 88 RESBL = 0x14, // Write: reset ball (strobe) 89 AUDC0 = 0x15, // Write: audio control 0 (D3-0) 90 AUDC1 = 0x16, // Write: audio control 1 (D4-0) 91 AUDF0 = 0x17, // Write: audio frequency 0 (D4-0) 92 AUDF1 = 0x18, // Write: audio frequency 1 (D3-0) 93 AUDV0 = 0x19, // Write: audio volume 0 (D3-0) 94 AUDV1 = 0x1a, // Write: audio volume 1 (D3-0) 95 GRP0 = 0x1b, // Write: graphics player 0 (D7-0) 96 GRP1 = 0x1c, // Write: graphics player 1 (D7-0) 97 ENAM0 = 0x1d, // Write: graphics (enable) missle 0 (D1) 98 ENAM1 = 0x1e, // Write: graphics (enable) missle 1 (D1) 99 ENABL = 0x1f, // Write: graphics (enable) ball (D1) 100 HMP0 = 0x20, // Write: horizontal motion player 0 (D7-4) 101 HMP1 = 0x21, // Write: horizontal motion player 1 (D7-4) 102 HMM0 = 0x22, // Write: horizontal motion missle 0 (D7-4) 103 HMM1 = 0x23, // Write: horizontal motion missle 1 (D7-4) 104 HMBL = 0x24, // Write: horizontal motion ball (D7-4) 105 VDELP0 = 0x25, // Write: vertical delay player 0 (D0) 106 VDELP1 = 0x26, // Write: vertical delay player 1 (D0) 107 VDELBL = 0x27, // Write: vertical delay ball (D0) 108 RESMP0 = 0x28, // Write: reset missle 0 to player 0 (D1) 109 RESMP1 = 0x29, // Write: reset missle 1 to player 1 (D1) 110 HMOVE = 0x2a, // Write: apply horizontal motion (strobe) 111 HMCLR = 0x2b, // Write: clear horizontal motion registers (strobe) 112 CXCLR = 0x2c, // Write: clear collision latches (strobe) 113 114 CXM0P = 0x00, // Read collision: D7=(M0,P1); D6=(M0,P0) 115 CXM1P = 0x01, // Read collision: D7=(M1,P0); D6=(M1,P1) 116 CXP0FB = 0x02, // Read collision: D7=(P0,PF); D6=(P0,BL) 117 CXP1FB = 0x03, // Read collision: D7=(P1,PF); D6=(P1,BL) 118 CXM0FB = 0x04, // Read collision: D7=(M0,PF); D6=(M0,BL) 119 CXM1FB = 0x05, // Read collision: D7=(M1,PF); D6=(M1,BL) 120 CXBLPF = 0x06, // Read collision: D7=(BL,PF); D6=(unused) 121 CXPPMM = 0x07, // Read collision: D7=(P0,P1); D6=(M0,M1) 122 INPT0 = 0x08, // Read pot port: D7 123 INPT1 = 0x09, // Read pot port: D7 124 INPT2 = 0x0a, // Read pot port: D7 125 INPT3 = 0x0b, // Read pot port: D7 126 INPT4 = 0x0c, // Read P1 joystick trigger: D7 127 INPT5 = 0x0d // Read P2 joystick trigger: D7 128 }; 129 130 /** 131 The TIA class uses some static tables that aren't dependent on the actual 132 TIA state. For code organization, it's better to place that functionality 133 here. 134 135 @author Stephen Anthony 136 @version $Id: TIATables.hxx 2838 2014-01-17 23:34:03Z stephena $ 137 */ 138 class TIATables 139 { 140 public: 141 /** 142 Compute all static tables used by the TIA 143 */ 144 static void computeAllTables(); 145 146 // Player mask table 147 // [suppress mode][nusiz][pixel] 148 static uInt8 PxMask[2][8][320]; 149 150 // Missle mask table (entries are true or false) 151 // [number][size][pixel] 152 // There are actually only 4 possible size combinations on a real system 153 // The fifth size is used for simulating the starfield effect in 154 // Cosmic Ark and Stay Frosty 155 static uInt8 MxMask[8][5][320]; 156 157 // Ball mask table (entries are true or false) 158 // [size][pixel] 159 static uInt8 BLMask[4][320]; 160 161 // Playfield mask table for reflected and non-reflected playfields 162 // [reflect, pixel] 163 static uInt32 PFMask[2][160]; 164 165 // A mask table which can be used when an object is disabled 166 static uInt8 DisabledMask[640]; 167 168 // Used to set the collision register to the correct value 169 static uInt16 CollisionMask[64]; 170 171 // Indicates the update delay associated with poking at a TIA address 172 static const Int16 PokeDelay[64]; 173 174 #if 0 175 // Used to convert value written in a motion register into 176 // its internal representation 177 static const Int32 CompleteMotion[76][16]; 178 #endif 179 180 // Indicates if HMOVE blanks should occur for the corresponding cycle 181 static const bool HMOVEBlankEnableCycles[76]; 182 183 // Used to reflect a players graphics 184 static uInt8 GRPReflect[256]; 185 186 // Indicates if player is being reset during delay, display or other times 187 // [nusiz][old pixel][new pixel] 188 static Int8 PxPosResetWhen[8][160][160]; 189 190 private: 191 // Compute the collision decode table 192 static void buildCollisionMaskTable(); 193 194 // Compute the player mask table 195 static void buildPxMaskTable(); 196 197 // Compute the missle mask table 198 static void buildMxMaskTable(); 199 200 // Compute the ball mask table 201 static void buildBLMaskTable(); 202 203 // Compute playfield mask table 204 static void buildPFMaskTable(); 205 206 // Compute the player reflect table 207 static void buildGRPReflectTable(); 208 209 // Compute the player position reset when table 210 static void buildPxPosResetWhenTable(); 211 }; 212 213 #endif 214