diff --git a/.gitattributes b/.gitattributes index 40576e804e3..a6d179f8033 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4852,7 +4852,6 @@ src/mame/machine/mc8123.c svneol=native#text/plain src/mame/machine/mc8123.h svneol=native#text/plain src/mame/machine/mcr.c svneol=native#text/plain src/mame/machine/mcr68.c svneol=native#text/plain -src/mame/machine/md_cart.c svneol=native#text/plain src/mame/machine/mega32x.c svneol=native#text/plain src/mame/machine/mega32x.h svneol=native#text/plain src/mame/machine/megacd.c svneol=native#text/plain @@ -4860,7 +4859,6 @@ src/mame/machine/megacd.h svneol=native#text/plain src/mame/machine/megacdcd.c svneol=native#text/plain src/mame/machine/megacdcd.h svneol=native#text/plain src/mame/machine/megadriv.c svneol=native#text/plain -src/mame/machine/megasvp.c svneol=native#text/plain src/mame/machine/megavdp.c svneol=native#text/plain src/mame/machine/megavdp.h svneol=native#text/plain src/mame/machine/meters.c svneol=native#text/plain @@ -6453,6 +6451,7 @@ src/mess/includes/mboard.h svneol=native#text/plain src/mess/includes/mc1000.h svneol=native#text/plain src/mess/includes/mc68328.h svneol=native#text/plain src/mess/includes/mc80.h svneol=native#text/plain +src/mess/includes/md.h svneol=native#text/plain src/mess/includes/micronic.h svneol=native#text/plain src/mess/includes/microtan.h svneol=native#text/plain src/mess/includes/mikro80.h svneol=native#text/plain @@ -7239,6 +7238,19 @@ src/mess/machine/mc6846.h svneol=native#text/plain src/mess/machine/mc6854.c svneol=native#text/plain src/mess/machine/mc6854.h svneol=native#text/plain src/mess/machine/mc80.c svneol=native#text/plain +src/mess/machine/md_eeprom.c svneol=native#text/plain +src/mess/machine/md_eeprom.h svneol=native#text/plain +src/mess/machine/md_jcart.c svneol=native#text/plain +src/mess/machine/md_jcart.h svneol=native#text/plain +src/mess/machine/md_rom.c svneol=native#text/plain +src/mess/machine/md_rom.h svneol=native#text/plain +src/mess/machine/md_sk.c svneol=native#text/plain +src/mess/machine/md_sk.h svneol=native#text/plain +src/mess/machine/md_slot.c svneol=native#text/plain +src/mess/machine/md_slot.h svneol=native#text/plain +src/mess/machine/md_stm95.c svneol=native#text/plain +src/mess/machine/md_stm95.h svneol=native#text/plain +src/mess/machine/megasvp.c svneol=native#text/plain src/mess/machine/mface2.c svneol=native#text/plain src/mess/machine/mface2.h svneol=native#text/plain src/mess/machine/micropolis.c svneol=native#text/plain diff --git a/hash/megadriv.xml b/hash/megadriv.xml index e2100ad7027..2693c543c24 100644 --- a/hash/megadriv.xml +++ b/hash/megadriv.xml @@ -225,6 +225,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -248,6 +249,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -508,6 +510,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -560,6 +563,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -676,6 +680,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Codemasters + @@ -689,6 +694,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Codemasters + @@ -703,6 +709,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Codemasters + @@ -717,6 +724,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -738,6 +746,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -770,6 +779,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -789,6 +799,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -804,6 +815,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -819,6 +831,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -843,6 +856,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -902,6 +916,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -963,6 +978,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -1052,6 +1068,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -1272,6 +1289,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -1349,6 +1367,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -1575,6 +1594,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -1683,6 +1703,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -1917,6 +1938,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Koei + @@ -1934,6 +1956,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -1948,6 +1971,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Koei + @@ -1965,6 +1989,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -2633,6 +2658,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -2647,6 +2673,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -2661,6 +2688,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -2675,6 +2703,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -2690,6 +2719,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -2704,6 +2734,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -2731,6 +2762,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -2745,6 +2777,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -2759,6 +2792,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -2831,6 +2865,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -2845,6 +2880,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -2975,6 +3011,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -3048,6 +3085,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Accolade + @@ -3636,6 +3674,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -3650,6 +3689,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -3783,6 +3823,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -4070,6 +4111,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Accolade + @@ -4107,6 +4149,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Codemasters + @@ -4119,6 +4162,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Codemasters + @@ -4944,6 +4988,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -4969,6 +5014,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -4983,6 +5029,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -4997,6 +5044,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5011,6 +5059,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5025,6 +5074,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5039,6 +5089,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5053,6 +5104,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5067,6 +5119,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5081,6 +5134,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5095,6 +5149,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5109,6 +5164,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5123,6 +5179,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5137,6 +5194,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5151,6 +5209,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5165,6 +5224,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5179,6 +5239,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5193,6 +5254,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5207,6 +5269,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5221,6 +5284,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5235,6 +5299,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5249,6 +5314,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5263,6 +5329,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -5277,6 +5344,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Acclaim Entertainment + @@ -6538,6 +6606,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Virgin Interactive + @@ -6712,6 +6781,7 @@ better to use names related to the actual pcb, possibly even reverting to use th <unknown> + @@ -6927,6 +6997,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -6944,6 +7015,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -7033,6 +7105,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Tec Toy + @@ -7080,6 +7153,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -7122,6 +7196,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -7538,6 +7613,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -7552,6 +7628,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -7758,6 +7835,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sony Imagesoft + @@ -7772,6 +7850,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sony Imagesoft + @@ -7786,6 +7865,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sony Imagesoft + @@ -7800,6 +7880,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sony Imagesoft + @@ -7922,6 +8003,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Renovation + @@ -7939,6 +8021,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -8091,6 +8174,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Tengen + @@ -8141,6 +8225,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -8227,6 +8312,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -8382,6 +8468,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Chuanpu Technologies + @@ -8473,6 +8560,7 @@ better to use names related to the actual pcb, possibly even reverting to use th <unlicensed> + @@ -8487,6 +8575,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -8501,6 +8590,7 @@ better to use names related to the actual pcb, possibly even reverting to use th <unlicensed> + @@ -8526,6 +8616,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -8806,6 +8897,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Acclaim Entertainment + @@ -9035,6 +9127,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Koei + @@ -9052,6 +9145,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -9102,6 +9196,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Koei + @@ -9119,6 +9214,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -9503,6 +9599,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -9515,6 +9612,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -9696,6 +9794,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Accolade + @@ -9945,6 +10044,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -9959,6 +10059,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -10056,6 +10157,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -10354,6 +10456,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -10372,6 +10475,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -10390,6 +10494,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -10407,6 +10512,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -10424,6 +10530,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -10439,6 +10546,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Accolade + @@ -10543,6 +10651,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -11174,6 +11283,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -11191,6 +11301,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -11291,6 +11402,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -11377,6 +11489,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -11402,6 +11515,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -11416,6 +11530,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -11433,6 +11548,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -11448,6 +11564,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -11462,6 +11579,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -11479,6 +11597,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -11496,6 +11615,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -11510,6 +11630,7 @@ better to use names related to the actual pcb, possibly even reverting to use th NCS + @@ -11524,6 +11645,7 @@ better to use names related to the actual pcb, possibly even reverting to use th NCS + @@ -11741,6 +11863,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Koei + @@ -11758,6 +11881,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -11772,6 +11896,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -11786,6 +11911,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -11800,6 +11926,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Sega + @@ -11853,6 +11980,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -11955,6 +12083,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -11969,6 +12098,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -11983,6 +12113,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -11997,6 +12128,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -12025,6 +12157,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -12352,6 +12485,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Renovation + @@ -12369,6 +12503,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -12400,6 +12535,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -12620,6 +12756,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Capcom + @@ -12635,6 +12772,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -12959,6 +13097,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Codemasters + @@ -12971,6 +13110,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Codemasters + @@ -12983,6 +13123,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Codemasters + @@ -13279,6 +13420,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -13326,6 +13468,7 @@ better to use names related to the actual pcb, possibly even reverting to use th Electronic Arts + @@ -13365,6 +13508,7 @@ better to use names related to the actual pcb, possibly even reverting to use th + @@ -13672,6 +13816,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -13703,6 +13848,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -13718,6 +13864,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -13743,6 +13890,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13757,6 +13905,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13772,6 +13921,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -13786,6 +13936,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13800,6 +13951,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13814,6 +13966,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13828,6 +13981,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13842,6 +13996,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13856,6 +14011,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13870,6 +14026,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13884,6 +14041,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13898,6 +14056,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13913,6 +14072,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13927,6 +14087,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13941,6 +14102,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13955,6 +14117,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13969,6 +14132,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13983,6 +14147,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -13997,6 +14162,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14011,6 +14177,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14025,6 +14192,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14039,6 +14207,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14053,6 +14222,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14067,6 +14237,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14081,6 +14252,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14095,6 +14267,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14109,6 +14282,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14123,6 +14297,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14170,6 +14345,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Arena + @@ -14182,6 +14358,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Arena + @@ -14197,6 +14374,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -14210,6 +14388,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -14253,6 +14432,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -14265,6 +14445,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Acclaim Entertainment + @@ -14277,6 +14458,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -14302,6 +14484,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -14316,6 +14499,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -14386,6 +14570,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -14400,6 +14585,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -14415,6 +14601,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -14429,6 +14616,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Mindscape + @@ -14443,6 +14631,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Mindscape + @@ -14474,6 +14663,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -14491,6 +14681,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -14508,6 +14699,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -14522,6 +14714,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14646,6 +14839,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14660,6 +14854,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14674,6 +14869,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14688,6 +14884,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14702,6 +14899,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14716,6 +14914,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14730,6 +14929,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14744,6 +14944,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14758,6 +14959,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14772,6 +14974,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14786,6 +14989,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14800,6 +15004,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14828,6 +15033,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -14845,6 +15051,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -14857,6 +15064,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Acclaim Entertainment + @@ -14883,6 +15091,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -14897,6 +15106,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -14922,6 +15132,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -14947,6 +15158,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14961,6 +15173,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14975,6 +15188,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -14989,6 +15203,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -15058,6 +15273,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -15072,6 +15288,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -15086,6 +15303,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -15100,6 +15318,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -15158,6 +15377,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -15170,6 +15390,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -15204,6 +15425,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tec Toy + @@ -15218,6 +15440,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tec Toy + @@ -15246,6 +15469,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -15299,6 +15523,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -15316,6 +15541,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -15330,6 +15556,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Koei + @@ -15347,6 +15574,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -15543,6 +15771,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Koei + @@ -15560,6 +15789,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -15704,6 +15934,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unknown> + @@ -15801,6 +16032,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Koei + @@ -15818,6 +16050,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -15940,6 +16173,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -15954,6 +16188,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -15971,6 +16206,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -15986,6 +16222,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -16001,6 +16238,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Accolade + @@ -16052,6 +16290,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -16066,6 +16305,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -16102,6 +16342,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -16119,6 +16360,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -16133,6 +16375,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -16147,6 +16390,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -16161,6 +16405,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tec Toy + @@ -16178,6 +16423,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -16280,6 +16526,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -16294,6 +16541,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tec Toy + @@ -16311,6 +16559,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -16326,6 +16575,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -16342,6 +16592,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -16359,6 +16610,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -16373,6 +16625,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -16387,6 +16640,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -16401,6 +16655,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -16415,6 +16670,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -16429,6 +16685,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -16556,6 +16813,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Microprose + @@ -16653,6 +16911,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -16676,6 +16935,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -16760,6 +17020,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -16810,6 +17071,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -16824,6 +17086,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -16849,6 +17112,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -17493,6 +17757,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -17581,6 +17846,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -17763,6 +18029,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -18221,6 +18488,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Koei + @@ -18238,6 +18506,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -18252,6 +18521,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Koei + @@ -18269,6 +18539,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -18405,6 +18676,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unknown> + @@ -18447,6 +18719,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -18560,6 +18833,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Renegade + @@ -18574,6 +18848,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Renegade + @@ -18589,6 +18864,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -18689,6 +18965,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -18703,6 +18980,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unknown> + @@ -18717,6 +18995,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -18731,6 +19010,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -18745,6 +19025,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -18759,6 +19040,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -18853,6 +19135,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -18867,6 +19150,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -18884,6 +19168,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -18901,6 +19186,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -18915,6 +19201,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -18929,6 +19216,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -18943,6 +19231,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -18957,6 +19246,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -18971,6 +19261,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tec Toy + @@ -18988,6 +19279,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -19386,6 +19678,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -19400,6 +19693,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Atlus + @@ -19417,6 +19711,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -19443,6 +19738,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -19459,8 +19755,10 @@ Notice that these are not working on real hardware due to bugged code with VDP i - + + + @@ -19587,33 +19885,6 @@ Notice that these are not working on real hardware due to bugged code with VDP i - - Sonic & Knuckles + Sonic the Hedgehog (World) - 199? - <unknown> - - - - - - - - - - - Sonic & Knuckles + Sonic the Hedgehog 2 (World) - 199? - <unknown> - - - - - - - - - - Knuckles in Sonic 2 (Prototype 0524, 19940527, 10.46) 199? @@ -19625,19 +19896,6 @@ Notice that these are not working on real hardware due to bugged code with VDP i - - Sonic & Knuckles + Sonic the Hedgehog 3 (World) - 199? - <unknown> - - - - - - - - - Sonic & Knuckles (Prototype 0525, 19940525, 15.28) 1994 @@ -19655,6 +19913,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unknown> + @@ -19669,6 +19928,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unknown> + @@ -20053,6 +20313,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -20067,6 +20328,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20081,6 +20343,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Treco + @@ -20095,6 +20358,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Treco + @@ -20112,6 +20376,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -20129,6 +20394,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -20407,6 +20673,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20455,6 +20722,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -20491,6 +20759,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20505,6 +20774,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20520,6 +20790,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20535,6 +20806,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20549,6 +20821,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20563,6 +20836,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20577,6 +20851,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20591,6 +20866,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20721,6 +20997,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20735,6 +21012,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20752,6 +21030,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -20779,6 +21058,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20793,6 +21073,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20807,6 +21088,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20821,6 +21103,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20835,6 +21118,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -20849,6 +21133,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -21255,6 +21540,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -21269,6 +21555,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -21432,6 +21719,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -21510,6 +21798,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -21538,6 +21827,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Seismic + @@ -21552,6 +21842,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i U.S. Gold + @@ -21732,7 +22023,8 @@ Notice that these are not working on real hardware due to bugged code with VDP i Capcom - + + @@ -21747,7 +22039,8 @@ Notice that these are not working on real hardware due to bugged code with VDP i - + + @@ -21759,7 +22052,8 @@ Notice that these are not working on real hardware due to bugged code with VDP i Capcom - + + @@ -21857,6 +22151,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -21932,6 +22227,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -21949,6 +22245,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -22047,6 +22344,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -22245,6 +22543,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tecmo + @@ -22259,6 +22558,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tecmo + @@ -22273,6 +22573,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tecmo + @@ -22290,6 +22591,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -22305,6 +22607,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tecmo + @@ -22322,6 +22625,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -22336,6 +22640,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tecmo + @@ -22350,6 +22655,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tecmo + @@ -22364,6 +22670,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tecmo + @@ -22381,6 +22688,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -22531,6 +22839,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -22849,6 +23158,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i American Softworks + @@ -22863,6 +23173,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i American Softworks + @@ -23024,6 +23335,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -23156,6 +23468,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Renovation + @@ -23173,6 +23486,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -23187,6 +23501,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -23201,6 +23516,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -23215,6 +23531,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -23254,6 +23571,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tradewest + @@ -23501,6 +23819,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Koei + @@ -23518,6 +23837,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -23532,6 +23852,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Koei + @@ -23549,6 +23870,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -23588,6 +23910,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Accolade + @@ -23959,6 +24282,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Electronic Arts + @@ -23976,6 +24300,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -24013,6 +24338,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -24157,6 +24483,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Micronet + @@ -24174,6 +24501,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -24188,6 +24516,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Treco + @@ -24213,6 +24542,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Time Warner Interactive + @@ -24525,6 +24855,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -24540,6 +24871,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -24552,6 +24884,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Tec Toy + @@ -24895,6 +25228,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i U.S. Gold + @@ -25189,6 +25523,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25225,6 +25560,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25239,6 +25575,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25253,6 +25590,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25267,6 +25605,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25281,6 +25620,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25295,6 +25635,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25309,6 +25650,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25323,6 +25665,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25337,6 +25680,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25351,6 +25695,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25365,6 +25710,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25379,6 +25725,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25393,6 +25740,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25407,6 +25755,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25421,6 +25770,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25446,6 +25796,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25471,6 +25822,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25485,6 +25837,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25499,6 +25852,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25513,6 +25867,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25527,6 +25882,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25541,6 +25897,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25566,6 +25923,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25580,6 +25938,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25594,6 +25953,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25608,6 +25968,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25622,6 +25983,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25636,6 +25998,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25661,6 +26024,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Sega + @@ -25723,6 +26087,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -25737,6 +26102,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Ming + @@ -26110,6 +26476,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i C&E + @@ -26122,6 +26489,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i C&E + @@ -26180,6 +26548,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Renovation + @@ -26197,6 +26566,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -26239,6 +26609,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -26256,6 +26627,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -26489,8 +26861,9 @@ Notice that these are not working on real hardware due to bugged code with VDP i 199? <unlicensed> - - + + + @@ -26501,8 +26874,9 @@ Notice that these are not working on real hardware due to bugged code with VDP i 199? <unknown> - - + + + @@ -26514,6 +26888,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26537,7 +26912,8 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> - + + @@ -26549,7 +26925,8 @@ Notice that these are not working on real hardware due to bugged code with VDP i Realtec - + + @@ -26561,20 +26938,22 @@ Notice that these are not working on real hardware due to bugged code with VDP i Realtec - + + - - Golden 10 in 1 + + Golden 10 in 1 (Incomplete Dump) 199? <unlicensed> - - + + + @@ -26586,6 +26965,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26598,6 +26978,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26610,6 +26991,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26622,6 +27004,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26634,6 +27017,8 @@ Notice that these are not working on real hardware due to bugged code with VDP i 199? <unlicensed> + + @@ -26646,6 +27031,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26658,6 +27044,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26671,8 +27058,10 @@ Notice that these are not working on real hardware due to bugged code with VDP i - + + + @@ -26683,6 +27072,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26695,6 +27085,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26707,7 +27098,8 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> - + + @@ -26719,6 +27111,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26731,6 +27124,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26742,7 +27136,6 @@ Notice that these are not working on real hardware due to bugged code with VDP i 199? <unlicensed> - @@ -26755,6 +27148,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26767,7 +27161,8 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unknown> - + + @@ -26779,7 +27174,8 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unknown> - + + @@ -26791,6 +27187,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26803,8 +27200,10 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> - + + + @@ -26815,8 +27214,10 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> - + + + @@ -26827,6 +27228,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26839,6 +27241,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> + @@ -26851,7 +27254,8 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> - + + @@ -26874,7 +27278,8 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> - + + @@ -26885,20 +27290,20 @@ Notice that these are not working on real hardware due to bugged code with VDP i 199? <unlicensed> - - + - + Whac-a-Critter (USA) 1993 Realtec - + + @@ -26910,6 +27315,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Radica Games ~ Sega + @@ -26922,6 +27328,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i Radica Games ~ Capcom + @@ -26931,7 +27338,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i - Chinese Fighter III (Chi, Alt) + Chinese Fighter III (Chi, Unprotected?) 199? <unlicensed> @@ -26942,7 +27349,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i - The King of Fighters '98 (Pirate) + K.O.F 98' (Unprotected?) 199? <unlicensed> @@ -27040,6 +27447,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unknown> + @@ -27066,8 +27474,10 @@ Notice that these are not working on real hardware due to bugged code with VDP i - + + + @@ -27078,7 +27488,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <unlicensed> - + @@ -28157,6 +28567,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -28174,6 +28585,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + @@ -28188,6 +28600,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i + diff --git a/src/mame/drivers/hshavoc.c b/src/mame/drivers/hshavoc.c index e441634e256..84be6a57bb0 100644 --- a/src/mame/drivers/hshavoc.c +++ b/src/mame/drivers/hshavoc.c @@ -115,7 +115,7 @@ ROM_END #endif -DRIVER_INIT_MEMBER(md_cons_state,hshavoc) +DRIVER_INIT_MEMBER(md_havoc_state,hshavoc) { int x; UINT16 *src = (UINT16 *)machine().root_device().memregion("maincpu")->base(); @@ -227,5 +227,5 @@ DRIVER_INIT_MEMBER(md_cons_state,hshavoc) -GAME( 1993, hshavoc, 0, md_bootleg, hshavoc, md_cons_state, hshavoc, ROT0, "Data East", "High Seas Havoc",GAME_NOT_WORKING ) -//GAME( 1993, hshavoc2, hshavoc, md_bootleg, hshavoc, md_cons_state, genesis, ROT0, "Data East", "High Seas Havoc (Genesis ROM)",GAME_NOT_WORKING ) +GAME( 1993, hshavoc, 0, md_bootleg, hshavoc, md_havoc_state, hshavoc, ROT0, "Data East", "High Seas Havoc",GAME_NOT_WORKING ) +//GAME( 1993, hshavoc2, hshavoc, md_bootleg, hshavoc, md_havoc_state, genesis, ROT0, "Data East", "High Seas Havoc (Genesis ROM)",GAME_NOT_WORKING ) diff --git a/src/mame/drivers/megadrvb.c b/src/mame/drivers/megadrvb.c index 14d84b2889f..4ec4cd6237a 100644 --- a/src/mame/drivers/megadrvb.c +++ b/src/mame/drivers/megadrvb.c @@ -763,7 +763,7 @@ DRIVER_INIT_MEMBER(md_boot_state,srmdb) DRIVER_INIT_CALL(megadriv); } -DRIVER_INIT_MEMBER(md_cons_state,topshoot) +DRIVER_INIT_MEMBER(md_boot_state,topshoot) { machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x200050, 0x200051, FUNC(topshoot_200051_r) ); machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_port(0x200042, 0x200043, "IN0"); @@ -785,4 +785,4 @@ GAME( 1993, aladmdb, 0, megadrvb, aladmdb, md_boot_state, aladmdb, ROT0, "b GAME( 1996, mk3mdb, 0, megadrvb, mk3mdb, md_boot_state, mk3mdb, ROT0, "bootleg / Midway", "Mortal Kombat 3 (bootleg of Megadrive version)", 0) GAME( 1994, ssf2mdb, 0, megadrvb, ssf2mdb, md_boot_state, ssf2mdb, ROT0, "bootleg / Capcom", "Super Street Fighter II - The New Challengers (bootleg of Japanese MegaDrive version)", 0) GAME( 1993, srmdb, 0, megadrvb, srmdb, md_boot_state, srmdb, ROT0, "bootleg / Konami", "Sunset Riders (bootleg of Megadrive version)", 0) -GAME( 1995, topshoot, 0, md_bootleg, topshoot, md_cons_state, topshoot, ROT0, "Sun Mixing", "Top Shooter", 0) +GAME( 1995, topshoot, 0, md_bootleg, topshoot, md_boot_state, topshoot, ROT0, "Sun Mixing", "Top Shooter", 0) diff --git a/src/mame/drivers/megatech.c b/src/mame/drivers/megatech.c index 964831c2f66..cddbdd013d2 100644 --- a/src/mame/drivers/megatech.c +++ b/src/mame/drivers/megatech.c @@ -599,17 +599,17 @@ static DEVICE_IMAGE_LOAD( megatech_cart ) { if (!mame_stricmp("genesis", pcb_name)) { - printf("%s is genesis\n", mt_cart->tag); + mame_printf_debug("%s is genesis\n", mt_cart->tag); state->m_cart_is_genesis[this_cart->slot] = 1; } else if (!mame_stricmp("sms", pcb_name)) { - printf("%s is sms\n", mt_cart->tag); + mame_printf_debug("%s is sms\n", mt_cart->tag); state->m_cart_is_genesis[this_cart->slot] = 0; } else { - printf("%s is invalid\n", mt_cart->tag); + mame_printf_debug("%s is invalid\n", mt_cart->tag); } } diff --git a/src/mame/includes/megadriv.h b/src/mame/includes/megadriv.h index 5aa60abaf3a..f7a3311665c 100644 --- a/src/mame/includes/megadriv.h +++ b/src/mame/includes/megadriv.h @@ -23,13 +23,7 @@ #define MASTER_CLOCK_PAL 53203424 #define SEGACD_CLOCK 12500000 - -#define MAX_MD_CART_SIZE 0x800000 - -/* where a fresh copy of rom is stashed for reset and banking setup */ -#define VIRGIN_COPY_GEN 0xd00000 - -#define MD_CPU_REGION_SIZE (MAX_MD_CART_SIZE + VIRGIN_COPY_GEN) +#define MD_CPU_REGION_SIZE 0x800000 extern int sega_cd_connected; @@ -41,17 +35,12 @@ INPUT_PORTS_EXTERN( megadriv ); INPUT_PORTS_EXTERN( megadri6 ); INPUT_PORTS_EXTERN( ssf2mdb ); INPUT_PORTS_EXTERN( mk3mdb ); -INPUT_PORTS_EXTERN( megdsvp ); MACHINE_CONFIG_EXTERN( megadriv_timers ); MACHINE_CONFIG_EXTERN( md_ntsc ); MACHINE_CONFIG_EXTERN( md_pal ); MACHINE_CONFIG_EXTERN( md_svp ); -MACHINE_CONFIG_EXTERN( megdsvppal ); -MACHINE_CONFIG_EXTERN( megadriv ); -MACHINE_CONFIG_EXTERN( megadpal ); -MACHINE_CONFIG_EXTERN( megdsvp ); MACHINE_CONFIG_EXTERN( genesis_32x ); MACHINE_CONFIG_EXTERN( genesis_32x_pal ); MACHINE_CONFIG_EXTERN( genesis_scd ); @@ -61,8 +50,7 @@ MACHINE_CONFIG_EXTERN( genesis_scd_mcdj ); MACHINE_CONFIG_EXTERN( genesis_32x_scd ); MACHINE_CONFIG_EXTERN( md_bootleg ); // for topshoot.c & hshavoc.c -extern UINT16* megadriv_backupram; -extern int megadriv_backupram_length; +extern cpu_device *_svp_cpu; extern UINT8 megatech_bios_port_cc_dc_r(running_machine &machine, int offset, int ctrl); extern void megadriv_stop_scanline_timer(running_machine &machine); @@ -384,52 +372,16 @@ struct megadriv_cart int ssf2_lastoff, ssf2_lastdata; }; -class md_cons_state : public md_base_state +class md_havoc_state : public md_base_state { public: - md_cons_state(const machine_config &mconfig, device_type type, const char *tag) + md_havoc_state(const machine_config &mconfig, device_type type, const char *tag) : md_base_state(mconfig, type, tag) { } - emu_timer *m_mess_io_timeout[3]; - int m_mess_io_stage[3]; - UINT8 m_jcart_io_data[2]; - - megadriv_cart m_md_cart; - DECLARE_DRIVER_INIT(hshavoc); - DECLARE_DRIVER_INIT(topshoot); - - DECLARE_DRIVER_INIT(genesis); - DECLARE_DRIVER_INIT(mess_md_common); - DECLARE_DRIVER_INIT(md_eur); - DECLARE_DRIVER_INIT(md_jpn); - }; -class mdsvp_state : public md_cons_state -{ -public: - mdsvp_state(const machine_config &mconfig, device_type type, const char *tag) - : md_cons_state(mconfig, type, tag) { } - - UINT8 *m_iram; // IRAM (0-0x7ff) - UINT8 *m_dram; // [0x20000]; - UINT32 m_pmac_read[6]; // read modes/addrs for PM0-PM5 - UINT32 m_pmac_write[6]; // write ... - PAIR m_pmc; - UINT32 m_emu_status; - UINT16 m_XST; // external status, mapped at a15000 and a15002 on 68k side. - UINT16 m_XST2; // status of XST (bit1 set when 68k writes to XST) -}; - -ADDRESS_MAP_EXTERN( svp_ssp_map, driver_device ); -ADDRESS_MAP_EXTERN( svp_ext_map, driver_device ); -extern void svp_init(running_machine &machine); -extern cpu_device *_svp_cpu; - - - UINT8 megadrive_io_read_data_port_3button(running_machine &machine, int portnum); class _32x_state : public md_base_state @@ -459,13 +411,8 @@ public: { } }; - -/*----------- defined in machine/md_cart.c -----------*/ - -MACHINE_CONFIG_EXTERN( genesis_cartslot ); MACHINE_CONFIG_EXTERN( _32x_cartslot ); -MACHINE_CONFIG_EXTERN( pico_cartslot ); -MACHINE_START( md_sram ); + /*----------- defined in drivers/megadriv.c -----------*/ diff --git a/src/mame/machine/md_cart.c b/src/mame/machine/md_cart.c deleted file mode 100644 index ba90676b309..00000000000 --- a/src/mame/machine/md_cart.c +++ /dev/null @@ -1,2262 +0,0 @@ -/*************************************************************************** - - megadriv.c - - Machine file to handle emulation of the Sega Mega Drive & Genesis in MESS. - - i2c games mapping table: - - game name | SDA_IN | SDA_OUT | SCL | SIZE_MASK | PAGE_MASK | - ----------------------------------|------------|------------|------------|----------------|-----------| - NBA Jam | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x00ff (24C02) | 0x03 | xx - NBA Jam TE | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x00ff (24C02) | 0x03 | xx - NBA Jam TE (32x) | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x00ff (24C02) | 0x03 | - NFL Quarterback Club | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x00ff (24C02) | 0x03 | xx - NFL Quarterback Club 96 | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x07ff (24C16) | 0x07 | xx - College Slam | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x1fff (24C64) | 0x07 | xx - Frank Thomas Big Hurt Baseball | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x1fff (24C64) | 0x07 | xx - NHLPA Hockey 93 | 0x200001-7 | 0x200001-7 | 0x200001-6 | 0x007f (24C01) | 0x03 | xx - Rings of Power | 0x200001-7 | 0x200001-7 | 0x200001-6 | 0x007f (24C01) | 0x03 | xx - Evander Holyfield's Boxing | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx - Greatest Heavyweights of the Ring | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx - Wonder Boy V | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx - Sports Talk Baseball | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx - Megaman - the Wily Wars | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx ** - Micro Machines 2 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x03ff (24C08) | 0x0f | - Micro Machines Military | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x03ff (24C08) | 0x0f | - Micro Machines 96 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x07ff (24C16) | 0x0f | - Brian Lara Cricket 96 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x1fff (24C64) | 0x??* | - ----------------------------------|------------|------------|------------|----------------|-----------| - - * Notes: check these - ** original Rockman Mega World (J) set uses normal backup RAM - - 2008-09: Moved here cart code and custom mapper handlers. Hopefully, - it will make painless the future merging with HazeMD - 2008-10: Fixed SRAM, matching as much as possible HazeMD. Some game is - not detected, however. E.g. Sonic 3. Also some games seem false - positives (e.g. Wonderboy 5: according to its headers it should - have 1byte of SRAM). Better detection routines would be welcome. - 2009-06: Changed SRAM code, fixing more games, including Sonic 3. The - false positives seem only some of the games using EEPROM. Todo - list in mess/drivers/genesis.c includes EEPROM emulation. - -***************************************************************************/ - - -#include "emu.h" -#include "formats/imageutl.h" -#include "cpu/m68000/m68000.h" - -#include "imagedev/cartslot.h" -#include "includes/megadriv.h" - - -/* PCB */ -enum -{ - SEGA_STD = 0, - - SEGA_SRAM, SEGA_FRAM, - - CM_JCART, CM_JCART_SEPROM, /* Codemasters PCB (J-Carts and SEPROM) */ - - SSF2, /* Super Street Fighter 2 */ - GAME_KANDUME, /* Game no Kandume Otokuyou */ - BEGGAR, /* Xin Qigai Wangzi uses different sram start address and has no valid header */ - - // EEPROM - SEGA_EEPROM, /* Wonder Boy V / Evander Holyfield's Boxing / Greatest Heavyweights of the Ring / Sports Talk Baseball / Megaman */ - NBA_JAM, /* NBA Jam */ - NBA_JAM_TE, /* NBA Jam TE / NFL Quarterback Club */ - NFL_QB_96, /* NFL Quarterback Club '96 */ - C_SLAM, /* College Slam / Frank Thomas Big Hurt Baseball */ - EA_NHLPA, /* NHLPA Hockey 93 / Rings of Power */ - CODE_MASTERS, /* Micro Machines 2 / Military / 96 / Brian Lara Cricket 96 */ - - MC_SUP19IN1, /* Super 19 in 1 */ - MC_SUP15IN1, /* Super 15 in 1 */ - MC_12IN1, /* 12 in 1 and a few more multicarts */ - BUGSLIFE, /* A Bug's Life */ - CHINFIGHT3, /* Chinese Fighters 3 */ - ELFWOR, /* Linghuan Daoshi Super Magician */ - KOF98, /* King of Fighters '98 */ - KOF99, /* King of Fighters '99 */ - LIONK2, /* Lion King 2 */ - LIONK3, /* Lion King 3 */ - SKINGKONG, /* Super King Kong 99 */ - SDK99, /* Super Donkey Kong 99 */ - MJLOVER, /* Mahjong Lover */ - MULAN, /* Hua Mu Lan - Mulan */ - POKEMON, /* Pocket Monster */ - POKEMON2, /* Pocket Monster 2 */ - KAIJU, /* Pokemon Stadium */ - RADICA, /* Radica TV games.. these probably should be a separate driver since they are a separate 'console' */ - REALTEC, /* Whac a Critter/Mallet legend, Defend the Earth, Funnyworld/Ballonboy */ - REDCLIFF, /* Romance of the Three Kingdoms - Battle of Red Cliffs, already decoded from .mdx format */ - REDCL_EN, /* The encoded version... */ - ROCKMANX3, /* Rockman X3 */ - SMB, /* Super Mario Bros. */ - SMB2, /* Super Mario Bros. 2 */ - SMOUSE, /* Smart Mouse */ - SOULBLAD, /* Soul Blade */ - SQUIRRELK, /* Squirrel King */ - SBUBBOB, /* Super Bubble Bobble */ - TOPFIGHTER, /* Top Fighter 2000 MK VIII */ - PSOLAR /* Pier Solar */ -}; - -struct md_pcb -{ - const char *pcb_name; - int pcb_id; -}; - -// Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it -static const md_pcb pcb_list[] = -{ - {"SEGA-EEPROM", SEGA_EEPROM}, - {"SEGA-SRAM", SEGA_SRAM}, - {"SEGA-FRAM", SEGA_FRAM}, - - {"CM-JCART", CM_JCART}, - {"CM-JCART-SEPROM", CM_JCART_SEPROM}, - {"CM-SEPROM", CODE_MASTERS}, - - {"SSF2", SSF2}, - {"GAMEKANDUME", GAME_KANDUME}, - {"BEGGAR", BEGGAR}, - - {"NBAJAM", NBA_JAM}, - {"NBAJAMTE", NBA_JAM_TE}, - {"NFLQB96", NFL_QB_96}, - {"CSLAM", C_SLAM}, - {"NHLPA", EA_NHLPA}, - - {"LIONK3", LIONK3}, - {"SDK99", SDK99}, - {"SKINGKONG", SKINGKONG}, - {"REDCLIFF", REDCL_EN}, - {"RADICA", RADICA}, - {"KOF98", KOF98}, - {"KOF99", KOF99}, - {"SOULBLAD", SOULBLAD}, - {"MJLOVER", MJLOVER}, - {"SQUIRRELK", SQUIRRELK}, - {"SMOUSE", SMOUSE}, - {"SMB", SMB}, - {"SMB2", SMB2}, - {"KAIJU", KAIJU}, - {"CHINFIGHT3", CHINFIGHT3}, - {"LIONK2", LIONK2}, - {"BUGSLIFE", BUGSLIFE}, - {"ELFWOR", ELFWOR}, - {"ROCKMANX3", ROCKMANX3}, - {"SBUBBOB", SBUBBOB}, - {"REALTEC", REALTEC}, - {"MC_SUP19IN1", MC_SUP19IN1}, - {"MC_SUP15IN1", MC_SUP15IN1}, - {"MC_12IN1", MC_12IN1}, - {"TOPFIGHTER", TOPFIGHTER}, - {"POKEMON", POKEMON}, - {"POKEMON2", POKEMON2}, - {"MULAN", MULAN}, - {"PSOLAR", PSOLAR} -}; - -static int md_get_pcb_id(const char *pcb) -{ - int i; - - for (i = 0; i < ARRAY_LENGTH(pcb_list); i++) - { - if (!mame_stricmp(pcb_list[i].pcb_name, pcb)) - return pcb_list[i].pcb_id; - } - - return SEGA_STD; -} - - -/************************************* - * - * Handlers for custom mappers - * - *************************************/ - -/************************************* - * Super Street Fighter II - *************************************/ -static WRITE16_HANDLER( genesis_ssf2_bank_w ) -{ - md_cons_state *state = space.machine().driver_data(); - UINT8 *ROM = state->memregion("maincpu")->base(); - - if ((state->m_md_cart.ssf2_lastoff != offset) || (state->m_md_cart.ssf2_lastdata != data)) - { - state->m_md_cart.ssf2_lastoff = offset; - state->m_md_cart.ssf2_lastdata = data; - switch (offset << 1) - { - case 0x00: /* write protect register */ // this is not a write protect, but seems to do nothing useful but reset bank0 after the checksum test (red screen otherwise) - if (data == 2) - { - memcpy(ROM + 0x000000, ROM + 0x400000 + (((data & 0xf) - 2) * 0x080000), 0x080000); - } - break; - case 0x02: /* 0x080000 - 0x0FFFFF */ - memcpy(ROM + 0x080000, ROM + 0x400000 + ((data & 0xf) * 0x080000), 0x080000); - break; - case 0x04: /* 0x100000 - 0x17FFFF */ - memcpy(ROM + 0x100000, ROM + 0x400000 + ((data & 0xf) * 0x080000), 0x080000); - break; - case 0x06: /* 0x180000 - 0x1FFFFF */ - memcpy(ROM + 0x180000, ROM + 0x400000 + ((data & 0xf) * 0x080000), 0x080000); - break; - case 0x08: /* 0x200000 - 0x27FFFF */ - memcpy(ROM + 0x200000, ROM + 0x400000 + ((data & 0xf) * 0x080000), 0x080000); - break; - case 0x0a: /* 0x280000 - 0x2FFFFF */ - memcpy(ROM + 0x280000, ROM + 0x400000 + ((data & 0xf) * 0x080000), 0x080000); - break; - case 0x0c: /* 0x300000 - 0x37FFFF */ - memcpy(ROM + 0x300000, ROM + 0x400000 + ((data & 0xf) * 0x080000), 0x080000); - break; - case 0x0e: /* 0x380000 - 0x3FFFFF */ - memcpy(ROM + 0x380000, ROM + 0x400000 + ((data & 0xf) * 0x080000), 0x080000); - break; - } - } -} - -/************************************* - * Lion King 3, Super King Kong 99 - * & Super Donkey Kong 99 - *************************************/ -#ifdef UNUSED_FUNCTION -static WRITE16_HANDLER( l3alt_pdat_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_md_cart.l3alt_pdat = data; -} - -static WRITE16_HANDLER( l3alt_pcmd_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_md_cart.l3alt_pcmd = data; -} -#endif - -static READ16_HANDLER( l3alt_prot_r ) -{ - md_cons_state *state = space.machine().driver_data(); - int retdata = 0; - - offset &= 0x07; - - switch (offset) - { - case 2: - - switch (state->m_md_cart.l3alt_pcmd) - { - case 1: - retdata = state->m_md_cart.l3alt_pdat >> 1; - break; - - case 2: - retdata = state->m_md_cart.l3alt_pdat >> 4; - retdata |= (state->m_md_cart.l3alt_pdat & 0x0f) << 4; - break; - - default: - /* printf("unk prot case %d\n", l3alt_pcmd); */ - retdata = (BIT(state->m_md_cart.l3alt_pdat, 7) << 0); - retdata |= (BIT(state->m_md_cart.l3alt_pdat, 6) << 1); - retdata |= (BIT(state->m_md_cart.l3alt_pdat, 5) << 2); - retdata |= (BIT(state->m_md_cart.l3alt_pdat, 4) << 3); - retdata |= (BIT(state->m_md_cart.l3alt_pdat, 3) << 4); - retdata |= (BIT(state->m_md_cart.l3alt_pdat, 2) << 5); - retdata |= (BIT(state->m_md_cart.l3alt_pdat, 1) << 6); - retdata |= (BIT(state->m_md_cart.l3alt_pdat, 0) << 7); - break; - } - break; - - default: - logerror("protection read, unknown offset\n"); - break; - } - -/* printf("%06x: l3alt_pdat_w %04x l3alt_pcmd_w %04x return %04x\n", activecpu_get_pc(), l3alt_pdat, l3alt_pcmd, retdata); */ - - return retdata; -} - -static WRITE16_HANDLER( l3alt_prot_w ) -{ - md_cons_state *state = space.machine().driver_data(); - offset &= 0x7; - - switch (offset) - { - case 0x0: - state->m_md_cart.l3alt_pdat = data; - break; - case 0x1: - state->m_md_cart.l3alt_pcmd = data; - break; - default: - logerror("protection write, unknown offst\n"); - break; - } -} - -static WRITE16_HANDLER( l3alt_bank_w ) -{ - offset &= 0x7; - - switch (offset) - { - case 0: - { - UINT8 *ROM = space.machine().root_device().memregion("maincpu")->base(); - /* printf("%06x data %04x\n",activecpu_get_pc(), data); */ - memcpy(&ROM[0x000000], &ROM[VIRGIN_COPY_GEN + (data & 0xffff) * 0x8000], 0x8000); - } - break; - - default: - logerror("unk bank w\n"); - break; - - } - -} - -/************************************* - * Whac a Critter/Mallet Legend, - * Defend the Earth, Funnyworld/Ballonboy - *************************************/ -static WRITE16_HANDLER( realtec_402000_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_md_cart.realtec_bank_addr = 0; - state->m_md_cart.realtec_bank_size = (data >> 8) & 0x1f; -} - -static WRITE16_HANDLER( realtec_400000_w ) -{ - md_cons_state *state = space.machine().driver_data(); - int bankdata = (data >> 9) & 0x7; - - UINT8 *ROM = state->memregion("maincpu")->base(); - - state->m_md_cart.realtec_old_bank_addr = state->m_md_cart.realtec_bank_addr; - state->m_md_cart.realtec_bank_addr = (state->m_md_cart.realtec_bank_addr & 0x7) | bankdata << 3; - - memcpy(ROM, ROM + (state->m_md_cart.realtec_bank_addr * 0x20000) + 0x400000, state->m_md_cart.realtec_bank_size * 0x20000); - memcpy(ROM + state->m_md_cart.realtec_bank_size * 0x20000, ROM + (state->m_md_cart.realtec_bank_addr * 0x20000) + 0x400000, state->m_md_cart.realtec_bank_size * 0x20000); -} - -static WRITE16_HANDLER( realtec_404000_w ) -{ - md_cons_state *state = space.machine().driver_data(); - int bankdata = (data >> 8) & 0x3; - UINT8 *ROM = state->memregion("maincpu")->base(); - - state->m_md_cart.realtec_old_bank_addr = state->m_md_cart.realtec_bank_addr; - state->m_md_cart.realtec_bank_addr = (state->m_md_cart.realtec_bank_addr & 0xf8) | bankdata; - - if (state->m_md_cart.realtec_old_bank_addr != state->m_md_cart.realtec_bank_addr) - { - memcpy(ROM, ROM + (state->m_md_cart.realtec_bank_addr * 0x20000)+ 0x400000, state->m_md_cart.realtec_bank_size * 0x20000); - memcpy(ROM + state->m_md_cart.realtec_bank_size * 0x20000, ROM + (state->m_md_cart.realtec_bank_addr * 0x20000) + 0x400000, state->m_md_cart.realtec_bank_size * 0x20000); - } -} - -/************************************* - * Chinese Fighters 3 - *************************************/ -static WRITE16_HANDLER( chifi3_bank_w ) -{ - UINT8 *ROM = space.machine().root_device().memregion("maincpu")->base(); - - if (data == 0xf100) // *hit player - { - int x; - for (x = 0; x < 0x100000; x += 0x10000) - { - memcpy(ROM + x, ROM + 0x410000, 0x10000); - } - } - else if (data == 0xd700) // title screen.. - { - int x; - for (x = 0; x < 0x100000; x += 0x10000) - { - memcpy(ROM + x, ROM + 0x470000, 0x10000); - } - } - else if (data == 0xd300) // character hits floor - { - int x; - for (x = 0; x < 0x100000; x += 0x10000) - { - memcpy(ROM + x, ROM + 0x430000, 0x10000); - } - } - else if (data == 0x0000) - { - int x; - for (x = 0; x < 0x100000; x += 0x10000) - { - memcpy(ROM + x, ROM + 0x400000 + x, 0x10000); - } - } - else - { - logerror("%06x chifi3, bankw? %04x %04x\n", space.device().safe_pc(), offset, data); - } - -} - -static READ16_HANDLER( chifi3_prot_r ) -{ - UINT32 retdat; - - /* not 100% correct, there may be some relationship between the reads here - and the writes made at the start of the game.. */ - - /* - 04dc10 chifi3, prot_r? 2800 - 04cefa chifi3, prot_r? 65262 - */ - - if (space.device().safe_pc() == 0x01782) // makes 'VS' screen appear - { - retdat = space.device().state().state_int(M68K_D3) & 0xff; - retdat <<= 8; - return retdat; - } - else if (space.device().safe_pc() == 0x1c24) // background gfx etc. - { - retdat = space.device().state().state_int(M68K_D3) & 0xff; - retdat <<= 8; - return retdat; - } - else if (space.device().safe_pc() == 0x10c4a) // unknown - { - return space.machine().rand(); - } - else if (space.device().safe_pc() == 0x10c50) // unknown - { - return space.machine().rand(); - } - else if (space.device().safe_pc() == 0x10c52) // relates to the game speed.. - { - retdat = space.device().state().state_int(M68K_D4) & 0xff; - retdat <<= 8; - return retdat; - } - else if (space.device().safe_pc() == 0x061ae) - { - retdat = space.device().state().state_int(M68K_D3) & 0xff; - retdat <<= 8; - return retdat; - } - else if (space.device().safe_pc() == 0x061b0) - { - retdat = space.device().state().state_int(M68K_D3) & 0xff; - retdat <<= 8; - return retdat; - } - else - { - logerror("%06x chifi3, prot_r? %04x\n", space.device().safe_pc(), offset); - } - - return 0; -} - -/************************************* - * Super 19 in 1 & Super 15 in 1 - *************************************/ -static WRITE16_HANDLER( s19in1_bank ) -{ - UINT8 *ROM = space.machine().root_device().memregion("maincpu")->base(); - memcpy(ROM + 0x000000, ROM + 0x400000 + ((offset << 1) * 0x10000), 0x80000); -} - -/************************************* - * Kaiju? (Pokemon Stadium) - *************************************/ -static WRITE16_HANDLER( kaiju_bank_w ) -{ - UINT8 *ROM = space.machine().root_device().memregion("maincpu")->base(); - memcpy(ROM + 0x000000, ROM + 0x400000 + (data & 0x7f) * 0x8000, 0x8000); -} - -/************************************* - * Soulblade - *************************************/ -static READ16_HANDLER( soulb_400006_r ) -{ -// printf("%06x soulb_400006_r\n",space.device().safe_pc()); - return 0xf000; -} - -static READ16_HANDLER( soulb_400002_r ) -{ -// printf("%06x soulb_400002_r\n",space.device().safe_pc()); - return 0x9800; -} - -static READ16_HANDLER( soulb_400004_r ) -{ -// return 0x9800; -// printf("%06x soulb_400004_r\n",space.device().safe_pc()); -// - return 0xc900; -//aa -//c9 -} - -/************************************* - * Mahjong Lover - *************************************/ -static READ16_HANDLER( mjlovr_prot_1_r ) -{ - return 0x9000; -} - -static READ16_HANDLER( mjlovr_prot_2_r ) -{ - return 0xd300; -} - -/************************************* - * Super Mario Bros - *************************************/ -static READ16_HANDLER( smbro_prot_r ) -{ - return 0xc; -} - - -/************************************* - * Smart Mouse - *************************************/ -static READ16_HANDLER( smous_prot_r ) -{ - switch (offset) - { - case 0: return 0x5500; - case 1: return 0x0f00; - case 2: return 0xaa00; - case 3: return 0xf000; - } - - return -1; -} - -/************************************* - * Super Bubble Bobble MD - *************************************/ -static READ16_HANDLER( sbub_extra1_r ) -{ - return 0x5500; -} - -static READ16_HANDLER( sbub_extra2_r ) -{ - return 0x0f00; -} - -/************************************* - * King of Fighters 99 - *************************************/ -static READ16_HANDLER( kof99_A13002_r ) -{ - // write 02 to a13002.. shift right 1? - return 0x01; -} - -static READ16_HANDLER( kof99_00A1303E_r ) -{ - // write 3e to a1303e.. shift right 1? - return 0x1f; -} - -static READ16_HANDLER( kof99_A13000_r ) -{ - // no write, startup check, chinese message if != 0 - return 0x0; -} - -/************************************* - * Radica controllers - *************************************/ -static READ16_HANDLER( radica_bank_select ) -{ - int bank = offset & 0x3f; - UINT8 *ROM = space.machine().root_device().memregion("maincpu")->base(); - memcpy(ROM, ROM + 0x400000 + (bank * 0x10000), 0x400000); - return 0; -} - -/************************************* - * ROTK Red Cliff - *************************************/ -static READ16_HANDLER( redclif_prot_r ) -{ - return -0x56 << 8; -} - -static READ16_HANDLER( redclif_prot2_r ) -{ - return 0x55 << 8; -} - -/************************************* - * Squirrel King - *************************************/ -static READ16_HANDLER( squirrel_king_extra_r ) -{ - md_cons_state *state = space.machine().driver_data(); - return state->m_md_cart.squirrel_king_extra; -} - -static WRITE16_HANDLER( squirrel_king_extra_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_md_cart.squirrel_king_extra = data; -} - -/************************************* - * Lion King 2 - *************************************/ -static READ16_HANDLER( lion2_prot1_r ) -{ - md_cons_state *state = space.machine().driver_data(); - return state->m_md_cart.lion2_prot1_data; -} - -static READ16_HANDLER( lion2_prot2_r ) -{ - md_cons_state *state = space.machine().driver_data(); - return state->m_md_cart.lion2_prot2_data; -} - -static WRITE16_HANDLER ( lion2_prot1_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_md_cart.lion2_prot1_data = data; -} - -static WRITE16_HANDLER ( lion2_prot2_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_md_cart.lion2_prot2_data = data; -} - -/************************************* - * Rockman X3 - *************************************/ -static READ16_HANDLER( rx3_extra_r ) -{ - return 0xc; -} - -/************************************* - * King of Fighters 98 - *************************************/ -static READ16_HANDLER( kof98_aa_r ) -{ - return 0xaa00; -} - -static READ16_HANDLER( kof98_0a_r ) -{ - return 0x0a00; -} - -static READ16_HANDLER( kof98_00_r ) -{ - return 0x0000; -} - -/************************************* - * Super Mario Bros 2 - *************************************/ -static READ16_HANDLER( smb2_extra_r ) -{ - return 0xa; -} - -/************************************* - * A Bug's Life - *************************************/ -static READ16_HANDLER( bugl_extra_r ) -{ - return 0x28; -} - -/************************************* - * Linghuan Daoshi Super Magician - * (internal game name Elf Wor) - *************************************/ -static READ16_HANDLER( elfwor_400000_r ) -{ - return 0x5500; -} - -static READ16_HANDLER( elfwor_400002_r ) -{ - return 0x0f00; -} - -static READ16_HANDLER( elfwor_400004_r ) -{ - return 0xc900; -} - -static READ16_HANDLER( elfwor_400006_r ) -{ - return 0x1800; -} - -/************************************* - * Top Fighter - there is more to - * this.. No display at startup etc.. - *************************************/ -static READ16_HANDLER( topfig_6BD294_r ) /* colours on title screen */ -{ - static int x = -1; - - /* - cpu #0 (PC=00177192): unmapped program memory word write to 006BD240 = 00A8 & 00FF - cpu #0 (PC=0017719A): unmapped program memory word write to 006BD2D2 = 0098 & 00FF - cpu #0 (PC=001771A2): unmapped program memory word read from 006BD294 & 00FF - */ - - if (space.device().safe_pc()==0x1771a2) return 0x50; - else - { - x++; - logerror("%06x topfig_6BD294_r %04x\n",space.device().safe_pc(), x); - return x; - } -} - -static READ16_HANDLER( topfig_6F5344_r ) // after char select -{ - static int x = -1; - - if (space.device().safe_pc()==0x4C94E) - { - return space.machine().device("maincpu")->state().state_int((M68K_D0)) & 0xff; - } - else - { - x++; - logerror("%06x topfig_6F5344_r %04x\n",space.device().safe_pc(), x); - return x; - } -} - -static WRITE16_HANDLER( topfig_bank_w ) -{ - UINT8 *ROM = space.machine().root_device().memregion("maincpu")->base(); - if (data == 0x002a) - { - memcpy(ROM + 0x060000, ROM + 0x570000, 0x8000); // == 0x2e*0x8000?! - // printf("%06x offset %06x, data %04x\n",space.device().safe_pc(), offset, data); - - } - else if (data==0x0035) // characters ingame - { - memcpy(ROM + 0x020000, ROM + 0x5a8000, 0x8000); // == 0x35*0x8000 - } - else if (data==0x000f) // special moves - { - memcpy(ROM + 0x058000, ROM + 0x478000, 0x8000); // == 0xf*0x8000 - } - else if (data==0x0000) - { - memcpy(ROM + 0x060000, ROM + 0x460000, 0x8000); - memcpy(ROM + 0x020000, ROM + 0x420000, 0x8000); - memcpy(ROM + 0x058000, ROM + 0x458000, 0x8000); - // printf("%06x offset %06x, data %04x\n",space.device().safe_pc(), offset, data); - } - else - { - logerror("%06x offset %06x, data %04x\n", space.device().safe_pc(), offset, data); - } - -} - -static READ16_HANDLER( topfig_645B44_r ) -{ - //cpu #0 (PC=0004DE00): unmapped program memory word write to 00689B80 = 004A & 00FF - //cpu #0 (PC=0004DE08): unmapped program memory word write to 00 = 00B5 & 00FF - //cpu #0 (PC=0004DE0C): unmapped program memory word read from 00645B44 & 00FF - - return 0x9f;//0x25; -} - -//cpu #0 (PC=0004CBAE): unmapped program memory word read from 006A35D4 & 00FF -- wants regD7 - - - -/************************************* - * 12 in 1 and other multigame carts - *************************************/ -static WRITE16_HANDLER( mc_12in1_bank_w ) -{ - UINT8 *ROM = space.machine().root_device().memregion("maincpu")->base(); - logerror("offset %06x", offset << 17); - memcpy(ROM + 0x000000, ROM + VIRGIN_COPY_GEN + ((offset & 0x3f) << 17), 0x100000); -} - - - -/************************************* - * Stub for TMSS bios bank - *************************************/ -static WRITE16_HANDLER( genesis_TMSS_bank_w ) -{ - /* this probably should do more, like make Genesis V2 'die' if the SEGA string is not written promptly */ -} - -/************************************* - * Pier Solar banking - *************************************/ - -static WRITE16_HANDLER( psolar_bank_w ) -{ - UINT8 *ROM = space.machine().root_device().memregion("maincpu")->base(); - logerror("switch bank %02x, page %02x\n",offset, data); - memcpy(&ROM[0x280000 + (0x80000 * offset)], &ROM[VIRGIN_COPY_GEN + (0x80000 * (data&0x0f))], 0x80000); -} - -static WRITE16_HANDLER( psolar_unk_w ) -{ - logerror("A13001 write %02x\n", data); -} - -static int psolar_rdcnt = 0; - -static READ16_HANDLER( psolar_hack_r ) -{ - // ugly hack until we don't know much about game protection - // first 3 reads from 15e6 return 0x00000010, then normal 0x00018010 value for crc check - UINT16 res; - if (psolar_rdcnt < 6) { - psolar_rdcnt++; - if (offset) - res = 0x10; - else - res = 0x00; - } else { - if (offset) - res = 0x8010; - else - res = 0x0001; - } - logerror("read 0x15e6 %d\n",psolar_rdcnt); - return res; -} -/************************************* - * - * Handlers for SRAM & EEPROM - * - *************************************/ - -/************************************* - * SRAM - *************************************/ -static READ16_HANDLER( genesis_sram_read ) -{ - md_cons_state *state = space.machine().driver_data(); - UINT8 *ROM; - int rom_offset; - - if (state->m_md_cart.sram_active) - return state->m_md_cart.sram[offset]; - else - { - ROM = state->memregion("maincpu")->base(); - rom_offset = state->m_md_cart.sram_start + (offset << 1); - - return (UINT16) ROM[rom_offset] | (ROM[rom_offset + 1] << 8); - } -} - -static WRITE16_HANDLER( genesis_sram_write ) -{ - md_cons_state *state = space.machine().driver_data(); - if (state->m_md_cart.sram_active) - { - if (!state->m_md_cart.sram_readonly) - state->m_md_cart.sram[offset] = data; - } -} - -static void install_sram_rw_handlers(running_machine &machine, bool mask_addr) -{ - md_cons_state *state = machine.driver_data(); - device_image_interface *image = dynamic_cast(machine.device("cart")); - // if sram_start/end come from the cart header, they might be incorrect! from softlist, they are fine. - UINT32 mask = mask_addr ? 0x3fffff : 0xffffff; - - mame_printf_debug("Allocing %d bytes for sram\n", state->m_md_cart.sram_end - state->m_md_cart.sram_start + 1); - state->m_md_cart.sram = auto_alloc_array(machine, UINT16, (state->m_md_cart.sram_end - state->m_md_cart.sram_start + 1) / sizeof(UINT16)); - image->battery_load(state->m_md_cart.sram, state->m_md_cart.sram_end - state->m_md_cart.sram_start + 1, 0xff); // Dino Dini's Soccer needs backup RAM to be 1fill - memcpy(megadriv_backupram, state->m_md_cart.sram, state->m_md_cart.sram_end - state->m_md_cart.sram_start + 1); - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(state->m_md_cart.sram_start & mask, state->m_md_cart.sram_end & mask, FUNC(genesis_sram_read)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(state->m_md_cart.sram_start & mask, state->m_md_cart.sram_end & mask, FUNC(genesis_sram_write)); - state->m_md_cart.sram_handlers_installed = 1; -} - -static WRITE16_HANDLER( genesis_sram_toggle ) -{ - md_cons_state *state = space.machine().driver_data(); - - /* unsure if this is actually supposed to toggle or just switch on? - Yet to encounter game that utilizes */ - state->m_md_cart.sram_active = (data & 1) ? 1 : 0; - state->m_md_cart.sram_readonly = (data & 2) ? 1 : 0; - - if (state->m_md_cart.sram_active && !state->m_md_cart.sram_handlers_installed) - install_sram_rw_handlers(space.machine(), TRUE); -} - -static READ16_HANDLER( sega_6658a_reg_r ) -{ - md_cons_state *state = space.machine().driver_data(); - return state->m_md_cart.sram_active; -} - -static WRITE16_HANDLER( sega_6658a_reg_w ) -{ - md_cons_state *state = space.machine().driver_data(); - if (data == 1) - state->m_md_cart.sram_active = 1; - if (data == 0) - state->m_md_cart.sram_active = 0; -} - -/************************************* - * I2C EEPROM - * bare minimum handlings - * TODO: supports proper device interfacing and parameter change! - *************************************/ - -static READ16_HANDLER( nba_jam_eeprom_r ) -{ - md_cons_state *state = space.machine().driver_data(); -// state->m_md_cart.i2c_mem = (i2cmem_sda_read(space.machine().device("i2cmem")) & 1); - return state->m_md_cart.i2c_mem & 1; -} - -static WRITE16_HANDLER( nba_jam_eeprom_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_md_cart.i2c_clk = (data & 0x0002) >> 1; - state->m_md_cart.i2c_mem = (data & 0x0001); - -// i2cmem_sda_write(space.machine().device("i2cmem"), state->m_md_cart.i2c_clk); -// i2cmem_scl_write(space.machine().device("i2cmem"), state->m_md_cart.i2c_mem); -} - -static READ16_HANDLER( nba_jam_te_eeprom_r ) -{ - md_cons_state *state = space.machine().driver_data(); -// state->m_md_cart.i2c_mem = (i2cmem_sda_read(space.machine().device("i2cmem")) & 1); - return (state->m_md_cart.i2c_mem & 1); -} - -static WRITE16_HANDLER( nba_jam_te_eeprom_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_md_cart.i2c_clk = ((data & 0x0100) >> 8); - state->m_md_cart.i2c_mem = data & 0x0001; - -// i2cmem_sda_write(space.machine().device("i2cmem"), state->m_md_cart.i2c_clk); -// i2cmem_scl_write(space.machine().device("i2cmem"), state->m_md_cart.i2c_mem); -} - -static READ16_HANDLER( ea_nhlpa_eeprom_r ) -{ - md_cons_state *state = space.machine().driver_data(); -// state->m_md_cart.i2c_mem = (i2cmem_sda_read(space.machine().device("i2cmem")) & 1); - return (state->m_md_cart.i2c_mem & 1) << 7; -} - -static WRITE16_HANDLER( ea_nhlpa_eeprom_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_md_cart.i2c_clk = ((data & 0x0040) >> 6); - state->m_md_cart.i2c_mem = ((data & 0x0080) >> 7); - -// i2cmem_sda_write(space.machine().device("i2cmem"), state->m_md_cart.i2c_clk); -// i2cmem_scl_write(space.machine().device("i2cmem"), state->m_md_cart.i2c_mem); -} - -/* TODO: identical as NBA Jam, used as kludge */ -static READ16_HANDLER( wboy_v_eeprom_r ) -{ - md_cons_state *state = space.machine().driver_data(); -// state->m_md_cart.i2c_mem = (i2cmem_sda_read(space.machine().device("i2cmem")) & 1); - return ~state->m_md_cart.i2c_mem & 1; -} - -static WRITE16_HANDLER( wboy_v_eeprom_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_md_cart.i2c_clk = (data & 0x0002) >> 1; - state->m_md_cart.i2c_mem = (data & 0x0001); - -// i2cmem_sda_write(space.machine().device("i2cmem"), state->m_md_cart.i2c_clk); -// i2cmem_scl_write(space.machine().device("i2cmem"), state->m_md_cart.i2c_mem); -} - -static READ16_HANDLER( codemasters_eeprom_r ) -{ - md_cons_state *state = space.machine().driver_data(); -// state->m_md_cart.i2c_mem = (i2cmem_sda_read(space.machine().device("i2cmem")) & 1); - return (state->m_md_cart.i2c_mem & 1) << 7; -} - -static WRITE16_HANDLER( codemasters_eeprom_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_md_cart.i2c_clk = (data & 0x0200) >> 9; - state->m_md_cart.i2c_mem = (data & 0x0100) >> 8; - -// i2cmem_sda_write(space.machine().device("i2cmem"), state->m_md_cart.i2c_clk); -// i2cmem_scl_write(space.machine().device("i2cmem"), state->m_md_cart.i2c_mem); -} - -/* ST M95320 32Kbit serial EEPROM implementation */ - -#define M95320_SIZE 0x1000 -enum STMSTATE -{ - IDLE = 0, - CMD_WRSR, - CMD_RDSR, - M95320_CMD_READ, - CMD_WRITE, - READING, - WRITING -}; - -class stm95_device -{ -public: - stm95_device() : stm_state(IDLE), stream_pos(0) {}; - UINT8 *eeprom_data; - void set_cs_line(int); - void set_halt_line(int state) {}; // not implemented - void set_si_line(int); - void set_sck_line(int state); - int get_so_line(void); -protected: - int latch; - int reset_line; - int sck_line; - int WEL; - - STMSTATE stm_state; - int stream_pos; - int stream_data; - int eeprom_addr; -}; - -void stm95_device::set_cs_line(int state) -{ - reset_line = state; - if (reset_line != CLEAR_LINE) - { - stream_pos = 0; - stm_state = IDLE; - } -} - -void stm95_device::set_si_line(int state) -{ - latch = state; -} - -int stm95_device::get_so_line(void) -{ - if (stm_state == READING || stm_state == CMD_RDSR) - return (stream_data >> 8) & 1; - else - return 0; -} - -void stm95_device::set_sck_line(int state) -{ - if (reset_line == CLEAR_LINE) - { - if (state == ASSERT_LINE && sck_line == CLEAR_LINE) - { - switch (stm_state) - { - case IDLE: - stream_data = (stream_data << 1) | (latch ? 1 : 0); - stream_pos++; - if (stream_pos == 8) - { - stream_pos = 0; - //printf("STM95 EEPROM: got cmd %02X\n", stream_data&0xff); - switch(stream_data & 0xff) - { - case 0x01: // write status register - if (WEL != 0) - stm_state = CMD_WRSR; - WEL = 0; - break; - case 0x02: // write - if (WEL != 0) - stm_state = CMD_WRITE; - stream_data = 0; - WEL = 0; - break; - case 0x03: // read - stm_state = M95320_CMD_READ; - stream_data = 0; - break; - case 0x04: // write disable - WEL = 0; - break; - case 0x05: // read status register - stm_state = CMD_RDSR; - stream_data = WEL<<1; - break; - case 0x06: // write enable - WEL = 1; - break; - default: - logerror("STM95 EEPROM: unknown cmd %02X\n", stream_data&0xff); - } - } - break; - case CMD_WRSR: - stream_pos++; // just skip, don't care block protection - if (stream_pos == 8) - { - stm_state = IDLE; - stream_pos = 0; - } - break; - case CMD_RDSR: - stream_data = stream_data<<1; - stream_pos++; - if (stream_pos == 8) - { - stm_state = IDLE; - stream_pos = 0; - } - break; - case M95320_CMD_READ: - stream_data = (stream_data << 1) | (latch ? 1 : 0); - stream_pos++; - if (stream_pos == 16) - { - eeprom_addr = stream_data & (M95320_SIZE - 1); - stream_data = eeprom_data[eeprom_addr]; - stm_state = READING; - stream_pos = 0; - } - break; - case READING: - stream_data = stream_data<<1; - stream_pos++; - if (stream_pos == 8) - { - if (++eeprom_addr == M95320_SIZE) - eeprom_addr = 0; - stream_data |= eeprom_data[eeprom_addr]; - stream_pos = 0; - } - break; - case CMD_WRITE: - stream_data = (stream_data << 1) | (latch ? 1 : 0); - stream_pos++; - if (stream_pos == 16) - { - eeprom_addr = stream_data & (M95320_SIZE - 1); - stm_state = WRITING; - stream_pos = 0; - } - break; - case WRITING: - stream_data = (stream_data << 1) | (latch ? 1 : 0); - stream_pos++; - if (stream_pos == 8) - { - eeprom_data[eeprom_addr] = stream_data; - if (++eeprom_addr == M95320_SIZE) - eeprom_addr = 0; - stream_pos = 0; - } - break; - } - } - } - sck_line = state; -} - -stm95_device STM95; - -static READ16_HANDLER( psolar_eeprom_r ) -{ - return STM95.get_so_line() & 1; -} - -static WRITE16_HANDLER( psolar_eeprom_w ) -{ - STM95.set_si_line(data & 0x01); - STM95.set_cs_line((data & 0x08)?ASSERT_LINE:CLEAR_LINE); - STM95.set_halt_line((data & 0x04)?ASSERT_LINE:CLEAR_LINE); - STM95.set_sck_line((data & 0x02)?ASSERT_LINE:CLEAR_LINE); -} - -/************************************* - * - * Machine driver reset - * - *************************************/ - -static void setup_megadriv_custom_mappers(running_machine &machine) -{ - md_cons_state *state = machine.driver_data(); - UINT32 mirroraddr; - UINT8 *ROM = state->memregion("maincpu")->base(); - - switch (state->m_md_cart.type) - { - case CM_JCART: - case CM_JCART_SEPROM: - /* Codemasters PCB (J-Carts) */ - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x38fffe, 0x38ffff, FUNC(jcart_ctrl_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x38fffe, 0x38ffff, FUNC(jcart_ctrl_w)); - break; - - case SSF2: - memcpy(&ROM[0x800000], &ROM[VIRGIN_COPY_GEN + 0x400000], 0x100000); - memcpy(&ROM[0x400000], &ROM[VIRGIN_COPY_GEN], 0x400000); - memcpy(&ROM[0x000000], &ROM[VIRGIN_COPY_GEN], 0x400000); - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xa130f0, 0xa130ff, FUNC(genesis_ssf2_bank_w)); - break; - - case LIONK3: - case SKINGKONG: - state->m_md_cart.l3alt_pdat = state->m_md_cart.l3alt_pcmd = 0; - memcpy(&ROM[0x000000], &ROM[VIRGIN_COPY_GEN], 0x200000); /* default rom */ - memcpy(&ROM[0x200000], &ROM[VIRGIN_COPY_GEN], 0x200000); /* default rom */ - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x600000, 0x6fffff, FUNC(l3alt_prot_r), FUNC(l3alt_prot_w)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x700000, 0x7fffff, FUNC(l3alt_bank_w)); - break; - - case SDK99: - state->m_md_cart.l3alt_pdat = state->m_md_cart.l3alt_pcmd = 0; - - memcpy(&ROM[0x000000], &ROM[VIRGIN_COPY_GEN], 0x300000); /* default rom */ - memcpy(&ROM[0x300000], &ROM[VIRGIN_COPY_GEN], 0x100000); /* default rom */ - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x600000, 0x6fffff, FUNC(l3alt_prot_r), FUNC(l3alt_prot_w)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x700000, 0x7fffff, FUNC(l3alt_bank_w)); - break; - - case REDCLIFF: - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400000, 0x400001, FUNC(redclif_prot2_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400004, 0x400005, FUNC(redclif_prot_r)); - break; - - case REDCL_EN: - for (int x = VIRGIN_COPY_GEN; x < VIRGIN_COPY_GEN + 0x200005; x++) - ROM[x] ^= 0x40; - memcpy(&ROM[0x000000], &ROM[VIRGIN_COPY_GEN + 4], 0x200000); /* default rom */ - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400000, 0x400001, FUNC(redclif_prot2_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400004, 0x400005, FUNC(redclif_prot_r)); - break; - - case RADICA: - memcpy(&ROM[0x000000], &ROM[VIRGIN_COPY_GEN], 0x400000); - memcpy(&ROM[0x400000], &ROM[VIRGIN_COPY_GEN], 0x400000); // keep a copy for later banking.. making use of huge ROM_REGION allocated to genesis driver - memcpy(&ROM[0x800000], &ROM[VIRGIN_COPY_GEN], 0x400000); // wraparound banking (from hazemd code) - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xa13000, 0xa1307f, FUNC(radica_bank_select)); - break; - - case KOF99: - //memcpy(&ROM[0x000000],&ROM[VIRGIN_COPY_GEN],0x300000); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xa13000, 0xa13001, FUNC(kof99_A13000_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xa13002, 0xa13003, FUNC(kof99_A13002_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xa1303e, 0xa1303f, FUNC(kof99_00A1303E_r)); - break; - - case SOULBLAD: - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400002, 0x400003, FUNC(soulb_400002_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400004, 0x400005, FUNC(soulb_400004_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400006, 0x400007, FUNC(soulb_400006_r)); - break; - - case MJLOVER: - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400000, 0x400001, FUNC(mjlovr_prot_1_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x401000, 0x401001, FUNC(mjlovr_prot_2_r)); - break; - - case SQUIRRELK: - state->m_md_cart.squirrel_king_extra = 0; - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400000, 0x400007, FUNC(squirrel_king_extra_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x400000, 0x400007, FUNC(squirrel_king_extra_w)); - break; - - case SMOUSE: - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400000, 0x400007, FUNC(smous_prot_r)); - break; - - case SMB: - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xa13000, 0xa13001, FUNC(smbro_prot_r)); - break; - - case SMB2: - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xa13000, 0xa13001, FUNC(smb2_extra_r)); - break; - - case KAIJU: - memcpy(&ROM[0x400000], &ROM[VIRGIN_COPY_GEN], 0x200000); - memcpy(&ROM[0x600000], &ROM[VIRGIN_COPY_GEN], 0x200000); - memcpy(&ROM[0x000000], &ROM[VIRGIN_COPY_GEN], 0x200000); - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x700000, 0x7fffff, FUNC(kaiju_bank_w)); - break; - - case CHINFIGHT3: - memcpy(&ROM[0x400000], &ROM[VIRGIN_COPY_GEN], 0x200000); - memcpy(&ROM[0x600000], &ROM[VIRGIN_COPY_GEN], 0x200000); - memcpy(&ROM[0x000000], &ROM[VIRGIN_COPY_GEN], 0x200000); - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400000, 0x4fffff, FUNC(chifi3_prot_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x600000, 0x6fffff, FUNC(chifi3_bank_w)); - break; - - case LIONK2: - state->m_md_cart.lion2_prot1_data = state->m_md_cart.lion2_prot2_data = 0; - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400002, 0x400003, FUNC(lion2_prot1_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400006, 0x400007, FUNC(lion2_prot2_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x400000, 0x400001, FUNC(lion2_prot1_w)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x400004, 0x400005, FUNC(lion2_prot2_w)); - break; - - case BUGSLIFE: - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xa13000, 0xa13001, FUNC(bugl_extra_r)); - break; - - case ELFWOR: - /* It return (0x55 @ 0x400000 OR 0xc9 @ 0x400004) AND (0x0f @ 0x400002 OR 0x18 @ 0x400006). It is probably best to add handlers for all 4 addresses. */ - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400000, 0x400001, FUNC(elfwor_400000_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400002, 0x400003, FUNC(elfwor_400002_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400004, 0x400005, FUNC(elfwor_400004_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400006, 0x400007, FUNC(elfwor_400006_r)); - break; - - case ROCKMANX3: - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xa13000, 0xa13001, FUNC(rx3_extra_r)); - break; - - case SBUBBOB: - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400000, 0x400001, FUNC(sbub_extra1_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x400002, 0x400003, FUNC(sbub_extra2_r)); - break; - - case KOF98: - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x480000, 0x480001, FUNC(kof98_aa_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x4800e0, 0x4800e1, FUNC(kof98_aa_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x4824a0, 0x4824a1, FUNC(kof98_aa_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x488880, 0x488881, FUNC(kof98_aa_r)); - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x4a8820, 0x4a8821, FUNC(kof98_0a_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x4f8820, 0x4f8821, FUNC(kof98_00_r)); - break; - - case REALTEC: - /* Realtec mapper!*/ - state->m_md_cart.realtec_bank_addr = state->m_md_cart.realtec_bank_size = 0; - state->m_md_cart.realtec_old_bank_addr = -1; - - memcpy(&ROM[0x400000], &ROM[VIRGIN_COPY_GEN], 0x80000); - - for (mirroraddr = 0; mirroraddr < 0x400000; mirroraddr += 0x2000) - memcpy(ROM + mirroraddr, ROM + VIRGIN_COPY_GEN + 0x7e000, 0x002000); /* copy last 8kb across the whole rom region */ - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x400000, 0x400001, FUNC(realtec_400000_w)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x402000, 0x402001, FUNC(realtec_402000_w)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x404000, 0x404001, FUNC(realtec_404000_w)); - break; - - case MC_SUP19IN1: - memcpy(&ROM[0x400000], &ROM[VIRGIN_COPY_GEN], 0x400000); // allow hard reset to menu - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xa13000, 0xa13039, FUNC(s19in1_bank)); - break; - - case MC_SUP15IN1: - memcpy(&ROM[0x400000], &ROM[VIRGIN_COPY_GEN], 0x200000); // allow hard reset to menu - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xa13000, 0xa13039, FUNC(s19in1_bank)); - break; - - case MC_12IN1: - memcpy(&ROM[0x000000], &ROM[VIRGIN_COPY_GEN], 0x400000); /* default rom */ - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xa13000, 0xa1303f, FUNC(mc_12in1_bank_w)); - break; - - case TOPFIGHTER: - memcpy(&ROM[0x000000], &ROM[VIRGIN_COPY_GEN], 0x400000); /* default rom */ - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x6f5344, 0x6f5345, FUNC(topfig_6F5344_r) ); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x6bd294, 0x6bd295, FUNC(topfig_6BD294_r) ); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x645b44, 0x645b45, FUNC(topfig_645B44_r) ); - - /* readd */ - //machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x689b80, 0x689b81, FUNC(MWA16_NOP)); - //machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x6d8b02, 0x6d8b03, FUNC(MWA16_NOP)); - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x700000, 0x7fffff, FUNC(topfig_bank_w) ); - break; - case PSOLAR: - memcpy(&ROM[0x000000], &ROM[VIRGIN_COPY_GEN], 0x400000); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xa13002, 0xa13007, FUNC(psolar_bank_w)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xa13000, 0xa13001, FUNC(psolar_unk_w)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x0015e6, 0x0015e9, FUNC(psolar_hack_r)); - psolar_rdcnt = 0; - break; - } - - /* games whose protection gets patched out */ - - if (state->m_md_cart.type == POKEMON) - { - /*todo: emulate protection instead - 0DD19E:47F8 - 0DD1A0:FFF0 - 0DD1A2:4E63 - 0DD46E:4EF8 - 0DD470:0300 - 0DD49C:6002 - */ - - /* - - you need to return 1 @ 0xa13002 and 0???1f @ 0xa1303E (it does word reads). - - */ - UINT16 *ROM16 = (UINT16 *)machine.root_device().memregion("maincpu")->base(); - - ROM16[0x0dd19e/2] = 0x47F8; - ROM16[0x0dd1a0/2] = 0xFFF0; - ROM16[0x0dd1a2/2] = 0x4E63; - ROM16[0x0dd46e/2] = 0x4EF8; - ROM16[0x0dd470/2] = 0x0300; - ROM16[0x0dd49c/2] = 0x6002; - } - - if (state->m_md_cart.type == POKEMON2) - { - /*todo: emulate protection instead - 006036:E000 - 002540:6026 - 001ED0:6026 - 002476:6022 - - */ - UINT16 *ROM16 = (UINT16 *)machine.root_device().memregion("maincpu")->base(); - - ROM16[0x06036/2] = 0xE000; - ROM16[0x02540/2] = 0x6026; - ROM16[0x01ED0/2] = 0x6026; - ROM16[0x02476/2] = 0x6022; - - ROM16[0x7E300/2] = 0x60FE; - } - - if (state->m_md_cart.type == MULAN) - { - /*todo: emulate protection instead - 006036:E000 - +more? - - */ - // ROM[0x01ED0/2] = 0xE000; - // ROM[0x02540/2] = 0xE000; - - UINT16 *ROM16 = (UINT16 *)machine.root_device().memregion("maincpu")->base(); - - ROM16[0x06036/2] = 0xE000; - } - - /* install NOP handler for TMSS */ - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xa14000, 0xa14003, FUNC(genesis_TMSS_bank_w)); -} - -static void setup_megadriv_sram(device_image_interface &image) -{ - running_machine &machine = image.device().machine(); - md_cons_state *state = machine.driver_data(); - UINT8 *ROM = state->memregion("maincpu")->base(); - megadriv_backupram = NULL; - state->m_md_cart.sram = NULL; - state->m_md_cart.sram_start = state->m_md_cart.sram_end = 0; - state->m_md_cart.has_serial_eeprom = 0; - state->m_md_cart.sram_detected = 0; - state->m_md_cart.sram_handlers_installed = 0; - state->m_md_cart.sram_readonly = 0; - state->m_md_cart.sram_active = 0; - - /* install SRAM & i2c handlers for the specific type of cart */ - switch (state->m_md_cart.type) - { - // These types only come from xml - // TODO: Eventually megadriv_backupram should point to the allocated cart:sram region! - // For now, we only use the region as a placeholder to carry size info... - case SEGA_SRAM: - state->m_md_cart.sram_start = 0x200000; - state->m_md_cart.sram_end = state->m_md_cart.sram_start + image.get_software_region_length("sram") - 1; - state->m_md_cart.sram_detected = 1; - megadriv_backupram = (UINT16*) (ROM + state->m_md_cart.sram_start); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xa130f0, 0xa130f1, FUNC(genesis_sram_toggle)); - if (state->m_md_cart.last_loaded_image_length <= state->m_md_cart.sram_start) - { - state->m_md_cart.sram_active = 1; - install_sram_rw_handlers(machine, FALSE); - } - break; - - case BEGGAR: - state->m_md_cart.sram_start = 0x400000; - state->m_md_cart.sram_end = state->m_md_cart.sram_start + 0xffff; - state->m_md_cart.sram_detected = 1; - state->m_md_cart.sram_active = 1; - megadriv_backupram = (UINT16*) (ROM + state->m_md_cart.sram_start); - install_sram_rw_handlers(machine, FALSE); - break; - - case SEGA_FRAM: - state->m_md_cart.sram_start = 0x200000; - state->m_md_cart.sram_end = state->m_md_cart.sram_start + image.get_software_region_length("fram") - 1; - state->m_md_cart.sram_detected = 1; - megadriv_backupram = (UINT16*) (ROM + state->m_md_cart.sram_start); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xa130f0, 0xa130f1, FUNC(sega_6658a_reg_r)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xa130f0, 0xa130f1, FUNC(sega_6658a_reg_w)); - install_sram_rw_handlers(machine, FALSE); - break; - - // These types might come either from xml or from old-styele loading - case SEGA_EEPROM: - state->m_md_cart.has_serial_eeprom = 1; - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x200000, 0x200001, FUNC(wboy_v_eeprom_r), FUNC(wboy_v_eeprom_w)); - break; - - case NBA_JAM: - state->m_md_cart.has_serial_eeprom = 1; - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x200000, 0x200001, FUNC(nba_jam_eeprom_r), FUNC(nba_jam_eeprom_w)); - break; - - case NBA_JAM_TE: - case NFL_QB_96: - case C_SLAM: // same handling but different sizes - state->m_md_cart.has_serial_eeprom = 1; - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x200000, 0x200001, FUNC(nba_jam_te_eeprom_r), FUNC(nba_jam_te_eeprom_w)); - break; - - case EA_NHLPA: - state->m_md_cart.has_serial_eeprom = 1; - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x200000, 0x200001, FUNC(ea_nhlpa_eeprom_r), FUNC(ea_nhlpa_eeprom_w)); - break; - - case CODE_MASTERS: - case CM_JCART_SEPROM: - state->m_md_cart.has_serial_eeprom = 1; - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x300000, 0x300001, FUNC(codemasters_eeprom_w)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x380000, 0x380001, FUNC(codemasters_eeprom_r)); - break; - case PSOLAR: - state->m_md_cart.sram_start = 0x800000; - state->m_md_cart.sram_end = state->m_md_cart.sram_start + M95320_SIZE - 1; - state->m_md_cart.sram = auto_alloc_array(machine, UINT16, M95320_SIZE / sizeof(UINT16)); - image.battery_load(state->m_md_cart.sram, M95320_SIZE, 0xff); - STM95.eeprom_data = (UINT8*)state->m_md_cart.sram; - - state->m_md_cart.has_serial_eeprom = 1; - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xa13008, 0xa13009, FUNC(psolar_eeprom_w)); - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xa1300a, 0xa1300b, FUNC(psolar_eeprom_r)); - break; - } - - // If the cart is not of a special type, we check the header. Unfortunately, there are ROMs without correct info in the header, - // hence we do the mapping anyway, but we activate SRAM later only if the game will access it. - if (!state->m_md_cart.sram_detected && !state->m_md_cart.has_serial_eeprom) - { - /* check if cart has battery save */ - if (ROM[0x1b1] == 'R' && ROM[0x1b0] == 'A') - { - /* SRAM info found in header */ - state->m_md_cart.sram_start = (ROM[0x1b5] << 24 | ROM[0x1b4] << 16 | ROM[0x1b7] << 8 | ROM[0x1b6]); - state->m_md_cart.sram_end = (ROM[0x1b9] << 24 | ROM[0x1b8] << 16 | ROM[0x1bb] << 8 | ROM[0x1ba]); - - if ((state->m_md_cart.sram_start > state->m_md_cart.sram_end) || ((state->m_md_cart.sram_end - state->m_md_cart.sram_start) >= 0x10000)) // we assume at most 64k of SRAM (HazeMD uses at most 64k). is this correct? - state->m_md_cart.sram_end = state->m_md_cart.sram_start + 0x0FFFF; - - /* for some games using serial EEPROM, difference between SRAM - end to start is 0 or 1. Currently EEPROM is not emulated. */ - if ((state->m_md_cart.sram_end - state->m_md_cart.sram_start) < 2) - state->m_md_cart.has_serial_eeprom = 1; - else - state->m_md_cart.sram_detected = 1; - } - else - { - /* set default SRAM positions, with size = 64k */ - state->m_md_cart.sram_start = 0x200000; - state->m_md_cart.sram_end = state->m_md_cart.sram_start + 0xffff; - } - - if (state->m_md_cart.sram_start & 1) - state->m_md_cart.sram_start -= 1; - - if (!(state->m_md_cart.sram_end & 1)) - state->m_md_cart.sram_end += 1; - - /* calculate backup RAM location */ - megadriv_backupram = (UINT16*) (ROM + (state->m_md_cart.sram_start & 0x3fffff)); - - if (state->m_md_cart.sram_detected) - logerror("SRAM detected from header: starting location %X - SRAM Length %X\n", state->m_md_cart.sram_start, state->m_md_cart.sram_end - state->m_md_cart.sram_start + 1); - - /* Enable SRAM handlers only if the game does not use EEPROM. */ - if (!state->m_md_cart.has_serial_eeprom) - { - /* Info from DGen: If SRAM does not overlap main ROM, set it active by - default since a few games can't manage to properly switch it on/off. */ - if (state->m_md_cart.last_loaded_image_length <= state->m_md_cart.sram_start) - state->m_md_cart.sram_active = 1; - - machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xa130f0, 0xa130f1, FUNC(genesis_sram_toggle)); - //printf("res: start %x, end %x, det %d, active %d\n", state->m_md_cart.sram_start, state->m_md_cart.sram_end, state->m_md_cart.sram_detected, state->m_md_cart.sram_active); - - /* Sonic 1 included in Sonic Classics doesn't have SRAM and - does lots of ROM access at this range, then only install read/ - write handlers if SRAM is active to not slow down emulation. */ - if (state->m_md_cart.sram_active) - install_sram_rw_handlers(machine, TRUE); - } - } -} - -/************************************* - * - * CART HANDLING - * - *************************************/ - - -/************************************* - * Helper function: Memcmp for both - * endianness - *************************************/ - -static int allendianmemcmp(const void *s1, const void *s2, size_t n) -{ - const unsigned char *realbuf; - -#ifdef LSB_FIRST - unsigned char flippedbuf[64]; - unsigned int i; - - if ((n & 1) || (n > 63)) return -1 ; // don't want odd sized buffers or too large a compare - for (i = 0; i < n; i++) flippedbuf[i] = *((char *)s2 + (i ^ 1)); - realbuf = flippedbuf; - -#else - - realbuf = (unsigned char *)s2; - -#endif - return memcmp(s1,realbuf,n); -} - - -/************************************* - * Helper function: Detect SMD file - *************************************/ - -/* code taken directly from GoodGEN by Cowering */ -static int genesis_is_funky_SMD(unsigned char *buf,unsigned int len) -{ - /* aq quiz */ - if (!strncmp("UZ(-01 ", (const char *) &buf[0xf0], 8)) - return 1; - - /* Phelios USA redump */ - /* target earth */ - /* klax (namcot) */ - if (buf[0x2080] == ' ' && buf[0x0080] == 'S' && buf[0x2081] == 'E' && buf[0x0081] == 'G') - return 1; - - /* jap baseball 94 */ - if (!strncmp("OL R-AEAL", (const char *) &buf[0xf0], 9)) - return 1; - - /* devilish Mahjong Tower */ - if (!strncmp("optrEtranet", (const char *) &buf[0xf3], 11)) - return 1; - - /* golden axe 2 beta */ - if (buf[0x0100] == 0x3c && buf[0x0101] == 0 && buf[0x0102] == 0 && buf[0x0103] == 0x3c) - return 1; - - /* omega race */ - if (!strncmp("OEARC ", (const char *) &buf[0x90], 8)) - return 1; - - /* budokan beta */ - if ((len >= 0x6708+8) && !strncmp(" NTEBDKN", (const char *) &buf[0x6708], 8)) - return 1; - - /* cdx pro 1.8 bios */ - if (!strncmp("so fCXP", (const char *) &buf[0x2c0], 7)) - return 1; - - /* ishido (hacked) */ - if (!strncmp("sio-Wyo ", (const char *) &buf[0x0090], 8)) - return 1; - - /* onslaught */ - if (!strncmp("SS CAL ", (const char *) &buf[0x0088], 8)) - return 1; - - /* tram terror pirate */ - if ((len >= 0x3648 + 8) && !strncmp("SG NEPIE", (const char *) &buf[0x3648], 8)) - return 1; - - /* breath of fire 3 chinese */ - if (buf[0x0007] == 0x1c && buf[0x0008] == 0x0a && buf[0x0009] == 0xb8 && buf[0x000a] == 0x0a) - return 1; - - /*tetris pirate */ - if ((len >= 0x1cbe + 5) && !strncmp("@TTI>", (const char *) &buf[0x1cbe], 5)) - return 1; - - return 0; -} - -/* code taken directly from GoodGEN by Cowering */ -static int genesis_is_SMD(unsigned char *buf,unsigned int len) -{ - if (buf[0x2080] == 'S' && buf[0x80] == 'E' && buf[0x2081] == 'G' && buf[0x81] == 'A') - return 1; - return genesis_is_funky_SMD(buf,len); -} - -/************************************* - * Loading a cart image *not* from - * softlist - *************************************/ - -static int megadrive_load_nonlist(device_image_interface &image) -{ - md_cons_state *state = image.device().machine().driver_data(); - unsigned char *ROM, *rawROM, *tmpROMnew, *tmpROM, *secondhalf; - int relocate, length, ptr, x; -#ifdef LSB_FIRST - unsigned char fliptemp; -#endif - - // STEP 1: determine the file type (SMD? MD? BIN?) - rawROM = state->memregion("maincpu")->base(); - ROM = rawROM /*+ 512 */; - - state->m_md_cart.last_loaded_image_length = -1; - - length = image.fread( rawROM + 0x2000, 0x800000); - - logerror("image length = 0x%x\n", length); - - /* is this a SMD file? */ - if (genesis_is_SMD(&rawROM[0x2200], (unsigned)length)) - { -// printf("SMD!\n"); - tmpROMnew = ROM; - tmpROM = ROM + 0x2000 + 512; - - for (ptr = 0; ptr < MAX_MD_CART_SIZE / (8192); ptr += 2) - { - for (x = 0; x < 8192; x++) - { - *tmpROMnew++ = *(tmpROM + ((ptr + 1) * 8192) + x); - *tmpROMnew++ = *(tmpROM + ((ptr + 0) * 8192) + x); - } - } - -#ifdef LSB_FIRST - tmpROMnew = ROM; - for (ptr = 0; ptr < length; ptr += 2) - { - fliptemp = tmpROMnew[ptr]; - tmpROMnew[ptr] = tmpROMnew[ptr + 1]; - tmpROMnew[ptr + 1] = fliptemp; - } -#endif - state->m_md_cart.last_loaded_image_length = length - 512; - memcpy(&ROM[VIRGIN_COPY_GEN], &ROM[0x000000], MAX_MD_CART_SIZE); /* store a copy of data */ - - relocate = 0; - - } - /* is this a MD file? */ - else if ((rawROM[0x2080] == 'E') && (rawROM[0x2081] == 'A') && - (rawROM[0x2082] == 'M' || rawROM[0x2082] == 'G')) - { -// printf("MD!\n"); - tmpROMnew = global_alloc_array(unsigned char, length); - secondhalf = &tmpROMnew[length >> 1]; - - if (!tmpROMnew) - { - logerror("Memory allocation failed reading roms!\n"); - return IMAGE_INIT_FAIL; - } - - memcpy(tmpROMnew, ROM + 0x2000, length); - for (ptr = 0; ptr < length; ptr += 2) - { - ROM[ptr] = secondhalf[ptr >> 1]; - ROM[ptr + 1] = tmpROMnew[ptr >> 1]; - } - global_free(tmpROMnew); - -#ifdef LSB_FIRST - for (ptr = 0; ptr < length; ptr += 2) - { - fliptemp = ROM[ptr]; - ROM[ptr] = ROM[ptr+1]; - ROM[ptr+1] = fliptemp; - } -#endif - state->m_md_cart.last_loaded_image_length = length; - memcpy(&ROM[VIRGIN_COPY_GEN], &ROM[0x000000], MAX_MD_CART_SIZE); /* store a copy of data */ - relocate = 0; - - } - /* BIN it is, then */ - else - { - relocate = 0x2000; - state->m_md_cart.last_loaded_image_length = length; - - for (ptr = 0; ptr < MAX_MD_CART_SIZE + relocate; ptr += 2) /* mangle bytes for little endian machines */ - { -#ifdef LSB_FIRST - int temp = ROM[relocate + ptr]; - - ROM[ptr] = ROM[relocate + ptr + 1]; - ROM[ptr + 1] = temp; -#else - ROM[ptr] = ROM[relocate + ptr]; - ROM[ptr + 1] = ROM[relocate + ptr + 1]; -#endif - } - - memcpy(&ROM[VIRGIN_COPY_GEN], &ROM[0x000000], MAX_MD_CART_SIZE); /* store a copy of data */ - } - - // STEP 2: determine the cart type (to deal with pirate mappers & eeprom) - - /* Default cartridge type */ - state->m_md_cart.type = SEGA_STD; - - /* Detect carts which need additional handlers */ - { - static const unsigned char smouse_sig[] = { 0x4d, 0xf9, 0x00, 0x40, 0x00, 0x02 }, - mjlover_sig[] = { 0x13, 0xf9, 0x00, 0x40, 0x00, 0x00 }, // move.b ($400000).l,($FFFF0C).l (partial) - squir_sig[] = { 0x26, 0x79, 0x00, 0xff, 0x00, 0xfa }, - bugsl_sig[] = { 0x20, 0x12, 0x13, 0xc0, 0x00, 0xff }, - sbub_sig[] = { 0x0c, 0x39, 0x00, 0x55, 0x00, 0x40 }, // cmpi.b #$55,($400000).l - lk3_sig[] = { 0x0c, 0x01, 0x00, 0x30, 0x66, 0xe4 }, - sdk_sig[] = { 0x48, 0xe7, 0xff, 0xfe, 0x52, 0x79 }, - redcliff_sig[] = { 0x10, 0x39, 0x00, 0x40, 0x00, 0x04 }, // move.b ($400004).l,d0 - redcl_en_sig[] = { 0x50, 0x79, 0x40, 0x00, 0x40, 0x44 }, // move.b ($400004).l,d0 - smb_sig[] = { 0x20, 0x4d, 0x41, 0x52, 0x49, 0x4f }, - smb2_sig[] = { 0x4e, 0xb9, 0x00, 0x0f, 0x25, 0x84 }, - kaiju_sig[] = { 0x19, 0x7c, 0x00, 0x01, 0x00, 0x00 }, - chifi3_sig[] = { 0xb6, 0x16, 0x66, 0x00, 0x00, 0x4a }, - lionk2_sig[] = { 0x26, 0x79, 0x00, 0xff, 0x00, 0xf4 }, - rx3_sig[] = { 0x66, 0x00, 0x00, 0x0e, 0x30, 0x3c }, - kof98_sig[] = { 0x9b, 0xfc, 0x00, 0x00, 0x4a, 0x00 }, - s15in1_sig[] = { 0x22, 0x3c, 0x00, 0xa1, 0x30, 0x00 }, - kof99_sig[] = { 0x20, 0x3c, 0x30, 0x00, 0x00, 0xa1 }, // move.l #$300000A1,d0 - radica_sig[] = { 0x4e, 0xd0, 0x30, 0x39, 0x00, 0xa1 }, // jmp (a0) move.w ($a130xx),d0 - soulb_sig[] = { 0x33, 0xfc, 0x00, 0x0c, 0x00, 0xff }, // move.w #$C,($FF020A).l (what happens if check fails) - s19in1_sig[] = { 0x13, 0xc0, 0x00, 0xa1, 0x30, 0x38 }, - rockman_sig[] = { 0xea, 0x80 }; - - switch (state->m_md_cart.last_loaded_image_length) - { - case 0x80000: - if (!allendianmemcmp(&ROM[0x08c8], &smouse_sig[0], sizeof(smouse_sig))) - state->m_md_cart.type = SMOUSE; - - if (!allendianmemcmp((char *)&ROM[0x7e30e], "SEGA", 4) || - !allendianmemcmp((char *)&ROM[0x7e100], "SEGA", 4) || - !allendianmemcmp((char *)&ROM[0x7e1e6], "SEGA", 4)) - state->m_md_cart.type = REALTEC; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM T-50396", 10)) // NHLPA Hockey 93 - state->m_md_cart.type = EA_NHLPA; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM MK-1215", 10)) // Evander Holyfield - state->m_md_cart.type = SEGA_EEPROM; - - break; - - case 0xc0000: - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM G-4060 ", 8)) // Wonder Boy V - state->m_md_cart.type = SEGA_EEPROM; - - break; - - case 0x100000: - if (!allendianmemcmp(&ROM[0x01b24], &mjlover_sig[0], sizeof(mjlover_sig))) - state->m_md_cart.type = MJLOVER; - - if (!allendianmemcmp(&ROM[0x03b4], &squir_sig[0], sizeof(squir_sig))) - state->m_md_cart.type = SQUIRRELK; - - if (!allendianmemcmp(&ROM[0xee0d0], &bugsl_sig[0], sizeof(bugsl_sig))) - state->m_md_cart.type = BUGSLIFE; - - if (!allendianmemcmp((char *)&ROM[0x0172], "GAME : ELF WOR", 14)) - state->m_md_cart.type = ELFWOR; - - if (!allendianmemcmp(&ROM[0x123e4], &sbub_sig[0], sizeof(sbub_sig))) - state->m_md_cart.type = SBUBBOB; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM T-50176", 10)) // Rings of Power - state->m_md_cart.type = EA_NHLPA; - - if (!allendianmemcmp((char *)&ROM[0x0180], "MK 00001211-00", 14)) // Sports Talk Baseball - state->m_md_cart.type = SEGA_EEPROM; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM T-120096-", 12)) // Micro Machines 2 - state->m_md_cart.type = CODE_MASTERS; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM T-120146-", 12)) // Brian Lara Cricket 96 / Shane Wayne Cricket 96 - state->m_md_cart.type = CODE_MASTERS; - - if (!allendianmemcmp((char *)&ROM[0x0190], "OJKRPTBVFCA ", 0x10)) // Micro Machines '96 / Military TODO: better way to recognize these? - state->m_md_cart.type = CODE_MASTERS; - break; - - case 0x200000: - if (!allendianmemcmp(&ROM[0x18c6], &lk3_sig[0], sizeof(lk3_sig))) - state->m_md_cart.type = LIONK3; - - if (!allendianmemcmp(&ROM[0x220], &sdk_sig[0], sizeof(sdk_sig))) - state->m_md_cart.type = SKINGKONG; - - if (!allendianmemcmp(&ROM[0xce560], &redcliff_sig[0], sizeof(redcliff_sig))) - state->m_md_cart.type = REDCLIFF; - - if (!allendianmemcmp(&ROM[0xc8cb0], &smb_sig[0], sizeof(smb_sig))) - state->m_md_cart.type = SMB; - - if (!allendianmemcmp(&ROM[0xf24d6], &smb2_sig[0], sizeof(smb2_sig))) - state->m_md_cart.type = SMB2; - - if (!allendianmemcmp(&ROM[0x674e], &kaiju_sig[0], sizeof(kaiju_sig))) - state->m_md_cart.type = KAIJU; - - if (!allendianmemcmp(&ROM[0x1780], &chifi3_sig[0], sizeof(chifi3_sig))) - state->m_md_cart.type = CHINFIGHT3; - - if (!allendianmemcmp(&ROM[0x03c2], &lionk2_sig[0], sizeof(lionk2_sig))) - state->m_md_cart.type = LIONK2; - - if (!allendianmemcmp(&ROM[0xc8b90], &rx3_sig[0], sizeof(rx3_sig))) - state->m_md_cart.type = ROCKMANX3; - - if (!allendianmemcmp(&ROM[0x56ae2], &kof98_sig[0], sizeof(kof98_sig))) - state->m_md_cart.type = KOF98; - - if (!allendianmemcmp(&ROM[0x17bb2], &s15in1_sig[0], sizeof(s15in1_sig))) - state->m_md_cart.type = MC_SUP15IN1; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM T-081326 ", 12)) // NBA Jam - state->m_md_cart.type = NBA_JAM; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM MK-1228", 10)) // Greatest Heavyweight of the Ring - state->m_md_cart.type = SEGA_EEPROM; - - if ((!allendianmemcmp((char *)&ROM[0x0180], "GM T-12046", 10)) || // Mega Man - (!allendianmemcmp((char *)&ROM[0x0180], "GM T-12053", 10) && !allendianmemcmp(&ROM[0x18e], &rockman_sig[0], sizeof(rockman_sig)))) // / Rock Man (EEPROM version) - state->m_md_cart.type = SEGA_EEPROM; - - break; - - case 0x200005: - if (!allendianmemcmp(&ROM[0xce564], &redcl_en_sig[0], sizeof(redcliff_sig))) - state->m_md_cart.type = REDCL_EN; - break; - - case 0x300000: - if (!allendianmemcmp(&ROM[0x220], &sdk_sig[0], sizeof(sdk_sig))) - state->m_md_cart.type = SDK99; - - if (!allendianmemcmp(&ROM[0x1fd0d2], &kof99_sig[0], sizeof(kof99_sig))) - state->m_md_cart.type = KOF99; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM T-81406", 10)) // NBA Jam TE - state->m_md_cart.type = NBA_JAM_TE; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM T-081276 ", 12)) // NFL Quarterback Club - state->m_md_cart.type = NBA_JAM_TE; - - break; - - case 0x400000: - if (!allendianmemcmp(&ROM[0x3c031c], &radica_sig[0], sizeof(radica_sig)) || - !allendianmemcmp(&ROM[0x3f031c], &radica_sig[0], sizeof(radica_sig))) // ssf+gng + radica vol1 - state->m_md_cart.type = RADICA; - - if (!allendianmemcmp(&ROM[0x028460], &soulb_sig[0], sizeof(soulb_sig))) - state->m_md_cart.type = SOULBLAD; - - if (!allendianmemcmp(&ROM[0x1e700], &s19in1_sig[0], sizeof(s19in1_sig))) - state->m_md_cart.type = MC_SUP19IN1; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM T-081586-", 12)) // NFL Quarterback Club 96 - state->m_md_cart.type = NFL_QB_96; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM T-081576 ", 12)) // College Slam - state->m_md_cart.type = C_SLAM; - - if (!allendianmemcmp((char *)&ROM[0x0180], "GM T-81476", 10)) // Big Hurt Baseball - state->m_md_cart.type = C_SLAM; - - break; - - case 0x500000: - if (!allendianmemcmp((char *)&ROM[0x0120], "SUPER STREET FIGHTER2 ", 22)) - state->m_md_cart.type = SSF2; - break; - case 0x800000: - if (!allendianmemcmp((char *)&ROM[0x0180], "GM T-574023-", 12)) // Pier Solar - state->m_md_cart.type = PSOLAR; - break; - default: - break; - } - } - - return IMAGE_INIT_PASS; -} - -static DEVICE_IMAGE_DISPLAY_INFO(megadriv) -{ - const char *compatibility = image.get_feature("compatibility"); - const char *chips = image.get_feature("addon"); - int md_region = megadrive_region_export + (megadrive_region_pal << 1); - - if (chips) - { - if (!mame_stricmp(chips, "SVP") && (image.device().machine().device("svp") == NULL)) - { - mame_printf_warning("This software requires emulation of the SVP CPU to work.\n"); - mame_printf_warning("It might not work in the system you are using.\n"); - } - } - - if (compatibility) - { - if (!mame_stricmp(compatibility, "PAL") && (md_region != 3)) - { - mame_printf_warning("This software requires a PAL console to work.\n"); - mame_printf_warning("It might not work in the system you are using.\n"); - } - if (!mame_stricmp(compatibility, "NTSC-J") && (md_region != 0)) - { - mame_printf_warning("This software requires a JPN console to work.\n"); - mame_printf_warning("It might not work in the system you are using.\n"); - } - if (!mame_stricmp(compatibility, "NTSC-U") && (md_region != 1)) - { - mame_printf_warning("This software requires a USA console to work.\n"); - mame_printf_warning("It might not work in the system you are using.\n"); - } - if (!mame_stricmp(compatibility, "EUR-JPN") && (md_region != 0 && md_region != 3)) - { - mame_printf_warning("This software requires a PAL or a JPN console to work.\n"); - mame_printf_warning("It might not work in the system you are using.\n"); - } - } -} - - -/************************************* - * Loading a cart image from softlist - *************************************/ - -static int megadrive_load_list(device_image_interface &image) -{ - md_cons_state *state = image.device().machine().driver_data(); - UINT8 *ROM = state->memregion("maincpu")->base(); - UINT32 length = image.get_software_region_length("rom"); - const char *pcb_name; - memcpy(ROM, image.get_software_region("rom"), length); - - state->m_md_cart.last_loaded_image_length = length; - - if ((pcb_name = image.get_feature("pcb_type")) == NULL) - state->m_md_cart.type = SEGA_STD; - else - state->m_md_cart.type = md_get_pcb_id(pcb_name); - - memcpy(&ROM[VIRGIN_COPY_GEN], &ROM[0x000000], MAX_MD_CART_SIZE); /* store a copy of data */ - - return IMAGE_INIT_PASS; -} - -static DEVICE_IMAGE_LOAD( genesis_cart ) -{ - md_cons_state *state = image.device().machine().driver_data(); - state->m_md_cart.type = SEGA_STD; - int res; - - // STEP 1: load the file image and keep a copy for later banking - // STEP 2: identify the cart type - // The two steps are carried out differently if we are loading from a list or not - if (image.software_entry() == NULL) - res = megadrive_load_nonlist(image); - else - res = megadrive_load_list(image); - - logerror("cart type: %d\n", state->m_md_cart.type); - - if (res == IMAGE_INIT_PASS) - { - // STEP 3: install memory handlers for this type of cart - setup_megadriv_custom_mappers(image.device().machine()); - - // STEP 4: take care of SRAM. - setup_megadriv_sram(image); - - return IMAGE_INIT_PASS; - } - else - return IMAGE_INIT_FAIL; -} - -/******* SRAM saving *******/ - -static void genesis_machine_stop(running_machine &machine) -{ - device_image_interface *image = dynamic_cast(machine.device("cart")); - md_cons_state *state = machine.driver_data(); - - /* Write out the battery file if necessary */ - if (state->m_md_cart.sram != NULL) - { - mame_printf_debug("Saving sram\n"); - image->battery_save(state->m_md_cart.sram, state->m_md_cart.sram_end - state->m_md_cart.sram_start + 1); - } -} - -MACHINE_START( md_sram ) -{ - machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(genesis_machine_stop), &machine)); -} - -/******* 32X image loading *******/ - -// FIXME: non-softlist loading should keep using ROM_CART_LOAD in the ROM definitions, -// once we better integrate softlist with the old loading procedures -static DEVICE_IMAGE_LOAD( _32x_cart ) -{ - UINT32 length; - UINT8 *temp_copy; - UINT16 *ROM16; - UINT32 *ROM32; - int i; - - if (image.software_entry() == NULL) - { - length = image.length(); - temp_copy = auto_alloc_array(image.device().machine(), UINT8, length); - image.fread( temp_copy, length); - } - else - { - length = image.get_software_region_length("rom"); - temp_copy = auto_alloc_array(image.device().machine(), UINT8, length); - memcpy(temp_copy, image.get_software_region("rom"), length); - } - - /* Copy the cart image in the locations the driver expects */ - // Notice that, by using pick_integer, we are sure the code works on both LE and BE machines - ROM16 = (UINT16 *) image.device().machine().root_device().memregion("gamecart")->base(); - for (i = 0; i < length; i += 2) - ROM16[i / 2] = pick_integer_be(temp_copy, i, 2); - - ROM32 = (UINT32 *) image.device().machine().root_device().memregion("gamecart_sh2")->base(); - for (i = 0; i < length; i += 4) - ROM32[i / 4] = pick_integer_be(temp_copy, i, 4); - - ROM16 = (UINT16 *) image.device().machine().root_device().memregion("maincpu")->base(); - for (i = 0x00; i < length; i += 2) - ROM16[i / 2] = pick_integer_be(temp_copy, i, 2); - - auto_free(image.device().machine(), temp_copy); - - return IMAGE_INIT_PASS; -} - -/******* Cart getinfo *******/ - -MACHINE_CONFIG_FRAGMENT( genesis_cartslot ) - MCFG_CARTSLOT_ADD("cart") - MCFG_CARTSLOT_EXTENSION_LIST("smd,bin,md,gen") - MCFG_CARTSLOT_MANDATORY - MCFG_CARTSLOT_INTERFACE("megadriv_cart") - MCFG_CARTSLOT_LOAD(genesis_cart) - MCFG_CARTSLOT_DISPLAY_INFO(megadriv) - MCFG_SOFTWARE_LIST_ADD("cart_list","megadriv") -MACHINE_CONFIG_END - -MACHINE_CONFIG_FRAGMENT( _32x_cartslot ) - MCFG_CARTSLOT_ADD("cart") - MCFG_CARTSLOT_EXTENSION_LIST("32x,bin") - MCFG_CARTSLOT_MANDATORY - MCFG_CARTSLOT_INTERFACE("_32x_cart") - MCFG_CARTSLOT_LOAD(_32x_cart) - MCFG_SOFTWARE_LIST_ADD("cart_list","32x") -MACHINE_CONFIG_END - -MACHINE_CONFIG_FRAGMENT( pico_cartslot ) - MCFG_CARTSLOT_ADD("cart") - MCFG_CARTSLOT_EXTENSION_LIST("bin") - MCFG_CARTSLOT_MANDATORY - MCFG_CARTSLOT_INTERFACE("pico_cart") - MCFG_CARTSLOT_LOAD(genesis_cart) - MCFG_SOFTWARE_LIST_ADD("cart_list","pico") -MACHINE_CONFIG_END diff --git a/src/mame/machine/megadriv.c b/src/mame/machine/megadriv.c index 15c17f99c1b..fe20a578b3f 100644 --- a/src/mame/machine/megadriv.c +++ b/src/mame/machine/megadriv.c @@ -30,9 +30,12 @@ Known Non-Issues (confirmed on Real Genesis) #include "sound/2612intf.h" #include "sound/dac.h" - #include "sound/sn76496.h" + #include "imagedev/chd_cd.h" +#include "imagedev/cartslot.h" +#include "formats/imageutl.h" + #include "includes/megadriv.h" #include "machine/nvram.h" #include "cpu/ssp1601/ssp1601.h" @@ -40,12 +43,14 @@ Known Non-Issues (confirmed on Real Genesis) #include "machine/megavdp.h" +MACHINE_CONFIG_EXTERN( megadriv ); static cpu_device *_genesis_snd_z80_cpu; int genesis_other_hacks = 0; // misc hacks timer_device* megadriv_scanline_timer; +cpu_device *_svp_cpu; struct genesis_z80_vars { @@ -318,7 +323,7 @@ UINT8 megadrive_io_read_data_port_3button(running_machine &machine, int portnum) { UINT8 retdata, helper = (megadrive_io_ctrl_regs[portnum] & 0x7f) | 0x80; // bit 7 always comes from megadrive_io_data_regs static const char *const pad3names[] = { "PAD1", "PAD2", "IN0", "UNK" }; - + if (megadrive_io_data_regs[portnum] & 0x40) { /* here we read B, C & the directional buttons */ @@ -885,41 +890,6 @@ MACHINE_CONFIG_END -INPUT_PORTS_START( megdsvp ) - PORT_INCLUDE( megadriv ) - - PORT_START("MEMORY_TEST") /* special memtest mode */ - /* Region setting for Console */ - PORT_DIPNAME( 0x01, 0x00, DEF_STR( Test ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) -INPUT_PORTS_END - -MACHINE_CONFIG_FRAGMENT( md_svp ) - MCFG_CPU_ADD("svp", SSP1601, MASTER_CLOCK_NTSC / 7 * 3) /* ~23 MHz (guessed) */ - MCFG_CPU_PROGRAM_MAP(svp_ssp_map) - MCFG_CPU_IO_MAP(svp_ext_map) -MACHINE_CONFIG_END - -MACHINE_CONFIG_DERIVED( megdsvp, megadriv ) - - MCFG_CPU_ADD("svp", SSP1601, MASTER_CLOCK_NTSC / 7 * 3) /* ~23 MHz (guessed) */ - MCFG_CPU_PROGRAM_MAP(svp_ssp_map) - MCFG_CPU_IO_MAP(svp_ext_map) - /* IRQs are not used by this CPU */ -MACHINE_CONFIG_END - -MACHINE_CONFIG_DERIVED( megdsvppal, megadpal ) - - MCFG_CPU_ADD("svp", SSP1601, MASTER_CLOCK_PAL / 7 * 3) /* ~23 MHz (guessed) */ - MCFG_CPU_PROGRAM_MAP(svp_ssp_map) - MCFG_CPU_IO_MAP(svp_ext_map) - /* IRQs are not used by this CPU */ -MACHINE_CONFIG_END - - - - SCREEN_UPDATE_RGB32(megadriv) { @@ -1030,8 +1000,8 @@ void megadriv_stop_scanline_timer(running_machine &machine) -UINT16* megadriv_backupram; -int megadriv_backupram_length; +static UINT16* megadriv_backupram; +static int megadriv_backupram_length; static NVRAM_HANDLER( megadriv ) { @@ -1190,7 +1160,7 @@ MACHINE_CONFIG_FRAGMENT( md_ntsc ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker",0.25) /* 3.58 MHz */ MACHINE_CONFIG_END -MACHINE_CONFIG_START( megadriv, md_cons_state ) +MACHINE_CONFIG_START( megadriv, md_base_state ) MCFG_FRAGMENT_ADD(md_ntsc) MACHINE_CONFIG_END @@ -1245,7 +1215,7 @@ MACHINE_CONFIG_FRAGMENT( md_pal ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker",0.25) /* 3.58 MHz */ MACHINE_CONFIG_END -MACHINE_CONFIG_START( megadpal, md_cons_state ) +MACHINE_CONFIG_START( megadpal, md_base_state ) MCFG_FRAGMENT_ADD(md_pal) MACHINE_CONFIG_END @@ -1295,6 +1265,64 @@ MACHINE_CONFIG_DERIVED( genesis_32x_pal, megadpal ) MACHINE_CONFIG_END + + +/******* 32X image loading *******/ + +// FIXME: non-softlist loading should keep using ROM_CART_LOAD in the ROM definitions, +// once we better integrate softlist with the old loading procedures +static DEVICE_IMAGE_LOAD( _32x_cart ) +{ + UINT32 length; + UINT8 *temp_copy; + UINT16 *ROM16; + UINT32 *ROM32; + int i; + + if (image.software_entry() == NULL) + { + length = image.length(); + temp_copy = auto_alloc_array(image.device().machine(), UINT8, length); + image.fread(temp_copy, length); + } + else + { + length = image.get_software_region_length("rom"); + temp_copy = auto_alloc_array(image.device().machine(), UINT8, length); + memcpy(temp_copy, image.get_software_region("rom"), length); + } + + /* Copy the cart image in the locations the driver expects */ + // Notice that, by using pick_integer, we are sure the code works on both LE and BE machines + ROM16 = (UINT16 *) image.device().machine().root_device().memregion("gamecart")->base(); + for (i = 0; i < length; i += 2) + ROM16[i / 2] = pick_integer_be(temp_copy, i, 2); + + ROM32 = (UINT32 *) image.device().machine().root_device().memregion("gamecart_sh2")->base(); + for (i = 0; i < length; i += 4) + ROM32[i / 4] = pick_integer_be(temp_copy, i, 4); + + ROM16 = (UINT16 *) image.device().machine().root_device().memregion("maincpu")->base(); + for (i = 0x00; i < length; i += 2) + ROM16[i / 2] = pick_integer_be(temp_copy, i, 2); + + auto_free(image.device().machine(), temp_copy); + + return IMAGE_INIT_PASS; +} + + +MACHINE_CONFIG_FRAGMENT( _32x_cartslot ) + MCFG_CARTSLOT_ADD("cart") + MCFG_CARTSLOT_EXTENSION_LIST("32x,bin") + MCFG_CARTSLOT_MANDATORY + MCFG_CARTSLOT_INTERFACE("_32x_cart") + MCFG_CARTSLOT_LOAD(_32x_cart) + MCFG_SOFTWARE_LIST_ADD("cart_list","32x") +MACHINE_CONFIG_END + + + struct cdrom_interface scd_cdrom = { "scd_cdrom", @@ -1362,7 +1390,7 @@ void md_base_state::megadriv_init_common() _svp_cpu = machine().device("svp"); if (_svp_cpu != NULL) { - printf("SVP (cpu) found '%s'\n", _svp_cpu->tag() ); + printf("SVP (cpu) found '%s'\n", _svp_cpu->tag()); } machine().device("maincpu")->execute().set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(md_base_state::genesis_int_callback),this)); @@ -1405,14 +1433,6 @@ void md_base_state::megadriv_init_common() } mame_printf_debug("\n"); } - - /* if we have an SVP cpu then do some extra initilization for it */ - if (_svp_cpu != NULL) - { - svp_init(machine()); - } - - } DRIVER_INIT_MEMBER(md_base_state,megadriv_c2) diff --git a/src/mame/mame.mak b/src/mame/mame.mak index 074b6fccbec..59ad34fafbf 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -1257,9 +1257,7 @@ $(MAMEOBJ)/sega.a: \ $(MACHINE)/megacd.o \ $(MACHINE)/megacdcd.o \ $(MACHINE)/mega32x.o \ - $(MACHINE)/megasvp.o \ $(MACHINE)/megavdp.o \ - $(MACHINE)/md_cart.o \ $(DRIVERS)/megadrvb.o \ $(DRIVERS)/megaplay.o \ $(DRIVERS)/megatech.o \ diff --git a/src/mess/drivers/megadriv.c b/src/mess/drivers/megadriv.c index 8e210823e95..ba730a63d57 100644 --- a/src/mess/drivers/megadriv.c +++ b/src/mess/drivers/megadriv.c @@ -1,15 +1,14 @@ #include "emu.h" -#include "includes/megadriv.h" +#include "includes/md.h" +#include "machine/md_slot.h" +#include "machine/md_rom.h" +//#include "machine/md_svp.h" +#include "machine/md_sk.h" +#include "machine/md_eeprom.h" +#include "machine/md_jcart.h" +#include "machine/md_stm95.h" -class pico_state : public md_cons_state -{ -public: - pico_state(const machine_config &mconfig, device_type type, const char *tag) - : md_cons_state(mconfig, type, tag) { } - - UINT8 m_page_register; -}; /************************************* * @@ -24,37 +23,6 @@ static TIMER_CALLBACK( mess_io_timeout_timer_callback ) state->m_mess_io_stage[(int)(FPTR)ptr] = -1; } -/* J-Cart controller port */ -WRITE16_HANDLER( jcart_ctrl_w ) -{ - md_cons_state *state = space.machine().driver_data(); - state->m_jcart_io_data[0] = (data & 1) << 6; - state->m_jcart_io_data[1] = (data & 1) << 6; -} - -READ16_HANDLER( jcart_ctrl_r ) -{ - md_cons_state *state = space.machine().driver_data(); - UINT16 retdata = 0; - UINT8 joy[2]; - - if (state->m_jcart_io_data[0] & 0x40) - { - joy[0] = state->ioport("JCART3_3B")->read_safe(0); - joy[1] = state->ioport("JCART4_3B")->read_safe(0); - retdata = (state->m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8); - } - else - { - joy[0] = ((state->ioport("JCART3_3B")->read_safe(0) & 0xc0) >> 2) | - (state->ioport("JCART3_3B")->read_safe(0) & 0x03); - joy[1] = ((state->ioport("JCART4_3B")->read_safe(0) & 0xc0) >> 2) | - (state->ioport("JCART4_3B")->read_safe(0) & 0x03); - retdata = (state->m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8); - } - return retdata; -} - static void mess_init_6buttons_pad(running_machine &machine) { md_cons_state *state = machine.driver_data(); @@ -147,7 +115,12 @@ static UINT8 mess_md_io_read_data_port(running_machine &machine, int portnum) /* Otherwise it's a 3 buttons Joypad */ else { - if (megadrive_io_data_regs[portnum] & 0x40) + // handle test input for SVP test + if (portnum == 0 && machine.root_device().ioport("MEMORY_TEST")->read_safe(0x00)) + { + retdata = (megadrive_io_data_regs[0] & 0xc0); + } + else if (megadrive_io_data_regs[portnum] & 0x40) { /* here we read B, C & the directional buttons */ retdata = (megadrive_io_data_regs[portnum] & helper_3b) | @@ -226,10 +199,6 @@ static INPUT_PORTS_START( md ) PORT_CONFNAME( 0xf0, 0x00, "Player 2 Controller" ) PORT_CONFSETTING( 0x00, "Joystick 3 Buttons" ) PORT_CONFSETTING( 0x10, "Joystick 6 Buttons" ) - PORT_CONFNAME( 0xf00, 0x00, "Player 3 Controller (J-Cart)" ) - PORT_CONFSETTING( 0x00, "Joystick 3 Buttons" ) - PORT_CONFNAME( 0xf000, 0x00, "Player 4 Controller (J-Cart)" ) - PORT_CONFSETTING( 0x00, "Joystick 3 Buttons" ) PORT_START("PAD1_3B") /* Joypad 1 (3 button + start) NOT READ DIRECTLY */ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x00) @@ -251,26 +220,6 @@ static INPUT_PORTS_START( md ) PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 A") PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00) PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00) - PORT_START("JCART3_3B") /* Joypad 3 on J-Cart (3 button + start) */ - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00) - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00) - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00) - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00) - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3) PORT_NAME("P3 B") PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00) - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("P3 C") PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00) - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3) PORT_NAME("P3 A") PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00) - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00) - - PORT_START("JCART4_3B") /* Joypad 4 on J-Cart (3 button + start) */ - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00) - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00) - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00) - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00) - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4) PORT_NAME("P4 B") PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00) - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4) PORT_NAME("P4 C") PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00) - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4) PORT_NAME("P4 A") PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00) - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00) - PORT_START("PAD1_6B") /* Joypad 1 (6 button + start + mode) NOT READ DIRECTLY */ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01) PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01) @@ -317,8 +266,20 @@ INPUT_PORTS_END static MACHINE_START( ms_megadriv ) { + md_cons_state *state = machine.driver_data(); + mess_init_6buttons_pad(machine); - MACHINE_START_CALL( md_sram ); + + // small hack, until SVP is converted to be a slot device + if (machine.device("svp") != NULL) + svp_init(machine); + else + { + machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7fffff, read16_delegate(FUNC(device_md_cart_interface::read),state->m_slotcart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write),state->m_slotcart->m_cart)); + machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0xa13000, 0xa130ff, read16_delegate(FUNC(device_md_cart_interface::read_a13),state->m_slotcart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write_a13),state->m_slotcart->m_cart)); + machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0xa15000, 0xa150ff, read16_delegate(FUNC(device_md_cart_interface::read_a15),state->m_slotcart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write_a15),state->m_slotcart->m_cart)); + machine.device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0xa14000, 0xa14003, write16_delegate(FUNC(device_md_cart_interface::write_tmss_bank),state->m_slotcart->m_cart)); + } } static MACHINE_RESET( ms_megadriv ) @@ -326,6 +287,61 @@ static MACHINE_RESET( ms_megadriv ) MACHINE_RESET_CALL( megadriv ); } +static SLOT_INTERFACE_START(md_cart) + SLOT_INTERFACE_INTERNAL("rom", MD_STD_ROM) + SLOT_INTERFACE_INTERNAL("rom_svp", MD_STD_ROM) +// SLOT_INTERFACE_INTERNAL("rom_svp", MD_ROM_SVP) // not ready yet... + SLOT_INTERFACE_INTERNAL("rom_sk", MD_ROM_SK) +// NVRAM handling + SLOT_INTERFACE_INTERNAL("rom_sram", MD_ROM_SRAM) + SLOT_INTERFACE_INTERNAL("rom_sramsafe", MD_ROM_SRAM) + SLOT_INTERFACE_INTERNAL("rom_fram", MD_ROM_FRAM) + SLOT_INTERFACE_INTERNAL("rom_beggar", MD_ROM_BEGGAR) +// EEPROM handling (not supported fully yet) + SLOT_INTERFACE_INTERNAL("rom_eeprom", MD_STD_EEPROM) + SLOT_INTERFACE_INTERNAL("rom_nbajam", MD_EEPROM_NBAJAM) + SLOT_INTERFACE_INTERNAL("rom_nbajamte", MD_EEPROM_NBAJAMTE) + SLOT_INTERFACE_INTERNAL("rom_nflqb", MD_EEPROM_NFLQB) + SLOT_INTERFACE_INTERNAL("rom_cslam", MD_EEPROM_CSLAM) + SLOT_INTERFACE_INTERNAL("rom_nhlpa", MD_EEPROM_NHLPA) + SLOT_INTERFACE_INTERNAL("rom_blara", MD_EEPROM_BLARA) +// J-Cart controller (Sampras Tennis) + SLOT_INTERFACE_INTERNAL("rom_jcart", MD_JCART) +// J-Cart controller + EEPROM handling (not supported fully yet) + SLOT_INTERFACE_INTERNAL("rom_codemast", MD_SEPROM_CODEMAST) + SLOT_INTERFACE_INTERNAL("rom_mm96", MD_SEPROM_MM96) +// STM95 EEPROM + SLOT_INTERFACE_INTERNAL("rom_stm95", MD_EEPROM_STM95) +// unique bankswitch + SLOT_INTERFACE_INTERNAL("rom_ssf2", MD_ROM_SSF2) + SLOT_INTERFACE_INTERNAL("rom_radica", MD_ROM_RADICA) +// pirate mappers (protection and/or bankswitch) + SLOT_INTERFACE_INTERNAL("rom_bugs", MD_ROM_BUGSLIFE) + SLOT_INTERFACE_INTERNAL("rom_chinf3", MD_ROM_CHINF3) + SLOT_INTERFACE_INTERNAL("rom_elfwor", MD_ROM_ELFWOR) + SLOT_INTERFACE_INTERNAL("rom_kof98", MD_ROM_KOF98) + SLOT_INTERFACE_INTERNAL("rom_kof99", MD_ROM_KOF99) + SLOT_INTERFACE_INTERNAL("rom_lion2", MD_ROM_LION2) + SLOT_INTERFACE_INTERNAL("rom_lion3", MD_ROM_LION3) + SLOT_INTERFACE_INTERNAL("rom_mcpir", MD_ROM_MCPIR) + SLOT_INTERFACE_INTERNAL("rom_mjlov", MD_ROM_MJLOV) + SLOT_INTERFACE_INTERNAL("rom_pokestad", MD_ROM_POKESTAD) + SLOT_INTERFACE_INTERNAL("rom_realtec", MD_ROM_REALTEC) + SLOT_INTERFACE_INTERNAL("rom_redcl", MD_ROM_REDCL) + SLOT_INTERFACE_INTERNAL("rom_rx3", MD_ROM_RX3) + SLOT_INTERFACE_INTERNAL("rom_sbubl", MD_ROM_SBUBL) + SLOT_INTERFACE_INTERNAL("rom_smb", MD_ROM_SMB) + SLOT_INTERFACE_INTERNAL("rom_smb2", MD_ROM_SMB2) + SLOT_INTERFACE_INTERNAL("rom_smouse", MD_ROM_SMOUSE) + SLOT_INTERFACE_INTERNAL("rom_soulb", MD_ROM_SOULB) + SLOT_INTERFACE_INTERNAL("rom_squir", MD_ROM_SQUIR) + SLOT_INTERFACE_INTERNAL("rom_topf", MD_ROM_TOPF) +// these have protection patched out, instead of emulated! + SLOT_INTERFACE_INTERNAL("rom_mulan", MD_STD_ROM) + SLOT_INTERFACE_INTERNAL("rom_poke", MD_STD_ROM) + SLOT_INTERFACE_INTERNAL("rom_poke2", MD_STD_ROM) +SLOT_INTERFACE_END + static MACHINE_CONFIG_START( ms_megadriv, md_cons_state ) MCFG_FRAGMENT_ADD( md_ntsc ) MCFG_NVRAM_HANDLER_CLEAR() @@ -333,7 +349,8 @@ static MACHINE_CONFIG_START( ms_megadriv, md_cons_state ) MCFG_MACHINE_START( ms_megadriv ) MCFG_MACHINE_RESET( ms_megadriv ) - MCFG_FRAGMENT_ADD( genesis_cartslot ) + MCFG_MD_CARTRIDGE_ADD("mdslot", md_cart, NULL, NULL) + MCFG_SOFTWARE_LIST_ADD("cart_list","megadriv") MACHINE_CONFIG_END static MACHINE_CONFIG_START( ms_megadpal, md_cons_state ) @@ -343,29 +360,8 @@ static MACHINE_CONFIG_START( ms_megadpal, md_cons_state ) MCFG_MACHINE_START( ms_megadriv ) MCFG_MACHINE_RESET( ms_megadriv ) - MCFG_FRAGMENT_ADD( genesis_cartslot ) -MACHINE_CONFIG_END - -static MACHINE_CONFIG_START( ms_megdsvp, mdsvp_state ) - MCFG_FRAGMENT_ADD( md_ntsc ) - MCFG_FRAGMENT_ADD( md_svp ) - MCFG_NVRAM_HANDLER_CLEAR() - - MCFG_MACHINE_START( ms_megadriv ) - MCFG_MACHINE_RESET( ms_megadriv ) - - MCFG_FRAGMENT_ADD( genesis_cartslot ) -MACHINE_CONFIG_END - -static MACHINE_CONFIG_START( ms_megdsvppal, mdsvp_state ) - MCFG_FRAGMENT_ADD( md_pal ) - MCFG_FRAGMENT_ADD( md_svp ) - MCFG_NVRAM_HANDLER_CLEAR() - - MCFG_MACHINE_START( ms_megadriv ) - MCFG_MACHINE_RESET( ms_megadriv ) - - MCFG_FRAGMENT_ADD( genesis_cartslot ) + MCFG_MD_CARTRIDGE_ADD("mdslot", md_cart, NULL, NULL) + MCFG_SOFTWARE_LIST_ADD("cart_list","megadriv") MACHINE_CONFIG_END @@ -640,6 +636,51 @@ ROM_START( 32x_scd ) ROM_LOAD( "32x_s_bios.bin", 0x000000, 0x000400, CRC(bfda1fe5) SHA1(4103668c1bbd66c5e24558e73d4f3f92061a109a) ) ROM_END +/****************************************** SVP emulation *****************************************/ + +INPUT_PORTS_START( megdsvp ) + PORT_INCLUDE( megadriv ) + + PORT_START("MEMORY_TEST") /* special memtest mode */ + /* Region setting for Console */ + PORT_DIPNAME( 0x01, 0x00, DEF_STR( Test ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x01, DEF_STR( On ) ) +INPUT_PORTS_END + + +static MACHINE_CONFIG_START( megdsvp, mdsvp_state ) + MCFG_FRAGMENT_ADD( md_ntsc ) + MCFG_NVRAM_HANDLER_CLEAR() + + MCFG_CPU_ADD("svp", SSP1601, MASTER_CLOCK_NTSC / 7 * 3) /* ~23 MHz (guessed) */ + MCFG_CPU_PROGRAM_MAP(svp_ssp_map) + MCFG_CPU_IO_MAP(svp_ext_map) + /* IRQs are not used by this CPU */ + + MCFG_MACHINE_START( ms_megadriv ) + MCFG_MACHINE_RESET( ms_megadriv ) + + MCFG_MD_CARTRIDGE_ADD("mdslot", md_cart, NULL, NULL) + MCFG_SOFTWARE_LIST_ADD("cart_list","megadriv") +MACHINE_CONFIG_END + +static MACHINE_CONFIG_START( megdsvp_pal, mdsvp_state ) + MCFG_FRAGMENT_ADD( md_pal ) + MCFG_NVRAM_HANDLER_CLEAR() + + MCFG_CPU_ADD("svp", SSP1601, MASTER_CLOCK_PAL / 7 * 3) /* ~23 MHz (guessed) */ + MCFG_CPU_PROGRAM_MAP(svp_ssp_map) + MCFG_CPU_IO_MAP(svp_ext_map) + /* IRQs are not used by this CPU */ + + MCFG_MACHINE_START( ms_megadriv ) + MCFG_MACHINE_RESET( ms_megadriv ) + + MCFG_MD_CARTRIDGE_ADD("mdslot", md_cart, NULL, NULL) + MCFG_SOFTWARE_LIST_ADD("cart_list","megadriv") +MACHINE_CONFIG_END + /****************************************** PICO emulation ****************************************/ @@ -828,6 +869,19 @@ static INPUT_PORTS_START( pico ) INPUT_PORTS_END +static SLOT_INTERFACE_START(pico_cart) + SLOT_INTERFACE_INTERNAL("rom", MD_STD_ROM) +SLOT_INTERFACE_END + +static MACHINE_START(pico) +{ + pico_state *state = machine.driver_data(); + machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7fffff, read16_delegate(FUNC(device_md_cart_interface::read),state->m_picocart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write),state->m_picocart->m_cart)); + machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0xa13000, 0xa130ff, read16_delegate(FUNC(device_md_cart_interface::read_a13),state->m_picocart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write_a13),state->m_picocart->m_cart)); + machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0xa15000, 0xa150ff, read16_delegate(FUNC(device_md_cart_interface::read_a15),state->m_picocart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write_a15),state->m_picocart->m_cart)); + machine.device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0xa14000, 0xa14003, write16_delegate(FUNC(device_md_cart_interface::write_tmss_bank),state->m_picocart->m_cart)); +} + static MACHINE_CONFIG_START( pico, pico_state ) MCFG_FRAGMENT_ADD( md_ntsc ) MCFG_NVRAM_HANDLER_CLEAR() @@ -837,9 +891,11 @@ static MACHINE_CONFIG_START( pico, pico_state ) MCFG_DEVICE_REMOVE("genesis_snd_z80") + MCFG_MACHINE_START( pico ) MCFG_MACHINE_RESET( ms_megadriv ) - MCFG_FRAGMENT_ADD( pico_cartslot ) + MCFG_PICO_CARTRIDGE_ADD("picoslot", pico_cart, NULL, NULL) + MCFG_SOFTWARE_LIST_ADD("cart_list","pico") MACHINE_CONFIG_END static MACHINE_CONFIG_START( picopal, pico_state ) @@ -851,9 +907,11 @@ static MACHINE_CONFIG_START( picopal, pico_state ) MCFG_DEVICE_REMOVE("genesis_snd_z80") + MCFG_MACHINE_START( pico ) MCFG_MACHINE_RESET( ms_megadriv ) - MCFG_FRAGMENT_ADD( pico_cartslot ) + MCFG_PICO_CARTRIDGE_ADD("picoslot", pico_cart, NULL, NULL) + MCFG_SOFTWARE_LIST_ADD("cart_list","pico") MACHINE_CONFIG_END @@ -886,9 +944,9 @@ CONS( 1988, megadrij, genesis, 0, ms_megadriv, md, md_cons_state, // these should not exist, the SVP hardware is in the cart and should be installed dynamically when selected from the Software List // this however involves installing entire CPUs at run/load time and I don't think we can do that. -CONS( 1993, gensvp, genesis, 0, ms_megdsvp, md, md_cons_state, genesis, "Sega", "Genesis (USA, NTSC, for SVP cart)", 0) -CONS( 1990, mdsvp, genesis, 0, ms_megdsvppal, md, md_cons_state, md_eur, "Sega", "Mega Drive (Europe, PAL, for SVP cart)", 0) -CONS( 1988, mdsvpj, genesis, 0, ms_megdsvp, md, md_cons_state, md_jpn, "Sega", "Mega Drive (Japan, NTSC, for SVP cart)", 0) +CONS( 1993, gensvp, genesis, 0, megdsvp, md, md_cons_state, genesis, "Sega", "Genesis (USA, NTSC, for SVP cart)", 0) +CONS( 1990, mdsvp, genesis, 0, megdsvp_pal, md, md_cons_state, md_eur, "Sega", "Mega Drive (Europe, PAL, for SVP cart)", 0) +CONS( 1988, mdsvpj, genesis, 0, megdsvp, md, md_cons_state, md_jpn, "Sega", "Mega Drive (Japan, NTSC, for SVP cart)", 0) // the 32X plugged in the cart slot, games plugged into the 32x. Maybe it should be handled as an expansion device? CONS( 1994, 32x, 0, 0, ms_32x, md, md_cons_state, genesis, "Sega", "Genesis with 32X (USA, NTSC)", GAME_NOT_WORKING ) diff --git a/src/mess/includes/md.h b/src/mess/includes/md.h new file mode 100644 index 00000000000..72c1cf8ca0a --- /dev/null +++ b/src/mess/includes/md.h @@ -0,0 +1,64 @@ +#ifndef __MD__ +#define __MD__ + +// Temporary include file to handle SVP add-on, until converted to a proper slot device +// Afterwards, these classes can be moved back to mess/drivers/megadriv.c! + +#include "includes/megadriv.h" +#include "machine/md_slot.h" + +class md_cons_state : public md_base_state +{ +public: + md_cons_state(const machine_config &mconfig, device_type type, const char *tag) + : md_base_state(mconfig, type, tag), + m_slotcart(*this, "mdslot") + { } + + emu_timer *m_mess_io_timeout[3]; + int m_mess_io_stage[3]; + + optional_device m_slotcart; + + DECLARE_DRIVER_INIT(mess_md_common); + DECLARE_DRIVER_INIT(genesis); + DECLARE_DRIVER_INIT(md_eur); + DECLARE_DRIVER_INIT(md_jpn); +}; + +class mdsvp_state : public md_cons_state +{ +public: + mdsvp_state(const machine_config &mconfig, device_type type, const char *tag) + : md_cons_state(mconfig, type, tag) { } + + UINT8 *m_iram; // IRAM (0-0x7ff) + UINT8 *m_dram; // [0x20000]; + UINT32 m_pmac_read[6]; // read modes/addrs for PM0-PM5 + UINT32 m_pmac_write[6]; // write ... + PAIR m_pmc; + UINT32 m_emu_status; + UINT16 m_XST; // external status, mapped at a15000 and a15002 on 68k side. + UINT16 m_XST2; // status of XST (bit1 set when 68k writes to XST) +}; + +class pico_state : public md_cons_state +{ +public: + pico_state(const machine_config &mconfig, device_type type, const char *tag) + : md_cons_state(mconfig, type, tag), + m_picocart(*this, "picoslot") { } + + optional_device m_picocart; + UINT8 m_page_register; +}; + + + +ADDRESS_MAP_EXTERN( svp_ssp_map, driver_device ); +ADDRESS_MAP_EXTERN( svp_ext_map, driver_device ); +extern void svp_init(running_machine &machine); +extern cpu_device *_svp_cpu; + + +#endif diff --git a/src/mess/machine/md_eeprom.c b/src/mess/machine/md_eeprom.c new file mode 100644 index 00000000000..3f8a5c7b1f4 --- /dev/null +++ b/src/mess/machine/md_eeprom.c @@ -0,0 +1,360 @@ +/*********************************************************************************************************** + + + MegaDrive / Genesis cart+EEPROM emulation + + + TODO: proper EEPROM emulation, still not worked on (just hooked up the I2C device) + + + i2c games mapping table: + + game name | SDA_IN | SDA_OUT | SCL | SIZE_MASK | PAGE_MASK | + ----------------------------------|------------|------------|------------|----------------|-----------| + NBA Jam | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x00ff (24C02) | 0x03 | xx + NBA Jam TE | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x00ff (24C02) | 0x03 | xx + NBA Jam TE (32x) | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x00ff (24C02) | 0x03 | + NFL Quarterback Club | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x00ff (24C02) | 0x03 | xx + NFL Quarterback Club 96 | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x07ff (24C16) | 0x07 | xx + College Slam | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x1fff (24C64) | 0x07 | xx + Frank Thomas Big Hurt Baseball | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x1fff (24C64) | 0x07 | xx + NHLPA Hockey 93 | 0x200001-7 | 0x200001-7 | 0x200001-6 | 0x007f (24C01) | 0x03 | xx + Rings of Power | 0x200001-7 | 0x200001-7 | 0x200001-6 | 0x007f (24C01) | 0x03 | xx + Evander Holyfield's Boxing | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx + Greatest Heavyweights of the Ring | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx + Wonder Boy V | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx + Sports Talk Baseball | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx + Megaman - the Wily Wars | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx ** + Micro Machines 2 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x03ff (24C08) | 0x0f | + Micro Machines Military | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x03ff (24C08) | 0x0f | + Micro Machines 96 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x07ff (24C16) | 0x0f | + Brian Lara Cricket 96 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x1fff (24C64) | 0x??* | + ----------------------------------|------------|------------|------------|----------------|-----------| + + * Notes: check these + ** original Rockman Mega World (J) set uses normal backup RAM + + + Micro Machines 2, Micro Machines Military, Micro Machines 96 are emulated in md_jcart + +***********************************************************************************************************/ + + + +#include "emu.h" +#include "machine/md_eeprom.h" + + +//------------------------------------------------- +// md_rom_device - constructor +//------------------------------------------------- + +const device_type MD_STD_EEPROM = &device_creator; +const device_type MD_EEPROM_NBAJAM = &device_creator; +const device_type MD_EEPROM_NBAJAMTE = &device_creator; +const device_type MD_EEPROM_NFLQB = &device_creator; +const device_type MD_EEPROM_CSLAM = &device_creator; +const device_type MD_EEPROM_NHLPA = &device_creator; +const device_type MD_EEPROM_BLARA = &device_creator; + + +md_std_eeprom_device::md_std_eeprom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, type, name, tag, owner, clock), + device_md_cart_interface( mconfig, *this ), + m_i2cmem(*this, "i2cmem") +{ +} + +md_std_eeprom_device::md_std_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MD_STD_EEPROM, "MD Standard cart + EEPROM", tag, owner, clock), + device_md_cart_interface( mconfig, *this ), + m_i2cmem(*this, "i2cmem") +{ +} + +md_eeprom_nbajam_device::md_eeprom_nbajam_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_eeprom_device(mconfig, MD_EEPROM_NBAJAM, "MD NBA Jam", tag, owner, clock) +{ +} + +md_eeprom_nbajamte_device::md_eeprom_nbajamte_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_eeprom_device(mconfig, MD_EEPROM_NBAJAMTE, "MD NBA Jam TE (and a few more)", tag, owner, clock) +{ +} + +md_eeprom_cslam_device::md_eeprom_cslam_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_eeprom_device(mconfig, MD_EEPROM_CSLAM, "MD College Slam", tag, owner, clock) +{ +} + +md_eeprom_nflqb_device::md_eeprom_nflqb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_eeprom_device(mconfig, MD_EEPROM_NFLQB, "MD NFL Quarterback 96", tag, owner, clock) +{ +} + +md_eeprom_nhlpa_device::md_eeprom_nhlpa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_eeprom_device(mconfig, MD_EEPROM_NHLPA, "MD NHLPA 93", tag, owner, clock) +{ +} + +md_eeprom_blara_device::md_eeprom_blara_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_eeprom_device(mconfig, MD_EEPROM_BLARA, "MD Brian Lara", tag, owner, clock) +{ +} + + +//------------------------------------------------- +// SERIAL I2C DEVICE +//------------------------------------------------- + +static const i2cmem_interface md_24c01_i2cmem_interface = +{ + I2CMEM_SLAVE_ADDRESS, 0, 0x80 +}; + + +static const i2cmem_interface md_24c02_i2cmem_interface = +{ + I2CMEM_SLAVE_ADDRESS, 0, 0x100 +}; + + +static const i2cmem_interface md_24c16_i2cmem_interface = +{ + I2CMEM_SLAVE_ADDRESS, 0, 0x800 +}; + + +static const i2cmem_interface md_24c64_i2cmem_interface = +{ + I2CMEM_SLAVE_ADDRESS, 0, 0x2000 +}; + + +// MD_STD_EEPROM & MD_EEPROM_NHLPA +MACHINE_CONFIG_FRAGMENT( md_i2c_24c01 ) + MCFG_I2CMEM_ADD("i2cmem", md_24c01_i2cmem_interface) +MACHINE_CONFIG_END + +// MD_EEPROM_NBAJAM & MD_EEPROM_NBAJAMTE +MACHINE_CONFIG_FRAGMENT( md_i2c_24c02 ) + MCFG_I2CMEM_ADD("i2cmem", md_24c02_i2cmem_interface) +MACHINE_CONFIG_END + +// MD_EEPROM_NFLQB +MACHINE_CONFIG_FRAGMENT( md_i2c_24c16 ) + MCFG_I2CMEM_ADD("i2cmem", md_24c16_i2cmem_interface) +MACHINE_CONFIG_END + +// MD_EEPROM_CSLAM & MD_EEPROM_BLARA +MACHINE_CONFIG_FRAGMENT( md_i2c_24c64 ) + MCFG_I2CMEM_ADD("i2cmem", md_24c64_i2cmem_interface) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor md_std_eeprom_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( md_i2c_24c01 ); +} + +machine_config_constructor md_eeprom_nbajam_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( md_i2c_24c02 ); +} + +machine_config_constructor md_eeprom_nbajamte_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( md_i2c_24c02 ); +} + +machine_config_constructor md_eeprom_cslam_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( md_i2c_24c64 ); +} + +machine_config_constructor md_eeprom_nflqb_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( md_i2c_24c16 ); +} + +machine_config_constructor md_eeprom_nhlpa_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( md_i2c_24c01 ); +} + +machine_config_constructor md_eeprom_blara_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( md_i2c_24c64 ); +} + + +void md_std_eeprom_device::device_start() +{ + m_i2c_mem = 0; + m_i2c_clk = 0; + save_item(NAME(m_i2c_mem)); + save_item(NAME(m_i2c_clk)); +} + +/*------------------------------------------------- + mapper specific handlers + -------------------------------------------------*/ + +/*------------------------------------------------- + CART + EEPROM + -------------------------------------------------*/ + +READ16_MEMBER(md_std_eeprom_device::read) +{ + if (offset == 0x200000/2) + { + m_i2c_mem = i2cmem_sda_read(m_i2cmem); + return ~m_i2c_mem & 1; + } + return m_rom[offset]; +} + +WRITE16_MEMBER(md_std_eeprom_device::write) +{ + if (offset == 0x200000/2) + { + m_i2c_clk = BIT(data, 1); + m_i2c_mem = BIT(data, 0); + i2cmem_scl_write(m_i2cmem, m_i2c_clk); + i2cmem_sda_write(m_i2cmem, m_i2c_mem); + } +} + +READ16_MEMBER(md_eeprom_nbajam_device::read) +{ + if (offset == 0x200000/2) + { + m_i2c_mem = i2cmem_sda_read(m_i2cmem); + return m_i2c_mem & 1; + } + return m_rom[offset]; +} + +WRITE16_MEMBER(md_eeprom_nbajam_device::write) +{ + if (offset == 0x200000/2) + { + m_i2c_clk = BIT(data, 1); + m_i2c_mem = BIT(data, 0); + i2cmem_scl_write(m_i2cmem, m_i2c_clk); + i2cmem_sda_write(m_i2cmem, m_i2c_mem); + } +} + +READ16_MEMBER(md_eeprom_nbajamte_device::read) +{ + if (offset == 0x200000/2) + { + m_i2c_mem = i2cmem_sda_read(m_i2cmem); + return m_i2c_mem & 1; + } + return m_rom[offset]; +} + +WRITE16_MEMBER(md_eeprom_nbajamte_device::write) +{ + if (offset == 0x200000/2) + { + m_i2c_clk = BIT(data, 8); + m_i2c_mem = BIT(data, 0); + i2cmem_scl_write(m_i2cmem, m_i2c_clk); + i2cmem_sda_write(m_i2cmem, m_i2c_mem); + } +} + +// same as NBAJAMTE above... derived class? +READ16_MEMBER(md_eeprom_cslam_device::read) +{ + if (offset == 0x200000/2) + { + m_i2c_mem = i2cmem_sda_read(m_i2cmem); + return m_i2c_mem & 1; + } + return m_rom[offset]; +} + +WRITE16_MEMBER(md_eeprom_cslam_device::write) +{ + if (offset == 0x200000/2) + { + m_i2c_clk = BIT(data, 8); + m_i2c_mem = BIT(data, 0); + i2cmem_scl_write(m_i2cmem, m_i2c_clk); + i2cmem_sda_write(m_i2cmem, m_i2c_mem); + } +} + +// same as NBAJAMTE above... derived class? +READ16_MEMBER(md_eeprom_nflqb_device::read) +{ + if (offset == 0x200000/2) + { + m_i2c_mem = i2cmem_sda_read(m_i2cmem); + return m_i2c_mem & 1; + } + return m_rom[offset]; +} + +WRITE16_MEMBER(md_eeprom_nflqb_device::write) +{ + if (offset == 0x200000/2) + { + m_i2c_clk = BIT(data, 8); + m_i2c_mem = BIT(data, 0); + i2cmem_scl_write(m_i2cmem, m_i2c_clk); + i2cmem_sda_write(m_i2cmem, m_i2c_mem); + } +} + +READ16_MEMBER(md_eeprom_nhlpa_device::read) +{ + if (offset == 0x200000/2) + { + m_i2c_mem = i2cmem_sda_read(m_i2cmem); + return (m_i2c_mem & 1) << 7; + } + return m_rom[offset]; +} + +WRITE16_MEMBER(md_eeprom_nhlpa_device::write) +{ + if (offset == 0x200000/2) + { + m_i2c_clk = BIT(data, 6); + m_i2c_mem = BIT(data, 7); + i2cmem_scl_write(m_i2cmem, m_i2c_clk); + i2cmem_sda_write(m_i2cmem, m_i2c_mem); + } +} + +READ16_MEMBER(md_eeprom_blara_device::read) +{ + if (offset == 0x380000/2) + { + m_i2c_mem = i2cmem_sda_read(m_i2cmem); + return (m_i2c_mem & 1) << 7; + } + return m_rom[offset]; +} + +WRITE16_MEMBER(md_eeprom_blara_device::write) +{ + if (offset == 0x380000/2) + { + m_i2c_clk = BIT(data, 9); + m_i2c_mem = BIT(data, 8); + i2cmem_scl_write(m_i2cmem, m_i2c_clk); + i2cmem_sda_write(m_i2cmem, m_i2c_mem); + } +} + diff --git a/src/mess/machine/md_eeprom.h b/src/mess/machine/md_eeprom.h new file mode 100644 index 00000000000..421932742f1 --- /dev/null +++ b/src/mess/machine/md_eeprom.h @@ -0,0 +1,147 @@ +#ifndef __MD_EEPROM_H +#define __MD_EEPROM_H + +#include "machine/md_slot.h" +#include "machine/i2cmem.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> md_std_eeprom_device + +class md_std_eeprom_device : public device_t, + public device_md_cart_interface +{ +public: + // construction/destruction + md_std_eeprom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); + md_std_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_std_eeprom"; } + virtual machine_config_constructor device_mconfig_additions() const; + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + + required_device m_i2cmem; + UINT8 m_i2c_mem, m_i2c_clk; +}; + +// ======================> md_eeprom_nbajam_device + +class md_eeprom_nbajam_device : public md_std_eeprom_device +{ +public: + // construction/destruction + md_eeprom_nbajam_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_eeprom_nbajam"; } + virtual machine_config_constructor device_mconfig_additions() const; + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); +}; + +// ======================> md_eeprom_nbajamte_device + +class md_eeprom_nbajamte_device : public md_std_eeprom_device +{ +public: + // construction/destruction + md_eeprom_nbajamte_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_eeprom_nbajamte"; } + virtual machine_config_constructor device_mconfig_additions() const; + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); +}; + +// ======================> md_eeprom_cslam_device (same read/write as nbajamte, but different I2C type) + +class md_eeprom_cslam_device : public md_std_eeprom_device +{ +public: + // construction/destruction + md_eeprom_cslam_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_eeprom_cslam"; } + virtual machine_config_constructor device_mconfig_additions() const; + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); +}; + +// ======================> md_eeprom_nflqb_device (same read/write as nbajamte, but different I2C type) + +class md_eeprom_nflqb_device : public md_std_eeprom_device +{ +public: + // construction/destruction + md_eeprom_nflqb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_eeprom_nflqb"; } + virtual machine_config_constructor device_mconfig_additions() const; + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); +}; + +// ======================> md_eeprom_nhlpa_device + +class md_eeprom_nhlpa_device : public md_std_eeprom_device +{ +public: + // construction/destruction + md_eeprom_nhlpa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_eeprom_nhlpa"; } + virtual machine_config_constructor device_mconfig_additions() const; + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); +}; + +// ======================> md_eeprom_blara_device (same read/write as codemast, but different I2C type) + +class md_eeprom_blara_device : public md_std_eeprom_device +{ +public: + // construction/destruction + md_eeprom_blara_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_eeprom_blara"; } + virtual machine_config_constructor device_mconfig_additions() const; + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); +}; + + +// device type definition +extern const device_type MD_STD_EEPROM; +extern const device_type MD_EEPROM_NBAJAM; +extern const device_type MD_EEPROM_NBAJAMTE; +extern const device_type MD_EEPROM_CSLAM; +extern const device_type MD_EEPROM_NFLQB; +extern const device_type MD_EEPROM_NHLPA; +extern const device_type MD_EEPROM_BLARA; + +#endif diff --git a/src/mess/machine/md_jcart.c b/src/mess/machine/md_jcart.c new file mode 100644 index 00000000000..606563e5f6a --- /dev/null +++ b/src/mess/machine/md_jcart.c @@ -0,0 +1,249 @@ +/*********************************************************************************************************** + + + MegaDrive / Genesis J-Cart (+SEPROM) emulation + + + i2c games mapping table: + + game name | SDA_IN | SDA_OUT | SCL | SIZE_MASK | PAGE_MASK | + ----------------------------------|------------|------------|------------|----------------|-----------| + Micro Machines 2 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x03ff (24C08) | 0x0f | + Micro Machines Military | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x03ff (24C08) | 0x0f | + Micro Machines 96 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x07ff (24C16) | 0x0f | + ----------------------------------|------------|------------|------------|----------------|-----------| + + * Notes: check these + + + TODO: proper SEPROM emulation, still not worked on (just hooked up the I2C device) + +***********************************************************************************************************/ + + + +#include "emu.h" +#include "machine/md_jcart.h" + + +//------------------------------------------------- +// md_rom_device - constructor +//------------------------------------------------- + +const device_type MD_JCART = &device_creator; +const device_type MD_SEPROM_CODEMAST = &device_creator; +const device_type MD_SEPROM_MM96 = &device_creator; + +// Sampras, Super Skidmarks? +md_jcart_device::md_jcart_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, type, name, tag, owner, clock), + device_md_cart_interface( mconfig, *this ), + m_jcart3(*this, "JCART3"), + m_jcart4(*this, "JCART4") +{ +} + +md_jcart_device::md_jcart_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MD_JCART, "MD J-Cart games", tag, owner, clock), + device_md_cart_interface( mconfig, *this ), + m_jcart3(*this, "JCART3"), + m_jcart4(*this, "JCART4") +{ +} + +// Micro Machines 2, Micro Machines Military +md_seprom_codemast_device::md_seprom_codemast_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) + : md_jcart_device(mconfig, type, name, tag, owner, clock), + m_i2cmem(*this, "i2cmem") +{ +} + +md_seprom_codemast_device::md_seprom_codemast_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_jcart_device(mconfig, MD_SEPROM_CODEMAST, "MD J-Cart games + SEPROM", tag, owner, clock), + m_i2cmem(*this, "i2cmem") +{ +} + +// Micro Machines 96 +md_seprom_mm96_device::md_seprom_mm96_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_seprom_codemast_device(mconfig, MD_SEPROM_MM96, "MD Micro Machine 96", tag, owner, clock) +{ +} + + +//------------------------------------------------- +// SERIAL I2C DEVICE +//------------------------------------------------- + +static const i2cmem_interface md_24c08_i2cmem_interface = +{ + I2CMEM_SLAVE_ADDRESS, 0, 0x400 +}; + +static const i2cmem_interface md_24c16a_i2cmem_interface = +{ + I2CMEM_SLAVE_ADDRESS, 0, 0x800 +}; + +// MD_SEPROM_CODEMAST +MACHINE_CONFIG_FRAGMENT( md_i2c_24c08 ) + MCFG_I2CMEM_ADD("i2cmem", md_24c08_i2cmem_interface) +MACHINE_CONFIG_END + +// MD_SEPROM_MM96 +MACHINE_CONFIG_FRAGMENT( md_i2c_24c16a ) + MCFG_I2CMEM_ADD("i2cmem", md_24c16a_i2cmem_interface) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor md_seprom_codemast_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( md_i2c_24c08 ); +} + +machine_config_constructor md_seprom_mm96_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( md_i2c_24c16a ); +} + + +static INPUT_PORTS_START( jcart_ipt ) + + PORT_START("JCART3") /* Joypad 3 on J-Cart (3 button + start) */ + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(3) + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(3) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(3) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(3) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3) PORT_NAME("P3 B") + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("P3 C") + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3) PORT_NAME("P3 A") + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(3) + + PORT_START("JCART4") /* Joypad 4 on J-Cart (3 button + start) */ + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(4) + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(4) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(4) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(4) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4) PORT_NAME("P4 B") + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4) PORT_NAME("P4 C") + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4) PORT_NAME("P4 A") + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(4) + +INPUT_PORTS_END + +ioport_constructor md_jcart_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( jcart_ipt ); +} + + +void md_jcart_device::device_start() +{ + m_jcart_io_data[0] = 0; + m_jcart_io_data[1] = 0; + save_item(NAME(m_jcart_io_data)); +} + +void md_seprom_codemast_device::device_start() +{ + m_i2c_mem = 0; + m_i2c_clk = 0; + m_jcart_io_data[0] = 0; + m_jcart_io_data[1] = 0; + save_item(NAME(m_i2c_mem)); + save_item(NAME(m_i2c_clk)); + save_item(NAME(m_jcart_io_data)); +} + + +/*------------------------------------------------- + mapper specific handlers + -------------------------------------------------*/ + +/*------------------------------------------------- + J-CART ONLY (Pete Sampras Tennis) + -------------------------------------------------*/ + +READ16_MEMBER(md_jcart_device::read) +{ + if (offset == 0x38fffe/2) + { + UINT8 joy[2]; + + if (m_jcart_io_data[0] & 0x40) + { + joy[0] = m_jcart3->read_safe(0); + joy[1] = m_jcart4->read_safe(0); + return (m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8); + } + else + { + joy[0] = ((m_jcart3->read_safe(0) & 0xc0) >> 2) | (m_jcart3->read_safe(0) & 0x03); + joy[1] = ((m_jcart4->read_safe(0) & 0xc0) >> 2) | (m_jcart4->read_safe(0) & 0x03); + return (m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8); + } + } + return m_rom[offset]; +} + +WRITE16_MEMBER(md_jcart_device::write) +{ + if (offset == 0x38fffe/2) + { + m_jcart_io_data[0] = (data & 1) << 6; + m_jcart_io_data[1] = (data & 1) << 6; + } +} + +/*------------------------------------------------- + J-CART + SEPROM + -------------------------------------------------*/ + +READ16_MEMBER(md_seprom_codemast_device::read) +{ + if (offset == 0x380000/2) + { + m_i2c_mem = i2cmem_sda_read(m_i2cmem); + return (m_i2c_mem & 1) << 7; + } + if (offset == 0x38fffe/2) + { + UINT8 joy[2]; + + if (m_jcart_io_data[0] & 0x40) + { + joy[0] = m_jcart3->read_safe(0); + joy[1] = m_jcart4->read_safe(0); + return (m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8); + } + else + { + joy[0] = ((m_jcart3->read_safe(0) & 0xc0) >> 2) | (m_jcart3->read_safe(0) & 0x03); + joy[1] = ((m_jcart4->read_safe(0) & 0xc0) >> 2) | (m_jcart4->read_safe(0) & 0x03); + return (m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8); + } + } + return m_rom[offset]; +} + +WRITE16_MEMBER(md_seprom_codemast_device::write) +{ + if (offset == 0x380000/2) + { + m_i2c_clk = BIT(data, 9); + m_i2c_mem = BIT(data, 8); + i2cmem_scl_write(m_i2cmem, m_i2c_clk); + i2cmem_sda_write(m_i2cmem, m_i2c_mem); + } + if (offset == 0x38fffe/2) + { + m_jcart_io_data[0] = (data & 1) << 6; + m_jcart_io_data[1] = (data & 1) << 6; + } +} + diff --git a/src/mess/machine/md_jcart.h b/src/mess/machine/md_jcart.h new file mode 100644 index 00000000000..bf7b3e7dd9b --- /dev/null +++ b/src/mess/machine/md_jcart.h @@ -0,0 +1,83 @@ +#ifndef __MD_JCART_H +#define __MD_JCART_H + +#include "machine/md_slot.h" +#include "machine/i2cmem.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> md_jcart_device + +class md_jcart_device : public device_t, + public device_md_cart_interface +{ +public: + // construction/destruction + md_jcart_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); + md_jcart_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_jcart"; } + virtual ioport_constructor device_input_ports() const; + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + + required_ioport m_jcart3; + required_ioport m_jcart4; + +private: + UINT8 m_jcart_io_data[2]; +}; + +// ======================> md_seprom_codemast_device + +class md_seprom_codemast_device : public md_jcart_device +{ +public: + // construction/destruction + md_seprom_codemast_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); + md_seprom_codemast_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_seprom_codemast"; } + virtual machine_config_constructor device_mconfig_additions() const; + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + + required_device m_i2cmem; + +private: + UINT8 m_jcart_io_data[2]; + UINT8 m_i2c_mem, m_i2c_clk; +}; + +// ======================> md_seprom_mm96_device (same read/write as codemast, but different I2C type) + +class md_seprom_mm96_device : public md_seprom_codemast_device +{ +public: + // construction/destruction + md_seprom_mm96_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_seprom_mm96"; } + virtual machine_config_constructor device_mconfig_additions() const; +}; + + + +// device type definition +extern const device_type MD_JCART; +extern const device_type MD_SEPROM_CODEMAST; +extern const device_type MD_SEPROM_MM96; + +#endif diff --git a/src/mess/machine/md_rom.c b/src/mess/machine/md_rom.c new file mode 100644 index 00000000000..8f8fd3246cc --- /dev/null +++ b/src/mess/machine/md_rom.c @@ -0,0 +1,924 @@ +/*********************************************************************************************************** + + + MegaDrive / Genesis cart emulation + + + Here we emulate bankswitch / protection / NVRAM found on generic carts with no additional hardware + + + ***********************************************************************************************************/ + +#include "emu.h" +#include "machine/md_rom.h" +#include "cpu/m68000/m68000.h" + + +//------------------------------------------------- +// md_rom_device - constructor +//------------------------------------------------- + +// BASE CARTS + NVRAM +const device_type MD_STD_ROM = &device_creator; +const device_type MD_ROM_SRAM = &device_creator; +const device_type MD_ROM_FRAM = &device_creator; + +// BASE CARTS + PROTECTION / BANKSWITCH +const device_type MD_ROM_SSF2 = &device_creator; +const device_type MD_ROM_BUGSLIFE = &device_creator; +const device_type MD_ROM_SMOUSE = &device_creator; +const device_type MD_ROM_SMB = &device_creator; +const device_type MD_ROM_SMB2 = &device_creator; +const device_type MD_ROM_SBUBL = &device_creator; +const device_type MD_ROM_RX3 = &device_creator; +const device_type MD_ROM_MJLOV = &device_creator; +const device_type MD_ROM_KOF98 = &device_creator; +const device_type MD_ROM_KOF99 = &device_creator; +const device_type MD_ROM_SOULB = &device_creator; +const device_type MD_ROM_CHINF3 = &device_creator; +const device_type MD_ROM_ELFWOR = &device_creator; +const device_type MD_ROM_LION2 = &device_creator; +const device_type MD_ROM_LION3 = &device_creator; +const device_type MD_ROM_MCPIR = &device_creator; +const device_type MD_ROM_POKESTAD = &device_creator; +const device_type MD_ROM_REALTEC = &device_creator; +const device_type MD_ROM_REDCL = &device_creator; +const device_type MD_ROM_SQUIR = &device_creator; +const device_type MD_ROM_TOPF = &device_creator; +const device_type MD_ROM_RADICA = &device_creator; +const device_type MD_ROM_BEGGAR = &device_creator; + +// below ones are currently unused, because the protection is patched out +const device_type MD_ROM_MULAN = &device_creator; +const device_type MD_ROM_POKE = &device_creator; +const device_type MD_ROM_POKE2 = &device_creator; + + +md_std_rom_device::md_std_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, type, name, tag, owner, clock), + device_md_cart_interface( mconfig, *this ) +{ +} + +md_std_rom_device::md_std_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MD_STD_ROM, "MD Standard cart", tag, owner, clock), + device_md_cart_interface( mconfig, *this ) +{ +} + +md_rom_sram_device::md_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_SRAM, "MD Standard cart + SRAM", tag, owner, clock) +{ +} + +md_rom_beggar_device::md_rom_beggar_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_BEGGAR, "MD Xin Qigai Wangzi", tag, owner, clock) +{ +} + +md_rom_fram_device::md_rom_fram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_FRAM, "MD Standard cart + FRAM", tag, owner, clock) +{ +} + +md_rom_ssf2_device::md_rom_ssf2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_SSF2, "MD Super SF2", tag, owner, clock) +{ +} + +md_rom_mcpirate_device::md_rom_mcpirate_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_MCPIR, "MD Pirate Multicarts (Various)", tag, owner, clock) +{ +} + +md_rom_bugslife_device::md_rom_bugslife_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_BUGSLIFE, "MD A Bug's Life", tag, owner, clock) +{ +} + +md_rom_smouse_device::md_rom_smouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_SMOUSE, "MD Huan Le Tao Qi Shu / Smart Mouse", tag, owner, clock) +{ +} + +md_rom_smb_device::md_rom_smb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_SMB, "MD Super Mario Bros.", tag, owner, clock) +{ +} + +md_rom_smb2_device::md_rom_smb2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_SMB2, "MD Super Mario Bros. 2", tag, owner, clock) +{ +} + +md_rom_sbubl_device::md_rom_sbubl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_SBUBL, "MD Super Bubble Bobble", tag, owner, clock) +{ +} + +md_rom_rx3_device::md_rom_rx3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_SMB2, "MD Rockman X3", tag, owner, clock) +{ +} + +md_rom_mjlov_device::md_rom_mjlov_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_MJLOV, "MD Ma Jiang Qing Ren / Mahjong Lover", tag, owner, clock) +{ +} + +md_rom_kof98_device::md_rom_kof98_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_KOF98, "MD KOF 98", tag, owner, clock) +{ +} + +md_rom_kof99_device::md_rom_kof99_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_KOF99, "MD KOF 99", tag, owner, clock) +{ +} + +md_rom_soulb_device::md_rom_soulb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_SOULB, "MD Soul Blade", tag, owner, clock) +{ +} + +md_rom_chinf3_device::md_rom_chinf3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_CHINF3, "MD Chinese Fighter 3", tag, owner, clock) +{ +} + +md_rom_elfwor_device::md_rom_elfwor_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_ELFWOR, "MD Linghuan Daoshi Super Magician / Elf Wor", tag, owner, clock) +{ +} + +md_rom_lion2_device::md_rom_lion2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_LION2, "MD Lion King 2", tag, owner, clock) +{ +} + +md_rom_lion3_device::md_rom_lion3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_LION3, "MD Lion King 3", tag, owner, clock) +{ +} + +md_rom_pokestad_device::md_rom_pokestad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_POKESTAD, "MD Pokemon Stadium", tag, owner, clock) +{ +} + +md_rom_realtec_device::md_rom_realtec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_REALTEC, "MD Realtec", tag, owner, clock) +{ +} + +md_rom_redcl_device::md_rom_redcl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_REDCL, "MD Redcliff", tag, owner, clock) +{ +} + +md_rom_squir_device::md_rom_squir_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_SQUIR, "MD Squirrel King", tag, owner, clock) +{ +} + +md_rom_topf_device::md_rom_topf_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_TOPF, "MD Top Fighter", tag, owner, clock) +{ +} + +md_rom_radica_device::md_rom_radica_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_RADICA, "MD Radica TV games", tag, owner, clock) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void md_rom_ssf2_device::device_start() +{ + for (int i = 0; i < 7; i++) + m_bank[i] = i; + m_lastoff = -1; + m_lastdata = -1; + save_item(NAME(m_bank)); + save_item(NAME(m_lastoff)); + save_item(NAME(m_lastdata)); +} + +void md_rom_mcpirate_device::device_start() +{ + m_bank = 0; + save_item(NAME(m_bank)); +} + +void md_rom_chinf3_device::device_start() +{ + m_bank = 0; + save_item(NAME(m_bank)); +} + +void md_rom_lion2_device::device_start() +{ + m_prot1_data = 0; + m_prot2_data = 0; + save_item(NAME(m_prot1_data)); + save_item(NAME(m_prot2_data)); +} + +void md_rom_lion3_device::device_start() +{ + m_prot_data = 0; + m_prot_cmd = 0; + m_bank = 0; + save_item(NAME(m_prot_data)); + save_item(NAME(m_prot_cmd)); + save_item(NAME(m_bank)); +} + +void md_rom_pokestad_device::device_start() +{ + m_bank = 0; + save_item(NAME(m_bank)); +} + +void md_rom_realtec_device::device_start() +{ + m_bank_addr = 0; + m_bank_size = 0; + m_old_bank_addr = -1; + save_item(NAME(m_bank_addr)); + save_item(NAME(m_bank_size)); + save_item(NAME(m_old_bank_addr)); +} + +void md_rom_squir_device::device_start() +{ + m_latch = 0; + save_item(NAME(m_latch)); +} + +void md_rom_topf_device::device_start() +{ + m_latch = 0; + m_bank[0] = m_bank[1] = m_bank[2] = 0; + save_item(NAME(m_latch)); + save_item(NAME(m_bank)); +} + +void md_rom_radica_device::device_start() +{ + m_bank = 0; + save_item(NAME(m_bank)); +} + +/*------------------------------------------------- + mapper specific handlers + -------------------------------------------------*/ + +/*------------------------------------------------- + CART + SRAM + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_sram_device::read) +{ + offset <<= 1; + // since a lot of generic carts ends up here if loaded from fullpath + // we access nvram only if m_nvram_handlers_installed has been turned on + if (m_nvram_handlers_installed) + { + if (offset >= m_nvram_start && offset < m_nvram_end && m_nvram_active) + return m_nvram[(offset - m_nvram_start)/2]; + } + return m_rom[offset/2]; +} + +WRITE16_MEMBER(md_rom_sram_device::write) +{ + // since a lot of generic carts ends up here if loaded from fullpath + // we access nvram only if m_nvram_handlers_installed has been turned on + if (m_nvram_handlers_installed) + { + offset <<= 1; + if (offset >= m_nvram_start && offset <= m_nvram_end && m_nvram_active && !m_nvram_readonly) + m_nvram[(offset - m_nvram_start)/2] = data; + } +} + +WRITE16_MEMBER(md_rom_sram_device::write_a13) +{ + offset <<= 1; + if (offset == 0xf) + { + /* unsure if this is actually supposed to toggle or just switch on? yet to encounter game that uses this */ + m_nvram_active = BIT(data, 0); + m_nvram_readonly = BIT(data, 1); + + // since a lot of generic carts ends up here if loaded from fullpath + // we turn on nvram (with m_nvram_handlers_installed) only if they toggle it on by writing here! + if (m_nvram_active && !m_nvram_handlers_installed) + m_nvram_handlers_installed = 1; + } +} + +/*------------------------------------------------- + BEGGAR PRINCE / XIN QIGAI WANGZI [same as above, but diff start/end... merge?] + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_beggar_device::read) +{ + offset <<= 1; + if (offset >= m_nvram_start && offset < m_nvram_end && m_nvram_active) + return m_nvram[(offset - m_nvram_start)/2]; + return m_rom[offset/2]; +} + +WRITE16_MEMBER(md_rom_beggar_device::write) +{ + offset <<= 1; + if (offset >= m_nvram_start && offset <= m_nvram_end && m_nvram_active && !m_nvram_readonly) + m_nvram[(offset - m_nvram_start)/2] = data; +} + +WRITE16_MEMBER(md_rom_beggar_device::write_a13) +{ + offset <<= 1; + if (offset == 0xf) + { + /* unsure if this is actually supposed to toggle or just switch on? yet to encounter game that uses this */ + m_nvram_active = BIT(data, 0); + m_nvram_readonly = BIT(data, 1); + } +} + +/*------------------------------------------------- + CART + FRAM [almost same as SRAM... merge common parts?] + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_fram_device::read) +{ + offset <<= 1; + if (offset >= m_nvram_start && offset < m_nvram_end && m_nvram_active) + return m_nvram[(offset - m_nvram_start)/2]; + return m_rom[offset/2]; +} + +WRITE16_MEMBER(md_rom_fram_device::write_a13) +{ + offset <<= 1; + if (offset == 0xf) + m_nvram_active = BIT(data, 0); +} + + +READ16_MEMBER(md_rom_fram_device::read_a13) +{ + if (offset == 0xf) + return m_nvram_active; + else + return 0xffff; +} + +/*------------------------------------------------- + SUPER STREET FIGHTERS 2 + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_ssf2_device::read) +{ + if (offset < 0x400000/2) + return m_rom[offset]; + else + return 0xffff; +} + +// I'm not very fond of the code below... +WRITE16_MEMBER(md_rom_ssf2_device::write_a13) +{ + if (offset >= 0xf0/2) + { + offset -= 0xf0/2; + if ((m_lastoff != offset) || (m_lastdata != data)) + { + m_lastoff = offset; + m_lastdata = data; + if (offset) // bank 0 is not modified + { + UINT16 *ROM = get_rom_base(); + m_bank[offset] = data & 0xf; + memcpy(ROM + offset * 0x080000/2, ROM + 0x400000/2 + (m_bank[offset] * 0x080000)/2, 0x080000); + } + } + } +} + +/*------------------------------------------------- + PIRATE MULTICARTS + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_mcpirate_device::read) +{ + if (offset < 0x400000/2) + { + return m_rom[offset + (m_bank * 0x10000)/2]; + } + else + { + return read(space, offset - 0x400000/2, 0xffff); + } +} + +WRITE16_MEMBER(md_rom_mcpirate_device::write_a13) +{ + offset <<= 1; + if (offset < 0x40) + m_bank = offset; +} + +/*------------------------------------------------- + A BUG'S LIFE + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_bugslife_device::read_a13) +{ + if (offset == 0) + return 0x28; + else + return 0xffff; +} + +/*------------------------------------------------- + CHINESE FIGHTER 3 + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_chinf3_device::read) +{ + if (offset < 0x100000/2) + { + if (!m_bank) + return m_rom[offset & 0xfffff/2]; + else + return m_rom[(offset & 0xffff/2) + (m_bank * 0x10000)/2]; + } + + // PROTECTION in 0x400000 - 0x4fffff + /* not 100% correct, there may be some relationship between the reads here + and the writes made at the start of the game.. */ + if (offset >= 0x400000/2 && offset < 0x500000/2) + { + UINT32 retdat = 0; + /* + 04dc10 chifi3, prot_r? 2800 + 04cefa chifi3, prot_r? 65262 + */ + if (space.machine().device("maincpu")->safe_pc() == 0x01782) // makes 'VS' screen appear + { + retdat = space.machine().device("maincpu")->state().state_int(M68K_D3) & 0xff; + retdat <<= 8; + return retdat; + } + else if (space.machine().device("maincpu")->safe_pc() == 0x1c24) // background gfx etc. + { + retdat = space.machine().device("maincpu")->state().state_int(M68K_D3) & 0xff; + retdat <<= 8; + return retdat; + } + else if (space.machine().device("maincpu")->safe_pc() == 0x10c4a) // unknown + { + return space.machine().rand(); + } + else if (space.machine().device("maincpu")->safe_pc() == 0x10c50) // unknown + { + return space.machine().rand(); + } + else if (space.machine().device("maincpu")->safe_pc() == 0x10c52) // relates to the game speed.. + { + retdat = space.machine().device("maincpu")->state().state_int(M68K_D4) & 0xff; + retdat <<= 8; + return retdat; + } + else if (space.machine().device("maincpu")->safe_pc() == 0x061ae) + { + retdat = space.machine().device("maincpu")->state().state_int(M68K_D3) & 0xff; + retdat <<= 8; + return retdat; + } + else if (space.machine().device("maincpu")->safe_pc() == 0x061b0) + { + retdat = space.machine().device("maincpu")->state().state_int(M68K_D3) & 0xff; + retdat <<= 8; + return retdat; + } + else + { + logerror("%06x chifi3, prot_r? %04x\n", space.machine().device("maincpu")->safe_pc(), offset); + } + return 0; + } + + return m_rom[offset & 0x1fffff/2]; +} + +WRITE16_MEMBER(md_rom_chinf3_device::write) +{ + if (offset >= 0x600000/2 && offset < 0x700000/2) + { + if (data == 0xf100) // *hit player + m_bank = 1; + else if (data == 0xd700) // title screen.. + m_bank = 7; + else if (data == 0xd300) // character hits floor + m_bank = 3; + else if (data == 0x0000) + m_bank = 0; + else + logerror("%06x chifi3, bankw? %04x %04x\n", space.device().safe_pc(), offset, data); + } +} + +/*------------------------------------------------- + LINGHUAN DAOSHI SUPER MAGICIAN / ELF WOR + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_elfwor_device::read) +{ + /* It returns (0x55 @ 0x400000 OR 0xc9 @ 0x400004) AND (0x0f @ 0x400002 OR 0x18 @ 0x400006). + It is probably best to add handlers for all 4 addresses. */ + if (offset == 0x400000/2) return 0x5500; + if (offset == 0x400002/2) return 0x0f00; + if (offset == 0x400004/2) return 0xc900; + if (offset == 0x400006/2) return 0x1800; + return m_rom[offset]; +} + +/*------------------------------------------------- + HUAN LE TAO QI SHU / SMART MOUSE + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_smouse_device::read) +{ + if (offset == 0x400000/2) return 0x5500; + if (offset == 0x400002/2) return 0x0f00; + if (offset == 0x400004/2) return 0xaa00; + if (offset == 0x400006/2) return 0xf000; + return m_rom[offset]; +} + +/*------------------------------------------------- + KOF98 + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_kof98_device::read) +{ + if (offset == 0x480000/2) return 0xaa00; + if (offset == 0x4800e0/2) return 0xaa00; + if (offset == 0x4824a0/2) return 0xaa00; + if (offset == 0x488880/2) return 0xaa00; + if (offset == 0x4a8820/2) return 0x0a00; + if (offset == 0x4f8820/2) return 0x0000; + return m_rom[offset]; +} + +/*------------------------------------------------- + KOF 99 + -------------------------------------------------*/ +// gfx glitch with the new code... uninitialized ram somewhere? +READ16_MEMBER(md_rom_kof99_device::read_a13) +{ + if (offset == 0x00/2) return 0x00; // startup protection check, chinese message if != 0 + if (offset == 0x02/2) return 0x01; // write 02 to a13002.. shift right 1? + if (offset == 0x3e/2) return 0x1f; // write 3e to a1303e.. shift right 1? + else return 0xffff; +} + +/*------------------------------------------------- + LION KING 2 + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_lion2_device::read) +{ + if (offset == 0x400002/2) return m_prot1_data; + if (offset == 0x400006/2) return m_prot2_data; + return m_rom[offset]; +} + +WRITE16_MEMBER(md_rom_lion2_device::write) +{ + if (offset == 0x400000/2) m_prot1_data = data; + if (offset == 0x400004/2) m_prot2_data = data; +} + +/*------------------------------------------------- + LION KING 3 + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_lion3_device::read) +{ + if (offset < 0x8000/2) + return m_rom[offset + (m_bank * 0x8000)/2]; + else if (offset >= 0x600000/2 && offset < 0x700000/2) + { + UINT16 retdata = 0; + switch (offset & 0x7) + { + case 2: + if (m_prot_cmd == 0) + retdata = (m_prot_data << 1); + else if (m_prot_cmd == 1) + retdata = (m_prot_data >> 1); + else if (m_prot_cmd == 2) + { + retdata = m_prot_data >> 4; + retdata |= (m_prot_data & 0x0f) << 4; + } + else + { + /* printf("unk prot case %d\n", m_prot_cmd); */ + retdata = (BIT(m_prot_data, 7) << 0); + retdata |= (BIT(m_prot_data, 6) << 1); + retdata |= (BIT(m_prot_data, 5) << 2); + retdata |= (BIT(m_prot_data, 4) << 3); + retdata |= (BIT(m_prot_data, 3) << 4); + retdata |= (BIT(m_prot_data, 2) << 5); + retdata |= (BIT(m_prot_data, 1) << 6); + retdata |= (BIT(m_prot_data, 0) << 7); + } + break; + + default: + logerror("protection read, unknown offset %x\n", offset & 0x7); + break; + } + return retdata; + } + + return m_rom[offset]; +} + +WRITE16_MEMBER(md_rom_lion3_device::write) +{ + if (offset >= 0x600000/2 && offset < 0x700000/2) + { + switch (offset & 0x7) + { + case 0x0: + m_prot_data = data; + break; + case 0x1: + m_prot_cmd = data; + break; + default: + logerror("protection write, unknown offset %d\n", offset & 0x7); + break; + } + } + if (offset >= 0x700000/2 && offset < 0x800000/2) + { + switch (offset & 0x7) + { + case 0x0: + m_bank = data & 0xffff; + break; + default: + logerror("bank write, unknown offset %d\n", offset & 0x7); + break; + } + } +} + +/*------------------------------------------------- + MA JIANG QING REN / MAHJONG LOVER + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_mjlov_device::read) +{ + if (offset == 0x400000/2) return 0x9000; + if (offset == 0x401000/2) return 0xd300; + return m_rom[offset]; +} + + +/*------------------------------------------------- + SUPER BUBBLE BOBBLE MD + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_sbubl_device::read) +{ + if (offset == 0x400000/2) return 0x5500; + if (offset == 0x400002/2) return 0x0f00; + return m_rom[offset]; +} + +/*------------------------------------------------- + SOUL BLADE + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_soulb_device::read) +{ + if (offset == 0x400002/2) return 0x9800; + if (offset == 0x400004/2) return 0xc900; + if (offset == 0x400006/2) return 0xf000; + return m_rom[offset]; +} + +/*------------------------------------------------- + POKEMON STADIUM / KAIJU + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_pokestad_device::read) +{ + if (offset < 0x8000/2) + return m_rom[offset + (m_bank * 0x8000)/2]; + return m_rom[offset]; +} + +WRITE16_MEMBER(md_rom_pokestad_device::write) +{ + if (offset >= 0x700000/2 && offset < 0x800000/2) + m_bank = data & 0x7f; +} + +/*------------------------------------------------- + REALTEC + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_realtec_device::read) +{ + if (offset < (m_bank_size * 0x20000)) // two banks of same (variable) size at the bottom of the rom + return m_rom[offset + (m_bank_addr * 0x20000)/2]; + return m_rom[(offset & 0x1fff/2) + 0x7e000/2]; // otherwise it accesses the final 8k of the image +} + +WRITE16_MEMBER(md_rom_realtec_device::write) +{ + if (offset == 0x400000/2) + { + m_old_bank_addr = m_bank_addr; + m_bank_addr = (m_bank_addr & 0x7) | ((data >> 9) & 0x7) << 3; + } + if (offset == 0x402000/2) + { + m_bank_addr = 0; + m_bank_size = (data >> 8) & 0x1f; + } + if (offset == 0x404000/2) + { + m_old_bank_addr = m_bank_addr; + m_bank_addr = (m_bank_addr & 0xf8) | ((data >> 8) & 0x3); + } +} + +/*------------------------------------------------- + RED CLIFF + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_redcl_device::read) +{ + if (offset == 0x400000/2) return 0x55 << 8; + if (offset == 0x400004/2) return -0x56 << 8; + return m_rom[offset]; +} + +/*------------------------------------------------- + ROCKMAN X3 + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_rx3_device::read_a13) +{ + if (offset == 0) + return 0x0c; + else + return 0xffff; +} + +/*------------------------------------------------- + SQUIRREL KING + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_squir_device::read) +{ + if ((offset >= 0x400000/2) && (offset < 0x400008/2)) + return m_latch; + return m_rom[offset]; +} + +WRITE16_MEMBER(md_rom_squir_device::write) +{ + if (offset >= 0x400000/2 && offset < 0x400008/2) + m_latch = data; +} + +/*------------------------------------------------- + SUPER MARIO BROS + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_smb_device::read_a13) +{ + if (offset == 0) + return 0x0c; + else + return 0xffff; +} + +/*------------------------------------------------- + SUPER MARIO BROS 2 + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_smb2_device::read_a13) +{ + if (offset == 0) + return 0x0a; + else + return 0xffff; +} + +/*------------------------------------------------- + TOP FIGHTER + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_topf_device::read) +{ + //cpu #0 (PC=0004CBAE): unmapped program memory word read from 006A35D4 & 00FF -- wants regD7 + if (offset == 0x645b44/2) + { + //cpu #0 (PC=0004DE00): unmapped program memory word write to 00689B80 = 004A & 00FF + //cpu #0 (PC=0004DE08): unmapped program memory word write to 00 = 00B5 & 00FF + //cpu #0 (PC=0004DE0C): unmapped program memory word read from 00645B44 & 00FF + + return 0x9f;//0x25; + } + if (offset == 0x6bd294/2) + { + /* + cpu #0 (PC=00177192): unmapped program memory word write to 006BD240 = 00A8 & 00FF + cpu #0 (PC=0017719A): unmapped program memory word write to 006BD2D2 = 0098 & 00FF + cpu #0 (PC=001771A2): unmapped program memory word read from 006BD294 & 00FF + */ + + if (space.device().safe_pc()==0x1771a2) return 0x50; + else + { + m_latch++; + logerror("%06x topfig_6BD294_r %04x\n",space.device().safe_pc(), m_latch); + return m_latch; + } + } + if (offset == 0x6f5344/2) + { + if (space.device().safe_pc()==0x4C94E) + return space.machine().device("maincpu")->state().state_int((M68K_D0)) & 0xff; + else + { + m_latch++; + logerror("%06x topfig_6F5344_r %04x\n", space.device().safe_pc(), m_latch); + return m_latch; + } + } + + if (offset >= 0x20000/2 && offset < 0x28000/2) + return m_rom[offset + (m_bank[0] * 0x188000)/2]; + + if (offset >= 0x58000/2 && offset < 0x60000/2) + return m_rom[offset + (m_bank[1] * 0x20000)/2]; + + if (offset >= 0x60000/2 && offset < 0x68000/2) + return m_rom[offset + (m_bank[2] * 0x110000)/2]; + + return m_rom[offset]; +} + +WRITE16_MEMBER(md_rom_topf_device::write) +{ + if (offset >= 0x700000/2 && offset < 0x800000/2) + { + if (data == 0x002a) + m_bank[2] = 1; // == 0x2e*0x8000?! + else if (data==0x0035) // characters ingame + m_bank[0] = 1; // == 0x35*0x8000 + else if (data==0x000f) // special moves + m_bank[1] = 1; // == 0xf*0x8000 + else if (data==0x0000) + { + m_bank[0] = 0; + m_bank[1] = 0; + m_bank[2] = 0; + } + else + logerror("%06x offset %06x, data %04x\n", space.device().safe_pc(), offset, data); + } +} + +/*------------------------------------------------- + RADICA TV GAMES [to be split...] + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_radica_device::read) +{ + return m_rom[m_bank * 0x10000/2 + offset]; +} + +READ16_MEMBER(md_rom_radica_device::read_a13) +{ + if (offset < 0x80) + m_bank = offset & 0x3f; + return 0; +} diff --git a/src/mess/machine/md_rom.h b/src/mess/machine/md_rom.h new file mode 100644 index 00000000000..1ad1b9c4fe8 --- /dev/null +++ b/src/mess/machine/md_rom.h @@ -0,0 +1,501 @@ +#ifndef __MD_ROM_H +#define __MD_ROM_H + +#include "machine/md_slot.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> md_std_rom_device + +class md_std_rom_device : public device_t, + public device_md_cart_interface +{ +public: + // construction/destruction + md_std_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); + md_std_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start() {}; + virtual void device_config_complete() { m_shortname = "md_std_rom"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read) { return m_rom[offset]; }; + virtual DECLARE_WRITE16_MEMBER(write) { }; +}; + +// ======================> md_rom_sram_device + +class md_rom_sram_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_sram"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + virtual DECLARE_WRITE16_MEMBER(write_a13); +}; + +// ======================> md_rom_beggar_device + +class md_rom_beggar_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_beggar_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_beggar"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + virtual DECLARE_WRITE16_MEMBER(write_a13); +}; + +// ======================> md_rom_fram_device + +class md_rom_fram_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_fram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_fram"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_READ16_MEMBER(read_a13); + virtual DECLARE_WRITE16_MEMBER(write_a13); +}; + +// ======================> md_rom_ssf2_device + +class md_rom_ssf2_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_ssf2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_rom_ssf2"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write_a13); + +private: + UINT8 m_bank[16]; + int m_lastoff, m_lastdata; +}; + +// ======================> md_rom_mcpirate_device + +class md_rom_mcpirate_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_mcpirate_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_rom_mcpirate"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write_a13); + +private: + UINT8 m_bank; +}; + + +// ======================> md_rom_bugslife_device + +class md_rom_bugslife_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_bugslife_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_bugslife"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read_a13); +}; + +// ======================> md_rom_chinf3_device + +class md_rom_chinf3_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_chinf3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_rom_chinf3"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + +private: + int m_bank; +}; + +// ======================> md_rom_elfwor_device + +class md_rom_elfwor_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_elfwor_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_elfwor"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); +}; + +// ======================> md_rom_kof98_device + +class md_rom_kof98_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_kof98_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_kof98"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); +}; + +// ======================> md_rom_kof99_device + +class md_rom_kof99_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_kof99_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_kof99"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read_a13); +}; + +// ======================> md_rom_lion2_device + +class md_rom_lion2_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_lion2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_rom_lion2"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + +private: + UINT16 m_prot1_data, m_prot2_data; +}; + +// ======================> md_rom_lion3_device + +class md_rom_lion3_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_lion3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_rom_lion3"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + +private: + UINT8 m_prot_data, m_prot_cmd; + UINT16 m_bank; +}; + +// ======================> md_rom_mjlov_device + +class md_rom_mjlov_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_mjlov_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_mjlov"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); +}; + +// ======================> md_rom_pokestad_device + +class md_rom_pokestad_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_pokestad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_rom_pokestad"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + +private: + UINT8 m_bank; +}; + +// ======================> md_rom_realtec_device + +class md_rom_realtec_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_realtec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_rom_realtec"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + +private: + UINT16 m_bank_addr, m_bank_size, m_old_bank_addr; +}; + +// ======================> md_rom_redcl_device + +class md_rom_redcl_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_redcl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_redcl"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); +}; + +// ======================> md_rom_rx3_device + +class md_rom_rx3_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_rx3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_rx3"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read_a13); +}; + +// ======================> md_rom_sbubl_device + +class md_rom_sbubl_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_sbubl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_sbubl"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); +}; + +// ======================> md_rom_smb_device + +class md_rom_smb_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_smb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_smb"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read_a13); +}; + +// ======================> md_rom_smb2_device + +class md_rom_smb2_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_smb2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_smb2"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read_a13); +}; + +// ======================> md_rom_smouse_device + +class md_rom_smouse_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_smouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_smouse"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); +}; + + +// ======================> md_rom_soulb_device + +class md_rom_soulb_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_soulb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_config_complete() { m_shortname = "md_rom_soulb"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); +}; + +// ======================> md_rom_squir_device + +class md_rom_squir_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_squir_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_rom_squir"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + +private: + UINT16 m_latch; +}; + +// ======================> md_rom_topf_device + +class md_rom_topf_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_topf_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_rom_topf"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + +private: + UINT16 m_latch; + UINT8 m_bank[3]; +}; + +// ======================> md_rom_radica_device + +class md_rom_radica_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_radica_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_rom_radica"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_READ16_MEMBER(read_a13); + +private: + UINT8 m_bank; +}; + + + +// device type definition +extern const device_type MD_STD_ROM; +extern const device_type MD_ROM_SRAM; +extern const device_type MD_ROM_FRAM; +extern const device_type MD_ROM_BEGGAR; +extern const device_type MD_ROM_BUGSLIFE; +extern const device_type MD_ROM_CHINF3; +extern const device_type MD_ROM_ELFWOR; +extern const device_type MD_ROM_KOF98; +extern const device_type MD_ROM_KOF99; +extern const device_type MD_ROM_LION2; +extern const device_type MD_ROM_LION3; +extern const device_type MD_ROM_MCPIR; +extern const device_type MD_ROM_MJLOV; +extern const device_type MD_ROM_POKESTAD; +extern const device_type MD_ROM_REALTEC; +extern const device_type MD_ROM_REDCL; +extern const device_type MD_ROM_RX3; +extern const device_type MD_ROM_SBUBL; +extern const device_type MD_ROM_SMB; +extern const device_type MD_ROM_SMB2; +extern const device_type MD_ROM_SMOUSE; +extern const device_type MD_ROM_SOULB; +extern const device_type MD_ROM_SSF2; +extern const device_type MD_ROM_SQUIR; +extern const device_type MD_ROM_TOPF; +extern const device_type MD_ROM_RADICA; + +// this are currently unused... protection is directly patched out! +extern const device_type MD_ROM_MULAN; +extern const device_type MD_ROM_POKE; +extern const device_type MD_ROM_POKE2; + +#endif diff --git a/src/mess/machine/md_sk.c b/src/mess/machine/md_sk.c new file mode 100644 index 00000000000..dbaf0822f69 --- /dev/null +++ b/src/mess/machine/md_sk.c @@ -0,0 +1,90 @@ +/*********************************************************************************************************** + + + Sonic & Knuckles pass-thorugh cart emulation + + + TODO: currently we only support loading of base carts with no bankswitch or protection... + shall we support other as well? + + + ***********************************************************************************************************/ + + + + +#include "emu.h" +#include "machine/md_sk.h" +#include "machine/md_rom.h" + + +//------------------------------------------------- +// md_rom_device - constructor +//------------------------------------------------- + +const device_type MD_ROM_SK = &device_creator; + + +md_rom_sk_device::md_rom_sk_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, type, name, tag, owner, clock), + device_md_cart_interface( mconfig, *this ), + m_exp(*this, "subslot") +{ +} + +md_rom_sk_device::md_rom_sk_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MD_ROM_SK, "MD Sonic & Knuckles", tag, owner, clock), + device_md_cart_interface( mconfig, *this ), + m_exp(*this, "subslot") +{ +} + + +void md_rom_sk_device::device_start() +{ +} + +/*------------------------------------------------- + mapper specific handlers + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_sk_device::read) +{ + if (m_exp->m_cart != NULL && m_exp->m_cart->get_rom_base() != NULL && offset >= 0x200000/2 && offset < (0x200000 + m_exp->m_cart->get_rom_size())/2) + return m_exp->m_cart->m_rom[offset - 0x200000/2]; + return m_rom[offset]; +} + +WRITE16_MEMBER(md_rom_sk_device::write) +{ +// should there be anything here? +} + +//------------------------------------------------- +// MACHINE_CONFIG_FRAGMENT( sk_slot ) +//------------------------------------------------- + +static SLOT_INTERFACE_START(sk_sub_cart) + SLOT_INTERFACE_INTERNAL("rom", MD_STD_ROM) + SLOT_INTERFACE_INTERNAL("rom_svp", MD_STD_ROM) + SLOT_INTERFACE_INTERNAL("rom_sram", MD_ROM_SRAM) + SLOT_INTERFACE_INTERNAL("rom_sramsafe", MD_ROM_SRAM) + SLOT_INTERFACE_INTERNAL("rom_fram", MD_ROM_FRAM) +// add all types?? +SLOT_INTERFACE_END + +static MACHINE_CONFIG_FRAGMENT( sk_slot ) + MCFG_MDSUB_CARTRIDGE_ADD("subslot", sk_sub_cart, NULL, NULL) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor md_rom_sk_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( sk_slot ); +} + diff --git a/src/mess/machine/md_sk.h b/src/mess/machine/md_sk.h new file mode 100644 index 00000000000..6a765a2b920 --- /dev/null +++ b/src/mess/machine/md_sk.h @@ -0,0 +1,34 @@ +#ifndef __MD_SK_H +#define __MD_SK_H + +#include "machine/md_slot.h" + + +// ======================> md_rom_sk_device + +class md_rom_sk_device : public device_t, + public device_md_cart_interface +{ +public: + // construction/destruction + md_rom_sk_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); + md_rom_sk_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_rom_sk"; } + virtual machine_config_constructor device_mconfig_additions() const; + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + +private: + required_device m_exp; +}; + + +// device type definition +extern const device_type MD_ROM_SK; + +#endif diff --git a/src/mess/machine/md_slot.c b/src/mess/machine/md_slot.c new file mode 100644 index 00000000000..7b0fec66188 --- /dev/null +++ b/src/mess/machine/md_slot.c @@ -0,0 +1,899 @@ +/*********************************************************************************************************** + + + MegaDrive cart emulation + (through slot devices) + + The driver exposes address ranges + 0x000000-0x7fffff to read/write (typically cart data, possibly banked, and some protection) + 0x130000-0x1300ff to read_a13/write_a13 (typically SRAM toggling or protection) + 0x150000-0x1500ff to read_a15/write_a15 (for SVP registers, not converted yet to slots) + + currently available slot devices: + md_rom: standard carts + carts with NVRAM (SRAM/FRAM) + pirate carts with protection & bankswitch + md_eeprom: carts + I2C EEPROM (EEPROM device hooked up only, support to be completed) + md_jcart: Codemasters J-Cart & J-Cart+SEPROM (again, EEPROM device hooked up only, support to be completed) + md_sk: Sonic & Knuckles pass-thorugh cart (enables a second slot to mount any other cart) + md_stm95: cart + STM95 EEPROM (e.g. Pier Solar) + + TODO: currently read access in 0x000000-0x7fffff are not masked (so we assume that no game attempts to + read beyond its ROM size). A regression test is pending to identify which games need this and mirror + them properly (Eke's doc states ROM data should be mirrored), but none of the ~120 games I tried + attempted that and a testcase would be appreciated + + ***********************************************************************************************************/ + + +#include "emu.h" +#include "machine/md_slot.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type MD_CART_SLOT = &device_creator; +const device_type PICO_CART_SLOT = &device_creator; +const device_type MD_SUBCART_SLOT = &device_creator; + + +//************************************************************************** +// MD cartridges Interface +//************************************************************************** + +//------------------------------------------------- +// device_md_cart_interface - constructor +//------------------------------------------------- + +device_md_cart_interface::device_md_cart_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device), + m_rom(NULL), + m_nvram(NULL), + m_rom_size(0), + m_nvram_size(0) +{ +} + + +//------------------------------------------------- +// ~device_md_cart_interface - destructor +//------------------------------------------------- + +device_md_cart_interface::~device_md_cart_interface() +{ +} + +//------------------------------------------------- +// rom_alloc - alloc the space for the cart +//------------------------------------------------- + +void device_md_cart_interface::rom_alloc(running_machine &machine, size_t size) +{ + if (m_rom == NULL) + { + m_rom = auto_alloc_array_clear(machine, UINT16, size/sizeof(UINT16)); + m_rom_size = size; + } +} + + +//------------------------------------------------- +// nvram_alloc - alloc the space for the nvram +//------------------------------------------------- + +void device_md_cart_interface::nvram_alloc(running_machine &machine, size_t size) +{ + if (m_nvram == NULL) + { + m_nvram = auto_alloc_array_clear(machine, UINT16, size/sizeof(UINT16)); + m_nvram_size = size; + } +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// base_md_cart_slot_device - constructor +//------------------------------------------------- +base_md_cart_slot_device::base_md_cart_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, type, name, tag, owner, clock), + device_image_interface(mconfig, *this), + device_slot_interface(mconfig, *this), + m_type(SEGA_STD) +{ +} + +md_cart_slot_device::md_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + base_md_cart_slot_device(mconfig, MD_CART_SLOT, "MD Cartridge Slot", tag, owner, clock) +{ +} + +md_subcart_slot_device::md_subcart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + base_md_cart_slot_device(mconfig, MD_SUBCART_SLOT, "MD Cartridge SubSlot", tag, owner, clock) +{ +} + +pico_cart_slot_device::pico_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + base_md_cart_slot_device(mconfig, PICO_CART_SLOT, "Pico Cartridge Slot", tag, owner, clock) +{ +} + +//------------------------------------------------- +// base_md_cart_slot_device - destructor +//------------------------------------------------- + +base_md_cart_slot_device::~base_md_cart_slot_device() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void base_md_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 base_md_cart_slot_device::device_config_complete() +{ + // set brief and instance name + update_names(); +} + + +//------------------------------------------------- +// MD PCB +//------------------------------------------------- + + +struct md_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 md_slot slot_list[] = +{ + { SEGA_SK, "rom_sk" }, + { SEGA_STD, "rom_svp"}, +// { SEGA_SVP, "rom_svp"}, // not ready yet... + + { SEGA_SRAM, "rom_sram" }, + { SEGA_FRAM, "rom_fram" }, + { BEGGAR, "rom_beggar"}, + + { SEGA_EEPROM, "rom_eeprom" }, + { NBA_JAM, "rom_nbajam" }, + { NBA_JAM_TE, "rom_nbajamte" }, + { NFL_QB_96, "rom_nflqb" }, + { C_SLAM, "rom_cslam" }, + { EA_NHLPA, "rom_nhlpa" }, + { BRIAN_LARA, "rom_blara" }, + + { CM_JCART, "rom_jcart" }, + { CODE_MASTERS, "rom_codemast" }, + { CM_MM96, "rom_mm96" }, + + { PSOLAR, "rom_stm95"}, + + { SSF2, "rom_ssf2" }, + { RADICA, "rom_radica" }, +// { GAME_KANDUME, "rom_gkand" }, // what's needed by this? + + { BUGSLIFE, "rom_bugs" }, + { CHINFIGHT3, "rom_chinf3" }, + { ELFWOR, "rom_elfwor" }, + { KAIJU, "rom_pokestad" }, + { KOF98, "rom_kof98" }, + { KOF99, "rom_kof99" }, + { LIONK2, "rom_lion2" }, + { LIONK3, "rom_lion3" }, + { MC_PIRATE, "rom_mcpir" }, + { MJLOVER, "rom_mjlov" }, + { MULAN, "rom_mulan"}, + { POKEMON, "rom_poke"}, + { POKEMON2, "rom_poke2"}, + { REALTEC, "rom_realtec" }, + { REDCL_EN, "rom_redcl" }, + { REDCLIFF, "rom_redcl" }, + { ROCKMANX3, "rom_rx3" }, + { SBUBBOB, "rom_sbubl" }, + { SMB, "rom_smb" }, + { SMB2, "rom_smb2" }, + { SMOUSE, "rom_smouse" }, + { SOULBLAD, "rom_soulblad" }, + { SQUIRRELK, "rom_squir" }, + { TOPFIGHTER, "rom_topf" }, + + { SEGA_SRAM_FULLPATH, "rom_sram" }, + { SEGA_SRAM_FALLBACK, "rom_sramsafe" } +}; + +static int md_get_pcb_id(const char *slot) +{ + for (int i = 0; i < ARRAY_LENGTH(slot_list); i++) + { + if (!mame_stricmp(slot_list[i].slot_option, slot)) + return slot_list[i].pcb_id; + } + + return SEGA_STD; +} + +static const char *md_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 "rom"; +} + + +/*------------------------------------------------- + SRAM handling + -------------------------------------------------*/ + +/*------------------------------------------------- + call load + -------------------------------------------------*/ + + +bool base_md_cart_slot_device::call_load() +{ + if (m_cart) + { + m_type = SEGA_STD; + int res; + + // STEP 1: load the file image and keep a copy for later banking + // STEP 2: identify the cart type + // The two steps are carried out differently if we are loading from a list or not + if (software_entry() == NULL) + res = load_nonlist(); + else + res = load_list(); + + //printf("cart type: %d\n", m_type); + + if (res == IMAGE_INIT_PASS) + { + // STEP 3: install memory handlers for this type of cart + setup_custom_mappers(); + + // STEP 4: take care of SRAM. + setup_nvram(); + + if (m_cart->get_nvram_size()) + battery_load(m_cart->get_nvram_base(), m_cart->get_nvram_size(), 0xff); + } + + return res; + + } + + return IMAGE_INIT_PASS; +} + + +int base_md_cart_slot_device::load_list() +{ + UINT16 *ROM; + UINT32 length = get_software_region_length("rom"); + const char *slot_name; + + m_cart->rom_alloc(machine(), length); + ROM = m_cart->get_rom_base(); + memcpy(ROM, get_software_region("rom"), length); + + if ((slot_name = get_feature("slot")) == NULL) + m_type = SEGA_STD; + else + m_type = md_get_pcb_id(slot_name); + + return IMAGE_INIT_PASS; +} + + +/************************************* + * Helper function: Detect SMD file + *************************************/ + +/* code taken directly from GoodGEN by Cowering */ +static int genesis_is_SMD(unsigned char *buf,unsigned int len) +{ + if (buf[0x2080] == 'S' && buf[0x80] == 'E' && buf[0x2081] == 'G' && buf[0x81] == 'A') + return 1; + + /* aq quiz */ + if (!strncmp("UZ(-01 ", (const char *) &buf[0xf0], 8)) + return 1; + + /* Phelios USA redump */ + /* target earth */ + /* klax (namcot) */ + if (buf[0x2080] == ' ' && buf[0x0080] == 'S' && buf[0x2081] == 'E' && buf[0x0081] == 'G') + return 1; + + /* jap baseball 94 */ + if (!strncmp("OL R-AEAL", (const char *) &buf[0xf0], 9)) + return 1; + + /* devilish Mahjong Tower */ + if (!strncmp("optrEtranet", (const char *) &buf[0xf3], 11)) + return 1; + + /* golden axe 2 beta */ + if (buf[0x0100] == 0x3c && buf[0x0101] == 0 && buf[0x0102] == 0 && buf[0x0103] == 0x3c) + return 1; + + /* omega race */ + if (!strncmp("OEARC ", (const char *) &buf[0x90], 8)) + return 1; + + /* budokan beta */ + if ((len >= 0x6708 + 8) && !strncmp(" NTEBDKN", (const char *) &buf[0x6708], 8)) + return 1; + + /* cdx pro 1.8 bios */ + if (!strncmp("so fCXP", (const char *) &buf[0x2c0], 7)) + return 1; + + /* ishido (hacked) */ + if (!strncmp("sio-Wyo ", (const char *) &buf[0x0090], 8)) + return 1; + + /* onslaught */ + if (!strncmp("SS CAL ", (const char *) &buf[0x0088], 8)) + return 1; + + /* tram terror pirate */ + if ((len >= 0x3648 + 8) && !strncmp("SG NEPIE", (const char *) &buf[0x3648], 8)) + return 1; + + /* breath of fire 3 chinese */ + if (buf[0x0007] == 0x1c && buf[0x0008] == 0x0a && buf[0x0009] == 0xb8 && buf[0x000a] == 0x0a) + return 1; + + /*tetris pirate */ + if ((len >= 0x1cbe + 5) && !strncmp("@TTI>", (const char *) &buf[0x1cbe], 5)) + return 1; + + return 0; +} + +/************************************* + * Loading a cart image *not* from + * softlist + *************************************/ + +int base_md_cart_slot_device::load_nonlist() +{ + unsigned char *ROM, *tmpROM; + UINT32 len = length(); + + // this contains an hack for SSF2: its current bankswitch code needs larger rom space to work + m_cart->rom_alloc(machine(), (len == 0x500000) ? 0x900000 : len); + + ROM = (unsigned char *)m_cart->get_rom_base(); + tmpROM = global_alloc_array(unsigned char, len); + + // STEP 1: determine the file type (SMD? MD? BIN?) + fread(tmpROM, len); + + /* is this a SMD file? */ + if (genesis_is_SMD(&tmpROM[0x200], len)) + { + mame_printf_debug("SMD!\n"); + + for (int ptr = 0; ptr < (len - 0x200) / 0x2000; ptr += 2) + { + for (int x = 0; x < 0x2000; x++) + { + *ROM++ = *(tmpROM + 0x200 + ((ptr + 1) * 0x2000) + x); + *ROM++ = *(tmpROM + 0x200 + ((ptr + 0) * 0x2000) + x); + } + } + + len -= 0x200; + } + /* is this a MD file? */ + else if ((tmpROM[0x80] == 'E') && (tmpROM[0x81] == 'A') && (tmpROM[0x82] == 'M' || tmpROM[0x82] == 'G')) + { + mame_printf_debug("MD!\n"); + + for (int ptr = 0; ptr < len; ptr += 2) + { + ROM[ptr] = tmpROM[(len >> 1) + (ptr >> 1)]; + ROM[ptr + 1] = tmpROM[(ptr >> 1)]; + } + } + /* BIN it is, then */ + else + { + fseek(0, SEEK_SET); + fread(ROM, len); + } + + global_free(tmpROM); + + // STEP 2: determine the cart type (to deal with pirate mappers & eeprom) + m_type = get_cart_type(ROM, len); + +#ifdef LSB_FIRST + unsigned char fliptemp; + // is this really needed nowadays? + for (int ptr = 0; ptr < len; ptr += 2) + { + fliptemp = ROM[ptr]; + ROM[ptr] = ROM[ptr+1]; + ROM[ptr+1] = fliptemp; + } +#endif + + return IMAGE_INIT_PASS; +} + +/*------------------------------------------------- + call_unloadload + -------------------------------------------------*/ + +void base_md_cart_slot_device::call_unload() +{ + if (m_cart->get_nvram_size()) + battery_save(m_cart->get_nvram_base(), m_cart->get_nvram_size()); +} + + +void base_md_cart_slot_device::setup_custom_mappers() +{ + UINT16 *ROM16 = m_cart->get_rom_base(); + + switch (m_type) + { + case SSF2: + // copy the image in 0x400000-0x900000 and keep the beginning for bankswitch + for (int x = 0x500000/2; x > 0; x--) + ROM16[x + 0x400000/2 - 1] = ROM16[x - 1]; + for (int x = 0; x < 0x400000/2; x++) + ROM16[x] = ROM16[x + 0x400000/2]; + break; + case REDCL_EN: + // decrypt + for (int x = 0; x < 0x200000/2; x++) + ROM16[x] = ROM16[x + 2] ^ 0x4040; + break; + + // patch out protection in a bunch of titles... + case POKEMON: + /*todo: emulate protection instead + 0dd19e:47f8 + 0dd1a0:fff0 + 0dd1a2:4e63 + 0dd46e:4ef8 + 0dd470:0300 + 0dd49c:6002 + */ + /* you need to return 1 @ 0xa13002 and 0???1f @ 0xa1303e (it does word reads). */ + ROM16[0x0dd19e/2] = 0x47f8; + ROM16[0x0dd1a0/2] = 0xfff0; + ROM16[0x0dd1a2/2] = 0x4e63; + ROM16[0x0dd46e/2] = 0x4ef8; + ROM16[0x0dd470/2] = 0x0300; + ROM16[0x0dd49c/2] = 0x6002; + break; + case POKEMON2: + /*todo: emulate protection instead + 006036:e000 + 002540:6026 + 001ed0:6026 + 002476:6022 + */ + ROM16[0x06036/2] = 0xe000; + ROM16[0x02540/2] = 0x6026; + ROM16[0x01ed0/2] = 0x6026; + ROM16[0x02476/2] = 0x6022; + ROM16[0x7e300/2] = 0x60fe; + break; + case MULAN: + /*todo: emulate protection instead + 006036:e000 + +more? + */ + // ROM16[0x01ed0/2] = 0xe000; + // ROM16[0x02540/2] = 0xe000; + ROM16[0x06036/2] = 0xe000; + break; + } +} + +void base_md_cart_slot_device::setup_nvram() +{ + UINT8 *ROM = (UINT8 *)m_cart->get_rom_base(); + m_cart->m_nvram_readonly = 0; + m_cart->m_nvram_active = 0; + m_cart->m_nvram_handlers_installed = 0; + + /* install SRAM & i2c handlers for the specific type of cart */ + switch (m_type) + { + // These types only come from fullpath loading + case SEGA_SRAM_FULLPATH: + m_cart->m_nvram_start = (ROM[0x1b5] << 24 | ROM[0x1b4] << 16 | ROM[0x1b7] << 8 | ROM[0x1b6]); + m_cart->m_nvram_end = (ROM[0x1b9] << 24 | ROM[0x1b8] << 16 | ROM[0x1bb] << 8 | ROM[0x1ba]); + logerror("SRAM detected from header: starting location %X - SRAM Length %X\n", m_cart->m_nvram_start, m_cart->m_nvram_end - m_cart->m_nvram_start + 1); + + // We assume at most 64k of SRAM. is this correct? + if ((m_cart->m_nvram_start > m_cart->m_nvram_end) || ((m_cart->m_nvram_end - m_cart->m_nvram_start) >= 0x10000)) + m_cart->m_nvram_end = m_cart->m_nvram_start + 0xffff; + + if (m_cart->m_nvram_start & 1) + m_cart->m_nvram_start -= 1; + + if (!(m_cart->m_nvram_end & 1)) + m_cart->m_nvram_end += 1; + + m_cart->nvram_alloc(machine(), m_cart->m_nvram_end - m_cart->m_nvram_start + 1); + if (m_cart->m_rom_size <= m_cart->m_nvram_start) + m_cart->m_nvram_active = 1; + m_cart->m_nvram_handlers_installed = 1; + // don't trust too much header? + m_cart->m_nvram_start &= 0x3fffff; + m_cart->m_nvram_end &= 0x3fffff; + break; + case SEGA_SRAM_FALLBACK: + m_cart->m_nvram_start = 0x200000; + m_cart->m_nvram_end = m_cart->m_nvram_start + 0xffff; + m_cart->nvram_alloc(machine(), m_cart->m_nvram_end - m_cart->m_nvram_start + 1); + if (m_cart->m_rom_size <= m_cart->m_nvram_start) + m_cart->m_nvram_active = 1; + break; + + // These types only come from softlist loading + case SEGA_SRAM: + m_cart->m_nvram_start = 0x200000; + m_cart->m_nvram_end = m_cart->m_nvram_start + get_software_region_length("sram") - 1; + m_cart->nvram_alloc(machine(), m_cart->m_nvram_end - m_cart->m_nvram_start + 1); + if (m_cart->m_rom_size <= m_cart->m_nvram_start) + m_cart->m_nvram_active = 1; + m_cart->m_nvram_handlers_installed = 1; + break; + case SEGA_FRAM: + m_cart->m_nvram_start = 0x200000; + m_cart->m_nvram_end = m_cart->m_nvram_start + get_software_region_length("fram") - 1; + m_cart->nvram_alloc(machine(), m_cart->m_nvram_end - m_cart->m_nvram_start + 1); + m_cart->m_nvram_active = 1; + m_cart->m_nvram_handlers_installed = 1; + break; + + // These types might come from both (pending proper id routines) + case BEGGAR: + m_cart->m_nvram_start = 0x400000; + m_cart->m_nvram_end = m_cart->m_nvram_start + 0xffff; + m_cart->nvram_alloc(machine(), m_cart->m_nvram_end - m_cart->m_nvram_start + 1); + m_cart->m_nvram_active = 1; + m_cart->m_nvram_handlers_installed = 1; + break; + } +} + + + +/*------------------------------------------------- + call softlist load + -------------------------------------------------*/ + +bool base_md_cart_slot_device::call_softlist_load(char *swlist, char *swname, rom_entry *start_entry) +{ + load_software_part_region(this, swlist, swname, start_entry ); + return TRUE; +} + +int base_md_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len) +{ + int type = SEGA_STD; + + /* Detect carts which need additional handlers */ + static const unsigned char smouse_sig[] = { 0x4d, 0xf9, 0x00, 0x40, 0x00, 0x02 }, + mjlover_sig[] = { 0x13, 0xf9, 0x00, 0x40, 0x00, 0x00 }, // move.b ($400000).l,($FFFF0C).l (partial) + squir_sig[] = { 0x26, 0x79, 0x00, 0xff, 0x00, 0xfa }, + bugsl_sig[] = { 0x20, 0x12, 0x13, 0xc0, 0x00, 0xff }, + sbub_sig[] = { 0x0c, 0x39, 0x00, 0x55, 0x00, 0x40 }, // cmpi.b #$55,($400000).l + lk3_sig[] = { 0x0c, 0x01, 0x00, 0x30, 0x66, 0xe4 }, + sdk_sig[] = { 0x48, 0xe7, 0xff, 0xfe, 0x52, 0x79 }, + redcliff_sig[] = { 0x10, 0x39, 0x00, 0x40, 0x00, 0x04 }, // move.b ($400004).l,d0 + redcl_en_sig[] = { 0x50, 0x79, 0x40, 0x00, 0x40, 0x44 }, // move.b ($400004).l,d0 + smb_sig[] = { 0x20, 0x4d, 0x41, 0x52, 0x49, 0x4f }, + smb2_sig[] = { 0x4e, 0xb9, 0x00, 0x0f, 0x25, 0x84 }, + kaiju_sig[] = { 0x19, 0x7c, 0x00, 0x01, 0x00, 0x00 }, + chifi3_sig[] = { 0xb6, 0x16, 0x66, 0x00, 0x00, 0x4a }, + lionk2_sig[] = { 0x26, 0x79, 0x00, 0xff, 0x00, 0xf4 }, + rx3_sig[] = { 0x66, 0x00, 0x00, 0x0e, 0x30, 0x3c }, + kof98_sig[] = { 0x9b, 0xfc, 0x00, 0x00, 0x4a, 0x00 }, + s15in1_sig[] = { 0x22, 0x3c, 0x00, 0xa1, 0x30, 0x00 }, + kof99_sig[] = { 0x20, 0x3c, 0x30, 0x00, 0x00, 0xa1 }, // move.l #$300000A1,d0 + radica_sig[] = { 0x4e, 0xd0, 0x30, 0x39, 0x00, 0xa1 }, // jmp (a0) move.w ($a130xx),d0 + soulb_sig[] = { 0x33, 0xfc, 0x00, 0x0c, 0x00, 0xff }, // move.w #$C,($FF020A).l (what happens if check fails) + s19in1_sig[] = { 0x13, 0xc0, 0x00, 0xa1, 0x30, 0x38 }, + rockman_sig[] = { 0xea, 0x80 }; + + switch (len) + { + case 0x80000: + if (!memcmp(&ROM[0x08c8], smouse_sig, sizeof(smouse_sig))) + type = SMOUSE; + + if (!memcmp((char *)&ROM[0x7e30e], "SEGA", 4) || + !memcmp((char *)&ROM[0x7e100], "SEGA", 4) || + !memcmp((char *)&ROM[0x7e1e6], "SEGA", 4)) + type = REALTEC; + + if (!memcmp((char *)&ROM[0x0180], "GM T-50396", 10)) // NHLPA Hockey 93 + type = EA_NHLPA; + + if (!memcmp((char *)&ROM[0x0180], "GM MK-1215", 10)) // Evander Holyfield + type = SEGA_EEPROM; + break; + + case 0xc0000: + + if (!memcmp((char *)&ROM[0x0180], "GM G-4060 ", 8)) // Wonder Boy V + type = SEGA_EEPROM; + break; + + case 0x100000: + if (!memcmp(&ROM[0x01b24], mjlover_sig, sizeof(mjlover_sig))) + type = MJLOVER; + + if (!memcmp(&ROM[0x03b4], squir_sig, sizeof(squir_sig))) + type = SQUIRRELK; + + if (!memcmp(&ROM[0xee0d0], bugsl_sig, sizeof(bugsl_sig))) + type = BUGSLIFE; + + if (!memcmp((char *)&ROM[0x0172], "GAME : ELF WOR", 14)) + type = ELFWOR; + + if (!memcmp(&ROM[0x123e4], sbub_sig, sizeof(sbub_sig))) + type = SBUBBOB; + + if (!memcmp((char *)&ROM[0x0180], "GM T-50176", 10)) // Rings of Power + type = EA_NHLPA; + + if (!memcmp((char *)&ROM[0x0180], "MK 00001211-00", 14)) // Sports Talk Baseball + type = SEGA_EEPROM; + + if (!memcmp((char *)&ROM[0x0180], "GM T-120096-", 12)) // Micro Machines 2 + type = CODE_MASTERS; + + if (!memcmp((char *)&ROM[0x0180], "GM T-120146-", 12)) // Brian Lara Cricket 96 / Shane Wayne Cricket 96 + type = BRIAN_LARA; + + if (!memcmp((char *)&ROM[0x0190], "OJKRPTBVFCA ", 0x10)) // Micro Machines '96 / Military TODO: better way to recognize these? + type = CODE_MASTERS; + break; + + case 0x200000: + if (!memcmp(&ROM[0x18c6], lk3_sig, sizeof(lk3_sig))) + type = LIONK3; + + if (!memcmp(&ROM[0x220], sdk_sig, sizeof(sdk_sig))) + type = LIONK3; + + if (!memcmp(&ROM[0xce560], redcliff_sig, sizeof(redcliff_sig))) + type = REDCLIFF; + + if (!memcmp(&ROM[0xc8cb0], smb_sig, sizeof(smb_sig))) + type = SMB; + + if (!memcmp(&ROM[0xf24d6], smb2_sig, sizeof(smb2_sig))) + type = SMB2; + + if (!memcmp(&ROM[0x674e], kaiju_sig, sizeof(kaiju_sig))) + type = KAIJU; + + if (!memcmp(&ROM[0x1780], chifi3_sig, sizeof(chifi3_sig))) + type = CHINFIGHT3; + + if (!memcmp(&ROM[0x03c2], lionk2_sig, sizeof(lionk2_sig))) + type = LIONK2; + + if (!memcmp(&ROM[0xc8b90], rx3_sig, sizeof(rx3_sig))) + type = ROCKMANX3; + + if (!memcmp(&ROM[0x56ae2], kof98_sig, sizeof(kof98_sig))) + type = KOF98; + + if (!memcmp(&ROM[0x17bb2], s15in1_sig, sizeof(s15in1_sig))) + type = MC_PIRATE; + + if (!memcmp((char *)&ROM[0x0180], "GM T-081326 ", 12)) // NBA Jam + type = NBA_JAM; + + if (!memcmp((char *)&ROM[0x0180], "GM MK-1228", 10)) // Greatest Heavyweight of the Ring + type = SEGA_EEPROM; + + if ((!memcmp((char *)&ROM[0x0180], "GM T-12046", 10)) || // Mega Man + (!memcmp((char *)&ROM[0x0180], "GM T-12053", 10) && !memcmp(&ROM[0x18e], rockman_sig, sizeof(rockman_sig)))) // / Rock Man (EEPROM version) + type = SEGA_EEPROM; + + break; + + case 0x200005: + if (!memcmp(&ROM[0xce564], redcl_en_sig, sizeof(redcliff_sig))) + type = REDCL_EN; + break; + + case 0x300000: + if (!memcmp(&ROM[0x220], sdk_sig, sizeof(sdk_sig))) + type = LIONK3; + + if (!memcmp(&ROM[0x1fd0d2], kof99_sig, sizeof(kof99_sig))) + type = KOF99; + + if (!memcmp((char *)&ROM[0x0180], "GM T-81406", 10)) // NBA Jam TE + type = NBA_JAM_TE; + + if (!memcmp((char *)&ROM[0x0180], "GM T-081276 ", 12)) // NFL Quarterback Club + type = NBA_JAM_TE; + + break; + + case 0x400000: + if (!memcmp(&ROM[0x3c031c], radica_sig, sizeof(radica_sig)) || + !memcmp(&ROM[0x3f031c], radica_sig, sizeof(radica_sig))) // ssf+gng + radica vol1 + type = RADICA; + + if (!memcmp(&ROM[0x028460], soulb_sig, sizeof(soulb_sig))) + type = SOULBLAD; + + if (!memcmp(&ROM[0x1e700], s19in1_sig, sizeof(s19in1_sig))) + type = MC_PIRATE; + + if (!memcmp((char *)&ROM[0x0180], "GM T-081586-", 12)) // NFL Quarterback Club 96 + type = NFL_QB_96; + + if (!memcmp((char *)&ROM[0x0180], "GM T-081576 ", 12)) // College Slam + type = C_SLAM; + + if (!memcmp((char *)&ROM[0x0180], "GM T-81476", 10)) // Big Hurt Baseball + type = C_SLAM; + + break; + + case 0x500000: + if (!memcmp((char *)&ROM[0x0120], "SUPER STREET FIGHTER2 ", 22)) + type = SSF2; + break; + + case 0x800000: + if (!memcmp((char *)&ROM[0x0180], "GM T-574023-", 12)) // Pier Solar + type = PSOLAR; + break; + + default: + break; + } + + //check for SRAM among the general carts + if (type == SEGA_STD) + { + // If the cart is not of a special type, we check the header for SRAM. + if (ROM[0x1b1] == 'R' && ROM[0x1b0] == 'A') + { + UINT32 start, end; + start = (ROM[0x1b5] << 24 | ROM[0x1b4] << 16 | ROM[0x1b7] << 8 | ROM[0x1b6]); + end = (ROM[0x1b9] << 24 | ROM[0x1b8] << 16 | ROM[0x1bb] << 8 | ROM[0x1ba]); + logerror("SRAM detected from header: starting location %X - SRAM Length %X\n", start, end - start + 1); + + // For some games using serial EEPROM, difference between SRAM end to start is 0 or 1. + // Carts with EEPROM should have been already detected above, but better safe than sorry + if (end - start < 2) + type = SEGA_EEPROM; + else + type = SEGA_SRAM_FULLPATH; + } + else + { + // Unfortunately, there are ROMs without correct info in the header, + // Hence, when loading from fullpath we do the SRAM mapping anyway... + // but treat it in a custom way + type = SEGA_SRAM_FALLBACK; + } + } + + return type; +} +/*------------------------------------------------- + get default card software + -------------------------------------------------*/ + +const char * base_md_cart_slot_device::get_default_card_software(const machine_config &config, emu_options &options) +{ + const char *slot_string = "rom"; + + if (open_image_file(options)) + { + UINT32 len = core_fsize(m_file); + UINT8 *ROM = global_alloc_array(UINT8, len); + int type; + + core_fread(m_file, ROM, len); + + type = get_cart_type(ROM, len); + slot_string = md_get_slot(type); + + global_free(ROM); + clear(); + + return slot_string; + } + else + return software_get_default_slot(config, options, this, "rom"); +} + + + +/*------------------------------------------------- + read + -------------------------------------------------*/ + +READ16_MEMBER(base_md_cart_slot_device::read) +{ + if (m_cart) + return m_cart->read(space, offset); + else + return 0xffff; +} + +READ16_MEMBER(base_md_cart_slot_device::read_a13) +{ + if (m_cart) + return m_cart->read_a13(space, offset); + else + return 0xffff; +} + +READ16_MEMBER(base_md_cart_slot_device::read_a15) +{ + if (m_cart) + return m_cart->read_a15(space, offset); + else + return 0xffff; +} + + +/*------------------------------------------------- + write + -------------------------------------------------*/ + +WRITE16_MEMBER(base_md_cart_slot_device::write) +{ + if (m_cart) + m_cart->write(space, offset, data); +} + +WRITE16_MEMBER(base_md_cart_slot_device::write_a13) +{ + if (m_cart) + m_cart->write_a13(space, offset, data); +} + +WRITE16_MEMBER(base_md_cart_slot_device::write_a15) +{ + if (m_cart) + m_cart->write_a15(space, offset, data); +} + diff --git a/src/mess/machine/md_slot.h b/src/mess/machine/md_slot.h new file mode 100644 index 00000000000..fca02970d83 --- /dev/null +++ b/src/mess/machine/md_slot.h @@ -0,0 +1,242 @@ +#ifndef __MD_SLOT_H +#define __MD_SLOT_H + +/*************************************************************************** + TYPE DEFINITIONS + ***************************************************************************/ + + +/* PCB */ +enum +{ + SEGA_STD = 0, + + // Cart + Slot Expansion + SEGA_SK, /* Sonic & Knuckles pass-through cart */ + + // Cart + SVP + SEGA_SVP, /* Virtua Racing */ + + // Cart + NVRAM + SEGA_SRAM, SEGA_FRAM, + BEGGAR, /* Xin Qigai Wangzi uses different sram start address and has no valid header */ + + // EEPROM + SEGA_EEPROM, /* Wonder Boy V / Evander Holyfield's Boxing / Greatest Heavyweights of the Ring / Sports Talk Baseball / Megaman */ + NBA_JAM, /* NBA Jam */ + NBA_JAM_TE, /* NBA Jam TE / NFL Quarterback Club */ + NFL_QB_96, /* NFL Quarterback Club '96 */ + C_SLAM, /* College Slam / Frank Thomas Big Hurt Baseball */ + EA_NHLPA, /* NHLPA Hockey 93 / Rings of Power */ + BRIAN_LARA, /* Brian Lara Cricket 96 */ + PSOLAR, /* Pier Solar (STM95 EEPROM) */ + + // J-Cart + CM_JCART, /* Pete Sampras Tennis */ + CODE_MASTERS, /* Micro Machines 2 / Military (J-Cart + SEPROM) */ + CM_MM96, /* Micro Machines 96 (J-Cart + SEPROM, diff I2C model) */ + + // Various + SSF2, /* Super Street Fighter 2 */ + GAME_KANDUME, /* Game no Kandume Otokuyou */ + RADICA, /* Radica TV games.. these probably should be a separate driver since they are a separate 'console' */ + + BUGSLIFE, /* A Bug's Life */ + CHINFIGHT3, /* Chinese Fighters 3 */ + ELFWOR, /* Linghuan Daoshi Super Magician */ + KAIJU, /* Pokemon Stadium */ + KOF98, /* King of Fighters '98 */ + KOF99, /* King of Fighters '99 */ + LIONK2, /* Lion King 2 */ + LIONK3, /* Lion King 3, Super Donkey Kong 99, Super King Kong 99 */ + MC_PIRATE, /* Super 19 in 1, Super 15 in 1, 12 in 1 and a few more multicarts */ + MJLOVER, /* Mahjong Lover */ + MULAN, /* Hua Mu Lan - Mulan */ + POKEMON, /* Pocket Monster */ + POKEMON2, /* Pocket Monster 2 */ + REALTEC, /* Whac a Critter/Mallet legend, Defend the Earth, Funnyworld/Ballonboy */ + REDCLIFF, /* Romance of the Three Kingdoms - Battle of Red Cliffs, already decoded from .mdx format */ + REDCL_EN, /* The encoded version... */ + ROCKMANX3, /* Rockman X3 */ + SBUBBOB, /* Super Bubble Bobble */ + SMB, /* Super Mario Bros. */ + SMB2, /* Super Mario Bros. 2 */ + SMOUSE, /* Smart Mouse */ + SOULBLAD, /* Soul Blade */ + SQUIRRELK, /* Squirrel King */ + TOPFIGHTER, /* Top Fighter 2000 MK VIII */ + + // when loading from fullpath, we need to treat SRAM in custom way + SEGA_SRAM_FULLPATH, + SEGA_SRAM_FALLBACK +}; + + +// ======================> md_cart_interface + +struct md_cart_interface +{ +}; + + +// ======================> device_md_cart_interface + +class device_md_cart_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_md_cart_interface(const machine_config &mconfig, device_t &device); + virtual ~device_md_cart_interface(); + + // reading and writing + virtual DECLARE_READ16_MEMBER(read) { return 0xffff; } + virtual DECLARE_WRITE16_MEMBER(write) {} + virtual DECLARE_READ16_MEMBER(read_a13) { return 0xffff; }; + virtual DECLARE_WRITE16_MEMBER(write_a13) {}; + virtual DECLARE_READ16_MEMBER(read_a15) { return 0xffff; }; + virtual DECLARE_WRITE16_MEMBER(write_a15) {}; + + /* this probably should do more, like make Genesis V2 'die' if the SEGA string is not written promptly */ + virtual DECLARE_WRITE16_MEMBER(write_tmss_bank) { logerror("Write to TMSS bank: offset %x data %x\n", 0xa14000 + (offset << 1), data); }; + + virtual void rom_alloc(running_machine &machine, size_t size); + virtual void nvram_alloc(running_machine &machine, size_t size); + virtual UINT16* get_rom_base() { return m_rom; }; + virtual UINT16* get_nvram_base() { return m_nvram; }; + virtual UINT32 get_rom_size() { return m_rom_size; }; + virtual UINT32 get_nvram_size() { return m_nvram_size; }; + + int m_nvram_start, m_nvram_end; + int m_nvram_active, m_nvram_readonly; + + // when loading from fullpath, we create NVRAM even if not set in the header + // however in this case we access it only if the game turn it on + // the variable below is basically needed to track this... + int m_nvram_handlers_installed; + + // internal state + UINT16 *m_rom; + UINT16 *m_nvram; + UINT32 m_rom_size; + UINT32 m_nvram_size; +}; + + +// ======================> base_md_cart_slot_device + +class base_md_cart_slot_device : public device_t, + public md_cart_interface, + public device_image_interface, + public device_slot_interface +{ +public: + // construction/destruction + base_md_cart_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); + virtual ~base_md_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(char *swlist, char *swname, rom_entry *start_entry); + + virtual int load_list(); + virtual int load_nonlist(); + virtual int get_cart_type(UINT8 *ROM, UINT32 len); + + + virtual void setup_custom_mappers(); + virtual void setup_nvram(); + + 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 0; } + virtual const option_guide *create_option_guide() const { return NULL; } + + // slot interface overrides + virtual const char * get_default_card_software(const machine_config &config, emu_options &options); + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_WRITE16_MEMBER(write); + virtual DECLARE_READ16_MEMBER(read_a13); + virtual DECLARE_WRITE16_MEMBER(write_a13); + virtual DECLARE_READ16_MEMBER(read_a15); + virtual DECLARE_WRITE16_MEMBER(write_a15); + +// FIXME: +// this should be private, but then there is some problem installing delegates in the driver... +//private: + + device_md_cart_interface* m_cart; + + int m_type; +}; + +// ======================> md_cart_slot_device + +class md_cart_slot_device : public base_md_cart_slot_device +{ +public: + // construction/destruction + md_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual const char *image_interface() const { return "megadriv_cart"; } + virtual const char *file_extensions() const { return "smd,bin,md,gen"; } +}; + + +// ======================> md_subcart_slot_device + +class md_subcart_slot_device : public base_md_cart_slot_device +{ +public: + // construction/destruction + md_subcart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual bool must_be_loaded() const { return 0; } + virtual const char *image_interface() const { return "megadriv_cart"; } + virtual const char *file_extensions() const { return "smd,bin,md,gen"; } +}; + + +// ======================> pico_cart_slot_device + +class pico_cart_slot_device : public base_md_cart_slot_device +{ +public: + // construction/destruction + pico_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual const char *image_interface() const { return "pico_cart"; } + virtual const char *file_extensions() const { return "bin,md"; } +}; + + +// device type definition +extern const device_type MD_CART_SLOT; +extern const device_type MD_SUBCART_SLOT; // needed to allow S&K pass-through to have non-mandatory cart +extern const device_type PICO_CART_SLOT; + + +/*************************************************************************** + DEVICE CONFIGURATION MACROS + ***************************************************************************/ + +#define MCFG_MD_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \ + MCFG_DEVICE_ADD(_tag, MD_CART_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false) + +#define MCFG_MDSUB_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \ + MCFG_DEVICE_ADD(_tag, MD_SUBCART_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false) + +#define MCFG_PICO_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \ + MCFG_DEVICE_ADD(_tag, PICO_CART_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false) + + +#endif diff --git a/src/mess/machine/md_stm95.c b/src/mess/machine/md_stm95.c new file mode 100644 index 00000000000..997cf1fdbda --- /dev/null +++ b/src/mess/machine/md_stm95.c @@ -0,0 +1,245 @@ +/*************************************************************************** + + + MegaDrive / Genesis Cart + STM95 EEPROM device + + + Emulation by MetalliC, converted to slot by Fabio Priuli + + + TO DO: split STM95 to a separate device... + +***************************************************************************/ + + +#include "emu.h" +#include "machine/md_stm95.h" + + +void stm95_eeprom_device::set_cs_line(int state) +{ + reset_line = state; + if (reset_line != CLEAR_LINE) + { + stream_pos = 0; + stm_state = IDLE; + } +} + +void stm95_eeprom_device::set_si_line(int state) +{ + latch = state; +} + +int stm95_eeprom_device::get_so_line(void) +{ + if (stm_state == READING || stm_state == CMD_RDSR) + return (stream_data >> 8) & 1; + else + return 0; +} + +void stm95_eeprom_device::set_sck_line(int state) +{ + if (reset_line == CLEAR_LINE) + { + if (state == ASSERT_LINE && sck_line == CLEAR_LINE) + { + switch (stm_state) + { + case IDLE: + stream_data = (stream_data << 1) | (latch ? 1 : 0); + stream_pos++; + if (stream_pos == 8) + { + stream_pos = 0; + //printf("STM95 EEPROM: got cmd %02X\n", stream_data&0xff); + switch(stream_data & 0xff) + { + case 0x01: // write status register + if (WEL != 0) + stm_state = CMD_WRSR; + WEL = 0; + break; + case 0x02: // write + if (WEL != 0) + stm_state = CMD_WRITE; + stream_data = 0; + WEL = 0; + break; + case 0x03: // read + stm_state = M95320_CMD_READ; + stream_data = 0; + break; + case 0x04: // write disable + WEL = 0; + break; + case 0x05: // read status register + stm_state = CMD_RDSR; + stream_data = WEL<<1; + break; + case 0x06: // write enable + WEL = 1; + break; + default: + logerror("STM95 EEPROM: unknown cmd %02X\n", stream_data&0xff); + } + } + break; + case CMD_WRSR: + stream_pos++; // just skip, don't care block protection + if (stream_pos == 8) + { + stm_state = IDLE; + stream_pos = 0; + } + break; + case CMD_RDSR: + stream_data = stream_data<<1; + stream_pos++; + if (stream_pos == 8) + { + stm_state = IDLE; + stream_pos = 0; + } + break; + case M95320_CMD_READ: + stream_data = (stream_data << 1) | (latch ? 1 : 0); + stream_pos++; + if (stream_pos == 16) + { + eeprom_addr = stream_data & (M95320_SIZE - 1); + stream_data = eeprom_data[eeprom_addr]; + stm_state = READING; + stream_pos = 0; + } + break; + case READING: + stream_data = stream_data<<1; + stream_pos++; + if (stream_pos == 8) + { + if (++eeprom_addr == M95320_SIZE) + eeprom_addr = 0; + stream_data |= eeprom_data[eeprom_addr]; + stream_pos = 0; + } + break; + case CMD_WRITE: + stream_data = (stream_data << 1) | (latch ? 1 : 0); + stream_pos++; + if (stream_pos == 16) + { + eeprom_addr = stream_data & (M95320_SIZE - 1); + stm_state = WRITING; + stream_pos = 0; + } + break; + case WRITING: + stream_data = (stream_data << 1) | (latch ? 1 : 0); + stream_pos++; + if (stream_pos == 8) + { + eeprom_data[eeprom_addr] = stream_data; + if (++eeprom_addr == M95320_SIZE) + eeprom_addr = 0; + stream_pos = 0; + } + break; + } + } + } + sck_line = state; +} + + + +//------------------------------------------------- +// md_rom_device - constructor +//------------------------------------------------- + +const device_type MD_EEPROM_STM95 = &device_creator; + + +md_eeprom_stm95_device::md_eeprom_stm95_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, type, name, tag, owner, clock), + device_md_cart_interface( mconfig, *this ) +{ +} + +md_eeprom_stm95_device::md_eeprom_stm95_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MD_EEPROM_STM95, "MD Cart + EEPROM STM95", tag, owner, clock), + device_md_cart_interface( mconfig, *this ) +{ +} + + +void md_eeprom_stm95_device::device_start() +{ + m_rdcnt = 0; + m_bank[0] = 0; + m_bank[1] = 0; + m_bank[2] = 0; + nvram_alloc(machine(), M95320_SIZE); + m_stm95.eeprom_data = (UINT8*)get_nvram_base(); +} + +/*------------------------------------------------- + mapper specific handlers + -------------------------------------------------*/ + +READ16_MEMBER(md_eeprom_stm95_device::read) +{ + if (offset == 0x0015e6/2 || offset == 0x0015e8/2) + { + // ugly hack until we don't know much about game protection + // first 3 reads from 15e6 return 0x00000010, then normal 0x00018010 value for crc check + UINT16 res; + offset -= 0x0015e6/2; + logerror("read 0x15e6 %d\n", m_rdcnt); + if (m_rdcnt < 6) + { + m_rdcnt++; + res = offset ? 0x10 : 0; + } + else + res = offset ? 0x8010 : 0x0001; + return res; + } + if (offset < 0x280000/2) + return m_rom[offset]; + else // last 0x180000 are bankswitched + { + UINT8 bank = (offset - 0x280000/2) >> 18; + return m_rom[(offset & 0x7ffff/2) + (m_bank[bank] * 0x80000)/2]; + } +} + +READ16_MEMBER(md_eeprom_stm95_device::read_a13) +{ + if (offset == 0x0a/2) + { + return m_stm95.get_so_line() & 1; + } + return 0xffff; +} + +WRITE16_MEMBER(md_eeprom_stm95_device::write_a13) +{ + if (offset == 0x00/2) + { + logerror("A13001 write %02x\n", data); + } + else if (offset < 0x08/2) + { + m_bank[offset - 1] = data & 0x0f; + } + else if (offset < 0x0a/2) + { + m_stm95.set_si_line(BIT(data, 0)); + m_stm95.set_sck_line(BIT(data, 1)); + m_stm95.set_halt_line(BIT(data, 2)); + m_stm95.set_cs_line(BIT(data, 3)); + } +} + diff --git a/src/mess/machine/md_stm95.h b/src/mess/machine/md_stm95.h new file mode 100644 index 00000000000..77bbad98e73 --- /dev/null +++ b/src/mess/machine/md_stm95.h @@ -0,0 +1,84 @@ +#ifndef __MD_STM95_H +#define __MD_STM95_H + +#include "machine/md_slot.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +/* ST M95320 32Kbit serial EEPROM implementation */ +// TO DO: STM95 should be made a separate EEPROM device and this should be merged with md_eeprom.c! + +#define M95320_SIZE 0x1000 + +enum STMSTATE +{ + IDLE = 0, + CMD_WRSR, + CMD_RDSR, + M95320_CMD_READ, + CMD_WRITE, + READING, + WRITING +}; + +class stm95_eeprom_device +{ +public: + stm95_eeprom_device() : + stm_state(IDLE), + stream_pos(0) + {}; + + UINT8 *eeprom_data; + void set_cs_line(int); + void set_halt_line(int state) {}; // not implemented + void set_si_line(int); + void set_sck_line(int state); + int get_so_line(void); + +protected: + int latch; + int reset_line; + int sck_line; + int WEL; + + STMSTATE stm_state; + int stream_pos; + int stream_data; + int eeprom_addr; +}; + + +// ======================> md_eeprom_stm95_device + +class md_eeprom_stm95_device : public device_t, + public device_md_cart_interface +{ +public: + // construction/destruction + md_eeprom_stm95_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); + md_eeprom_stm95_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_config_complete() { m_shortname = "md_eeprom_stm95"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); + virtual DECLARE_READ16_MEMBER(read_a13); + virtual DECLARE_WRITE16_MEMBER(write_a13); + +private: + UINT8 m_bank[3]; + int m_rdcnt; + + stm95_eeprom_device m_stm95; +}; + + +// device type definition +extern const device_type MD_EEPROM_STM95; + +#endif diff --git a/src/mame/machine/megasvp.c b/src/mess/machine/megasvp.c similarity index 91% rename from src/mame/machine/megasvp.c rename to src/mess/machine/megasvp.c index 7cb2c4cc02d..bbe7e3c3827 100644 --- a/src/mame/machine/megasvp.c +++ b/src/mess/machine/megasvp.c @@ -1,11 +1,6 @@ /* Megadrive SVP emulation (Virtua Racing) */ -#include "includes/megadriv.h" - - - -/* SVP (virtua racing) */ -cpu_device *_svp_cpu; +#include "includes/md.h" /****************************************** SVP related *****************************************/ @@ -65,15 +60,15 @@ static UINT32 pm_io(address_space &space, int reg, int write, UINT32 d) state->m_emu_status &= ~SSP_PMC_SET; return 0; } - + // just in case if (state->m_emu_status & SSP_PMC_HAVE_ADDR) { state->m_emu_status &= ~SSP_PMC_HAVE_ADDR; } - + if (reg == 4 || (space.device().state().state_int(SSP_ST) & 0x60)) { - #define CADDR ((((mode<<16)&0x7f0000)|addr)<<1) +#define CADDR ((((mode<<16)&0x7f0000)|addr)<<1) UINT16 *dram = (UINT16 *)state->m_dram; if (write) { @@ -83,14 +78,14 @@ static UINT32 pm_io(address_space &space, int reg, int write, UINT32 d) { int inc = get_inc(mode); if (mode & 0x0400) { - overwrite_write(&dram[addr], d); + overwrite_write(&dram[addr], d); } else dram[addr] = d; state->m_pmac_write[reg] += inc; } else if ((mode & 0xfbff) == 0x4018) // DRAM, cell inc { if (mode & 0x0400) { - overwrite_write(&dram[addr], d); + overwrite_write(&dram[addr], d); } else dram[addr] = d; state->m_pmac_write[reg] += (addr&1) ? 31 : 1; } @@ -103,7 +98,7 @@ static UINT32 pm_io(address_space &space, int reg, int write, UINT32 d) else { logerror("ssp FIXME: PM%i unhandled write mode %04x, [%06x] %04x\n", - reg, mode, CADDR, d); + reg, mode, CADDR, d); } } else @@ -125,17 +120,17 @@ static UINT32 pm_io(address_space &space, int reg, int write, UINT32 d) else { logerror("ssp FIXME: PM%i unhandled read mode %04x, [%06x]\n", - reg, mode, CADDR); + reg, mode, CADDR); d = 0; } } - + // PMC value corresponds to last PMR accessed (not sure). state->m_pmc.d = state->m_pmac_read[write ? reg + 6 : reg]; - + return d; } - + return (UINT32)-1; } @@ -192,7 +187,7 @@ static READ16_HANDLER( read_XST ) mdsvp_state *state = space.machine().driver_data(); UINT32 d = pm_io(space, 3, 0, 0); if (d != (UINT32)-1) return d; - + return state->m_XST; } @@ -201,7 +196,7 @@ static WRITE16_HANDLER( write_XST ) mdsvp_state *state = space.machine().driver_data(); UINT32 r = pm_io(space, 3, 1, data); if (r != (UINT32)-1) return; - + state->m_XST2 |= 1; state->m_XST = data; } @@ -261,10 +256,10 @@ static READ16_HANDLER( svp_68k_io_r ) UINT32 d; switch (offset) { - // 0xa15000, 0xa15002 + // 0xa15000, 0xa15002 case 0: case 1: return state->m_XST; - // 0xa15004 + // 0xa15004 case 2: d = state->m_XST2; state->m_XST2 &= ~1; return d; default: logerror("unhandled SVP reg read @ %x\n", offset<<1); } @@ -276,10 +271,10 @@ static WRITE16_HANDLER( svp_68k_io_w ) mdsvp_state *state = space.machine().driver_data(); switch (offset) { - // 0xa15000, 0xa15002 + // 0xa15000, 0xa15002 case 0: case 1: state->m_XST = data; state->m_XST2 |= 2; break; - // 0xa15006 + // 0xa15006 case 3: break; // possibly halts SSP1601 default: logerror("unhandled SVP reg write %04x @ %x\n", data, offset<<1); } @@ -320,20 +315,9 @@ ADDRESS_MAP_START( svp_ext_map, AS_IO, 16, driver_device ) ADDRESS_MAP_END -/* emulate testmode plug */ -static UINT8 megadrive_io_read_data_port_svp(running_machine &machine, int portnum) -{ - if (portnum == 0 && machine.root_device().ioport("MEMORY_TEST")->read_safe(0x00)) - { - return (megadrive_io_data_regs[0] & 0xc0); - } - return megadrive_io_read_data_port_3button(machine, portnum); -} - - static READ16_HANDLER( svp_speedup_r ) { - space.device().execute().spin_until_time(attotime::from_usec(100)); + space.device().execute().spin_until_time(attotime::from_usec(100)); return 0x0425; } @@ -341,8 +325,8 @@ static READ16_HANDLER( svp_speedup_r ) void svp_init(running_machine &machine) { mdsvp_state *state = machine.driver_data(); - UINT8 *ROM; - + UINT8 *ROM = state->memregion("maincpu")->base(); + memset(state->m_pmac_read, 0, ARRAY_LENGTH(state->m_pmac_read)); memset(state->m_pmac_write, 0, ARRAY_LENGTH(state->m_pmac_write)); state->m_pmc.d = 0; @@ -351,7 +335,7 @@ void svp_init(running_machine &machine) state->m_emu_status = 0; state->m_XST = 0; state->m_XST2 = 0; - + /* SVP stuff */ state->m_dram = auto_alloc_array(machine, UINT8, 0x20000); machine.device("maincpu")->memory().space(AS_PROGRAM).install_ram(0x300000, 0x31ffff, state->m_dram); @@ -359,14 +343,14 @@ void svp_init(running_machine &machine) // "cell arrange" 1 and 2 machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x390000, 0x39ffff, FUNC(svp_68k_cell1_r)); machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x3a0000, 0x3affff, FUNC(svp_68k_cell2_r)); - + machine.device("svp")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x438, 0x438, FUNC(svp_speedup_r)); + if (state->m_slotcart->m_cart->get_rom_base() != NULL) + memcpy(ROM, state->m_slotcart->m_cart->get_rom_base(), state->m_slotcart->m_cart->get_rom_size()); + state->m_iram = auto_alloc_array(machine, UINT8, 0x800); state->membank("bank3")->set_base(state->m_iram); /* SVP ROM just shares m68k region.. */ - ROM = state->memregion("maincpu")->base(); state->membank("bank4")->set_base(ROM + 0x800); - - megadrive_io_read_data_port_ptr = megadrive_io_read_data_port_svp; } diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 891990e0ddd..471350165fc 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -455,7 +455,6 @@ $(MESSOBJ)/mame.a: \ $(MAME_MACHINE)/megacd.o \ $(MAME_MACHINE)/megacdcd.o \ $(MAME_MACHINE)/mega32x.o \ - $(MAME_MACHINE)/megasvp.o \ $(MAME_MACHINE)/megavdp.o \ $(MAME_MACHINE)/dc.o \ $(MAME_DRIVERS)/naomi.o \ @@ -1617,7 +1616,13 @@ $(MESSOBJ)/sanyo.a: \ $(MESSOBJ)/sega.a: \ $(MESS_DRIVERS)/sg1000.o \ - $(MAME_MACHINE)/md_cart.o \ + $(MESS_MACHINE)/md_slot.o \ + $(MESS_MACHINE)/md_rom.o \ + $(MESS_MACHINE)/md_sk.o \ + $(MESS_MACHINE)/md_eeprom.o \ + $(MESS_MACHINE)/md_jcart.o \ + $(MESS_MACHINE)/md_stm95.o \ + $(MESS_MACHINE)/megasvp.o \ $(MESS_DRIVERS)/megadriv.o \ $(MESS_DRIVERS)/dccons.o \ $(MAME_MACHINE)/gdrom.o \