diff --git a/.gitattributes b/.gitattributes index 949fcc0ec52..e4df589bace 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1526,6 +1526,16 @@ src/emu/bus/tvc/hbf.c svneol=native#text/plain src/emu/bus/tvc/hbf.h svneol=native#text/plain src/emu/bus/tvc/tvc.c svneol=native#text/plain src/emu/bus/tvc/tvc.h svneol=native#text/plain +src/emu/bus/vcs/compumat.c svneol=native#text/plain +src/emu/bus/vcs/compumat.h svneol=native#text/plain +src/emu/bus/vcs/dpc.c svneol=native#text/plain +src/emu/bus/vcs/dpc.h svneol=native#text/plain +src/emu/bus/vcs/rom.c svneol=native#text/plain +src/emu/bus/vcs/rom.h svneol=native#text/plain +src/emu/bus/vcs/scharger.c svneol=native#text/plain +src/emu/bus/vcs/scharger.h svneol=native#text/plain +src/emu/bus/vcs/vcs_slot.c svneol=native#text/plain +src/emu/bus/vcs/vcs_slot.h svneol=native#text/plain src/emu/bus/vcs_ctrl/ctrl.c svneol=native#text/plain src/emu/bus/vcs_ctrl/ctrl.h svneol=native#text/plain src/emu/bus/vcs_ctrl/joybooster.c svneol=native#text/plain diff --git a/hash/a2600.xml b/hash/a2600.xml index e9b3081be2b..d5b26a1ab84 100644 --- a/hash/a2600.xml +++ b/hash/a2600.xml @@ -15,6 +15,7 @@ Info from Atariage and Atarimania + @@ -29,6 +30,7 @@ Info from Atariage and Atarimania + @@ -43,6 +45,7 @@ Info from Atariage and Atarimania + @@ -59,6 +62,7 @@ Info from Atariage and Atarimania + @@ -73,6 +77,7 @@ Info from Atariage and Atarimania + @@ -88,6 +93,7 @@ Info from Atariage and Atarimania + @@ -102,6 +108,7 @@ Info from Atariage and Atarimania + @@ -117,6 +124,7 @@ Info from Atariage and Atarimania + @@ -132,6 +140,7 @@ Info from Atariage and Atarimania + @@ -147,6 +156,7 @@ Info from Atariage and Atarimania + @@ -162,6 +172,7 @@ Info from Atariage and Atarimania + @@ -243,6 +254,7 @@ Info from Atariage and Atarimania + @@ -255,6 +267,7 @@ Info from Atariage and Atarimania Atari + @@ -269,6 +282,7 @@ Info from Atariage and Atarimania + @@ -283,6 +297,7 @@ Info from Atariage and Atarimania + @@ -296,6 +311,7 @@ Info from Atariage and Atarimania + @@ -310,6 +326,7 @@ Info from Atariage and Atarimania + @@ -325,6 +342,7 @@ Info from Atariage and Atarimania + @@ -340,6 +358,7 @@ Info from Atariage and Atarimania + @@ -355,6 +374,7 @@ Info from Atariage and Atarimania + @@ -395,6 +415,7 @@ Info from Atariage and Atarimania + @@ -424,6 +445,7 @@ Info from Atariage and Atarimania + @@ -682,6 +704,7 @@ Info from Atariage and Atarimania + @@ -698,6 +721,7 @@ Info from Atariage and Atarimania + @@ -714,6 +738,7 @@ Info from Atariage and Atarimania + @@ -730,6 +755,7 @@ Info from Atariage and Atarimania + @@ -773,6 +799,7 @@ Info from Atariage and Atarimania + @@ -850,6 +877,7 @@ Info from Atariage and Atarimania + @@ -865,6 +893,7 @@ Info from Atariage and Atarimania + @@ -908,6 +937,7 @@ Info from Atariage and Atarimania + @@ -924,6 +954,7 @@ Info from Atariage and Atarimania + @@ -1006,6 +1037,7 @@ Info from Atariage and Atarimania + @@ -1020,6 +1052,7 @@ Info from Atariage and Atarimania + @@ -1035,6 +1068,7 @@ Info from Atariage and Atarimania + @@ -1050,6 +1084,7 @@ Info from Atariage and Atarimania + @@ -1065,6 +1100,7 @@ Info from Atariage and Atarimania + @@ -1081,6 +1117,7 @@ Info from Atariage and Atarimania + @@ -1607,6 +1644,7 @@ Info from Atariage and Atarimania + @@ -1621,6 +1659,7 @@ Info from Atariage and Atarimania + @@ -1635,6 +1674,7 @@ Info from Atariage and Atarimania + @@ -1649,6 +1689,7 @@ Info from Atariage and Atarimania + @@ -1663,6 +1704,7 @@ Info from Atariage and Atarimania + @@ -1677,6 +1719,7 @@ Info from Atariage and Atarimania + @@ -1756,6 +1799,7 @@ Info from Atariage and Atarimania + @@ -1881,6 +1925,7 @@ Info from Atariage and Atarimania + @@ -1908,6 +1953,7 @@ Info from Atariage and Atarimania Activision + @@ -1920,6 +1966,7 @@ Info from Atariage and Atarimania Activision + @@ -1976,6 +2023,7 @@ Info from Atariage and Atarimania Atari + @@ -2055,6 +2103,7 @@ Info from Atariage and Atarimania Atari + @@ -2067,6 +2116,7 @@ Info from Atariage and Atarimania Atari + @@ -2079,6 +2129,7 @@ Info from Atariage and Atarimania Atari + @@ -2091,6 +2142,7 @@ Info from Atariage and Atarimania Atari + @@ -2125,6 +2177,7 @@ Info from Atariage and Atarimania Atari + @@ -2137,6 +2190,7 @@ Info from Atariage and Atarimania Atari + @@ -2207,6 +2261,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -2219,6 +2274,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -2231,6 +2287,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -2243,6 +2300,7 @@ Info from Atariage and Atarimania Atari + @@ -2255,6 +2313,7 @@ Info from Atariage and Atarimania Atari + @@ -2267,6 +2326,7 @@ Info from Atariage and Atarimania TNT Games + @@ -2461,6 +2521,7 @@ Info from Atariage and Atarimania + @@ -2665,6 +2726,7 @@ Info from Atariage and Atarimania Sega + @@ -2677,6 +2739,7 @@ Info from Atariage and Atarimania Sega + @@ -2711,6 +2774,7 @@ Info from Atariage and Atarimania Atari + @@ -2723,6 +2787,7 @@ Info from Atariage and Atarimania Atari + @@ -2735,6 +2800,7 @@ Info from Atariage and Atarimania M Network + @@ -2747,6 +2813,7 @@ Info from Atariage and Atarimania Telegames + @@ -2781,6 +2848,7 @@ Info from Atariage and Atarimania M Network + @@ -2826,6 +2894,7 @@ Info from Atariage and Atarimania Coleco + @@ -2838,6 +2907,7 @@ Info from Atariage and Atarimania Coleco + @@ -2850,6 +2920,7 @@ Info from Atariage and Atarimania Coleco + @@ -2862,6 +2933,7 @@ Info from Atariage and Atarimania Coleco + @@ -2874,6 +2946,7 @@ Info from Atariage and Atarimania <unknown> + @@ -2886,6 +2959,7 @@ Info from Atariage and Atarimania Coleco + @@ -2898,6 +2972,7 @@ Info from Atariage and Atarimania Coleco + @@ -2910,6 +2985,7 @@ Info from Atariage and Atarimania Coleco + @@ -2922,6 +2998,7 @@ Info from Atariage and Atarimania Coleco + @@ -2934,6 +3011,7 @@ Info from Atariage and Atarimania Coleco + @@ -2968,6 +3046,7 @@ Info from Atariage and Atarimania Epyx + @@ -2980,6 +3059,7 @@ Info from Atariage and Atarimania Epyx + @@ -3118,6 +3198,7 @@ Info from Atariage and Atarimania Atari + @@ -3130,6 +3211,7 @@ Info from Atariage and Atarimania Atari + @@ -3175,6 +3257,7 @@ Info from Atariage and Atarimania HES + @@ -3420,6 +3503,7 @@ Info from Atariage and Atarimania Xonox + @@ -3575,6 +3659,7 @@ Info from Atariage and Atarimania Atari + @@ -3587,6 +3672,7 @@ Info from Atariage and Atarimania Activision + @@ -3599,6 +3685,7 @@ Info from Atariage and Atarimania Activision + @@ -3611,6 +3698,7 @@ Info from Atariage and Atarimania Activision + @@ -3711,6 +3799,7 @@ Info from Atariage and Atarimania Sega + @@ -3723,6 +3812,7 @@ Info from Atariage and Atarimania Sega + @@ -3746,6 +3836,7 @@ Info from Atariage and Atarimania Atari + @@ -3758,6 +3849,7 @@ Info from Atariage and Atarimania Atari + @@ -3770,6 +3862,7 @@ Info from Atariage and Atarimania Atari + @@ -4029,6 +4122,7 @@ Info from Atariage and Atarimania + @@ -4141,6 +4235,7 @@ Info from Atariage and Atarimania Atari + @@ -4197,6 +4292,7 @@ Info from Atariage and Atarimania Atari + @@ -4209,6 +4305,7 @@ Info from Atariage and Atarimania Atari + @@ -4244,6 +4341,7 @@ Info from Atariage and Atarimania + @@ -4256,6 +4354,7 @@ Info from Atariage and Atarimania Atari + @@ -4269,6 +4368,7 @@ Info from Atariage and Atarimania + @@ -4381,6 +4481,7 @@ Info from Atariage and Atarimania + @@ -4394,6 +4495,7 @@ Info from Atariage and Atarimania + @@ -4407,6 +4509,7 @@ Info from Atariage and Atarimania + @@ -4452,6 +4555,7 @@ Info from Atariage and Atarimania HES + @@ -4531,6 +4635,7 @@ Info from Atariage and Atarimania + @@ -4544,6 +4649,7 @@ Info from Atariage and Atarimania + @@ -4756,6 +4862,7 @@ Info from Atariage and Atarimania + @@ -4769,6 +4876,7 @@ Info from Atariage and Atarimania + @@ -4782,6 +4890,7 @@ Info from Atariage and Atarimania + @@ -4894,6 +5003,7 @@ Info from Atariage and Atarimania + @@ -4907,6 +5017,7 @@ Info from Atariage and Atarimania + @@ -5007,6 +5118,7 @@ Info from Atariage and Atarimania Atari + @@ -5019,6 +5131,7 @@ Info from Atariage and Atarimania Atari + @@ -5075,6 +5188,7 @@ Info from Atariage and Atarimania Atari + @@ -5087,6 +5201,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -5099,6 +5214,7 @@ Info from Atariage and Atarimania CCE + @@ -5111,6 +5227,7 @@ Info from Atariage and Atarimania Tron + @@ -5123,6 +5240,7 @@ Info from Atariage and Atarimania Activision + @@ -5135,6 +5253,7 @@ Info from Atariage and Atarimania Activision + @@ -5147,6 +5266,7 @@ Info from Atariage and Atarimania CCE + @@ -5159,6 +5279,7 @@ Info from Atariage and Atarimania Atari + @@ -5171,6 +5292,7 @@ Info from Atariage and Atarimania Atari + @@ -5271,6 +5393,7 @@ Info from Atariage and Atarimania Atari + @@ -5294,6 +5417,7 @@ Info from Atariage and Atarimania Atari + @@ -5306,6 +5430,7 @@ Info from Atariage and Atarimania Atari + @@ -5318,6 +5443,7 @@ Info from Atariage and Atarimania Atari + @@ -5330,6 +5456,7 @@ Info from Atariage and Atarimania Atari + @@ -5353,6 +5480,7 @@ Info from Atariage and Atarimania Atari + @@ -5365,6 +5493,7 @@ Info from Atariage and Atarimania Atari + @@ -5455,6 +5584,7 @@ Info from Atariage and Atarimania + @@ -5478,6 +5608,7 @@ Info from Atariage and Atarimania Atari + @@ -5655,6 +5786,7 @@ Info from Atariage and Atarimania Tigervision + @@ -5667,6 +5799,7 @@ Info from Atariage and Atarimania Tigervision + @@ -5701,6 +5834,7 @@ Info from Atariage and Atarimania Absolute Entertainment + @@ -5813,6 +5947,7 @@ Info from Atariage and Atarimania + @@ -5826,6 +5961,7 @@ Info from Atariage and Atarimania + @@ -5838,6 +5974,7 @@ Info from Atariage and Atarimania Imagic + @@ -5850,6 +5987,7 @@ Info from Atariage and Atarimania Imagic + @@ -5907,6 +6045,7 @@ Info from Atariage and Atarimania Video Game Program + @@ -6194,6 +6333,7 @@ Info from Atariage and Atarimania Atari + @@ -6206,6 +6346,7 @@ Info from Atariage and Atarimania Atari + @@ -6240,6 +6381,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -6252,6 +6394,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -6286,6 +6429,7 @@ Info from Atariage and Atarimania Coleco + @@ -6408,6 +6552,7 @@ Info from Atariage and Atarimania UA Limited + @@ -6464,6 +6609,7 @@ Info from Atariage and Atarimania Atari + @@ -6476,6 +6622,7 @@ Info from Atariage and Atarimania CCE + @@ -6488,6 +6635,7 @@ Info from Atariage and Atarimania Digivision + @@ -6500,6 +6648,7 @@ Info from Atariage and Atarimania Atari + @@ -6512,6 +6661,7 @@ Info from Atariage and Atarimania Atari + @@ -6524,6 +6674,7 @@ Info from Atariage and Atarimania Atari + @@ -6591,6 +6742,7 @@ Info from Atariage and Atarimania Atari + @@ -6669,6 +6821,7 @@ Info from Atariage and Atarimania Xonox + @@ -6681,6 +6834,7 @@ Info from Atariage and Atarimania Xonox + @@ -6693,6 +6847,7 @@ Info from Atariage and Atarimania Activision + @@ -6705,6 +6860,7 @@ Info from Atariage and Atarimania Activision + @@ -6717,6 +6873,7 @@ Info from Atariage and Atarimania Salu + @@ -6729,6 +6886,7 @@ Info from Atariage and Atarimania Salu + @@ -6917,6 +7075,7 @@ Info from Atariage and Atarimania Atari + @@ -6929,6 +7088,7 @@ Info from Atariage and Atarimania Atari + @@ -6941,6 +7101,7 @@ Info from Atariage and Atarimania CCE + @@ -6964,6 +7125,7 @@ Info from Atariage and Atarimania Atari + @@ -6976,6 +7138,7 @@ Info from Atariage and Atarimania Atari + @@ -6999,6 +7162,7 @@ Info from Atariage and Atarimania Atari + @@ -7011,6 +7175,7 @@ Info from Atariage and Atarimania Atari + @@ -7045,6 +7210,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -7057,6 +7223,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -7069,6 +7236,7 @@ Info from Atariage and Atarimania Activision + @@ -7081,6 +7249,7 @@ Info from Atariage and Atarimania CCE + @@ -7093,6 +7262,7 @@ Info from Atariage and Atarimania Tron + @@ -7105,6 +7275,7 @@ Info from Atariage and Atarimania Activision + @@ -7250,6 +7421,7 @@ Info from Atariage and Atarimania Atari + @@ -7298,6 +7470,7 @@ Info from Atariage and Atarimania HES + @@ -7431,6 +7604,7 @@ Info from Atariage and Atarimania Atari + @@ -7443,6 +7617,7 @@ Info from Atariage and Atarimania Atari + @@ -7598,6 +7773,7 @@ Info from Atariage and Atarimania Sega + @@ -7610,6 +7786,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -7688,6 +7865,7 @@ Info from Atariage and Atarimania Atari + @@ -7700,6 +7878,7 @@ Info from Atariage and Atarimania <unknown> + @@ -7712,6 +7891,7 @@ Info from Atariage and Atarimania Atari + @@ -7725,6 +7905,7 @@ Info from Atariage and Atarimania + @@ -7738,6 +7919,7 @@ Info from Atariage and Atarimania + @@ -7773,6 +7955,7 @@ Info from Atariage and Atarimania Atari + @@ -7785,6 +7968,7 @@ Info from Atariage and Atarimania CCE + @@ -7797,6 +7981,7 @@ Info from Atariage and Atarimania CCE + @@ -7809,6 +7994,7 @@ Info from Atariage and Atarimania <unknown> + @@ -7821,6 +8007,7 @@ Info from Atariage and Atarimania Atari + @@ -7833,6 +8020,7 @@ Info from Atariage and Atarimania Atari + @@ -7900,6 +8088,7 @@ Info from Atariage and Atarimania Atari + @@ -7912,6 +8101,7 @@ Info from Atariage and Atarimania Atari + @@ -7924,6 +8114,7 @@ Info from Atariage and Atarimania Zirok + @@ -8157,6 +8348,7 @@ Info from Atariage and Atarimania + @@ -8170,6 +8362,7 @@ Info from Atariage and Atarimania + @@ -8183,6 +8376,7 @@ Info from Atariage and Atarimania + @@ -8228,6 +8422,7 @@ Info from Atariage and Atarimania Atari + @@ -8240,6 +8435,7 @@ Info from Atariage and Atarimania CCE + @@ -8252,6 +8448,7 @@ Info from Atariage and Atarimania Atari + @@ -8275,6 +8472,7 @@ Info from Atariage and Atarimania Telegames + @@ -8287,6 +8485,7 @@ Info from Atariage and Atarimania Activision + @@ -8299,6 +8498,7 @@ Info from Atariage and Atarimania CCE + @@ -8311,6 +8511,7 @@ Info from Atariage and Atarimania Activision + @@ -8510,6 +8711,7 @@ Info from Atariage and Atarimania Atari + @@ -8577,6 +8779,7 @@ Info from Atariage and Atarimania Coleco + @@ -8589,6 +8792,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -8601,6 +8805,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -8702,6 +8907,7 @@ Info from Atariage and Atarimania CommaVid + @@ -8805,6 +9011,7 @@ Info from Atariage and Atarimania Atari + @@ -8817,6 +9024,7 @@ Info from Atariage and Atarimania CCE + @@ -8829,6 +9037,7 @@ Info from Atariage and Atarimania Zirok + @@ -8842,6 +9051,7 @@ Info from Atariage and Atarimania + @@ -8877,6 +9087,7 @@ Info from Atariage and Atarimania M Network + @@ -8993,6 +9204,7 @@ Info from Atariage and Atarimania + @@ -9005,6 +9217,7 @@ Info from Atariage and Atarimania Dynacom + @@ -9133,6 +9346,7 @@ Info from Atariage and Atarimania Atari + @@ -9146,6 +9360,7 @@ Info from Atariage and Atarimania + @@ -9170,6 +9385,7 @@ Info from Atariage and Atarimania + @@ -9183,6 +9399,7 @@ Info from Atariage and Atarimania + @@ -9196,6 +9413,7 @@ Info from Atariage and Atarimania + @@ -9210,6 +9428,7 @@ Info from Atariage and Atarimania + @@ -9224,6 +9443,7 @@ Info from Atariage and Atarimania + @@ -9236,6 +9456,7 @@ Info from Atariage and Atarimania Atari + @@ -9248,6 +9469,7 @@ Info from Atariage and Atarimania Tigervision + @@ -9260,6 +9482,7 @@ Info from Atariage and Atarimania Tigervision + @@ -9272,6 +9495,7 @@ Info from Atariage and Atarimania Tigervision + @@ -9284,6 +9508,7 @@ Info from Atariage and Atarimania Tigervision + @@ -9297,6 +9522,7 @@ Info from Atariage and Atarimania + @@ -9368,6 +9594,7 @@ Info from Atariage and Atarimania + @@ -9380,6 +9607,7 @@ Info from Atariage and Atarimania Atari + @@ -9555,6 +9783,7 @@ Info from Atariage and Atarimania Atari + @@ -9567,6 +9796,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -9579,6 +9809,7 @@ Info from Atariage and Atarimania Atari + @@ -9591,6 +9822,7 @@ Info from Atariage and Atarimania CCE + @@ -9603,6 +9835,7 @@ Info from Atariage and Atarimania Intellivision + @@ -9615,6 +9848,7 @@ Info from Atariage and Atarimania Tron + @@ -9628,6 +9862,7 @@ Info from Atariage and Atarimania + @@ -9640,6 +9875,7 @@ Info from Atariage and Atarimania Atari + @@ -9652,6 +9888,7 @@ Info from Atariage and Atarimania Atari + @@ -9664,6 +9901,7 @@ Info from Atariage and Atarimania Atari + @@ -9676,6 +9914,7 @@ Info from Atariage and Atarimania Atari + @@ -9688,6 +9927,7 @@ Info from Atariage and Atarimania Atari + @@ -9700,6 +9940,7 @@ Info from Atariage and Atarimania Imagic + @@ -9712,6 +9953,7 @@ Info from Atariage and Atarimania Activision + @@ -9725,6 +9967,7 @@ Info from Atariage and Atarimania + @@ -9748,6 +9991,7 @@ Info from Atariage and Atarimania Joystik + @@ -9784,6 +10028,7 @@ Info from Atariage and Atarimania Xonox + @@ -9796,6 +10041,7 @@ Info from Atariage and Atarimania Atari + @@ -9820,6 +10066,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -9867,6 +10114,7 @@ Info from Atariage and Atarimania Coleco + @@ -9880,6 +10128,7 @@ Info from Atariage and Atarimania + @@ -9892,6 +10141,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -9949,6 +10199,7 @@ Info from Atariage and Atarimania Atari + @@ -9961,6 +10212,7 @@ Info from Atariage and Atarimania CCE + @@ -9974,6 +10226,7 @@ Info from Atariage and Atarimania + @@ -9986,6 +10239,7 @@ Info from Atariage and Atarimania Atari + @@ -10010,6 +10264,7 @@ Info from Atariage and Atarimania + @@ -10023,6 +10278,7 @@ Info from Atariage and Atarimania + @@ -10036,6 +10292,7 @@ Info from Atariage and Atarimania + @@ -10251,6 +10508,7 @@ Info from Atariage and Atarimania Atari + @@ -10263,6 +10521,7 @@ Info from Atariage and Atarimania Atari + @@ -10298,6 +10557,7 @@ Info from Atariage and Atarimania + @@ -10311,6 +10571,7 @@ Info from Atariage and Atarimania + @@ -10378,6 +10639,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -10412,6 +10674,7 @@ Info from Atariage and Atarimania Atari + @@ -10424,6 +10687,7 @@ Info from Atariage and Atarimania Atari + @@ -10436,6 +10700,7 @@ Info from Atariage and Atarimania Atari + @@ -10448,6 +10713,7 @@ Info from Atariage and Atarimania Atari + @@ -10704,6 +10970,7 @@ Info from Atariage and Atarimania Atari + @@ -10716,6 +10983,7 @@ Info from Atariage and Atarimania Atari + @@ -10728,6 +10996,7 @@ Info from Atariage and Atarimania Atari + @@ -10751,6 +11020,7 @@ Info from Atariage and Atarimania Absolute Entertainment + @@ -10895,6 +11165,7 @@ Info from Atariage and Atarimania Atari + @@ -10907,6 +11178,7 @@ Info from Atariage and Atarimania CCE + @@ -10919,6 +11191,7 @@ Info from Atariage and Atarimania <unknown> + @@ -10931,6 +11204,7 @@ Info from Atariage and Atarimania Zirok + @@ -10943,6 +11217,7 @@ Info from Atariage and Atarimania Atari + @@ -10955,6 +11230,7 @@ Info from Atariage and Atarimania Ubi Soft + @@ -11011,6 +11287,7 @@ Info from Atariage and Atarimania Atari + @@ -11023,6 +11300,7 @@ Info from Atariage and Atarimania Atari + @@ -11035,6 +11313,7 @@ Info from Atariage and Atarimania Atari + @@ -11058,6 +11337,7 @@ Info from Atariage and Atarimania Activision + @@ -11070,6 +11350,7 @@ Info from Atariage and Atarimania Activision + @@ -11082,6 +11363,7 @@ Info from Atariage and Atarimania Activision + @@ -11381,6 +11663,7 @@ Info from Atariage and Atarimania UA Limited + @@ -11404,6 +11687,7 @@ Info from Atariage and Atarimania Tigervision + @@ -11416,6 +11700,7 @@ Info from Atariage and Atarimania Tigervision + @@ -11439,6 +11724,7 @@ Info from Atariage and Atarimania Tigervision + @@ -11451,6 +11737,7 @@ Info from Atariage and Atarimania Atari + @@ -11463,6 +11750,7 @@ Info from Atariage and Atarimania Atari + @@ -11475,6 +11763,7 @@ Info from Atariage and Atarimania CCE + @@ -11487,6 +11776,7 @@ Info from Atariage and Atarimania Tron + @@ -11499,6 +11789,7 @@ Info from Atariage and Atarimania Atari + @@ -11511,6 +11802,7 @@ Info from Atariage and Atarimania Atari + @@ -11578,6 +11870,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -11590,6 +11883,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -11602,6 +11896,7 @@ Info from Atariage and Atarimania 20th Century Fox Video Games + @@ -11614,6 +11909,7 @@ Info from Atariage and Atarimania Activision + @@ -11626,6 +11922,7 @@ Info from Atariage and Atarimania CCE + @@ -11638,6 +11935,7 @@ Info from Atariage and Atarimania Activision + @@ -11650,6 +11948,7 @@ Info from Atariage and Atarimania Activision + @@ -11662,6 +11961,7 @@ Info from Atariage and Atarimania <unknown> + @@ -11674,6 +11974,7 @@ Info from Atariage and Atarimania Activision + @@ -11763,6 +12064,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -11775,6 +12077,7 @@ Info from Atariage and Atarimania Atari + @@ -11798,6 +12101,7 @@ Info from Atariage and Atarimania Atari + @@ -11810,6 +12114,7 @@ Info from Atariage and Atarimania Sunrise Software + @@ -11822,6 +12127,7 @@ Info from Atariage and Atarimania Telegames + @@ -11856,6 +12162,7 @@ Info from Atariage and Atarimania Atari + @@ -11945,6 +12252,7 @@ Info from Atariage and Atarimania HES + @@ -11969,6 +12277,7 @@ Info from Atariage and Atarimania + @@ -11982,6 +12291,7 @@ Info from Atariage and Atarimania + @@ -12005,6 +12315,7 @@ Info from Atariage and Atarimania Atari + @@ -12017,6 +12328,7 @@ Info from Atariage and Atarimania Atari + @@ -12073,6 +12385,7 @@ Info from Atariage and Atarimania Activision + @@ -12085,6 +12398,7 @@ Info from Atariage and Atarimania Activision + @@ -12119,6 +12433,7 @@ Info from Atariage and Atarimania Atari + @@ -12131,6 +12446,7 @@ Info from Atariage and Atarimania Atari + @@ -12143,6 +12459,7 @@ Info from Atariage and Atarimania Atari + @@ -12155,6 +12472,7 @@ Info from Atariage and Atarimania Atari + @@ -12167,6 +12485,7 @@ Info from Atariage and Atarimania Atari + @@ -12179,6 +12498,7 @@ Info from Atariage and Atarimania Atari + @@ -12191,6 +12511,7 @@ Info from Atariage and Atarimania Atari + @@ -12203,6 +12524,7 @@ Info from Atariage and Atarimania Atari + @@ -12215,6 +12537,7 @@ Info from Atariage and Atarimania Atari + @@ -12228,6 +12551,7 @@ Info from Atariage and Atarimania Atari + @@ -12240,6 +12564,7 @@ Info from Atariage and Atarimania Atari + @@ -12252,6 +12577,7 @@ Info from Atariage and Atarimania Atari + @@ -12264,6 +12590,7 @@ Info from Atariage and Atarimania <unknown> + @@ -12276,6 +12603,7 @@ Info from Atariage and Atarimania <unknown> + @@ -12288,6 +12616,7 @@ Info from Atariage and Atarimania Atari + @@ -12344,6 +12673,7 @@ Info from Atariage and Atarimania CCE + @@ -12389,6 +12719,7 @@ Info from Atariage and Atarimania Tigervision + @@ -12555,6 +12886,7 @@ Info from Atariage and Atarimania Activision + @@ -12600,6 +12932,7 @@ Info from Atariage and Atarimania Activision + @@ -12634,6 +12967,7 @@ Info from Atariage and Atarimania Atari + @@ -12646,6 +12980,7 @@ Info from Atariage and Atarimania CCE + @@ -12658,6 +12993,7 @@ Info from Atariage and Atarimania Atari + @@ -12670,6 +13006,7 @@ Info from Atariage and Atarimania Atari + @@ -12682,6 +13019,7 @@ Info from Atariage and Atarimania Xonox + @@ -12694,6 +13032,7 @@ Info from Atariage and Atarimania Xonox + @@ -12717,6 +13056,7 @@ Info from Atariage and Atarimania Activision + @@ -12729,6 +13069,7 @@ Info from Atariage and Atarimania Activision + @@ -12741,6 +13082,7 @@ Info from Atariage and Atarimania Coleco + @@ -12753,6 +13095,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -12897,6 +13240,7 @@ Info from Atariage and Atarimania Atari + @@ -12909,6 +13253,7 @@ Info from Atariage and Atarimania Atari + @@ -12921,6 +13266,7 @@ Info from Atariage and Atarimania Atari + @@ -12933,6 +13279,7 @@ Info from Atariage and Atarimania Atari + @@ -12945,6 +13292,7 @@ Info from Atariage and Atarimania Atari + @@ -12957,6 +13305,7 @@ Info from Atariage and Atarimania Atari + @@ -12970,6 +13319,7 @@ Info from Atariage and Atarimania + @@ -12983,6 +13333,7 @@ Info from Atariage and Atarimania + @@ -13282,6 +13633,7 @@ Info from Atariage and Atarimania + @@ -13295,6 +13647,7 @@ Info from Atariage and Atarimania + @@ -13318,6 +13671,7 @@ Info from Atariage and Atarimania Atari + @@ -13364,6 +13718,7 @@ Info from Atariage and Atarimania + @@ -13377,6 +13732,7 @@ Info from Atariage and Atarimania + @@ -13400,6 +13756,7 @@ Info from Atariage and Atarimania Atari + @@ -13412,6 +13769,7 @@ Info from Atariage and Atarimania Atari + @@ -13424,6 +13782,7 @@ Info from Atariage and Atarimania Atari + @@ -13436,6 +13795,7 @@ Info from Atariage and Atarimania Atari + @@ -13448,6 +13808,7 @@ Info from Atariage and Atarimania Xonox + @@ -13460,6 +13821,7 @@ Info from Atariage and Atarimania Xonox + @@ -13472,6 +13834,7 @@ Info from Atariage and Atarimania Absolute Entertainment + @@ -13484,6 +13847,7 @@ Info from Atariage and Atarimania Absolute Entertainment + @@ -13606,6 +13970,7 @@ Info from Atariage and Atarimania Imagic + @@ -13684,6 +14049,7 @@ Info from Atariage and Atarimania HES + @@ -13696,6 +14062,7 @@ Info from Atariage and Atarimania Coleco + @@ -13708,6 +14075,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -13720,6 +14088,7 @@ Info from Atariage and Atarimania Coleco + @@ -13776,6 +14145,7 @@ Info from Atariage and Atarimania Atari + @@ -13788,6 +14158,7 @@ Info from Atariage and Atarimania Intellivision + @@ -13800,6 +14171,7 @@ Info from Atariage and Atarimania CCE + @@ -13812,6 +14184,7 @@ Info from Atariage and Atarimania Digivision + @@ -13824,6 +14197,7 @@ Info from Atariage and Atarimania Atari + @@ -13836,6 +14210,7 @@ Info from Atariage and Atarimania Century + @@ -13848,6 +14223,7 @@ Info from Atariage and Atarimania Atari + @@ -13860,6 +14236,7 @@ Info from Atariage and Atarimania Atari + @@ -13872,6 +14249,7 @@ Info from Atariage and Atarimania Atari + @@ -13895,6 +14273,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -13907,6 +14286,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -13941,6 +14321,7 @@ Info from Atariage and Atarimania Atari + @@ -13953,6 +14334,7 @@ Info from Atariage and Atarimania Atari + @@ -13976,6 +14358,7 @@ Info from Atariage and Atarimania Atari + @@ -13988,6 +14371,7 @@ Info from Atariage and Atarimania Atari + @@ -14000,6 +14384,7 @@ Info from Atariage and Atarimania Atari + @@ -14012,6 +14397,7 @@ Info from Atariage and Atarimania Atari + @@ -14256,6 +14642,7 @@ Info from Atariage and Atarimania Activision + @@ -14268,6 +14655,7 @@ Info from Atariage and Atarimania Activision + @@ -14280,6 +14668,7 @@ Info from Atariage and Atarimania Activision + @@ -14578,6 +14967,7 @@ Info from Atariage and Atarimania Xonox + @@ -14590,6 +14980,7 @@ Info from Atariage and Atarimania Xonox + @@ -14646,6 +15037,7 @@ Info from Atariage and Atarimania HES + @@ -14658,6 +15050,7 @@ Info from Atariage and Atarimania Tigervision + @@ -14670,6 +15063,7 @@ Info from Atariage and Atarimania Tigervision + @@ -14683,6 +15077,7 @@ Info from Atariage and Atarimania + @@ -14696,6 +15091,7 @@ Info from Atariage and Atarimania + @@ -14708,6 +15104,7 @@ Info from Atariage and Atarimania <unknown> + @@ -14852,6 +15249,7 @@ Info from Atariage and Atarimania Atari + @@ -14864,6 +15262,7 @@ Info from Atariage and Atarimania Atari + @@ -14920,6 +15319,7 @@ Info from Atariage and Atarimania Sega + @@ -14932,6 +15332,7 @@ Info from Atariage and Atarimania Sega + @@ -15010,6 +15411,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -15022,6 +15424,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -15034,6 +15437,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -15046,6 +15450,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -15058,6 +15463,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -15070,6 +15476,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -15093,6 +15500,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -15161,6 +15569,7 @@ Info from Atariage and Atarimania + @@ -15174,6 +15583,7 @@ Info from Atariage and Atarimania + @@ -15450,6 +15860,7 @@ Info from Atariage and Atarimania Imagic + @@ -15462,6 +15873,7 @@ Info from Atariage and Atarimania Imagic + @@ -15474,6 +15886,7 @@ Info from Atariage and Atarimania Epyx + @@ -15486,6 +15899,7 @@ Info from Atariage and Atarimania Epyx + @@ -15498,6 +15912,7 @@ Info from Atariage and Atarimania HES + @@ -15510,6 +15925,7 @@ Info from Atariage and Atarimania Atari + @@ -15522,6 +15938,7 @@ Info from Atariage and Atarimania Atari + @@ -15534,6 +15951,7 @@ Info from Atariage and Atarimania CCE + @@ -15546,6 +15964,7 @@ Info from Atariage and Atarimania CCE + @@ -15602,6 +16021,7 @@ Info from Atariage and Atarimania Arcadia Corporation ~ Starpath Corporation + @@ -15614,6 +16034,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -15626,6 +16047,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -15672,6 +16094,7 @@ Info from Atariage and Atarimania + @@ -15684,6 +16107,7 @@ Info from Atariage and Atarimania CCE + @@ -15697,6 +16121,7 @@ Info from Atariage and Atarimania + @@ -15709,6 +16134,7 @@ Info from Atariage and Atarimania CCE + @@ -15721,6 +16147,7 @@ Info from Atariage and Atarimania HES + @@ -15733,6 +16160,7 @@ Info from Atariage and Atarimania Xonox + @@ -15745,6 +16173,7 @@ Info from Atariage and Atarimania Digivision + @@ -15757,6 +16186,7 @@ Info from Atariage and Atarimania VGS + @@ -15769,6 +16199,7 @@ Info from Atariage and Atarimania CCE + @@ -15781,6 +16212,7 @@ Info from Atariage and Atarimania Tron + @@ -15870,6 +16302,7 @@ Info from Atariage and Atarimania Amiga + @@ -15882,6 +16315,7 @@ Info from Atariage and Atarimania Amiga + @@ -15960,6 +16394,7 @@ Info from Atariage and Atarimania Atari + @@ -15972,6 +16407,7 @@ Info from Atariage and Atarimania Atari + @@ -15984,6 +16420,7 @@ Info from Atariage and Atarimania Atari + @@ -15996,6 +16433,7 @@ Info from Atariage and Atarimania Atari + @@ -16008,6 +16446,7 @@ Info from Atariage and Atarimania Atari + @@ -16108,6 +16547,7 @@ Info from Atariage and Atarimania Sega + @@ -16164,6 +16604,7 @@ Info from Atariage and Atarimania American Videogame + @@ -16176,6 +16617,7 @@ Info from Atariage and Atarimania Atari + @@ -16188,6 +16630,7 @@ Info from Atariage and Atarimania Atari + @@ -16200,6 +16643,7 @@ Info from Atariage and Atarimania Atari + @@ -16212,6 +16656,7 @@ Info from Atariage and Atarimania Atari + @@ -16224,6 +16669,7 @@ Info from Atariage and Atarimania Atari + @@ -16247,6 +16693,7 @@ Info from Atariage and Atarimania Atari + @@ -16270,6 +16717,7 @@ Info from Atariage and Atarimania Atari + @@ -16436,6 +16884,7 @@ Info from Atariage and Atarimania Activision + @@ -16448,6 +16897,7 @@ Info from Atariage and Atarimania Coleco + @@ -16526,6 +16976,7 @@ Info from Atariage and Atarimania Absolute Entertainment + @@ -16538,6 +16989,7 @@ Info from Atariage and Atarimania Absolute Entertainment + @@ -16572,6 +17024,7 @@ Info from Atariage and Atarimania Xonox + @@ -16584,6 +17037,7 @@ Info from Atariage and Atarimania Absolute Entertainment + @@ -16596,6 +17050,7 @@ Info from Atariage and Atarimania DSD-Camelot + @@ -16630,6 +17085,7 @@ Info from Atariage and Atarimania Atari + @@ -16719,6 +17175,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -16731,6 +17188,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -16776,6 +17234,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -16788,6 +17247,7 @@ Info from Atariage and Atarimania Parker Brothers + @@ -16866,6 +17326,7 @@ Info from Atariage and Atarimania Universal + @@ -16878,6 +17339,7 @@ Info from Atariage and Atarimania Sega + @@ -16890,6 +17352,7 @@ Info from Atariage and Atarimania Atari + @@ -16902,6 +17365,7 @@ Info from Atariage and Atarimania CCE + @@ -16914,6 +17378,7 @@ Info from Atariage and Atarimania VGS + @@ -16926,6 +17391,7 @@ Info from Atariage and Atarimania Atari + @@ -16938,6 +17404,7 @@ Info from Atariage and Atarimania Atari + @@ -17082,6 +17549,7 @@ Info from Atariage and Atarimania CommaVid + @@ -17095,6 +17563,7 @@ Info from Atariage and Atarimania CommaVid + @@ -17294,6 +17763,7 @@ Info from Atariage and Atarimania HES + @@ -17394,6 +17864,7 @@ Info from Atariage and Atarimania Imagic + @@ -17406,6 +17877,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -17418,6 +17890,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -17430,6 +17903,7 @@ Info from Atariage and Atarimania Epyx + @@ -17442,6 +17916,7 @@ Info from Atariage and Atarimania Epyx + @@ -17619,6 +18094,7 @@ Info from Atariage and Atarimania Atari + @@ -17631,6 +18107,7 @@ Info from Atariage and Atarimania Atari + @@ -17643,6 +18120,7 @@ Info from Atariage and Atarimania Atari + @@ -17655,6 +18133,7 @@ Info from Atariage and Atarimania Atari + @@ -17667,6 +18146,7 @@ Info from Atariage and Atarimania CCE + @@ -17736,6 +18216,7 @@ Info from Atariage and Atarimania Coleco + @@ -17748,6 +18229,7 @@ Info from Atariage and Atarimania CBS Electronics + @@ -17765,26 +18247,26 @@ Info from Atariage and Atarimania - - - + CompuMate (PAL) 1983 Spectravideo + - - Compumate + + CompuMate 1983 Spectravideo + diff --git a/src/emu/bus/bus.mak b/src/emu/bus/bus.mak index 99475416480..9fa91b00075 100644 --- a/src/emu/bus/bus.mak +++ b/src/emu/bus/bus.mak @@ -562,18 +562,33 @@ endif #------------------------------------------------- # -#@src/emu/bus/vcs/ctrl.h,BUSES += VCS +#@src/emu/bus/vcs/vcs_slot.h,BUSES += VCS #------------------------------------------------- ifneq ($(filter VCS,$(BUSES)),) OBJDIRS += $(BUSOBJ)/vcs -BUSOBJS += $(BUSOBJ)/vcs/ctrl.o -BUSOBJS += $(BUSOBJ)/vcs/joystick.o -BUSOBJS += $(BUSOBJ)/vcs/joybooster.o -BUSOBJS += $(BUSOBJ)/vcs/keypad.o -BUSOBJS += $(BUSOBJ)/vcs/lightpen.o -BUSOBJS += $(BUSOBJ)/vcs/paddles.o -BUSOBJS += $(BUSOBJ)/vcs/wheel.o +BUSOBJS += $(BUSOBJ)/vcs/vcs_slot.o +BUSOBJS += $(BUSOBJ)/vcs/rom.o +BUSOBJS += $(BUSOBJ)/vcs/compumat.o +BUSOBJS += $(BUSOBJ)/vcs/dpc.o +BUSOBJS += $(BUSOBJ)/vcs/scharger.o +endif + + +#------------------------------------------------- +# +#@src/emu/bus/vcs/ctrl.h,BUSES += VCS_CTRL +#------------------------------------------------- + +ifneq ($(filter VCS_CTRL,$(BUSES)),) +OBJDIRS += $(BUSOBJ)/vcs_ctrl +BUSOBJS += $(BUSOBJ)/vcs_ctrl/ctrl.o +BUSOBJS += $(BUSOBJ)/vcs_ctrl/joystick.o +BUSOBJS += $(BUSOBJ)/vcs_ctrl/joybooster.o +BUSOBJS += $(BUSOBJ)/vcs_ctrl/keypad.o +BUSOBJS += $(BUSOBJ)/vcs_ctrl/lightpen.o +BUSOBJS += $(BUSOBJ)/vcs_ctrl/paddles.o +BUSOBJS += $(BUSOBJ)/vcs_ctrl/wheel.o endif diff --git a/src/emu/bus/vcs/compumat.c b/src/emu/bus/vcs/compumat.c new file mode 100644 index 00000000000..fe67e120c41 --- /dev/null +++ b/src/emu/bus/vcs/compumat.c @@ -0,0 +1,51 @@ +/*************************************************************************** + + Atari 2600 cart Spectravideo Compumate (Cart + keyboard!) + + This is tricky to implement and it is only a skeleton ATM. + The device needs to interface with both the TIA and the RIOT. + +***************************************************************************/ + + +#include "emu.h" +#include "compumat.h" + +const device_type A26_ROM_COMPUMATE = &device_creator; + + +a26_rom_cm_device::a26_rom_cm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_COMPUMATE, "Atari 2600 ROM Cart Compumate", tag, owner, clock, "a2600_cm", __FILE__) +{ +} + +//------------------------------------------------- +// mapper specific start/reset +//------------------------------------------------- + +void a26_rom_cm_device::device_start() +{ + save_item(NAME(m_base_bank)); +} + +void a26_rom_cm_device::device_reset() +{ + m_base_bank = 3; +} + + +static INPUT_PORTS_START( keyboard ) +INPUT_PORTS_END + + +ioport_constructor a26_rom_cm_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( keyboard ); +} + + + +READ8_MEMBER(a26_rom_cm_device::read_rom) +{ + return m_rom[offset + (m_base_bank * 0x1000)]; +} diff --git a/src/emu/bus/vcs/compumat.h b/src/emu/bus/vcs/compumat.h new file mode 100644 index 00000000000..d2d81fc83f0 --- /dev/null +++ b/src/emu/bus/vcs/compumat.h @@ -0,0 +1,33 @@ +#ifndef __VCS_COMPUMAT_H +#define __VCS_COMPUMAT_H + +#include "rom.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> a26_rom_cm_device + +class a26_rom_cm_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_cm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual ioport_constructor device_input_ports() const; + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + +private: +}; + + +// device type definition +extern const device_type A26_ROM_COMPUMATE; + +#endif diff --git a/src/emu/bus/vcs/dpc.c b/src/emu/bus/vcs/dpc.c new file mode 100644 index 00000000000..85d8689067d --- /dev/null +++ b/src/emu/bus/vcs/dpc.c @@ -0,0 +1,282 @@ +/*************************************************************************** + + + Atari 2600 cart with DPC chip (Pitfall II) + +***************************************************************************/ + + +#include "emu.h" +#include "dpc.h" + + +// DPC device + +const device_type ATARI_DPC = &device_creator; + + +dpc_device::dpc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, ATARI_DPC, "Atari DCP", tag, owner, clock, "atari_dcp", __FILE__), + m_displaydata(NULL) +{ +} + + +void dpc_device::device_start() +{ + m_oscillator = timer_alloc(TIMER_OSC); + m_oscillator->reset(); +} + +void dpc_device::device_reset() +{ + for (int data_fetcher = 0; data_fetcher < 8; data_fetcher++) + { + m_df[data_fetcher].osc_clk = 0; + m_df[data_fetcher].flag = 0; + m_df[data_fetcher].music_mode = 0; + } + m_oscillator->adjust(attotime::from_hz(18400), 0, attotime::from_hz(18400)); + +} + +void dpc_device::check_flag(UINT8 data_fetcher) +{ + /* Set flag when low counter equals top */ + if (m_df[data_fetcher].low == m_df[data_fetcher].top) + m_df[data_fetcher].flag = 1; + + /* Reset flag when low counter equals bottom */ + if (m_df[data_fetcher].low == m_df[data_fetcher].bottom) + m_df[data_fetcher].flag = 0; +} + +void dpc_device::decrement_counter(UINT8 data_fetcher) +{ + m_df[data_fetcher].low -= 1; + if (m_df[data_fetcher].low == 0xff) + { + m_df[data_fetcher].high -= 1; + if (data_fetcher > 4 && m_df[data_fetcher].music_mode) + m_df[data_fetcher].low = m_df[data_fetcher].top; + } + + check_flag(data_fetcher); +} + + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void dpc_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + if (id == TIMER_OSC) + { + // callback + for (int data_fetcher = 5; data_fetcher < 8; data_fetcher++) + { + if (m_df[data_fetcher].osc_clk) + { + decrement_counter(data_fetcher); + } + } + } +} + + +//------------------------------------------------- +// Read / Write accesses +//------------------------------------------------- + +READ8_MEMBER(dpc_device::read) +{ + static const UINT8 dpc_amplitude[8] = { 0x00, 0x04, 0x05, 0x09, 0x06, 0x0a, 0x0b, 0x0f }; + UINT8 data_fetcher = offset & 0x07; + UINT8 data = 0xff; + + //logerror("%04X: Read from DPC offset $%02X\n", machine().device("maincpu")->pc(), offset); + if (offset < 0x08) + { + switch(offset & 0x06) + { + case 0x00: // Random number generator + case 0x02: + return m_shift_reg; + case 0x04: // Sound value, MOVAMT value AND'd with Draw Line Carry; with Draw Line Add + m_latch_62 = m_latch_64; + case 0x06: // Sound value, MOVAMT value AND'd with Draw Line Carry; without Draw Line Add + m_latch_64 = m_latch_62 + m_df[4].top; + m_dlc = (m_latch_62 + m_df[4].top > 0xff) ? 1 : 0; + data = 0; + if (m_df[5].music_mode && m_df[5].flag) + data |= 0x01; + + if (m_df[6].music_mode && m_df[6].flag) + data |= 0x02; + + if (m_df[7].music_mode && m_df[7].flag) + data |= 0x04; + + return (m_dlc ? m_movamt & 0xf0 : 0) | dpc_amplitude[data]; + } + } + else + { + UINT8 display_data = m_displaydata[(~((m_df[data_fetcher].low | (m_df[data_fetcher].high << 8))) & 0x7ff)]; + + switch (offset & 0x38) + { + case 0x08: // display data + data = display_data; + break; + case 0x10: // display data AND'd w/flag + data = m_df[data_fetcher].flag ? display_data : 0x00; + break; + case 0x18: // display data AND'd w/flag, nibbles swapped + data = m_df[data_fetcher].flag ? BITSWAP8(display_data,3,2,1,0,7,6,5,4) : 0x00; + break; + case 0x20: // display data AND'd w/flag, byte reversed + data = m_df[data_fetcher].flag ? BITSWAP8(display_data,0,1,2,3,4,5,6,7) : 0x00; + break; + case 0x28: // display data AND'd w/flag, rotated right + data = m_df[data_fetcher].flag ? (display_data >> 1) : 0x00; + break; + case 0x30: // display data AND'd w/flag, rotated left + data = m_df[data_fetcher].flag ? (display_data << 1) : 0x00; + break; + case 0x38: // flag + data = m_df[data_fetcher].flag ? 0xff : 0x00; + break; + } + + if (data_fetcher < 5 || !m_df[data_fetcher].osc_clk) + { + decrement_counter(data_fetcher); + } + } + return data; +} + +WRITE8_MEMBER(dpc_device::write) +{ + UINT8 data_fetcher = offset & 0x07; + + switch (offset & 0x38) + { + case 0x00: // Top count + m_df[data_fetcher].top = data; + m_df[data_fetcher].flag = 0; + check_flag(data_fetcher); + break; + case 0x08: // Bottom count + m_df[data_fetcher].bottom = data; + check_flag(data_fetcher); + break; + case 0x10: // Counter low + m_df[data_fetcher].low = data; + if (data_fetcher == 4) + m_latch_64 = data; + + if (data_fetcher > 4 && m_df[data_fetcher].music_mode) + m_df[data_fetcher].low = m_df[data_fetcher].top; + + check_flag(data_fetcher); + break; + case 0x18: // Counter high + m_df[data_fetcher].high = data; + m_df[data_fetcher].music_mode = data & 0x10; + m_df[data_fetcher].osc_clk = data & 0x20; + if (data_fetcher > 4 && m_df[data_fetcher].music_mode && m_df[data_fetcher].low == 0xff) + { + m_df[data_fetcher].low = m_df[data_fetcher].top; + check_flag(data_fetcher); + } + break; + case 0x20: // Draw line movement value / MOVAMT + m_movamt = data; + break; + case 0x28: // Not used + logerror("%04X: Write to unused DPC register $%02X, data $%02X\n", machine().device("maincpu")->pc(), offset, data); + break; + case 0x30: // Random number generator reset + m_shift_reg = 0; + break; + case 0x38: // Not used + logerror("%04X: Write to unused DPC register $%02X, data $%02X\n", machine().device("maincpu")->pc(), offset, data); + break; + } +} + + + +// cart device + +const device_type A26_ROM_DPC = &device_creator; + + +a26_rom_dpc_device::a26_rom_dpc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f8_device(mconfig, A26_ROM_DPC, "Atari 2600 ROM Cart Pitfall II", tag, owner, clock, "a2600_dcp", __FILE__), + m_dpc(*this, "dpc") +{ +} + +//------------------------------------------------- +// mapper specific start/reset +//------------------------------------------------- + +void a26_rom_dpc_device::device_start() +{ + save_item(NAME(m_base_bank)); +} + +void a26_rom_dpc_device::device_reset() +{ + m_base_bank = 0; +} + +void a26_rom_dpc_device::setup_addon_ptr(UINT8 *ptr) +{ + m_dpc->set_display_data(ptr); +} + + +static MACHINE_CONFIG_FRAGMENT( a26_dpc ) + MCFG_DEVICE_ADD("dpc", ATARI_DPC, 0) +MACHINE_CONFIG_END + +machine_config_constructor a26_rom_dpc_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( a26_dpc ); +} + + +READ8_MEMBER(a26_rom_dpc_device::read_rom) +{ + if (offset < 0x40) + return m_dpc->read(space, offset); + else + return a26_rom_f8_device::read_rom(space, offset); +} + +WRITE8_MEMBER(a26_rom_dpc_device::write_bank) +{ + if (offset >= 0x40 && offset < 0x80) + m_dpc->write(space, offset, data); + else + a26_rom_f8_device::write_bank(space, offset, data); +} + +DIRECT_UPDATE_MEMBER(a26_rom_dpc_device::cart_opbase) +{ + if (!direct.space().debugger_access()) + { + UINT8 new_bit; + new_bit = (m_dpc->m_shift_reg & 0x80) ^ ((m_dpc->m_shift_reg & 0x20) << 2); + new_bit = new_bit ^ (((m_dpc->m_shift_reg & 0x10) << 3) ^ ((m_dpc->m_shift_reg & 0x08) << 4)); + new_bit = new_bit ^ 0x80; + m_dpc->m_shift_reg = new_bit | (m_dpc->m_shift_reg >> 1); + } + return address; +} + diff --git a/src/emu/bus/vcs/dpc.h b/src/emu/bus/vcs/dpc.h new file mode 100644 index 00000000000..8cf12d893eb --- /dev/null +++ b/src/emu/bus/vcs/dpc.h @@ -0,0 +1,93 @@ +#ifndef __VCS_DCP_H +#define __VCS_DCP_H + +#include "rom.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// TO DO: DPC should be made a separate device! + +struct df_t { + UINT8 top; + UINT8 bottom; + UINT8 low; + UINT8 high; + UINT8 flag; + UINT8 music_mode; /* Only used by data fetchers 5,6, and 7 */ + UINT8 osc_clk; /* Only used by data fetchers 5,6, and 7 */ +}; + +// m_dpc.oscillator = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(a2600_state::modeDPC_timer_callback),this)); + +class dpc_device : public device_t +{ +public: + // construction/destruction + dpc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + df_t m_df[8]; + UINT8 m_movamt; + UINT8 m_latch_62; + UINT8 m_latch_64; + UINT8 m_dlc; + UINT8 m_shift_reg; + UINT8 *m_displaydata; + void set_display_data(UINT8 *data) { m_displaydata = data; } + + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual DECLARE_READ8_MEMBER(read); + virtual DECLARE_WRITE8_MEMBER(write); + +private: + + void decrement_counter(UINT8 data_fetcher); + void check_flag(UINT8 data_fetcher); + + static const device_timer_id TIMER_OSC = 0; + emu_timer *m_oscillator; +}; + + +// device type definition +extern const device_type ATARI_DPC; + + + +// ======================> a26_rom_dpc_device + +class a26_rom_dpc_device : public a26_rom_f8_device +{ +public: + // construction/destruction + a26_rom_dpc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual machine_config_constructor device_mconfig_additions() const; + virtual void device_reset(); + + required_device m_dpc; + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); + virtual DECLARE_DIRECT_UPDATE_MEMBER(cart_opbase); + + virtual void setup_addon_ptr(UINT8 *ptr); + +protected: +// int m_reset_bank; +}; + + +// device type definition +extern const device_type A26_ROM_DPC; + +#endif diff --git a/src/emu/bus/vcs/rom.c b/src/emu/bus/vcs/rom.c new file mode 100755 index 00000000000..2953f705e2c --- /dev/null +++ b/src/emu/bus/vcs/rom.c @@ -0,0 +1,1054 @@ +/*********************************************************************************************************** + + A2600 VCS ROM cart emulation + Simple cart hardware with no additional hw + + Mapper implementation based on the wonderful docs by Kevtris + http://blog.kevtris.org/blogfiles/Atari%202600%20Mappers.txt + + (also inspired by previous work by Wilbert Pol et al.) + + ***********************************************************************************************************/ + + +#include "emu.h" +#include "rom.h" + + +//------------------------------------------------- +// a26_rom_*k_device - constructor +//------------------------------------------------- + +const device_type A26_ROM_2K = &device_creator; +const device_type A26_ROM_4K = &device_creator; +const device_type A26_ROM_F4 = &device_creator; +const device_type A26_ROM_F6 = &device_creator; +const device_type A26_ROM_F8 = &device_creator; +const device_type A26_ROM_F8_SW = &device_creator; +const device_type A26_ROM_FA = &device_creator; +const device_type A26_ROM_FE = &device_creator; +const device_type A26_ROM_3E = &device_creator; +const device_type A26_ROM_3F = &device_creator; +const device_type A26_ROM_E0 = &device_creator; +const device_type A26_ROM_E7 = &device_creator; +const device_type A26_ROM_UA = &device_creator; +const device_type A26_ROM_CV = &device_creator; +const device_type A26_ROM_DC = &device_creator; +const device_type A26_ROM_FV = &device_creator; +const device_type A26_ROM_JVP = &device_creator; +const device_type A26_ROM_4IN1 = &device_creator; +const device_type A26_ROM_8IN1 = &device_creator; +const device_type A26_ROM_32IN1 = &device_creator; + + +a26_rom_2k_device::a26_rom_2k_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_vcs_cart_interface( mconfig, *this ) +{ +} + +a26_rom_2k_device::a26_rom_2k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, A26_ROM_2K, "Atari VCS 2600 2K ROM Carts", tag, owner, clock, "vcs_2k", __FILE__), + device_vcs_cart_interface( mconfig, *this ) +{ +} + + +a26_rom_4k_device::a26_rom_4k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_2k_device(mconfig, A26_ROM_4K, "Atari VCS 2600 4K ROM Carts", tag, owner, clock, "vcs_4k", __FILE__) +{ +} + + +a26_rom_f6_device::a26_rom_f6_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) + : a26_rom_2k_device(mconfig, type, name, tag, owner, clock, shortname, source), + m_base_bank(-1) // set to -1 to help the Xin1 multicart... +{ +} + +a26_rom_f6_device::a26_rom_f6_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_2k_device(mconfig, A26_ROM_F6, "Atari VCS 2600 ROM Carts w/F6 bankswitch", tag, owner, clock, "vcs_f6", __FILE__), + m_base_bank(-1) // set to -1 to help the Xin1 multicart... +{ +} + + +a26_rom_f4_device::a26_rom_f4_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_F4, "Atari VCS 2600 ROM Carts w/F4 bankswitch", tag, owner, clock, "vcs_f4", __FILE__) +{ +} + + +a26_rom_f8_device::a26_rom_f8_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) + : a26_rom_f6_device(mconfig, type, name, tag, owner, clock, shortname, source) +{ +} + +a26_rom_f8_device::a26_rom_f8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_F8, "Atari VCS 2600 ROM Carts w/F8 bankswitch", tag, owner, clock, "vcs_f8", __FILE__) +{ +} + +a26_rom_f8_sw_device::a26_rom_f8_sw_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f8_device(mconfig, A26_ROM_F8_SW, "Atari VCS 2600 ROM Cart Snow White", tag, owner, clock, "vcs_f8_sw", __FILE__) +{ +} + +a26_rom_fa_device::a26_rom_fa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_FA, "Atari VCS 2600 ROM Carts w/FA bankswitch", tag, owner, clock, "vcs_fa", __FILE__) +{ +} + + +a26_rom_fe_device::a26_rom_fe_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_2k_device(mconfig, A26_ROM_FE, "Atari VCS 2600 ROM Carts w/FE bankswitch", tag, owner, clock, "vcs_fe", __FILE__) +{ +} + + +a26_rom_3e_device::a26_rom_3e_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_3E, "Atari VCS 2600 ROM Carts w/3E bankswitch", tag, owner, clock, "vcs_3e", __FILE__) +{ +} + + +a26_rom_3f_device::a26_rom_3f_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_3F, "Atari VCS 2600 ROM Carts w/3F bankswitch", tag, owner, clock, "vcs_3f", __FILE__) +{ +} + + +a26_rom_e0_device::a26_rom_e0_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_E0, "Atari VCS 2600 ROM Carts w/E0 bankswitch", tag, owner, clock, "vcs_e0", __FILE__) +{ +} + + +a26_rom_e7_device::a26_rom_e7_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_E7, "Atari VCS 2600 ROM Carts w/E7 bankswitch", tag, owner, clock, "vcs_e7", __FILE__) +{ +} + + +a26_rom_ua_device::a26_rom_ua_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_UA, "Atari VCS 2600 ROM Carts w/UA bankswitch", tag, owner, clock, "vcs_ua", __FILE__) +{ +} + + +a26_rom_cv_device::a26_rom_cv_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_2k_device(mconfig, A26_ROM_CV, "Atari VCS 2600 ROM Carts w/Commavid bankswitch", tag, owner, clock, "vcs_cv", __FILE__) +{ +} + + +a26_rom_dc_device::a26_rom_dc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_DC, "Atari VCS 2600 ROM Carts w/Dynacom bankswitch", tag, owner, clock, "vcs_dc", __FILE__) +{ +} + + +a26_rom_fv_device::a26_rom_fv_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_FV, "Atari VCS 2600 ROM Carts w/FV bankswitch", tag, owner, clock, "vcs_fv", __FILE__) +{ +} + + +a26_rom_jvp_device::a26_rom_jvp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_JVP, "Atari VCS 2600 ROM Carts w/JVP bankswitch", tag, owner, clock, "vcs_jvp", __FILE__) +{ +} + + +a26_rom_4in1_device::a26_rom_4in1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_4IN1, "Atari VCS 2600 ROM Cart 4 in 1", tag, owner, clock, "vcs_4in1", __FILE__) +{ +} + + +a26_rom_8in1_device::a26_rom_8in1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f8_device(mconfig, A26_ROM_8IN1, "Atari VCS 2600 ROM Cart 8 in 1", tag, owner, clock, "vcs_8in1", __FILE__) +{ +} + + +a26_rom_32in1_device::a26_rom_32in1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_32IN1, "Atari VCS 2600 ROM Cart 32 in 1", tag, owner, clock, "vcs_32in1", __FILE__) +{ +} + + +void a26_rom_2k_device::device_start() +{ +} + +void a26_rom_2k_device::device_reset() +{ +} + +void a26_rom_f6_device::device_start() +{ + save_item(NAME(m_base_bank)); +} + +void a26_rom_f6_device::device_reset() +{ + m_base_bank = 0; +} + +void a26_rom_f4_device::device_reset() +{ + m_base_bank = 7; +} + +void a26_rom_f8_sw_device::device_reset() +{ + // Snow White proto starts from bank 1!!! + m_base_bank = 1; +} + +void a26_rom_fe_device::device_start() +{ + save_item(NAME(m_base_bank)); + save_item(NAME(m_trigger_on_next_access)); +} + +void a26_rom_fe_device::device_reset() +{ + m_base_bank = 0; + m_trigger_on_next_access = 0; +} + +void a26_rom_3e_device::device_start() +{ + save_item(NAME(m_base_bank)); + save_item(NAME(m_ram_bank)); + save_item(NAME(m_ram_enable)); +} + +void a26_rom_3e_device::device_reset() +{ + m_num_bank = m_rom.count() / 0x800; + m_base_bank = m_num_bank - 1; + m_ram_bank = 0; + m_ram_enable = 0; +} + +void a26_rom_3f_device::device_reset() +{ + m_num_bank = m_rom.count() / 0x800; + m_base_bank = m_num_bank - 1; +} + +void a26_rom_e0_device::device_start() +{ + save_item(NAME(m_base_banks)); +} + +void a26_rom_e0_device::device_reset() +{ + m_base_banks[0] = 4; + m_base_banks[1] = 5; + m_base_banks[2] = 6; + m_base_banks[3] = 7; +} + +void a26_rom_e7_device::device_start() +{ + save_item(NAME(m_base_bank)); + save_item(NAME(m_ram_bank)); +} + +void a26_rom_e7_device::device_reset() +{ + m_base_bank = 0; + m_ram_bank = 0; +} + +void a26_rom_ua_device::device_reset() +{ + m_base_bank = 0; +} + +void a26_rom_fv_device::device_start() +{ + save_item(NAME(m_base_bank)); + save_item(NAME(m_locked)); +} + +void a26_rom_fv_device::device_reset() +{ + m_base_bank = 0; + m_locked = 0; +} + + +void a26_rom_4in1_device::device_reset() +{ + m_base_bank++; + m_base_bank &= 3; +} + + +void a26_rom_8in1_device::device_start() +{ + save_item(NAME(m_base_bank)); + save_item(NAME(m_reset_bank)); +} + +void a26_rom_8in1_device::device_reset() +{ + // we use here two different bank counter: the main one for the 8x8K chunks, + // and the usual one (m_base_bank) for the 4K bank of the current game + m_reset_bank++; + m_reset_bank &= 7; + m_base_bank = 0; +} + + +void a26_rom_32in1_device::device_reset() +{ + m_base_bank++; + m_base_bank &= 0x1f; +} + + +/*------------------------------------------------- + mapper specific handlers + -------------------------------------------------*/ + +/*------------------------------------------------- + BASE 2K & 4K Carts: + no bankswitch + + GAMES: a large majority + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_2k_device::read_rom) +{ + // Super Chip RAM reads are mapped in 0x1080-0x10ff + if (m_ram && offset >= 0x80 && offset < 0x100) + { + return m_ram[offset & (m_ram.count() - 1)]; + } + + return m_rom[offset & (m_rom.count() - 1)]; +} + +/*------------------------------------------------- + "F4 Bankswitch" Carts: + read/write access to 0x1ff4-0x1ffb determines the + 4K ROM bank to be read + + GAMES: Fatal Run + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_f4_device::read_rom) +{ + // Super Chip RAM reads are mapped in 0x1080-0x10ff + if (m_ram && offset >= 0x80 && offset < 0x100) + { + return m_ram[offset & (m_ram.count() - 1)]; + } + + // update banks + if (!space.debugger_access()) + { + switch (offset) + { + case 0x0ff4: + case 0x0ff5: + case 0x0ff6: + case 0x0ff7: + case 0x0ff8: + case 0x0ff9: + case 0x0ffa: + case 0x0ffb: + m_base_bank = offset - 0x0ff4; + break; + } + } + + return m_rom[offset + (m_base_bank * 0x1000)]; +} + +WRITE8_MEMBER(a26_rom_f4_device::write_bank) +{ + // Super Chip RAM writes are mapped in 0x1000-0x107f + if (m_ram && offset < 0x80) + { + m_ram[offset & (m_ram.count() - 1)] = data; + return; + } + + switch (offset) + { + case 0x0ff4: + case 0x0ff5: + case 0x0ff6: + case 0x0ff7: + case 0x0ff8: + case 0x0ff9: + case 0x0ffa: + case 0x0ffb: + m_base_bank = offset - 0x0ff4; + break; + default: + logerror("Write Bank outside expected range (0x%X).\n", offset + 0x1000); + break; + } +} + +/*------------------------------------------------- + "F6 Bankswitch" Carts: + read/write access to 0x1ff6-0x1ff9 determines the + 4K ROM bank to be read + + GAMES: Atari 16K games, like Crossbow, Crystal + Castles and the 2-in-1 carts + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_f6_device::read_rom) +{ + // Super Chip RAM reads are mapped in 0x1080-0x10ff + if (m_ram && offset >= 0x80 && offset < 0x100) + { + return m_ram[offset & (m_ram.count() - 1)]; + } + + // update banks + if (!space.debugger_access()) + { + switch (offset) + { + case 0x0ff6: + case 0x0ff7: + case 0x0ff8: + case 0x0ff9: + m_base_bank = offset - 0x0ff6; + break; + } + } + + return m_rom[offset + (m_base_bank * 0x1000)]; +} + +WRITE8_MEMBER(a26_rom_f6_device::write_bank) +{ + // Super Chip RAM writes are mapped in 0x1000-0x107f + if (m_ram && offset < 0x80) + { + m_ram[offset & (m_ram.count() - 1)] = data; + return; + } + + switch (offset) + { + case 0x0ff6: + case 0x0ff7: + case 0x0ff8: + case 0x0ff9: + m_base_bank = offset - 0x0ff6; + break; + default: + logerror("Write Bank outside expected range (0x%X).\n", offset + 0x1000); + break; + } +} + +DIRECT_UPDATE_MEMBER(a26_rom_f6_device::cart_opbase) +{ + if ((address & 0x1fff) >= 0x1ff6 && (address & 0x1fff) <= 0x1ff9) + { + if (!direct.space().debugger_access()) + write_bank(direct.space(), (address & 0x1fff) - 0x1ff6, 0); + } + return address; +} + +/*------------------------------------------------- + "F8 Bankswitch" Carts: + read/write access to 0x1ff8-0x1ff9 determines the + 4K ROM bank to be read + + GAMES: Atari 8K games, like Asteroids, Battlezone + and Taz + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_f8_device::read_rom) +{ + // Super Chip RAM reads are mapped in 0x1080-0x10ff + if (m_ram && offset >= 0x80 && offset < 0x100) + { + return m_ram[offset & (m_ram.count() - 1)]; + } + + // update banks + if (!space.debugger_access()) + { + switch (offset) + { + case 0x0ff8: + case 0x0ff9: + m_base_bank = offset - 0x0ff8; + break; + } + } + + return m_rom[offset + (m_base_bank * 0x1000)]; +} + +WRITE8_MEMBER(a26_rom_f8_device::write_bank) +{ + // Super Chip RAM writes are mapped in 0x1000-0x107f + if (m_ram && offset < 0x80) + { + m_ram[offset & (m_ram.count() - 1)] = data; + return; + } + + switch (offset) + { + case 0x0ff8: + case 0x0ff9: + m_base_bank = offset - 0x0ff8; + break; + default: + logerror("Write Bank outside expected range (0x%X).\n", offset + 0x1000); + break; + } +} + +/*------------------------------------------------- + "FA Bankswitch" Carts: + read/write access to 0x1ff8-0x1ffa determines the + 4K ROM bank to be read + These games contained the CBS RAM+ chip (256bytes + of RAM) + + GAMES: CBS RAM Plus games like Omega Race and Tunnel + Runner + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_fa_device::read_rom) +{ + // CBS RAM+ reads are mapped in 0x1100-0x11ff + if (m_ram && offset >= 0x100 && offset < 0x200) + { + return m_ram[offset & (m_ram.count() - 1)]; + } + + // update banks + if (!space.debugger_access()) + { + switch (offset) + { + case 0x0ff8: + case 0x0ff9: + case 0x0ffa: + m_base_bank = offset - 0x0ff8; + break; + } + } + + return m_rom[offset + (m_base_bank * 0x1000)]; +} + +WRITE8_MEMBER(a26_rom_fa_device::write_bank) +{ + // CBS RAM+ writes are mapped in 0x1000-0x10ff + if (m_ram && offset < 0x100) + { + m_ram[offset & (m_ram.count() - 1)] = data; + } + + switch (offset) + { + case 0x0ff8: + case 0x0ff9: + case 0x0ffa: + m_base_bank = offset - 0x0ff8; + break; + default: + logerror("Write Bank outside expected range (0x%X).\n", offset + 0x1000); + break; + } +} + +/*------------------------------------------------- + "FE Bankswitch" Carts: + read/write access to 0x01fe-0x1ff determines the + 4K ROM bank to be read + + GAMES: Activision 8K games like Decathlon + + -------------------------------------------------*/ +/* + + There seems to be a kind of lag between the writing to address 0x1FE and the + Activision switcher springing into action. It waits for the next byte to arrive + on the data bus, which is the new PCH in the case of a JSR, and the PCH of the + stored PC on the stack in the case of an RTS. + + depending on last byte & 0x20 -> 0x00 -> switch to bank #1 + -> 0x20 -> switch to bank #0 + + */ + +READ8_MEMBER(a26_rom_fe_device::read_rom) +{ + UINT8 data; + + // Super Chip RAM reads are mapped in 0x1080-0x10ff + if (m_ram && offset >= 0x80 && offset < 0x100) + { + return m_ram[offset & (m_ram.count() - 1)]; + } + + data = m_rom[offset + (m_base_bank * 0x1000)]; + + if (!space.debugger_access()) + { + if (m_trigger_on_next_access) + { + m_base_bank = BIT(data, 5) ? 0 : 1; + m_trigger_on_next_access = 0; + } + } + + return data; +} + +WRITE8_MEMBER(a26_rom_fe_device::write_ram) +{ + // Super Chip RAM writes are mapped in 0x1000-0x107f + if (m_ram && offset < 0x80) + { + m_ram[offset & (m_ram.count() - 1)] = data; + } +} + +READ8_MEMBER(a26_rom_fe_device::read_bank) +{ + UINT8 data = space.read_byte(0xfe + offset); + + if (!space.debugger_access()) + { + switch (offset & 1) + { + case 0: + // The next byte on the data bus determines which bank to switch to + m_trigger_on_next_access = 1; + break; + + case 1: + if (m_trigger_on_next_access) + { + m_base_bank = BIT(data, 5) ? 0 : 1; + m_trigger_on_next_access = 0; + } + break; + } + } + return data; +} + +WRITE8_MEMBER(a26_rom_fe_device::write_bank) +{ + space.write_byte(0xfe, data); + if (!space.debugger_access()) + { + // The next byte on the data bus determines which bank to switch to + m_trigger_on_next_access = 1; + } +} + +/*------------------------------------------------- + "3E Bankswitch" Carts: + write access to 0x3e determines the 2K ROM bank to + be read, write access to 0x3f determines the RAM bank + to be read + + GAMES: Boulder Dash (Homebrew) + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_3e_device::read_rom) +{ + if (m_ram && m_ram_enable && offset >= 0x400 && offset < 0x600) + { + offset -= 0x400; + return m_ram[offset + (m_ram_bank * 0x200)]; + } + + if (offset >= 0x800) + return m_rom[offset + (m_num_bank - 1) * 0x800]; + else + return m_rom[offset + m_base_bank * 0x800]; +} + +WRITE8_MEMBER(a26_rom_3e_device::write_bank) +{ + if (offset) // 0x3f + { + m_base_bank = data & (m_num_bank - 1); + m_ram_enable = 0; + } + else // 0x3e + { + m_ram_bank = data & 0x3f; + m_ram_enable = 1; + } +} + +WRITE8_MEMBER(a26_rom_3e_device::write_ram) +{ + if (m_ram && m_ram_enable && offset >= 0x400 && offset < 0x600) + { + offset -= 0x400; + m_ram[offset + (m_ram_bank * 0x200)] = data; + } +} + +/*------------------------------------------------- + "3F Bankswitch" Carts: + write access to 0x00-0x3f determines the 2K ROM bank + to be read + + GAMES: Tigervision 8K games like Espial and Miner + 2049er. Extended version with bankswitch up to 512K + shall be supported as well (but we lack a test case) + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_3f_device::read_rom) +{ + if (offset >= 0x800) + return m_rom[(offset & 0x7ff) + (m_num_bank - 1) * 0x800]; + else + return m_rom[offset + m_base_bank * 0x800]; +} + +WRITE8_MEMBER(a26_rom_3f_device::write_bank) +{ + m_base_bank = data & (m_num_bank - 1); +} + +/*------------------------------------------------- + "E0 Bankswitch" Carts: + read/write access to 0x1fe0-0x1ff8 determines the + 1K ROM bank to be read in each 1K chunk (0x1c00-0x1fff + always points to the last 1K of the ROM) + + GAMES: Parker Bros. 8K games like Gyruss and Popeye + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_e0_device::read_rom) +{ + // update banks + if (!space.debugger_access()) + { + if (offset >= 0xfe0 && offset <= 0xff8) + m_base_banks[(offset >> 3) & 3] = offset & 7; + } + + return m_rom[(offset & 0x3ff) + (m_base_banks[(offset >> 10) & 3] * 0x400)]; +} + +WRITE8_MEMBER(a26_rom_e0_device::write_bank) +{ + if (offset >= 0xfe0 && offset <= 0xff8) + m_base_banks[(offset >> 3) & 3] = offset & 7; +} + + +/*------------------------------------------------- + "E7 Bankswitch" Carts: + this PCB can handle up to 16K of ROM and 2K of RAM, + with the following layout + 1000-17ff is selectable bank + 1800-19ff is RAM + 1a00-1fff is fixed to the last 0x600 of ROM + + The selectable bank can be ROM (if selected by + 0x1fe0-0x1fe6 access) or a first 1K of RAM (if + selected by 0x1fe7 access). + The other 256byte RAM bank can be one of the + four different chunks forming the other 1K of RAM + (the bank is selected by accessing 0x1fe8-0x1feb) + + GAMES: M Network 16K games like Burgertime and + Bump'n Jump + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_e7_device::read_rom) +{ + // update banks + if (!space.debugger_access()) + { + if (offset >= 0xfe0 && offset <= 0xfe7) + m_base_bank = offset - 0xfe0; + if (offset >= 0xfe8 && offset <= 0xfeb) + m_ram_bank = offset - 0xfe8; + } + + if (m_ram) + { + // 1K of RAM + if (m_base_bank == 0x07 && offset >= 0x400 && offset < 0x800) + return m_ram[0x400 + (offset & 0x3ff)]; + // the other 1K of RAM + if (offset >= 0x900 && offset < 0xa00) + { + offset -= 0x900; + return m_ram[offset + (m_ram_bank * 0x100)]; + } + } + + if (offset > 0x800) + return m_rom[(offset & 0x7ff) + 0x3800]; + else + return m_rom[(offset & 0x7ff) + (m_base_bank * 0x800)]; +} + +WRITE8_MEMBER(a26_rom_e7_device::write_bank) +{ + if (offset >= 0xfe0 && offset <= 0xfe7) + m_base_bank = offset - 0xfe0; + if (offset >= 0xfe8 && offset <= 0xfeb) + m_ram_bank = offset - 0xfe8; + + if (m_ram) + { + // 1K of RAM + if (m_base_bank == 0x07 && offset < 0x400) + m_ram[0x400 + (offset & 0x3ff)] = data; + // the other 1K of RAM + if (offset >= 0x800 && offset < 0x900) + { + offset -= 0x800; + m_ram[offset + (m_ram_bank * 0x100)] = data; + } + } +} + +/*------------------------------------------------- + "UA Bankswitch" Carts: + read/write access to 0x200-0x27f determines the + 4K ROM bank to be read (0x220-0x23f for low 4K, + 0x240-0x27f for high 4K) + + GAMES: UA Ltd. 8K games like Funky Flash and + Pleaides + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_ua_device::read_rom) +{ + return m_rom[(offset + (m_base_bank * 0x1000)) & (m_rom.count() - 1)]; +} + +READ8_MEMBER(a26_rom_ua_device::read_bank) +{ + if (!space.debugger_access()) + m_base_bank = offset >> 6; + + return 0; +} + +WRITE8_MEMBER(a26_rom_ua_device::write_bank) +{ + m_base_bank = offset >> 6; +} + + +/*------------------------------------------------- + Commavid Carts: + It allows for both ROM and RAM on the cartridge, + without using bankswitching. There's 2K of ROM + and 1K of RAM. + + GAMES: Magicard and Video Life by Commavid + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_cv_device::read_rom) +{ + if (m_ram && offset < 0x400) + { + return m_ram[offset & (m_ram.count() - 1)]; + } + + // games shall not read from 0x1400-0x17ff (RAM write) + // but we fall back to ROM just in case... + return m_rom[offset & 0x7ff]; +} + +WRITE8_MEMBER(a26_rom_cv_device::write_bank) +{ + if (m_ram && offset >= 0x400 && offset < 0x800) + { + m_ram[offset & (m_ram.count() - 1)] = data; + } +} + + +/*------------------------------------------------- + Dynacom Megaboy Carts (aka "F0 Banswitch"): + read/write access to 0x1ff0 determines the 4K ROM + bank to be read (each access increases the bank index + up to 16, since the cart was 64K wide) + + GAMES: Megaboy by Dynacom + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_dc_device::read_rom) +{ + if (!space.debugger_access()) + { + if (offset == 0xff0) + m_base_bank = (m_base_bank + 1) & 0x0f; + } + + if (offset == 0xfec) + return m_base_bank; + + return m_rom[offset + (m_base_bank * 0x1000)]; +} + +WRITE8_MEMBER(a26_rom_dc_device::write_bank) +{ + if (offset == 0xff0) + m_base_bank = (m_base_bank + 1) & 0x0f; +} + + +/*------------------------------------------------- + "FV Bankswitch" Carts: + The first access to 0x1fd0 switch the bank, but + only if pc() & 0x1f00 == 0x1f00! + + GAMES: Challenge by HES + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_fv_device::read_rom) +{ + if (!space.debugger_access()) + { + if (offset == 0xfd0) + { + if (!m_locked && (machine().device("maincpu")->pc() & 0x1f00) == 0x1f00) + { + m_locked = 1; + m_base_bank = m_base_bank ^ 0x01; + } + } + } + + return m_rom[offset + (m_base_bank * 0x1000)]; +} + +WRITE8_MEMBER(a26_rom_fv_device::write_bank) +{ + if (offset == 0xfd0) + { + if (!m_locked && (machine().device("maincpu")->pc() & 0x1f00) == 0x1f00) + { + m_locked = 1; + m_base_bank = m_base_bank ^ 0x01; + } + } +} + + +/*------------------------------------------------- + "JVP Bankswitch" Carts: + read/write access to 0x0fa0-0x0fc0 determines the + 4K ROM bank to be read (notice that this overlaps + the RIOT, currently handled in the main driver until + I can better investigate the behavior) + + GAMES: No test case!?! + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_jvp_device::read_rom) +{ + return m_rom[offset + (m_base_bank * 0x1000)]; +} + +WRITE8_MEMBER(a26_rom_jvp_device::write_bank) +{ + switch (offset) + { + case 0x00: + case 0x20: + m_base_bank ^= 1; + break; + default: + //printf("%04X: write to unknown mapper address %02X\n", m_maincpu->pc(), 0xfa0 + offset); + break; + } +} + + +/*------------------------------------------------- + 4 in 1 Carts (Reset based): + the 4K bank changes at each reset + + GAMES: 4 in 1 carts + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_4in1_device::read_rom) +{ + return m_rom[offset + (m_base_bank * 0x1000)]; +} + + +/*------------------------------------------------- + 8 in 1 Carts (Reset based): + the 8K banks change at each reset, and internally + each game runs as a F8-bankswitched cart + + GAMES: 8 in 1 cart + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_8in1_device::read_rom) +{ + if (!space.debugger_access()) + { + switch (offset) + { + case 0x0ff8: + case 0x0ff9: + m_base_bank = offset - 0x0ff8; + break; + } + } + + return m_rom[offset + (m_base_bank * 0x1000) + (m_reset_bank * 0x2000)]; +} + + +/*------------------------------------------------- + 32 in 1 Carts (Reset based): + the 2K banks change at each reset + + GAMES: 32 in 1 cart + + -------------------------------------------------*/ + +READ8_MEMBER(a26_rom_32in1_device::read_rom) +{ + return m_rom[(offset & 0x7ff) + (m_base_bank * 0x800)]; +} + diff --git a/src/emu/bus/vcs/rom.h b/src/emu/bus/vcs/rom.h new file mode 100755 index 00000000000..33b00d0b5ea --- /dev/null +++ b/src/emu/bus/vcs/rom.h @@ -0,0 +1,389 @@ +#ifndef __VCS_ROM_H +#define __VCS_ROM_H + +#include "vcs_slot.h" + + +// ======================> a26_rom_2k_device + +class a26_rom_2k_device : public device_t, + public device_vcs_cart_interface +{ +public: + // construction/destruction + a26_rom_2k_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + a26_rom_2k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); +}; + + +// ======================> a26_rom_4k_device + +class a26_rom_4k_device : public a26_rom_2k_device +{ +public: + // construction/destruction + a26_rom_4k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // reading and writing + + // accesses just use the 2K ones, since it is just direct access to ROM/RAM + // masked with its size! +}; + + +// ======================> a26_rom_f6_device + +class a26_rom_f6_device : public a26_rom_2k_device +{ +public: + // construction/destruction + a26_rom_f6_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + a26_rom_f6_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); + virtual DECLARE_DIRECT_UPDATE_MEMBER(cart_opbase); + +protected: + int m_base_bank; +}; + + +// ======================> a26_rom_f4_device + +class a26_rom_f4_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_f4_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); +}; + + +// ======================> a26_rom_f8_device + +class a26_rom_f8_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_f8_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + a26_rom_f8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); +}; + + +// ======================> a26_rom_f8_sw_device + +class a26_rom_f8_sw_device : public a26_rom_f8_device +{ +public: + // construction/destruction + a26_rom_f8_sw_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_reset(); +}; + + +// ======================> a26_rom_fa_device + +class a26_rom_fa_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_fa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); +}; + + +// ======================> a26_rom_fe_device + +class a26_rom_fe_device : public a26_rom_2k_device +{ +public: + // construction/destruction + a26_rom_fe_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_READ8_MEMBER(read_bank); + virtual DECLARE_WRITE8_MEMBER(write_ram); + virtual DECLARE_WRITE8_MEMBER(write_bank); + +protected: + int m_base_bank; + int m_trigger_on_next_access; +}; + + +// ======================> a26_rom_3e_device + +class a26_rom_3e_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_3e_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); + virtual DECLARE_WRITE8_MEMBER(write_ram); + +protected: + int m_num_bank; + int m_ram_bank; + int m_ram_enable; +}; + + +// ======================> a26_rom_3f_device + +class a26_rom_3f_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_3f_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); + +protected: + int m_num_bank; +}; + + +// ======================> a26_rom_e0_device + +class a26_rom_e0_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_e0_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); + +protected: + int m_base_banks[4]; +}; + + +// ======================> a26_rom_e7_device + +class a26_rom_e7_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_e7_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); + +protected: + int m_ram_bank; +}; + + +// ======================> a26_rom_ua_device + +class a26_rom_ua_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_ua_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_READ8_MEMBER(read_bank); + virtual DECLARE_WRITE8_MEMBER(write_bank); +}; + + +// ======================> a26_rom_cv_device + +class a26_rom_cv_device : public a26_rom_2k_device +{ +public: + // construction/destruction + a26_rom_cv_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); +}; + + +// ======================> a26_rom_dc_device + +class a26_rom_dc_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_dc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); +}; + + +// ======================> a26_rom_fv_device + +class a26_rom_fv_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_fv_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); + +protected: + int m_locked; +}; + + +// ======================> a26_rom_jvp_device + +class a26_rom_jvp_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_jvp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_WRITE8_MEMBER(write_bank); +}; + + +// ======================> a26_rom_4in1_device + +class a26_rom_4in1_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_4in1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); +}; + + +// ======================> a26_rom_8in1_device + +class a26_rom_8in1_device : public a26_rom_f8_device +{ +public: + // construction/destruction + a26_rom_8in1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + +protected: + int m_reset_bank; +}; + + +// ======================> a26_rom_32in1_device + +class a26_rom_32in1_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_32in1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_reset(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); +}; + + +// device type definition +extern const device_type A26_ROM_2K; +extern const device_type A26_ROM_4K; +extern const device_type A26_ROM_F4; +extern const device_type A26_ROM_F6; +extern const device_type A26_ROM_F8; +extern const device_type A26_ROM_F8_SW; +extern const device_type A26_ROM_FA; +extern const device_type A26_ROM_FE; +extern const device_type A26_ROM_3E; +extern const device_type A26_ROM_3F; +extern const device_type A26_ROM_E0; +extern const device_type A26_ROM_E7; +extern const device_type A26_ROM_UA; +extern const device_type A26_ROM_CV; +extern const device_type A26_ROM_DC; +extern const device_type A26_ROM_FV; +extern const device_type A26_ROM_JVP; +extern const device_type A26_ROM_4IN1; +extern const device_type A26_ROM_8IN1; +extern const device_type A26_ROM_32IN1; + + +#endif diff --git a/src/emu/bus/vcs/scharger.c b/src/emu/bus/vcs/scharger.c new file mode 100644 index 00000000000..efd685a5969 --- /dev/null +++ b/src/emu/bus/vcs/scharger.c @@ -0,0 +1,212 @@ +/*************************************************************************** + + Atari 2600 cart Starpath Supercharger (Cart + Tape drive!) + + + + From kevtris notes ( http://blog.kevtris.org/blogfiles/Atari%202600%20Mappers.txt ): + + + - Control register [0x1ff8] + + 7 0 + --------- + 1FF8: DDDB BBWE + + D: write delay (see below) + B: bankswitching mode (see below) + W: RAM write enable (1 = enabled, 0 = disabled) + E: ROM power enable (0 = enabled, 1 = turn off ROM) + + - Audio input register [0x1ff9] + + 7 0 + --------- + 1FF9: 0000 000A + + A: Supercharger audio data. 0 = low input, 1 = high input. + + +***************************************************************************/ + + +#include "emu.h" +#include "scharger.h" +#include "sound/wave.h" +#include "formats/a26_cas.h" + +const device_type A26_ROM_SUPERCHARGER = &device_creator; + + +a26_rom_ss_device::a26_rom_ss_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : a26_rom_f6_device(mconfig, A26_ROM_SUPERCHARGER, "Atari 2600 ROM Cart Supercharger", tag, owner, clock, "a2600_ss", __FILE__), + m_cassette(*this, "cassette") +{ +} + +//------------------------------------------------- +// mapper specific start/reset +//------------------------------------------------- + +void a26_rom_ss_device::device_start() +{ + m_maincpu = machine().device("maincpu"); + + save_item(NAME(m_base_banks)); + save_item(NAME(m_reg)); + save_item(NAME(m_write_delay)); + save_item(NAME(m_ram_write_enabled)); + save_item(NAME(m_rom_enabled)); + save_item(NAME(m_byte_started)); + save_item(NAME(m_last_address)); + save_item(NAME(m_diff_adjust)); +} + +void a26_rom_ss_device::device_reset() +{ + // banks = 0, 1, 2 are 2K chunk of RAM (of the available 6K), banks = 3 is ROM! + m_base_banks[0] = 2; + m_base_banks[1] = 3; + m_ram_write_enabled = 0; + m_byte_started = 0; + m_reg = 0; + m_write_delay = 0; + m_rom_enabled = 1; + m_last_address = 0; + m_diff_adjust = 0; +} + + +static MACHINE_CONFIG_FRAGMENT( a26_ss ) + MCFG_CASSETTE_ADD("cassette") + MCFG_CASSETTE_FORMATS(a26_cassette_formats) + MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED) + MCFG_CASSETTE_INTERFACE("a2600_cass") + +// MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette") +// MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) +MACHINE_CONFIG_END + +machine_config_constructor a26_rom_ss_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( a26_ss ); +} + +inline UINT8 a26_rom_ss_device::read_byte(UINT32 offset) +{ + if (offset < 0x800) + return m_ram[(offset & 0x7ff) + (m_base_banks[0] * 0x800)]; + else if (m_base_banks[1] != 3) + return m_ram[(offset & 0x7ff) + (m_base_banks[1] * 0x800)]; + else if (m_rom_enabled) + return m_rom[offset & 0x7ff]; + else + return 0xff; +} + +READ8_MEMBER(a26_rom_ss_device::read_rom) +{ + if (space.debugger_access()) + return read_byte(offset); + + // Bankswitch + if (offset == 0xff8) + { + //logerror("%04X: Access to control register data = %02X\n", m_maincpu->pc(), m_modeSS_byte); + m_write_delay = m_reg >> 5; + m_ram_write_enabled = BIT(m_reg, 1); + m_rom_enabled = !BIT(m_reg, 0); + + // compensate time spent in this access to avoid spurious RAM write + m_byte_started -= 5; + + // handle bankswitch + switch (m_reg & 0x1c) + { + case 0x00: + m_base_banks[0] = 2; + m_base_banks[1] = 3; + break; + case 0x04: + m_base_banks[0] = 0; + m_base_banks[1] = 3; + break; + case 0x08: + m_base_banks[0] = 2; + m_base_banks[1] = 0; + break; + case 0x0c: + m_base_banks[0] = 0; + m_base_banks[1] = 2; + break; + case 0x10: + m_base_banks[0] = 2; + m_base_banks[1] = 3; + break; + case 0x14: + m_base_banks[0] = 1; + m_base_banks[1] = 3; + break; + case 0x18: + m_base_banks[0] = 2; + m_base_banks[1] = 1; + break; + case 0x1c: + m_base_banks[0] = 1; + m_base_banks[1] = 2; + break; + } + + return read_byte(offset); + } + // Cassette port read + else if (offset == 0xff9) + { + //logerror("%04X: Cassette port read, tap_val = %f\n", m_maincpu->pc(), tap_val); + double tap_val = m_cassette->input(); + + // compensate time spent in this access to avoid spurious RAM write + m_byte_started -= 5; + + if (tap_val < 0) + return 0x00; + else + return 0x01; + } + // Possible RAM write + else + { + if (m_ram_write_enabled) + { + /* Check for dummy read from same address */ + if (m_last_address == offset) + m_diff_adjust++; + + int diff = m_maincpu->total_cycles() - m_byte_started; + //logerror("%04X: offset = %04X, %d\n", m_maincpu->pc(), offset, diff); + + if (diff - m_diff_adjust == 5) + { + //logerror("%04X: RAM write offset = %04X, data = %02X\n", m_maincpu->pc(), offset, m_modeSS_byte ); + if (offset < 0x800) + m_ram[(offset & 0x7ff) + (m_base_banks[0] * 0x800)] = m_reg; + else if (m_base_banks[1] != 3) + m_ram[(offset & 0x7ff) + (m_base_banks[1] * 0x800)] = m_reg; + } + else if (offset < 0x0100) + { + m_reg = offset; + m_byte_started = m_maincpu->total_cycles(); + m_diff_adjust = 0; + } + } + else if (offset < 0x0100) + { + m_reg = offset; + m_byte_started = m_maincpu->total_cycles(); + m_diff_adjust = 0; + } + m_last_address = offset; + return read_byte(offset); + } +} diff --git a/src/emu/bus/vcs/scharger.h b/src/emu/bus/vcs/scharger.h new file mode 100644 index 00000000000..d13d8e5b6d7 --- /dev/null +++ b/src/emu/bus/vcs/scharger.h @@ -0,0 +1,45 @@ +#ifndef __VCS_SCHARGER_H +#define __VCS_SCHARGER_H + +#include "rom.h" +#include "imagedev/cassette.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> a26_rom_ss_device + +class a26_rom_ss_device : public a26_rom_f6_device +{ +public: + // construction/destruction + a26_rom_ss_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual machine_config_constructor device_mconfig_additions() const; + virtual void device_reset(); + + required_device m_cassette; + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + +private: + cpu_device *m_maincpu; + inline UINT8 read_byte(UINT32 offset); + + int m_base_banks[2]; + UINT8 m_reg; + UINT8 m_write_delay, m_ram_write_enabled, m_rom_enabled; + UINT32 m_byte_started; + UINT16 m_last_address; + UINT32 m_diff_adjust; +}; + + +// device type definition +extern const device_type A26_ROM_SUPERCHARGER; + +#endif diff --git a/src/emu/bus/vcs/vcs_slot.c b/src/emu/bus/vcs/vcs_slot.c new file mode 100755 index 00000000000..114c02b1743 --- /dev/null +++ b/src/emu/bus/vcs/vcs_slot.c @@ -0,0 +1,838 @@ +/*********************************************************************************************************** + + + Atari VCS 2600 cart emulation + (through slot devices) + + Emulation of the cartslot for Atari 2600 + Several banking schemes have been used for larger roms, + and some carts contained RAM (so called "Special Chip") + + Mapper identification routines based on Cowering's code. + + ***********************************************************************************************************/ + + +#include "emu.h" +#include "vcs_slot.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type VCS_CART_SLOT = &device_creator; + + +//------------------------------------------------- +// device_vcs_cart_interface - constructor +//------------------------------------------------- + +device_vcs_cart_interface::device_vcs_cart_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) +{ +} + + +//------------------------------------------------- +// ~device_vcs_cart_interface - destructor +//------------------------------------------------- + +device_vcs_cart_interface::~device_vcs_cart_interface() +{ +} + +//------------------------------------------------- +// rom_alloc - alloc the space for the cart +//------------------------------------------------- + +void device_vcs_cart_interface::rom_alloc(UINT32 size) +{ + if (m_rom == NULL) + m_rom.resize(size); +} + +//------------------------------------------------- +// ram_alloc - alloc the space for the on-cart RAM +//------------------------------------------------- + +void device_vcs_cart_interface::ram_alloc(UINT32 size) +{ + if (m_ram == NULL) + m_ram.resize(size); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// vcs_cart_slot_device - constructor +//------------------------------------------------- +vcs_cart_slot_device::vcs_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, VCS_CART_SLOT, "Atari VCS 2600 Cartridge Slot", tag, owner, clock, "vcs_cart_slot", __FILE__), + device_image_interface(mconfig, *this), + device_slot_interface(mconfig, *this) +{ +} + + +//------------------------------------------------- +// vcs_cart_slot_device - destructor +//------------------------------------------------- + +vcs_cart_slot_device::~vcs_cart_slot_device() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void vcs_cart_slot_device::device_start() +{ + m_cart = dynamic_cast(get_card_device()); +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void vcs_cart_slot_device::device_config_complete() +{ + // set brief and instance name + update_names(); +} + + + +/*------------------------------------------------- + call load + -------------------------------------------------*/ + +//------------------------------------------------- +// VCS PCBs +//------------------------------------------------- + +struct vcs_slot +{ + int pcb_id; + const char *slot_option; +}; + +// Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it +static const vcs_slot slot_list[] = +{ + { A26_2K, "a26_2k" }, + { A26_4K, "a26_4k" }, + { A26_F4, "a26_f4" }, + { A26_F6, "a26_f6" }, + { A26_F8, "a26_f8" }, + { A26_F8SW, "a26_f8sw" }, + { A26_FA, "a26_fa" }, + { A26_FE, "a26_fe" }, + { A26_E0, "a26_e0" }, + { A26_E7, "a26_e7" }, + { A26_3E, "a26_3e" }, + { A26_3F, "a26_3f" }, + { A26_UA, "a26_ua" }, + { A26_CV, "a26_cv" }, + { A26_DC, "a26_dc" }, + { A26_FV, "a26_fv" }, + { A26_JVP, "a26_jvp" }, + { A26_CM, "a26_cm" }, + { A26_SS, "a26_ss" }, + { A26_DPC, "a26_dpc" }, + { A26_4IN1, "a26_4in1" }, + { A26_8IN1, "a26_8in1" }, + { A26_32IN1, "a26_32in1" }, +}; + +static int vcs_get_pcb_id(const char *slot) +{ + for (int i = 0; i < ARRAY_LENGTH(slot_list); i++) + { + if (!core_stricmp(slot_list[i].slot_option, slot)) + return slot_list[i].pcb_id; + } + + return 0; +} + +static const char *vcs_get_slot(int type) +{ + for (int i = 0; i < ARRAY_LENGTH(slot_list); i++) + { + if (slot_list[i].pcb_id == type) + return slot_list[i].slot_option; + } + + return "a26_4k"; +} + +bool vcs_cart_slot_device::call_load() +{ + UINT8 *ROM; + UINT32 len; + + if (software_entry() != NULL) + len = get_software_region_length("rom"); + else + len = length(); + + //printf("Size: 0x%X\n", len); + + // check that filesize is among the supported ones + switch (len) + { + case 0x00800: + case 0x01000: + case 0x02000: + case 0x028ff: + case 0x02900: + case 0x03000: + case 0x04000: + case 0x08000: + case 0x10000: + case 0x80000: + break; + + default: + seterror(IMAGE_ERROR_UNSUPPORTED, "Invalid rom file size" ); + return IMAGE_INIT_FAIL; + } + + m_cart->rom_alloc(len); + ROM = m_cart->get_rom_base(); + + if (software_entry() != NULL) + { + const char *pcb_name; + memcpy(ROM, get_software_region("rom"), len); + + if ((pcb_name = get_feature("slot")) != NULL) + m_type = vcs_get_pcb_id(pcb_name); + else + { + // identify type based on size + switch (len) + { + case 0x800: + m_type = A26_2K; + break; + case 0x1000: + m_type = A26_4K; + break; + case 0x2000: + m_type = A26_F8; + break; + case 0x28ff: + case 0x2900: + m_type = A26_DPC; + break; + case 0x3000: + m_type = A26_FA; + break; + case 0x4000: + m_type = A26_F6; + break; + case 0x8000: + m_type = A26_F4; + break; + case 0x10000: + m_type = A26_32IN1; + break; + case 0x80000: + m_type = A26_3F; + break; + default: + m_type = A26_4K; + printf("Unrecognized cart type!\n"); + break; + } + + } + } + else + { + fread(ROM, len); + m_type = identify_cart_type(ROM, len); + } + + //printf("Type: %s\n", vcs_get_slot(m_type)); + + // check for Special Chip (128bytes of RAM) + if (len == 0x2000 || len == 0x4000 || len == 0x8000) + if (detect_super_chip(ROM, len)) + { + m_cart->ram_alloc(0x80); + //printf("Super Chip detected!\n"); + } + // Super chip games: + // dig dig, crystal castles, millipede, stargate, defender ii, jr. Pac Man, + // desert falcon, dark chambers, super football, sprintmaster, fatal run, + // off the wall, shooting arcade, secret quest, radar lock, save mary, klax + + // add CBS RAM+ (128bytes of RAM) + if (m_type == A26_FA) + m_cart->ram_alloc(0x100); + // add M Network RAM + else if (m_type == A26_E7) + m_cart->ram_alloc(0x800); + // add Commavid RAM + else if (m_type == A26_CV) + m_cart->ram_alloc(0x400); + // add Starpath Superchager RAM + else if (m_type == A26_SS) + m_cart->ram_alloc(0x1800); + // add Boulder Dash RAM + else if (m_type == A26_3E) + m_cart->ram_alloc(0x8000); + + // pass a pointer to the now allocated ROM for the DPC chip + if (m_type == A26_DPC) + m_cart->setup_addon_ptr((UINT8 *)m_cart->get_rom_base() + 0x2000); + + return IMAGE_INIT_PASS; +} + + +/*------------------------------------------------- + call_unload + -------------------------------------------------*/ + +void vcs_cart_slot_device::call_unload() +{ +} + + + +/*------------------------------------------------- + call softlist load + -------------------------------------------------*/ + +bool vcs_cart_slot_device::call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) +{ + load_software_part_region(*this, swlist, swname, start_entry ); + return TRUE; +} + + +/*------------------------------------------------- + detection helper routines + -------------------------------------------------*/ + +int vcs_cart_slot_device::detect_modeDC(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + // signature is also in 'video reflex'.. maybe figure out that controller port someday... + static const unsigned char signature[3] = { 0x8d, 0xf0, 0xff }; + + if (len == 0x10000) + { + for (int i = 0; i < len - sizeof signature; i++) + { + if (!memcmp(&cart[i], signature, sizeof signature)) + { + numfound = 1; + } + } + } + if (numfound) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_modeF6(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + static const unsigned char signature[3] = { 0x8d, 0xf6, 0xff }; + + if (len == 0x4000) + { + for (int i = 0; i < len - sizeof signature; i++) + { + if (!memcmp(&cart[i], signature, sizeof signature)) + { + numfound = 1; + } + } + } + if (numfound) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_snowhite(UINT8 *cart, UINT32 len) +{ + static const unsigned char snowwhite[] = { 0x10, 0xd0, 0xff, 0xff }; // Snow White Proto + + if (len == 0x2000 && !memcmp(&cart[0x1ffc], snowwhite, sizeof(snowwhite))) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_mode3E(UINT8 *cart, UINT32 len) +{ + // this one is a little hacky... looks for STY $3e, which is unique to + // 'not boulderdash', but is the only example I have (cow) + // Would have used STA $3e, but 'Alien' and 'Star Raiders' do that for unknown reasons + int numfound = 0; + static const unsigned char signature[3] = { 0x84, 0x3e, 0x9d }; + + if (len == 0x0800 || len == 0x1000) + { + for (int i = 0; i < len - sizeof signature; i++) + { + if (!memcmp(&cart[i], signature, sizeof signature)) + { + numfound = 1; + } + } + } + if (numfound) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_modeSS(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + static const unsigned char signature[5] = { 0xbd, 0xe5, 0xff, 0x95, 0x81 }; + + if (len == 0x0800 || len == 0x1000) + { + for (int i = 0; i < len - sizeof signature; i++) + { + if (!memcmp(&cart[i], signature, sizeof signature)) + { + numfound = 1; + } + } + } + if (numfound) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_modeFE(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + static const unsigned char signatures[][5] = { + { 0x20, 0x00, 0xd0, 0xc6, 0xc5 }, + { 0x20, 0xc3, 0xf8, 0xa5, 0x82 }, + { 0xd0, 0xfb, 0x20, 0x73, 0xfe }, + { 0x20, 0x00, 0xf0, 0x84, 0xd6 } + }; + + if (len == 0x2000) + { + for (int i = 0; i < len - (sizeof signatures/sizeof signatures[0]); i++) + { + for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) + { + if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0])) + { + numfound = 1; + } + } + } + } + if (numfound) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_modeE0(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + static const unsigned char signatures[][3] = { + { 0x8d, 0xe0, 0x1f }, + { 0x8d, 0xe0, 0x5f }, + { 0x8d, 0xe9, 0xff }, + { 0xad, 0xe9, 0xff }, + { 0xad, 0xed, 0xff }, + { 0xad, 0xf3, 0xbf } + }; + + if (len == 0x2000) + { + for (int i = 0; i < len - (sizeof signatures/sizeof signatures[0]); i++) + { + for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) + { + if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0])) + { + numfound = 1; + } + } + } + } + if (numfound) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_modeCV(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + static const unsigned char signatures[][3] = { + { 0x9d, 0xff, 0xf3 }, + { 0x99, 0x00, 0xf4 } + }; + + if (len == 0x0800 || len == 0x1000) + { + for (int i = 0; i < len - (sizeof signatures/sizeof signatures[0]); i++) + { + for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) + { + if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0])) + { + numfound = 1; + } + } + } + } + if (numfound) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_modeFV(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + static const unsigned char signatures[][3] = { { 0x2c, 0xd0, 0xff } }; + + if (len == 0x2000) + { + for (int i = 0; i < len - (sizeof signatures/sizeof signatures[0]); i++) + { + for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) + { + if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0])) + { + numfound = 1; + } + } + } + } + if (numfound) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_modeJVP(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + static const unsigned char signatures[][4] = { + { 0x2c, 0xc0, 0xef, 0x60 }, + { 0x8d, 0xa0, 0x0f, 0xf0 } + }; + + if (len == 0x4000 || len == 0x2000) + { + for (int i = 0; i < len - (sizeof signatures/sizeof signatures[0]); i++) + { + for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) + { + if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0])) + { + numfound = 1; + } + } + } + } + if (numfound) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_modeE7(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + static const unsigned char signatures[][3] = { + { 0xad, 0xe5, 0xff }, + { 0x8d, 0xe7, 0xff } + }; + + if (len == 0x2000 || len == 0x4000) + { + for (int i = 0; i < len - (sizeof signatures/sizeof signatures[0]); i++) + { + for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) + { + if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0])) + { + numfound = 1; + } + } + } + } + if (numfound) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_modeUA(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + static const unsigned char signature[3] = { 0x8d, 0x40, 0x02 }; + + if (len == 0x2000) + { + for (int i = 0; i < len - sizeof signature; i++) + { + if (!memcmp(&cart[i], signature, sizeof signature)) + { + numfound = 1; + } + } + } + if (numfound) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_8K_mode3F(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + static const unsigned char signature1[4] = { 0xa9, 0x01, 0x85, 0x3f }; + static const unsigned char signature2[4] = { 0xa9, 0x02, 0x85, 0x3f }; + // have to look for two signatures because 'not boulderdash' gives false positive otherwise + + if (len == 0x2000) + { + for (int i = 0; i < len - sizeof signature1; i++) + { + if (!memcmp(&cart[i], signature1, sizeof signature1)) + { + numfound |= 0x01; + } + if (!memcmp(&cart[i], signature2, sizeof signature2)) + { + numfound |= 0x02; + } + } + } + if (numfound == 0x03) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_32K_mode3F(UINT8 *cart, UINT32 len) +{ + int numfound = 0; + static const unsigned char signature[4] = { 0xa9, 0x0e, 0x85, 0x3f }; + + if (len >= 0x8000) + { + for (int i = 0; i < len - sizeof signature; i++) + { + if (!memcmp(&cart[i], signature, sizeof signature)) + { + numfound++; + } + } + } + if (numfound > 1) + return 1; + return 0; +} + +int vcs_cart_slot_device::detect_super_chip(UINT8 *cart, UINT32 len) +{ + static const unsigned char signatures[][5] = { + { 0xa2, 0x7f, 0x9d, 0x00, 0xf0 }, // dig dug + { 0xae, 0xf6, 0xff, 0x4c, 0x00 } // off the wall + }; + + if (len == 0x4000) + { + for (int i = 0; i < len - (sizeof signatures/sizeof signatures[0]); i++) + { + for (int j = 0; j < (sizeof signatures/sizeof signatures[0]); j++) + { + if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0])) + { + return 1; + } + } + } + } + for (int i = 0x1000; i < len; i += 0x1000) + { + if (memcmp(cart, cart + i, 0x100)) + { + return 0; + } + } + /* Check the reset vector does not point into the super chip RAM area */ + if ((((cart[0x0ffd] << 8) | cart[0x0ffc]) & 0x0fff) < 0x0100) + { + return 0; + } + return 1; +} + + +/*------------------------------------------------- + identify_cart_type - code to detect cart type from + fullpath + -------------------------------------------------*/ + +// 4in1 & 8in1 are not currently detected from fullpath... +int vcs_cart_slot_device::identify_cart_type(UINT8 *ROM, UINT32 len) +{ + int type = 0xff; + + // auto-detect bank mode + if (detect_modeDC(ROM, len)) + type = A26_DC; + else if (detect_mode3E(ROM, len)) + type = A26_3E; + else if (detect_modeFE(ROM, len)) + type = A26_FE; + else if (detect_modeSS(ROM, len)) + type = A26_SS; + else if (detect_modeE0(ROM, len)) + type = A26_E0; + else if (detect_modeCV(ROM, len)) + type = A26_CV; + else if (detect_modeFV(ROM, len)) + type = A26_FV; + else if (detect_modeJVP(ROM, len)) + type = A26_JVP; + else if (detect_modeUA(ROM, len)) + type = A26_UA; + else if (detect_8K_mode3F(ROM, len)) + type = A26_3F; + else if (detect_32K_mode3F(ROM, len)) + type = A26_3F; + else if (detect_modeE7(ROM, len)) + type = A26_E7; + else if (detect_snowhite(ROM, len)) + type = A26_F8SW; + + // otherwise, choose based on size + if (type == 0xff) + { + switch (len) + { + case 0x800: + type = A26_2K; + break; + case 0x1000: + type = A26_4K; + break; + case 0x2000: + type = A26_F8; + break; + case 0x28ff: + case 0x2900: + type = A26_DPC; + break; + case 0x3000: + type = A26_FA; + break; + case 0x4000: + type = A26_F6; + break; + case 0x8000: + type = A26_F4; + break; + case 0x10000: + type = A26_32IN1; + break; + case 0x80000: + type = A26_3F; + break; + default: + type = A26_4K; + printf("Unrecognized cart type!\n"); + break; + } + } + + return type; +} + +/*------------------------------------------------- + get default card software + -------------------------------------------------*/ + +void vcs_cart_slot_device::get_default_card_software(astring &result) +{ + if (open_image_file(mconfig().options())) + { + const char *slot_string = "a26_4k"; + UINT32 len = core_fsize(m_file); + dynamic_buffer rom(len); + int type; + + core_fread(m_file, rom, len); + + type = identify_cart_type(rom, len); + slot_string = vcs_get_slot(type); + + clear(); + + result.cpy(slot_string); + } + else + software_get_default_slot(result, "a26_4k"); +} + + +/*------------------------------------------------- + read + -------------------------------------------------*/ + +READ8_MEMBER(vcs_cart_slot_device::read_rom) +{ + if (m_cart) + return m_cart->read_rom(space, offset, mem_mask); + else + return 0xff; +} + +READ8_MEMBER(vcs_cart_slot_device::read_bank) +{ + if (m_cart) + return m_cart->read_bank(space, offset, mem_mask); + else + return 0xff; +} + + +/*------------------------------------------------- + write + -------------------------------------------------*/ + +WRITE8_MEMBER(vcs_cart_slot_device::write_bank) +{ + if (m_cart) + m_cart->write_bank(space, offset, data, mem_mask); +} + +WRITE8_MEMBER(vcs_cart_slot_device::write_ram) +{ + if (m_cart) + m_cart->write_ram(space, offset, data, mem_mask); +} + + +/*------------------------------------------------- + direct update + -------------------------------------------------*/ + +DIRECT_UPDATE_MEMBER(vcs_cart_slot_device::cart_opbase) +{ + if (m_cart) + return m_cart->cart_opbase(direct, address); + else + return address; +} diff --git a/src/emu/bus/vcs/vcs_slot.h b/src/emu/bus/vcs/vcs_slot.h new file mode 100755 index 00000000000..ce7b020d483 --- /dev/null +++ b/src/emu/bus/vcs/vcs_slot.h @@ -0,0 +1,154 @@ +#ifndef __VCS_SLOT_H +#define __VCS_SLOT_H + + +/*************************************************************************** + TYPE DEFINITIONS + ***************************************************************************/ + + +/* PCB */ +enum +{ + A26_2K = 0, + A26_4K, + A26_F4, + A26_F6, + A26_F8, + A26_F8SW, + A26_FA, + A26_FE, + A26_3E, // to test + A26_3F, + A26_E0, + A26_E7, + A26_UA, + A26_DC, + A26_CV, + A26_FV, + A26_JVP, // to test + A26_32IN1, + A26_8IN1, + A26_4IN1, + A26_DPC, + A26_SS, + A26_CM +}; + + +// ======================> device_vcs_cart_interface + +class device_vcs_cart_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_vcs_cart_interface(const machine_config &mconfig, device_t &device); + virtual ~device_vcs_cart_interface(); + + // reading from ROM + virtual DECLARE_READ8_MEMBER(read_rom) { return 0xff; } + // writing to RAM chips (sometimes it is in a different range than write_bank!) + virtual DECLARE_WRITE8_MEMBER(write_ram) {} + + // read/write to bankswitch address + virtual DECLARE_READ8_MEMBER(read_bank) { return 0xff; } + virtual DECLARE_WRITE8_MEMBER(write_bank) {} + + // direct update handler + virtual DECLARE_DIRECT_UPDATE_MEMBER(cart_opbase) { return address; } + + virtual void setup_addon_ptr(UINT8 *ptr) {} + + void rom_alloc(UINT32 size); + void ram_alloc(UINT32 size); + UINT8* get_rom_base() { return m_rom; } + UINT8* get_ram_base() { return m_ram; } + UINT32 get_rom_size() { return m_rom.bytes(); } + UINT32 get_ram_size() { return m_ram.bytes(); } + +protected: + // internal state + dynamic_buffer m_rom; + dynamic_buffer m_ram; +}; + + +// ======================> vcs_cart_slot_device + +class vcs_cart_slot_device : public device_t, + public device_image_interface, + public device_slot_interface +{ +public: + // construction/destruction + vcs_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~vcs_cart_slot_device(); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete(); + + // image-level overrides + virtual bool call_load(); + virtual void call_unload(); + virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry); + + int get_cart_type() { return m_type; }; + int identify_cart_type(UINT8 *ROM, UINT32 len); + + virtual iodevice_t image_type() const { return IO_CARTSLOT; } + virtual bool is_readable() const { return 1; } + virtual bool is_writeable() const { return 0; } + virtual bool is_creatable() const { return 0; } + virtual bool must_be_loaded() const { return 1; } + virtual bool is_reset_on_load() const { return 1; } + virtual const option_guide *create_option_guide() const { return NULL; } + virtual const char *image_interface() const { return "a2600_cart"; } + virtual const char *file_extensions() const { return "bin,a26"; } + + // slot interface overrides + virtual void get_default_card_software(astring &result); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_rom); + virtual DECLARE_READ8_MEMBER(read_bank); + virtual DECLARE_WRITE8_MEMBER(write_bank); + virtual DECLARE_WRITE8_MEMBER(write_ram); + virtual DECLARE_DIRECT_UPDATE_MEMBER(cart_opbase); + +private: + device_vcs_cart_interface* m_cart; + int m_type; + + int detect_snowhite(UINT8 *cart, UINT32 len); + int detect_modeDC(UINT8 *cart, UINT32 len); + int detect_modeF6(UINT8 *cart, UINT32 len); + int detect_mode3E(UINT8 *cart, UINT32 len); + int detect_modeSS(UINT8 *cart, UINT32 len); + int detect_modeFE(UINT8 *cart, UINT32 len); + int detect_modeE0(UINT8 *cart, UINT32 len); + int detect_modeCV(UINT8 *cart, UINT32 len); + int detect_modeFV(UINT8 *cart, UINT32 len); + int detect_modeJVP(UINT8 *cart, UINT32 len); + int detect_modeE7(UINT8 *cart, UINT32 len); + int detect_modeUA(UINT8 *cart, UINT32 len); + int detect_8K_mode3F(UINT8 *cart, UINT32 len); + int detect_32K_mode3F(UINT8 *cart, UINT32 len); + int detect_super_chip(UINT8 *cart, UINT32 len); +}; + + +// device type definition +extern const device_type VCS_CART_SLOT; + + +/*************************************************************************** + DEVICE CONFIGURATION MACROS + ***************************************************************************/ + +#define MCFG_VCS_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \ + MCFG_DEVICE_ADD(_tag, VCS_CART_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) + + +#endif diff --git a/src/mess/drivers/a2600.c b/src/mess/drivers/a2600.c index a165be50b88..c2f2dfea7cc 100644 --- a/src/mess/drivers/a2600.c +++ b/src/mess/drivers/a2600.c @@ -11,39 +11,18 @@ TODO: #include "emu.h" #include "machine/6532riot.h" #include "cpu/m6502/m6502.h" -#include "sound/wave.h" #include "sound/tiaintf.h" -#include "imagedev/cartslot.h" -#include "imagedev/cassette.h" -#include "formats/a26_cas.h" #include "video/tia.h" -#include "bus/vcs/ctrl.h" -#include "hashfile.h" +#include "bus/vcs/vcs_slot.h" +#include "bus/vcs/rom.h" +#include "bus/vcs/dpc.h" +#include "bus/vcs/scharger.h" +#include "bus/vcs/compumat.h" +#include "bus/vcs_ctrl/ctrl.h" #define CONTROL1_TAG "joyport1" #define CONTROL2_TAG "joyport2" -struct df_t { - UINT8 top; - UINT8 bottom; - UINT8 low; - UINT8 high; - UINT8 flag; - UINT8 music_mode; /* Only used by data fetchers 5,6, and 7 */ - UINT8 osc_clk; /* Only used by data fetchers 5,6, and 7 */ -}; - -struct dpc_t -{ - df_t df[8]; - UINT8 movamt; - UINT8 latch_62; - UINT8 latch_64; - UINT8 dlc; - UINT8 shift_reg; - emu_timer *oscillator; -}; - class a2600_state : public driver_device { @@ -51,1224 +30,54 @@ public: a2600_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_riot_ram(*this, "riot_ram"), - m_banking_mode(0xff), m_joy1(*this, CONTROL1_TAG), m_joy2(*this, CONTROL2_TAG) , + m_cartslot(*this, "cartslot"), m_maincpu(*this, "maincpu"), - m_cassette(*this, "cassette"), - m_modeFE_trigger_on_next_access(false), m_screen(*this, "screen") { } - dpc_t m_dpc; - memory_region* m_extra_RAM; - UINT8* m_bank_base[5]; - UINT8* m_ram_base; required_shared_ptr m_riot_ram; - UINT8 m_banking_mode; - unsigned m_cart_size; - unsigned m_number_banks; - unsigned m_current_bank; - unsigned m_current_reset_bank_counter; - unsigned m_mode3E_ram_enabled; - UINT8 m_modeSS_byte; - UINT32 m_modeSS_byte_started; - unsigned m_modeSS_write_delay; - unsigned m_modeSS_write_enabled; - unsigned m_modeSS_high_ram_enabled; - unsigned m_modeSS_diff_adjust; - UINT16 m_modeSS_last_address; - unsigned m_FVlocked; UINT16 m_current_screen_height; - DECLARE_DIRECT_UPDATE_MEMBER(modeF6_opbase); - DECLARE_DIRECT_UPDATE_MEMBER(modeDPC_opbase_handler); - DECLARE_READ8_MEMBER(modeF8_switch_r); - DECLARE_READ8_MEMBER(modeFA_switch_r); - DECLARE_READ8_MEMBER(modeF6_switch_r); - DECLARE_READ8_MEMBER(modeF4_switch_r); - DECLARE_READ8_MEMBER(modeE0_switch_r); - DECLARE_READ8_MEMBER(modeE7_switch_r); - DECLARE_READ8_MEMBER(modeE7_RAM_switch_r); - DECLARE_READ8_MEMBER(modeUA_switch_r); - DECLARE_READ8_MEMBER(modeDC_switch_r); - DECLARE_READ8_MEMBER(modeFV_switch_r); - DECLARE_READ8_MEMBER(modeJVP_switch_r); - DECLARE_WRITE8_MEMBER(modeF8_switch_w); - DECLARE_WRITE8_MEMBER(modeFA_switch_w); - DECLARE_WRITE8_MEMBER(modeF6_switch_w); - DECLARE_WRITE8_MEMBER(modeF4_switch_w); - DECLARE_WRITE8_MEMBER(modeE0_switch_w); - DECLARE_WRITE8_MEMBER(modeE7_switch_w); - DECLARE_WRITE8_MEMBER(modeE7_RAM_switch_w); - DECLARE_WRITE8_MEMBER(mode3F_switch_w); - DECLARE_WRITE8_MEMBER(modeUA_switch_w); - DECLARE_WRITE8_MEMBER(modeDC_switch_w); - DECLARE_WRITE8_MEMBER(mode3E_switch_w); - DECLARE_WRITE8_MEMBER(mode3E_RAM_switch_w); - DECLARE_WRITE8_MEMBER(mode3E_RAM_w); - DECLARE_WRITE8_MEMBER(modeFV_switch_w); - DECLARE_WRITE8_MEMBER(modeJVP_switch_w); - DECLARE_READ8_MEMBER(modeSS_r); - DECLARE_READ8_MEMBER(modeDPC_r); - DECLARE_WRITE8_MEMBER(modeDPC_w); - DECLARE_READ8_MEMBER(modeFE_switch_r); - DECLARE_WRITE8_MEMBER(modeFE_switch_w); - DECLARE_READ8_MEMBER(modeFE_rom_r); - DECLARE_READ8_MEMBER(current_bank_r); - DECLARE_READ16_MEMBER(a2600_read_input_port); - DECLARE_READ8_MEMBER(a2600_get_databus_contents); - DECLARE_WRITE16_MEMBER(a2600_tia_vsync_callback); - DECLARE_WRITE16_MEMBER(a2600_tia_vsync_callback_pal); - void modeDPC_check_flag(UINT8 data_fetcher); - void modeDPC_decrement_counter(UINT8 data_fetcher); - virtual void machine_reset(); DECLARE_MACHINE_START(a2600); - TIMER_CALLBACK_MEMBER(modeDPC_timer_callback); DECLARE_WRITE8_MEMBER(switch_A_w); DECLARE_READ8_MEMBER(switch_A_r); DECLARE_WRITE8_MEMBER(switch_B_w); DECLARE_WRITE_LINE_MEMBER(irq_callback); DECLARE_READ8_MEMBER(riot_input_port_8_r); - DECLARE_DEVICE_IMAGE_LOAD_MEMBER( a2600_cart ); + DECLARE_READ16_MEMBER(a2600_read_input_port); + DECLARE_READ8_MEMBER(a2600_get_databus_contents); + DECLARE_WRITE16_MEMBER(a2600_tia_vsync_callback); + DECLARE_WRITE16_MEMBER(a2600_tia_vsync_callback_pal); + // investigate how the carts mapped here (Mapper JVP) interact with the RIOT device + DECLARE_READ8_MEMBER(cart_over_riot_r); + DECLARE_WRITE8_MEMBER(cart_over_riot_w); protected: required_device m_joy1; required_device m_joy2; - int next_bank(); - void modeF8_switch(UINT16 offset, UINT8 data); - void modeFA_switch(UINT16 offset, UINT8 data); - void modeF6_switch(UINT16 offset, UINT8 data); - void modeF4_switch(UINT16 offset, UINT8 data); - void mode3F_switch(UINT16 offset, UINT8 data); - void modeUA_switch(UINT16 offset, UINT8 data); - void modeE0_switch(UINT16 offset, UINT8 data); - void modeE7_switch(UINT16 offset, UINT8 data); - void modeE7_RAM_switch(UINT16 offset, UINT8 data); - void modeDC_switch(UINT16 offset, UINT8 data); - void mode3E_switch(UINT16 offset, UINT8 data); - void mode3E_RAM_switch(UINT16 offset, UINT8 data); - void modeFV_switch(UINT16 offset, UINT8 data); - void modeJVP_switch(UINT16 offset, UINT8 data); - void install_banks(int count, unsigned init); + required_device m_cartslot; - UINT8 *m_cart; - int detect_modeDC(); - int detect_modef6(); - int detect_mode3E(); - int detect_modeSS(); - int detect_modeFE(); - int detect_modeE0(); - int detect_modeCV(); - int detect_modeFV(); - int detect_modeJVP(); - int detect_modeE7(); - int detect_modeUA(); - int detect_8K_mode3F(); - int detect_32K_mode3F(); - int detect_super_chip(); unsigned long detect_2600controllers(); required_device m_maincpu; - required_device m_cassette; - bool m_modeFE_trigger_on_next_access; required_device m_screen; }; -#define CART machine().root_device().memregion("user1")->base() - #define MASTER_CLOCK_NTSC 3579545 #define MASTER_CLOCK_PAL 3546894 #define CATEGORY_SELECT 16 -enum -{ - mode2K, - mode4K, - modeF8, - modeFA, - modeF6, - modeF4, - modeFE, - modeE0, - mode3F, - modeUA, - modeE7, - modeDC, - modeCV, - mode3E, - modeSS, - modeFV, - modeDPC, - mode32in1, - modeJVP, - mode8in1, - mode4in1 -}; - static const UINT16 supported_screen_heights[4] = { 262, 312, 328, 342 }; -int a2600_state::detect_modeDC() -{ - int i,numfound = 0; - // signature is also in 'video reflex'.. maybe figure out that controller port someday... - static const unsigned char signature[3] = { 0x8d, 0xf0, 0xff }; - if (m_cart_size == 0x10000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - sizeof signature; i++) - { - if (!memcmp(&cart[i], signature,sizeof signature)) - { - numfound = 1; - } - } - } - if (numfound) return 1; - return 0; -} - -int a2600_state::detect_modef6() -{ - int i, numfound = 0; - static const unsigned char signature[3] = { 0x8d, 0xf6, 0xff }; - if (m_cart_size == 0x4000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - sizeof signature; i++) - { - if (!memcmp(&cart[i], signature, sizeof signature)) - { - numfound = 1; - } - } - } - if (numfound) return 1; - return 0; -} - -int a2600_state::detect_mode3E() -{ - // this one is a little hacky.. looks for STY $3e, which is unique to - // 'not boulderdash', but is the only example i have (cow) - // Would have used STA $3e, but 'Alien' and 'Star Raiders' do that for unknown reasons - - int i,numfound = 0; - static const unsigned char signature[3] = { 0x84, 0x3e, 0x9d }; - if (m_cart_size == 0x0800 || m_cart_size == 0x1000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - sizeof signature; i++) - { - if (!memcmp(&cart[i], signature,sizeof signature)) - { - numfound = 1; - } - } - } - if (numfound) return 1; - return 0; -} - -int a2600_state::detect_modeSS() -{ - int i,numfound = 0; - static const unsigned char signature[5] = { 0xbd, 0xe5, 0xff, 0x95, 0x81 }; - if (m_cart_size == 0x0800 || m_cart_size == 0x1000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - sizeof signature; i++) - { - if (!memcmp(&cart[i], signature,sizeof signature)) - { - numfound = 1; - } - } - } - if (numfound) return 1; - return 0; -} - -int a2600_state::detect_modeFE() -{ - int i,j,numfound = 0; - static const unsigned char signatures[][5] = { - { 0x20, 0x00, 0xd0, 0xc6, 0xc5 }, - { 0x20, 0xc3, 0xf8, 0xa5, 0x82 }, - { 0xd0, 0xfb, 0x20, 0x73, 0xfe }, - { 0x20, 0x00, 0xf0, 0x84, 0xd6 } - }; - if (m_cart_size == 0x2000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - (sizeof signatures/sizeof signatures[0]); i++) - { - for (j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) - { - if (!memcmp(&cart[i], &signatures[j],sizeof signatures[0])) - { - numfound = 1; - } - } - } - } - if (numfound) return 1; - return 0; -} - -int a2600_state::detect_modeE0() -{ - int i,j,numfound = 0; - static const unsigned char signatures[][3] = { - { 0x8d, 0xe0, 0x1f }, - { 0x8d, 0xe0, 0x5f }, - { 0x8d, 0xe9, 0xff }, - { 0xad, 0xe9, 0xff }, - { 0xad, 0xed, 0xff }, - { 0xad, 0xf3, 0xbf } - }; - if (m_cart_size == 0x2000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - (sizeof signatures/sizeof signatures[0]); i++) - { - for (j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) - { - if (!memcmp(&cart[i], &signatures[j],sizeof signatures[0])) - { - numfound = 1; - } - } - } - } - if (numfound) return 1; - return 0; -} - -int a2600_state::detect_modeCV() -{ - int i,j,numfound = 0; - static const unsigned char signatures[][3] = { - { 0x9d, 0xff, 0xf3 }, - { 0x99, 0x00, 0xf4 } - }; - if (m_cart_size == 0x0800 || m_cart_size == 0x1000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - (sizeof signatures/sizeof signatures[0]); i++) - { - for (j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) - { - if (!memcmp(&cart[i], &signatures[j],sizeof signatures[0])) - { - numfound = 1; - } - } - } - } - if (numfound) return 1; - return 0; -} - -int a2600_state::detect_modeFV() -{ - int i,j,numfound = 0; - static const unsigned char signatures[][3] = { - { 0x2c, 0xd0, 0xff } - }; - if (m_cart_size == 0x2000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - (sizeof signatures/sizeof signatures[0]); i++) - { - for (j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) - { - if (!memcmp(&cart[i], &signatures[j],sizeof signatures[0])) - { - numfound = 1; - } - } - } - m_FVlocked = 0; - } - if (numfound) return 1; - return 0; -} - -int a2600_state::detect_modeJVP() -{ - int i,j,numfound = 0; - static const unsigned char signatures[][4] = { - { 0x2c, 0xc0, 0xef, 0x60 }, - { 0x8d, 0xa0, 0x0f, 0xf0 } - }; - if (m_cart_size == 0x4000 || m_cart_size == 0x2000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - (sizeof signatures/sizeof signatures[0]); i++) - { - for (j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) - { - if (!memcmp(&cart[i], &signatures[j],sizeof signatures[0])) - { - numfound = 1; - } - } - } - } - if (numfound) return 1; - return 0; -} - -int a2600_state::detect_modeE7() -{ - int i,j,numfound = 0; - static const unsigned char signatures[][3] = { - { 0xad, 0xe5, 0xff }, - { 0x8d, 0xe7, 0xff } - }; - if (m_cart_size == 0x2000 || m_cart_size == 0x4000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - (sizeof signatures/sizeof signatures[0]); i++) - { - for (j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++) - { - if (!memcmp(&cart[i], &signatures[j],sizeof signatures[0])) - { - numfound = 1; - } - } - } - } - if (numfound) return 1; - return 0; -} - -int a2600_state::detect_modeUA() -{ - int i,numfound = 0; - static const unsigned char signature[3] = { 0x8d, 0x40, 0x02 }; - if (m_cart_size == 0x2000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - sizeof signature; i++) - { - if (!memcmp(&cart[i], signature,sizeof signature)) - { - numfound = 1; - } - } - } - if (numfound) return 1; - return 0; -} - -int a2600_state::detect_8K_mode3F() -{ - int i,numfound = 0; - static const unsigned char signature1[4] = { 0xa9, 0x01, 0x85, 0x3f }; - static const unsigned char signature2[4] = { 0xa9, 0x02, 0x85, 0x3f }; - // have to look for two signatures because 'not boulderdash' gives false positive otherwise - if (m_cart_size == 0x2000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - sizeof signature1; i++) - { - if (!memcmp(&cart[i], signature1,sizeof signature1)) - { - numfound |= 0x01; - } - if (!memcmp(&cart[i], signature2,sizeof signature2)) - { - numfound |= 0x02; - } - } - } - if (numfound == 0x03) return 1; - return 0; -} - -int a2600_state::detect_32K_mode3F() -{ - int i,numfound = 0; - static const unsigned char signature[4] = { 0xa9, 0x0e, 0x85, 0x3f }; - if (m_cart_size >= 0x8000) - { - UINT8 *cart = CART; - for (i = 0; i < m_cart_size - sizeof signature; i++) - { - if (!memcmp(&cart[i], signature,sizeof signature)) - { - numfound++; - } - } - } - if (numfound > 1) return 1; - return 0; -} - -int a2600_state::detect_super_chip() -{ - int i,j; - UINT8 *cart = CART; - static const unsigned char signatures[][5] = { - { 0xa2, 0x7f, 0x9d, 0x00, 0xf0 }, // dig dug - { 0xae, 0xf6, 0xff, 0x4c, 0x00 } // off the wall - }; - - if (m_cart_size == 0x4000) - { - for (i = 0; i < m_cart_size - (sizeof signatures/sizeof signatures[0]); i++) - { - for (j = 0; j < (sizeof signatures/sizeof signatures[0]); j++) - { - if (!memcmp(&cart[i], &signatures[j],sizeof signatures[0])) - { - return 1; - } - } - } - } - for (i = 0x1000; i < m_cart_size; i += 0x1000) - { - if (memcmp(cart, cart + i, 0x100)) - { - return 0; - } - } - /* Check the reset vector does not point into the super chip RAM area */ - i = ( cart[0x0FFD] << 8 ) | cart[0x0FFC]; - if ( ( i & 0x0FFF ) < 0x0100 ) - { - return 0; - } - return 1; -} - - -DEVICE_IMAGE_LOAD_MEMBER( a2600_state, a2600_cart ) -{ - UINT8 *cart = memregion("user1")->base(); - - if (image.software_entry() == NULL) - m_cart_size = image.length(); - else - m_cart_size = image.get_software_region_length("rom"); - - switch (m_cart_size) - { - case 0x00800: - case 0x01000: - case 0x02000: - case 0x028ff: - case 0x02900: - case 0x03000: - case 0x04000: - case 0x08000: - case 0x10000: - case 0x80000: - break; - - default: - image.seterror(IMAGE_ERROR_UNSUPPORTED, "Invalid rom file size" ); - return 1; /* unsupported image format */ - } - - m_current_bank = 0; - - if (image.software_entry() == NULL) - { - image.fread(cart, m_cart_size); - } - else - { - memcpy(cart, image.get_software_region("rom"), m_cart_size); - - const char *mapper = image.get_feature("mapper"); - - if ( mapper != NULL ) - { - static const struct { const char *mapper_name; int mapper_type; } mapper_types[] = - { - { "F8", modeF8 }, - { "FA", modeFA }, - { "F6", modeF6 }, - { "F4", modeF4 }, - { "FE", modeFE }, - { "E0", modeE0 }, - { "3F", mode3F }, - { "UA", modeUA }, - { "E7", modeE7 }, - { "DC", modeDC }, - { "CV", modeCV }, - { "3E", mode3E }, - { "SS", modeSS }, - { "FV", modeFV }, - { "DPC", modeDPC }, - { "32in1", mode32in1 }, - { "JVP", modeJVP }, - { "4in1", mode4in1 }, - { "8in1", mode8in1 }, - }; - - for (int i = 0; i < ARRAY_LENGTH(mapper_types) && m_banking_mode == 0xff; i++) - { - if (!core_stricmp(mapper, mapper_types[i].mapper_name)) - { - m_banking_mode = mapper_types[i].mapper_type; - } - } - } - } - - if (!(m_cart_size == 0x4000 && detect_modef6())) - { - while (m_cart_size > 0x00800) - { - if (!memcmp(cart, &cart[m_cart_size/2],m_cart_size/2)) m_cart_size /= 2; - else break; - } - } - - return 0; -} - - -int a2600_state::next_bank() -{ - return m_current_bank = (m_current_bank + 1) % 16; -} - - -void a2600_state::modeF8_switch(UINT16 offset, UINT8 data) -{ - m_bank_base[1] = m_cart + 0x2000 * m_current_reset_bank_counter + 0x1000 * offset; - membank("bank1")->set_base(m_bank_base[1]); -} - -void a2600_state::modeFA_switch(UINT16 offset, UINT8 data) -{ - m_bank_base[1] = m_cart + 0x1000 * offset; - membank("bank1")->set_base(m_bank_base[1]); -} - -void a2600_state::modeF6_switch(UINT16 offset, UINT8 data) -{ - m_bank_base[1] = m_cart + 0x1000 * offset; - membank("bank1")->set_base(m_bank_base[1]); -} - -void a2600_state::modeF4_switch(UINT16 offset, UINT8 data) -{ - m_bank_base[1] = m_cart + 0x1000 * offset; - membank("bank1")->set_base(m_bank_base[1]); -} - -void a2600_state::mode3F_switch(UINT16 offset, UINT8 data) -{ - m_bank_base[1] = m_cart + 0x800 * (data & (m_number_banks - 1)); - membank("bank1")->set_base(m_bank_base[1]); -} - -void a2600_state::modeUA_switch(UINT16 offset, UINT8 data) -{ - m_bank_base[1] = m_cart + (offset >> 6) * 0x1000; - membank("bank1")->set_base(m_bank_base[1]); -} - -void a2600_state::modeE0_switch(UINT16 offset, UINT8 data) -{ - int bank = 1 + (offset >> 3); - char bank_name[10]; - sprintf(bank_name,"bank%d",bank); - m_bank_base[bank] = m_cart + 0x400 * (offset & 7); - membank(bank_name)->set_base(m_bank_base[bank]); -} - -void a2600_state::modeE7_switch(UINT16 offset, UINT8 data) -{ - m_bank_base[1] = m_cart + 0x800 * offset; - membank("bank1")->set_base(m_bank_base[1]); -} - -void a2600_state::modeE7_RAM_switch(UINT16 offset, UINT8 data) -{ - membank("bank9")->set_base(m_extra_RAM->base() + (4 + offset) * 256 ); -} - -void a2600_state::modeDC_switch(UINT16 offset, UINT8 data) -{ - m_bank_base[1] = m_cart + 0x1000 * next_bank(); - membank("bank1")->set_base(m_bank_base[1]); -} - -void a2600_state::mode3E_switch(UINT16 offset, UINT8 data) -{ - m_bank_base[1] = m_cart + 0x800 * (data & (m_number_banks - 1)); - membank("bank1")->set_base(m_bank_base[1]); - m_mode3E_ram_enabled = 0; -} - -void a2600_state::mode3E_RAM_switch(UINT16 offset, UINT8 data) -{ - m_ram_base = m_extra_RAM->base() + 0x200 * ( data & 0x3F ); - membank("bank1")->set_base(m_ram_base); - m_mode3E_ram_enabled = 1; -} - -void a2600_state::modeFV_switch(UINT16 offset, UINT8 data) -{ - if (!m_FVlocked && ( m_maincpu->pc() & 0x1F00 ) == 0x1F00 ) - { - m_FVlocked = 1; - m_current_bank = m_current_bank ^ 0x01; - m_bank_base[1] = m_cart + 0x1000 * m_current_bank; - membank("bank1")->set_base(m_bank_base[1]); - } -} - -void a2600_state::modeJVP_switch(UINT16 offset, UINT8 data) -{ - switch( offset ) - { - case 0x00: - case 0x20: - m_current_bank ^= 1; - break; - default: - printf("%04X: write to unknown mapper address %02X\n", m_maincpu->pc(), 0xfa0 + offset ); - break; - } - m_bank_base[1] = m_cart + 0x1000 * m_current_bank; - membank("bank1")->set_base(m_bank_base[1] ); -} - - -/* These read handlers will return the byte from the new bank */ -READ8_MEMBER(a2600_state::modeF8_switch_r) -{ - if ( !space.debugger_access() ) - { - modeF8_switch(offset, 0); - } - return m_bank_base[1][0xff8 + offset]; -} - -READ8_MEMBER(a2600_state::modeFA_switch_r) -{ - if ( !space.debugger_access() ) - { - modeFA_switch(offset, 0); - } - return m_bank_base[1][0xff8 + offset]; -} - -READ8_MEMBER(a2600_state::modeF6_switch_r) -{ - if ( ! space.debugger_access() ) - { - modeF6_switch(offset, 0); - } - return m_bank_base[1][0xff6 + offset]; -} - -READ8_MEMBER(a2600_state::modeF4_switch_r) -{ - if ( ! space.debugger_access() ) - { - modeF4_switch(offset, 0); - } - return m_bank_base[1][0xff4 + offset]; -} - -READ8_MEMBER(a2600_state::modeE0_switch_r) -{ - if ( ! space.debugger_access() ) - { - modeE0_switch(offset, 0); - } - return m_bank_base[4][0x3e0 + offset]; -} - -READ8_MEMBER(a2600_state::modeE7_switch_r) -{ - if ( ! space.debugger_access() ) - { - modeE7_switch(offset, 0); - } - return m_bank_base[1][0xfe0 + offset]; -} - -READ8_MEMBER(a2600_state::modeE7_RAM_switch_r) -{ - if ( ! space.debugger_access() ) - { - modeE7_RAM_switch(offset, 0); - } - return 0; -} - -READ8_MEMBER(a2600_state::modeUA_switch_r) -{ - if ( ! space.debugger_access() ) - { - modeUA_switch(offset, 0); - } - return 0; -} - -READ8_MEMBER(a2600_state::modeDC_switch_r) -{ - if ( ! space.debugger_access() ) - { - modeDC_switch(offset, 0); - } - return m_bank_base[1][0xff0 + offset]; -} - -READ8_MEMBER(a2600_state::modeFV_switch_r) -{ - if ( ! space.debugger_access() ) - { - modeFV_switch(offset, 0); - } - return m_bank_base[1][0xfd0 + offset]; -} - -READ8_MEMBER(a2600_state::modeJVP_switch_r) -{ - if ( ! space.debugger_access() ) - { - modeJVP_switch(offset, 0); - } - return m_riot_ram[ 0x20 + offset ]; -} - - -WRITE8_MEMBER(a2600_state::modeF8_switch_w){ modeF8_switch(offset, data); } -WRITE8_MEMBER(a2600_state::modeFA_switch_w){ modeFA_switch(offset, data); } -WRITE8_MEMBER(a2600_state::modeF6_switch_w){ modeF6_switch(offset, data); } -WRITE8_MEMBER(a2600_state::modeF4_switch_w){ modeF4_switch(offset, data); } -WRITE8_MEMBER(a2600_state::modeE0_switch_w){ modeE0_switch(offset, data); } -WRITE8_MEMBER(a2600_state::modeE7_switch_w){ modeE7_switch(offset, data); } -WRITE8_MEMBER(a2600_state::modeE7_RAM_switch_w){ modeE7_RAM_switch(offset, data); } -WRITE8_MEMBER(a2600_state::mode3F_switch_w){ mode3F_switch(offset, data); } -WRITE8_MEMBER(a2600_state::modeUA_switch_w){ modeUA_switch(offset, data); } -WRITE8_MEMBER(a2600_state::modeDC_switch_w){ modeDC_switch(offset, data); } -WRITE8_MEMBER(a2600_state::mode3E_switch_w){ mode3E_switch(offset, data); } -WRITE8_MEMBER(a2600_state::mode3E_RAM_switch_w){ mode3E_RAM_switch(offset, data); } -WRITE8_MEMBER(a2600_state::mode3E_RAM_w) -{ - if ( m_mode3E_ram_enabled ) - { - m_ram_base[offset] = data; - } -} -WRITE8_MEMBER(a2600_state::modeFV_switch_w){ modeFV_switch(offset, data); } -WRITE8_MEMBER(a2600_state::modeJVP_switch_w) -{ - modeJVP_switch(offset, data); m_riot_ram[ 0x20 + offset ] = data; -} - - -DIRECT_UPDATE_MEMBER(a2600_state::modeF6_opbase) -{ - if ( ( address & 0x1FFF ) >= 0x1FF6 && ( address & 0x1FFF ) <= 0x1FF9 ) - { - if ( ! direct.space().debugger_access() ) - { - modeF6_switch_w(m_maincpu->space(AS_PROGRAM), ( address & 0x1FFF ) - 0x1FF6, 0 ); - } - } - return address; -} - - -READ8_MEMBER(a2600_state::modeSS_r) -{ - UINT8 data = ( offset & 0x800 ) ? m_bank_base[2][offset & 0x7FF] : m_bank_base[1][offset]; - - if ( space.debugger_access() ) - { - return data; - } - - //logerror("%04X: read from modeSS area offset = %04X\n", m_maincpu->pc(), offset); - /* Check for control register "write" */ - if ( offset == 0xFF8 ) - { - //logerror("%04X: write to modeSS control register data = %02X\n", m_maincpu->pc(), m_modeSS_byte); - m_modeSS_write_enabled = m_modeSS_byte & 0x02; - m_modeSS_write_delay = m_modeSS_byte >> 5; - switch ( m_modeSS_byte & 0x1C ) - { - case 0x00: - m_bank_base[1] = m_extra_RAM->base() + 2 * 0x800; - m_bank_base[2] = ( m_modeSS_byte & 0x01 ) ? memregion("maincpu")->base() + 0x1800 : memregion("user1")->base(); - m_modeSS_high_ram_enabled = 0; - break; - case 0x04: - m_bank_base[1] = m_extra_RAM->base(); - m_bank_base[2] = ( m_modeSS_byte & 0x01 ) ? memregion("maincpu")->base() + 0x1800 : memregion("user1")->base(); - m_modeSS_high_ram_enabled = 0; - break; - case 0x08: - m_bank_base[1] = m_extra_RAM->base() + 2 * 0x800; - m_bank_base[2] = m_extra_RAM->base(); - m_modeSS_high_ram_enabled = 1; - break; - case 0x0C: - m_bank_base[1] = m_extra_RAM->base(); - m_bank_base[2] = m_extra_RAM->base() + 2 * 0x800; - m_modeSS_high_ram_enabled = 1; - break; - case 0x10: - m_bank_base[1] = m_extra_RAM->base() + 2 * 0x800; - m_bank_base[2] = ( m_modeSS_byte & 0x01 ) ? memregion("maincpu")->base() + 0x1800 : memregion("user1")->base(); - m_modeSS_high_ram_enabled = 0; - break; - case 0x14: - m_bank_base[1] = m_extra_RAM->base() + 0x800; - m_bank_base[2] = ( m_modeSS_byte & 0x01 ) ? memregion("maincpu")->base() + 0x1800 : memregion("user1")->base(); - m_modeSS_high_ram_enabled = 0; - break; - case 0x18: - m_bank_base[1] = m_extra_RAM->base() + 2 * 0x800; - m_bank_base[2] = m_extra_RAM->base() + 0x800; - m_modeSS_high_ram_enabled = 1; - break; - case 0x1C: - m_bank_base[1] = m_extra_RAM->base() + 0x800; - m_bank_base[2] = m_extra_RAM->base() + 2 * 0x800; - m_modeSS_high_ram_enabled = 1; - break; - } - membank("bank1")->set_base(m_bank_base[1] ); - membank("bank2")->set_base(m_bank_base[2] ); - // Make sure we do not trigger a spurious RAM write - m_modeSS_byte_started -= 5; - } - else if ( offset == 0xFF9 ) - { - /* Cassette port read */ - double tap_val = m_cassette->input(); - //logerror("%04X: Cassette port read, tap_val = %f\n", m_maincpu->pc(), tap_val); - if ( tap_val < 0 ) - { - data = 0x00; - } - else - { - data = 0x01; - } - // Make sure we do not trigger a spurious RAM write - m_modeSS_byte_started -= 5; - } - else - { - /* Possible RAM write */ - if ( m_modeSS_write_enabled ) - { - /* Check for dummy read from same address */ - if ( m_modeSS_last_address == offset ) - { - m_modeSS_diff_adjust += 1; - } - - int diff = m_maincpu->total_cycles() - m_modeSS_byte_started; - //logerror("%04X: offset = %04X, %d\n", m_maincpu->pc(), offset, diff); - if ( diff - m_modeSS_diff_adjust == 5 ) - { - //logerror("%04X: RAM write offset = %04X, data = %02X\n", m_maincpu->pc(), offset, m_modeSS_byte ); - if ( offset & 0x800 ) - { - if ( m_modeSS_high_ram_enabled ) - { - m_bank_base[2][offset & 0x7FF] = m_modeSS_byte; - data = m_modeSS_byte; - } - } - else - { - m_bank_base[1][offset] = m_modeSS_byte; - data = m_modeSS_byte; - } - } - else if ( offset < 0x0100 ) - { - m_modeSS_byte = offset; - m_modeSS_byte_started = m_maincpu->total_cycles(); - m_modeSS_diff_adjust = 0; - } - m_modeSS_last_address = offset; - } - else if ( offset < 0x0100 ) - { - m_modeSS_byte = offset; - m_modeSS_byte_started = m_maincpu->total_cycles(); - m_modeSS_last_address = offset; - m_modeSS_diff_adjust = 0; - } - } - return data; -} - -void a2600_state::modeDPC_check_flag(UINT8 data_fetcher) -{ - /* Set flag when low counter equals top */ - if ( m_dpc.df[data_fetcher].low == m_dpc.df[data_fetcher].top ) - { - m_dpc.df[data_fetcher].flag = 1; - } - /* Reset flag when low counter equals bottom */ - if ( m_dpc.df[data_fetcher].low == m_dpc.df[data_fetcher].bottom ) - { - m_dpc.df[data_fetcher].flag = 0; - } -} - -void a2600_state::modeDPC_decrement_counter(UINT8 data_fetcher) -{ - m_dpc.df[data_fetcher].low -= 1; - if ( m_dpc.df[data_fetcher].low == 0xFF ) - { - m_dpc.df[data_fetcher].high -= 1; - if ( data_fetcher > 4 && m_dpc.df[data_fetcher].music_mode ) - { - m_dpc.df[data_fetcher].low = m_dpc.df[data_fetcher].top; - } - } - - modeDPC_check_flag(data_fetcher ); -} - -TIMER_CALLBACK_MEMBER(a2600_state::modeDPC_timer_callback) -{ - int data_fetcher; - for( data_fetcher = 5; data_fetcher < 8; data_fetcher++ ) - { - if ( m_dpc.df[data_fetcher].osc_clk ) - { - modeDPC_decrement_counter(data_fetcher ); - } - } -} - -DIRECT_UPDATE_MEMBER(a2600_state::modeDPC_opbase_handler) -{ - if ( ! direct.space().debugger_access() ) - { - UINT8 new_bit; - new_bit = ( m_dpc.shift_reg & 0x80 ) ^ ( ( m_dpc.shift_reg & 0x20 ) << 2 ); - new_bit = new_bit ^ ( ( ( m_dpc.shift_reg & 0x10 ) << 3 ) ^ ( ( m_dpc.shift_reg & 0x08 ) << 4 ) ); - new_bit = new_bit ^ 0x80; - m_dpc.shift_reg = new_bit | ( m_dpc.shift_reg >> 1 ); - } - return address; -} - -READ8_MEMBER(a2600_state::modeDPC_r) -{ - static const UINT8 dpc_amplitude[8] = { 0x00, 0x04, 0x05, 0x09, 0x06, 0x0A, 0x0B, 0x0F }; - UINT8 data_fetcher = offset & 0x07; - UINT8 data = 0xFF; - - logerror("%04X: Read from DPC offset $%02X\n", m_maincpu->pc(), offset); - if ( offset < 0x08 ) - { - switch( offset & 0x06 ) - { - case 0x00: /* Random number generator */ - case 0x02: - return m_dpc.shift_reg; - case 0x04: /* Sound value, MOVAMT value AND'd with Draw Line Carry; with Draw Line Add */ - m_dpc.latch_62 = m_dpc.latch_64; - case 0x06: /* Sound value, MOVAMT value AND'd with Draw Line Carry; without Draw Line Add */ - m_dpc.latch_64 = m_dpc.latch_62 + m_dpc.df[4].top; - m_dpc.dlc = ( m_dpc.latch_62 + m_dpc.df[4].top > 0xFF ) ? 1 : 0; - data = 0; - if ( m_dpc.df[5].music_mode && m_dpc.df[5].flag ) - { - data |= 0x01; - } - if ( m_dpc.df[6].music_mode && m_dpc.df[6].flag ) - { - data |= 0x02; - } - if ( m_dpc.df[7].music_mode && m_dpc.df[7].flag ) - { - data |= 0x04; - } - return ( m_dpc.dlc ? m_dpc.movamt & 0xF0 : 0 ) | dpc_amplitude[data]; - } - } - else - { - UINT8 display_data = memregion("user1")->base()[0x2000 + ( ~ ( ( m_dpc.df[data_fetcher].low | ( m_dpc.df[data_fetcher].high << 8 ) ) ) & 0x7FF ) ]; - - switch( offset & 0x38 ) - { - case 0x08: /* display data */ - data = display_data; - break; - case 0x10: /* display data AND'd w/flag */ - data = m_dpc.df[data_fetcher].flag ? display_data : 0x00; - break; - case 0x18: /* display data AND'd w/flag, nibbles swapped */ - data = m_dpc.df[data_fetcher].flag ? BITSWAP8(display_data,3,2,1,0,7,6,5,4) : 0x00; - break; - case 0x20: /* display data AND'd w/flag, byte reversed */ - data = m_dpc.df[data_fetcher].flag ? BITSWAP8(display_data,0,1,2,3,4,5,6,7) : 0x00; - break; - case 0x28: /* display data AND'd w/flag, rotated right */ - data = m_dpc.df[data_fetcher].flag ? ( display_data >> 1 ) : 0x00; - break; - case 0x30: /* display data AND'd w/flag, rotated left */ - data = m_dpc.df[data_fetcher].flag ? ( display_data << 1 ) : 0x00; - break; - case 0x38: /* flag */ - data = m_dpc.df[data_fetcher].flag ? 0xFF : 0x00; - break; - } - - if ( data_fetcher < 5 || ! m_dpc.df[data_fetcher].osc_clk ) - { - modeDPC_decrement_counter(data_fetcher ); - } - } - return data; -} - -WRITE8_MEMBER(a2600_state::modeDPC_w) -{ - UINT8 data_fetcher = offset & 0x07; - - switch( offset & 0x38 ) - { - case 0x00: /* Top count */ - m_dpc.df[data_fetcher].top = data; - m_dpc.df[data_fetcher].flag = 0; - modeDPC_check_flag(data_fetcher ); - break; - case 0x08: /* Bottom count */ - m_dpc.df[data_fetcher].bottom = data; - modeDPC_check_flag(data_fetcher ); - break; - case 0x10: /* Counter low */ - m_dpc.df[data_fetcher].low = data; - if ( data_fetcher == 4 ) - { - m_dpc.latch_64 = data; - } - if ( data_fetcher > 4 && m_dpc.df[data_fetcher].music_mode ) - { - m_dpc.df[data_fetcher].low = m_dpc.df[data_fetcher].top; - } - modeDPC_check_flag(data_fetcher ); - break; - case 0x18: /* Counter high */ - m_dpc.df[data_fetcher].high = data; - m_dpc.df[data_fetcher].music_mode = data & 0x10; - m_dpc.df[data_fetcher].osc_clk = data & 0x20; - if ( data_fetcher > 4 && m_dpc.df[data_fetcher].music_mode && m_dpc.df[data_fetcher].low == 0xFF ) - { - m_dpc.df[data_fetcher].low = m_dpc.df[data_fetcher].top; - modeDPC_check_flag(data_fetcher ); - } - break; - case 0x20: /* Draw line movement value / MOVAMT */ - m_dpc.movamt = data; - break; - case 0x28: /* Not used */ - logerror("%04X: Write to unused DPC register $%02X, data $%02X\n", m_maincpu->pc(), offset, data); - break; - case 0x30: /* Random number generator reset */ - m_dpc.shift_reg = 0; - break; - case 0x38: /* Not used */ - logerror("%04X: Write to unused DPC register $%02X, data $%02X\n", m_maincpu->pc(), offset, data); - break; - } -} - -/* - -There seems to be a kind of lag between the writing to address 0x1FE and the -Activision switcher springing into action. It waits for the next byte to arrive -on the data bus, which is the new PCH in the case of a JSR, and the PCH of the -stored PC on the stack in the case of an RTS. - -depending on last byte & 0x20 -> 0x00 -> switch to bank #1 - -> 0x20 -> switch to bank #0 - - */ - - -READ8_MEMBER(a2600_state::modeFE_switch_r) -{ - UINT8 data = space.read_byte(0xFE + offset ); - - if ( ! space.debugger_access() ) - { - switch ( offset & 1 ) - { - case 0: - /* The next byte on the data bus determines which bank to switch to */ - m_modeFE_trigger_on_next_access = true; - break; - - case 1: - if ( m_modeFE_trigger_on_next_access ) { - m_bank_base[1] = m_cart + 0x1000 * ( ( data & 0x20 ) ? 0 : 1 ); - m_modeFE_trigger_on_next_access = false; - } - break; - } - } - return data; -} - - -WRITE8_MEMBER(a2600_state::modeFE_switch_w) -{ - space.write_byte(0xFE, data ); - if ( ! space.debugger_access() ) - { - /* The next byte on the data bus determines which bank to switch to */ - m_modeFE_trigger_on_next_access = true; - } -} - - -READ8_MEMBER(a2600_state::modeFE_rom_r) -{ - UINT8 data = m_bank_base[1][offset];; - - if ( ! space.debugger_access() ) - { - if ( m_modeFE_trigger_on_next_access ) - { - m_bank_base[1] = m_cart + 0x1000 * ( ( data & 0x20 ) ? 0 : 1 ); - m_modeFE_trigger_on_next_access = false; - } - } - - return data; -} - - -READ8_MEMBER(a2600_state::current_bank_r) -{ - return m_current_bank; -} static ADDRESS_MAP_START(a2600_mem, AS_PROGRAM, 8, a2600_state ) ADDRESS_MAP_GLOBAL_MASK(0x1fff) - AM_RANGE(0x0000, 0x007F) AM_MIRROR(0x0F00) AM_DEVREADWRITE("tia_video", tia_video_device, read, write) - AM_RANGE(0x0080, 0x00FF) AM_MIRROR(0x0D00) AM_RAM AM_SHARE("riot_ram") - AM_RANGE(0x0280, 0x029F) AM_MIRROR(0x0D00) AM_DEVREADWRITE("riot", riot6532_device, read, write) - AM_RANGE(0x1000, 0x1FFF) AM_ROMBANK("bank1") + AM_RANGE(0x0000, 0x007f) AM_MIRROR(0x0f00) AM_DEVREADWRITE("tia_video", tia_video_device, read, write) + AM_RANGE(0x0080, 0x00ff) AM_MIRROR(0x0d00) AM_RAM AM_SHARE("riot_ram") + AM_RANGE(0x0280, 0x029f) AM_MIRROR(0x0d00) AM_DEVREADWRITE("riot", riot6532_device, read, write) + // AM_RANGE(0x1000, 0x1fff) is cart data and it is configured at reset time, depending on the mounted cart! ADDRESS_MAP_END WRITE8_MEMBER(a2600_state::switch_A_w) @@ -1313,28 +122,6 @@ READ8_MEMBER(a2600_state::riot_input_port_8_r) return ioport("SWB")->read(); } -void a2600_state::install_banks(int count, unsigned init) -{ - int i; - - for (i = 0; i < count; i++) - { - static const char *const handler[] = - { - "bank1", - "bank2", - "bank3", - "bank4", - }; - - m_maincpu->space(AS_PROGRAM).install_read_bank( - 0x1000 + (i + 0) * 0x1000 / count - 0, - 0x1000 + (i + 1) * 0x1000 / count - 1, handler[i]); - - m_bank_base[i + 1] = m_cart + init; - membank(handler[i])->set_base(m_bank_base[i + 1]); - } -} READ16_MEMBER(a2600_state::a2600_read_input_port) { @@ -1442,16 +229,85 @@ WRITE16_MEMBER(a2600_state::a2600_tia_vsync_callback_pal) } } +// TODO: is this the correct behavior for the real hardware?!? +READ8_MEMBER(a2600_state::cart_over_riot_r) +{ + if (!space.debugger_access()) + if (m_cartslot) + m_cartslot->write_bank(space, offset, 0); + return m_riot_ram[0x20 + offset]; +} + +WRITE8_MEMBER(a2600_state::cart_over_riot_w) +{ + if (m_cartslot) + m_cartslot->write_bank(space, offset, 0); + m_riot_ram[0x20 + offset] = data; + +} MACHINE_START_MEMBER(a2600_state,a2600) { m_current_screen_height = m_screen->height(); - m_extra_RAM = machine().memory().region_alloc("user2", 0x8600, 1, ENDIANNESS_LITTLE); - memset( m_riot_ram, 0x00, 0x80 ); - m_current_reset_bank_counter = 0xFF; - m_dpc.oscillator = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(a2600_state::modeDPC_timer_callback),this)); - m_cart = CART; - m_modeSS_last_address = 0; + memset(m_riot_ram, 0x00, 0x80); + + switch (m_cartslot->get_cart_type()) + { + case A26_2K: + case A26_4K: + case A26_F4: + case A26_F8: + case A26_F8SW: + case A26_FA: + case A26_E0: + case A26_E7: + case A26_CV: + case A26_DC: + case A26_FV: + case A26_8IN1: + m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x1000, 0x1fff, read8_delegate(FUNC(vcs_cart_slot_device::read_rom),(vcs_cart_slot_device*)m_cartslot), write8_delegate(FUNC(vcs_cart_slot_device::write_bank),(vcs_cart_slot_device*)m_cartslot)); + break; + case A26_F6: + case A26_DPC: + m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x1000, 0x1fff, read8_delegate(FUNC(vcs_cart_slot_device::read_rom),(vcs_cart_slot_device*)m_cartslot), write8_delegate(FUNC(vcs_cart_slot_device::write_bank),(vcs_cart_slot_device*)m_cartslot)); + m_maincpu->space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(vcs_cart_slot_device::cart_opbase),(vcs_cart_slot_device*)m_cartslot)); + break; + case A26_FE: + m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x1000, 0x1fff, read8_delegate(FUNC(vcs_cart_slot_device::read_rom),(vcs_cart_slot_device*)m_cartslot), write8_delegate(FUNC(vcs_cart_slot_device::write_ram),(vcs_cart_slot_device*)m_cartslot)); + m_maincpu->space(AS_PROGRAM).install_read_handler(0x01fe, 0x01ff, read8_delegate(FUNC(vcs_cart_slot_device::read_bank),(vcs_cart_slot_device*)m_cartslot)); + m_maincpu->space(AS_PROGRAM).install_write_handler(0x01fe, 0x01fe, write8_delegate(FUNC(vcs_cart_slot_device::write_bank),(vcs_cart_slot_device*)m_cartslot)); + break; + case A26_3E: + m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x1000, 0x1fff, read8_delegate(FUNC(vcs_cart_slot_device::read_rom),(vcs_cart_slot_device*)m_cartslot), write8_delegate(FUNC(vcs_cart_slot_device::write_ram),(vcs_cart_slot_device*)m_cartslot)); + m_maincpu->space(AS_PROGRAM).install_write_handler(0x3e, 0x3f, write8_delegate(FUNC(vcs_cart_slot_device::write_bank),(vcs_cart_slot_device*)m_cartslot)); + break; + case A26_3F: + m_maincpu->space(AS_PROGRAM).install_read_handler(0x1000, 0x1fff, read8_delegate(FUNC(vcs_cart_slot_device::read_rom),(vcs_cart_slot_device*)m_cartslot)); + m_maincpu->space(AS_PROGRAM).install_write_handler(0x00, 0x3f, write8_delegate(FUNC(vcs_cart_slot_device::write_bank),(vcs_cart_slot_device*)m_cartslot)); + break; + case A26_UA: + m_maincpu->space(AS_PROGRAM).install_read_handler(0x1000, 0x1fff, read8_delegate(FUNC(vcs_cart_slot_device::read_rom),(vcs_cart_slot_device*)m_cartslot)); + m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x200, 0x27f, read8_delegate(FUNC(vcs_cart_slot_device::read_bank),(vcs_cart_slot_device*)m_cartslot), write8_delegate(FUNC(vcs_cart_slot_device::write_bank),(vcs_cart_slot_device*)m_cartslot)); + break; + case A26_JVP: + m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x1000, 0x1fff, read8_delegate(FUNC(vcs_cart_slot_device::read_rom),(vcs_cart_slot_device*)m_cartslot), write8_delegate(FUNC(vcs_cart_slot_device::write_bank),(vcs_cart_slot_device*)m_cartslot)); + // to verify the actual behavior... + m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xfa0, 0xfc0, read8_delegate(FUNC(a2600_state::cart_over_riot_r), this), write8_delegate(FUNC(a2600_state::cart_over_riot_w), this)); + break; + case A26_4IN1: + case A26_32IN1: + m_maincpu->space(AS_PROGRAM).install_read_handler(0x1000, 0x1fff, read8_delegate(FUNC(vcs_cart_slot_device::read_rom),(vcs_cart_slot_device*)m_cartslot)); + break; + case A26_SS: + m_maincpu->space(AS_PROGRAM).install_read_handler(0x1000, 0x1fff, read8_delegate(FUNC(vcs_cart_slot_device::read_rom),(vcs_cart_slot_device*)m_cartslot)); + break; + case A26_CM: + m_maincpu->space(AS_PROGRAM).install_read_handler(0x1000, 0x1fff, read8_delegate(FUNC(vcs_cart_slot_device::read_rom),(vcs_cart_slot_device*)m_cartslot)); + break; + } + + /* Banks may have changed, reset the cpu so it uses the correct reset vector */ + m_maincpu->reset(); } @@ -1535,349 +391,9 @@ unsigned a2600_state::long detect_2600controllers() } #endif -void a2600_state::machine_reset() -{ - address_space& space = m_maincpu->space(AS_PROGRAM); - int chip = 0xFF; - static const unsigned char snowwhite[] = { 0x10, 0xd0, 0xff, 0xff }; // Snow White Proto - - m_current_reset_bank_counter++; - - /* auto-detect bank mode */ - if (m_banking_mode == 0xff) if (detect_modeDC()) m_banking_mode = modeDC; - if (m_banking_mode == 0xff) if (detect_mode3E()) m_banking_mode = mode3E; - if (m_banking_mode == 0xff) if (detect_modeFE()) m_banking_mode = modeFE; - if (m_banking_mode == 0xff) if (detect_modeSS()) m_banking_mode = modeSS; - if (m_banking_mode == 0xff) if (detect_modeE0()) m_banking_mode = modeE0; - if (m_banking_mode == 0xff) if (detect_modeCV()) m_banking_mode = modeCV; - if (m_banking_mode == 0xff) if (detect_modeFV()) m_banking_mode = modeFV; - if (m_banking_mode == 0xff) if (detect_modeJVP()) m_banking_mode = modeJVP; - if (m_banking_mode == 0xff) if (detect_modeUA()) m_banking_mode = modeUA; - if (m_banking_mode == 0xff) if (detect_8K_mode3F()) m_banking_mode = mode3F; - if (m_banking_mode == 0xff) if (detect_32K_mode3F()) m_banking_mode = mode3F; - if (m_banking_mode == 0xff) if (detect_modeE7()) m_banking_mode = modeE7; - - if (m_banking_mode == 0xff) - { - switch (m_cart_size) - { - case 0x800: - m_banking_mode = mode2K; - break; - case 0x1000: - m_banking_mode = mode4K; - break; - case 0x2000: - m_banking_mode = modeF8; - break; - case 0x28FF: - case 0x2900: - m_banking_mode = modeDPC; - break; - case 0x3000: - m_banking_mode = modeFA; - break; - case 0x4000: - m_banking_mode = modeF6; - break; - case 0x8000: - m_banking_mode = modeF4; - break; - case 0x10000: - m_banking_mode = mode32in1; - break; - case 0x80000: - m_banking_mode = mode3F; - break; - } - } - - /* auto-detect super chip */ - - chip = 0; - - if (m_cart_size == 0x2000 || m_cart_size == 0x4000 || m_cart_size == 0x8000) - { - chip = detect_super_chip(); - } - - /* Super chip games: - dig dig, crystal castles, millipede, stargate, defender ii, jr. Pac Man, - desert falcon, dark chambers, super football, sprintmaster, fatal run, - off the wall, shooting arcade, secret quest, radar lock, save mary, klax - */ - - /* set up ROM banks */ - - switch (m_banking_mode) - { - case mode2K: - install_banks(2, 0x0000); - break; - - case mode4K: - install_banks(1, 0x0000); - break; - - case mode4in1: - m_current_reset_bank_counter = m_current_reset_bank_counter & 0x03; - install_banks(1, m_current_reset_bank_counter * 0x1000); - break; - - case mode8in1: - m_current_reset_bank_counter = m_current_reset_bank_counter & 0x07; - if ( m_current_reset_bank_counter == 7 ) - { - /* Special case for Yar's Revenge */ - install_banks(1, 0x2000 * m_current_reset_bank_counter + 0x0000); - } - else - { - install_banks(1, 0x2000 * m_current_reset_bank_counter + 0x1000); - } - break; - - case modeF8: - m_current_reset_bank_counter = 0; - if (!memcmp(&CART[0x1ffc],snowwhite,sizeof(snowwhite))) - { - install_banks(1, 0x0000); - } - else - { - install_banks(1, 0x1000); - } - break; - - case modeFA: - install_banks(1, 0x2000); - break; - - case modeF6: - install_banks(1, 0x0000); - break; - - case modeF4: - install_banks(1, 0x7000); - break; - - case modeFE: - install_banks(1, 0x0000); - break; - - case modeE0: - install_banks(4, 0x1c00); - break; - - case mode3F: - install_banks(2, m_cart_size - 0x800); - m_number_banks = m_cart_size / 0x800; - break; - - case modeUA: - install_banks(1, 0x1000); - break; - - case modeE7: - install_banks(2, 0x3800); - break; - - case modeDC: - install_banks(1, 0x1000 * m_current_bank); - break; - - case modeCV: - install_banks(2, 0x0000); - break; - - case mode3E: - install_banks(2, m_cart_size - 0x800); - m_number_banks = m_cart_size / 0x800; - m_mode3E_ram_enabled = 0; - break; - - case modeSS: - install_banks(2, 0x0000); - break; - - case modeFV: - install_banks(1, 0x0000); - m_current_bank = 0; - break; - - case modeDPC: - m_current_reset_bank_counter = 0; - install_banks(1, 0x0000); - break; - - case mode32in1: - install_banks(2, 0x0000); - m_current_reset_bank_counter = m_current_reset_bank_counter & 0x1F; - break; - - case modeJVP: - m_current_reset_bank_counter = m_current_reset_bank_counter & 1; - if ( m_cart_size == 0x2000 ) - m_current_reset_bank_counter = 0; - m_current_bank = m_current_reset_bank_counter * 2; - install_banks(1, 0x1000 * m_current_bank); - break; - } - - /* set up bank counter */ - - if (m_banking_mode == modeDC) - { - space.install_read_handler(0x1fec, 0x1fec, read8_delegate(FUNC(a2600_state::current_bank_r),this)); - } - - /* set up bank switch registers */ - - switch (m_banking_mode) - { - case modeF8: - case mode8in1: - space.install_write_handler(0x1ff8, 0x1ff9, write8_delegate(FUNC(a2600_state::modeF8_switch_w),this)); - space.install_read_handler(0x1ff8, 0x1ff9, read8_delegate(FUNC(a2600_state::modeF8_switch_r),this)); - break; - - case modeFA: - space.install_write_handler(0x1ff8, 0x1ffa, write8_delegate(FUNC(a2600_state::modeFA_switch_w),this)); - space.install_read_handler(0x1ff8, 0x1ffa, read8_delegate(FUNC(a2600_state::modeFA_switch_r),this)); - break; - - case modeF6: - space.install_write_handler(0x1ff6, 0x1ff9, write8_delegate(FUNC(a2600_state::modeF6_switch_w),this)); - space.install_read_handler(0x1ff6, 0x1ff9, read8_delegate(FUNC(a2600_state::modeF6_switch_r),this)); - space.set_direct_update_handler(direct_update_delegate(FUNC(a2600_state::modeF6_opbase), this)); - break; - - case modeF4: - space.install_write_handler(0x1ff4, 0x1ffb, write8_delegate(FUNC(a2600_state::modeF4_switch_w),this)); - space.install_read_handler(0x1ff4, 0x1ffb, read8_delegate(FUNC(a2600_state::modeF4_switch_r),this)); - break; - - case modeE0: - space.install_write_handler(0x1fe0, 0x1ff8, write8_delegate(FUNC(a2600_state::modeE0_switch_w),this)); - space.install_read_handler(0x1fe0, 0x1ff8, read8_delegate(FUNC(a2600_state::modeE0_switch_r),this)); - break; - - case mode3F: - space.install_write_handler(0x00, 0x3f, write8_delegate(FUNC(a2600_state::mode3F_switch_w),this)); - break; - - case modeUA: - space.install_write_handler(0x200, 0x27f, write8_delegate(FUNC(a2600_state::modeUA_switch_w),this)); - space.install_read_handler(0x200, 0x27f, read8_delegate(FUNC(a2600_state::modeUA_switch_r),this)); - break; - - case modeE7: - space.install_write_handler(0x1fe0, 0x1fe7, write8_delegate(FUNC(a2600_state::modeE7_switch_w),this)); - space.install_read_handler(0x1fe0, 0x1fe7, read8_delegate(FUNC(a2600_state::modeE7_switch_r),this)); - space.install_write_handler(0x1fe8, 0x1feb, write8_delegate(FUNC(a2600_state::modeE7_RAM_switch_w),this)); - space.install_read_handler(0x1fe8, 0x1feb, read8_delegate(FUNC(a2600_state::modeE7_RAM_switch_r),this)); - space.install_write_bank(0x1800, 0x18ff, "bank9"); - space.install_read_bank(0x1900, 0x19ff, "bank9"); - membank("bank9")->set_base(m_extra_RAM->base() + 4 * 256 ); - break; - - case modeDC: - space.install_write_handler(0x1ff0, 0x1ff0, write8_delegate(FUNC(a2600_state::modeDC_switch_w),this)); - space.install_read_handler(0x1ff0, 0x1ff0, read8_delegate(FUNC(a2600_state::modeDC_switch_r),this)); - break; - - case modeFE: - space.install_write_handler(0x01fe, 0x01fe, write8_delegate(FUNC(a2600_state::modeFE_switch_w),this)); - space.install_read_handler(0x01fe, 0x01ff, read8_delegate(FUNC(a2600_state::modeFE_switch_r),this)); - space.install_read_handler(0x1000, 0x1fff, read8_delegate(FUNC(a2600_state::modeFE_rom_r),this)); - m_modeFE_trigger_on_next_access = false; - break; - - case mode3E: - space.install_write_handler(0x3e, 0x3e, write8_delegate(FUNC(a2600_state::mode3E_RAM_switch_w),this)); - space.install_write_handler(0x3f, 0x3f, write8_delegate(FUNC(a2600_state::mode3E_switch_w),this)); - space.install_write_handler(0x1400, 0x15ff, write8_delegate(FUNC(a2600_state::mode3E_RAM_w),this)); - break; - - case modeSS: - space.install_read_handler(0x1000, 0x1fff, read8_delegate(FUNC(a2600_state::modeSS_r),this)); - m_bank_base[1] = m_extra_RAM->base() + 2 * 0x800; - m_bank_base[2] = CART; - membank("bank1")->set_base(m_bank_base[1] ); - membank("bank2")->set_base(m_bank_base[2] ); - m_modeSS_write_enabled = 0; - m_modeSS_byte_started = 0; - /* The Supercharger has no motor control so just enable it */ - m_cassette->change_state(CASSETTE_MOTOR_ENABLED, CASSETTE_MOTOR_DISABLED ); - break; - - case modeFV: - space.install_write_handler(0x1fd0, 0x1fd0, write8_delegate(FUNC(a2600_state::modeFV_switch_w),this)); - space.install_read_handler(0x1fd0, 0x1fd0, read8_delegate(FUNC(a2600_state::modeFV_switch_r),this)); - break; - - case modeDPC: - space.install_read_handler(0x1000, 0x103f, read8_delegate(FUNC(a2600_state::modeDPC_r),this)); - space.install_write_handler(0x1040, 0x107f, write8_delegate(FUNC(a2600_state::modeDPC_w),this)); - space.install_write_handler(0x1ff8, 0x1ff9, write8_delegate(FUNC(a2600_state::modeF8_switch_w),this)); - space.install_read_handler(0x1ff8, 0x1ff9, read8_delegate(FUNC(a2600_state::modeF8_switch_r),this)); - space.set_direct_update_handler(direct_update_delegate(FUNC(a2600_state::modeDPC_opbase_handler), this)); - { - int data_fetcher; - for( data_fetcher = 0; data_fetcher < 8; data_fetcher++ ) - { - m_dpc.df[data_fetcher].osc_clk = 0; - m_dpc.df[data_fetcher].flag = 0; - m_dpc.df[data_fetcher].music_mode = 0; - } - } - m_dpc.oscillator->adjust(attotime::from_hz(18400), 0, attotime::from_hz(18400)); - break; - - case mode32in1: - membank("bank1")->set_base(CART + m_current_reset_bank_counter * 0x800 ); - membank("bank2")->set_base(CART + m_current_reset_bank_counter * 0x800 ); - break; - - case modeJVP: - space.install_read_handler(0x0FA0, 0x0FC0, read8_delegate(FUNC(a2600_state::modeJVP_switch_r),this)); - space.install_write_handler(0x0FA0, 0x0FC0, write8_delegate(FUNC(a2600_state::modeJVP_switch_w),this)); - break; - } - - /* set up extra RAM */ - - if (m_banking_mode == modeFA) - { - space.install_write_bank(0x1000, 0x10ff, "bank9"); - space.install_read_bank(0x1100, 0x11ff, "bank9"); - - membank("bank9")->set_base(m_extra_RAM->base()); - } - - if (m_banking_mode == modeCV) - { - space.install_write_bank(0x1400, 0x17ff, "bank9"); - space.install_read_bank(0x1000, 0x13ff, "bank9"); - - membank("bank9")->set_base(m_extra_RAM->base()); - } - - if (chip) - { - space.install_write_bank(0x1000, 0x107f, "bank9"); - space.install_read_bank(0x1080, 0x10ff, "bank9"); - - membank("bank9")->set_base(m_extra_RAM->base()); - } - - /* Banks may have changed, reset the cpu so it uses the correct reset vector */ - m_maincpu->reset(); -} - static INPUT_PORTS_START( a2600 ) - PORT_START("SWB") /* SWCHB */ + PORT_START("SWB") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset Game") PORT_CODE(KEYCODE_2) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Select Game") PORT_CODE(KEYCODE_1) PORT_BIT ( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) @@ -1895,12 +411,34 @@ static INPUT_PORTS_START( a2600 ) INPUT_PORTS_END +static SLOT_INTERFACE_START(a2600_cart) + SLOT_INTERFACE_INTERNAL("a26_2k", A26_ROM_2K) + SLOT_INTERFACE_INTERNAL("a26_4k", A26_ROM_4K) + SLOT_INTERFACE_INTERNAL("a26_f4", A26_ROM_F4) + SLOT_INTERFACE_INTERNAL("a26_f6", A26_ROM_F6) + SLOT_INTERFACE_INTERNAL("a26_f8", A26_ROM_F8) + SLOT_INTERFACE_INTERNAL("a26_f8sw", A26_ROM_F8_SW) + SLOT_INTERFACE_INTERNAL("a26_fa", A26_ROM_FA) + SLOT_INTERFACE_INTERNAL("a26_fe", A26_ROM_FE) + SLOT_INTERFACE_INTERNAL("a26_3e", A26_ROM_3E) + SLOT_INTERFACE_INTERNAL("a26_3f", A26_ROM_3F) + SLOT_INTERFACE_INTERNAL("a26_e0", A26_ROM_E0) + SLOT_INTERFACE_INTERNAL("a26_e7", A26_ROM_E7) + SLOT_INTERFACE_INTERNAL("a26_ua", A26_ROM_UA) + SLOT_INTERFACE_INTERNAL("a26_cv", A26_ROM_CV) + SLOT_INTERFACE_INTERNAL("a26_dc", A26_ROM_DC) + SLOT_INTERFACE_INTERNAL("a26_fv", A26_ROM_FV) + SLOT_INTERFACE_INTERNAL("a26_jvp", A26_ROM_JVP) + SLOT_INTERFACE_INTERNAL("a26_cm", A26_ROM_COMPUMATE) + SLOT_INTERFACE_INTERNAL("a26_ss", A26_ROM_SUPERCHARGER) + SLOT_INTERFACE_INTERNAL("a26_dpc", A26_ROM_DPC) + SLOT_INTERFACE_INTERNAL("a26_4in1", A26_ROM_4IN1) + SLOT_INTERFACE_INTERNAL("a26_8in1", A26_ROM_8IN1) + SLOT_INTERFACE_INTERNAL("a26_32in1", A26_ROM_32IN1) +SLOT_INTERFACE_END + static MACHINE_CONFIG_FRAGMENT(a2600_cartslot) - MCFG_CARTSLOT_ADD("cart") - MCFG_CARTSLOT_EXTENSION_LIST("bin,a26") - MCFG_CARTSLOT_MANDATORY - MCFG_CARTSLOT_LOAD(a2600_state,a2600_cart) - MCFG_CARTSLOT_INTERFACE("a2600_cart") + MCFG_VCS_CARTRIDGE_ADD("cartslot", a2600_cart, NULL) /* software lists */ MCFG_SOFTWARE_LIST_ADD("cart_list","a2600") @@ -1930,8 +468,6 @@ static MACHINE_CONFIG_START( a2600, a2600_state ) MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_TIA_ADD("tia", MASTER_CLOCK_NTSC/114) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.90) - MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette") - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) /* devices */ MCFG_DEVICE_ADD("riot", RIOT6532, MASTER_CLOCK_NTSC / 3) @@ -1946,10 +482,6 @@ static MACHINE_CONFIG_START( a2600, a2600_state ) MCFG_FRAGMENT_ADD(a2600_cartslot) MCFG_SOFTWARE_LIST_FILTER("cart_list", "NTSC") - MCFG_CASSETTE_ADD( "cassette" ) - MCFG_CASSETTE_FORMATS(a26_cassette_formats) - MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED) - MCFG_CASSETTE_INTERFACE("a2600_cass") MACHINE_CONFIG_END @@ -1977,8 +509,6 @@ static MACHINE_CONFIG_START( a2600p, a2600_state ) MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_TIA_ADD("tia", MASTER_CLOCK_PAL/114) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.90) - MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette") - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) /* devices */ MCFG_DEVICE_ADD("riot", RIOT6532, MASTER_CLOCK_PAL / 3) @@ -1993,18 +523,11 @@ static MACHINE_CONFIG_START( a2600p, a2600_state ) MCFG_FRAGMENT_ADD(a2600_cartslot) MCFG_SOFTWARE_LIST_FILTER("cart_list", "PAL") - MCFG_CASSETTE_ADD( "cassette" ) - MCFG_CASSETTE_FORMATS(a26_cassette_formats) - MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED) - MCFG_CASSETTE_INTERFACE("a2600_cass") MACHINE_CONFIG_END ROM_START( a2600 ) - ROM_REGION( 0x2000, "maincpu", 0 ) - ROM_FILL( 0x0000, 0x2000, 0xFF ) - ROM_REGION( 0x80000, "user1", 0 ) - ROM_FILL( 0x00000, 0x80000, 0xFF ) + ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASEFF ) ROM_END #define rom_a2600p rom_a2600