From 120a6070e8bb36dd0be40d96d1b1dd1c33095e81 Mon Sep 17 00:00:00 2001 From: Zsolt Vasvari Date: Sun, 13 Jan 2008 06:14:20 +0000 Subject: [PATCH] Fixes victory137b4gre and victory37b16gre src/mame/audio/berzerk.c - Added sh_reset src/mame/audio/exidy.c src/mame/includes/exidy.h - Added reset functionality - Moved Victory hardware routines here src/mame/drivers/victory.c - Some clean-up, mirrored memory map for audio CPU src/mame/video/victory.c - Simplified code by removing complicated dirty tracking. Now VIDEO_UPDATE is called on every frame, further simplifing code src/mame/drivers/exidy.c - Mirrored memory map for audio CPU - Added sh_reset src/emu/machine/6821pia.c src/emu/machine/6821pia.h - Added orthogonal accessors - Removed hacky update_shared_irq_handler(), now the same IRQ callback maybe called multiple times, but this shouldn't be a problem - IRQ lines are cleared on a reset src/emu/sound/tms5220.c - Disabled code that set the Buffer Empty flag after a stop frame. This fixes Victory. This might be the incorrect fix but the old code wasn't working either. --- src/emu/machine/6821pia.c | 211 ++++++++++++++++++------------- src/emu/machine/6821pia.h | 8 +- src/emu/sound/tms5220.c | 55 ++------- src/mame/audio/berzerk.c | 4 +- src/mame/audio/exidy.c | 221 +++++++++++++++++++++++---------- src/mame/drivers/exidy.c | 16 +-- src/mame/drivers/victory.c | 133 ++++---------------- src/mame/includes/exidy.h | 9 ++ src/mame/video/victory.c | 246 +++++++++++-------------------------- 9 files changed, 418 insertions(+), 485 deletions(-) diff --git a/src/emu/machine/6821pia.c b/src/emu/machine/6821pia.c index e2c0d8801e3..d75e81b0870 100644 --- a/src/emu/machine/6821pia.c +++ b/src/emu/machine/6821pia.c @@ -177,6 +177,8 @@ void pia_reset(void) { const pia6821_interface *intf = pias[i].intf; + if (intf == NULL) continue; + memset(&pias[i], 0, sizeof(pias[i])); pias[i].intf = intf; @@ -190,48 +192,15 @@ void pia_reset(void) pias[i].in_a = 0xff; pias[i].in_ca1 = TRUE; pias[i].in_ca2 = TRUE; + + /* clear the IRQs */ + if (intf->irq_a_func) (*intf->irq_a_func)(FALSE); + if (intf->irq_b_func) (*intf->irq_b_func)(FALSE); } } -/************************************* - * - * Wire-OR for all interrupt handlers - * - *************************************/ - -static void update_shared_irq_handler(void (*irq_func)(int state)) -{ - int i; - - /* search all PIAs for this same IRQ function */ - for (i = 0; i < MAX_PIA; i++) - { - if (pias[i].intf) - { - /* check IRQ A */ - if ((pias[i].intf->irq_a_func == irq_func) && pias[i].irq_a_state) - { - (*irq_func)(TRUE); - return; - } - - /* check IRQ B */ - if ((pias[i].intf->irq_b_func == irq_func) && pias[i].irq_b_state) - { - (*irq_func)(TRUE); - return; - } - } - } - - /* if we found nothing, the state is off */ - (*irq_func)(FALSE); -} - - - /************************************* * * External interrupt check @@ -249,7 +218,7 @@ static void update_interrupts(pia6821 *p) { p->irq_a_state = new_state; - if (p->intf->irq_a_func) update_shared_irq_handler(p->intf->irq_a_func); + if (p->intf->irq_a_func) (p->intf->irq_a_func)(p->irq_a_state); } /* then do IRQ B */ @@ -259,7 +228,7 @@ static void update_interrupts(pia6821 *p) { p->irq_b_state = new_state; - if (p->intf->irq_b_func) update_shared_irq_handler(p->intf->irq_b_func); + if (p->intf->irq_b_func) (p->intf->irq_b_func)(p->irq_b_state); } } @@ -879,12 +848,22 @@ void pia_set_port_a_z_mask(int which, UINT8 data) * *************************************/ +UINT8 pia_get_input_a(int which) +{ + pia6821 *p = &pias[which]; + + return p->in_a; +} + + void pia_set_input_a(int which, UINT8 data, UINT8 z_mask) { pia6821 *p = &pias[which]; assert_always(p->intf->in_a_func == NULL, "pia_set_input_a() called when in_a_func implemented"); + LOG(("cpu #%d (PC=%08X): PIA #%d: set input port A = %02X\n", cpu_getactivecpu(), safe_activecpu_get_pc(), which, data)); + p->in_a = data; p->port_a_z_mask = z_mask; p->in_a_pushed = TRUE; @@ -908,6 +887,14 @@ UINT8 pia_get_output_a(int which) * *************************************/ +int pia_get_input_ca1(int which) +{ + pia6821 *p = &pias[which]; + + return p->in_ca1; +} + + void pia_set_input_ca1(int which, int data) { pia6821 *p = &pias[which]; @@ -915,10 +902,14 @@ void pia_set_input_ca1(int which, int data) /* limit the data to 0 or 1 */ data = data ? TRUE : FALSE; + LOG(("cpu #%d (PC=%08X): PIA #%d: set input CA1 = %d\n", cpu_getactivecpu(), safe_activecpu_get_pc(), which, data)); + /* the new state has caused a transition */ if ((p->in_ca1 != data) && ((data && C1_LOW_TO_HIGH(p->ctl_a)) || (!data && C1_HIGH_TO_LOW(p->ctl_a)))) { + LOG(("cpu #%d (PC=%08X): PIA #%d: CA1 triggering\n", cpu_getactivecpu(), safe_activecpu_get_pc(), which)); + /* mark the IRQ */ p->irq_a1 = TRUE; @@ -943,6 +934,14 @@ void pia_set_input_ca1(int which, int data) * *************************************/ +int pia_get_input_ca2(int which) +{ + pia6821 *p = &pias[which]; + + return p->in_ca2; +} + + void pia_set_input_ca2(int which, int data) { pia6821 *p = &pias[which]; @@ -950,11 +949,15 @@ void pia_set_input_ca2(int which, int data) /* limit the data to 0 or 1 */ data = data ? 1 : 0; + LOG(("cpu #%d (PC=%08X): PIA #%d: set input CA2 = %d\n", cpu_getactivecpu(), safe_activecpu_get_pc(), which, data)); + /* if input mode and the new state has caused a transition */ if (C2_INPUT(p->ctl_a) && (p->in_ca2 != data) && ((data && C2_LOW_TO_HIGH(p->ctl_a)) || (!data && C2_HIGH_TO_LOW(p->ctl_a)))) { + LOG(("cpu #%d (PC=%08X): PIA #%d: CA2 triggering\n", cpu_getactivecpu(), safe_activecpu_get_pc(), which)); + /* mark the IRQ */ p->irq_a2 = TRUE; @@ -985,12 +988,22 @@ int pia_get_output_ca2(int which) * *************************************/ +UINT8 pia_get_input_b(int which) +{ + pia6821 *p = &pias[which]; + + return p->in_b; +} + + void pia_set_input_b(int which, UINT8 data) { pia6821 *p = &pias[which]; assert_always(p->intf->in_b_func == NULL, "pia_set_input_b() called when in_b_func implemented"); + LOG(("cpu #%d (PC=%08X): PIA #%d: set input port B = %02X\n", cpu_getactivecpu(), safe_activecpu_get_pc(), which, data)); + p->in_b = data; p->in_b_pushed = TRUE; } @@ -1014,6 +1027,14 @@ UINT8 pia_get_output_b(int which) * *************************************/ +int pia_get_input_cb1(int which) +{ + pia6821 *p = &pias[which]; + + return p->in_cb1; +} + + void pia_set_input_cb1(int which, int data) { pia6821 *p = &pias[which]; @@ -1021,10 +1042,14 @@ void pia_set_input_cb1(int which, int data) /* limit the data to 0 or 1 */ data = data ? 1 : 0; + LOG(("cpu #%d (PC=%08X): PIA #%d: set input CB1 = %d\n", cpu_getactivecpu(), safe_activecpu_get_pc(), which, data)); + /* the new state has caused a transition */ if ((p->in_cb1 != data) && ((data && C1_LOW_TO_HIGH(p->ctl_b)) || (!data && C1_HIGH_TO_LOW(p->ctl_b)))) { + LOG(("cpu #%d (PC=%08X): PIA #%d: CB1 triggering\n", cpu_getactivecpu(), safe_activecpu_get_pc(), which)); + /* mark the IRQ */ p->irq_b1 = 1; @@ -1050,6 +1075,14 @@ void pia_set_input_cb1(int which, int data) * *************************************/ +int pia_get_input_cb2(int which) +{ + pia6821 *p = &pias[which]; + + return p->in_cb2; +} + + void pia_set_input_cb2(int which, int data) { pia6821 *p = &pias[which]; @@ -1057,11 +1090,15 @@ void pia_set_input_cb2(int which, int data) /* limit the data to 0 or 1 */ data = data ? 1 : 0; + LOG(("cpu #%d (PC=%08X): PIA #%d: set input CB2 = %d\n", cpu_getactivecpu(), safe_activecpu_get_pc(), which, data)); + /* if input mode and the new state has caused a transition */ if (C2_INPUT(p->ctl_b) && (p->in_cb2 != data) && ((data && C2_LOW_TO_HIGH(p->ctl_b)) || (!data && C2_HIGH_TO_LOW(p->ctl_b)))) { + LOG(("cpu #%d (PC=%08X): PIA #%d: CB2 triggering\n", cpu_getactivecpu(), safe_activecpu_get_pc(), which)); + /* mark the IRQ */ p->irq_b2 = 1; @@ -1256,23 +1293,23 @@ WRITE8_HANDLER( pia_5_portb_w ) { pia_set_input_b(5, data); } WRITE8_HANDLER( pia_6_portb_w ) { pia_set_input_b(6, data); } WRITE8_HANDLER( pia_7_portb_w ) { pia_set_input_b(7, data); } -READ8_HANDLER( pia_0_porta_r ) { return pias[0].in_a; } -READ8_HANDLER( pia_1_porta_r ) { return pias[1].in_a; } -READ8_HANDLER( pia_2_porta_r ) { return pias[2].in_a; } -READ8_HANDLER( pia_3_porta_r ) { return pias[3].in_a; } -READ8_HANDLER( pia_4_porta_r ) { return pias[4].in_a; } -READ8_HANDLER( pia_5_porta_r ) { return pias[5].in_a; } -READ8_HANDLER( pia_6_porta_r ) { return pias[6].in_a; } -READ8_HANDLER( pia_7_porta_r ) { return pias[7].in_a; } +READ8_HANDLER( pia_0_porta_r ) { return pia_get_input_a(0); } +READ8_HANDLER( pia_1_porta_r ) { return pia_get_input_a(1); } +READ8_HANDLER( pia_2_porta_r ) { return pia_get_input_a(2); } +READ8_HANDLER( pia_3_porta_r ) { return pia_get_input_a(3); } +READ8_HANDLER( pia_4_porta_r ) { return pia_get_input_a(4); } +READ8_HANDLER( pia_5_porta_r ) { return pia_get_input_a(5); } +READ8_HANDLER( pia_6_porta_r ) { return pia_get_input_a(6); } +READ8_HANDLER( pia_7_porta_r ) { return pia_get_input_a(7); } -READ8_HANDLER( pia_0_portb_r ) { return pias[0].in_b; } -READ8_HANDLER( pia_1_portb_r ) { return pias[1].in_b; } -READ8_HANDLER( pia_2_portb_r ) { return pias[2].in_b; } -READ8_HANDLER( pia_3_portb_r ) { return pias[3].in_b; } -READ8_HANDLER( pia_4_portb_r ) { return pias[4].in_b; } -READ8_HANDLER( pia_5_portb_r ) { return pias[5].in_b; } -READ8_HANDLER( pia_6_portb_r ) { return pias[6].in_b; } -READ8_HANDLER( pia_7_portb_r ) { return pias[7].in_b; } +READ8_HANDLER( pia_0_portb_r ) { return pia_get_input_b(0); } +READ8_HANDLER( pia_1_portb_r ) { return pia_get_input_b(1); } +READ8_HANDLER( pia_2_portb_r ) { return pia_get_input_b(2); } +READ8_HANDLER( pia_3_portb_r ) { return pia_get_input_b(3); } +READ8_HANDLER( pia_4_portb_r ) { return pia_get_input_b(4); } +READ8_HANDLER( pia_5_portb_r ) { return pia_get_input_b(5); } +READ8_HANDLER( pia_6_portb_r ) { return pia_get_input_b(6); } +READ8_HANDLER( pia_7_portb_r ) { return pia_get_input_b(7); } /******************* 1-bit CA1/CA2/CB1/CB2 port interfaces *******************/ @@ -1312,38 +1349,38 @@ WRITE8_HANDLER( pia_5_cb2_w ) { pia_set_input_cb2(5, data); } WRITE8_HANDLER( pia_6_cb2_w ) { pia_set_input_cb2(6, data); } WRITE8_HANDLER( pia_7_cb2_w ) { pia_set_input_cb2(7, data); } -READ8_HANDLER( pia_0_ca1_r ) { return pias[0].in_ca1; } -READ8_HANDLER( pia_1_ca1_r ) { return pias[1].in_ca1; } -READ8_HANDLER( pia_2_ca1_r ) { return pias[2].in_ca1; } -READ8_HANDLER( pia_3_ca1_r ) { return pias[3].in_ca1; } -READ8_HANDLER( pia_4_ca1_r ) { return pias[4].in_ca1; } -READ8_HANDLER( pia_5_ca1_r ) { return pias[5].in_ca1; } -READ8_HANDLER( pia_6_ca1_r ) { return pias[6].in_ca1; } -READ8_HANDLER( pia_7_ca1_r ) { return pias[7].in_ca1; } +READ8_HANDLER( pia_0_ca1_r ) { return pia_get_input_ca1(0); } +READ8_HANDLER( pia_1_ca1_r ) { return pia_get_input_ca1(1); } +READ8_HANDLER( pia_2_ca1_r ) { return pia_get_input_ca1(2); } +READ8_HANDLER( pia_3_ca1_r ) { return pia_get_input_ca1(3); } +READ8_HANDLER( pia_4_ca1_r ) { return pia_get_input_ca1(4); } +READ8_HANDLER( pia_5_ca1_r ) { return pia_get_input_ca1(5); } +READ8_HANDLER( pia_6_ca1_r ) { return pia_get_input_ca1(6); } +READ8_HANDLER( pia_7_ca1_r ) { return pia_get_input_ca1(7); } -READ8_HANDLER( pia_0_ca2_r ) { return pias[0].in_ca2; } -READ8_HANDLER( pia_1_ca2_r ) { return pias[1].in_ca2; } -READ8_HANDLER( pia_2_ca2_r ) { return pias[2].in_ca2; } -READ8_HANDLER( pia_3_ca2_r ) { return pias[3].in_ca2; } -READ8_HANDLER( pia_4_ca2_r ) { return pias[4].in_ca2; } -READ8_HANDLER( pia_5_ca2_r ) { return pias[5].in_ca2; } -READ8_HANDLER( pia_6_ca2_r ) { return pias[6].in_ca2; } -READ8_HANDLER( pia_7_ca2_r ) { return pias[7].in_ca2; } +READ8_HANDLER( pia_0_ca2_r ) { return pia_get_input_ca2(0); } +READ8_HANDLER( pia_1_ca2_r ) { return pia_get_input_ca2(1); } +READ8_HANDLER( pia_2_ca2_r ) { return pia_get_input_ca2(2); } +READ8_HANDLER( pia_3_ca2_r ) { return pia_get_input_ca2(3); } +READ8_HANDLER( pia_4_ca2_r ) { return pia_get_input_ca2(4); } +READ8_HANDLER( pia_5_ca2_r ) { return pia_get_input_ca2(5); } +READ8_HANDLER( pia_6_ca2_r ) { return pia_get_input_ca2(6); } +READ8_HANDLER( pia_7_ca2_r ) { return pia_get_input_ca2(7); } -READ8_HANDLER( pia_0_cb1_r ) { return pias[0].in_cb1; } -READ8_HANDLER( pia_1_cb1_r ) { return pias[1].in_cb1; } -READ8_HANDLER( pia_2_cb1_r ) { return pias[2].in_cb1; } -READ8_HANDLER( pia_3_cb1_r ) { return pias[3].in_cb1; } -READ8_HANDLER( pia_4_cb1_r ) { return pias[4].in_cb1; } -READ8_HANDLER( pia_5_cb1_r ) { return pias[5].in_cb1; } -READ8_HANDLER( pia_6_cb1_r ) { return pias[6].in_cb1; } -READ8_HANDLER( pia_7_cb1_r ) { return pias[7].in_cb1; } +READ8_HANDLER( pia_0_cb1_r ) { return pia_get_input_cb1(0); } +READ8_HANDLER( pia_1_cb1_r ) { return pia_get_input_cb1(1); } +READ8_HANDLER( pia_2_cb1_r ) { return pia_get_input_cb1(2); } +READ8_HANDLER( pia_3_cb1_r ) { return pia_get_input_cb1(3); } +READ8_HANDLER( pia_4_cb1_r ) { return pia_get_input_cb1(4); } +READ8_HANDLER( pia_5_cb1_r ) { return pia_get_input_cb1(5); } +READ8_HANDLER( pia_6_cb1_r ) { return pia_get_input_cb1(6); } +READ8_HANDLER( pia_7_cb1_r ) { return pia_get_input_cb1(7); } -READ8_HANDLER( pia_0_cb2_r ) { return pias[0].in_cb2; } -READ8_HANDLER( pia_1_cb2_r ) { return pias[1].in_cb2; } -READ8_HANDLER( pia_2_cb2_r ) { return pias[2].in_cb2; } -READ8_HANDLER( pia_3_cb2_r ) { return pias[3].in_cb2; } -READ8_HANDLER( pia_4_cb2_r ) { return pias[4].in_cb2; } -READ8_HANDLER( pia_5_cb2_r ) { return pias[5].in_cb2; } -READ8_HANDLER( pia_6_cb2_r ) { return pias[6].in_cb2; } -READ8_HANDLER( pia_7_cb2_r ) { return pias[7].in_cb2; } +READ8_HANDLER( pia_0_cb2_r ) { return pia_get_input_cb2(0); } +READ8_HANDLER( pia_1_cb2_r ) { return pia_get_input_cb2(1); } +READ8_HANDLER( pia_2_cb2_r ) { return pia_get_input_cb2(2); } +READ8_HANDLER( pia_3_cb2_r ) { return pia_get_input_cb2(3); } +READ8_HANDLER( pia_4_cb2_r ) { return pia_get_input_cb2(4); } +READ8_HANDLER( pia_5_cb2_r ) { return pia_get_input_cb2(5); } +READ8_HANDLER( pia_6_cb2_r ) { return pia_get_input_cb2(6); } +READ8_HANDLER( pia_7_cb2_r ) { return pia_get_input_cb2(7); } diff --git a/src/emu/machine/6821pia.h b/src/emu/machine/6821pia.h index 1960591cd2f..9930c5503e6 100644 --- a/src/emu/machine/6821pia.h +++ b/src/emu/machine/6821pia.h @@ -76,6 +76,7 @@ void pia_set_port_a_z_mask(int which, UINT8 data); /* see second note */ /*------------- Device interface for port A --------------*/ +UINT8 pia_get_input_a(int which); void pia_set_input_a(int which, UINT8 data, UINT8 z_mask); UINT8 pia_get_output_a(int which); @@ -83,19 +84,22 @@ UINT8 pia_get_output_a(int which); /*----------- Device interface for the CA1 pin -----------*/ +int pia_get_input_ca1(int which); void pia_set_input_ca1(int which, int data); /*----------- Device interface for the CA2 pin -----------*/ +int pia_get_input_ca2(int which); void pia_set_input_ca2(int which, int data); int pia_get_output_ca2(int which); -/*------------- Device interface for port A --------------*/ +/*------------- Device interface for port B --------------*/ +UINT8 pia_get_input_b(int which); void pia_set_input_b(int which, UINT8 data); UINT8 pia_get_output_b(int which); @@ -103,12 +107,14 @@ UINT8 pia_get_output_b(int which); /*----------- Device interface for the CB1 pin -----------*/ +int pia_get_input_cb1(int which); void pia_set_input_cb1(int which, int data); /*----------- Device interface for the CB2 pin -----------*/ +int pia_get_input_cb2(int which); void pia_set_input_cb2(int which, int data); int pia_get_output_cb2(int which); int pia_get_output_cb2_z(int which); /* see first note */ diff --git a/src/emu/sound/tms5220.c b/src/emu/sound/tms5220.c index c6907163d40..6c6e8a577df 100644 --- a/src/emu/sound/tms5220.c +++ b/src/emu/sound/tms5220.c @@ -26,7 +26,6 @@ * modified code so that the beast only start speaking at the start of next frame, like the data sheet says */ -#define USE_OBSOLETE_HACK 0 #ifndef TRUE @@ -58,9 +57,6 @@ struct tms5220 */ UINT8 tms5220_speaking; /* Speak or Speak External command in progress */ UINT8 speak_external; /* Speak External command in progress */ - #if USE_OBSOLETE_HACK - UINT8 speak_delay_frames; - #endif UINT8 talk_status; /* tms5220 is really currently speaking */ UINT8 first_frame; /* we have just started speaking, and we are to parse the first frame */ UINT8 last_frame; /* we are doing the frame of sound */ @@ -231,9 +227,6 @@ void tms5220_reset_chip(void *chip) /* initialize the chip state */ /* Note that we do not actually clear IRQ on start-up : IRQ is even raised if tms->buffer_empty or tms->buffer_low are 0 */ tms->tms5220_speaking = tms->speak_external = tms->talk_status = tms->first_frame = tms->last_frame = tms->irq_pin = 0; -#if USE_OBSOLETE_HACK - tms->speak_delay_frames = 0; -#endif if (tms->irq_func) tms->irq_func(0); tms->buffer_empty = tms->buffer_low = 1; @@ -511,38 +504,6 @@ tryagain: tms->buffer_empty = 0; } -#if 0 - /* we are to speak, yet we fill with 0s until start of next frame */ - if (tms->first_frame) - { - while ((size > 0) && ((tms->sample_count != 0) || (tms->interp_count != 0))) - { - tms->sample_count = (tms->sample_count + 1) % 200; - tms->interp_count = (tms->interp_count + 1) % 25; - buffer[buf_count] = 0x00; /* should be (-1 << 8) ??? (cf note in data sheet, p 10, table 4) */ - buf_count++; - size--; - } - } -#endif - -#if USE_OBSOLETE_HACK - /* apply some delay before we actually consume data; Victory requires this */ - if (tms->speak_delay_frames) - { - if (size <= tms->speak_delay_frames) - { - tms->speak_delay_frames -= size; - size = 0; - } - else - { - size -= tms->speak_delay_frames; - tms->speak_delay_frames = 0; - } - } -#endif - /* loop until the buffer is full or we've stopped speaking */ while ((size > 0) && tms->talk_status) { @@ -847,10 +808,6 @@ static void process_command(struct tms5220 *tms) case 0x60 : /* speak external */ tms->tms5220_speaking = tms->speak_external = 1; -#if USE_OBSOLETE_HACK - tms->speak_delay_frames = 10; -#endif - tms->RDB_flag = FALSE; /* according to the datasheet, this will cause an interrupt due to a BE condition */ @@ -946,11 +903,15 @@ static int parse_frame(struct tms5220 *tms, int the_first_frame) /* if the previous frame was a stop frame, don't do anything */ if ((! the_first_frame) && (tms->old_energy == (energytable[15] >> 6))) - /*return 1;*/ - { - tms->buffer_empty = 1; return 1; - } +// WARNING: This code below breaks Victory's power-on test! If you change it +// make sure you test Victory. +// { +// if (DEBUG_5220) logerror("Buffer Empty set - Last frame stop frame\n"); + +// tms->buffer_empty = 1; +// return 1; +// } if (tms->speak_external) /* count the total number of bits available */ diff --git a/src/mame/audio/berzerk.c b/src/mame/audio/berzerk.c index c7908a84fdf..b30674240ac 100644 --- a/src/mame/audio/berzerk.c +++ b/src/mame/audio/berzerk.c @@ -23,7 +23,9 @@ static const struct S14001A_interface berzerk_s14001a_interface = static const struct CustomSound_interface custom_interface = { - berzerk_sh_start + berzerk_sh_start, + 0, + berzerk_sh_reset, }; diff --git a/src/mame/audio/exidy.c b/src/mame/audio/exidy.c index e5f4d4ea26c..985194c26bc 100644 --- a/src/mame/audio/exidy.c +++ b/src/mame/audio/exidy.c @@ -21,7 +21,7 @@ * *************************************/ -#define CRYSTAL_OSC (3579545) +#define CRYSTAL_OSC (XTAL_3_579545MHz) #define SH8253_CLOCK (CRYSTAL_OSC/2) #define SH6840_CLOCK (CRYSTAL_OSC/4) #define SH6532_CLOCK (CRYSTAL_OSC/4) @@ -43,8 +43,7 @@ enum * *************************************/ -/* IRQ variables */ -static UINT8 pia_irq_state; +/* IRQ variable */ static UINT8 riot_irq_state; /* 6532 variables */ @@ -87,7 +86,9 @@ static UINT32 sh6840_LFSR_2 = 0xffffffff;/* ditto */ static UINT32 sh6840_LFSR_3 = 0xffffffff;/* ditto */ static UINT32 sh6840_clocks_per_sample; static UINT32 sh6840_clock_count; + static UINT8 exidy_sfxctrl; +static UINT8 victory_sound_response_ack_clk; /* 7474 @ F4 */ /* 8253 variables */ struct sh8253_timer_channel @@ -117,11 +118,11 @@ static double freq_to_step; * *************************************/ -static void exidy_irq(int state); +static void update_irq_state(int); + +static WRITE8_HANDLER( victory_sound_irq_clear_w ); +static WRITE8_HANDLER( victory_main_ack_w ); -WRITE8_HANDLER(victory_sound_response_w); -WRITE8_HANDLER(victory_sound_irq_clear_w); -WRITE8_HANDLER(victory_main_ack_w); /* PIA 0 */ static const pia6821_interface pia_0_intf = @@ -136,35 +137,28 @@ static const pia6821_interface pia_1_intf = { /*inputs : A/B,CA/B1,CA/B2 */ 0, 0, 0, 0, 0, 0, /*outputs: A/B,CA/B2 */ pia_0_portb_w, pia_0_porta_w, pia_0_cb1_w, pia_0_ca1_w, - /*irqs : A/B */ 0, exidy_irq + /*irqs : A/B */ 0, update_irq_state }; /* Victory PIA 0 */ -static const pia6821_interface victory_pia_0_intf = +static const pia6821_interface victory_pia_1_intf = { /*inputs : A/B,CA/B1,CA/B2 */ 0, 0, 0, 0, 0, 0, - /*outputs: A/B,CA/B2 */ 0, victory_sound_response_w, victory_sound_irq_clear_w, victory_main_ack_w, - /*irqs : A/B */ 0, exidy_irq + /*outputs: A/B,CA/B2 */ 0, 0, victory_sound_irq_clear_w, victory_main_ack_w, + /*irqs : A/B */ 0, update_irq_state }; /************************************* * - * Interrupt generation helpers + * Interrupt generation helper * *************************************/ -INLINE void update_irq_state(void) +static void update_irq_state(/* unused */ int state) { - cpunum_set_input_line(1, M6502_IRQ_LINE, (pia_irq_state | riot_irq_state) ? ASSERT_LINE : CLEAR_LINE); -} - - -static void exidy_irq(int state) -{ - pia_irq_state = state; - update_irq_state(); + cpunum_set_input_line(1, M6502_IRQ_LINE, (pia_get_irq_b(1) | riot_irq_state) ? ASSERT_LINE : CLEAR_LINE); } @@ -382,6 +376,71 @@ static void exidy_stream_update(void *param, stream_sample_t **inputs, stream_sa +/************************************* + * + * Extra logic for Victory + * + *************************************/ + +#define VICTORY_LOG_SOUND 0 + + +READ8_HANDLER( victory_sound_response_r ) +{ + UINT8 ret = pia_get_output_b(1); + + if (VICTORY_LOG_SOUND) logerror("%04X:!!!! Sound response read = %02X\n", activecpu_get_previouspc(), ret); + + pia_set_input_cb1(1, 0); + + return ret; +} + + +READ8_HANDLER( victory_sound_status_r ) +{ + UINT8 ret = (pia_get_input_ca1(1) << 7) | (pia_get_input_cb1(1) << 6); + + if (VICTORY_LOG_SOUND) logerror("%04X:!!!! Sound status read = %02X\n", activecpu_get_previouspc(), ret); + + return ret; +} + + +static TIMER_CALLBACK( delayed_command_w ) +{ + pia_set_input_a(1, param, 0); + pia_set_input_ca1(1, 0); +} + +WRITE8_HANDLER( victory_sound_command_w ) +{ + if (VICTORY_LOG_SOUND) logerror("%04X:!!!! Sound command = %02X\n", activecpu_get_previouspc(), data); + + timer_call_after_resynch(NULL, data, delayed_command_w); +} + + +WRITE8_HANDLER( victory_sound_irq_clear_w ) +{ + if (VICTORY_LOG_SOUND) logerror("%04X:!!!! Sound IRQ clear = %02X\n", activecpu_get_previouspc(), data); + + if (!data) pia_set_input_ca1(1, 1); +} + + +static WRITE8_HANDLER( victory_main_ack_w ) +{ + if (VICTORY_LOG_SOUND) logerror("%04X:!!!! Sound Main ACK W = %02X\n", activecpu_get_previouspc(), data); + + if (victory_sound_response_ack_clk && !data) + pia_set_input_cb1(1, 1); + + victory_sound_response_ack_clk = data; +} + + + /************************************* * * Sound startup routines @@ -409,36 +468,13 @@ static void *common_start(void) /* allocate the stream */ exidy_stream = stream_create(0, 1, sample_rate, NULL, exidy_stream_update); - /* Init PIA */ - pia_reset(); - - /* Init LFSR */ - sh6840_LFSR_oldxor = 0; - sh6840_LFSR_0 = 0xffffffff; - sh6840_LFSR_1 = 0xffffffff; - sh6840_LFSR_2 = 0xffffffff; - sh6840_LFSR_3 = 0xffffffff; - - /* Init 6532 */ + /* 6532 */ riot_timer = timer_alloc(riot_interrupt, NULL); - riot_irq_flag = 0; - riot_timer_irq_enable = 0; - riot_porta_data = 0xff; - riot_portb_data = 0xff; - riot_clock_divisor = 1; - riot_state = RIOT_IDLE; - /* Init 6840 */ - memset(sh6840_timer, 0, sizeof(sh6840_timer)); + /* 6840 */ sh6840_clocks_per_sample = (int)((double)SH6840_CLOCK / (double)sample_rate * (double)(1 << 24)); - sh6840_MSB = 0; - sh6840_volume[0] = 0; - sh6840_volume[1] = 0; - sh6840_volume[2] = 0; - exidy_sfxctrl = 0; - /* Init 8253 */ - memset(sh8253_timer, 0, sizeof(sh8253_timer)); + /* 8253 */ freq_to_step = (double)(1 << 24) / (double)sample_rate; return auto_malloc(1); @@ -447,7 +483,6 @@ static void *common_start(void) void *exidy_sh_start(int clock, const struct CustomSound_interface *config) { - /* Init PIA */ pia_config(0, &pia_0_intf); pia_config(1, &pia_1_intf); has_sh8253 = TRUE; @@ -457,10 +492,9 @@ void *exidy_sh_start(int clock, const struct CustomSound_interface *config) void *victory_sh_start(int clock, const struct CustomSound_interface *config) { - /* Init PIA */ - pia_config(0, &victory_pia_0_intf); - pia_0_cb1_w(0, 1); + pia_config(1, &victory_pia_1_intf); has_sh8253 = TRUE; + return common_start(); } @@ -473,6 +507,73 @@ void *berzerk_sh_start(int clock, const struct CustomSound_interface *config) +/************************************* + * + * Sound reset routines + * + *************************************/ + +static void common_reset(void) +{ + /* PIA */ + pia_reset(); + + /* LFSR */ + sh6840_LFSR_oldxor = 0; + sh6840_LFSR_0 = 0xffffffff; + sh6840_LFSR_1 = 0xffffffff; + sh6840_LFSR_2 = 0xffffffff; + sh6840_LFSR_3 = 0xffffffff; + + /* 6532 */ + riot_irq_flag = 0; + riot_timer_irq_enable = 0; + riot_porta_data = 0xff; + riot_portb_data = 0xff; + riot_clock_divisor = 1; + riot_state = RIOT_IDLE; + + /* 6840 */ + memset(sh6840_timer, 0, sizeof(sh6840_timer)); + sh6840_MSB = 0; + sh6840_volume[0] = 0; + sh6840_volume[1] = 0; + sh6840_volume[2] = 0; + exidy_sfxctrl = 0; + + /* 8253 */ + memset(sh8253_timer, 0, sizeof(sh8253_timer)); +} + + +void exidy_sh_reset(void *token) +{ + common_reset(); +} + + +void victory_sh_reset(void *token) +{ + common_reset(); + + /* the flip-flop @ F4 is reset */ + victory_sound_response_ack_clk = 0; + pia_set_input_cb1(1, 1); + + /* these two lines shouldn't be needed, but it avoids the log entry + as the sound CPU checks port A before the main CPU ever writes to it */ + pia_set_input_a(1, 0, 0); + pia_set_input_ca1(1, 1); +} + + +void berzerk_sh_reset(void *token) +{ + common_reset(); +} + + + /************************************* * * 6532 RIOT timer callback @@ -487,7 +588,7 @@ static TIMER_CALLBACK( riot_interrupt ) /* generate the IRQ */ riot_irq_flag |= 0x80; riot_irq_state = riot_timer_irq_enable; - update_irq_state(); + update_irq_state(0); /* now start counting clock cycles down */ riot_state = RIOT_POST_COUNT; @@ -512,9 +613,6 @@ static TIMER_CALLBACK( riot_interrupt ) WRITE8_HANDLER( exidy_shriot_w ) { - /* mask to the low 7 bits */ - offset &= 0x7f; - /* I/O is done if A2 == 0 */ if ((offset & 0x04) == 0) { @@ -568,10 +666,10 @@ WRITE8_HANDLER( exidy_shriot_w ) if (riot_state != RIOT_COUNT) riot_irq_flag &= ~0x80; riot_irq_state = 0; - update_irq_state(); + update_irq_state(0); /* set the enable from the offset */ - riot_timer_irq_enable = offset & 0x08; + riot_timer_irq_enable = (offset & 0x08) ? 1 : 0; /* set a new timer */ riot_clock_divisor = divisors[offset & 0x03]; @@ -590,9 +688,6 @@ WRITE8_HANDLER( exidy_shriot_w ) READ8_HANDLER( exidy_shriot_r ) { - /* mask to the low 7 bits */ - offset &= 0x7f; - /* I/O is done if A2 == 0 */ if ((offset & 0x04) == 0) { @@ -624,7 +719,7 @@ READ8_HANDLER( exidy_shriot_r ) int temp = riot_irq_flag; riot_irq_flag = 0; riot_irq_state = 0; - update_irq_state(); + update_irq_state(0); return temp; } @@ -666,7 +761,6 @@ WRITE8_HANDLER( exidy_sh8253_w ) stream_update(exidy_stream); - offset &= 3; switch (offset) { case 0: @@ -723,8 +817,6 @@ WRITE8_HANDLER( exidy_sh6840_w ) /* force an update of the stream */ stream_update(exidy_stream); - /* only look at the low 3 bits */ - offset &= 7; switch (offset) { /* offset 0 writes to either channel 0 control or channel 2 control */ @@ -784,7 +876,6 @@ WRITE8_HANDLER( exidy_sfxctrl_w ) { stream_update(exidy_stream); - offset &= 3; switch (offset) { case 0: diff --git a/src/mame/drivers/exidy.c b/src/mame/drivers/exidy.c index 0ab8264ba0c..3d907545582 100644 --- a/src/mame/drivers/exidy.c +++ b/src/mame/drivers/exidy.c @@ -286,13 +286,13 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( sound_map, ADDRESS_SPACE_PROGRAM, 8 ) ADDRESS_MAP_FLAGS( AMEF_ABITS(15) ) - AM_RANGE(0x0000, 0x007f) AM_MIRROR(0x780) AM_RAM - AM_RANGE(0x0800, 0x0fff) AM_READWRITE(exidy_shriot_r, exidy_shriot_w) - AM_RANGE(0x1000, 0x17ff) AM_READWRITE(pia_1_r, pia_1_w) - AM_RANGE(0x1800, 0x1fff) AM_READWRITE(exidy_sh8253_r, exidy_sh8253_w) + AM_RANGE(0x0000, 0x007f) AM_MIRROR(0x0780) AM_RAM + AM_RANGE(0x0800, 0x087f) AM_MIRROR(0x0780) AM_READWRITE(exidy_shriot_r, exidy_shriot_w) + AM_RANGE(0x1000, 0x1003) AM_MIRROR(0x07fc) AM_READWRITE(pia_1_r, pia_1_w) + AM_RANGE(0x1800, 0x1803) AM_MIRROR(0x07fc) AM_READWRITE(exidy_sh8253_r, exidy_sh8253_w) AM_RANGE(0x2000, 0x27ff) AM_WRITE(exidy_sound_filter_w) - AM_RANGE(0x2800, 0x2fff) AM_READWRITE(exidy_sh6840_r, exidy_sh6840_w) - AM_RANGE(0x3000, 0x37ff) AM_WRITE(exidy_sfxctrl_w) + AM_RANGE(0x2800, 0x2807) AM_MIRROR(0x07f8) AM_READWRITE(exidy_sh6840_r, exidy_sh6840_w) + AM_RANGE(0x3000, 0x3003) AM_MIRROR(0x07fc) AM_WRITE(exidy_sfxctrl_w) AM_RANGE(0x5800, 0x7fff) AM_ROM ADDRESS_MAP_END @@ -822,7 +822,9 @@ static const struct Samplesinterface targ_samples_interface = static const struct CustomSound_interface exidy_custom_interface = { - exidy_sh_start + exidy_sh_start, + 0, + exidy_sh_reset }; diff --git a/src/mame/drivers/victory.c b/src/mame/drivers/victory.c index 9369145ac2d..cc64d36122c 100644 --- a/src/mame/drivers/victory.c +++ b/src/mame/drivers/victory.c @@ -97,90 +97,11 @@ #include "driver.h" #include "exidy.h" +#include "victory.h" #include "machine/6821pia.h" #include "sound/5220intf.h" -#define LOG_SOUND 0 - - -static UINT8 sound_response; -static UINT8 sound_response_ack_clk; - - -/* video driver data & functions */ -extern UINT8 *victory_charram; - -VIDEO_START( victory ); -VIDEO_EOF( victory ); -VIDEO_UPDATE( victory ); -INTERRUPT_GEN( victory_vblank_interrupt ); - -READ8_HANDLER( victory_video_control_r ); -WRITE8_HANDLER( victory_video_control_w ); -WRITE8_HANDLER( victory_paletteram_w ); -WRITE8_HANDLER( victory_videoram_w ); -WRITE8_HANDLER( victory_charram_w ); - - - -/************************************* - * - * Sound CPU control - * - *************************************/ - -static READ8_HANDLER( sound_response_r ) -{ - if (LOG_SOUND) logerror("%04X:!!!! Sound response read = %02X\n", activecpu_get_previouspc(), sound_response); - pia_0_cb1_w(0, 0); - return sound_response; -} - - -static READ8_HANDLER( sound_status_r ) -{ - if (LOG_SOUND) logerror("%04X:!!!! Sound status read = %02X\n", activecpu_get_previouspc(), (pia_0_ca1_r(0) << 7) | (pia_0_cb1_r(0) << 6)); - return (pia_0_ca1_r(0) << 7) | (pia_0_cb1_r(0) << 6); -} - - -static TIMER_CALLBACK( delayed_command_w ) -{ - pia_0_porta_w(0, param); - pia_0_ca1_w(0, 0); - if (LOG_SOUND) logerror("%04X:!!!! Sound command = %02X\n", activecpu_get_previouspc(), param); -} - -static WRITE8_HANDLER( sound_command_w ) -{ - timer_call_after_resynch(NULL, data, delayed_command_w); -} - - -WRITE8_HANDLER( victory_sound_response_w ) -{ - sound_response = data; - if (LOG_SOUND) logerror("%04X:!!!! Sound response = %02X\n", activecpu_get_previouspc(), data); -} - - -WRITE8_HANDLER( victory_sound_irq_clear_w ) -{ - if (LOG_SOUND) logerror("%04X:!!!! Sound IRQ clear = %02X\n", activecpu_get_previouspc(), data); - if (!data) pia_0_ca1_w(0, 1); -} - - -WRITE8_HANDLER( victory_main_ack_w ) -{ - if (LOG_SOUND) logerror("%04X:!!!! Sound ack = %02X\n", activecpu_get_previouspc(), data); - if (sound_response_ack_clk && !data) - pia_0_cb1_w(0, 1); - sound_response_ack_clk = data; -} - - /************************************* * @@ -190,10 +111,10 @@ WRITE8_HANDLER( victory_main_ack_w ) static WRITE8_HANDLER( lamp_control_w ) { - set_led_status(0,data & 0x80); - set_led_status(1,data & 0x40); - set_led_status(2,data & 0x20); - set_led_status(3,data & 0x10); + set_led_status(0, data & 0x80); + set_led_status(1, data & 0x40); + set_led_status(2, data & 0x20); + set_led_status(3, data & 0x10); } @@ -208,17 +129,17 @@ static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0xbfff) AM_ROM AM_RANGE(0xc000, 0xc0ff) AM_READ(victory_video_control_r) AM_RANGE(0xc100, 0xc1ff) AM_WRITE(victory_video_control_w) - AM_RANGE(0xc200, 0xc3ff) AM_WRITE(victory_paletteram_w) AM_BASE(&paletteram) - AM_RANGE(0xc400, 0xc7ff) AM_READWRITE(MRA8_RAM, victory_videoram_w) AM_BASE(&videoram) - AM_RANGE(0xc800, 0xdfff) AM_READWRITE(MRA8_RAM, victory_charram_w) AM_BASE(&victory_charram) + AM_RANGE(0xc200, 0xc3ff) AM_WRITE(victory_paletteram_w) + AM_RANGE(0xc400, 0xc7ff) AM_RAM AM_BASE(&victory_videoram) + AM_RANGE(0xc800, 0xdfff) AM_RAM AM_BASE(&victory_charram) AM_RANGE(0xe000, 0xefff) AM_RAM AM_RANGE(0xf000, 0xf7ff) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size) - AM_RANGE(0xf800, 0xf800) AM_READWRITE(sound_response_r, sound_command_w) - AM_RANGE(0xf801, 0xf801) AM_READ(sound_status_r) + AM_RANGE(0xf800, 0xf800) AM_MIRROR(0x07fc) AM_READWRITE(victory_sound_response_r, victory_sound_command_w) + AM_RANGE(0xf801, 0xf801) AM_MIRROR(0x07fc) AM_READ(victory_sound_status_r) ADDRESS_MAP_END -static ADDRESS_MAP_START( main_iomap, ADDRESS_SPACE_IO, 8 ) +static ADDRESS_MAP_START( main_io_map, ADDRESS_SPACE_IO, 8 ) ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) AM_RANGE(0x00, 0x03) AM_READ(input_port_0_r) AM_RANGE(0x04, 0x07) AM_READ(input_port_1_r) @@ -237,15 +158,16 @@ ADDRESS_MAP_END * *************************************/ -static ADDRESS_MAP_START( sound_map, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x00ff) AM_MIRROR(0xf00) AM_RAM - AM_RANGE(0x1000, 0x1fff) AM_READWRITE(exidy_shriot_r, exidy_shriot_w) - AM_RANGE(0x2000, 0x27ff) AM_READWRITE(pia_0_r, pia_0_w) - AM_RANGE(0x3000, 0x3fff) AM_READWRITE(exidy_sh8253_r, exidy_sh8253_w) - AM_RANGE(0x4000, 0x4fff) AM_WRITE(exidy_sound_filter_w) - AM_RANGE(0x5000, 0x5fff) AM_READWRITE(exidy_sh6840_r, exidy_sh6840_w) - AM_RANGE(0x6000, 0x6fff) AM_WRITE(exidy_sfxctrl_w) - AM_RANGE(0xc000, 0xffff) AM_ROM +static ADDRESS_MAP_START( audio_map, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x00ff) AM_MIRROR(0x0f00) AM_RAM + AM_RANGE(0x1000, 0x107f) AM_MIRROR(0x0f80) AM_READWRITE(exidy_shriot_r, exidy_shriot_w) + AM_RANGE(0x2000, 0x2003) AM_MIRROR(0x0ffc) AM_READWRITE(pia_1_r, pia_1_w) + AM_RANGE(0x3000, 0x3003) AM_MIRROR(0x0ffc) AM_READWRITE(exidy_sh8253_r, exidy_sh8253_w) + AM_RANGE(0x4000, 0x4fff) AM_NOP + AM_RANGE(0x5000, 0x5007) AM_MIRROR(0x0ff8) AM_READWRITE(exidy_sh6840_r, exidy_sh6840_w) + AM_RANGE(0x6000, 0x6003) AM_MIRROR(0x0ffc) AM_WRITE(exidy_sfxctrl_w) + AM_RANGE(0x7000, 0xafff) AM_NOP + AM_RANGE(0xb000, 0xffff) AM_ROM ADDRESS_MAP_END @@ -310,7 +232,7 @@ static const struct CustomSound_interface custom_interface = { victory_sh_start, 0, - 0 + victory_sh_reset, }; @@ -324,26 +246,25 @@ static const struct CustomSound_interface custom_interface = static MACHINE_DRIVER_START( victory ) /* basic machine hardware */ - MDRV_CPU_ADD(Z80, 4000000) + MDRV_CPU_ADD(Z80, VICTORY_MAIN_CPU_CLOCK) MDRV_CPU_PROGRAM_MAP(main_map,0) - MDRV_CPU_IO_MAP(main_iomap,0) + MDRV_CPU_IO_MAP(main_io_map,0) MDRV_CPU_VBLANK_INT(victory_vblank_interrupt,1) - MDRV_CPU_ADD(M6502,3579545/4) /* audio CPU */ - MDRV_CPU_PROGRAM_MAP(sound_map,0) + MDRV_CPU_ADD(M6502, VICTORY_AUDIO_CPU_CLOCK) + MDRV_CPU_PROGRAM_MAP(audio_map,0) MDRV_NVRAM_HANDLER(generic_0fill) /* video hardware */ - MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_UPDATE_BEFORE_VBLANK) + MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_UPDATE_BEFORE_VBLANK | VIDEO_ALWAYS_UPDATE) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) /* using the standard Exidy video parameters for now, needs to be confirmed */ MDRV_SCREEN_RAW_PARAMS(EXIDY_PIXEL_CLOCK, EXIDY_HTOTAL, EXIDY_HBEND, EXIDY_HBSTART, EXIDY_VTOTAL, EXIDY_VBEND, EXIDY_VBSTART) MDRV_PALETTE_LENGTH(64) MDRV_VIDEO_START(victory) - MDRV_VIDEO_EOF(victory) MDRV_VIDEO_UPDATE(victory) /* sound hardware */ diff --git a/src/mame/includes/exidy.h b/src/mame/includes/exidy.h index e2fd9d31d49..2bcb16d23b7 100644 --- a/src/mame/includes/exidy.h +++ b/src/mame/includes/exidy.h @@ -25,8 +25,13 @@ /*----------- defined in audio/exidy.c -----------*/ void *exidy_sh_start(int clock, const struct CustomSound_interface *config); +void exidy_sh_reset(void *token); + void *victory_sh_start(int clock, const struct CustomSound_interface *config); +void victory_sh_reset(void *token); + void *berzerk_sh_start(int clock, const struct CustomSound_interface *config); +void berzerk_sh_reset(void *token); WRITE8_HANDLER( exidy_shriot_w ); WRITE8_HANDLER( exidy_sfxctrl_w ); @@ -37,6 +42,10 @@ READ8_HANDLER( exidy_shriot_r ); READ8_HANDLER( exidy_sh8253_r ); READ8_HANDLER( exidy_sh6840_r ); +READ8_HANDLER( victory_sound_response_r ); +READ8_HANDLER( victory_sound_status_r ); +WRITE8_HANDLER( victory_sound_command_w ); + WRITE8_HANDLER( mtrap_voiceio_w ); READ8_HANDLER( mtrap_voiceio_r ); diff --git a/src/mame/video/victory.c b/src/mame/video/victory.c index 71c0dd5fa26..55e3d796a93 100644 --- a/src/mame/video/victory.c +++ b/src/mame/video/victory.c @@ -5,17 +5,17 @@ ***************************************************************************/ #include "driver.h" +#include "victory.h" /* globally-accessible storage */ +UINT8 *victory_videoram; UINT8 *victory_charram; /* local allocated storage */ +static UINT16 victory_paletteram[0x40]; /* 9 bits used */ static UINT8 *bgbitmap; static UINT8 *fgbitmap; -static UINT8 *bgdirty; -static UINT8 *chardirty; -static UINT8 *scandirty; static UINT8 *rram, *gram, *bram; /* interrupt, collision, and control states */ @@ -23,7 +23,6 @@ static UINT8 vblank_irq; static UINT8 fgcoll, fgcollx, fgcolly; static UINT8 bgcoll, bgcollx, bgcolly; static UINT8 scrollx, scrolly; -static UINT8 update_complete; static UINT8 video_control; /* microcode state */ @@ -44,7 +43,7 @@ static struct /* from what I can tell, this should be divided by 32, not 8 */ /* but the interrupt test does some precise timing, and fails */ /* if it's not 8 */ -#define MICRO_STATE_CLOCK_PERIOD ATTOTIME_IN_HZ(11827000/8) +#define MICRO_STATE_CLOCK_PERIOD ATTOTIME_IN_HZ(VICTORY_MICRO_STATE_CLOCK / 8) /* debugging constants */ @@ -79,25 +78,17 @@ VIDEO_START( victory ) bgbitmap = auto_malloc(256 * 256); fgbitmap = auto_malloc(256 * 256); - /* allocate dirty maps */ - bgdirty = auto_malloc(32 * 32); - chardirty = auto_malloc(256); - scandirty = auto_malloc(512); - - /* mark everything dirty */ - memset(bgdirty, 1, 32 * 32); - memset(chardirty, 1, 256); - memset(scandirty, 1, 512); - /* reset globals */ vblank_irq = 0; fgcoll = fgcollx = fgcolly = 0; bgcoll = bgcollx = bgcolly = 0; scrollx = scrolly = 0; - update_complete = 0; video_control = 0; memset(µ, 0, sizeof(micro)); micro.timer = timer_alloc(NULL, NULL); + + /* register for state saving */ + state_save_register_global_array(victory_paletteram); } @@ -120,55 +111,34 @@ static void victory_update_irq(void) INTERRUPT_GEN( victory_vblank_interrupt ) { vblank_irq = 1; + victory_update_irq(); - logerror("------------- VBLANK ----------------\n"); } /************************************* * - * Video RAM write - * - *************************************/ - -WRITE8_HANDLER( victory_videoram_w ) -{ - if (videoram[offset] != data) - { - videoram[offset] = data; - bgdirty[offset] = 1; - } -} - - - -/************************************* - * - * Character RAM write - * - *************************************/ - -WRITE8_HANDLER( victory_charram_w ) -{ - if (victory_charram[offset] != data) - { - victory_charram[offset] = data; - chardirty[(offset / 8) % 256] = 1; - } -} - - - -/************************************* - * - * Palette RAM write + * Palette handling * *************************************/ WRITE8_HANDLER( victory_paletteram_w ) { - palette_set_color_rgb(Machine, offset & 0x3f, pal3bit(((offset & 0x80) >> 5) | ((data & 0xc0) >> 6)), pal3bit(data >> 0), pal3bit(data >> 3)); + victory_paletteram[offset & 0x3f] = ((offset & 0x80) << 1) | data; +} + + +static void set_palette(running_machine *machine) +{ + offs_t offs; + + for (offs = 0; offs < 0x40; offs++) + { + UINT16 data = victory_paletteram[offs]; + + palette_set_color_rgb(machine, offs, pal3bit(data >> 6), pal3bit(data >> 0), pal3bit(data >> 3)); + } } @@ -185,12 +155,12 @@ READ8_HANDLER( victory_video_control_r ) switch (offset) { - case 0: /* 5XFIQ */ + case 0x00: /* 5XFIQ */ result = fgcollx; if (LOG_COLLISION) logerror("%04X:5XFIQ read = %02X\n", activecpu_get_previouspc(), result); return result; - case 1: /* 5CLFIQ */ + case 0x01: /* 5CLFIQ */ result = fgcolly; if (fgcoll) { @@ -200,12 +170,12 @@ READ8_HANDLER( victory_video_control_r ) if (LOG_COLLISION) logerror("%04X:5CLFIQ read = %02X\n", activecpu_get_previouspc(), result); return result; - case 2: /* 5BACKX */ + case 0x02: /* 5BACKX */ result = bgcollx & 0xfc; if (LOG_COLLISION) logerror("%04X:5BACKX read = %02X\n", activecpu_get_previouspc(), result); return result; - case 3: /* 5BACKY */ + case 0x03: /* 5BACKY */ result = bgcolly; if (bgcoll) { @@ -215,7 +185,7 @@ READ8_HANDLER( victory_video_control_r ) if (LOG_COLLISION) logerror("%04X:5BACKY read = %02X\n", activecpu_get_previouspc(), result); return result; - case 4: /* 5STAT */ + case 0x04: /* 5STAT */ // D7 = BUSY (9A1) -- microcode // D6 = 5FCIRQ (3B1) // D5 = 5VIRQ @@ -249,12 +219,12 @@ WRITE8_HANDLER( victory_video_control_w ) { switch (offset) { - case 0: /* LOAD IL */ + case 0x00: /* LOAD IL */ if (LOG_MICROCODE) logerror("%04X:IL=%02X\n", activecpu_get_previouspc(), data); micro.i = (micro.i & 0xff00) | (data & 0x00ff); break; - case 1: /* LOAD IH */ + case 0x01: /* LOAD IH */ if (LOG_MICROCODE) logerror("%04X:IH=%02X\n", activecpu_get_previouspc(), data); micro.i = (micro.i & 0x00ff) | ((data << 8) & 0xff00); if (micro.cmdlo == 5) @@ -264,7 +234,7 @@ WRITE8_HANDLER( victory_video_control_w ) } break; - case 2: /* LOAD CMD */ + case 0x02: /* LOAD CMD */ if (LOG_MICROCODE) logerror("%04X:CMD=%02X\n", activecpu_get_previouspc(), data); micro.cmd = data; micro.cmdlo = data & 7; @@ -279,12 +249,12 @@ WRITE8_HANDLER( victory_video_control_w ) } break; - case 3: /* LOAD G */ + case 0x03: /* LOAD G */ if (LOG_MICROCODE) logerror("%04X:G=%02X\n", activecpu_get_previouspc(), data); micro.g = data; break; - case 4: /* LOAD X */ + case 0x04: /* LOAD X */ if (LOG_MICROCODE) logerror("%04X:X=%02X\n", activecpu_get_previouspc(), data); micro.xp = data; if (micro.cmdlo == 3) @@ -294,7 +264,7 @@ WRITE8_HANDLER( victory_video_control_w ) } break; - case 5: /* LOAD Y */ + case 0x05: /* LOAD Y */ if (LOG_MICROCODE) logerror("%04X:Y=%02X\n", activecpu_get_previouspc(), data); micro.yp = data; if (micro.cmdlo == 4) @@ -304,12 +274,12 @@ WRITE8_HANDLER( victory_video_control_w ) } break; - case 6: /* LOAD R */ + case 0x06: /* LOAD R */ if (LOG_MICROCODE) logerror("%04X:R=%02X\n", activecpu_get_previouspc(), data); micro.r = data; break; - case 7: /* LOAD B */ + case 0x07: /* LOAD B */ if (LOG_MICROCODE) logerror("%04X:B=%02X\n", activecpu_get_previouspc(), data); micro.b = data; if (micro.cmdlo == 2) @@ -324,17 +294,17 @@ WRITE8_HANDLER( victory_video_control_w ) } break; - case 8: /* SCROLLX */ + case 0x08: /* SCROLLX */ if (LOG_MICROCODE) logerror("%04X:SCROLLX write = %02X\n", activecpu_get_previouspc(), data); scrollx = data; break; - case 9: /* SCROLLY */ + case 0x09: /* SCROLLY */ if (LOG_MICROCODE) logerror("%04X:SCROLLY write = %02X\n", activecpu_get_previouspc(), data); scrolly = data; break; - case 10: /* CONTROL */ + case 0x0a: /* CONTROL */ // D7 = HLMBK // D6 = VLMBK // D5 = BIRQEA @@ -346,7 +316,7 @@ WRITE8_HANDLER( victory_video_control_w ) video_control = data; break; - case 11: /* CLRVIRQ */ + case 0x0b: /* CLRVIRQ */ if (LOG_MICROCODE) logerror("%04X:CLRVIRQ write = %02X\n", activecpu_get_previouspc(), data); vblank_irq = 0; victory_update_irq(); @@ -601,7 +571,6 @@ static int command2(void) if (micro.cmd & 0x40) rram[addr] = micro.r; - scandirty[addr >> 5] = 1; count_states(3); return 0; } @@ -708,11 +677,6 @@ static int command3(void) } } - /* mark scanlines dirty */ - sy = micro.yp; - for (y = 0; y < ycount; y++) - scandirty[sy++ & 0xff] = 1; - count_states(3 + (2 + 2 * ycount) * xcount); return micro.cmd & 0x80; @@ -858,7 +822,6 @@ static int command5(void) bram[addr + 1] ^= micro.b << nshift; rram[addr + 0] ^= micro.r >> shift; rram[addr + 1] ^= micro.r << nshift; - scandirty[y] = 1; acc += i; if (acc & 0x100) @@ -895,7 +858,6 @@ static int command5(void) bram[addr + 1] ^= micro.b << nshift; rram[addr + 0] ^= micro.r >> shift; rram[addr + 1] ^= micro.r << nshift; - scandirty[y] = 1; acc += i; if (acc & 0x100) @@ -962,8 +924,6 @@ static int command6(void) bram[daddr] = bram[saddr]; if (micro.cmd & 0x40) rram[daddr] = rram[saddr]; - - scandirty[daddr >> 5] = 1; } count_states(3 + 2 * (64 - (micro.r & 31) * 2)); @@ -1047,7 +1007,6 @@ static int command7(void) count_states(4); - scandirty[micro.yp] = 1; return micro.cmd & 0x80; } @@ -1062,37 +1021,28 @@ static void update_background(void) { int x, y, row, offs; - /* update the background and any dirty characters in it */ for (y = offs = 0; y < 32; y++) for (x = 0; x < 32; x++, offs++) { - int code = videoram[offs]; + int code = victory_videoram[offs]; - /* see if the videoram or character RAM has changed, redraw it */ - if (bgdirty[offs] || chardirty[code]) + for (row = 0; row < 8; row++) { - for (row = 0; row < 8; row++) - { - UINT8 pix2 = victory_charram[0x0000 + 8 * code + row]; - UINT8 pix1 = victory_charram[0x0800 + 8 * code + row]; - UINT8 pix0 = victory_charram[0x1000 + 8 * code + row]; - UINT8 *dst = &bgbitmap[(y * 8 + row) * 256 + x * 8]; + UINT8 pix2 = victory_charram[0x0000 + 8 * code + row]; + UINT8 pix1 = victory_charram[0x0800 + 8 * code + row]; + UINT8 pix0 = victory_charram[0x1000 + 8 * code + row]; + UINT8 *dst = &bgbitmap[(y * 8 + row) * 256 + x * 8]; - *dst++ = ((pix2 & 0x80) >> 5) | ((pix1 & 0x80) >> 6) | ((pix0 & 0x80) >> 7); - *dst++ = ((pix2 & 0x40) >> 4) | ((pix1 & 0x40) >> 5) | ((pix0 & 0x40) >> 6); - *dst++ = ((pix2 & 0x20) >> 3) | ((pix1 & 0x20) >> 4) | ((pix0 & 0x20) >> 5); - *dst++ = ((pix2 & 0x10) >> 2) | ((pix1 & 0x10) >> 3) | ((pix0 & 0x10) >> 4); - *dst++ = ((pix2 & 0x08) >> 1) | ((pix1 & 0x08) >> 2) | ((pix0 & 0x08) >> 3); - *dst++ = ((pix2 & 0x04) ) | ((pix1 & 0x04) >> 1) | ((pix0 & 0x04) >> 2); - *dst++ = ((pix2 & 0x02) << 1) | ((pix1 & 0x02) ) | ((pix0 & 0x02) >> 1); - *dst++ = ((pix2 & 0x01) << 2) | ((pix1 & 0x01) << 1) | ((pix0 & 0x01) ); - } - bgdirty[offs] = 0; + *dst++ = ((pix2 & 0x80) >> 5) | ((pix1 & 0x80) >> 6) | ((pix0 & 0x80) >> 7); + *dst++ = ((pix2 & 0x40) >> 4) | ((pix1 & 0x40) >> 5) | ((pix0 & 0x40) >> 6); + *dst++ = ((pix2 & 0x20) >> 3) | ((pix1 & 0x20) >> 4) | ((pix0 & 0x20) >> 5); + *dst++ = ((pix2 & 0x10) >> 2) | ((pix1 & 0x10) >> 3) | ((pix0 & 0x10) >> 4); + *dst++ = ((pix2 & 0x08) >> 1) | ((pix1 & 0x08) >> 2) | ((pix0 & 0x08) >> 3); + *dst++ = ((pix2 & 0x04) ) | ((pix1 & 0x04) >> 1) | ((pix0 & 0x04) >> 2); + *dst++ = ((pix2 & 0x02) << 1) | ((pix1 & 0x02) ) | ((pix0 & 0x02) >> 1); + *dst++ = ((pix2 & 0x01) << 2) | ((pix1 & 0x01) << 1) | ((pix0 & 0x01) ); } } - - /* reset the char dirty array */ - memset(chardirty, 0, 256); } @@ -1106,30 +1056,27 @@ static void update_foreground(void) { int x, y; - /* update the foreground's dirty scanlines */ for (y = 0; y < 256; y++) - if (scandirty[y]) + { + UINT8 *dst = &fgbitmap[y * 256]; + + /* assemble the RGB bits for each 8-pixel chunk */ + for (x = 0; x < 256; x += 8) { - UINT8 *dst = &fgbitmap[y * 256]; + UINT8 g = gram[y * 32 + x / 8]; + UINT8 b = bram[y * 32 + x / 8]; + UINT8 r = rram[y * 32 + x / 8]; - /* assemble the RGB bits for each 8-pixel chunk */ - for (x = 0; x < 256; x += 8) - { - UINT8 g = gram[y * 32 + x / 8]; - UINT8 b = bram[y * 32 + x / 8]; - UINT8 r = rram[y * 32 + x / 8]; - - *dst++ = ((r & 0x80) >> 5) | ((b & 0x80) >> 6) | ((g & 0x80) >> 7); - *dst++ = ((r & 0x40) >> 4) | ((b & 0x40) >> 5) | ((g & 0x40) >> 6); - *dst++ = ((r & 0x20) >> 3) | ((b & 0x20) >> 4) | ((g & 0x20) >> 5); - *dst++ = ((r & 0x10) >> 2) | ((b & 0x10) >> 3) | ((g & 0x10) >> 4); - *dst++ = ((r & 0x08) >> 1) | ((b & 0x08) >> 2) | ((g & 0x08) >> 3); - *dst++ = ((r & 0x04) ) | ((b & 0x04) >> 1) | ((g & 0x04) >> 2); - *dst++ = ((r & 0x02) << 1) | ((b & 0x02) ) | ((g & 0x02) >> 1); - *dst++ = ((r & 0x01) << 2) | ((b & 0x01) << 1) | ((g & 0x01) ); - } - scandirty[y] = 0; + *dst++ = ((r & 0x80) >> 5) | ((b & 0x80) >> 6) | ((g & 0x80) >> 7); + *dst++ = ((r & 0x40) >> 4) | ((b & 0x40) >> 5) | ((g & 0x40) >> 6); + *dst++ = ((r & 0x20) >> 3) | ((b & 0x20) >> 4) | ((g & 0x20) >> 5); + *dst++ = ((r & 0x10) >> 2) | ((b & 0x10) >> 3) | ((g & 0x10) >> 4); + *dst++ = ((r & 0x08) >> 1) | ((b & 0x08) >> 2) | ((g & 0x08) >> 3); + *dst++ = ((r & 0x04) ) | ((b & 0x04) >> 1) | ((g & 0x04) >> 2); + *dst++ = ((r & 0x02) << 1) | ((b & 0x02) ) | ((g & 0x02) >> 1); + *dst++ = ((r & 0x01) << 2) | ((b & 0x01) << 1) | ((g & 0x01) ); } + } } @@ -1143,50 +1090,6 @@ static TIMER_CALLBACK( bgcoll_irq_callback ) -/************************************* - * - * End-of-frame callback - * - *************************************/ - -VIDEO_EOF( victory ) -{ - int bgcollmask = (video_control & 4) ? 4 : 7; - int count = 0; - int x, y; - - /* if we already did it, skip it */ - if (update_complete) - { - update_complete = 0; - return; - } - update_complete = 0; - - /* update the foreground & background */ - update_foreground(); - update_background(); - - /* blend the bitmaps and do collision detection */ - for (y = 0; y < 256; y++) - { - int sy = (scrolly + y) & 255; - UINT8 *fg = &fgbitmap[y * 256]; - UINT8 *bg = &bgbitmap[sy * 256]; - - /* do the blending */ - for (x = 0; x < 256; x++) - { - int fpix = *fg++; - int bpix = bg[(x + scrollx) & 255]; - if (fpix && (bpix & bgcollmask) && count++ < 128) - timer_set(video_screen_get_time_until_pos(0, y, x), NULL, x | (y << 8), bgcoll_irq_callback); - } - } -} - - - /************************************* * * Standard screen refresh callback @@ -1199,6 +1102,9 @@ VIDEO_UPDATE( victory ) int count = 0; int x, y; + /* copy the palette from palette RAM */ + set_palette(machine); + /* update the foreground & background */ update_foreground(); update_background(); @@ -1206,7 +1112,7 @@ VIDEO_UPDATE( victory ) /* blend the bitmaps and do collision detection */ for (y = 0; y < 256; y++) { - int sy = (scrolly + y) & 255; + UINT8 sy = scrolly + y; UINT8 *fg = &fgbitmap[y * 256]; UINT8 *bg = &bgbitmap[sy * 256]; UINT8 scanline[256]; @@ -1225,7 +1131,5 @@ VIDEO_UPDATE( victory ) draw_scanline8(bitmap, 0, y, 256, scanline, machine->pens, -1); } - /* indicate that we already did collision detection */ - update_complete = 1; return 0; }