trunk/src/mame/drivers/speedbal.c
| r31485 | r31486 | |
| 5 | 5 | this was available in a number of cabinet types including 'Super Pin-Ball' |
| 6 | 6 | which mimicked a Pinball table in design, complete with 7-seg scoreboard. |
| 7 | 7 | |
| 8 | | TODO: |
| 9 | | - decrypt Music Ball |
| 10 | | |
| 11 | | |
| 12 | 8 | driver by Joseba Epalza |
| 13 | 9 | |
| 14 | 10 | - 4MHz XTAL, 20MHz XTAL |
| r31485 | r31486 | |
| 314 | 310 | ROM_LOAD( "sb6.bin", 0x08000, 0x08000, CRC(0e2506eb) SHA1(56f779266b977819063c475b84ca246fc6d8d6a7) ) |
| 315 | 311 | ROM_END |
| 316 | 312 | |
| 317 | | //#define USE_DECRYPTION_HELPER |
| 318 | | |
| 319 | 313 | ROM_START( musicbal ) |
| 320 | 314 | ROM_REGION( 0x10000, "maincpu", 0 ) /* 64K for code: main - encrypted */ |
| 321 | 315 | ROM_LOAD( "01.bin", 0x0000, 0x8000, CRC(412298a2) SHA1(3c3247b466880cd78dd7f7f73911f475352c15df) ) |
| r31485 | r31486 | |
| 336 | 330 | ROM_REGION( 0x10000, "sprites", ROMREGION_INVERT ) // still contain Speed Ball logos! |
| 337 | 331 | ROM_LOAD( "07.bin", 0x00000, 0x08000, CRC(310e1e23) SHA1(290f3e1c7b907165fe60a4ebe7a8b04b2451b3b1) ) /* sprites */ |
| 338 | 332 | ROM_LOAD( "06.bin", 0x08000, 0x08000, CRC(2e7772f8) SHA1(caded1a72356501282e627e23718c30cb8f09370) ) |
| 339 | | #ifdef USE_DECRYPTION_HELPER |
| 340 | | /* speed ball code for decryption comparison help */ |
| 341 | | |
| 342 | | ROM_REGION( 0x10000, "helper", 0 ) |
| 343 | | ROM_LOAD( "sb1.bin", 0x0000, 0x8000, CRC(1c242e34) SHA1(8b2e8983e0834c99761ce2b5ea765dba56e77964) ) |
| 344 | | ROM_LOAD( "sb3.bin", 0x8000, 0x8000, CRC(7682326a) SHA1(15a72bf088a9adfaa50c11202b4970e07c309a21) ) |
| 345 | | #endif |
| 346 | | |
| 347 | 333 | ROM_END |
| 348 | 334 | |
| 349 | 335 | |
| 350 | | |
| 351 | | |
| 352 | | |
| 353 | | |
| 354 | | |
| 355 | | #define MUSICBALL_XOR05 { rom[i] = rom[i] ^ 0x05; } |
| 356 | | #define MUSICBALL_XOR84 { rom[i] = rom[i] ^ 0x84; } |
| 357 | | #define MUSICBALL_SWAP1 { rom[i] = BITSWAP8(rom[i],2,6,5,4,3,7,0,1); } |
| 358 | | #define MUSICBALL_SWAP2 { rom[i] = BITSWAP8(rom[i],7,6,5,4,3,0,2,1); } |
| 359 | | // are bits 6,5,4,3 affected, or does this work on only the 4 bits? |
| 360 | | |
| 361 | 336 | DRIVER_INIT_MEMBER(speedbal_state,musicbal) |
| 362 | 337 | { |
| 363 | 338 | UINT8* rom = memregion("maincpu")->base(); |
| 364 | | |
| 365 | | // significant blocks of text etc. should be the same as speedbal |
| 366 | | |
| 339 | |
| 340 | const UINT8 xorTable[8] = {0x05, 0x06, 0x84, 0x84, 0x00, 0x87, 0x84, 0x84}; // XORs affecting bits #0, #1, #2 & #7 |
| 341 | const int swapTable[4][4] = { // 4 possible swaps affecting bits #0, #1, #2 & #7 |
| 342 | {1,0,7,2}, |
| 343 | {2,7,0,1}, |
| 344 | {7,2,1,0}, |
| 345 | {0,2,1,7} |
| 346 | }; |
| 347 | |
| 367 | 348 | for (int i=0;i<0x8000;i++) |
| 368 | 349 | { |
| 369 | | // some bits are ^ 0x05 |
| 370 | | /*if ((i&0x30) == 0x00) |
| 371 | | { |
| 372 | | if ((( i & 0x0f ) > 0x08) && (( i & 0x0f ) < 0x0f)) MUSICBALL_XOR05 |
| 373 | | } |
| 374 | | */ |
| 350 | int addIdx = BIT(i,3)^(BIT(i,5)<<1)^(BIT(i,9)<<2); // 3 bits of address... |
| 351 | int xorMask = xorTable[addIdx]; // ... control the xor... |
| 352 | int bswIdx = xorMask & 3; // ... and the bitswap |
| 375 | 353 | |
| 376 | | if (!(i&0x0800)) |
| 377 | | { |
| 378 | | if (i&0x0020) { MUSICBALL_XOR84 } |
| 379 | | else |
| 380 | | { |
| 381 | | if (i&0x08) { MUSICBALL_XOR84 } |
| 382 | | } |
| 383 | | } |
| 384 | | else |
| 385 | | { |
| 386 | | MUSICBALL_XOR84 |
| 387 | | } |
| 354 | // only bits #0, #1, #2 & #7 are affected |
| 355 | rom[i] = BITSWAP8(rom[i], swapTable[bswIdx][3], 6,5,4,3, swapTable[bswIdx][2], swapTable[bswIdx][1], swapTable[bswIdx][0]) ^ xorTable[addIdx]; |
| 356 | } |
| 388 | 357 | |
| 389 | | /* |
| 390 | | 6608: 00, 00, 00, 00, 00, 00, 00, 00, // wrong |
| 391 | | 6618: 00, 05, 05, 00, 00, 00, 05, 05, |
| 392 | | |
| 393 | | 6648: 00, 05, 05, 05, 05, 05, 05, 00, |
| 394 | | 6658: 05, 05, 00, 05, 00, 00, 00, 00, |
| 395 | | |
| 396 | | 6688: 05, 05, 05, 05, 05, 05, 05, 00, |
| 397 | | 6698: 00, 00, 00, 00, 05, 00, 00, 05, |
| 398 | | |
| 399 | | 66c8: 05, 00, 05, 00, 05, 00, 00, 05, |
| 400 | | 66d8: 05, 05, 05, 05, 00, 05, 05, 05, |
| 401 | | |
| 402 | | 6708: 00, 05, 00, 05, 05, 00, 05, 00, |
| 403 | | 6718: 00, 05, 00, 05, 05, 00, 05, 00, |
| 404 | | |
| 405 | | 6748: 05, 05, 05, 05, 05, 05, 05, 00, |
| 406 | | 6758: 05, 00, 00, 05, 00, 05, 00, 05, |
| 407 | | |
| 408 | | 6788: 05, 00, 00, 05, 05, 00, 05, 00, |
| 409 | | 6798: 05, 00, 05, 00, 05, 05, 05, 05, |
| 410 | | |
| 411 | | 67c8: 00, 00, 05, 00, 05, 05, 05, 05, |
| 412 | | 67d8: 00, 00, 05, 00, 05, 05, 05, 05, |
| 413 | | */ |
| 414 | | |
| 415 | | |
| 416 | | |
| 417 | | |
| 418 | | if (!(i&0x0800)) |
| 419 | | { |
| 420 | | if (i&0x0020) { MUSICBALL_SWAP1 } |
| 421 | | else |
| 422 | | { |
| 423 | | if (i&0x08) { MUSICBALL_SWAP2 } |
| 424 | | else { MUSICBALL_SWAP1 } |
| 425 | | } |
| 426 | | } |
| 427 | | else |
| 428 | | { |
| 429 | | MUSICBALL_SWAP1 |
| 430 | | } |
| 431 | | |
| 432 | | } |
| 433 | | |
| 434 | | #ifdef USE_DECRYPTION_HELPER |
| 435 | | UINT8* helper = memregion("helper")->base(); |
| 436 | | |
| 437 | | int speedball_position = 0x590c; // a block of text that should mostly match here (terminators seem to be changed 1F 60 <-> DD 52 tho) |
| 438 | | int musicball_position = 0x6610; // it's mostly the pattern of where xor 0x05 gets applied we're interested in |
| 439 | | int blocklength = 0x2e0; // there is a clear change in pattern > 6800 |
| 440 | | |
| 441 | | |
| 442 | | if (helper) |
| 443 | | { |
| 444 | | int bytecount = 0; |
| 445 | | |
| 446 | | for (int i=0;i<blocklength;i++) |
| 447 | | { |
| 448 | | UINT8 music = rom[musicball_position+i]; |
| 449 | | UINT8 speed = helper[speedball_position+i]; |
| 450 | | |
| 451 | | if (bytecount==0) printf("%04x: ", musicball_position+i); |
| 452 | | |
| 453 | | UINT8 display = music ^ speed; |
| 454 | | |
| 455 | | // filter out the terminators |
| 456 | | if (display == 0xc2) display = 0x00; |
| 457 | | if (display == 0x32) display = 0x00; |
| 458 | | |
| 459 | | if (display == 0xc7) display = 0x05; |
| 460 | | if (display == 0x37) display = 0x05; |
| 461 | | |
| 462 | | //printf("%02x-%02x, ", music, speed); |
| 463 | | printf("%02x, ", display); |
| 464 | | |
| 465 | | bytecount++; |
| 466 | | if (bytecount==16) { bytecount = 0; printf("\n"); } |
| 467 | | |
| 468 | | } |
| 469 | | |
| 470 | | } |
| 471 | | |
| 472 | | { |
| 473 | | FILE *fp; |
| 474 | | char filename[256]; |
| 475 | | sprintf(filename,"decrypted_%s", machine().system().name); |
| 476 | | fp=fopen(filename, "w+b"); |
| 477 | | if (fp) |
| 478 | | { |
| 479 | | fwrite(rom, 0x8000, 1, fp); |
| 480 | | fclose(fp); |
| 481 | | } |
| 482 | | } |
| 483 | | #endif |
| 484 | | |
| 485 | 358 | DRIVER_INIT_CALL(speedbal); |
| 486 | | |
| 487 | 359 | } |
| 488 | 360 | |
| 489 | 361 | |
| 490 | 362 | |
| 491 | 363 | GAMEL( 1987, speedbal, 0, speedbal, speedbal, speedbal_state, speedbal, ROT270, "Tecfri / Desystem S.A.", "Speed Ball", 0, layout_speedbal ) |
| 492 | | GAMEL( 1988, musicbal, 0, speedbal, speedbal, speedbal_state, musicbal, ROT270, "Tecfri / Desystem S.A.", "Music Ball", GAME_NOT_WORKING, layout_speedbal ) |
| 364 | GAMEL( 1988, musicbal, 0, speedbal, speedbal, speedbal_state, musicbal, ROT270, "Tecfri / Desystem S.A.", "Music Ball", 0, layout_speedbal ) |