1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood, ElSemi, Xing Xing
3 /***********************************************************************
4 PGM IGS027A ARM protection simulations & emulation - type 1
5
6 these are simulations of the 'kov' type ARM device
7 used by
8
9 Knights of Valor (kov) + bootlegs
10 Knights of Valor Plus (kovplus)
11 Puzzli 2 / Puzzli 2 Super (puzzli2s)
12 Photo Y2k2 (py2k2)
13 Photo Y2k2 - Flash 3-in-1 (pgm3in1)
14 Puzzle Star (puzlstar)
15
16 These are implemented in 55857E type chips
17
18 the following appear to have the same basic behavior as the
19 early '55857E' type chips, but are actually using the '55857G'
20 chips, which execute only area (confirmed on ddpdoj at least)
21
22 DoDonPachi Dai-ou-jou (ddpdoj)
23 Espgaluda (espgal)
24 Ketsui (ket)
25 Oriental Legend Super Plus (oldsplus)
26 Knights of Valor Super Plus (kovshp) + bootlegs
27
28 the following also use the 55857E type and we emulate the
29 internal ROM
30
31 Photo Y2k (photoy2k)
32 Knights of Valor Superheros (kovsh) + bootlegs
33
34 ----
35
36 Many of the simulations are preliminary. If functions to access
37 internal tables exist it is sometimes possible to extract the ROM
38 via these functions if the buffers are unchecked, however many
39 games have no table accesses.
40
41 ----
42
43 The basic protection communication is the same between all games
44 however the commands differ
45
46 None of these games have an external ARM rom, although it appears
47 the program code does check for the possibility of one existing.
48
49 The 68k ROM gets checksummed by the ARM, the code doesn't even
50 get decrytped if it fails.
51
52 68k code is encrypted on these, decryption table is uploaded to
53 ARM space.
54
55 Game Region is supplied by internal ARM rom.
56
57
58 ***********************************************************************/
59
60 #include "emu.h"
61 #include "machine/pgmprot_igs027a_type1.h"
62
63 #include "screen.h"
64
65
66 /**************************** EMULATION *******************************/
67 /* used by photoy2k, kovsh */
68
arm7_type1_protlatch_r(offs_t offset)69 u16 pgm_arm_type1_state::arm7_type1_protlatch_r(offs_t offset)
70 {
71 if (!machine().side_effects_disabled())
72 machine().scheduler().synchronize(); // force resync
73
74 if (offset & 1)
75 return m_arm_type1_highlatch_68k_w;
76 else
77 return m_arm_type1_lowlatch_68k_w;
78 }
79
arm7_type1_protlatch_w(offs_t offset,u16 data)80 void pgm_arm_type1_state::arm7_type1_protlatch_w(offs_t offset, u16 data)
81 {
82 machine().scheduler().synchronize(); // force resync
83
84 if (offset & 1)
85 {
86 m_arm_type1_highlatch_arm_w = data;
87 m_arm_type1_highlatch_68k_w = 0;
88 }
89 else
90 {
91 m_arm_type1_lowlatch_arm_w = data;
92 m_arm_type1_lowlatch_68k_w = 0;
93 }
94 }
95
arm7_type1_68k_protlatch_r(offs_t offset)96 u16 pgm_arm_type1_state::arm7_type1_68k_protlatch_r(offs_t offset)
97 {
98 if (!machine().side_effects_disabled())
99 machine().scheduler().synchronize(); // force resync
100
101 switch (offset)
102 {
103 case 1: return m_arm_type1_highlatch_arm_w;
104 case 0: return m_arm_type1_lowlatch_arm_w;
105 }
106 return -1;
107 }
108
arm7_type1_68k_protlatch_w(offs_t offset,u16 data)109 void pgm_arm_type1_state::arm7_type1_68k_protlatch_w(offs_t offset, u16 data)
110 {
111 machine().scheduler().synchronize(); // force resync
112
113 switch (offset)
114 {
115 case 1:
116 m_arm_type1_highlatch_68k_w = data;
117 break;
118
119 case 0:
120 m_arm_type1_lowlatch_68k_w = data;
121 break;
122 }
123 }
124
arm7_type1_ram_r(offs_t offset,u16 mem_mask)125 u16 pgm_arm_type1_state::arm7_type1_ram_r(offs_t offset, u16 mem_mask)
126 {
127 const u16 *share16 = reinterpret_cast<u16 *>(m_arm7_shareram.target());
128
129 if (PGMARM7LOGERROR)
130 logerror("M68K: ARM7 Shared RAM Read: %04x = %04x (%08x) %s\n", BYTE_XOR_LE(offset), share16[BYTE_XOR_LE(offset)], mem_mask, machine().describe_context());
131 return share16[BYTE_XOR_LE(offset << 1)];
132 }
133
arm7_type1_ram_w(offs_t offset,u16 data,u16 mem_mask)134 void pgm_arm_type1_state::arm7_type1_ram_w(offs_t offset, u16 data, u16 mem_mask)
135 {
136 u16 *share16 = reinterpret_cast<u16 *>(m_arm7_shareram.target());
137
138 if (PGMARM7LOGERROR)
139 logerror("M68K: ARM7 Shared RAM Write: %04x = %04x (%04x) %s\n", BYTE_XOR_LE(offset), data, mem_mask, machine().describe_context());
140 COMBINE_DATA(&share16[BYTE_XOR_LE(offset << 1)]);
141 }
142
143
arm7_type1_unk_r()144 u32 pgm_arm_type1_state::arm7_type1_unk_r()
145 {
146 const u32 val = m_arm_type1_counter;
147 if (!machine().side_effects_disabled())
148 m_arm_type1_counter++;
149 return val;
150 }
151
arm7_type1_exrom_r()152 u32 pgm_arm_type1_state::arm7_type1_exrom_r()
153 {
154 return 0x00000000;
155 }
156
arm7_type1_shareram_r(offs_t offset,u32 mem_mask)157 u32 pgm_arm_type1_state::arm7_type1_shareram_r(offs_t offset, u32 mem_mask)
158 {
159 if (PGMARM7LOGERROR)
160 logerror("ARM7: ARM7 Shared RAM Read: %04x = %08x (%08x) %s\n", offset << 2, m_arm7_shareram[offset], mem_mask, machine().describe_context());
161 return m_arm7_shareram[offset];
162 }
163
arm7_type1_shareram_w(offs_t offset,u32 data,u32 mem_mask)164 void pgm_arm_type1_state::arm7_type1_shareram_w(offs_t offset, u32 data, u32 mem_mask)
165 {
166 if (PGMARM7LOGERROR)
167 logerror("ARM7: ARM7 Shared RAM Write: %04x = %08x (%08x) %s\n", offset << 2, data, mem_mask, machine().describe_context());
168 COMBINE_DATA(&m_arm7_shareram[offset]);
169 }
170
171 /* 55857E? */
172 /* Knights of Valor, Photo Y2k */
173 /* no execute only space? */
kov_map(address_map & map)174 void pgm_arm_type1_state::kov_map(address_map &map)
175 {
176 pgm_mem(map);
177 map(0x100000, 0x4effff).bankr("bank1"); /* Game ROM */
178 map(0x4f0000, 0x4f003f).rw(FUNC(pgm_arm_type1_state::arm7_type1_ram_r), FUNC(pgm_arm_type1_state::arm7_type1_ram_w)); /* ARM7 Shared RAM */
179 map(0x500000, 0x500005).rw(FUNC(pgm_arm_type1_state::arm7_type1_68k_protlatch_r), FUNC(pgm_arm_type1_state::arm7_type1_68k_protlatch_w)); /* ARM7 Latch */
180 }
181
_55857E_arm7_map(address_map & map)182 void pgm_arm_type1_state::_55857E_arm7_map(address_map &map)
183 {
184 map(0x00000000, 0x00003fff).rom();
185 map(0x08100000, 0x083fffff).r(FUNC(pgm_arm_type1_state::arm7_type1_exrom_r)); // unpopulated, returns 0 to keep checksum happy
186 map(0x10000000, 0x100003ff).ram(); // internal ram for asic
187 map(0x40000000, 0x40000003).rw(FUNC(pgm_arm_type1_state::arm7_type1_protlatch_r), FUNC(pgm_arm_type1_state::arm7_type1_protlatch_w));
188 map(0x40000008, 0x4000000b).nopw(); // ?
189 map(0x4000000c, 0x4000000f).r(FUNC(pgm_arm_type1_state::arm7_type1_unk_r));
190 map(0x50800000, 0x5080003f).rw(FUNC(pgm_arm_type1_state::arm7_type1_shareram_r), FUNC(pgm_arm_type1_state::arm7_type1_shareram_w)).share("arm7_shareram");
191 map(0x50000000, 0x500003ff).ram(); // uploads xor table to decrypt 68k rom here
192 }
193
194
195 /**************************** SIMULATIONS *****************************/
196
kov_sim_map(address_map & map)197 void pgm_arm_type1_state::kov_sim_map(address_map &map)
198 {
199 pgm_mem(map);
200 map(0x100000, 0x4effff).bankr("bank1"); /* Game ROM */
201 }
202
cavepgm_mem(address_map & map)203 void pgm_arm_type1_state::cavepgm_mem(address_map &map)
204 {
205 pgm_base_mem(map);
206 map(0x000000, 0x3fffff).rom();
207 /* protection devices installed (simulated) later */
208 }
209
210
machine_start()211 void pgm_arm_type1_state::machine_start()
212 {
213 save_item(NAME(m_value0));
214 save_item(NAME(m_value1));
215 save_item(NAME(m_valuekey));
216 save_item(NAME(m_valueresponse));
217 save_item(NAME(m_curslots));
218 save_item(NAME(m_slots));
219 }
220
pgm_arm_type1(machine_config & config)221 void pgm_arm_type1_state::pgm_arm_type1(machine_config &config) // ARM7 Shared motherboard XTAL
222 {
223 pgmbase(config);
224 m_maincpu->set_addrmap(AS_PROGRAM, &pgm_arm_type1_state::kov_map);
225
226 /* protection CPU */
227 ARM7(config, m_prot, 20000000); // 55857E?
228 m_prot->set_addrmap(AS_PROGRAM, &pgm_arm_type1_state::_55857E_arm7_map);
229 }
230
pgm_arm_type1_sim(machine_config & config)231 void pgm_arm_type1_state::pgm_arm_type1_sim(machine_config &config) // When simulated
232 {
233 pgm_arm_type1(config);
234 m_maincpu->set_addrmap(AS_PROGRAM, &pgm_arm_type1_state::kov_sim_map);
235
236 /* protection CPU */
237 m_prot->set_disable();
238 }
239
pgm_arm_type1_cave(machine_config & config)240 void pgm_arm_type1_state::pgm_arm_type1_cave(machine_config &config)
241 {
242 pgm_arm_type1_sim(config);
243 // pgm_arm_type1(config); // When ARM7 ROM is dumped and hooked up
244
245 m_maincpu->set_addrmap(AS_PROGRAM, &pgm_arm_type1_state::cavepgm_mem);
246 }
247
arm7_type1_latch_init()248 void pgm_arm_type1_state::arm7_type1_latch_init()
249 {
250 m_arm_type1_highlatch_arm_w = 0;
251 m_arm_type1_lowlatch_arm_w = 0;
252 m_arm_type1_highlatch_68k_w = 0;
253 m_arm_type1_lowlatch_68k_w = 0;
254 m_arm_type1_counter = 1;
255
256 save_item(NAME(m_arm_type1_highlatch_arm_w));
257 save_item(NAME(m_arm_type1_lowlatch_arm_w));
258 save_item(NAME(m_arm_type1_highlatch_68k_w));
259 save_item(NAME(m_arm_type1_lowlatch_68k_w));
260 save_item(NAME(m_arm_type1_counter));
261 }
262
kovsh_fake_region_r()263 u16 pgm_arm_type1_state::kovsh_fake_region_r()
264 {
265 const int regionhack = m_regionhack->read();
266 if (regionhack != 0xff) return regionhack;
267
268 offs_t offset = 0x4;
269 u16 *share16 = reinterpret_cast<u16 *>(m_arm7_shareram.target());
270 return share16[BYTE_XOR_LE(offset << 1)];
271 }
272
init_photoy2k()273 void pgm_arm_type1_state::init_photoy2k()
274 {
275 pgm_basic_init();
276 pgm_photoy2k_decrypt(machine());
277 arm7_type1_latch_init();
278 /* we only have a china internal ROM dumped for now.. allow region to be changed for debugging (to ensure all alt titles / regions can be seen) */
279 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0008, 0x4f0009, read16smo_delegate(*this, FUNC(pgm_arm_type1_state::kovsh_fake_region_r)));
280 }
281
init_kovsh()282 void pgm_arm_type1_state::init_kovsh()
283 {
284 pgm_basic_init();
285 pgm_kovsh_decrypt(machine());
286 arm7_type1_latch_init();
287 /* we only have a china internal ROM dumped for now.. allow region to be changed for debugging (to ensure all alt titles / regions can be seen) */
288 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0008, 0x4f0009, read16smo_delegate(*this, FUNC(pgm_arm_type1_state::kovsh_fake_region_r)));
289 }
290
291 /* Fake remapping of ASIC commands to the ones used by KOVSH due to the lack of the real ARM rom for this set */
kovshp_asic27a_write_word(offs_t offset,u16 data)292 void pgm_arm_type1_state::kovshp_asic27a_write_word(offs_t offset, u16 data)
293 {
294 switch (offset)
295 {
296 case 0:
297 m_arm_type1_lowlatch_68k_w = data;
298 return;
299
300 case 1:
301 {
302 const u8 asic_key = data >> 8;
303 u8 asic_cmd = (data & 0xff) ^ asic_key;
304
305 switch (asic_cmd)
306 {
307 case 0x9a: asic_cmd = 0x99; break; // kovshxas
308
309 case 0x38: asic_cmd = 0xad; break;
310 case 0x43: asic_cmd = 0xca; break;
311 case 0x56: asic_cmd = 0xac; break;
312 case 0x73: asic_cmd = 0x93; break;
313 case 0x84: asic_cmd = 0xb3; break;
314 case 0x87: asic_cmd = 0xb1; break;
315 case 0x89: asic_cmd = 0xb6; break;
316 case 0x93: asic_cmd = 0x73; break;
317 case 0xa5: asic_cmd = 0xa9; break;
318 case 0xac: asic_cmd = 0x56; break;
319 case 0xad: asic_cmd = 0x38; break;
320 case 0xb1: asic_cmd = 0x87; break;
321 case 0xb3: asic_cmd = 0x84; break;
322 case 0xb4: asic_cmd = 0x90; break;
323 case 0xb6: asic_cmd = 0x89; break;
324 case 0xc5: asic_cmd = 0x8c; break;
325 case 0xca: asic_cmd = 0x43; break;
326 case 0xcc: asic_cmd = 0xf0; break;
327 case 0xd0: asic_cmd = 0xe0; break;
328 case 0xe0: asic_cmd = 0xd0; break;
329 case 0xe7: asic_cmd = 0x70; break;
330 case 0xed: asic_cmd = 0xcb; break;
331 case 0xf0: asic_cmd = 0xcc; break;
332 case 0xf1: asic_cmd = 0xf5; break;
333 case 0xf2: asic_cmd = 0xf1; break;
334 case 0xf4: asic_cmd = 0xf2; break;
335 case 0xf5: asic_cmd = 0xf4; break;
336 case 0xfc: asic_cmd = 0xc0; break;
337 case 0xfe: asic_cmd = 0xc3; break;
338
339 case 0xa6: asic_cmd = 0xa9; break;
340 case 0xaa: asic_cmd = 0x56; break;
341 case 0xf8: asic_cmd = 0xf3; break;
342 }
343
344 m_arm_type1_highlatch_68k_w = asic_cmd ^ (asic_key | (asic_key << 8));
345 }
346 return;
347 }
348 }
349
350
init_kovshp()351 void pgm_arm_type1_state::init_kovshp()
352 {
353 pgm_basic_init();
354 pgm_kovshp_decrypt(machine());
355 arm7_type1_latch_init();
356 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0008, 0x4f0009, read16smo_delegate(*this, FUNC(pgm_arm_type1_state::kovsh_fake_region_r)));
357 m_maincpu->space(AS_PROGRAM).install_write_handler(0x500000, 0x500005, write16sm_delegate(*this, FUNC(pgm_arm_type1_state::kovshp_asic27a_write_word)));
358 }
359
360
361 /* bootleg inits */
362
init_kovshxas()363 void pgm_arm_type1_state::init_kovshxas()
364 {
365 pgm_basic_init();
366 // pgm_kovshp_decrypt(machine());
367 arm7_type1_latch_init();
368 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0008, 0x4f0009, read16smo_delegate(*this, FUNC(pgm_arm_type1_state::kovsh_fake_region_r)));
369 m_maincpu->space(AS_PROGRAM).install_write_handler(0x500000, 0x500005, write16sm_delegate(*this, FUNC(pgm_arm_type1_state::kovshp_asic27a_write_word)));
370 }
371
pgm_decode_kovlsqh2_tiles()372 void pgm_arm_type1_state::pgm_decode_kovlsqh2_tiles()
373 {
374 u16 *src = (u16 *)(memregion("tiles")->base() + 0x180000);
375 std::vector<u16> dst(0x800000);
376
377 for (int i = 0; i < 0x800000 / 2; i++)
378 {
379 const int j = bitswap<24>(i, 23, 22, 9, 8, 21, 18, 0, 1, 2, 3, 16, 15, 14, 13, 12, 11, 10, 19, 20, 17, 7, 6, 5, 4);
380
381 dst[j] = bitswap<16>(src[i], 1, 14, 8, 7, 0, 15, 6, 9, 13, 2, 5, 10, 12, 3, 4, 11);
382 }
383
384 memcpy( src, &dst[0], 0x800000 );
385 }
386
pgm_decode_kovlsqh2_sprites(u8 * src)387 void pgm_arm_type1_state::pgm_decode_kovlsqh2_sprites( u8 *src )
388 {
389 std::vector<u8> dst(0x800000);
390
391 for (int i = 0; i < 0x800000; i++)
392 {
393 const int j = bitswap<24>(i, 23, 10, 9, 22, 19, 18, 20, 21, 17, 16, 15, 14, 13, 12, 11, 8, 7, 6, 5, 4, 3, 2, 1, 0);
394
395 dst[j] = src[i];
396 }
397
398 memcpy( src, &dst[0], 0x800000 );
399 }
400
pgm_decode_kovlsqh2_samples()401 void pgm_arm_type1_state::pgm_decode_kovlsqh2_samples()
402 {
403 u8 *src = (u8 *)(memregion("ics")->base() + 0x400000);
404
405 for (int i = 0; i < 0x400000; i+=2) {
406 src[i + 0x000001] = src[i + 0x400001];
407 }
408
409 memcpy( src + 0x400000, src, 0x400000 );
410 }
411
pgm_decode_kovqhsgs_program()412 void pgm_arm_type1_state::pgm_decode_kovqhsgs_program()
413 {
414 u16 *src = (u16 *)(memregion("maincpu")->base() + 0x100000);
415 std::vector<u16> dst(0x400000);
416
417 for (int i = 0; i < 0x400000 / 2; i++)
418 {
419 const int j = bitswap<24>(i, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 5, 4, 3, 2, 1, 0);
420
421 dst[j] = bitswap<16>(src[i], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 4, 5, 3, 2, 1, 0);
422 }
423
424 memcpy( src, &dst[0], 0x400000 );
425 }
426
pgm_decode_kovqhsgs2_program()427 void pgm_arm_type1_state::pgm_decode_kovqhsgs2_program()
428 {
429 u16 *src = (u16 *)(memregion("maincpu")->base() + 0x100000);
430 std::vector<u16> dst(0x400000);
431
432 for (int i = 0; i < 0x400000 / 2; i++)
433 {
434 const int j = bitswap<24>(i, 23, 22, 21, 20, 19, 16, 15, 14, 13, 12, 11, 10, 9, 8, 0, 1, 2, 3, 4, 5, 6, 18, 17, 7);
435
436 dst[j] = src[i];
437 }
438
439 memcpy( src, &dst[0], 0x400000 );
440 }
441
442
init_kovlsqh2()443 void pgm_arm_type1_state::init_kovlsqh2()
444 {
445 pgm_decode_kovqhsgs2_program();
446 pgm_decode_kovlsqh2_tiles();
447
448 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x0000000);
449 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x0800000);
450 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x1000000);
451 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x1800000);
452 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x2000000);
453 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x2800000);
454 pgm_decode_kovlsqh2_sprites(memregion("sprmask")->base() + 0x0000000);
455 pgm_decode_kovlsqh2_sprites(memregion("sprmask")->base() + 0x0800000);
456
457 pgm_decode_kovlsqh2_samples();
458 pgm_basic_init();
459 arm7_type1_latch_init();
460 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0008, 0x4f0009, read16smo_delegate(*this, FUNC(pgm_arm_type1_state::kovsh_fake_region_r)));
461 m_maincpu->space(AS_PROGRAM).install_write_handler(0x500000, 0x500005, write16sm_delegate(*this, FUNC(pgm_arm_type1_state::kovshp_asic27a_write_word)));
462 }
463
init_kovqhsgs()464 void pgm_arm_type1_state::init_kovqhsgs()
465 {
466 pgm_decode_kovqhsgs_program();
467 pgm_decode_kovlsqh2_tiles();
468
469 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x0000000);
470 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x0800000);
471 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x1000000);
472 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x1800000);
473 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x2000000);
474 pgm_decode_kovlsqh2_sprites(memregion("sprcol")->base() + 0x2800000);
475 pgm_decode_kovlsqh2_sprites(memregion("sprmask")->base() + 0x0000000);
476 pgm_decode_kovlsqh2_sprites(memregion("sprmask")->base() + 0x0800000);
477
478 pgm_decode_kovlsqh2_samples();
479 pgm_basic_init();
480 arm7_type1_latch_init();
481 /* we only have a china internal ROM dumped for now.. allow region to be changed for debugging (to ensure all alt titles / regions can be seen) */
482 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0008, 0x4f0009, read16smo_delegate(*this, FUNC(pgm_arm_type1_state::kovsh_fake_region_r)));
483 }
484
485 /*
486 in Ketsui (ket) @ 000A719C (move.w)
487
488 if you change D0 to 0x12
489 the game will runs to "Asic27 Test" mode
490
491 bp A71A0,1,{d0=0x12;g}
492 */
493
arm7_type1_sim_r(offs_t offset)494 u16 pgm_arm_type1_state::arm7_type1_sim_r(offs_t offset)
495 {
496 if (offset == 0)
497 {
498 u16 d = m_valueresponse & 0xffff;
499 u16 realkey = m_valuekey >> 8;
500 realkey |= m_valuekey;
501 d ^= realkey;
502 return d;
503 }
504 else if (offset == 1)
505 {
506 u16 d = m_valueresponse >> 16;
507 u16 realkey = m_valuekey >> 8;
508 realkey |= m_valuekey;
509 d ^= realkey;
510 return d;
511 }
512 return 0xffff;
513 }
514
515 /* working */
command_handler_ddp3(int pc)516 void pgm_arm_type1_state::command_handler_ddp3(int pc)
517 {
518 switch (m_ddp3lastcommand)
519 {
520 default:
521 printf("%06x command %02x | %04x\n", pc, m_ddp3lastcommand, m_value0);
522 m_valueresponse = 0x880000;
523 break;
524
525 case 0x40:
526 m_valueresponse = 0x880000;
527 m_slots[(m_value0 >> 10) & 0x1F]=
528 (m_slots[(m_value0 >> 5) & 0x1F]+
529 m_slots[(m_value0 >> 0) & 0x1F]) & 0xffffff;
530 break;
531
532 case 0x67: // set high bits
533 // printf("%s command %02x | %04x\n", machine().describe_context().c_str(), m_ddp3lastcommand, m_value0);
534 m_valueresponse = 0x880000;
535 m_curslots = (m_value0 & 0xff00) >> 8;
536 m_slots[m_curslots] = (m_value0 & 0x00ff) << 16;
537 break;
538
539 case 0xe5: // set low bits for operation?
540 // printf("%s command %02x | %04x\n", machine().describe_context().c_str(), m_ddp3lastcommand, m_value0);
541 m_valueresponse = 0x880000;
542 m_slots[m_curslots] |= (m_value0 & 0xffff);
543 break;
544
545 case 0x8e: // read back result of operations
546 // printf("%s command %02x | %04x\n", machine().describe_context().c_str(), m_ddp3lastcommand, m_value0);
547 m_valueresponse = m_slots[m_value0 & 0xff];
548 break;
549
550 case 0x99: // reset?
551 m_simregion = 0;//m_region->read();
552 m_valuekey = 0x100;
553 m_valueresponse = 0x00880000 | m_simregion << 8;
554 break;
555
556 }
557 }
558
559 /* preliminary */
560
561 // should be correct, note each value only appears once
562 u8 puzzli2_level_decode[256] = {
563 // 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , a , b , c , d , e , f ,
564 0x32, 0x3e, 0xb2, 0x37, 0x31, 0x22, 0xd6, 0x0d, 0x35, 0x5c, 0x8d, 0x3c, 0x7a, 0x5f, 0xd7, 0xac, // 0x0
565 // 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , x , x ,
566 0x53, 0xff, 0xeb, 0x44, 0xe8, 0x11, 0x69, 0x77, 0xd9, 0x34, 0x36, 0x45, 0xa6, 0xe9, 0x1c, 0xc6, // 0x1
567 // 0 , 0 , x , x , x , 0 , x , 0 , x , 0 , 0 , 0 , 0 , x , 0 , x ,
568 0x3b, 0xbd, 0xad, 0x2e, 0x18, 0xdf, 0xa1, 0xab, 0xdd, 0x52, 0x57, 0xc2, 0xe5, 0x0a, 0x00, 0x6d, // 0x2
569 // 0 , 0 , 0 , 1 , 1 , 1 , 1 , x , 1 , 1 , 0 , 0 , 1 , 1 , x , 0 ,
570 0x67, 0x64, 0x15, 0x70, 0xb6, 0x39, 0x27, 0x78, 0x82, 0xd2, 0x71, 0xb9, 0x13, 0xf5, 0x93, 0x92, // 0x3
571 // 0 , x , 1 , 1 , x , 1 , 1 , 1 , 1 , 1 , 1 , 1 , x , 0 , x , x ,
572 0xfa, 0xe7, 0x5e, 0xb0, 0xf6, 0xaf, 0x95, 0x8a, 0x7c, 0x73, 0xf9, 0x63, 0x86, 0xcb, 0x1a, 0x56, // 0x4
573 // 0 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 0 ,
574 0xf1, 0x3a, 0xae, 0x61, 0x01, 0x29, 0x97, 0x23, 0x8e, 0x5d, 0x9a, 0x65, 0x74, 0x21, 0x20, 0x40, // 0x5
575 // 0 , 1 , 1 , 1 , 1 , 0 , x , x , x , 0 , 0 , 1 , 1 , 1 , 1 , 1 ,
576 0xd3, 0x05, 0xa2, 0xe1, 0xbc, 0x9e, 0x1e, 0x10, 0x14, 0x0c, 0x88, 0x9c, 0xec, 0x38, 0xb5, 0x9d, // 0x6
577 // 1 , 0 , 0 , x , 1 , 1 , 0 , 0 , x , 0 , x , 0 , 0 , 1 , 1 , 1 ,
578 0x2d, 0xf7, 0x17, 0x0e, 0x84, 0xc7, 0x7d, 0xce, 0x94, 0x16, 0x48, 0xa8, 0x81, 0x6e, 0x7b, 0xd8, // 0x7
579 // 1 , 1 , 1 , 1 , x , 0 , x , 0 , 1 , 1 , 1 , x , x , 1 , 1 , 1 ,
580 0xa7, 0x7f, 0x42, 0xe6, 0xa0, 0x2a, 0xef, 0xee, 0x24, 0xba, 0xb8, 0x7e, 0xc9, 0x2b, 0x90, 0xcc, // 0x8
581 // 1 , x , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
582 0x5b, 0xd1, 0xf3, 0xe2, 0x6f, 0xed, 0x9f, 0xf0, 0x4b, 0x54, 0x8c, 0x08, 0xf8, 0x51, 0x68, 0xc8, // 0x9
583 // x , 0 , 0 , 0 , 0 , 0 , 0 , 0 , x , 0 , x , 0 , 0 , 0 , 0 , 1 ,
584 0x03, 0x0b, 0xbb, 0xc1, 0xe3, 0x4d, 0x04, 0xc5, 0x8f, 0x09, 0x0f, 0xbf, 0x62, 0x49, 0x76, 0x59, // 0xa
585 // 1 , 1 , 1 , 1 , 1 , x , 0 , 1 , 1 , 0 , x , 1 , 1 , 1 , 1 , 0 ,
586 0x1d, 0x80, 0xde, 0x60, 0x07, 0xe0, 0x1b, 0x66, 0xa5, 0xbe, 0xcd, 0x87, 0xdc, 0xc3, 0x6b, 0x4e, // 0xb
587 // 0 , 1 , 1 , 1 , 1 , x , 0 , x , 0 , x , 0 , 1 , 1 , 0 , 1 , 1 ,
588 0xd0, 0xfd, 0xd4, 0x3f, 0x98, 0x96, 0x2f, 0x4c, 0xb3, 0xea, 0x2c, 0x75, 0xe4, 0xc0, 0x6c, 0x6a, // 0xc
589 // 0 , x , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , x , 1 , 1 , 1 ,
590 0x9b, 0xb7, 0x43, 0x8b, 0x41, 0x47, 0x02, 0xdb, 0x99, 0x3d, 0xa3, 0x79, 0x50, 0x4f, 0xb4, 0x55, // 0xd
591 // 1 , 0 , 0 , 0 , 1 , 0 , 0 , x , x , 1 , 1 , 1 , 0 , 1 , 1 , 1 ,
592 0x5a, 0x25, 0xf4, 0xca, 0x58, 0x30, 0xc4, 0x12, 0xa9, 0x46, 0xda, 0x91, 0xa4, 0xaa, 0xfc, 0x85, // 0xe
593 // 1 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , x ,
594 0xfb, 0x89, 0x06, 0xcf, 0xfe, 0x33, 0xd5, 0x28, 0x1f, 0x19, 0x4a, 0xb1, 0x83, 0xf2, 0x72, 0x26, // 0xf
595 // x , x , 1 , 1 , 1 , 1 , 1 , 1 , x , 0 , 1 , 1 , 1 , 1 , 1 , 1 ,
596 };
597
598
599 #define puzzli2_printf logerror
600
command_handler_puzzli2(int pc)601 void pgm_arm_type1_state::command_handler_puzzli2(int pc)
602 {
603 switch (m_ddp3lastcommand)
604 {
605 case 0x31:
606 {
607 // how is this selected? command 54?
608
609 /* writes the following sequence before how to play
610 each level has a different sequence written before it, size of sequence doesn't seem directly connected to level size (unlike the reads)
611 so it's probably compressed somehow as well as scrambled? 68k doesnt know in advance how big each lot of data is either, it only stops
612 writing when it gets a difference response from the MCU.
613
614 00138278: 31 00fd | (set xor table offset)
615 UNKNOWN - related to depth / number of columns?
616 00138278: 31 0087 | value 87, after xor is 75 (table address,value fd,f2)
617 COLUMN 1
618 00138278: 31 0032 | value 32, after xor is 40 (table address,value fe,72) << 4 is the number of entries in this column
619 00138278: 31 0029 | value 29, after xor is 0f (table address,value ff,26) << 0x0f is a mask of 4 bits..
620
621 00138278: 31 0031 | value 31, after xor is 03 (table address,value 00,32) -> 0x0103
622 00138278: 31 003f | value 3f, after xor is 01 (table address,value 01,3e) -> 0x0101
623 00138278: 31 00b0 | value b0, after xor is 02 (table address,value 02,b2) -> 0x0102
624 00138278: 31 0035 | value 35, after xor is 02 (table address,value 03,37) -> 0x0102
625 COLUMN 2
626 00138278: 31 0071 | value 71, after xor is 40 (table address,value 04,31) << 4 is the number of entries in this column
627 00138278: 31 002d | value 2d, after xor is 0f (table address,value 05,22) << 0x0f is a mask of 4 bits..
628
629 00138278: 31 00d5 | value d5, after xor is 03 (table address,value 06,d6) -> 0x0103
630 00138278: 31 000d | value 0d, after xor is 00 (table address,value 07,0d) -> 0x0100
631 00138278: 31 0034 | value 34, after xor is 01 (table address,value 08,35) -> 0x0101
632 00138278: 31 0059 | value 59, after xor is 05 (table address,value 09,5c) -> 0x0105
633 COLUMN 3
634 00138278: 31 00dd | value dd, after xor is 50 (table address,value 0a,8d) << 5 is the number of entries in this column
635 00138278: 31 0023 | value 23, after xor is 1f (table address,value 0b,3c) << 0x1f is a mask of 5 bits..
636
637 00138278: 31 007a | value 7a, after xor is 00 (table address,value 0c,7a) -> 0x0100
638 00138278: 31 00f3 | value f3, after xor is 01 (table address,value fd,f2) -> 0x0101
639 00138278: 31 0077 | value 77, after xor is 05 (table address,value fe,72) -> 0x0105
640 00138278: 31 0022 | value 22, after xor is 04 (table address,value ff,26) -> 0x0104
641 00138278: 31 0036 | value 36, after xor is 04 (table address,value 00,32) -> 0x0104
642 COLUMN 4
643 00138278: 31 002e | value 2e, after xor is 10 (table address,value 01,3e) << 1 is the number of entries in this column
644 00138278: 31 00b3 | value b3, after xor is 01 (table address,value 02,b2) << 0x01 is a mask of 1 bit..
645
646 00138278: 31 0035 | value 35, after xor is 02 (table address,value 03,37) -> 0x0102
647 COLUMN 5
648 00138278: 31 0041 | value 41, after xor is 70 (table address,value 04,31) << 7 is the number of entries in this column
649 00138278: 31 005d | value 5d, after xor is 7f (table address,value 05,22) << 0x7f is a mask of 7 bits..
650
651 00138278: 31 00d6 | value d6, after xor is 00 (table address,value 06,d6) -> 0x0100
652 00138278: 31 000c | value 0c, after xor is 01 (table address,value 07,0d) -> 0x0101
653 00138278: 31 0036 | value 36, after xor is 03 (table address,value 08,35) -> 0x0103
654 00138278: 31 005e | value 5e, after xor is 02 (table address,value 09,5c) -> 0x0102
655 00138278: 31 0089 | value 89, after xor is 04 (table address,value 0a,8d) -> 0x0104
656 00138278: 31 003c | value 3c, after xor is 00 (table address,value 0b,3c) -> 0x0100
657 00138278: 31 007a | value 7a, after xor is 00 (table address,value 0c,7a) -> 0x0100
658 COLUMN 6
659 00138278: 31 00a2 | value a2, after xor is 50 (table address,value fd,f2) << 5 is the number of entries in this column
660 00138278: 31 006d | value 6d, after xor is 1f (table address,value fe,72) << 0x1f is a mask of 5 bits..
661
662 00138278: 31 0023 | value 23, after xor is 05 (table address,value ff,26) -> 0x0105
663 00138278: 31 0037 | value 37, after xor is 05 (table address,value 00,32) -> 0x0105
664 00138278: 31 003f | value 3f, after xor is 01 (table address,value 01,3e) -> 0x0101
665 00138278: 31 00b3 | value b3, after xor is 01 (table address,value 02,b2) -> 0x0101
666 00138278: 31 0034 | value 34, after xor is 03 (table address,value 03,37) -> 0x0103
667 ^ (end, returning 630006 as playfield width)
668
669 */
670
671 if (command_31_write_type==2)
672 {
673 puzzli2_printf("%08x: %02x %04x | ",pc, m_ddp3lastcommand, m_value0);
674
675 // this shouldn't apply to the stuff written on startup, only the level data..
676
677 if (hackcount2==0)
678 {
679 puzzli2_take_leveldata_value(m_value0 & 0xff);
680
681 hack_31_table_offset = m_value0 & 0xff;
682 hack_31_table_offset2 = 0;
683 hackcount2++;
684 m_valueresponse = 0x00d20000;
685
686 //puzzli2_printf("(set xor table offset)\n");
687 }
688 else // how do we decide end?
689 {
690 int end = puzzli2_take_leveldata_value(m_value0 & 0xff);
691
692 if (!end)
693 {
694 // always d2 0000 when writing doing level data
695 // but different for the writes on startup?
696 m_valueresponse = 0x00d20000;
697
698 //u8 tableaddr = (hack_31_table_offset + (hack_31_table_offset2 & 0xf)) & 0xff;
699 //u8 xoredval = m_value0 ^ puzzli2_level_decode[tableaddr];
700 //puzzli2_printf("value %02x, after xor is %02x (table address,value %02x,%02x)\n", m_value0, xoredval, tableaddr, puzzli2_level_decode[tableaddr]);
701
702 hackcount2++;
703 hack_31_table_offset2++;
704 }
705 else
706 {
707 hackcount2 = 0;
708
709 // when the ARM detects the end of the stream has been reached it returns a 0x63 status with the number of columns in the data word
710 m_valueresponse = 0x00630000 | numbercolumns;
711
712 //u8 tableaddr = (hack_31_table_offset + (hack_31_table_offset2 & 0xf)) & 0xff;
713 //u8 xoredval = m_value0 ^ puzzli2_level_decode[tableaddr];
714 //puzzli2_printf("value %02x, after xor is %02x (table address,value %02x,%02x) (end, returning %02x as playfield width)\n", m_value0, xoredval, tableaddr, puzzli2_level_decode[tableaddr], m_valueresponse);
715 }
716 }
717 }
718 else
719 {
720 // todo, responses when uploading the startup values are different
721 puzzli2_printf("%08x: %02x %04x (for z80 address?)\n ",pc, m_ddp3lastcommand, m_value0);
722
723 m_valueresponse = 0x00d20000 | p2_31_retcounter;
724 p2_31_retcounter++; // returns 0xc for the first one, 0x19 for the last one
725 }
726
727 }
728 break;
729
730 // after writing the compressed and scrambled data stream for the level (copied from ROM) with command 0x31
731 // the game expects to read back a fully formed level structure from the ARM
732 case 0x13:
733 {
734 puzzli2_printf("%08x: %02x %04x (READ LEVEL DATA) | ",pc, m_ddp3lastcommand, m_value0);
735
736 // this is the how to play screen, correctly returned with current code
737 /*
738 u16 retvals[61] =
739 { 0x0008, // depth (-2?)
740 0x0103, 0x0101, 0x0102, 0x0102, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // first column
741 0x0103, 0x0100, 0x0101, 0x0105, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
742 0x0100, 0x0101, 0x0105, 0x0104, 0x0104, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
743 0x0102, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
744 0x0100, 0x0101, 0x0103, 0x0102, 0x0104, 0x0100 ,0x0100, 0x0000, 0x0000, 0x0000,
745 0x0105, 0x0105, 0x0101, 0x0101, 0x0103, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 // last column
746 };
747 */
748
749
750 u16* leveldata = &level_structure[0][0];
751 if (hackcount==0)
752 {
753 m_valueresponse = 0x002d0000 | ((depth>>4)+1); // this *seems* to come from upper bits of the first real value written to the device during the level stream (verify, seems wrong for some levels because you get a black bar on the bottom of the screen, but might be bad xors)
754 puzzli2_printf("level depth returning %08x\n", m_valueresponse );
755 }
756 else if (hackcount<((10*numbercolumns)+1))
757 {
758 m_valueresponse = 0x002d0000 | leveldata[hackcount-1];
759 puzzli2_printf("level data returning %08x\n", m_valueresponse );
760 }
761 else
762 {
763 hackcount=0;
764 m_valueresponse = 0x00740054; // 0x0074 0054 is returned after how to play reads above.. where does 0x54 come from?
765 puzzli2_printf("END returning %08x\n", m_valueresponse );
766
767 }
768
769 hackcount++;
770
771
772 // 2d seems to be used when there is more data available
773 // 74 seems to be used when there isn't.. (end of buffer reached?)
774 // 2d or 74! (based on?)
775
776 }
777 break;
778
779
780
781 case 0x38: // Reset
782 puzzli2_printf("%08x: %02x %04x (RESET)\n",pc, m_ddp3lastcommand, m_value0);
783 m_simregion = m_region->read();
784 m_valueresponse = 0x780000 | m_simregion<<8; // this must also return the cart region or the game will act in odd ways when inserting a coin on continue, or during the game on later levels
785 m_valuekey = 0x100;
786 m_puzzli_54_trigger = 0;
787
788 break;
789
790
791
792
793 // 47 and 52 are used to get the images during the intro sequence, different each loop
794 // also some other gfx?
795 // logic here seems correct, not sure where the 0x19 and 0x5 etc. come from tho!
796 case 0x47:
797 puzzli2_printf("%08x: %02x %04x (GFX OFF PART 1)\n",pc, m_ddp3lastcommand, m_value0);
798
799 hack_47_value = m_value0;
800
801 //hack_47_value = ((m_value0 & 0x0700) >> 8) * 0x19;
802 //hack_47_value +=((m_value0 & 0x0007) >> 0) * 0x05;
803 if (m_value0 & 0xf0f0) puzzli2_printf("unhandled 0x47 bits %04x\n", m_value0);
804
805 //puzzli2_printf("0x47 value was %04x - using %04x\n", m_value0, hack_47_value);
806
807 m_valueresponse = 0x00740047;
808
809 break;
810
811 case 0x52:
812 puzzli2_printf("%08x: %02x %04x (GFX OFF PART 2)\n",pc, m_ddp3lastcommand, m_value0);
813
814 //puzzli2_printf("which %04x\n", m_value0);
815 if (m_value0 & 0xfff0) puzzli2_printf("unhandled 0x52 bits %04x\n", m_value0);
816
817 // it writes a value of 0x0000 then expects to read back like
818 // this for the lower part of the game backgrounds
819 if (m_value0 == 0x0000)
820 {
821 int val = ((hack_47_value & 0x0f00) >> 8) * 0x19;
822 m_valueresponse = 0x00740000 | (val & 0xffff);
823 }
824 else
825 {
826 int val = ((hack_47_value & 0x0f00) >> 8) * 0x19;
827 val +=((hack_47_value & 0x000f) >> 0) * 0x05;
828 val += m_value0 & 0x000f;
829 m_valueresponse = 0x00740000 | (val & 0xffff);
830
831 }
832
833
834
835 break;
836
837
838
839 case 0x61: // ??
840 puzzli2_printf("%08x: %02x %04x\n",pc, m_ddp3lastcommand, m_value0);
841
842 // this command is written before the values used to decrypt the z80 addresses (assumed) are uploaded with command 31
843 command_31_write_type = 1;
844
845 m_valueresponse = 0x36 << 16;
846 p2_31_retcounter = 0xc;
847 break;
848
849 case 0x41: // ASIC status?
850 puzzli2_printf("%08x: %02x %04x (UNK)\n",pc, m_ddp3lastcommand, m_value0);
851
852 // this command is written after the values used to decrypt the z80 addresses (assumed) are uploaded with command 31
853 command_31_write_type = 0;
854
855 //m_valueresponse = 0x74 << 16;
856 m_valueresponse = 0x740061;
857 break;
858
859 case 0x54: // ??
860 puzzli2_printf("%08x: %02x %04x\n",pc, m_ddp3lastcommand, m_value0);
861
862 // this command is written before uploading the compressed level data stream with command 31
863
864 command_31_write_type = 2;
865 stage = -1;
866 m_puzzli_54_trigger = 1;
867 hackcount2 = 0;
868 hackcount = 0;
869 m_valueresponse = 0x36 << 16;
870
871 // clear the return structure
872 for (auto & elem : level_structure)
873 for (int rows=0;rows<10;rows++)
874 elem[rows] = 0x0000;
875
876 break;
877
878 /*
879
880 puzzli2 on startup (00148a84) puzzli2s on startup (0014cf58)
881
882 (001489f6: 61 0202 0014ceca: 61 0202)
883 always
884 : 31 004e a6f7 | : 31 | 0051 14c9 + 26DD2
885 : 31 279e 534f | : 31 | 27a0 c121
886 : 31 ab5c a7cf | : 31 | ab5f 15a1
887 : 31 145f 7054 | : 31 | 1461 de26
888 : 31 85a0 7b7f | : 31 | 85a2 e951
889 : 31 7003 c5ab | : 31 | 7006 337d
890 : 31 456d f3aa | : 31 | 4570 617c
891
892 (00148b34: 41 e2bb 0014d008: 41 706d)
893
894 actual values needed always
895 0x001694a8 / 0x0019027a + 26DD2
896 0x0016cfae / 0x00193D80
897 0x0016ebf2 / 0x001959c4
898 0x0016faa8 / 0x0019687a
899 0x00174416 / 0x0019b1e8
900
901 0x00166178 / 0x0018cf4a
902 0x00166e72 / 0x0018dc44
903
904 as you can see the difference between the values written is always 26dd2, as is the difference between offsets expected
905 this makes it impossible to know which value is for which address without further tests!
906
907
908 */
909
910 // I think the values returned here must be connected to the values written to command 31 on startup
911 // 63/67 are used on startup to get the z80 music at least
912 case 0x63: // used as a read address by the 68k code (related to previous uploaded values like cave?) should point at a table of ~0x80 in size? seems to use values as further pointers?
913 puzzli2_printf("%08x: %02x %04x (Z80 ADDR PART 1)\n",pc, m_ddp3lastcommand, m_value0);
914
915 if (!strcmp(machine().system().name,"puzzli2"))
916 {
917 if (m_value0 == 0x0000)
918 {
919 m_valueresponse = 0x001694a8;
920 }
921 else if (m_value0 == 0x0001)
922 {
923 m_valueresponse = 0x0016cfae;
924 }
925 else if (m_value0 == 0x0002)
926 {
927 m_valueresponse = 0x0016ebf2; // right for puzzli2 , wrong for puzzli2s, probably calculated from the writes then?
928 }
929 else if (m_value0 == 0x0003) // before 'cast' screen
930 {
931 m_valueresponse = 0x0016faa8;
932 }
933 else if (m_value0 == 0x0004) // 2 player demo
934 {
935 m_valueresponse = 0x00174416;
936 }
937 else
938 {
939 puzzli2_printf("unk case x63\n");
940 m_valueresponse = 0x00600000; // wrong
941
942 }
943 }
944 else // puzzli2 super
945 {
946 if (m_value0 == 0x0000)
947 {
948 m_valueresponse = 0x19027a;
949 }
950 else if (m_value0 == 0x0001)
951 {
952 m_valueresponse = 0x193D80;
953 }
954 else if (m_value0 == 0x0002)
955 {
956 m_valueresponse = 0x1959c4;
957 }
958 else if (m_value0 == 0x0003)
959 {
960 m_valueresponse = 0x19687a;
961 }
962 else if (m_value0 == 0x0004)
963 {
964 m_valueresponse = 0x19b1e8;
965 }
966 else
967 {
968 puzzli2_printf("unk case x63\n");
969 m_valueresponse = 0x00600000; // wrong
970 }
971 }
972 break;
973
974 case 0x67: // used as a read address by the 68k code (related to previous uploaded values like cave?) directly reads ~0xDBE from the address..
975 puzzli2_printf("%08x: %02x %04x (Z80 ADDR PART 2)\n",pc, m_ddp3lastcommand, m_value0);
976
977 if (!strcmp(machine().system().name,"puzzli2"))
978 {
979 if ( (m_value0 == 0x0000) || (m_value0 == 0x0001) || (m_value0 == 0x0002) || (m_value0 == 0x0003) )
980 {
981 m_valueresponse = 0x00166178; // right for puzzli2 , wrong for puzzli2s, probably calculated from the writes then?
982 }
983 else if ( m_value0 == 0x0004 ) // 2 player demo
984 {
985 m_valueresponse = 0x00166e72;
986 }
987 else
988 {
989 puzzli2_printf("unk case x67\n");
990 m_valueresponse = 0x00400000; // wrong
991 }
992 }
993 else // puzzli2 super
994 {
995 if ((m_value0 == 0x0000) || (m_value0 == 0x0001) || (m_value0 == 0x0002) || (m_value0 == 0x0003))
996 {
997 m_valueresponse = 0x18cf4a;
998 }
999 else if ( m_value0 == 0x0004 ) // 2 player demo
1000 {
1001 m_valueresponse = 0x0018dc44;
1002 }
1003 else
1004 {
1005 puzzli2_printf("unk case x67\n");
1006 m_valueresponse = 0x00600000; // wrong
1007 }
1008 }
1009 break;
1010
1011 default:
1012 puzzli2_printf("%08x: %02x %04x\n",pc, m_ddp3lastcommand, m_value0);
1013
1014 m_valueresponse = 0x74 << 16;
1015 break;
1016 }
1017 }
1018
py2k2_sprite_offset(u16 base,u16 pos)1019 static u32 py2k2_sprite_offset(u16 base, u16 pos)
1020 {
1021 u16 ret = 0;
1022 u16 offset = (base * 16) + (pos & 0xf);
1023
1024 switch (base & ~0x3f)
1025 {
1026 case 0x000: ret = bitswap<16>(offset ^ 0x0030, 15, 14, 13, 12, 11, 10, 0, 2, 3, 9, 5, 4, 8, 7, 6, 1); break;
1027 case 0x040: ret = bitswap<16>(offset ^ 0x03c0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 1, 2, 0, 5, 3, 4); break;
1028 case 0x080: ret = bitswap<16>(offset ^ 0x0000, 15, 14, 13, 12, 11, 10, 0, 3, 4, 6, 8, 7, 5, 9, 2, 1); break;
1029 case 0x0c0: ret = bitswap<16>(offset ^ 0x0001, 15, 14, 13, 12, 11, 10, 6, 5, 4, 3, 2, 1, 9, 8, 7, 0); break;
1030 case 0x100: ret = bitswap<16>(offset ^ 0x0030, 15, 14, 13, 12, 11, 10, 0, 2, 3, 9, 5, 4, 8, 7, 6, 1); break;
1031 case 0x140: ret = bitswap<16>(offset ^ 0x01c0, 15, 14, 13, 12, 11, 10, 2, 8, 7, 6, 4, 3, 5, 9, 0, 1); break;
1032 case 0x180: ret = bitswap<16>(offset ^ 0x0141, 15, 14, 13, 12, 11, 10, 4, 8, 2, 6, 1, 7, 9, 5, 3, 0); break;
1033 case 0x1c0: ret = bitswap<16>(offset ^ 0x0090, 15, 14, 13, 12, 11, 10, 5, 3, 7, 2, 1, 4, 0, 9, 8, 6); break;
1034 case 0x200: ret = bitswap<16>(offset ^ 0x02a1, 15, 14, 13, 12, 11, 10, 9, 1, 7, 8, 5, 6, 2, 4, 3, 0); break;
1035 case 0x240: ret = bitswap<16>(offset ^ 0x0000, 15, 14, 13, 12, 11, 10, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4); break;
1036 case 0x280: ret = bitswap<16>(offset ^ 0x02a1, 15, 14, 13, 12, 11, 10, 9, 1, 7, 8, 5, 6, 2, 4, 3, 0); break;
1037 case 0x2c0: ret = bitswap<16>(offset ^ 0x0000, 15, 14, 13, 12, 11, 10, 0, 3, 4, 6, 8, 7, 5, 9, 2, 1); break;
1038 case 0x300: ret = bitswap<16>(offset ^ 0x03c0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 1, 2, 0, 5, 3, 4); break;
1039 case 0x340: ret = bitswap<16>(offset ^ 0x0030, 15, 14, 13, 12, 11, 10, 0, 2, 3, 9, 5, 4, 8, 7, 6, 1); break;
1040 case 0x380: ret = bitswap<16>(offset ^ 0x0001, 15, 14, 13, 12, 11, 10, 6, 5, 4, 3, 2, 1, 9, 8, 7, 0); break;
1041 case 0x3c0: ret = bitswap<16>(offset ^ 0x0090, 15, 14, 13, 12, 11, 10, 5, 3, 7, 2, 1, 4, 0, 9, 8, 6); break;
1042 case 0x400: ret = bitswap<16>(offset ^ 0x02a1, 15, 14, 13, 12, 11, 10, 9, 1, 7, 8, 5, 6, 2, 4, 3, 0); break;
1043 case 0x440: ret = bitswap<16>(offset ^ 0x03c0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 1, 2, 0, 5, 3, 4); break;
1044 case 0x480: ret = bitswap<16>(offset ^ 0x0141, 15, 14, 13, 12, 11, 10, 4, 8, 2, 6, 1, 7, 9, 5, 3, 0); break;
1045 case 0x4c0: ret = bitswap<16>(offset ^ 0x01c0, 15, 14, 13, 12, 11, 10, 2, 8, 7, 6, 4, 3, 5, 9, 0, 1); break;
1046 case 0x500: ret = bitswap<16>(offset ^ 0x0141, 15, 14, 13, 12, 11, 10, 4, 8, 2, 6, 1, 7, 9, 5, 3, 0); break;
1047 case 0x540: ret = bitswap<16>(offset ^ 0x0030, 15, 14, 13, 12, 11, 10, 0, 2, 3, 9, 5, 4, 8, 7, 6, 1); break;
1048 case 0x580: ret = bitswap<16>(offset ^ 0x03c0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 1, 2, 0, 5, 3, 4); break;
1049 case 0x5c0: ret = bitswap<16>(offset ^ 0x0090, 15, 14, 13, 12, 11, 10, 5, 3, 7, 2, 1, 4, 0, 9, 8, 6); break;
1050 case 0x600: ret = bitswap<16>(offset ^ 0x0000, 15, 14, 13, 12, 11, 10, 0, 3, 4, 6, 8, 7, 5, 9, 2, 1); break;
1051 case 0x640: ret = bitswap<16>(offset ^ 0x0000, 15, 14, 13, 12, 11, 10, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5); break;
1052 }
1053
1054 if (offset >= 0xce80/2 && offset <= 0xceff/2) ret -= 0x0100;
1055 if (offset >= 0xcf00/2 && offset <= 0xcf7f/2) ret += 0x0100;
1056
1057 return ret;
1058 }
1059
1060 /* preliminary */
command_handler_py2k2(int pc)1061 void pgm_arm_type1_state::command_handler_py2k2(int pc)
1062 {
1063 switch (m_ddp3lastcommand)
1064 {
1065 case 0x30:
1066 m_valueresponse = py2k2_sprite_offset(m_py2k2_sprite_base, m_py2k2_sprite_pos++);
1067 break;
1068 case 0x32:
1069 m_py2k2_sprite_base = m_value0;
1070 m_py2k2_sprite_pos = 0;
1071 m_valueresponse = py2k2_sprite_offset(m_py2k2_sprite_base, m_py2k2_sprite_pos++);
1072 break;
1073 case 0xba:
1074 m_valueresponse = m_py2k2_prev_base;
1075 m_py2k2_prev_base = m_value0;
1076 break;
1077 case 0x99: // reset?
1078 m_py2k2_prev_base = m_value0;
1079 m_simregion = m_region->read();
1080 m_valuekey = 0x100;
1081 m_valueresponse = 0x00880000 | m_simregion<<8;
1082 break;
1083 case 0xc0:
1084 puzzli2_printf("%06x command %02x | %04x\n", pc, m_ddp3lastcommand, m_value0);
1085 m_valueresponse = 0x880000;
1086 break;
1087 case 0xc3:
1088 m_valueresponse = 0x904000 + ((m_extra_ram[0xc0] + (m_value0 * 0x40)) * 4);
1089 break;
1090 case 0xd0:
1091 m_valueresponse = 0xa01000 + (m_value0 * 0x20);
1092 break;
1093 case 0xdc:
1094 m_valueresponse = 0xa00800 + (m_value0 * 0x40);
1095 break;
1096 case 0xe0:
1097 m_valueresponse = 0xa00000 + ((m_value0 & 0x1f) * 0x40);
1098 break;
1099 case 0xcb: // Background layer 'x' select (pgm3in1, same as kov)
1100 m_valueresponse = 0x880000;
1101 break;
1102 case 0xcc: // Background layer offset (pgm3in1, same as kov)
1103 {
1104 int y = m_value0;
1105 if (y & 0x400) y = -(0x400 - (y & 0x3ff));
1106 m_valueresponse = 0x900000 + ((m_extra_ram[0xcb] + (y * 0x40)) * 4);
1107 }
1108 break;
1109 case 0x33:
1110 case 0x34:
1111 case 0x35:
1112 case 0x37:
1113 case 0x38:
1114 default:
1115 puzzli2_printf("%06x command %02x | %04x\n", pc, m_ddp3lastcommand, m_value0);
1116 m_valueresponse = 0x880000;
1117 break;
1118 }
1119 }
1120
1121 /* preliminary */
1122
1123
1124 static const int pstar_ba[0x1E]={
1125 0x02,0x00,0x00,0x01,0x00,0x03,0x00,0x00, //0
1126 0x02,0x00,0x06,0x00,0x22,0x04,0x00,0x03, //8
1127 0x00,0x00,0x06,0x00,0x20,0x07,0x00,0x03, //10
1128 0x00,0x21,0x01,0x00,0x00,0x63
1129 };
1130
1131 static const int pstar_b0[0x10]={
1132 0x09,0x0A,0x0B,0x00,0x01,0x02,0x03,0x04,
1133 0x05,0x06,0x07,0x08,0x00,0x00,0x00,0x00
1134 };
1135
1136 static const int pstar_ae[0x10]={
1137 0x5D,0x86,0x8C ,0x8B,0xE0,0x8B,0x62,0xAF,
1138 0xB6,0xAF,0x10A,0xAF,0x00,0x00,0x00,0x00
1139 };
1140
1141 static const int pstar_a0[0x10]={
1142 0x02,0x03,0x04,0x05,0x06,0x01,0x0A,0x0B,
1143 0x0C,0x0D,0x0E,0x09,0x00,0x00,0x00,0x00,
1144 };
1145
1146 static const int pstar_9d[0x10]={
1147 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1148 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1149 };
1150
1151 static const int pstar_90[0x10]={
1152 0x0C,0x10,0x0E,0x0C,0x00,0x00,0x00,0x00,
1153 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
1154 };
1155 static const int pstar_8c[0x23]={
1156 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1157 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,
1158 0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,
1159 0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,
1160 0x03,0x03,0x03
1161 };
1162
1163 static const int pstar_80[0x1a3]={
1164 0x03,0x03,0x04,0x04,0x04,0x04,0x05,0x05,
1165 0x05,0x05,0x06,0x06,0x03,0x03,0x04,0x04,
1166 0x05,0x05,0x05,0x05,0x06,0x06,0x07,0x07,
1167 0x03,0x03,0x04,0x04,0x05,0x05,0x05,0x05,
1168 0x06,0x06,0x07,0x07,0x06,0x06,0x06,0x06,
1169 0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,
1170 0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x07,
1171 0x07,0x07,0x08,0x08,0x05,0x05,0x05,0x05,
1172 0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,
1173 0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,
1174 0x09,0x09,0x09,0x09,0x07,0x07,0x07,0x07,
1175 0x07,0x08,0x08,0x08,0x08,0x09,0x09,0x09,
1176 0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,
1177 0x08,0x08,0x09,0x09,0x05,0x05,0x06,0x06,
1178 0x06,0x07,0x07,0x08,0x08,0x08,0x08,0x09,
1179 0x07,0x07,0x07,0x07,0x07,0x08,0x08,0x08,
1180 0x08,0x09,0x09,0x09,0x06,0x06,0x07,0x03,
1181 0x07,0x06,0x07,0x07,0x08,0x07,0x05,0x04,
1182 0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,
1183 0x06,0x06,0x06,0x06,0x03,0x04,0x04,0x04,
1184 0x04,0x05,0x05,0x06,0x06,0x06,0x06,0x07,
1185 0x04,0x04,0x05,0x05,0x06,0x06,0x06,0x06,
1186 0x06,0x07,0x07,0x08,0x05,0x05,0x06,0x07,
1187 0x07,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
1188 0x05,0x05,0x05,0x07,0x07,0x07,0x07,0x07,
1189 0x07,0x08,0x08,0x08,0x08,0x08,0x09,0x09,
1190 0x09,0x09,0x03,0x04,0x04,0x05,0x05,0x05,
1191 0x06,0x06,0x07,0x07,0x07,0x07,0x08,0x08,
1192 0x08,0x09,0x09,0x09,0x03,0x04,0x05,0x05,
1193 0x04,0x03,0x04,0x04,0x04,0x05,0x05,0x04,
1194 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
1195 0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04,
1196 0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,
1197 0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,
1198 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1199 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1200 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1201 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1202 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1203 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1204 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1205 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1206 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1207 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1208 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1209 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1210 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1211 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1212 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1213 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,
1214 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,
1215 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1216 0x00,0x00,0x00
1217 };
1218
command_handler_pstars(int pc)1219 void pgm_arm_type1_state::command_handler_pstars(int pc)
1220 {
1221 switch (m_ddp3lastcommand)
1222 {
1223 case 0x99:
1224 m_simregion = m_region->read();
1225 m_valuekey = 0x100;
1226 m_valueresponse = 0x00880000 | m_simregion<<8;
1227 break;
1228
1229 case 0xe0:
1230 m_valueresponse = 0xa00000 + (m_value0 << 6);
1231 break;
1232
1233 case 0xdc:
1234 m_valueresponse = 0xa00800 + (m_value0 << 6);
1235 break;
1236
1237 case 0xd0:
1238 m_valueresponse = 0xa01000 + (m_value0 << 5);
1239 break;
1240
1241 case 0xb1:
1242 m_pstar_b1_value = m_value0;
1243 m_valueresponse = 0x890000;
1244 break;
1245
1246 case 0xbf:
1247 m_valueresponse = m_pstar_b1_value * m_value0;
1248 break;
1249
1250 case 0xc1: //TODO:TIMER 0,1,2,FIX TO 0 should be OK?
1251 m_valueresponse = 0;
1252 break;
1253
1254 case 0xce: //TODO:TIMER 0,1,2
1255 m_pstar_ce_value = m_value0;
1256 m_valueresponse=0x890000;
1257 break;
1258
1259 case 0xcf: //TODO:TIMER 0,1,2
1260 m_extra_ram[m_pstar_ce_value] = m_value0;
1261 m_valueresponse = 0x890000;
1262 break;
1263
1264 case 0xe7:
1265 m_pstar_e7_value = (m_value0 >> 12) & 0xf;
1266 m_slots[m_pstar_e7_value] &= 0xffff;
1267 m_slots[m_pstar_e7_value] |= (m_value0 & 0xff) << 16;
1268 m_valueresponse = 0x890000;
1269 break;
1270
1271 case 0xe5:
1272 m_slots[m_pstar_e7_value] &= 0xff0000;
1273 m_slots[m_pstar_e7_value] |= m_value0;
1274 m_valueresponse = 0x890000;
1275 break;
1276
1277 case 0xf8: //@73C
1278 m_valueresponse = m_slots[m_value0 & 0xf] & 0xffffff;
1279 break;
1280
1281 case 0xba:
1282 m_valueresponse = pstar_ba[m_value0];
1283 break;
1284
1285 case 0xb0:
1286 m_valueresponse = pstar_b0[m_value0];
1287 break;
1288
1289 case 0xae:
1290 m_valueresponse = pstar_ae[m_value0];
1291 break;
1292
1293 case 0xa0:
1294 m_valueresponse = pstar_a0[m_value0];
1295 break;
1296
1297 case 0x9d:
1298 m_valueresponse = pstar_9d[m_value0];
1299 break;
1300
1301 case 0x90:
1302 m_valueresponse = pstar_90[m_value0];
1303 break;
1304
1305 case 0x8c:
1306 m_valueresponse = pstar_8c[m_value0];
1307 break;
1308
1309 case 0x80:
1310 m_valueresponse = pstar_80[m_value0];
1311 break;
1312
1313 default:
1314 m_valueresponse = 0x890000;
1315 logerror("PSTARS PC(%06x) UNKNOWN %4X %4X\n", pc, m_value1, m_value0);
1316 }
1317 }
1318
1319 /* Old KOV and bootlegs sim ... really these should be read out... */
1320
1321 static const u8 kov_BATABLE[0x40] = {
1322 0x00,0x29,0x2c,0x35,0x3a,0x41,0x4a,0x4e,0x57,0x5e,0x77,0x79,0x7a,0x7b,0x7c,0x7d,
1323 0x7e,0x7f,0x80,0x81,0x82,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x90,
1324 0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9e,0xa3,0xd4,0xa9,0xaf,0xb5,0xbb,0xc1
1325 };
1326
1327 static const u8 kov_B0TABLE[16] = { 2, 0, 1, 4, 3 }; // Maps char portraits to tables
1328
1329
command_handler_kov(int pc)1330 void pgm_arm_type1_state::command_handler_kov(int pc)
1331 {
1332 switch (m_ddp3lastcommand)
1333 {
1334 case 0x67: // unknown or status check?
1335 case 0x8e:
1336 case 0xa3:
1337 case 0x33: // kovsgqyz (a3)
1338 case 0x3a: // kovplus
1339 case 0xc5: // kovplus
1340 m_valueresponse = 0x880000;
1341 break;
1342
1343 case 0x99: // Reset
1344 m_simregion = m_region->read();
1345 m_valueresponse = 0x880000 | m_simregion<<8;
1346 m_valuekey = 0x100;
1347 break;
1348
1349 case 0x9d: // Sprite palette offset
1350 m_valueresponse = 0xa00000 + ((m_value0 & 0x1f) * 0x40);
1351 break;
1352
1353 case 0xb0: // Read from data table
1354 m_valueresponse = kov_B0TABLE[m_value0 & 0x0f];
1355 break;
1356
1357 case 0xb4: // Copy slot 'a' to slot 'b'
1358 case 0xb7: // kovsgqyz (b4)
1359 {
1360 m_valueresponse = 0x880000;
1361
1362 if (m_value0 == 0x0102) m_value0 = 0x0100; // why?
1363
1364 m_slots[(m_value0 >> 8) & 0x0f] = m_slots[(m_value0 >> 0) & 0x0f];
1365 }
1366 break;
1367
1368 case 0xba: // Read from data table
1369 m_valueresponse = kov_BATABLE[m_value0 & 0x3f];
1370 break;
1371
1372 case 0xc0: // Text layer 'x' select
1373 m_valueresponse = 0x880000;
1374 m_kov_c0_value = m_value0;
1375 break;
1376
1377 case 0xc3: // Text layer offset
1378 m_valueresponse = 0x904000 + ((m_kov_c0_value + (m_value0 * 0x40)) * 4);
1379 break;
1380
1381 case 0xcb: // Background layer 'x' select
1382 m_valueresponse = 0x880000;
1383 m_kov_cb_value = m_value0;
1384 break;
1385
1386 case 0xcc: // Background layer offset
1387 {
1388 int y = m_value0;
1389 if (y & 0x400) y = -(0x400 - (y & 0x3ff));
1390 m_valueresponse = 0x900000 + ((m_kov_cb_value + (y * 0x40)) * 4);
1391 }
1392 break;
1393
1394 case 0xd0: // Text palette offset
1395 case 0xcd: // kovsgqyz (d0)
1396 m_valueresponse = 0xa01000 + (m_value0 * 0x20);
1397 break;
1398
1399 case 0xd6: // Copy slot to slot 0
1400 m_valueresponse = 0x880000;
1401 m_slots[0] = m_slots[m_value0 & 0x0f];
1402 break;
1403
1404 case 0xdc: // Background palette offset
1405 case 0x11: // kovsgqyz (dc)
1406 m_valueresponse = 0xa00800 + (m_value0 * 0x40);
1407 break;
1408
1409 case 0xe0: // Sprite palette offset
1410 case 0x9e: // kovsgqyz (e0)
1411 m_valueresponse = 0xa00000 + ((m_value0 & 0x1f) * 0x40);
1412 break;
1413
1414 case 0xe5: // Write slot (low)
1415 {
1416 m_valueresponse = 0x880000;
1417
1418 s32 sel = (m_curslots >> 12) & 0x0f;
1419 m_slots[sel] = (m_slots[sel] & 0x00ff0000) | ((m_value0 & 0xffff) << 0);
1420 }
1421 break;
1422
1423 case 0xe7: // Write slot (and slot select) (high)
1424 {
1425 m_valueresponse = 0x880000;
1426 m_curslots = m_value0;
1427
1428 s32 sel = (m_curslots >> 12) & 0x0f;
1429 m_slots[sel] = (m_slots[sel] & 0x0000ffff) | ((m_value0 & 0x00ff) << 16);
1430 }
1431 break;
1432
1433 case 0xf0: // Some sort of status read?
1434 m_valueresponse = 0x00c000;
1435 break;
1436
1437 case 0xf8: // Read slot
1438 case 0xab: // kovsgqyz (f8)
1439 m_valueresponse = m_slots[m_value0 & 0x0f] & 0x00ffffff;
1440 break;
1441
1442 case 0xfc: // Adjust damage level to char experience level
1443 m_valueresponse = (m_value0 * m_kov_fe_value) >> 6;
1444 break;
1445
1446 case 0xfe: // Damage level adjust
1447 m_valueresponse = 0x880000;
1448 m_kov_fe_value = m_value0;
1449 break;
1450
1451 default:
1452 m_valueresponse = 0x880000;
1453 // logerror("Unknown ASIC27 command: %2.2x data: %4.4x\n", (data ^ m_valuekey) & 0xff, m_value0);
1454 break;
1455 }
1456 }
1457
1458
1459 /* Oriental Legend Super Plus ARM simulation */
1460
1461 static const int oldsplus_80[0x5]={
1462 0xbb8,0x1770,0x2328,0x2ee0,0xf4240
1463 };
1464
1465 static const int oldsplus_fc[0x20]={
1466 0x00,0x00,0x0a,0x3a,0x4e,0x2e,0x03,0x40,
1467 0x33,0x43,0x26,0x2c,0x00,0x00,0x00,0x00,
1468 0x00,0x00,0x44,0x4d,0xb,0x27,0x3d,0x0f,
1469 0x37,0x2b,0x02,0x2f,0x15,0x45,0x0e,0x30
1470 };
1471
1472 static const int oldsplus_a0[0x20]={
1473 0x000,0x023,0x046,0x069,0x08c,0x0af,0x0d2,0x0f5,
1474 0x118,0x13b,0x15e,0x181,0x1a4,0x1c7,0x1ea,0x20d,
1475 0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,
1476 0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,
1477 };
1478
1479 static const int oldsplus_90[0x7]={
1480 0x50,0xa0,0xc8,0xf0,0x190,0x1f4,0x258
1481 };
1482
1483 static const int oldsplus_5e[0x20]={
1484 0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,
1485 0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,
1486 0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1487 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
1488 };
1489
1490 static const int oldsplus_b0[0xe0]={
1491 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1492 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1493 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1494 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1495
1496 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1497 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1498 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1499 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1500
1501 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1502 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,
1503 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
1504 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,
1505
1506 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1507 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1508 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,
1509 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
1510
1511 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,
1512 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
1513 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,
1514 0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,
1515
1516 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1517 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
1518 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
1519 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
1520
1521 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,
1522 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,
1523 0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
1524 0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f
1525 };
1526
1527 static const int oldsplus_ae[0xe0]={
1528 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
1529 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
1530 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
1531 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
1532
1533 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
1534 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
1535 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
1536 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
1537
1538 0x1E,0x1F,0x20,0x21,0x22,0x23,0x23,0x23,
1539 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1540 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1541 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1542
1543 0x1F,0x20,0x21,0x22,0x23,0x23,0x23,0x23,
1544 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1545 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1546 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1547
1548 0x20,0x21,0x22,0x23,0x23,0x23,0x23,0x23,
1549 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1550 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1551 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1552
1553 0x21,0x22,0x23,0x23,0x23,0x23,0x23,0x23,
1554 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1555 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1556 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1557
1558 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1559 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1560 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
1561 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23
1562 };
1563
1564 static const int oldsplus_ba[0x4]={
1565 0x3138,0x2328,0x1C20,0x1518
1566 };
1567
1568 static const int oldsplus_9d[0x111]={
1569 0x0000,0x0064,0x00c8,0x012c,0x0190,0x01f4,0x0258,0x02bc,
1570 0x02f8,0x0334,0x0370,0x03ac,0x03e8,0x0424,0x0460,0x049c,
1571 0x04d8,0x0514,0x0550,0x058c,0x05c8,0x0604,0x0640,0x06bc,
1572 0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,
1573 0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x0000,
1574 0x0064,0x00c8,0x012c,0x0190,0x01f4,0x0258,0x02bc,0x0302,
1575 0x0348,0x038e,0x03d4,0x041a,0x0460,0x04a6,0x04ec,0x0532,
1576 0x0578,0x05be,0x0604,0x064a,0x0690,0x06d6,0x06bc,0x06bc,
1577 0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,
1578 0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x0000,0x0064,
1579 0x00c8,0x012c,0x0190,0x01f4,0x0258,0x02bc,0x0316,0x0370,
1580 0x03ca,0x0424,0x047e,0x04d8,0x0532,0x058c,0x05e6,0x0640,
1581 0x069a,0x06f4,0x074e,0x07a8,0x0802,0x06bc,0x06bc,0x06bc,
1582 0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,
1583 0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x0000,0x0064,0x00c8,
1584 0x012c,0x0190,0x01f4,0x0258,0x02bc,0x032a,0x0398,0x0406,
1585 0x0474,0x04e2,0x0550,0x05be,0x062c,0x069a,0x0708,0x0776,
1586 0x07e4,0x0852,0x08c0,0x092e,0x06bc,0x06bc,0x06bc,0x06bc,
1587 0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,
1588 0x06bc,0x06bc,0x06bc,0x06bc,0x0000,0x0064,0x00c8,0x012c,
1589 0x0190,0x01f4,0x0258,0x02bc,0x0348,0x03d4,0x0460,0x04ec,
1590 0x0578,0x0604,0x0690,0x071c,0x07a8,0x0834,0x08c0,0x094c,
1591 0x09d8,0x0a64,0x0af0,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,
1592 0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,
1593 0x06bc,0x06bc,0x06bc,0x0000,0x0064,0x00c8,0x012c,0x0190,
1594 0x01f4,0x0258,0x02bc,0x0384,0x044c,0x0514,0x05dc,0x06a4,
1595 0x076c,0x0834,0x08fc,0x09c4,0x0a8c,0x0b54,0x0c1c,0x0ce4,
1596 0x0dac,0x0e74,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,
1597 0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,
1598 0x06bc,0x06bc,0x0000,0x0064,0x00c8,0x012c,0x0190,0x01f4,
1599 0x0258,0x02bc,0x030c,0x035c,0x03ac,0x03fc,0x044c,0x049c,
1600 0x04ec,0x053c,0x058c,0x05dc,0x062c,0x067c,0x06cc,0x071c,
1601 0x076c,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,
1602 0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,0x06bc,
1603 0x06bc
1604 };
1605
1606 static const int oldsplus_8c[0x20]={
1607 0x0032,0x0032,0x0064,0x0096,0x0096,0x00fa,0x012c,0x015e,
1608 0x0032,0x0064,0x0096,0x00c8,0x00c8,0x012c,0x015e,0x0190,
1609 0x0064,0x0096,0x00c8,0x00fa,0x00fa,0x015e,0x0190,0x01c2,
1610 0x0096,0x00c8,0x00fa,0x012c,0x012c,0x0190,0x01c2,0x01f4
1611 };
1612
1613
command_handler_oldsplus(int pc)1614 void pgm_arm_type1_state::command_handler_oldsplus(int pc)
1615 {
1616 switch (m_ddp3lastcommand)
1617 {
1618 case 0x88:
1619 m_simregion = m_region->read();
1620 m_valuekey = 0x100;
1621 m_valueresponse = 0x00990000 | m_simregion<<8;
1622
1623 break;
1624
1625 case 0xd0:
1626 m_valueresponse = 0xa01000 + (m_value0 << 5);
1627 break;
1628
1629 case 0xc0:
1630 m_valueresponse = 0xa00000 + (m_value0 << 6);
1631 break;
1632
1633 case 0xc3:
1634 m_valueresponse = 0xa00800 + (m_value0 << 6);
1635 break;
1636
1637 case 0x36:
1638 m_extra_ram[0x36] = m_value0;
1639 m_valueresponse = 0x990000;
1640 break;
1641
1642 case 0x33:
1643 m_extra_ram[0x33] = m_value0;
1644 m_valueresponse = 0x990000;
1645 break;
1646
1647 case 0x35:
1648 m_extra_ram[0x36] += m_value0;
1649 m_valueresponse = 0x990000;
1650 break;
1651
1652 case 0x37:
1653 m_extra_ram[0x33] += m_value0;
1654 m_valueresponse = 0x990000;
1655 break;
1656
1657 case 0x34:
1658 m_valueresponse = m_extra_ram[0x36];
1659 break;
1660
1661 case 0x38:
1662 m_valueresponse = m_extra_ram[0x33];
1663 break;
1664
1665 case 0x80:
1666 m_valueresponse = oldsplus_80[m_value0];
1667 break;
1668
1669 case 0xe7:
1670 m_extra_ram[0xe7] = m_value0;
1671 m_valueresponse = 0x990000;
1672 break;
1673
1674 case 0xe5:
1675 switch (m_extra_ram[0xe7])
1676 {
1677 case 0xb000:
1678 m_slots[0xb] = m_value0;
1679 m_slots[0xc] = 0;
1680 break;
1681
1682 case 0xc000:
1683 m_slots[0xc] = m_value0;
1684 break;
1685
1686 case 0xd000:
1687 m_slots[0xd] = m_value0;
1688 break;
1689
1690 case 0xf000:
1691 m_slots[0xf] = m_value0;
1692 break;
1693 }
1694 m_valueresponse = 0x990000;
1695 break;
1696
1697 case 0xf8:
1698 m_valueresponse = m_slots[m_value0];
1699 break;
1700
1701 case 0xfc:
1702 m_valueresponse = oldsplus_fc[m_value0];
1703 break;
1704
1705 case 0xc5:
1706 m_slots[0xd] --;
1707 m_valueresponse = 0x990000;
1708 break;
1709
1710 case 0xd6:
1711 m_slots[0xb] ++;
1712 m_valueresponse = 0x990000;
1713 break;
1714
1715 case 0x3a:
1716 m_slots[0xf] = 0;
1717 m_valueresponse = 0x990000;
1718 break;
1719
1720 case 0xf0:
1721 m_extra_ram[0xf0] = m_value0;
1722 m_valueresponse = 0x990000;
1723 break;
1724
1725 case 0xed:
1726 m_valueresponse = m_value0 << 0x6;
1727 m_valueresponse += m_extra_ram[0xf0];
1728 m_valueresponse = m_valueresponse << 0x2;
1729 m_valueresponse += 0x900000;
1730 break;
1731
1732 case 0xe0:
1733 m_extra_ram[0xe0] = m_value0;
1734 m_valueresponse = 0x990000;
1735 break;
1736
1737 case 0xdc:
1738 m_valueresponse = m_value0 << 0x6;
1739 m_valueresponse += m_extra_ram[0xe0];
1740 m_valueresponse = m_valueresponse << 0x2;
1741 m_valueresponse += 0x904000;
1742 break;
1743
1744 case 0xcb:
1745 m_valueresponse = 0xc000;
1746 break;
1747
1748 case 0xa0:
1749 m_valueresponse = oldsplus_a0[m_value0];
1750 break;
1751
1752 case 0xba:
1753 m_valueresponse = oldsplus_ba[m_value0];
1754 break;
1755
1756 case 0x5e:
1757 m_valueresponse = oldsplus_5e[m_value0];
1758 break;
1759
1760 case 0xb0:
1761 m_valueresponse = oldsplus_b0[m_value0];
1762 break;
1763
1764 case 0xae:
1765 m_valueresponse = oldsplus_ae[m_value0];
1766 break;
1767
1768 case 0x9d:
1769 m_valueresponse = oldsplus_9d[m_value0];
1770 break;
1771
1772 case 0x90:
1773 m_valueresponse = oldsplus_90[m_value0];
1774 break;
1775
1776 case 0x8c:
1777 m_valueresponse = oldsplus_8c[m_value0];
1778 break;
1779
1780 default:
1781 m_valueresponse = 0x990000;
1782 printf("%06X: oldsplus_UNKNOWN W CMD %X VAL %X\n", pc,m_value1,m_value0);
1783 break;
1784 }
1785 }
1786
arm7_type1_sim_w(offs_t offset,u16 data)1787 void pgm_arm_type1_state::arm7_type1_sim_w(offs_t offset, u16 data)
1788 {
1789 const int pc = m_maincpu->pc();
1790
1791 if (offset == 0)
1792 {
1793 m_value0 = data;
1794 return;
1795 }
1796 else if (offset == 1)
1797 {
1798 u16 realkey;
1799 if ((data >> 8) == 0xff)
1800 m_valuekey = 0xff00;
1801 realkey = m_valuekey >> 8;
1802 realkey |= m_valuekey;
1803 {
1804 m_valuekey += 0x0100;
1805 m_valuekey &= 0xff00;
1806 if (m_valuekey == 0xff00)
1807 m_valuekey = 0x0100;
1808 }
1809 data ^= realkey;
1810 m_value1 = data;
1811 m_value0 ^= realkey;
1812
1813 m_ddp3lastcommand = m_value1 & 0xff;
1814
1815 (this->*arm_sim_handler)(pc);
1816 }
1817 else if (offset == 2)
1818 {
1819 }
1820 }
1821
arm7_type1_sim_protram_r(offs_t offset)1822 u16 pgm_arm_type1_state::arm7_type1_sim_protram_r(offs_t offset)
1823 {
1824 if (offset == 4)
1825 return m_simregion;
1826
1827 return 0x0000;
1828 }
1829
pstars_arm7_type1_sim_protram_r(offs_t offset)1830 u16 pgm_arm_type1_state::pstars_arm7_type1_sim_protram_r(offs_t offset)
1831 {
1832 if (offset == 4) //region
1833 return m_region->read();
1834 else if (offset >= 0x10) //timer
1835 {
1836 const u16 val = m_extra_ram[offset - 0x10];
1837 if (!machine().side_effects_disabled())
1838 {
1839 logerror("PSTARS ACCESS COUNTER %6X\n", val);
1840 m_extra_ram[offset - 0x10]--;
1841 }
1842 return val;
1843 }
1844 return 0x0000;
1845 }
1846
1847
init_ddp3()1848 void pgm_arm_type1_state::init_ddp3()
1849 {
1850 pgm_basic_init(false);
1851 pgm_py2k2_decrypt(machine()); // yes, it's the same as photo y2k2
1852 arm_sim_handler = &pgm_arm_type1_state::command_handler_ddp3;
1853 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x500000, 0x500005, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_r)), write16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_w)));
1854 }
1855
init_ket()1856 void pgm_arm_type1_state::init_ket()
1857 {
1858 pgm_basic_init(false);
1859 pgm_ket_decrypt(machine());
1860 arm_sim_handler = &pgm_arm_type1_state::command_handler_ddp3;
1861 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x400000, 0x400005, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_r)), write16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_w)));
1862 }
1863
init_espgal()1864 void pgm_arm_type1_state::init_espgal()
1865 {
1866 pgm_basic_init(false);
1867 pgm_espgal_decrypt(machine());
1868 arm_sim_handler = &pgm_arm_type1_state::command_handler_ddp3;
1869 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x400000, 0x400005, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_r)), write16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_w)));
1870 }
1871
1872
count_bits(u16 value)1873 int count_bits(u16 value)
1874 {
1875 int count = 0;
1876 for (int i = 0; i < 16; i++)
1877 {
1878 int bit = (value >> i) & 1;
1879
1880 if (bit) count++;
1881 }
1882
1883 return count;
1884 }
1885
get_position_of_bit(u16 value,int bit_wanted)1886 int get_position_of_bit(u16 value, int bit_wanted)
1887 {
1888 int count = 0;
1889 for (int i = 0; i < 16; i++)
1890 {
1891 int bit = (value >> i) & 1;
1892
1893 if (bit) count++;
1894
1895 if (count==(bit_wanted+1))
1896 return i;
1897 }
1898
1899 return -1;
1900 }
1901
puzzli2_take_leveldata_value(u8 datvalue)1902 int pgm_arm_type1_state::puzzli2_take_leveldata_value(u8 datvalue)
1903 {
1904 if (stage == -1)
1905 {
1906 entries_left = 0;
1907 currentcolumn = 0;
1908 currentrow = 0;
1909 num_entries = 0;
1910 full_entry = 0;
1911 prev_tablloc = 0;
1912 numbercolumns = 0;
1913 depth = 0;
1914 m_row_bitmask = 0;
1915
1916 puzzli2_printf("%02x <- table offset\n", datvalue);
1917 tableoffs = datvalue;
1918 tableoffs2 = 0;
1919 stage = 0;
1920 }
1921 else
1922 {
1923 u8 rawvalue = datvalue;
1924 u8 tableloc = (tableoffs+tableoffs2) & 0xff;
1925 rawvalue ^= puzzli2_level_decode[tableloc];
1926
1927 tableoffs2++;
1928 tableoffs2 &= 0xf;
1929
1930 if (stage == 0)
1931 {
1932 stage = 1;
1933
1934 // this seems to be the first thing returned back when reading the level structure always seems to be 0x8 or 0x7, makes sense, levels would be too difficult otherwise ;-) (actually puzzli2 seems to have one specifying 5 unless it's a decrypt table error?!)
1935 depth = (rawvalue & 0xf0);
1936 numbercolumns = (rawvalue & 0x0f);
1937 numbercolumns++;
1938
1939 puzzli2_printf("%02x <- Sizes (level depth %01x) (number of columns %01x)", rawvalue, depth>>4, numbercolumns);
1940
1941 if ((depth != 0x80) && (depth != 0x70) && (depth != 0x50))
1942 fatalerror("depth isn't 0x5, 0x7 or 0x8");
1943
1944 // it seems to use this to specify the number of columns, ie how many data structures follow, so that the ARM knows when to send back the 'finished' flag.
1945 // it also gets returned at the end with said flag
1946 if ((numbercolumns != 0x6) && (numbercolumns != 0x7) && (numbercolumns != 0x8))
1947 fatalerror("number of columns specified isn't 6,7, or 8");
1948
1949 puzzli2_printf("\n");
1950
1951 }
1952 else if (stage == 1)
1953 {
1954 puzzli2_printf("%02x <- Number of Entries for this Column (and upper mask) (column is %d) (xor table location is %02x) ", rawvalue, currentcolumn, tableloc);
1955 stage = 2;
1956 entries_left = (rawvalue >> 4);
1957 m_row_bitmask = (rawvalue & 0x0f)<<8;
1958
1959 full_entry = rawvalue;
1960 prev_tablloc = tableloc;
1961
1962 num_entries = entries_left;
1963
1964 if (num_entries == 0x00)
1965 {
1966 puzzli2_printf("0 entries for this column?"); // seems a valid condition based on the data
1967 }
1968
1969 puzzli2_printf("\n");
1970 }
1971 else if (stage == 2)
1972 {
1973 puzzli2_printf("%02x <- Mask value equal to number of entries (xor table location is %02x)", rawvalue, tableloc);
1974 stage = 3;
1975
1976 m_row_bitmask |= rawvalue;
1977
1978 int num_mask_bits = count_bits(m_row_bitmask);
1979
1980 if (num_mask_bits != num_entries)
1981 puzzli2_printf(" error - number of mask bits != number of entries - ");
1982
1983 //
1984 if (entries_left == 0)
1985 {
1986 // for 0 entries skip back to state 1 instead of 3, because there is nothing following
1987 stage = 1;
1988 currentcolumn++;
1989 currentrow = 0;
1990 m_row_bitmask = 0;
1991
1992 coverage[tableloc] = 1;
1993 if (rawvalue != 0)
1994 {
1995 puzzli2_printf(" invalid mask after 00 length?");
1996 // attempt to correct the table
1997 //new_puzzli2_level_decode[tableloc] = new_puzzli2_level_decode[tableloc] ^ rawvalue;
1998
1999 }
2000 coverage[prev_tablloc] = 1;
2001 if (full_entry != 0)
2002 {
2003 puzzli2_printf(" previous value wasn't 0x00");
2004 }
2005
2006 if (currentcolumn == numbercolumns)
2007 {
2008 return 1;
2009 }
2010
2011 }
2012 else
2013 {
2014 if (num_entries> 0xa)
2015 {
2016 puzzli2_printf(" more than 10 entries?");
2017 }
2018 else
2019 {
2020 // this isn't a strict rule
2021 // the mask is used so they can specify spaces between elements too without storing the 00 bytes
2022 coverage[tableloc] = 1;
2023
2024 int desired_mask = 0;
2025
2026 if (num_entries == 0x00) desired_mask = 0x00;
2027 if (num_entries == 0x01) desired_mask = 0x01;
2028 if (num_entries == 0x02) desired_mask = 0x03;
2029 if (num_entries == 0x03) desired_mask = 0x07;
2030 if (num_entries == 0x04) desired_mask = 0x0f;
2031 if (num_entries == 0x05) desired_mask = 0x1f;
2032 if (num_entries == 0x06) desired_mask = 0x3f;
2033 if (num_entries == 0x07) desired_mask = 0x7f;
2034 if (num_entries == 0x08) desired_mask = 0xff;
2035 if (num_entries == 0x09) desired_mask = 0xff;
2036 if (num_entries == 0x0a) desired_mask = 0xff;
2037
2038 if (rawvalue != desired_mask)
2039 {
2040 puzzli2_printf(" possible wrong mask?");
2041 }
2042
2043 }
2044
2045 }
2046
2047 puzzli2_printf("\n");
2048
2049 }
2050 else if (stage == 3)
2051 {
2052 u16 object_value;
2053
2054 // return values
2055 // 0x0100 = normal fish
2056 // 0x0120 = fish in bubble
2057 // 0x0140 = fish in egg
2058 // 0x0160 = buggy fish in egg (displayed as normal fish)
2059 // 0x0180 = fish on hook
2060 // 0x01a0 = fish on hook (uncatchable)
2061 // 0x01c0 - fish on hook (uncatchable)
2062 // 0x01e0 - fish on hook (uncatchable)
2063
2064 // fish values
2065 // 100 101 102 103 104 105 106 107 108 normal
2066 // 110 - renders as a flashing fish you can't catch? glitches game?
2067 // 111 - repeat of other fish type you can't catch...
2068
2069 if (rawvalue <= 0x10) // regular fish
2070 {
2071 int fishtype = rawvalue;
2072 puzzli2_printf("%02x <- fish type %d", rawvalue, fishtype);
2073 object_value = 0x0100 + fishtype;
2074 // 0x110 is a flashy fish? might be glitchy and need a special number..
2075 }
2076 else if (rawvalue <= 0x21) // fish in bubbles
2077 {
2078 int fishtype = rawvalue - 0x11;
2079 puzzli2_printf("%02x <- fish in bubble %d", rawvalue, fishtype);
2080 object_value = 0x0120 + fishtype;
2081 // 0x130 is a flashy fish? might be glitchy and need a special number..
2082 }
2083 else if (rawvalue <= 0x32) // fish in eggs
2084 {
2085 int fishtype = rawvalue - 0x22;
2086 puzzli2_printf("%02x <- fish in egg %d", rawvalue, fishtype);
2087 object_value = 0x0140 + fishtype;
2088 // 0x150 is a flashy fish? might be glitchy and need a special number..
2089
2090 }
2091 else if (rawvalue <= 0x43) // fish on hook cases, seem to be base 0x180
2092 {
2093 int fishtype = rawvalue - 0x33;
2094 puzzli2_printf("%02x <- fish on hook %d", rawvalue, fishtype);
2095 object_value = 0x0180 + fishtype;
2096 // 0x190 is a flashy fish? might be glitchy and need a special number..
2097
2098 }
2099 ////////////////////// special objects follow
2100 else if (rawvalue == 0xd0) {object_value = 0x0200; puzzli2_printf("%02x <- generic bubbles", rawvalue);}
2101
2102 else if (rawvalue == 0xe0) {object_value = 0x8000; puzzli2_printf("%02x <- solid middle", rawvalue);}
2103 else if (rawvalue == 0xe1) {object_value = 0x8020; puzzli2_printf("%02x <- solid top slant down", rawvalue);} // solid slant top down
2104 else if (rawvalue == 0xe2) {object_value = 0x8040; puzzli2_printf("%02x <- solid top slant up", rawvalue);} // solid slant top up
2105 else if (rawvalue == 0xe3) {object_value = 0x8060; puzzli2_printf("%02x <- solid bottom slant up", rawvalue);}
2106 else if (rawvalue == 0xe4) {object_value = 0x8080; puzzli2_printf("%02x <- solid bottom slant down", rawvalue);} // sold slant bottom up
2107
2108 else {object_value = 0xffff; puzzli2_printf("%02x <- unknown object", rawvalue);}
2109
2110 puzzli2_printf(" (xor table location is %02x)\n",tableloc);
2111
2112 if (object_value == 0xffff)
2113 {
2114 object_value = 0x110;
2115 popmessage("unknown object type %02x\n", rawvalue);
2116 }
2117
2118 const int realrow = get_position_of_bit(m_row_bitmask, currentrow);
2119
2120 if (realrow != -1)
2121 level_structure[currentcolumn][realrow] = object_value;
2122
2123 currentrow++;
2124
2125 entries_left--;
2126 if (entries_left == 0)
2127 {
2128 stage = 1;
2129 currentcolumn++;
2130 currentrow = 0;
2131 m_row_bitmask = 0;
2132
2133 if (currentcolumn == numbercolumns)
2134 {
2135 return 1;
2136 }
2137
2138 }
2139 }
2140
2141 }
2142
2143 return 0;
2144 }
2145
2146
2147
init_puzzli2()2148 void pgm_arm_type1_state::init_puzzli2()
2149 {
2150 pgm_basic_init();
2151
2152 pgm_puzzli2_decrypt(machine());
2153 arm_sim_handler = &pgm_arm_type1_state::command_handler_puzzli2;
2154 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x500000, 0x500005, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_r)), write16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_w)));
2155 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0000, 0x4f003f, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_protram_r)));
2156 m_irq4_disabled = 1; // // doesn't like this irq?? - seems to be RTC related
2157
2158 hackcount = 0;
2159 hackcount2 = 0;
2160 hack_47_value = 0;
2161 hack_31_table_offset = 0;
2162
2163 //#define PUZZLI2_LEVEL_STRUCTURE_LOG
2164 #ifdef PUZZLI2_LEVEL_STRUCTURE_LOG
2165 u8 *src2 = (u8 *) (machine().root_device().memregion("maincpu")->base());
2166
2167 int offset;
2168 int limit;
2169 for (int i = 0; i < 256; i++)
2170 coverage[i] = 0;
2171
2172 if (!strcmp(machine().system().name,"puzzli2"))
2173 {
2174 offset = 0x17ab66;
2175 limit = 476;
2176 }
2177 else
2178 {
2179 offset = 0x16c3ca;
2180 limit = 500;
2181 }
2182
2183
2184
2185
2186 for (int i = 0; i < limit; i++)
2187 {
2188 u32 val1 = (src2[offset+1]<<24) | (src2[offset+0] << 16) | (src2[offset+3]<<8) | (src2[offset+2] << 0);
2189 offset += 4;
2190 u32 val2 = (src2[offset+1]<<24) | (src2[offset+0] << 16) | (src2[offset+3]<<8) | (src2[offset+2] << 0);
2191
2192
2193 printf("(%d) data range %08x %08x\n", i, val1, val2);
2194
2195 int x = 0;
2196
2197 stage = -1;
2198
2199 for (x = val1; x < val2; x++)
2200 {
2201 int end = puzzli2_take_leveldata_value(src2[x^1]);
2202
2203 if (end)
2204 {
2205 printf("--- ended at %08x (val 2 was %08x)\n",x ,val2);
2206
2207 if ( (val2-x) > 2 )
2208 {
2209 fatalerror("ended even earlier than padding byte\n");
2210 }
2211 else if ( (val2-x) == 2)
2212 {
2213 printf("ended with padding byte\n");
2214 }
2215 else if ( (val2-x) == 1)
2216 {
2217 printf("ended normally\n");
2218 }
2219 else // can't happen
2220 {
2221 fatalerror("ended after marker?!\n");
2222 }
2223
2224 x = val2;
2225 }
2226
2227 }
2228
2229 printf("total number of valid columns was %02x\n", currentcolumn);
2230
2231 if ((currentcolumn != 0x6) && (currentcolumn != 0x7) && (currentcolumn != 0x8)) // 5 is suspicious
2232 fatalerror("invalid number of columns?\n");
2233
2234 if (numbercolumns != currentcolumn)
2235 fatalerror("mismatch in number of columns vs specified amount\n");
2236
2237 printf("\n");
2238
2239
2240 }
2241
2242
2243 #endif
2244
2245 #if 0
2246 if (!strcmp(machine().system().name,"puzzli2"))
2247 {
2248 u8 *src3 = (u8 *) (machine().root_device().memregion("maincpu")->base());
2249 printf("how to play data pointer %02x %02x %02x %02x\n", src3[0x17b28e ^1], src3[0x17b28f ^1], src3[0x17b290 ^1], src3[0x17b291 ^1]);
2250 src3[0x17b28e ^1] = 0x00;
2251 src3[0x17b28f ^1] = 0x11;
2252 src3[0x17b290 ^1] = 0x42;
2253 src3[0x17b291 ^1] = 0x40;
2254 }
2255
2256
2257 pgm_puzzli2_decrypt(machine());
2258
2259 {
2260 u8 *ROM = (u8*)memregion("maincpu")->base();
2261
2262 FILE *fp;
2263 char filename[256];
2264 sprintf(filename,"trojan_%s", machine().system().name);
2265 fp=fopen(filename, "w+b");
2266 if (fp)
2267 {
2268 fwrite(ROM+0x100000, 0x200000, 1, fp);
2269 fclose(fp);
2270 }
2271 }
2272
2273
2274 pgm_puzzli2_decrypt(machine());
2275 #endif
2276 }
2277
init_py2k2()2278 void pgm_arm_type1_state::init_py2k2()
2279 {
2280 pgm_basic_init();
2281 pgm_py2k2_decrypt(machine());
2282 arm_sim_handler = &pgm_arm_type1_state::command_handler_py2k2;
2283 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x500000, 0x500005, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_r)), write16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_w)));
2284 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0000, 0x4f003f, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_protram_r)));
2285
2286 m_py2k2_sprite_pos = 0;
2287 m_py2k2_sprite_base = 0;
2288 m_py2k2_prev_base = 0;
2289 save_item(NAME(m_py2k2_sprite_pos));
2290 save_item(NAME(m_py2k2_sprite_base));
2291 save_item(NAME(m_py2k2_prev_base));
2292 }
2293
init_pgm3in1()2294 void pgm_arm_type1_state::init_pgm3in1()
2295 {
2296 pgm_basic_init();
2297 pgm_decrypt_pgm3in1(machine());
2298 arm_sim_handler = &pgm_arm_type1_state::command_handler_py2k2;
2299 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x500000, 0x500005,read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_r)), write16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_w)));
2300 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0000, 0x4f003f, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_protram_r)));
2301 m_irq4_disabled = 1; // // doesn't like this irq??
2302 }
2303
init_pstar()2304 void pgm_arm_type1_state::init_pstar()
2305 {
2306 pgm_basic_init();
2307 pgm_pstar_decrypt(machine());
2308 arm7_type1_latch_init();
2309
2310 m_pstar_e7_value = 0;
2311 m_pstar_b1_value = 0;
2312 m_pstar_ce_value = 0;
2313 m_extra_ram[0] = 0;
2314 m_extra_ram[1] = 0;
2315 m_extra_ram[2] = 0;
2316 memset(m_slots, 0, 16 * sizeof(u32));
2317
2318 arm_sim_handler = &pgm_arm_type1_state::command_handler_pstars;
2319 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x500000, 0x500005, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_r)), write16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_w)));
2320 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0000, 0x4f003f, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::pstars_arm7_type1_sim_protram_r)));
2321
2322 save_item(NAME(m_pstar_e7_value));
2323 save_item(NAME(m_pstar_b1_value));
2324 save_item(NAME(m_pstar_ce_value));
2325 save_item(NAME(m_extra_ram));
2326 }
2327
init_kov()2328 void pgm_arm_type1_state::init_kov()
2329 {
2330 pgm_basic_init();
2331 pgm_kov_decrypt(machine());
2332 arm7_type1_latch_init();
2333 m_curslots = 0;
2334 m_kov_c0_value = 0;
2335 m_kov_cb_value = 0;
2336 m_kov_fe_value = 0;
2337 arm_sim_handler = &pgm_arm_type1_state::command_handler_kov;
2338 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x500000, 0x500005, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_r)), write16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_w)));
2339 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0000, 0x4f003f, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_protram_r)));
2340 }
2341
init_kovboot()2342 void pgm_arm_type1_state::init_kovboot()
2343 {
2344 pgm_basic_init();
2345 // pgm_kov_decrypt(machine());
2346 arm7_type1_latch_init();
2347 m_curslots = 0;
2348 m_kov_c0_value = 0;
2349 m_kov_cb_value = 0;
2350 m_kov_fe_value = 0;
2351 arm_sim_handler = &pgm_arm_type1_state::command_handler_kov;
2352 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x500000, 0x500005, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_r)), write16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_w)));
2353 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0000, 0x4f003f, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_protram_r)));
2354
2355 }
2356
init_oldsplus()2357 void pgm_arm_type1_state::init_oldsplus()
2358 {
2359 pgm_basic_init();
2360 pgm_oldsplus_decrypt(machine());
2361 arm7_type1_latch_init();
2362 memset(m_extra_ram, 0, 0x100 * sizeof(u16));
2363 memset(m_slots, 0, 0x100 * sizeof(u32));
2364 arm_sim_handler = &pgm_arm_type1_state::command_handler_oldsplus;
2365 m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x500000, 0x500005, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_r)), write16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_w)));
2366 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0000, 0x4f003f, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_protram_r)));
2367 save_item(NAME(m_extra_ram));
2368 }
2369
2370 INPUT_PORTS_START( photoy2k )
2371 PORT_INCLUDE ( pgm )
2372
2373 PORT_START("RegionHack") /* Region - supplied by protection device */
2374 PORT_CONFNAME( 0x00ff, 0x00ff, DEF_STR( Region ) )
2375 PORT_CONFSETTING( 0x0000, DEF_STR( Taiwan ) )
2376 PORT_CONFSETTING( 0x0001, DEF_STR( China ) )
2377 PORT_CONFSETTING( 0x0002, "Japan (Alta license)" )
2378 PORT_CONFSETTING( 0x0003, DEF_STR( World ) )
2379 PORT_CONFSETTING( 0x0004, DEF_STR( Korea ) )
2380 PORT_CONFSETTING( 0x0005, DEF_STR( Hong_Kong ) )
2381 PORT_CONFSETTING( 0x00ff, "Untouched" ) // don't hack the region
2382 INPUT_PORTS_END
2383
2384 INPUT_PORTS_START( photoy2kj )
2385 PORT_INCLUDE ( pgm )
2386
2387 PORT_START("RegionHack") /* Region - supplied by protection device */
2388 PORT_CONFNAME( 0x00ff, 0x0002, DEF_STR( Region ) )
2389 PORT_CONFSETTING( 0x0000, DEF_STR( Taiwan ) )
2390 PORT_CONFSETTING( 0x0001, DEF_STR( China ) )
2391 PORT_CONFSETTING( 0x0002, "Japan (Alta license)" )
2392 PORT_CONFSETTING( 0x0003, DEF_STR( World ) )
2393 PORT_CONFSETTING( 0x0004, DEF_STR( Korea ) )
2394 PORT_CONFSETTING( 0x0005, DEF_STR( Hong_Kong ) )
2395 PORT_CONFSETTING( 0x00ff, "Untouched" ) // don't hack the region
2396 INPUT_PORTS_END
2397
2398 INPUT_PORTS_START( kovsh )
2399 PORT_INCLUDE ( pgm )
2400
2401 PORT_START("RegionHack") /* Region - supplied by protection device */
2402 PORT_CONFNAME( 0x00ff, 0x00ff, DEF_STR( Region ) )
2403 PORT_CONFSETTING( 0x0000, DEF_STR( China ) )
2404 PORT_CONFSETTING( 0x0001, DEF_STR( Taiwan ) )
2405 PORT_CONFSETTING( 0x0002, "Japan (Alta license)" )
2406 PORT_CONFSETTING( 0x0003, DEF_STR( Korea ) )
2407 PORT_CONFSETTING( 0x0004, DEF_STR( Hong_Kong ) )
2408 PORT_CONFSETTING( 0x0005, DEF_STR( World ) )
2409 PORT_CONFSETTING( 0x00ff, "Untouched" ) // don't hack the region
2410 INPUT_PORTS_END
2411
2412
2413
2414 INPUT_PORTS_START( sango )
2415 PORT_INCLUDE ( pgm )
2416
2417 PORT_MODIFY("Region") /* Region - supplied by protection device */
2418 PORT_CONFNAME( 0x000f, 0x0005, DEF_STR( Region ) )
2419 PORT_CONFSETTING( 0x0000, DEF_STR( China ) )
2420 PORT_CONFSETTING( 0x0001, DEF_STR( Taiwan ) )
2421 PORT_CONFSETTING( 0x0002, "Japan (Alta license)" )
2422 PORT_CONFSETTING( 0x0003, DEF_STR( Korea ) )
2423 PORT_CONFSETTING( 0x0004, DEF_STR( Hong_Kong ) )
2424 PORT_CONFSETTING( 0x0005, DEF_STR( World ) )
2425 INPUT_PORTS_END
2426
2427 INPUT_PORTS_START( sango_ch )
2428 PORT_INCLUDE ( pgm )
2429
2430 PORT_MODIFY("Region") /* Region - supplied by protection device */
2431 PORT_CONFNAME( 0x000f, 0x0000, DEF_STR( Region ) )
2432 PORT_CONFSETTING( 0x0000, DEF_STR( China ) )
2433 PORT_CONFSETTING( 0x0001, DEF_STR( Taiwan ) )
2434 PORT_CONFSETTING( 0x0002, "Japan (Alta license)" )
2435 PORT_CONFSETTING( 0x0003, DEF_STR( Korea ) )
2436 PORT_CONFSETTING( 0x0004, DEF_STR( Hong_Kong ) )
2437 PORT_CONFSETTING( 0x0005, DEF_STR( World ) )
2438 INPUT_PORTS_END
2439
2440
2441 INPUT_PORTS_START( oldsplus )
2442 PORT_INCLUDE ( pgm )
2443
2444 PORT_MODIFY("Region") /* Region - supplied by protection device */
2445 PORT_CONFNAME( 0x000f, 0x0001, DEF_STR( Region ) )
2446 PORT_CONFSETTING( 0x0001, DEF_STR( China ) )
2447 PORT_CONFSETTING( 0x0002, DEF_STR( Japan ) )
2448 PORT_CONFSETTING( 0x0003, DEF_STR( Korea ) )
2449 PORT_CONFSETTING( 0x0004, DEF_STR( Hong_Kong ) )
2450 PORT_CONFSETTING( 0x0005, DEF_STR( World ) )
2451 PORT_CONFSETTING( 0x0006, DEF_STR( Taiwan ) )
2452 INPUT_PORTS_END
2453
2454 INPUT_PORTS_START( pstar )
2455 PORT_INCLUDE ( pgm )
2456
2457 PORT_MODIFY("Region") /* Region - supplied by protection device */
2458 PORT_CONFNAME( 0x000f, 0x0005, DEF_STR( Region ) )
2459 PORT_CONFSETTING( 0x0000, DEF_STR( China ) )
2460 PORT_CONFSETTING( 0x0001, DEF_STR( Taiwan ) )
2461 PORT_CONFSETTING( 0x0002, "Japan (Alta license)" )
2462 PORT_CONFSETTING( 0x0003, DEF_STR( Korea ) )
2463 PORT_CONFSETTING( 0x0004, DEF_STR( Hong_Kong ) )
2464 PORT_CONFSETTING( 0x0005, DEF_STR( World ) )
2465 INPUT_PORTS_END
2466
2467 INPUT_PORTS_START( py2k2 )
2468 PORT_INCLUDE ( pgm )
2469
2470 PORT_MODIFY("Region") /* Region - supplied by protection device */
2471 PORT_CONFNAME( 0x000f, 0x0003, DEF_STR( Region ) )
2472 PORT_CONFSETTING( 0x0000, DEF_STR( Taiwan ) )
2473 PORT_CONFSETTING( 0x0001, DEF_STR( China ) )
2474 PORT_CONFSETTING( 0x0002, "Japan (Alta license)" )
2475 PORT_CONFSETTING( 0x0003, DEF_STR( World ) )
2476 PORT_CONFSETTING( 0x0004, DEF_STR( Korea ) )
2477 PORT_CONFSETTING( 0x0005, DEF_STR( Hong_Kong ) )
2478 PORT_CONFSETTING( 0x0006, "Singapore, Malaysia" )
2479 INPUT_PORTS_END
2480
2481 INPUT_PORTS_START( pgm3in1 )
2482 PORT_INCLUDE ( pgm )
2483
2484 PORT_MODIFY("Region") /* Region - supplied by protection device */
2485 PORT_CONFNAME( 0x000f, 0x0003, DEF_STR( Region ) )
2486 PORT_CONFSETTING( 0x0000, DEF_STR( China ) )
2487 PORT_CONFSETTING( 0x0001, DEF_STR( Taiwan ) )
2488 PORT_CONFSETTING( 0x0002, DEF_STR( Hong_Kong ) )
2489 PORT_CONFSETTING( 0x0003, DEF_STR( World ) )
2490 INPUT_PORTS_END
2491
2492
2493 INPUT_PORTS_START( puzzli2 )
2494 PORT_INCLUDE ( pgm )
2495
2496 PORT_MODIFY("Region") /* Region - supplied by protection device */
2497 PORT_CONFNAME( 0x000f, 0x0005, DEF_STR( Region ) )
2498 PORT_CONFSETTING( 0x0000, DEF_STR( Taiwan ) )
2499 PORT_CONFSETTING( 0x0001, DEF_STR( China ) )
2500 PORT_CONFSETTING( 0x0002, "Japan (Alta license)" )
2501 PORT_CONFSETTING( 0x0003, DEF_STR( Korea ) )
2502 PORT_CONFSETTING( 0x0004, DEF_STR( Hong_Kong ) )
2503 PORT_CONFSETTING( 0x0005, DEF_STR( World ) )
2504 INPUT_PORTS_END
2505
2506
2507 // CAVE PCB has some input differs; no 3P/4P inputs
2508 INPUT_PORTS_START( espgal )
2509 PORT_INCLUDE ( pgm )
2510
2511 PORT_MODIFY("P3P4")
2512 PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) // unused
2513
2514 PORT_MODIFY("Service")
2515 PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("Test")
2516 PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Service")
2517 PORT_BIT( 0x0ccc, IP_ACTIVE_LOW, IPT_UNKNOWN ) // unused
2518
2519 PORT_MODIFY("DSW")
2520 PORT_SERVICE_DIPLOC( 0x0001, IP_ACTIVE_LOW, "SW1:1" )
2521 PORT_DIPUNKNOWN_DIPLOC( 0x0002, IP_ACTIVE_LOW, "SW1:2" )
2522 PORT_DIPUNKNOWN_DIPLOC( 0x0004, IP_ACTIVE_LOW, "SW1:3" )
2523 PORT_DIPUNKNOWN_DIPLOC( 0x0008, IP_ACTIVE_LOW, "SW1:4" )
2524 PORT_DIPUNKNOWN_DIPLOC( 0x0010, IP_ACTIVE_LOW, "SW1:5" )
2525 PORT_DIPUNKNOWN_DIPLOC( 0x0020, IP_ACTIVE_LOW, "SW1:6" )
2526 PORT_DIPUNKNOWN_DIPLOC( 0x0040, IP_ACTIVE_LOW, "SW1:7" )
2527 PORT_DIPUNKNOWN_DIPLOC( 0x0080, IP_ACTIVE_LOW, "SW1:8" )
2528 INPUT_PORTS_END
2529
2530
2531 INPUT_PORTS_START( ddp3 ) // No button 4
2532 PORT_INCLUDE ( espgal )
2533
2534 PORT_MODIFY("Service")
2535 PORT_BIT( 0x0300, IP_ACTIVE_LOW, IPT_UNKNOWN ) // unused
2536 INPUT_PORTS_END
2537