280
280
#include "wecleman.lh"
281
281
#include "includes/wecleman.h"
283
/* Variables only used here: */
284
static UINT16 *blitter_regs;
285
static int multiply_reg[2];
286
static UINT16 *wecleman_protection_ram;
287
static int spr_color_offs;
289
/* Variables that video has acces to: */
290
int wecleman_selected_ip, wecleman_irqctrl;
292
284
/***************************************************************************
296
288
static READ16_HANDLER( wecleman_protection_r )
290
wecleman_state *state = space->machine().driver_data<wecleman_state>();
298
291
int blend, data0, data1, r0, g0, b0, r1, g1, b1;
300
data0 = wecleman_protection_ram[0];
301
blend = wecleman_protection_ram[2];
302
data1 = wecleman_protection_ram[1];
293
data0 = state->m_protection_ram[0];
294
blend = state->m_protection_ram[2];
295
data1 = state->m_protection_ram[1];
305
298
// a precalculated table will take an astronomical 4096^2(colors) x 1024(steps) x 2(word) bytes
351
343
static WRITE16_HANDLER( irqctrl_w )
345
wecleman_state *state = space->machine().driver_data<wecleman_state>();
353
346
if (ACCESSING_BITS_0_7)
355
// logerror("CPU #0 - PC = %06X - $140005 <- %02X (old value: %02X)\n",cpu_get_pc(space->cpu), data&0xFF, old_data&0xFF);
348
// logerror("CPU #0 - PC = %06X - $140005 <- %02X (old value: %02X)\n",cpu_get_pc(&space->device()), data&0xFF, old_data&0xFF);
357
350
// Bit 0 : SUBINT
358
if ( (wecleman_irqctrl & 1) && (!(data & 1)) ) // 1->0 transition
359
cputag_set_input_line(space->machine, "sub", 4, HOLD_LINE);
351
if ( (state->m_irqctrl & 1) && (!(data & 1)) ) // 1->0 transition
352
cputag_set_input_line(space->machine(), "sub", 4, HOLD_LINE);
361
354
// Bit 1 : NSUBRST
363
cputag_set_input_line(space->machine, "sub", INPUT_LINE_RESET, CLEAR_LINE);
356
cputag_set_input_line(space->machine(), "sub", INPUT_LINE_RESET, CLEAR_LINE);
365
cputag_set_input_line(space->machine, "sub", INPUT_LINE_RESET, ASSERT_LINE);
358
cputag_set_input_line(space->machine(), "sub", INPUT_LINE_RESET, ASSERT_LINE);
367
360
// Bit 2 : SOUND-ON
368
361
// Bit 3 : SOUNDRST
369
362
// Bit 4 : SCR-HCNT
370
363
// Bit 5 : SCR-VCNT
371
364
// Bit 6 : TV-KILL
372
wecleman_irqctrl = data; // latch the value
365
state->m_irqctrl = data; // latch the value
387
380
static WRITE16_HANDLER( selected_ip_w )
389
if (ACCESSING_BITS_0_7) wecleman_selected_ip = data & 0xff; // latch the value
382
wecleman_state *state = space->machine().driver_data<wecleman_state>();
383
if (ACCESSING_BITS_0_7) state->m_selected_ip = data & 0xff; // latch the value
392
386
/* $140021.b - Return the previously selected input port's value */
393
387
static READ16_HANDLER( selected_ip_r )
395
switch ( (wecleman_selected_ip >> 5) & 3 )
389
wecleman_state *state = space->machine().driver_data<wecleman_state>();
390
switch ( (state->m_selected_ip >> 5) & 3 )
396
391
{ // From WEC Le Mans Schems:
397
case 0: return input_port_read(space->machine, "ACCEL"); // Accel - Schems: Accelevr
392
case 0: return input_port_read(space->machine(), "ACCEL"); // Accel - Schems: Accelevr
398
393
case 1: return ~0; // ????? - Schems: Not Used
399
case 2: return input_port_read(space->machine, "STEER"); // Wheel - Schems: Handlevr
394
case 2: return input_port_read(space->machine(), "STEER"); // Wheel - Schems: Handlevr
400
395
case 3: return ~0; // Table - Schems: Turnvr
402
397
default: return ~0;
440
435
static WRITE16_HANDLER( blitter_w )
442
COMBINE_DATA(&blitter_regs[offset]);
437
wecleman_state *state = space->machine().driver_data<wecleman_state>();
438
COMBINE_DATA(&state->m_blitter_regs[offset]);
444
440
/* do a blit if $80010.b has been written */
445
441
if ( (offset == 0x10/2) && (ACCESSING_BITS_8_15) )
447
443
/* 80000.b = ?? usually 0 - other values: 02 ; 00 - ? logic function ? */
448
444
/* 80001.b = ?? usually 0 - other values: 3f ; 01 - ? height ? */
449
int minterm = ( blitter_regs[0x0/2] & 0xFF00 ) >> 8;
450
int list_len = ( blitter_regs[0x0/2] & 0x00FF ) >> 0;
445
int minterm = ( state->m_blitter_regs[0x0/2] & 0xFF00 ) >> 8;
446
int list_len = ( state->m_blitter_regs[0x0/2] & 0x00FF ) >> 0;
452
448
/* 80002.w = ?? always 0 - ? increment per horizontal line ? */
453
449
/* no proof at all, it's always 0 */
454
//int srcdisp = blitter_regs[0x2/2] & 0xFF00;
455
//int destdisp = blitter_regs[0x2/2] & 0x00FF;
450
//int srcdisp = state->m_blitter_regs[0x2/2] & 0xFF00;
451
//int destdisp = state->m_blitter_regs[0x2/2] & 0x00FF;
457
453
/* 80004.l = source data address */
458
int src = ( blitter_regs[0x4/2] << 16 ) + blitter_regs[0x6/2];
454
int src = ( state->m_blitter_regs[0x4/2] << 16 ) + state->m_blitter_regs[0x6/2];
460
456
/* 80008.l = list of blits address */
461
int list = ( blitter_regs[0x8/2] << 16 ) + blitter_regs[0xA/2];
457
int list = ( state->m_blitter_regs[0x8/2] << 16 ) + state->m_blitter_regs[0xA/2];
463
459
/* 8000C.l = destination address */
464
int dest = ( blitter_regs[0xC/2] << 16 ) + blitter_regs[0xE/2];
460
int dest = ( state->m_blitter_regs[0xC/2] << 16 ) + state->m_blitter_regs[0xE/2];
466
462
/* 80010.b = number of words to move */
467
int size = ( blitter_regs[0x10/2] ) & 0x00FF;
463
int size = ( state->m_blitter_regs[0x10/2] ) & 0x00FF;
469
465
/* Word aligned transfers only ?? */
470
466
src &= (~1); list &= (~1); dest &= (~1);
518
514
static WRITE16_HANDLER( wecleman_soundlatch_w );
520
static ADDRESS_MAP_START( wecleman_map, ADDRESS_SPACE_PROGRAM, 16 )
516
static ADDRESS_MAP_START( wecleman_map, AS_PROGRAM, 16 )
521
517
AM_RANGE(0x000000, 0x03ffff) AM_ROM // ROM (03c000-03ffff used as RAM sometimes!)
522
AM_RANGE(0x040494, 0x040495) AM_WRITE(wecleman_videostatus_w) AM_BASE(&wecleman_videostatus) // cloud blending control (HACK)
518
AM_RANGE(0x040494, 0x040495) AM_WRITE(wecleman_videostatus_w) AM_BASE_MEMBER(wecleman_state, m_videostatus) // cloud blending control (HACK)
523
519
AM_RANGE(0x040000, 0x043fff) AM_RAM // RAM
524
AM_RANGE(0x060000, 0x060005) AM_WRITE(wecleman_protection_w) AM_BASE(&wecleman_protection_ram)
520
AM_RANGE(0x060000, 0x060005) AM_WRITE(wecleman_protection_w) AM_BASE_MEMBER(wecleman_state, m_protection_ram)
525
521
AM_RANGE(0x060006, 0x060007) AM_READ(wecleman_protection_r) // MCU read
526
AM_RANGE(0x080000, 0x080011) AM_RAM_WRITE(blitter_w) AM_BASE(&blitter_regs) // Blitter
527
AM_RANGE(0x100000, 0x103fff) AM_RAM_WRITE(wecleman_pageram_w) AM_BASE(&wecleman_pageram) // Background Layers
528
AM_RANGE(0x108000, 0x108fff) AM_RAM_WRITE(wecleman_txtram_w) AM_BASE(&wecleman_txtram) // Text Layer
522
AM_RANGE(0x080000, 0x080011) AM_RAM_WRITE(blitter_w) AM_BASE_MEMBER(wecleman_state, m_blitter_regs) // Blitter
523
AM_RANGE(0x100000, 0x103fff) AM_RAM_WRITE(wecleman_pageram_w) AM_BASE_MEMBER(wecleman_state, m_pageram) // Background Layers
524
AM_RANGE(0x108000, 0x108fff) AM_RAM_WRITE(wecleman_txtram_w) AM_BASE_MEMBER(wecleman_state, m_txtram) // Text Layer
529
525
AM_RANGE(0x110000, 0x110fff) AM_RAM_WRITE(wecleman_paletteram16_SSSSBBBBGGGGRRRR_word_w) AM_BASE_GENERIC(paletteram)
530
526
AM_RANGE(0x124000, 0x127fff) AM_RAM AM_SHARE("share1") // Shared with main CPU
531
AM_RANGE(0x130000, 0x130fff) AM_RAM AM_BASE_GENERIC(spriteram) // Sprites
527
AM_RANGE(0x130000, 0x130fff) AM_RAM AM_BASE_MEMBER(wecleman_state, m_spriteram) // Sprites
532
528
AM_RANGE(0x140000, 0x140001) AM_WRITE(wecleman_soundlatch_w) // To sound CPU
533
529
AM_RANGE(0x140002, 0x140003) AM_WRITE(selected_ip_w) // Selects accelerator / wheel / ..
534
530
AM_RANGE(0x140004, 0x140005) AM_WRITE(irqctrl_w) // Main CPU controls the other CPUs
550
546
static WRITE16_HANDLER( hotchase_soundlatch_w );
552
static ADDRESS_MAP_START( hotchase_map, ADDRESS_SPACE_PROGRAM, 16 )
548
static ADDRESS_MAP_START( hotchase_map, AS_PROGRAM, 16 )
553
549
AM_RANGE(0x000000, 0x03ffff) AM_ROM
554
550
AM_RANGE(0x040000, 0x063fff) AM_RAM // RAM (weird size!?)
555
AM_RANGE(0x080000, 0x080011) AM_RAM_WRITE(blitter_w) AM_BASE(&blitter_regs) // Blitter
551
AM_RANGE(0x080000, 0x080011) AM_RAM_WRITE(blitter_w) AM_BASE_MEMBER(wecleman_state, m_blitter_regs) // Blitter
556
552
AM_RANGE(0x100000, 0x100fff) AM_DEVREADWRITE8("k051316_1", k051316_r, k051316_w, 0x00ff) // Background
557
553
AM_RANGE(0x101000, 0x10101f) AM_DEVWRITE8("k051316_1", k051316_ctrl_w, 0x00ff) // Background Ctrl
558
554
AM_RANGE(0x102000, 0x102fff) AM_DEVREADWRITE8("k051316_2", k051316_r, k051316_w, 0x00ff) // Foreground
559
555
AM_RANGE(0x103000, 0x10301f) AM_DEVWRITE8("k051316_2", k051316_ctrl_w, 0x00ff) // Foreground Ctrl
560
556
AM_RANGE(0x110000, 0x111fff) AM_RAM_WRITE(hotchase_paletteram16_SBGRBBBBGGGGRRRR_word_w) AM_BASE_GENERIC(paletteram)
561
557
AM_RANGE(0x120000, 0x123fff) AM_RAM AM_SHARE("share1") // Shared with sub CPU
562
AM_RANGE(0x130000, 0x130fff) AM_RAM AM_BASE_GENERIC(spriteram) // Sprites
558
AM_RANGE(0x130000, 0x130fff) AM_RAM AM_BASE_MEMBER(wecleman_state, m_spriteram) // Sprites
564
560
AM_RANGE(0x140000, 0x140001) AM_WRITE(hotchase_soundlatch_w) // To sound CPU
565
561
AM_RANGE(0x140002, 0x140003) AM_WRITE(selected_ip_w) // Selects accelerator / wheel /
579
575
WEC Le Mans 24 Sub CPU Handlers
580
576
***************************************************************************/
582
static ADDRESS_MAP_START( wecleman_sub_map, ADDRESS_SPACE_PROGRAM, 16 )
578
static ADDRESS_MAP_START( wecleman_sub_map, AS_PROGRAM, 16 )
583
579
AM_RANGE(0x000000, 0x00ffff) AM_ROM // ROM
584
AM_RANGE(0x060000, 0x060fff) AM_RAM AM_BASE(&wecleman_roadram) AM_SIZE(&wecleman_roadram_size) // Road
580
AM_RANGE(0x060000, 0x060fff) AM_RAM AM_BASE_MEMBER(wecleman_state, m_roadram) AM_SIZE_MEMBER(wecleman_state, m_roadram_size) // Road
585
581
AM_RANGE(0x070000, 0x073fff) AM_RAM AM_SHARE("share1") // RAM (Shared with main CPU)
590
586
Hot Chase Sub CPU Handlers
591
587
***************************************************************************/
593
static ADDRESS_MAP_START( hotchase_sub_map, ADDRESS_SPACE_PROGRAM, 16 )
589
static ADDRESS_MAP_START( hotchase_sub_map, AS_PROGRAM, 16 )
594
590
AM_RANGE(0x000000, 0x01ffff) AM_ROM // ROM
595
AM_RANGE(0x020000, 0x020fff) AM_RAM AM_BASE(&wecleman_roadram) AM_SIZE(&wecleman_roadram_size) // Road
591
AM_RANGE(0x020000, 0x020fff) AM_RAM AM_BASE_MEMBER(wecleman_state, m_roadram) AM_SIZE_MEMBER(wecleman_state, m_roadram_size) // Road
596
592
AM_RANGE(0x040000, 0x043fff) AM_RAM AM_SHARE("share1") // Shared with main CPU
597
593
AM_RANGE(0x060000, 0x060fff) AM_RAM // RAM
608
604
if (ACCESSING_BITS_0_7)
610
606
soundlatch_w(space, 0, data & 0xFF);
611
cputag_set_input_line(space->machine, "audiocpu", 0, HOLD_LINE);
607
cputag_set_input_line(space->machine(), "audiocpu", 0, HOLD_LINE);
615
611
/* Protection - an external multiplyer connected to the sound CPU */
616
612
static READ8_HANDLER( multiply_r )
618
return (multiply_reg[0] * multiply_reg[1]) & 0xFF;
614
wecleman_state *state = space->machine().driver_data<wecleman_state>();
615
return (state->m_multiply_reg[0] * state->m_multiply_reg[1]) & 0xFF;
621
618
static WRITE8_HANDLER( multiply_w )
623
multiply_reg[offset] = data;
620
wecleman_state *state = space->machine().driver_data<wecleman_state>();
621
state->m_multiply_reg[offset] = data;
626
624
/* K007232 registers reminder:
644
642
k007232_set_bank(device, 0, ~data&1 ); //* (wecleman062gre)
647
static ADDRESS_MAP_START( wecleman_sound_map, ADDRESS_SPACE_PROGRAM, 8 )
645
static ADDRESS_MAP_START( wecleman_sound_map, AS_PROGRAM, 8 )
648
646
AM_RANGE(0x0000, 0x7fff) AM_ROM
649
647
AM_RANGE(0x8000, 0x83ff) AM_RAM
650
648
AM_RANGE(0x8500, 0x8500) AM_WRITENOP // incresed with speed (global volume)?
737
735
k007232_w(device, offset ^ 1, data);
740
static ADDRESS_MAP_START( hotchase_sound_map, ADDRESS_SPACE_PROGRAM, 8 )
738
static ADDRESS_MAP_START( hotchase_sound_map, AS_PROGRAM, 8 )
741
739
AM_RANGE(0x0000, 0x07ff) AM_RAM
742
740
AM_RANGE(0x1000, 0x100d) AM_DEVREADWRITE("konami1", hotchase_k007232_r, hotchase_k007232_w) // 3 x K007232
743
741
AM_RANGE(0x2000, 0x200d) AM_DEVREADWRITE("konami2", hotchase_k007232_r, hotchase_k007232_w)
1023
1021
static INTERRUPT_GEN( wecleman_interrupt )
1025
1023
if (cpu_getiloops(device) == 0)
1026
cpu_set_input_line(device, 4, HOLD_LINE); /* once */
1024
device_set_input_line(device, 4, HOLD_LINE); /* once */
1028
cpu_set_input_line(device, 5, HOLD_LINE); /* to read input ports */
1026
device_set_input_line(device, 5, HOLD_LINE); /* to read input ports */
1031
1029
static MACHINE_RESET( wecleman )
1033
k007232_set_bank( machine->device("konami"), 0, 1 );
1031
k007232_set_bank( machine.device("konami"), 0, 1 );
1036
static MACHINE_CONFIG_START( wecleman, driver_device )
1034
static MACHINE_CONFIG_START( wecleman, wecleman_state )
1038
1036
/* basic machine hardware */
1039
1037
MCFG_CPU_ADD("maincpu", M68000, 10000000) /* Schems show 10MHz */
1058
1056
MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
1059
1057
MCFG_SCREEN_SIZE(320 +16, 224 +16)
1060
1058
MCFG_SCREEN_VISIBLE_AREA(0 +8, 320-1 +8, 0 +8, 224-1 +8)
1059
MCFG_SCREEN_UPDATE(wecleman)
1062
1061
MCFG_GFXDECODE(wecleman)
1064
1063
MCFG_PALETTE_LENGTH(2048)
1066
1065
MCFG_VIDEO_START(wecleman)
1067
MCFG_VIDEO_UPDATE(wecleman)
1069
1067
/* sound hardware */
1070
1068
MCFG_SPEAKER_STANDARD_MONO("mono")
1129
1127
MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
1130
1128
MCFG_SCREEN_SIZE(320, 224)
1131
1129
MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1)
1130
MCFG_SCREEN_UPDATE(hotchase)
1133
1132
MCFG_GFXDECODE(hotchase)
1134
1133
MCFG_PALETTE_LENGTH(2048*2)
1136
1135
MCFG_VIDEO_START(hotchase)
1137
MCFG_VIDEO_UPDATE(hotchase)
1139
1137
MCFG_K051316_ADD("k051316_1", hotchase_k051316_intf_0)
1140
1138
MCFG_K051316_ADD("k051316_2", hotchase_k051316_intf_1)
1214
static void wecleman_unpack_sprites(running_machine *machine)
1212
static void wecleman_unpack_sprites(running_machine &machine)
1216
1214
const char *region = "gfx1"; // sprites
1218
const UINT32 len = machine->region(region)->bytes();
1219
UINT8 *src = machine->region(region)->base() + len / 2 - 1;
1220
UINT8 *dst = machine->region(region)->base() + len - 1;
1216
const UINT32 len = machine.region(region)->bytes();
1217
UINT8 *src = machine.region(region)->base() + len / 2 - 1;
1218
UINT8 *dst = machine.region(region)->base() + len - 1;
1222
1220
while(dst > src)
1231
static void bitswap(running_machine *machine,UINT8 *src,size_t len,int _14,int _13,int _12,int _11,int _10,int _f,int _e,int _d,int _c,int _b,int _a,int _9,int _8,int _7,int _6,int _5,int _4,int _3,int _2,int _1,int _0)
1229
static void bitswap(running_machine &machine,UINT8 *src,size_t len,int _14,int _13,int _12,int _11,int _10,int _f,int _e,int _d,int _c,int _b,int _a,int _9,int _8,int _7,int _6,int _5,int _4,int _3,int _2,int _1,int _0)
1233
1231
UINT8 *buffer = auto_alloc_array(machine, UINT8, len);
1245
1243
/* Unpack sprites data and do some patching */
1246
1244
static DRIVER_INIT( wecleman )
1246
wecleman_state *state = machine.driver_data<wecleman_state>();
1250
// UINT16 *RAM1 = (UINT16 *) machine->region("maincpu")->base(); /* Main CPU patches */
1249
// UINT16 *RAM1 = (UINT16 *) machine.region("maincpu")->base(); /* Main CPU patches */
1251
1250
// RAM1[0x08c2/2] = 0x601e; // faster self test
1253
1252
/* Decode GFX Roms - Compensate for the address lines scrambling */
1257
1256
I hope you'll appreciate this effort! */
1259
1258
/* let's swap even and odd *pixels* of the sprites */
1260
RAM = machine->region("gfx1")->base();
1261
len = machine->region("gfx1")->bytes();
1259
RAM = machine.region("gfx1")->base();
1260
len = machine.region("gfx1")->bytes();
1262
1261
for (i = 0; i < len; i ++)
1264
1263
/* TODO: could be wrong, colors have to be fixed. */
1267
1266
RAM[i] = BITSWAP8(RAM[i],7,0,1,2,3,4,5,6);
1270
bitswap(machine, machine->region("gfx1")->base(), machine->region("gfx1")->bytes(),
1269
bitswap(machine, machine.region("gfx1")->base(), machine.region("gfx1")->bytes(),
1271
1270
0,1,20,19,18,17,14,9,16,6,4,7,8,15,10,11,13,5,12,3,2);
1273
1272
/* Now we can unpack each nibble of the sprites into a pixel (one byte) */
1274
1273
wecleman_unpack_sprites(machine);
1276
1275
/* Bg & Fg & Txt */
1277
bitswap(machine, machine->region("gfx2")->base(), machine->region("gfx2")->bytes(),
1276
bitswap(machine, machine.region("gfx2")->base(), machine.region("gfx2")->bytes(),
1278
1277
20,19,18,17,16,15,12,7,14,4,2,5,6,13,8,9,11,3,10,1,0);
1281
bitswap(machine, machine->region("gfx3")->base(), machine->region("gfx3")->bytes(),
1280
bitswap(machine, machine.region("gfx3")->base(), machine.region("gfx3")->bytes(),
1282
1281
20,19,18,17,16,15,14,7,12,4,2,5,6,13,8,9,11,3,10,1,0);
1284
spr_color_offs = 0x40;
1283
state->m_spr_color_offs = 0x40;
1338
1337
in a ROM module definition. This routine unpacks each sprite nibble
1339
1338
into a byte, doubling the memory consumption. */
1341
static void hotchase_sprite_decode( running_machine *machine, int num16_banks, int bank_size )
1340
static void hotchase_sprite_decode( running_machine &machine, int num16_banks, int bank_size )
1343
1342
UINT8 *base, *temp;
1346
base = machine->region("gfx1")->base(); // sprites
1345
base = machine.region("gfx1")->base(); // sprites
1347
1346
temp = auto_alloc_array(machine, UINT8, bank_size );
1349
1348
for( i = num16_banks; i >0; i-- ){
1396
1396
/* Decode GFX Roms */
1398
1398
/* Let's swap even and odd bytes of the sprites gfx roms */
1399
RAM = machine->region("gfx1")->base();
1399
RAM = machine.region("gfx1")->base();
1401
1401
/* Now we can unpack each nibble of the sprites into a pixel (one byte) */
1402
1402
hotchase_sprite_decode(machine,3,0x80000*2); // num banks, bank len
1404
1404
/* Let's copy the second half of the fg layer gfx (charset) over the first */
1405
RAM = machine->region("gfx3")->base();
1405
RAM = machine.region("gfx3")->base();
1406
1406
memcpy(&RAM[0], &RAM[0x10000/2], 0x10000/2);
1408
state->m_spr_color_offs = 0;