1 #include "../vidhrdw/wecleman.c"
2
3 /***************************************************************************
4 WEC Le Mans 24 & Hot Chase
5
6 (C) 1986 & 1988 Konami
7
8 driver by Luca Elia (eliavit@unina.it)
9
10
11 ----------------------------------------------------------------------
12 Hardware Main Sub Sound Sound Chips
13 ----------------------------------------------------------------------
14 [WEC Le Mans 24] 68000 68000 Z-80 YM2151 YM3012 1x007232
15
16 [Hot Chase] 68000 68000 68B09E 3x007232
17
18 [CPU PCB GX763 350861B]
19 007641 007770 3x007232 051550
20
21 [VID PCB GX763 350860A AI AM-1]
22 007634 007635 3x051316 007558 007557
23 ----------------------------------------------------------------------
24
25
26 ----------------------------------------------------------------
27 Main CPU [WEC Le Mans 24] [Hot Chase]
28 ----------------------------------------------------------------
29 ROM R 000000-03ffff <
30 Work RAM RW 040000-043fff 040000-063fff*
31 ? RW 060000-060007 -
32 Blitter W 080000-080011 <
33 Page RAM RW 100000-103fff -
34 Text RAM RW 108000-108fff -
35 Palette RAM RW 110000-110fff 110000-111fff**
36 Shared RAM RW 124000-127fff 120000-123fff
37 Sprites RAM RW 130000-130fff <
38 Input Ports RW 1400xx-1400xx <
39 Background RW - 100000-100fff
40 Background Ctrl W - 101000-10101f
41 Foreground RW - 102000-102fff
42 Foreground Ctrl W - 103000-10301f
43
44 * weird ** only half used
45
46 ----------------------------------------------------------------
47 Sub CPU [WEC Le Mans 24] [Hot Chase]
48 ----------------------------------------------------------------
49
50 ROM R 000000-00ffff 000000-01ffff
51 Work RAM RW - 060000-060fff
52 Road RAM RW 060000-060fff 020000-020fff
53 Shared RAM RW 070000-073fff 040000-043fff
54
55
56 ---------------------------------------------------------------------------
57 Game code
58 [WEC Le Mans 24]
59 ---------------------------------------------------------------------------
60
61 Interesting locations (main cpu)
62 --------------------------------
63
64 There's some 68000 assembly code in ASCII around d88 :-)
65
66 040000+
67 7-9 *** hi score/10 (BCD 3 bytes) ***
68 b-d *** score/10 (BCD 3 bytes) ***
69 1a,127806 <- 140011.b
70 1b,127807 <- 140013.b
71 1c,127808 <- 140013.b
72 1d,127809 <- 140015.b
73 1e,12780a <- 140017.b
74 1f <- 140013.b
75 30 *** credits ***
76 3a,3b,3c,3d <-140021.b
77 3a = accelerator 3b = ?? 3c = steering 3d = table
78
79 d2.w -> 108f24 fg y scroll
80 112.w -> 108f26 bg y scroll
81
82 16c influences 140031.b
83 174 screen address
84 180 input port selection (->140003.b ->140021.b)
85 181 ->140005.b
86 185 bit 7 high -> must copy sprite data to 130000
87 1dc+(1da).w ->140001.b
88
89 40a.w,c.w *** time (BCD) ***
90 411 EF if brake, 0 otherwise
91 416 ?
92 419 gear: 0=lo,1=hi
93 41e.w speed related ->127880
94 424.w speed BCD
95 43c.w accel?
96 440.w level?
97
98 806.w scrollx related
99 80e.w scrolly related
100
101 c08.b routine select: 1>1e1a4 2>1e1ec 3>1e19e other>1e288 (map screen)
102
103 117a.b selected letter when entering name in hi-scores
104 117e.w cycling color in hi-scores
105
106 12c0.w ?time,pos,len related?
107 12c2.w
108 12c4.w
109 12c6.w
110
111 1400-1bff color data (0000-1023 chars)
112 1c00-23ff color data (1024-2047 sprites?)
113
114 2400 Sprite data: 40 entries x 4 bytes = 100
115 2800 Sprite data: 40 entries x 40 bytes = 1000
116 3800 Sprite data: 40 entries x 10 bytes = 400
117
118 Interesting routines (main cpu)
119 -------------------------------
120
121 804 mem test
122 818 end mem test (cksums at 100, addresses at A90)
123 82c other cpu test
124 a0c rom test
125 c1a prints string (a1)
126 1028 end test
127 204c print 4*3 box of chars to a1, made up from 2 2*6 (a0)=0xLR (Left,Righ index)
128 4e62 raws in the fourth page of chars
129 6020 test screen (print)
130 60d6 test screen
131 62c4 motor test?
132 6640 print input port values ( 6698 = scr_disp.w,ip.b,bit.b[+/-] )
133
134 819c prepares sprite data
135 8526 blitter: 42400->130000
136 800c 8580 sprites setup on map screen
137
138 1833a cycle cols on hi-scores
139 18514 hiscores: main loop
140 185e8 hiscores: wheel selects letter
141
142 TRAP#0 prints string: A0-> addr.l, attr.w, (char.b)*, 0
143
144 IRQs 1,3,6] 602
145 2,7] 1008->12dc ORI.W #$2700,(A7) RTE
146 4] 1004->124c
147 5] 106c->1222 calls sequence: $3d24 $1984 $28ca $36d2 $3e78
148
149
150
151
152 Interesting locations (sub cpu)
153 -------------------------------
154
155 Interesting routines (sub cpu)
156 ------------------------------
157
158 1028 'wait for command' loop.
159 1138 lev4 irq
160 1192 copies E0*4 bytes: (a1)+ -> (a0)+
161
162
163
164
165
166 ---------------------------------------------------------------------------
167 Game code
168 [Hot Chase]
169 ---------------------------------------------------------------------------
170
171 This game has been probably coded by the same programmers of WEC Le Mans 24
172 It shares some routines and there is the (hidden?) string "WEC 2" somewhere
173
174 Main CPU Sub CPU
175
176 Interrupts: 1, 7] FFFFFFFF FFFFFFFF
177 2,3,4,5,6] 221c 1288
178
179 Self Test:
180 0] pause,120002==55,pause,120002==AA,pause,120002==CC, (on error set bit d7.0)
181 6] 60000-63fff(d7.1),40000-41fff(d7.2)
182 8] 40000/2<-chksum 0-20000(e/o);40004/6<-chksum 20000-2ffff(e/o) (d7.3456)
183 9] chksums from sub cpu: even->40004 odd->(40006) (d7.78)
184 A] 110000-111fff(even)(d7.9),102000-102fff(odd)(d7.a)
185 C] 100000-100fff(odd)(d7.b),pause,pause,pause
186 10] 120004==0(d7.c),120006==0(d7.d),130000-1307ff(first $A of every $10 bytes only)(d7.e),pause
187 14] 102000<-hw screen+(d7==0)? jmp 1934/1000
188 15] 195c start of game
189
190
191 Interesting locations (main cpu)
192 --------------------------------
193
194 60024.b <- !140017.b (DSW 1 - coinage)
195 60025.b <- !140015.b (DSW 2 - options)
196 6102c.w *** time ***
197
198 Interesting routines (main cpu)
199 -------------------------------
200
201 18d2 (d7.d6)?print BAD/OK to (a5)+, jmp(D0)
202 1d58 print d2.w to (a4)+, jmp(a6)
203 580c writes at 60000
204 61fc print test strings
205 18cbe print "game over"
206
207
208
209
210 ---------------------------------------------------------------------------
211 Issues
212 [WEC Le Mans 24]
213 ---------------------------------------------------------------------------
214
215 - Wrong colours (only the text layer is ok at the moment. Note that the top
216 half of colours is written by the blitter, 16 colours a time, the bottom
217 half by the cpu, 8 colours a time)
218 - The parallactic scrolling is sometimes wrong
219
220 ---------------------------------------------------------------------------
221 Issues
222 [Hot Chase]
223 ---------------------------------------------------------------------------
224
225 - Samples pitch is too low
226 - No zoom and rotation of the layers
227
228 ---------------------------------------------------------------------------
229 Common Issues
230 ---------------------------------------------------------------------------
231
232 - One ROM unused (32K in hotchase, 16K in wecleman)
233 - Incomplete DSWs
234 - No shadow sprites
235 - Sprite ram is not cleared by the game and no sprite list end-marker
236 is written. We cope with that with an hack in the Blitter but there
237 must be a register to do the trick
238
239
240 ***************************************************************************/
241
242 #include "driver.h"
243 #include "vidhrdw/generic.h"
244 #include "vidhrdw/konamiic.h"
245 #include "cpu/m6809/m6809.h"
246
247 /* Variables only used here: */
248
249 static unsigned char *sharedram, *blitter_regs;
250 static int multiply_reg[2];
251
252
253
254 /* Variables that vidhrdw has acces to: */
255
256 int wecleman_selected_ip, wecleman_irqctrl;
257
258
259 /* Variables defined in vidhrdw: */
260
261 extern unsigned char *wecleman_pageram, *wecleman_txtram, *wecleman_roadram, *wecleman_unknown;
262 extern size_t wecleman_roadram_size;
263 extern int wecleman_bgpage[4], wecleman_fgpage[4], *wecleman_gfx_bank;
264
265
266 /* Functions defined in vidhrdw: */
267
268 WRITE_HANDLER( paletteram_SBGRBBBBGGGGRRRR_word_w );
269
270 READ_HANDLER( wecleman_pageram_r );
271 WRITE_HANDLER( wecleman_pageram_w );
272 READ_HANDLER( wecleman_txtram_r );
273 WRITE_HANDLER( wecleman_txtram_w );
274 void wecleman_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
275 int wecleman_vh_start(void);
276
277 void hotchase_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
278 int hotchase_vh_start(void);
279 void hotchase_vh_stop(void);
280
281
282
283 /* This macro is used to decipher the gfx ROMs */
284
285 #define BITSWAP(_from,_len,_14,_13,_12,_11,_10,_f,_e,_d,_c,_b,_a,_9,_8,_7,_6,_5,_4,_3,_2,_1,_0)\
286 { unsigned char *buffer; \
287 unsigned char *src = _from; \
288 if ((buffer = (unsigned char*)malloc(_len))) \
289 { \
290 for (i = 0 ; i <= _len ; i++) \
291 buffer[i] = \
292 src[(((i & (1 << _0))?(1<<0x0):0) + \
293 ((i & (1 << _1))?(1<<0x1):0) + \
294 ((i & (1 << _2))?(1<<0x2):0) + \
295 ((i & (1 << _3))?(1<<0x3):0) + \
296 ((i & (1 << _4))?(1<<0x4):0) + \
297 ((i & (1 << _5))?(1<<0x5):0) + \
298 ((i & (1 << _6))?(1<<0x6):0) + \
299 ((i & (1 << _7))?(1<<0x7):0) + \
300 ((i & (1 << _8))?(1<<0x8):0) + \
301 ((i & (1 << _9))?(1<<0x9):0) + \
302 ((i & (1 << _a))?(1<<0xa):0) + \
303 ((i & (1 << _b))?(1<<0xb):0) + \
304 ((i & (1 << _c))?(1<<0xc):0) + \
305 ((i & (1 << _d))?(1<<0xd):0) + \
306 ((i & (1 << _e))?(1<<0xe):0) + \
307 ((i & (1 << _f))?(1<<0xf):0) + \
308 ((i & (1 << _10))?(1<<0x10):0) + \
309 ((i & (1 << _11))?(1<<0x11):0) + \
310 ((i & (1 << _12))?(1<<0x12):0) + \
311 ((i & (1 << _13))?(1<<0x13):0) + \
312 ((i & (1 << _14))?(1<<0x14):0))]; \
313 memcpy(src, buffer, _len); \
314 free(buffer); \
315 } \
316 }
317
318
319
320 /***************************************************************************
321 Common routines
322 ***************************************************************************/
323
324
325 /* 140005.b (WEC Le Mans 24 Schematics)
326
327 COMMAND
328 ___|____
329 | CK 8|--/ 7
330 | LS273 7| TV-KILL 6
331 | 6| SCR-VCNT 5
332 | 5| SCR-HCNT 4
333 | 5H 4| SOUND-RST 3
334 | 3| SOUND-ON 2
335 | 2| NSUBRST 1
336 | 1| SUBINT 0
337 |__CLR___|
338 |
339 NEXRES
340
341 Schems: SUBRESET does a RST+HALT
342 Sub CPU IRQ 4 generated by SUBINT, no other IRQs
343 */
344
WRITE_HANDLER(irqctrl_w)345 static WRITE_HANDLER( irqctrl_w )
346 {
347
348 // logerror("CPU #0 - PC = %06X - $140005 <- %02X (old value: %02X)\n",cpu_get_pc(), data&0xFF, old_data&0xFF);
349
350 // Bit 0 : SUBINT
351 if ( (wecleman_irqctrl & 1) && (!(data & 1)) ) // 1->0 transition
352 cpu_set_irq_line(1,4,HOLD_LINE);
353
354
355 // Bit 1 : NSUBRST
356 if (data & 2)
357 cpu_set_reset_line(1,CLEAR_LINE);
358 else
359 cpu_set_reset_line(1,ASSERT_LINE);
360
361
362 // Bit 2 : SOUND-ON
363 // Bit 3 : SOUNDRST
364 // Bit 4 : SCR-HCNT
365 // Bit 5 : SCR-VCNT
366 // Bit 6 : TV-KILL
367
368 wecleman_irqctrl = data; // latch the value
369 }
370
371
372
373
374
READ_HANDLER(accelerator_r)375 static READ_HANDLER( accelerator_r )
376 {
377 #define MAX_ACCEL 0x80
378
379 return (readinputport(4) & 1) ? MAX_ACCEL : 0;
380 }
381
382
383 /* This function allows the gear to be handled using two buttons
384 A macro is needed because wecleman sees the high gear when a
385 bit is on, hotchase when a bit is off */
386
387 #define READ_GEAR(_name_,_high_gear_) \
388 READ_HANDLER( _name_ ) \
389 { \
390 static int ret = (_high_gear_ ^ 1) << 5; /* start with low gear */ \
391 switch ( (readinputport(4) >> 2) & 3 ) \
392 { \
393 case 1 : ret = (_high_gear_ ^ 1) << 5; break; /* low gear */ \
394 case 2 : ret = (_high_gear_ ) << 5; break; /* high gear */ \
395 } \
396 return (ret | readinputport(0)); /* previous value */ \
397 }
398
399 READ_GEAR(wecleman_gear_r,1)
400 READ_GEAR(hotchase_gear_r,0)
401
402
403
404 /* 140003.b (usually paired with a write to 140021.b)
405
406 Bit:
407
408 7------- ?
409 -65----- input selection (0-3)
410 ---43--- ?
411 -----2-- start light
412 ------10 ? out 1/2
413
414 */
WRITE_HANDLER(selected_ip_w)415 static WRITE_HANDLER( selected_ip_w )
416 {
417 wecleman_selected_ip = data; // latch the value
418 }
419
420
421 /* $140021.b - Return the previously selected input port's value */
READ_HANDLER(selected_ip_r)422 static READ_HANDLER( selected_ip_r )
423 {
424 switch ( (wecleman_selected_ip >> 5) & 3 )
425 { // From WEC Le Mans Schems:
426 case 0: return accelerator_r(offset); // Accel - Schems: Accelevr
427 case 1: return 0xffff; // ????? - Schems: Not Used
428 case 2: return input_port_5_r(offset); // Wheel - Schems: Handlevr
429 case 3: return 0xffff; // Table - Schems: Turnvr
430
431 default: return 0xffff;
432 }
433 }
434
435
436
437 /* Data is read from and written to *sharedram* */
READ_HANDLER(sharedram_r)438 static READ_HANDLER( sharedram_r ) { return READ_WORD(&sharedram[offset]); }
WRITE_HANDLER(sharedram_w)439 static WRITE_HANDLER( sharedram_w ) { COMBINE_WORD_MEM(&sharedram[offset], data); }
440
441
442 /* Data is read from and written to *spriteram* */
READ_HANDLER(spriteram_word_r)443 static READ_HANDLER( spriteram_word_r ) { return READ_WORD(&spriteram[offset]); }
WRITE_HANDLER(spriteram_word_w)444 static WRITE_HANDLER( spriteram_word_w ) { COMBINE_WORD_MEM(&spriteram[offset], data); }
445
446
447
448
449 /* Word Blitter - Copies data around (Work RAM, Sprite RAM etc.)
450 It's fed with a list of blits to do
451
452 Offset:
453
454 00.b ? Number of words - 1 to add to address per transfer
455 01.b ? logic function / blit mode
456 02.w ? (always 0)
457 04.l Source address (Base address of source data)
458 08.l List of blits address
459 0c.l Destination address
460 01.b ? Number of transfers
461 10.b Triggers the blit
462 11.b Number of words per transfer
463
464 The list contains 4 bytes per blit:
465
466 Offset:
467
468 00.w ?
469 02.w offset from Base address
470
471 */
472
READ_HANDLER(blitter_r)473 static READ_HANDLER( blitter_r )
474 {
475 return READ_WORD(&blitter_regs[offset]);
476 }
477
WRITE_HANDLER(blitter_w)478 static WRITE_HANDLER( blitter_w )
479 {
480 COMBINE_WORD_MEM(&blitter_regs[offset],data);
481
482 /* do a blit if $80010.b has been written */
483 if ((offset == 0x10) && (data&0x00FF0000))
484 {
485 /* 80000.b = ?? usually 0 - other values: 02 ; 00 - ? logic function ? */
486 /* 80001.b = ?? usually 0 - other values: 3f ; 01 - ? height ? */
487 int minterm = (READ_WORD(&blitter_regs[0x0]) & 0xFF00 ) >> 8;
488 int list_len = (READ_WORD(&blitter_regs[0x0]) & 0x00FF ) >> 0;
489
490 /* 80002.w = ?? always 0 - ? increment per horizontal line ? */
491 /* no proof at all, it's always 0 */
492 // int srcdisp = READ_WORD(&blitter_regs[0x2])&0xFF00;
493 // int destdisp = READ_WORD(&blitter_regs[0x2])&0x00FF;
494
495 /* 80004.l = source data address */
496 int src = (READ_WORD(&blitter_regs[0x4])<<16)+
497 READ_WORD(&blitter_regs[0x6]);
498
499 /* 80008.l = list of blits address */
500 int list = (READ_WORD(&blitter_regs[0x8])<<16)+
501 READ_WORD(&blitter_regs[0xA]);
502
503 /* 8000C.l = destination address */
504 int dest = (READ_WORD(&blitter_regs[0xC])<<16)+
505 READ_WORD(&blitter_regs[0xE]);
506
507 /* 80010.b = number of words to move */
508 int size = (READ_WORD(&blitter_regs[0x10]))&0x00FF;
509
510 #if 0
511 {
512 int i;
513 logerror("Blitter (PC = %06X): ",cpu_get_pc());
514 for (i=0;i<0x12;i+=2) logerror("%04X ",READ_WORD(&blitter_regs[i]) );
515 logerror("\n");
516 }
517 #endif
518
519 /* Word aligned transfers only */
520 src &= (~1); list &= (~1); dest &= (~1);
521
522
523 /* Two minterms / blit modes are used */
524 if (minterm != 2)
525 {
526 /* One single blit */
527 for ( ; size > 0 ; size--)
528 {
529 /* maybe slower than a memcpy but safer (and errors are logged) */
530 cpu_writemem24bew_word(dest,cpu_readmem24bew_word(src));
531 src += 2; dest += 2;
532 }
533 // src += srcdisp; dest += destdisp;
534 }
535 else
536 {
537 /* Number of blits in the list */
538 for ( ; list_len > 0 ; list_len-- )
539 {
540 int j;
541
542 /* Read offset of source from the list of blits */
543 int addr = src + cpu_readmem24bew_word( list + 2 );
544
545 for (j = size; j > 0; j--)
546 {
547 cpu_writemem24bew_word(dest,cpu_readmem24bew_word(addr));
548 dest += 2; addr += 2;
549 }
550 dest += 16-size*2; /* hack for the blit to Sprites RAM */
551 list += 4;
552 }
553
554 /* hack for the blit to Sprites RAM - Sprite list end-marker */
555 cpu_writemem24bew_word(dest,0xFFFF);
556 }
557 } /* end blit */
558 }
559
560
561
562 /*
563 **
564 ** Main cpu data
565 **
566 **
567 */
568
569
570
571 /***************************************************************************
572 WEC Le Mans 24
573 ***************************************************************************/
574
575 static WRITE_HANDLER( wecleman_soundlatch_w );
576
577 static struct MemoryReadAddress wecleman_readmem[] =
578 {
579 { 0x000000, 0x03ffff, MRA_ROM }, // ROM
580 { 0x040000, 0x043fff, MRA_BANK1 }, // RAM
581 { 0x060000, 0x060007, MRA_BANK2 }, // Video Registers? (only 60006.w is read)
582 { 0x080000, 0x080011, blitter_r }, // Blitter (reading is for debug)
583 { 0x100000, 0x103fff, wecleman_pageram_r }, // Background Layers
584 { 0x108000, 0x108fff, wecleman_txtram_r }, // Text Layer
585 { 0x110000, 0x110fff, paletteram_word_r }, // Palette
586 { 0x124000, 0x127fff, sharedram_r }, // Shared with sub CPU
587 { 0x130000, 0x130fff, spriteram_word_r }, // Sprites
588 // Input Ports:
589 { 0x140010, 0x140011, wecleman_gear_r }, // Coins + brake + gear
590 { 0x140012, 0x140013, input_port_1_r }, // ??
591 { 0x140014, 0x140015, input_port_2_r }, // DSW
592 { 0x140016, 0x140017, input_port_3_r }, // DSW
593 { 0x140020, 0x140021, selected_ip_r }, // Accelerator or Wheel or ..
594 { -1 }
595 };
596
597 static struct MemoryWriteAddress wecleman_writemem[] =
598 {
599 { 0x000000, 0x03ffff, MWA_ROM }, // ROM (03c000-03ffff used as RAM sometimes!)
600 { 0x040000, 0x043fff, MWA_BANK1 }, // RAM
601 { 0x060000, 0x060007, MWA_BANK2, &wecleman_unknown }, // Video Registers?
602 { 0x080000, 0x080011, blitter_w, &blitter_regs }, // Blitter
603 { 0x100000, 0x103fff, wecleman_pageram_w, &wecleman_pageram }, // Background Layers
604 { 0x108000, 0x108fff, wecleman_txtram_w, &wecleman_txtram }, // Text Layer
605 { 0x110000, 0x110fff, paletteram_SBGRBBBBGGGGRRRR_word_w, &paletteram }, // Palette
606 { 0x124000, 0x127fff, sharedram_w, &sharedram }, // Shared with main CPU
607 { 0x130000, 0x130fff, spriteram_word_w, &spriteram, &spriteram_size }, // Sprites
608 { 0x140000, 0x140001, wecleman_soundlatch_w }, // To sound CPU
609 { 0x140002, 0x140003, selected_ip_w }, // Selects accelerator / wheel / ..
610 { 0x140004, 0x140005, irqctrl_w }, // Main CPU controls the other CPUs
611 { 0x140006, 0x140007, MWA_NOP }, // Watchdog reset
612 { 0x140020, 0x140021, MWA_NOP }, // Paired with writes to $140003
613 { 0x140030, 0x140031, MWA_BANK3 }, // ??
614 { -1 }
615 };
616
617
618
619
620
621
622
623
624
625 /***************************************************************************
626 Hot Chase
627 ***************************************************************************/
628
READ_HANDLER(hotchase_K051316_0_r)629 static READ_HANDLER( hotchase_K051316_0_r )
630 {
631 return K051316_0_r(offset >> 1);
632 }
633
READ_HANDLER(hotchase_K051316_1_r)634 static READ_HANDLER( hotchase_K051316_1_r )
635 {
636 return K051316_1_r(offset >> 1);
637 }
638
WRITE_HANDLER(hotchase_K051316_0_w)639 static WRITE_HANDLER( hotchase_K051316_0_w )
640 {
641 if ((data & 0x00ff0000) == 0)
642 K051316_0_w(offset >> 1, data & 0xff);
643 }
644
WRITE_HANDLER(hotchase_K051316_1_w)645 static WRITE_HANDLER( hotchase_K051316_1_w )
646 {
647 if ((data & 0x00ff0000) == 0)
648 K051316_1_w(offset >> 1, data & 0xff);
649 }
650
WRITE_HANDLER(hotchase_K051316_ctrl_0_w)651 static WRITE_HANDLER( hotchase_K051316_ctrl_0_w )
652 {
653 if ((data & 0x00ff0000) == 0)
654 K051316_ctrl_0_w(offset >> 1, data & 0xff);
655 }
656
WRITE_HANDLER(hotchase_K051316_ctrl_1_w)657 static WRITE_HANDLER( hotchase_K051316_ctrl_1_w )
658 {
659 if ((data & 0x00ff0000) == 0)
660 K051316_ctrl_1_w(offset >> 1, data & 0xff);
661 }
662
663
664 WRITE_HANDLER( hotchase_soundlatch_w );
665
666 static struct MemoryReadAddress hotchase_readmem[] =
667 {
668 { 0x000000, 0x03ffff, MRA_ROM }, // ROM
669 { 0x040000, 0x063fff, MRA_BANK1 }, // RAM (weird size!?)
670 { 0x080000, 0x080011, MRA_BANK2 }, // Blitter
671 { 0x100000, 0x100fff, hotchase_K051316_0_r }, // Background
672 { 0x102000, 0x102fff, hotchase_K051316_1_r }, // Foreground
673 { 0x110000, 0x111fff, paletteram_word_r }, // Palette (only the first 2048 colors used)
674 { 0x120000, 0x123fff, sharedram_r }, // Shared with sub CPU
675 { 0x130000, 0x130fff, spriteram_word_r }, // Sprites
676 // Input Ports:
677 { 0x140006, 0x140007, MRA_NOP }, // Watchdog reset
678 { 0x140010, 0x140011, hotchase_gear_r }, // Coins + brake + gear
679 { 0x140012, 0x140013, input_port_1_r }, // ?? bit 4 from sound cpu
680 { 0x140014, 0x140015, input_port_2_r }, // DSW 2
681 { 0x140016, 0x140017, input_port_3_r }, // DSW 1
682 { 0x140020, 0x140021, selected_ip_r }, // Accelerator or Wheel or ..
683 // { 0x140022, 0x140023, MRA_NOP }, // ??
684 { -1 }
685 };
686
687 static struct MemoryWriteAddress hotchase_writemem[] =
688 {
689 { 0x000000, 0x03ffff, MWA_ROM }, // ROM
690 { 0x040000, 0x063fff, MWA_BANK1 }, // RAM (weird size!?)
691 { 0x080000, 0x080011, blitter_w, &blitter_regs }, // Blitter
692 { 0x100000, 0x100fff, hotchase_K051316_0_w }, // Background
693 { 0x101000, 0x10101f, hotchase_K051316_ctrl_0_w }, // Background Ctrl
694 { 0x102000, 0x102fff, hotchase_K051316_1_w }, // Foreground
695 { 0x103000, 0x10301f, hotchase_K051316_ctrl_1_w }, // Foreground Ctrl
696 { 0x110000, 0x111fff, paletteram_SBGRBBBBGGGGRRRR_word_w, &paletteram }, // Palette
697 { 0x120000, 0x123fff, sharedram_w, &sharedram }, // Shared with sub CPU
698 { 0x130000, 0x130fff, spriteram_word_w, &spriteram, &spriteram_size }, // Sprites
699 // Input Ports:
700 { 0x140000, 0x140001, hotchase_soundlatch_w }, // To sound CPU
701 { 0x140002, 0x140003, selected_ip_w }, // Selects accelerator / wheel / ..
702 { 0x140004, 0x140005, irqctrl_w }, // Main CPU controls the other CPUs
703 { 0x140020, 0x140021, MWA_NOP }, // Paired with writes to $140003
704 // { 0x140030, 0x140031, MWA_NOP }, // ??
705 { -1 }
706 };
707
708
709
710
711
712
713 /*
714 **
715 ** Sub cpu data
716 **
717 **
718 */
719
720 /***************************************************************************
721 WEC Le Mans 24
722 ***************************************************************************/
723
724 static struct MemoryReadAddress wecleman_sub_readmem[] =
725 {
726 { 0x000000, 0x00ffff, MRA_ROM }, // ROM
727 { 0x060000, 0x060fff, MRA_BANK8 }, // Road
728 { 0x070000, 0x073fff, &sharedram_r }, // RAM (Shared with main CPU)
729 { -1 }
730 };
731
732 static struct MemoryWriteAddress wecleman_sub_writemem[] =
733 {
734 { 0x000000, 0x00ffff, MWA_ROM }, // ROM
735 { 0x060000, 0x060fff, MWA_BANK8, &wecleman_roadram, &wecleman_roadram_size }, // Road
736 { 0x070000, 0x073fff, sharedram_w }, // RAM (Shared with main CPU)
737 { -1 }
738 };
739
740
741
742
743
744
745
746
747
748
749
750
751 /***************************************************************************
752 Hot Chase
753 ***************************************************************************/
754
755
756 static struct MemoryReadAddress hotchase_sub_readmem[] =
757 {
758 { 0x000000, 0x01ffff, MRA_ROM }, // ROM
759 { 0x020000, 0x020fff, MRA_BANK7 }, // Road
760 { 0x060000, 0x060fff, MRA_BANK8 }, // RAM
761 { 0x040000, 0x043fff, &sharedram_r }, // Shared with main CPU
762 { -1 }
763 };
764
765 static struct MemoryWriteAddress hotchase_sub_writemem[] =
766 {
767 { 0x000000, 0x01ffff, MWA_ROM }, // ROM
768 { 0x020000, 0x020fff, MWA_BANK7, &wecleman_roadram, &wecleman_roadram_size }, // Road
769 { 0x060000, 0x060fff, MWA_BANK8 }, // RAM
770 { 0x040000, 0x043fff, sharedram_w }, // Shared with main CPU
771 { -1 }
772 };
773
774
775
776
777
778
779
780
781
782
783 /*
784 **
785 ** Sound cpu data
786 **
787 **
788 */
789
790 /***************************************************************************
791 WEC Le Mans 24
792 ***************************************************************************/
793
794 /* 140001.b */
WRITE_HANDLER(wecleman_soundlatch_w)795 WRITE_HANDLER( wecleman_soundlatch_w )
796 {
797 soundlatch_w(0,data & 0xFF);
798 cpu_set_irq_line(2,0, HOLD_LINE);
799 }
800
801
802 /* Protection - an external multiplyer connected to the sound CPU */
READ_HANDLER(multiply_r)803 READ_HANDLER( multiply_r )
804 {
805 return (multiply_reg[0] * multiply_reg[1]) & 0xFF;
806 }
WRITE_HANDLER(multiply_w)807 WRITE_HANDLER( multiply_w )
808 {
809 multiply_reg[offset] = data;
810 }
811
812
813 /* K007232 registers reminder:
814
815 [Ch A] [Ch B] [Meaning]
816 00 06 address step (low byte)
817 01 07 address step (high byte, max 1)
818 02 08 sample address (low byte)
819 03 09 sample address (mid byte)
820 04 0a sample address (high byte, max 1 -> max rom size: $20000)
821 05 0b Reading this byte triggers the sample
822
823 [Ch A & B]
824 0c volume
825 0d play sample once or looped (2 channels -> 2 bits (0&1))
826
827 ** sample playing ends when a byte with bit 7 set is reached **/
828
WRITE_HANDLER(wecleman_K007232_bank_w)829 WRITE_HANDLER( wecleman_K007232_bank_w )
830 {
831 K007232_bankswitch(0, memory_region(REGION_SOUND1),
832 memory_region((data & 1) ? REGION_SOUND1 : REGION_SOUND2) );
833 }
834
835 static struct MemoryReadAddress wecleman_sound_readmem[] =
836 {
837 { 0x0000, 0x7fff, MRA_ROM }, // ROM
838 { 0x8000, 0x83ff, MRA_RAM }, // RAM
839 { 0x9000, 0x9000, multiply_r }, // Protection
840 { 0xa000, 0xa000, soundlatch_r }, // From main CPU
841 { 0xb000, 0xb00d, K007232_read_port_0_r }, // K007232 (Reading offset 5/b triggers the sample)
842 { 0xc001, 0xc001, YM2151_status_port_0_r }, // YM2151
843 { -1 }
844 };
845
846 static struct MemoryWriteAddress wecleman_sound_writemem[] =
847 {
848 { 0x0000, 0x7fff, MWA_ROM }, // ROM
849 { 0x8000, 0x83ff, MWA_RAM }, // RAM
850 // { 0x8500, 0x8500, MWA_NOP }, // incresed with speed (global volume)?
851 { 0x9000, 0x9001, multiply_w }, // Protection
852 // { 0x9006, 0x9006, MWA_NOP }, // ?
853 { 0xb000, 0xb00d, K007232_write_port_0_w }, // K007232
854 { 0xc000, 0xc000, YM2151_register_port_0_w }, // YM2151
855 { 0xc001, 0xc001, YM2151_data_port_0_w },
856 { 0xf000, 0xf000, wecleman_K007232_bank_w }, // Samples banking
857 { -1 }
858 };
859
860
861 /***************************************************************************
862 Hot Chase
863 ***************************************************************************/
864
865 /* 140001.b */
WRITE_HANDLER(hotchase_soundlatch_w)866 WRITE_HANDLER( hotchase_soundlatch_w )
867 {
868 soundlatch_w(0,data & 0xFF);
869 cpu_set_irq_line(2,M6809_IRQ_LINE, HOLD_LINE);
870 }
871
872 static struct K007232_interface hotchase_k007232_interface =
873 {
874 3,
875 { REGION_SOUND1, REGION_SOUND2, REGION_SOUND3 },
876 { K007232_VOL( 33,MIXER_PAN_CENTER, 33,MIXER_PAN_CENTER ),
877 K007232_VOL( 33,MIXER_PAN_LEFT, 33,MIXER_PAN_RIGHT ),
878 K007232_VOL( 33,MIXER_PAN_LEFT, 33,MIXER_PAN_RIGHT ) },
879 { 0,0,0 }
880 };
881
WRITE_HANDLER(hotchase_sound_control_w)882 WRITE_HANDLER( hotchase_sound_control_w )
883 {
884 int reg[8];
885
886 reg[offset] = data;
887
888 switch (offset)
889 {
890 case 0x0: /* Change volume of voice A (l&r speaker at once) */
891 case 0x2: /* for 3 chips.. */
892 case 0x4:
893 // chip, channel (l/r), volA, volB
894 K007232_set_volume( offset / 2, 0, (data >> 4) * 0x11, (reg[offset^1] >> 4) * 0x11);
895 K007232_set_volume( offset / 2, 1, (data & 15) * 0x11, (reg[offset^1] & 15) * 0x11);
896 break;
897
898 case 0x1: /* Change volume of voice B (l&r speaker at once) */
899 case 0x3: /* for 3 chips.. */
900 case 0x5:
901 // chip, channel (l/r), volA, volB
902 K007232_set_volume( offset / 2, 0, (reg[offset^1] >> 4) * 0x11, (data >> 4) * 0x11);
903 K007232_set_volume( offset / 2, 1, (reg[offset^1] & 15) * 0x11, (data & 15) * 0x11);
904 break;
905
906 case 0x06: /* Bankswitch for chips 0 & 1 */
907 {
908 unsigned char *RAM0 = memory_region(hotchase_k007232_interface.bank[0]);
909 unsigned char *RAM1 = memory_region(hotchase_k007232_interface.bank[1]);
910
911 int bank0_a = (data >> 1) & 1;
912 int bank1_a = (data >> 2) & 1;
913 int bank0_b = (data >> 3) & 1;
914 int bank1_b = (data >> 4) & 1;
915 // bit 6: chip 2 - ch0 ?
916 // bit 7: chip 2 - ch1 ?
917
918 K007232_bankswitch(0, &RAM0[bank0_a*0x20000], &RAM0[bank0_b*0x20000]);
919 K007232_bankswitch(1, &RAM1[bank1_a*0x20000], &RAM1[bank1_b*0x20000]);
920 }
921 break;
922
923 case 0x07: /* Bankswitch for chip 2 */
924 {
925 unsigned char *RAM2 = memory_region(hotchase_k007232_interface.bank[2]);
926
927 int bank2_a = (data >> 0) & 7;
928 int bank2_b = (data >> 3) & 7;
929
930 K007232_bankswitch(2, &RAM2[bank2_a*0x20000], &RAM2[bank2_b*0x20000]);
931 }
932 break;
933 }
934 }
935
936
937 /* Read and write handlers for one K007232 chip:
938 even and odd register are mapped swapped */
939
940 #define HOTCHASE_K007232_RW(_chip_) \
941 READ_HANDLER( hotchase_K007232_##_chip_##_r ) \
942 { \
943 return K007232_read_port_##_chip_##_r(offset ^ 1); \
944 } \
945 WRITE_HANDLER( hotchase_K007232_##_chip_##_w ) \
946 { \
947 K007232_write_port_##_chip_##_w(offset ^ 1, data); \
948 } \
949
950 /* 3 x K007232 */
951 HOTCHASE_K007232_RW(0)
952 HOTCHASE_K007232_RW(1)
953 HOTCHASE_K007232_RW(2)
954
955
956
957 static struct MemoryReadAddress hotchase_sound_readmem[] =
958 {
959 { 0x0000, 0x07ff, MRA_RAM }, // RAM
960 { 0x1000, 0x100d, hotchase_K007232_0_r }, // 3 x K007232
961 { 0x2000, 0x200d, hotchase_K007232_1_r },
962 { 0x3000, 0x300d, hotchase_K007232_2_r },
963 { 0x6000, 0x6000, soundlatch_r }, // From main CPU (Read on IRQ)
964 { 0x8000, 0xffff, MRA_ROM }, // ROM
965 { -1 }
966 };
967
968 static struct MemoryWriteAddress hotchase_sound_writemem[] =
969 {
970 { 0x0000, 0x07ff, MWA_RAM }, // RAM
971 { 0x1000, 0x100d, hotchase_K007232_0_w }, // 3 x K007232
972 { 0x2000, 0x200d, hotchase_K007232_1_w },
973 { 0x3000, 0x300d, hotchase_K007232_2_w },
974 { 0x4000, 0x4007, hotchase_sound_control_w }, // Sound volume, banking, etc.
975 { 0x5000, 0x5000, MWA_NOP }, // ? (written with 0 on IRQ, 1 on FIRQ)
976 { 0x7000, 0x7000, MWA_NOP }, // Command acknowledge ?
977 { 0x8000, 0xffff, MWA_ROM }, // ROM
978 { -1 }
979 };
980
981
982
983
984
985 /***************************************************************************
986
987 Input Ports
988
989 ***************************************************************************/
990
991 // Fake input port to read the status of the four buttons
992 // Used to implement both the accelerator and the shift using 2 buttons
993
994 #define BUTTONS_STATUS \
995 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) \
996 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) \
997 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) \
998 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 )
999
1000
1001
1002
1003 #define DRIVING_WHEEL \
1004 PORT_ANALOG( 0xff, 0x80, IPT_AD_STICK_X | IPF_CENTER, 50, 5, 0, 0xff)
1005
1006
1007
1008
1009 #define CONTROLS_AND_COINS(_default_) \
1010 PORT_BIT( 0x01, _default_, IPT_COIN1 ) \
1011 PORT_BIT( 0x02, _default_, IPT_COIN2 ) \
1012 PORT_BITX( 0x04, _default_, IPT_SERVICE, DEF_STR( Service_Mode ), KEYCODE_F2, IP_JOY_NONE ) \
1013 PORT_BIT( 0x08, _default_, IPT_COIN3 ) /* Called "service" */ \
1014 PORT_BIT( 0x10, _default_, IPT_START1 ) /* Start */ \
1015 /* PORT_BIT( 0x20, _default_, IPT_BUTTON3 | IPF_TOGGLE ) */ /* Shift (we handle this with 2 buttons) */ \
1016 PORT_BIT( 0x40, _default_, IPT_BUTTON2 ) /* Brake */ \
1017 PORT_BIT( 0x80, _default_, IPT_UNKNOWN ) /* ? */
1018
1019
1020 /***************************************************************************
1021 WEC Le Mans 24
1022 ***************************************************************************/
1023
1024 INPUT_PORTS_START( wecleman )
1025
1026 PORT_START /* IN0 - Controls and Coins - $140011.b */
1027 CONTROLS_AND_COINS(IP_ACTIVE_HIGH)
1028
1029 PORT_START /* IN1 - Motor? - $140013.b */
1030 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) // ? right sw
1031 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) // ? left sw
1032 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) // ? thermo
1033 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // ? from sound cpu ?
1034 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
1035 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
1036 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
1037 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
1038
1039 PORT_START /* IN2 - DSW A (Coinage) - $140015.b */
1040 PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) )
1041 PORT_DIPSETTING( 0x02, DEF_STR( 4C_1C ) )
1042 PORT_DIPSETTING( 0x05, DEF_STR( 3C_1C ) )
1043 PORT_DIPSETTING( 0x08, DEF_STR( 2C_1C ) )
1044 PORT_DIPSETTING( 0x04, DEF_STR( 3C_2C ) )
1045 PORT_DIPSETTING( 0x01, DEF_STR( 4C_3C ) )
1046 PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) )
1047 PORT_DIPSETTING( 0x03, DEF_STR( 3C_4C ) )
1048 PORT_DIPSETTING( 0x07, DEF_STR( 2C_3C ) )
1049 PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
1050 PORT_DIPSETTING( 0x06, DEF_STR( 2C_5C ) )
1051 PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
1052 PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
1053 PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) )
1054 PORT_DIPSETTING( 0x0a, DEF_STR( 1C_6C ) )
1055 PORT_DIPSETTING( 0x09, DEF_STR( 1C_7C ) )
1056 PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
1057 PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) )
1058 PORT_DIPSETTING( 0x20, DEF_STR( 4C_1C ) )
1059 PORT_DIPSETTING( 0x50, DEF_STR( 3C_1C ) )
1060 PORT_DIPSETTING( 0x80, DEF_STR( 2C_1C ) )
1061 PORT_DIPSETTING( 0x40, DEF_STR( 3C_2C ) )
1062 PORT_DIPSETTING( 0x10, DEF_STR( 4C_3C ) )
1063 PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) )
1064 PORT_DIPSETTING( 0x30, DEF_STR( 3C_4C ) )
1065 PORT_DIPSETTING( 0x70, DEF_STR( 2C_3C ) )
1066 PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
1067 PORT_DIPSETTING( 0x60, DEF_STR( 2C_5C ) )
1068 PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
1069 PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) )
1070 PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
1071 PORT_DIPSETTING( 0xa0, DEF_STR( 1C_6C ) )
1072 PORT_DIPSETTING( 0x90, DEF_STR( 1C_7C ) )
1073 PORT_DIPSETTING( 0x00, DEF_STR( Unknown ) )
1074
1075 PORT_START /* IN3 - DSW B (options) - $140017.b */
1076 PORT_DIPNAME( 0x01, 0x01, "Speed Unit" )
1077 PORT_DIPSETTING( 0x01, "Km/h" )
1078 PORT_DIPSETTING( 0x00, "mph" )
1079 PORT_DIPNAME( 0x02, 0x02, "Unknown B-1" ) // single
1080 PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
1081 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
1082 PORT_DIPNAME( 0x04, 0x04, "Unknown B-2" )
1083 PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
1084 PORT_DIPNAME( 0x18, 0x18, DEF_STR( Difficulty ) )
1085 PORT_DIPSETTING( 0x18, "Easy" ) // 66 seconds at the start
1086 PORT_DIPSETTING( 0x10, "Normal" ) // 64
1087 PORT_DIPSETTING( 0x08, "Hard" ) // 62
1088 PORT_DIPSETTING( 0x00, "Hardest" ) // 60
1089 PORT_DIPNAME( 0x20, 0x00, DEF_STR( Demo_Sounds ) )
1090 PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
1091 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
1092 PORT_DIPNAME( 0x40, 0x40, "Unknown B-6" )
1093 PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
1094 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
1095 PORT_DIPNAME( 0x80, 0x80, "Unknown B-7" )
1096 PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
1097 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
1098
1099 PORT_START /* IN4 - Fake input port - Buttons status */
1100 BUTTONS_STATUS
1101
1102 PORT_START /* IN5 - Driving Wheel - $140021.b (2) */
1103 DRIVING_WHEEL
1104
1105 INPUT_PORTS_END
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119 /***************************************************************************
1120 Hot Chase
1121 ***************************************************************************/
1122
1123 INPUT_PORTS_START( hotchase )
1124
1125 PORT_START /* IN0 - Controls and Coins - $140011.b */
1126 CONTROLS_AND_COINS(IP_ACTIVE_LOW)
1127
1128 PORT_START /* IN1 - Motor? - $140013.b */
1129 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) // ? right sw
1130 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) // ? left sw
1131 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) // ? thermo
1132 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // ? from sound cpu ?
1133 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
1134 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
1135 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
1136 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
1137
1138 PORT_START /* IN2 - DSW 2 (options) - $140015.b */
1139 PORT_DIPNAME( 0x01, 0x01, "Unknown 2-0" ) // single
1140 PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
1141 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
1142 PORT_DIPNAME( 0x02, 0x02, "Unknown 2-1" ) // single (wheel related)
1143 PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
1144 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
1145 PORT_DIPNAME( 0x04, 0x04, "Unknown 2-2" )
1146 PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
1147 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
1148 PORT_DIPNAME( 0x18, 0x18, "Unknown 2-3&4" )
1149 PORT_DIPSETTING( 0x18, "0" )
1150 PORT_DIPSETTING( 0x10, "4" )
1151 PORT_DIPSETTING( 0x08, "8" )
1152 PORT_DIPSETTING( 0x00, "c" )
1153 PORT_DIPNAME( 0x20, 0x20, "Unknown 2-5" ) // single
1154 PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
1155 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
1156 /* wheel <-> brake ; accel -> start */
1157 PORT_DIPNAME( 0x40, 0x40, "Unknown 2-6" ) // single (wheel<->brake)
1158 PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
1159 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
1160 PORT_DIPNAME( 0x80, 0x80, "Unknown 2-7" ) // single
1161 PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
1162 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
1163
1164 PORT_START /* IN3 - DSW 1 (Coinage) - $140017.b */
1165 PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) )
1166 PORT_DIPSETTING( 0x02, DEF_STR( 5C_1C ) )
1167 PORT_DIPSETTING( 0x04, DEF_STR( 4C_1C ) )
1168 PORT_DIPSETTING( 0x07, DEF_STR( 3C_1C ) )
1169 PORT_DIPSETTING( 0x0a, DEF_STR( 2C_1C ) )
1170 PORT_DIPSETTING( 0x01, DEF_STR( 5C_3C ) )
1171 PORT_DIPSETTING( 0x06, DEF_STR( 3C_2C ) )
1172 PORT_DIPSETTING( 0x03, DEF_STR( 4C_3C ) )
1173 PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) )
1174 PORT_DIPSETTING( 0x05, DEF_STR( 3C_4C ) )
1175 PORT_DIPSETTING( 0x09, DEF_STR( 2C_3C ) )
1176 PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
1177 PORT_DIPSETTING( 0x08, DEF_STR( 2C_5C ) )
1178 PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
1179 PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
1180 PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) )
1181 PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
1182 PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) )
1183 PORT_DIPSETTING( 0x20, DEF_STR( 5C_1C ) )
1184 PORT_DIPSETTING( 0x70, DEF_STR( 3C_1C ) )
1185 PORT_DIPSETTING( 0xa0, DEF_STR( 2C_1C ) )
1186 PORT_DIPSETTING( 0x10, DEF_STR( 5C_3C ) )
1187 PORT_DIPSETTING( 0x60, DEF_STR( 3C_2C ) )
1188 PORT_DIPSETTING( 0x30, DEF_STR( 4C_3C ) )
1189 PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) )
1190 PORT_DIPSETTING( 0x50, DEF_STR( 3C_4C ) )
1191 PORT_DIPSETTING( 0x90, DEF_STR( 2C_3C ) )
1192 PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
1193 PORT_DIPSETTING( 0x80, DEF_STR( 2C_5C ) )
1194 PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
1195 PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) )
1196 PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
1197 PORT_DIPSETTING( 0x00, "1 Coin/99 Credits" )
1198 // PORT_DIPSETTING( 0x40, "0C_0C" ) // Coin B insertion freezes the game!
1199
1200 PORT_START /* IN4 - Fake input port - Buttons status */
1201 BUTTONS_STATUS
1202
1203 PORT_START /* IN5 - Driving Wheel - $140021.b (2) */
1204 DRIVING_WHEEL
1205
1206 INPUT_PORTS_END
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216 /***************************************************************************
1217
1218 Graphics Layout
1219
1220 ***************************************************************************/
1221
1222
1223 /***************************************************************************
1224 WEC Le Mans 24
1225 ***************************************************************************/
1226
1227 static struct GfxLayout wecleman_bg_layout =
1228 {
1229 8,8,
1230 8*0x8000*3/(8*8*3),
1231 3,
1232 { 0,0x8000*8,0x8000*8*2 },
1233 {0,7,6,5,4,3,2,1},
1234 {0*8,1*8,2*8,3*8,4*8,5*8,6*8,7*8},
1235 8*8
1236 };
1237
1238 /* We draw the road, made of 512 pixel lines, using 64x1 tiles */
1239 static struct GfxLayout wecleman_road_layout =
1240 {
1241 64,1,
1242 8*0x4000*3/(64*1*3),
1243 3,
1244 { 0x4000*8*2,0x4000*8*1,0x4000*8*0 },
1245 {0,7,6,5,4,3,2,1,
1246 8,15,14,13,12,11,10,9,
1247 16,23,22,21,20,19,18,17,
1248 24,31,30,29,28,27,26,25,
1249
1250 0+32,7+32,6+32,5+32,4+32,3+32,2+32,1+32,
1251 8+32,15+32,14+32,13+32,12+32,11+32,10+32,9+32,
1252 16+32,23+32,22+32,21+32,20+32,19+32,18+32,17+32,
1253 24+32,31+32,30+32,29+32,28+32,27+32,26+32,25+32},
1254 {0},
1255 64*1
1256 };
1257
1258
1259 static struct GfxDecodeInfo wecleman_gfxdecodeinfo[] =
1260 {
1261 // REGION_GFX1 holds sprite, which are not decoded here
1262 { REGION_GFX2, 0, &wecleman_bg_layout, 0, 2048/8 }, // [0] bg + fg + txt
1263 { REGION_GFX3, 0, &wecleman_road_layout, 0, 2048/8 }, // [1] road
1264 { -1 }
1265 };
1266
1267
1268
1269 /***************************************************************************
1270 Hot Chase
1271 ***************************************************************************/
1272
1273
1274 /* We draw the road, made of 512 pixel lines, using 64x1 tiles */
1275 static struct GfxLayout hotchase_road_layout =
1276 {
1277 64,1,
1278 8*0x20000/(64*1*4),
1279 4,
1280 { 0, 1, 2, 3 },
1281 {0*4,1*4,2*4,3*4,4*4,5*4,6*4,7*4,
1282 8*4,9*4,10*4,11*4,12*4,13*4,14*4,15*4,
1283 16*4,17*4,18*4,19*4,20*4,21*4,22*4,23*4,
1284 24*4,25*4,26*4,27*4,28*4,29*4,30*4,31*4,
1285
1286 32*4,33*4,34*4,35*4,36*4,37*4,38*4,39*4,
1287 40*4,41*4,42*4,43*4,44*4,45*4,46*4,47*4,
1288 48*4,49*4,50*4,51*4,52*4,53*4,54*4,55*4,
1289 56*4,57*4,58*4,59*4,60*4,61*4,62*4,63*4},
1290 {0},
1291 64*1*4
1292 };
1293
1294
1295 static struct GfxDecodeInfo hotchase_gfxdecodeinfo[] =
1296 {
1297 // REGION_GFX1 holds sprite, which are not decoded here
1298 // REGION_GFX2 and 3 are for the 051316
1299 { REGION_GFX4, 0, &hotchase_road_layout, 0x70*16, 16 }, // road
1300 { -1 }
1301 };
1302
1303
1304
1305
1306 /***************************************************************************
1307 WEC Le Mans 24
1308 ***************************************************************************/
1309
1310
1311
1312
wecleman_interrupt(void)1313 static int wecleman_interrupt( void )
1314 {
1315 if (cpu_getiloops() == 0) return 4; /* once */
1316 else return 5; /* to read input ports */
1317 }
1318
1319
1320 static struct YM2151interface ym2151_interface =
1321 {
1322 1,
1323 3579545, /* same as sound cpu */
1324 { 80 },
1325 { 0 }
1326 };
1327
1328
1329
1330 static struct K007232_interface wecleman_k007232_interface =
1331 {
1332 1,
1333 { REGION_SOUND1 }, /* but the 2 channels use different ROMs !*/
1334 { K007232_VOL( 20,MIXER_PAN_LEFT, 20,MIXER_PAN_RIGHT ) },
1335 {0}
1336 };
1337
1338
1339
wecleman_init_machine(void)1340 void wecleman_init_machine(void)
1341 {
1342 K007232_bankswitch(0, memory_region(REGION_SOUND1), /* the 2 channels use different ROMs */
1343 memory_region(REGION_SOUND2) );
1344 }
1345
1346
1347 static struct MachineDriver machine_driver_wecleman =
1348 {
1349 {
1350 {
1351 CPU_M68000,
1352 10000000, /* Schems show 10MHz */
1353 wecleman_readmem,wecleman_writemem,0,0,
1354 wecleman_interrupt, 5 + 1, /* in order to read the inputs once per frame */
1355 },
1356 {
1357 CPU_M68000,
1358 10000000, /* Schems show 10MHz */
1359 wecleman_sub_readmem,wecleman_sub_writemem,0,0,
1360 ignore_interrupt,1, /* lev 4 irq generated by main CPU */
1361 },
1362 {
1363 /* Schems: can be reset, no nmi, soundlatch, 3.58MHz */
1364 CPU_Z80 | CPU_AUDIO_CPU,
1365 3579545,
1366 wecleman_sound_readmem,wecleman_sound_writemem,0,0,
1367 ignore_interrupt,1, /* irq caused by main cpu */
1368 },
1369 },
1370 60,DEFAULT_60HZ_VBLANK_DURATION,
1371 1,
1372 wecleman_init_machine,
1373
1374 /* video hardware */
1375 320, 224, { 0, 320-1, 0, 224-1 },
1376
1377 wecleman_gfxdecodeinfo,
1378 2048, 2048,
1379 0,
1380
1381 VIDEO_TYPE_RASTER | VIDEO_MODIFIES_PALETTE,
1382 0,
1383 wecleman_vh_start,
1384 0,
1385 wecleman_vh_screenrefresh,
1386
1387 /* sound hardware */
1388 0,0,0,0,
1389 {
1390 {
1391 SOUND_YM2151,
1392 &ym2151_interface
1393 },
1394 {
1395 SOUND_K007232,
1396 &wecleman_k007232_interface
1397 },
1398 }
1399 };
1400
1401
1402
1403
1404
1405 /***************************************************************************
1406 Hot Chase
1407 ***************************************************************************/
1408
1409
1410
hotchase_init_machine(void)1411 void hotchase_init_machine(void) { }
hotchase_interrupt(void)1412 int hotchase_interrupt( void ) {return 4; }
hotchase_sound_interrupt(void)1413 int hotchase_sound_interrupt(void) {return M6809_INT_FIRQ; }
1414
1415 static struct MachineDriver machine_driver_hotchase =
1416 {
1417 {
1418 {
1419 CPU_M68000,
1420 10000000, /* 10 MHz - PCB is drawn in one set's readme */
1421 hotchase_readmem,hotchase_writemem,0,0,
1422 hotchase_interrupt,1,
1423 },
1424 {
1425 CPU_M68000,
1426 10000000, /* 10 MHz - PCB is drawn in one set's readme */
1427 hotchase_sub_readmem,hotchase_sub_writemem,0,0,
1428 ignore_interrupt,1, /* lev 4 irq generated by main CPU */
1429 },
1430 {
1431 CPU_M6809 | CPU_AUDIO_CPU,
1432 3579545, /* 3.579 MHz - PCB is drawn in one set's readme */
1433 hotchase_sound_readmem,hotchase_sound_writemem,0,0,
1434 hotchase_sound_interrupt,8, /* FIRQ, while IRQ is caused by main cpu */
1435 /* Amuse: every 2 ms */
1436 },
1437 },
1438 60,DEFAULT_60HZ_VBLANK_DURATION,
1439 1,
1440 hotchase_init_machine,
1441
1442 /* video hardware */
1443 320, 224, { 0, 320-1, 0, 224-1 },
1444
1445 hotchase_gfxdecodeinfo,
1446 2048, 2048,
1447 0,
1448
1449 VIDEO_TYPE_RASTER | VIDEO_MODIFIES_PALETTE,
1450 0,
1451 hotchase_vh_start,
1452 hotchase_vh_stop,
1453 hotchase_vh_screenrefresh,
1454
1455 /* sound hardware */
1456 0,0,0,0,
1457 {
1458 {
1459 SOUND_K007232,
1460 &hotchase_k007232_interface
1461 }
1462 }
1463 };
1464
1465
1466
1467 /***************************************************************************
1468
1469 ROMs Loading
1470
1471 ***************************************************************************/
1472
1473
1474
1475 /***************************************************************************
1476 WEC Le Mans 24
1477 ***************************************************************************/
1478
1479 ROM_START( wecleman )
1480
1481 ROM_REGION( 0x40000, REGION_CPU1 ) /* Main CPU Code */
1482 ROM_LOAD_EVEN( "602f08.17h", 0x00000, 0x10000, 0x493b79d3 )
1483 ROM_LOAD_ODD ( "602f11.23h", 0x00000, 0x10000, 0x6bb4f1fa )
1484 ROM_LOAD_EVEN( "602a09.18h", 0x20000, 0x10000, 0x8a9d756f )
1485 ROM_LOAD_ODD ( "602a10.22h", 0x20000, 0x10000, 0x569f5001 )
1486
1487 ROM_REGION( 0x10000, REGION_CPU2 ) /* Sub CPU Code */
1488 ROM_LOAD_EVEN( "602a06.18a", 0x00000, 0x08000, 0xe12c0d11 )
1489 ROM_LOAD_ODD( "602a07.20a", 0x00000, 0x08000, 0x47968e51 )
1490
1491 ROM_REGION( 0x10000, REGION_CPU3 ) /* Sound CPU Code */
1492 ROM_LOAD( "602a01.6d", 0x00000, 0x08000, 0xdeafe5f1 )
1493
1494 ROM_REGION( 0x200000 * 2, REGION_GFX1 ) /* x2, do not dispose */
1495 ROM_LOAD( "602a25.12e", 0x000000, 0x20000, 0x0eacf1f9 ) // zooming sprites
1496 ROM_LOAD( "602a26.14e", 0x020000, 0x20000, 0x2182edaf )
1497 ROM_LOAD( "602a27.15e", 0x040000, 0x20000, 0xb22f08e9 )
1498 ROM_LOAD( "602a28.17e", 0x060000, 0x20000, 0x5f6741fa )
1499 ROM_LOAD( "602a21.6e", 0x080000, 0x20000, 0x8cab34f1 )
1500 ROM_LOAD( "602a22.7e", 0x0a0000, 0x20000, 0xe40303cb )
1501 ROM_LOAD( "602a23.9e", 0x0c0000, 0x20000, 0x75077681 )
1502 ROM_LOAD( "602a24.10e", 0x0e0000, 0x20000, 0x583dadad )
1503 ROM_LOAD( "602a17.12c", 0x100000, 0x20000, 0x31612199 )
1504 ROM_LOAD( "602a18.14c", 0x120000, 0x20000, 0x3f061a67 )
1505 ROM_LOAD( "602a19.15c", 0x140000, 0x20000, 0x5915dbc5 )
1506 ROM_LOAD( "602a20.17c", 0x160000, 0x20000, 0xf87e4ef5 )
1507 ROM_LOAD( "602a13.6c", 0x180000, 0x20000, 0x5d3589b8 )
1508 ROM_LOAD( "602a14.7c", 0x1a0000, 0x20000, 0xe3a75f6c )
1509 ROM_LOAD( "602a15.9c", 0x1c0000, 0x20000, 0x0d493c9f )
1510 ROM_LOAD( "602a16.10c", 0x1e0000, 0x20000, 0xb08770b3 )
1511
1512 ROM_REGION( 0x18000, REGION_GFX2 | REGIONFLAG_DISPOSE )
1513 ROM_LOAD( "602a31.26g", 0x000000, 0x08000, 0x01fa40dd ) // layers
1514 ROM_LOAD( "602a30.24g", 0x008000, 0x08000, 0xbe5c4138 )
1515 ROM_LOAD( "602a29.23g", 0x010000, 0x08000, 0xf1a8d33e )
1516
1517 ROM_REGION( 0x0c000, REGION_GFX3 | REGIONFLAG_DISPOSE )
1518 ROM_LOAD( "602a04.11e", 0x000000, 0x08000, 0xade9f359 ) // road
1519 ROM_LOAD( "602a05.13e", 0x008000, 0x04000, 0xf22b7f2b )
1520
1521 ROM_REGION( 0x20000, REGION_SOUND1 ) /* Samples (Channel A) */
1522 ROM_LOAD( "602a03.10a", 0x00000, 0x20000, 0x31392b01 )
1523
1524 ROM_REGION( 0x20000, REGION_SOUND2 ) /* Samples (Channel B) */
1525 ROM_LOAD( "602a02.8a", 0x00000, 0x20000, 0xe2be10ae )
1526
1527 ROM_REGION( 0x04000, REGION_USER1 )
1528 ROM_LOAD( "602a12.1a", 0x000000, 0x04000, 0x77b9383d ) // ??
1529
1530 ROM_END
1531
1532
1533
wecleman_unpack_sprites(void)1534 void wecleman_unpack_sprites(void)
1535 {
1536 const int region = REGION_GFX1; // sprites
1537
1538 const unsigned int len = memory_region_length(region);
1539 unsigned char *src = memory_region(region) + len / 2 - 1;
1540 unsigned char *dst = memory_region(region) + len - 1;
1541
1542 while(dst > src)
1543 {
1544 unsigned char data = *src--;
1545 if( (data&0xf0) == 0xf0 ) data &= 0x0f;
1546 if( (data&0x0f) == 0x0f ) data &= 0xf0;
1547 *dst-- = data & 0xF; *dst-- = data >> 4;
1548 }
1549 }
1550
1551
1552
1553 /* Unpack sprites data and do some patching */
init_wecleman(void)1554 void init_wecleman(void)
1555 {
1556 unsigned char *RAM;
1557 int i;
1558
1559 /* Optional code patches */
1560
1561 /* Main CPU patches */
1562 RAM = memory_region(REGION_CPU1);
1563 // WRITE_WORD (&RAM[0x08c2],0x601e); // faster self test
1564
1565 /* Sub CPU patches */
1566 RAM = memory_region(REGION_CPU2);
1567
1568 /* Sound CPU patches */
1569 RAM = memory_region(REGION_CPU3);
1570
1571
1572 /* Decode GFX Roms - Compensate for the address lines scrambling */
1573
1574 /* Sprites - decrypting the sprites nearly KILLED ME!
1575 It's been the main cause of the delay of this driver ...
1576 I hope you'll appreciate this effort! */
1577
1578 /* let's swap even and odd *pixels* of the sprites */
1579 RAM = memory_region(REGION_GFX1);
1580 for (i = 0; i < memory_region_length(REGION_GFX1); i ++)
1581 {
1582 int x = RAM[i];
1583 /* TODO: could be wrong, colors have to be fixed. */
1584 /* The only certain thing is that 87 must convert to f0 */
1585 /* otherwise stray lines appear, made of pens 7 & 8 */
1586 x = ((x & 0x07) << 5) | ((x & 0xf8) >> 3);
1587 RAM[i] = x;
1588 }
1589
1590 BITSWAP(memory_region(REGION_GFX1), memory_region_length(REGION_GFX1),
1591 0,1,20,19,18,17,14,9,16,6,4,7,8,15,10,11,13,5,12,3,2)
1592
1593 /* Now we can unpack each nibble of the sprites into a pixel (one byte) */
1594 wecleman_unpack_sprites();
1595
1596
1597
1598 /* Bg & Fg & Txt */
1599 BITSWAP(memory_region(REGION_GFX2), memory_region_length(REGION_GFX2),
1600 20,19,18,17,16,15,12,7,14,4,2,5,6,13,8,9,11,3,10,1,0);
1601
1602
1603
1604 /* Road */
1605 BITSWAP(memory_region(REGION_GFX3), memory_region_length(REGION_GFX3),
1606 20,19,18,17,16,15,14,7,12,4,2,5,6,13,8,9,11,3,10,1,0);
1607 }
1608
1609
1610
1611
1612
1613 /***************************************************************************
1614 Hot Chase
1615 ***************************************************************************/
1616
1617
1618 ROM_START( hotchase )
1619 ROM_REGION( 0x40000, REGION_CPU1 ) /* Main Code */
1620 ROM_LOAD_EVEN( "763k05", 0x000000, 0x010000, 0xf34fef0b )
1621 ROM_LOAD_ODD ( "763k04", 0x000000, 0x010000, 0x60f73178 )
1622 ROM_LOAD_EVEN( "763k03", 0x020000, 0x010000, 0x28e3a444 )
1623 ROM_LOAD_ODD ( "763k02", 0x020000, 0x010000, 0x9510f961 )
1624
1625 ROM_REGION( 0x20000, REGION_CPU2 ) /* Sub Code */
1626 ROM_LOAD_EVEN( "763k07", 0x000000, 0x010000, 0xae12fa90 )
1627 ROM_LOAD_ODD ( "763k06", 0x000000, 0x010000, 0xb77e0c07 )
1628
1629 ROM_REGION( 0x10000, REGION_CPU3 ) /* Sound Code */
1630 ROM_LOAD( "763f01", 0x8000, 0x8000, 0x4fddd061 )
1631
1632 ROM_REGION( 0x300000 * 2, REGION_GFX1 ) /* x2, do not dispose */
1633 ROM_LOAD( "763e17", 0x000000, 0x080000, 0x8db4e0aa ) // zooming sprites
1634 ROM_LOAD( "763e20", 0x080000, 0x080000, 0xa22c6fce )
1635 ROM_LOAD( "763e18", 0x100000, 0x080000, 0x50920d01 )
1636 ROM_LOAD( "763e21", 0x180000, 0x080000, 0x77e0e93e )
1637 ROM_LOAD( "763e19", 0x200000, 0x080000, 0xa2622e56 )
1638 ROM_LOAD( "763e22", 0x280000, 0x080000, 0x967c49d1 )
1639
1640 ROM_REGION( 0x20000, REGION_GFX2 )
1641 ROM_LOAD( "763e14", 0x000000, 0x020000, 0x60392aa1 ) // bg
1642
1643 ROM_REGION( 0x10000, REGION_GFX3 )
1644 ROM_LOAD( "763a13", 0x000000, 0x010000, 0x8bed8e0d ) // fg (patched)
1645
1646 ROM_REGION( 0x20000, REGION_GFX4 | REGIONFLAG_DISPOSE )
1647 ROM_LOAD( "763e15", 0x000000, 0x020000, 0x7110aa43 ) // road
1648
1649 ROM_REGION( 0x40000, REGION_SOUND1 ) /* Samples */
1650 ROM_LOAD( "763e11", 0x000000, 0x040000, 0x9d99a5a7 ) // 2 banks
1651
1652 ROM_REGION( 0x40000, REGION_SOUND2 ) /* Samples */
1653 ROM_LOAD( "763e10", 0x000000, 0x040000, 0xca409210 ) // 2 banks
1654
1655 ROM_REGION( 0x100000, REGION_SOUND3 ) /* Samples */
1656 ROM_LOAD( "763e08", 0x000000, 0x080000, 0x054a9a63 ) // 4 banks
1657 ROM_LOAD( "763e09", 0x080000, 0x080000, 0xc39857db ) // 4 banks
1658
1659 ROM_REGION( 0x08000, REGION_USER1 )
1660 ROM_LOAD( "763a12", 0x000000, 0x008000, 0x05f1e553 ) // ??
1661 ROM_END
1662
1663
1664
1665
1666 /* Important: you must leave extra space when listing sprite ROMs
1667 in a ROM module definition. This routine unpacks each sprite nibble
1668 into a byte, doubling the memory consumption. */
1669
hotchase_sprite_decode(int num_banks,int bank_size)1670 void hotchase_sprite_decode( int num_banks, int bank_size )
1671 {
1672 unsigned char *base, *temp;
1673 int i;
1674
1675 base = memory_region(REGION_GFX1); // sprites
1676 temp = (unsigned char*)malloc( bank_size );
1677 if( !temp ) return;
1678
1679 for( i = num_banks; i >0; i-- ){
1680 unsigned char *finish = base + 2*bank_size*i;
1681 unsigned char *dest = finish - 2*bank_size;
1682
1683 unsigned char *p1 = temp;
1684 unsigned char *p2 = temp+bank_size/2;
1685
1686 unsigned char data;
1687
1688 memcpy (temp, base+bank_size*(i-1), bank_size);
1689
1690 do {
1691 data = *p1++;
1692 if( (data&0xf0) == 0xf0 ) data &= 0x0f;
1693 if( (data&0x0f) == 0x0f ) data &= 0xf0;
1694 *dest++ = data >> 4;
1695 *dest++ = data & 0xF;
1696 data = *p1++;
1697 if( (data&0xf0) == 0xf0 ) data &= 0x0f;
1698 if( (data&0x0f) == 0x0f ) data &= 0xf0;
1699 *dest++ = data >> 4;
1700 *dest++ = data & 0xF;
1701
1702
1703 data = *p2++;
1704 if( (data&0xf0) == 0xf0 ) data &= 0x0f;
1705 if( (data&0x0f) == 0x0f ) data &= 0xf0;
1706 *dest++ = data >> 4;
1707 *dest++ = data & 0xF;
1708 data = *p2++;
1709 if( (data&0xf0) == 0xf0 ) data &= 0x0f;
1710 if( (data&0x0f) == 0x0f ) data &= 0xf0;
1711 *dest++ = data >> 4;
1712 *dest++ = data & 0xF;
1713 } while( dest<finish );
1714 }
1715 free( temp );
1716 }
1717
1718
1719
1720
1721 /* Unpack sprites data and do some patching */
init_hotchase(void)1722 void init_hotchase(void)
1723 {
1724 unsigned char *RAM;
1725 int i;
1726
1727 /* Optional code patches */
1728
1729 /* Main CPU patches */
1730 RAM = memory_region(REGION_CPU1);
1731 WRITE_WORD (&RAM[0x1140],0x0015); WRITE_WORD (&RAM[0x195c],0x601A); // faster self test
1732
1733 /* Sub CPU patches */
1734 RAM = memory_region(REGION_CPU2);
1735
1736 /* Sound CPU patches */
1737 RAM = memory_region(REGION_CPU3);
1738
1739
1740 /* Decode GFX Roms */
1741
1742 /* Let's swap even and odd bytes of the sprites gfx roms */
1743 RAM = memory_region(REGION_GFX1);
1744 for (i = 0; i < memory_region_length(REGION_GFX1); i += 2)
1745 {
1746 int x = RAM[i];
1747 RAM[i] = RAM[i+1];
1748 RAM[i+1] = x;
1749 }
1750
1751 /* Now we can unpack each nibble of the sprites into a pixel (one byte) */
1752 hotchase_sprite_decode(3,0x80000*2); // num banks, bank len
1753
1754
1755 /* Let's copy the second half of the fg layer gfx (charset) over the first */
1756 RAM = memory_region(REGION_GFX3);
1757 memcpy(&RAM[0], &RAM[0x10000/2], 0x10000/2);
1758
1759 }
1760
1761
1762
1763 /***************************************************************************
1764
1765 Game driver(s)
1766
1767 ***************************************************************************/
1768
1769 GAMEX(1986, wecleman, 0, wecleman, wecleman, wecleman, ROT0, "Konami", "WEC Le Mans 24", GAME_WRONG_COLORS )
1770 GAME( 1988, hotchase, 0, hotchase, hotchase, hotchase, ROT0, "Konami", "Hot Chase" )
1771