1 // license:BSD-3-Clause
2 // copyright-holders:S. Smith,David Haywood,Fabio Priuli
3
4
5 #include "emu.h"
6 #include "prot_kof98.h"
7
8 DEFINE_DEVICE_TYPE(NG_KOF98_PROT, kof98_prot_device, "ng_kof98_prot", "Neo Geo KoF 98 Protection")
9
10
kof98_prot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)11 kof98_prot_device::kof98_prot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
12 device_t(mconfig, NG_KOF98_PROT, tag, owner, clock),
13 m_prot_state(0)
14 {
15 }
16
17
device_start()18 void kof98_prot_device::device_start()
19 {
20 save_item(NAME(m_prot_state));
21 }
22
device_reset()23 void kof98_prot_device::device_reset()
24 {
25 }
26
27
28 /* Kof98 uses an early encryption, quite different from the others */
decrypt_68k(uint8_t * cpurom,uint32_t cpurom_size)29 void kof98_prot_device::decrypt_68k(uint8_t* cpurom, uint32_t cpurom_size)
30 {
31 uint8_t *src = cpurom;
32 std::vector<uint8_t> dst(0x200000);
33 int i, j, k;
34 static const uint32_t sec[]={ 0x000000, 0x100000, 0x000004, 0x100004, 0x10000a, 0x00000a, 0x10000e, 0x00000e };
35 static const uint32_t pos[]={ 0x000, 0x004, 0x00a, 0x00e };
36
37 memcpy(&dst[0], src, 0x200000);
38 for (i = 0x800; i < 0x100000; i += 0x200)
39 {
40 for (j = 0; j < 0x100; j += 0x10)
41 {
42 for (k = 0; k < 16; k += 2)
43 {
44 memcpy(&src[i+j+k], &dst[i+j+sec[k/2]+0x100], 2);
45 memcpy(&src[i+j+k+0x100], &dst[i+j+sec[k/2]], 2);
46 }
47 if (i >= 0x080000 && i < 0x0c0000)
48 {
49 for (k = 0; k < 4; k++)
50 {
51 memcpy(&src[i+j+pos[k]], &dst[i+j+pos[k]], 2);
52 memcpy(&src[i+j+pos[k]+0x100], &dst[i+j+pos[k]+0x100], 2);
53 }
54 }
55 else if (i >= 0x0c0000)
56 {
57 for (k = 0; k < 4; k++)
58 {
59 memcpy(&src[i+j+pos[k]], &dst[i+j+pos[k]+0x100], 2);
60 memcpy(&src[i+j+pos[k]+0x100], &dst[i+j+pos[k]], 2);
61 }
62 }
63 }
64 memcpy(&src[i+0x000000], &dst[i+0x000000], 2);
65 memcpy(&src[i+0x000002], &dst[i+0x100000], 2);
66 memcpy(&src[i+0x000100], &dst[i+0x000100], 2);
67 memcpy(&src[i+0x000102], &dst[i+0x100100], 2);
68 }
69 memmove(&src[0x100000], &src[0x200000], 0x400000);
70
71 uint16_t* mem16 = (uint16_t*)cpurom;
72 m_default_rom[0] = mem16[0x100/2];
73 m_default_rom[1] = mem16[0x102/2];
74 }
75
76
77 /************************ King of Fighters 98*******************
78 The encrypted set has a rom overlay feature, checked at
79 various points in the game.
80 Boards used: NEO-MVS PROGSF1 (1998.6.17) / NEO-MVS PROGSF1E (1998.6.18)
81 The boards have an ALTERA chip (EPM7128SQC100-15) which is tied to 242-P1
82 ***************************************************************/
83
protection_r(offs_t offset)84 uint16_t kof98_prot_device::protection_r(offs_t offset)
85 {
86 if (m_prot_state == 1)
87 {
88 if (!offset)
89 return 0x00c2;
90 else
91 return 0x00fd;
92 }
93 if (m_prot_state == 2)
94 {
95 if (!offset)
96 return 0x4e45;
97 else
98 return 0x4f2d;
99 }
100
101 if (!offset)
102 return m_default_rom[0];
103 else
104 return m_default_rom[1];
105 }
106
107
108 /* when 0x20aaaa contains 0x0090 (word) then 0x100 (normally the neogeo header) should return 0x00c200fd worked out using real hw */
protection_w(uint16_t data)109 void kof98_prot_device::protection_w(uint16_t data)
110 {
111 /* info from razoola */
112 switch (data)
113 {
114 case 0x0090:
115 logerror ("%s kof98 - protection 0x0090x\n", machine().describe_context());
116 m_prot_state = 1;
117 break;
118
119 case 0x00f0:
120 logerror ("%s kof98 - protection 0x00f0x\n", machine().describe_context());
121 m_prot_state = 2;
122 break;
123
124 default: // 00aa is written, but not needed?
125 logerror ("%s kof98 - unknown protection write %04x\n", machine().describe_context(), data);
126 break;
127 }
128 }
129