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.
This commit is contained in:
Zsolt Vasvari 2008-01-13 06:14:20 +00:00
parent f44732e5af
commit 120a6070e8
9 changed files with 418 additions and 485 deletions

View File

@ -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); }

View File

@ -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 */

View File

@ -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 */

View File

@ -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,
};

View File

@ -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:

View File

@ -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
};

View File

@ -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 */

View File

@ -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 );

View File

@ -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(&micro, 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;
}