mirror of
https://github.com/holub/mame
synced 2025-06-05 12:26:35 +03:00
TMS3203x core updates:
* fixed interrupt handling * added support for edge-triggered interrupts on '32 * expanded interrupt support for the '32 * updated drivers using TMS3203x core to deassert interrupts * added externally accessible functions for converting '3x floating point format * updated gaelco3d driver to use new functions Zeus2 (+related) updates: * fixed save states for DCS games * cleaned up Zeus2 waveram handling * added Zeus2 save state support * added preliminary model and quad rendering support for Zeus2 * added support to timekpr for the ZPRAM used on Zeus2 * hooked up ZPRAM in Zeus2 games * hooked up controls in Zeus2 games * updated poly.c to ensure it is idle before saving state
This commit is contained in:
parent
8d6c62b976
commit
2f8231e10a
@ -717,7 +717,6 @@ static void adsp2100_init(int index, int clock, const void *config, int (*irqcal
|
||||
state_save_register_item("adsp2100", index, adsp2100.fl0);
|
||||
state_save_register_item("adsp2100", index, adsp2100.fl1);
|
||||
state_save_register_item("adsp2100", index, adsp2100.fl2);
|
||||
|
||||
state_save_register_item("adsp2100", index, adsp2100.idma_addr);
|
||||
state_save_register_item("adsp2100", index, adsp2100.idma_cache);
|
||||
state_save_register_item("adsp2100", index, adsp2100.idma_offs);
|
||||
@ -725,7 +724,6 @@ static void adsp2100_init(int index, int clock, const void *config, int (*irqcal
|
||||
state_save_register_item("adsp2100", index, adsp2100.imask);
|
||||
state_save_register_item("adsp2100", index, adsp2100.icntl);
|
||||
state_save_register_item("adsp2100", index, adsp2100.ifc);
|
||||
|
||||
state_save_register_item_array("adsp2100", index, adsp2100.irq_state);
|
||||
state_save_register_item_array("adsp2100", index, adsp2100.irq_latch);
|
||||
state_save_register_item("adsp2100", index, adsp2100.interrupt_cycles);
|
||||
|
@ -1793,7 +1793,7 @@ static void float_imm(void)
|
||||
|
||||
static void idle(void)
|
||||
{
|
||||
tms32031.is_idling = 1;
|
||||
tms32031.is_idling = TRUE;
|
||||
IREG(TMR_ST) |= GIEFLAG;
|
||||
check_irqs();
|
||||
if (tms32031.is_idling)
|
||||
@ -2541,7 +2541,7 @@ static void rtps_reg(void)
|
||||
IREG(TMR_RE) = tms32031.pc;
|
||||
IREG(TMR_ST) |= RMFLAG;
|
||||
tms32031_icount -= 3*2;
|
||||
tms32031.delayed = 1;
|
||||
tms32031.delayed = TRUE;
|
||||
}
|
||||
|
||||
static void rtps_dir(void)
|
||||
@ -2551,7 +2551,7 @@ static void rtps_dir(void)
|
||||
IREG(TMR_RE) = tms32031.pc;
|
||||
IREG(TMR_ST) |= RMFLAG;
|
||||
tms32031_icount -= 3*2;
|
||||
tms32031.delayed = 1;
|
||||
tms32031.delayed = TRUE;
|
||||
}
|
||||
|
||||
static void rtps_ind(void)
|
||||
@ -2561,7 +2561,7 @@ static void rtps_ind(void)
|
||||
IREG(TMR_RE) = tms32031.pc;
|
||||
IREG(TMR_ST) |= RMFLAG;
|
||||
tms32031_icount -= 3*2;
|
||||
tms32031.delayed = 1;
|
||||
tms32031.delayed = TRUE;
|
||||
}
|
||||
|
||||
static void rtps_imm(void)
|
||||
@ -2571,7 +2571,7 @@ static void rtps_imm(void)
|
||||
IREG(TMR_RE) = tms32031.pc;
|
||||
IREG(TMR_ST) |= RMFLAG;
|
||||
tms32031_icount -= 3*2;
|
||||
tms32031.delayed = 1;
|
||||
tms32031.delayed = TRUE;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*/
|
||||
@ -5308,7 +5308,7 @@ static void ldizuf_imm(void)
|
||||
|
||||
INLINE void execute_delayed(UINT32 newpc)
|
||||
{
|
||||
tms32031.delayed = 1;
|
||||
tms32031.delayed = TRUE;
|
||||
|
||||
execute_one();
|
||||
execute_one();
|
||||
@ -5317,10 +5317,10 @@ INLINE void execute_delayed(UINT32 newpc)
|
||||
tms32031.pc = newpc;
|
||||
UPDATEPC(tms32031.pc);
|
||||
|
||||
tms32031.delayed = 0;
|
||||
tms32031.delayed = FALSE;
|
||||
if (tms32031.irq_pending)
|
||||
{
|
||||
tms32031.irq_pending = 0;
|
||||
tms32031.irq_pending = FALSE;
|
||||
check_irqs();
|
||||
}
|
||||
}
|
||||
@ -5473,7 +5473,12 @@ static void trap(int trapnum)
|
||||
{
|
||||
WMEM(++IREG(TMR_SP), tms32031.pc);
|
||||
IREG(TMR_ST) &= ~GIEFLAG;
|
||||
tms32031.pc = tms32031.mcu_mode ? (0x809fc0 + trapnum) : RMEM(trapnum);
|
||||
if (tms32031.is_32032)
|
||||
tms32031.pc = RMEM(((IREG(TMR_IF) >> 16) << 8) + trapnum);
|
||||
else if (tms32031.mcu_mode)
|
||||
tms32031.pc = 0x809fc0 + trapnum;
|
||||
else
|
||||
tms32031.pc = RMEM(trapnum);
|
||||
UPDATEPC(tms32031.pc);
|
||||
tms32031_icount -= 4*2;
|
||||
}
|
||||
@ -5494,6 +5499,7 @@ static void retic_reg(void)
|
||||
UPDATEPC(tms32031.pc);
|
||||
IREG(TMR_ST) |= GIEFLAG;
|
||||
tms32031_icount -= 3*2;
|
||||
check_irqs();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,11 +95,12 @@ typedef struct
|
||||
UINT32 bkmask;
|
||||
|
||||
/* internal stuff */
|
||||
UINT32 ppc;
|
||||
UINT32 op;
|
||||
UINT16 irq_state;
|
||||
UINT8 delayed;
|
||||
UINT8 irq_pending;
|
||||
UINT8 mcu_mode;
|
||||
UINT8 is_32032;
|
||||
UINT8 is_idling;
|
||||
int interrupt_cycles;
|
||||
|
||||
@ -167,7 +168,6 @@ typedef union int_double
|
||||
} int_double;
|
||||
|
||||
|
||||
#if 0
|
||||
static float dsp_to_float(union genreg *fp)
|
||||
{
|
||||
int_double id;
|
||||
@ -187,7 +187,6 @@ static float dsp_to_float(union genreg *fp)
|
||||
}
|
||||
return id.f[0];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static double dsp_to_double(union genreg *fp)
|
||||
@ -252,6 +251,46 @@ static void double_to_dsp(double val, union genreg *result)
|
||||
}
|
||||
|
||||
|
||||
float convert_tms3203x_fp_to_float(UINT32 floatdata)
|
||||
{
|
||||
union genreg gen;
|
||||
|
||||
SET_MANTISSA(&gen, floatdata << 8);
|
||||
SET_EXPONENT(&gen, (INT32)floatdata >> 24);
|
||||
|
||||
return dsp_to_float(&gen);
|
||||
}
|
||||
|
||||
|
||||
double convert_tms3203x_fp_to_double(UINT32 floatdata)
|
||||
{
|
||||
union genreg gen;
|
||||
|
||||
SET_MANTISSA(&gen, floatdata << 8);
|
||||
SET_EXPONENT(&gen, (INT32)floatdata >> 24);
|
||||
|
||||
return dsp_to_double(&gen);
|
||||
}
|
||||
|
||||
|
||||
UINT32 convert_float_to_tms3203x_fp(float fval)
|
||||
{
|
||||
union genreg gen;
|
||||
|
||||
double_to_dsp(fval, &gen);
|
||||
return (EXPONENT(&gen) << 24) | ((UINT32)MANTISSA(&gen) >> 8);
|
||||
}
|
||||
|
||||
|
||||
UINT32 convert_double_to_tms3203x_fp(double dval)
|
||||
{
|
||||
union genreg gen;
|
||||
|
||||
double_to_dsp(dval, &gen);
|
||||
return (EXPONENT(&gen) << 24) | ((UINT32)MANTISSA(&gen) >> 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
EXECEPTION HANDLING
|
||||
@ -274,51 +313,64 @@ INLINE void invalid_instruction(UINT32 op)
|
||||
|
||||
static void check_irqs(void)
|
||||
{
|
||||
int validints = IREG(TMR_IF) & IREG(TMR_IE) & 0x07ff;
|
||||
if (validints && (IREG(TMR_ST) & GIEFLAG))
|
||||
{
|
||||
int whichtrap = 0;
|
||||
int i;
|
||||
int whichtrap = 0;
|
||||
UINT16 validints;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 11; i++)
|
||||
if (validints & (1 << i))
|
||||
{
|
||||
whichtrap = i + 1;
|
||||
break;
|
||||
}
|
||||
/* determine if we have any live interrupts */
|
||||
validints = IREG(TMR_IF) & IREG(TMR_IE) & 0x0fff;
|
||||
if (validints == 0 || (IREG(TMR_ST) & GIEFLAG) == 0)
|
||||
return;
|
||||
|
||||
if (whichtrap)
|
||||
/* find the lowest signalled value */
|
||||
for (i = 0; i < 12; i++)
|
||||
if (validints & (1 << i))
|
||||
{
|
||||
tms32031.is_idling = 0;
|
||||
if (!tms32031.delayed)
|
||||
{
|
||||
trap(whichtrap);
|
||||
|
||||
/* for internal sources, clear the interrupt when taken */
|
||||
if (whichtrap > 4)
|
||||
IREG(TMR_IF) &= ~(1 << (whichtrap - 1));
|
||||
}
|
||||
else
|
||||
tms32031.irq_pending = 1;
|
||||
whichtrap = i + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* no longer idling if we get here */
|
||||
tms32031.is_idling = FALSE;
|
||||
if (!tms32031.delayed)
|
||||
{
|
||||
UINT16 intmask = 1 << (whichtrap - 1);
|
||||
|
||||
/* bit in IF is cleared when interrupt is taken */
|
||||
IREG(TMR_IF) &= ~intmask;
|
||||
trap(whichtrap);
|
||||
|
||||
/* external interrupts are level-sensitive on the '31 and can be
|
||||
configured as such on the '32; in that case, if the external
|
||||
signal is still high, we need to retrigger the interrupt */
|
||||
if (whichtrap < 4 && (!tms32031.is_32032 || (IREG(TMR_ST) & 0x4000) == 0))
|
||||
IREG(TMR_IF) |= tms32031.irq_state & intmask;
|
||||
}
|
||||
else
|
||||
tms32031.irq_pending = TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void set_irq_line(int irqline, int state)
|
||||
{
|
||||
if (irqline < 11)
|
||||
{
|
||||
/* update the state */
|
||||
if (state == ASSERT_LINE)
|
||||
IREG(TMR_IF) |= 1 << irqline;
|
||||
else
|
||||
IREG(TMR_IF) &= ~(1 << irqline);
|
||||
UINT16 oldstate = tms32031.irq_state;
|
||||
UINT16 intmask = 1 << irqline;
|
||||
|
||||
/* ignore anything out of range */
|
||||
if (irqline >= 12)
|
||||
return;
|
||||
|
||||
/* check for IRQs */
|
||||
if (state != CLEAR_LINE)
|
||||
check_irqs();
|
||||
/* update the external state */
|
||||
if (state == ASSERT_LINE)
|
||||
{
|
||||
tms32031.irq_state |= intmask;
|
||||
IREG(TMR_IF) |= intmask;
|
||||
}
|
||||
else
|
||||
tms32031.irq_state &= ~intmask;
|
||||
|
||||
/* check for IRQs */
|
||||
check_irqs();
|
||||
}
|
||||
|
||||
|
||||
@ -376,8 +428,8 @@ static void tms32031_init(int index, int clock, const void *_config, int (*irqca
|
||||
state_save_register_generic("tms32031", index, namebuf, tms32031.r[i].i8, UINT8, 8);
|
||||
}
|
||||
state_save_register_item("tms32031", index, tms32031.bkmask);
|
||||
state_save_register_item("tms32031", index, tms32031.ppc);
|
||||
state_save_register_item("tms32031", index, tms32031.op);
|
||||
state_save_register_item("tms32031", index, tms32031.irq_state);
|
||||
state_save_register_item("tms32031", index, tms32031.delayed);
|
||||
state_save_register_item("tms32031", index, tms32031.irq_pending);
|
||||
state_save_register_item("tms32031", index, tms32031.mcu_mode);
|
||||
@ -391,14 +443,15 @@ static void tms32031_reset(void)
|
||||
/* if we have a config struct, get the boot ROM address */
|
||||
if (tms32031.bootoffset)
|
||||
{
|
||||
tms32031.mcu_mode = 1;
|
||||
tms32031.mcu_mode = TRUE;
|
||||
tms32031.pc = boot_loader(tms32031.bootoffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
tms32031.mcu_mode = 0;
|
||||
tms32031.mcu_mode = FALSE;
|
||||
tms32031.pc = RMEM(0);
|
||||
}
|
||||
tms32031.is_32032 = FALSE;
|
||||
|
||||
/* reset some registers */
|
||||
IREG(TMR_IE) = 0;
|
||||
@ -407,8 +460,14 @@ static void tms32031_reset(void)
|
||||
IREG(TMR_IOF) = 0;
|
||||
|
||||
/* reset internal stuff */
|
||||
tms32031.delayed = tms32031.irq_pending = 0;
|
||||
tms32031.is_idling = 0;
|
||||
tms32031.delayed = tms32031.irq_pending = FALSE;
|
||||
tms32031.is_idling = FALSE;
|
||||
}
|
||||
|
||||
static void tms32032_reset(void)
|
||||
{
|
||||
tms32031_reset();
|
||||
tms32031.is_32032 = TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -465,10 +524,10 @@ static int tms32031_execute(int cycles)
|
||||
IREG(TMR_ST) &= ~RMFLAG;
|
||||
if (tms32031.delayed)
|
||||
{
|
||||
tms32031.delayed = 0;
|
||||
tms32031.delayed = FALSE;
|
||||
if (tms32031.irq_pending)
|
||||
{
|
||||
tms32031.irq_pending = 0;
|
||||
tms32031.irq_pending = FALSE;
|
||||
check_irqs();
|
||||
}
|
||||
}
|
||||
@ -593,6 +652,7 @@ static void tms32031_set_info(UINT32 state, cpuinfo *info)
|
||||
case CPUINFO_INT_INPUT_STATE + TMS32031_TINT0: set_irq_line(TMS32031_TINT0, info->i); break;
|
||||
case CPUINFO_INT_INPUT_STATE + TMS32031_TINT1: set_irq_line(TMS32031_TINT1, info->i); break;
|
||||
case CPUINFO_INT_INPUT_STATE + TMS32031_DINT: set_irq_line(TMS32031_DINT, info->i); break;
|
||||
case CPUINFO_INT_INPUT_STATE + TMS32031_DINT1: set_irq_line(TMS32031_DINT1, info->i); break;
|
||||
|
||||
case CPUINFO_INT_PC:
|
||||
case CPUINFO_INT_REGISTER + TMS32031_PC: tms32031.pc = info->i; break;
|
||||
@ -692,8 +752,9 @@ void tms32031_get_info(UINT32 state, cpuinfo *info)
|
||||
case CPUINFO_INT_INPUT_STATE + TMS32031_TINT0: info->i = (IREG(TMR_IF) & (1 << TMS32031_TINT0)) ? ASSERT_LINE : CLEAR_LINE; break;
|
||||
case CPUINFO_INT_INPUT_STATE + TMS32031_TINT1: info->i = (IREG(TMR_IF) & (1 << TMS32031_TINT1)) ? ASSERT_LINE : CLEAR_LINE; break;
|
||||
case CPUINFO_INT_INPUT_STATE + TMS32031_DINT: info->i = (IREG(TMR_IF) & (1 << TMS32031_DINT)) ? ASSERT_LINE : CLEAR_LINE; break;
|
||||
case CPUINFO_INT_INPUT_STATE + TMS32031_DINT1: info->i = (IREG(TMR_IF) & (1 << TMS32031_DINT1)) ? ASSERT_LINE : CLEAR_LINE; break;
|
||||
|
||||
case CPUINFO_INT_PREVIOUSPC: info->i = tms32031.ppc; break;
|
||||
case CPUINFO_INT_PREVIOUSPC: /* not implemented */ break;
|
||||
|
||||
case CPUINFO_INT_PC:
|
||||
case CPUINFO_INT_REGISTER + TMS32031_PC: info->i = tms32031.pc; break;
|
||||
@ -819,6 +880,7 @@ void tms32032_get_info(UINT32 state, cpuinfo *info)
|
||||
switch (state)
|
||||
{
|
||||
/* --- the following bits of info are returned as pointers to data or functions --- */
|
||||
case CPUINFO_PTR_RESET: info->reset = tms32032_reset; break;
|
||||
case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_internal_32032; break;
|
||||
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
|
@ -59,6 +59,8 @@ enum
|
||||
#define TMS32031_TINT0 8 /* timer 0 interrupt */
|
||||
#define TMS32031_TINT1 9 /* timer 1 interrupt */
|
||||
#define TMS32031_DINT 10 /* DMA interrupt */
|
||||
#define TMS32031_DINT0 10 /* DMA 0 interrupt (32032 only) */
|
||||
#define TMS32031_DINT1 11 /* DMA 1 interrupt (32032 only) */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
@ -68,4 +70,9 @@ enum
|
||||
extern void tms32031_get_info(UINT32 state, cpuinfo *info);
|
||||
extern void tms32032_get_info(UINT32 state, cpuinfo *info);
|
||||
|
||||
extern float convert_tms3203x_fp_to_float(UINT32 floatdata);
|
||||
extern double convert_tms3203x_fp_to_double(UINT32 floatdata);
|
||||
extern UINT32 convert_float_to_tms3203x_fp(float fval);
|
||||
extern UINT32 convert_double_to_tms3203x_fp(double dval);
|
||||
|
||||
#endif /* _TMS32031_H */
|
||||
|
@ -268,6 +268,19 @@ void timekeeper_init( int chip, int type, UINT8 *data )
|
||||
c->offset_flags = 0x1ff0;
|
||||
c->size = 0x2000;
|
||||
break;
|
||||
case TIMEKEEPER_MIDZEUS2:
|
||||
c->offset_control = 0x7ff8;
|
||||
c->offset_seconds = 0x7ff9;
|
||||
c->offset_minutes = 0x7ffa;
|
||||
c->offset_hours = 0x7ffb;
|
||||
c->offset_day = 0x7ffc;
|
||||
c->offset_date = 0x7ffd;
|
||||
c->offset_month = 0x7ffe;
|
||||
c->offset_year = 0x7fff;
|
||||
c->offset_century = -1;
|
||||
c->offset_flags = -1;
|
||||
c->size = 0x8000;
|
||||
break;
|
||||
}
|
||||
|
||||
if( data == NULL )
|
||||
@ -383,6 +396,18 @@ static void timekeeper_write( UINT32 chip, offs_t offset, UINT8 data )
|
||||
c->data[ offset ] = data;
|
||||
}
|
||||
|
||||
/* 8bit memory handlers */
|
||||
|
||||
READ8_HANDLER( timekeeper_0_r )
|
||||
{
|
||||
return timekeeper_read(0, offset);
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( timekeeper_0_w )
|
||||
{
|
||||
timekeeper_write(0, offset, data);
|
||||
}
|
||||
|
||||
/* 16bit memory handlers */
|
||||
|
||||
static UINT16 timekeeper_msb16_read( UINT32 chip, offs_t offset, UINT16 mem_mask )
|
||||
|
@ -15,11 +15,17 @@ extern void timekeeper_init( int chip, int type, UINT8 *data );
|
||||
#define TIMEKEEPER_M48T58 ( 1 )
|
||||
#define TIMEKEEPER_M48T02 ( 2 )
|
||||
#define TIMEKEEPER_MK48T08 ( 3 )
|
||||
#define TIMEKEEPER_MIDZEUS2 ( 4 )
|
||||
|
||||
/* nvram handlers */
|
||||
|
||||
extern NVRAM_HANDLER( timekeeper_0 );
|
||||
|
||||
/* 8bit memory handlers */
|
||||
|
||||
extern READ8_HANDLER( timekeeper_0_r );
|
||||
extern WRITE8_HANDLER( timekeeper_0_w );
|
||||
|
||||
/* 16bit memory handlers */
|
||||
|
||||
extern READ16_HANDLER( timekeeper_0_msb16_r );
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "poly.h"
|
||||
#include "eminline.h"
|
||||
#include "mame.h"
|
||||
#include "state.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
@ -205,6 +206,7 @@ struct _poly_manager
|
||||
static void **allocate_array(size_t *itemsize, UINT32 itemcount);
|
||||
static void free_array(void **array);
|
||||
static void *poly_item_callback(void *param, int threadid);
|
||||
static void poly_state_presave(void *param);
|
||||
|
||||
|
||||
|
||||
@ -356,6 +358,9 @@ poly_manager *poly_alloc(int max_polys, size_t extra_data_size, UINT8 flags)
|
||||
/* create the work queue */
|
||||
if (!(flags & POLYFLAG_NO_WORK_QUEUE))
|
||||
poly->queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ);
|
||||
|
||||
/* request a pre-save callback for synchronization */
|
||||
state_save_register_func_presave_ptr(poly_state_presave, poly);
|
||||
return poly;
|
||||
}
|
||||
|
||||
@ -1408,3 +1413,15 @@ static void *poly_item_callback(void *param, int threadid)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
poly_state_presave - pre-save callback to
|
||||
ensure everything is synced before saving
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void poly_state_presave(void *param)
|
||||
{
|
||||
poly_manager *poly = param;
|
||||
poly_wait(poly, "pre-save");
|
||||
}
|
||||
|
@ -466,6 +466,7 @@ static READ32_HANDLER( cage_from_main_r )
|
||||
logerror("%06X:CAGE read command = %04X\n", activecpu_get_pc(), cage_from_main);
|
||||
cpu_to_cage_ready = 0;
|
||||
update_control_lines();
|
||||
cpunum_set_input_line(cage_cpu, TMS32031_IRQ0, CLEAR_LINE);
|
||||
return cage_from_main;
|
||||
}
|
||||
|
||||
|
@ -891,6 +891,8 @@ static void dcs_register_state(void)
|
||||
state_save_register_global(transfer.writes_left);
|
||||
state_save_register_global(transfer.sum);
|
||||
state_save_register_global(transfer.fifo_entries);
|
||||
|
||||
state_save_register_global_pointer(dcs_sram, 0x8000*4 / sizeof(dcs_sram[0]));
|
||||
}
|
||||
|
||||
|
||||
@ -924,7 +926,6 @@ void dcs_init(void)
|
||||
|
||||
void dcs2_init(int dram_in_mb, offs_t polling_offset)
|
||||
{
|
||||
dcs_register_state();
|
||||
memset(&dcs, 0, sizeof(dcs));
|
||||
|
||||
/* find the DCS CPU and the sound ROMs */
|
||||
@ -978,6 +979,9 @@ void dcs2_init(int dram_in_mb, offs_t polling_offset)
|
||||
if (transfer.hle_enabled)
|
||||
transfer.watchdog = timer_alloc(transfer_watchdog_callback, NULL);
|
||||
|
||||
/* register for save states */
|
||||
dcs_register_state();
|
||||
|
||||
/* reset the system */
|
||||
dcs_reset(Machine, NULL, 0);
|
||||
}
|
||||
|
@ -133,7 +133,10 @@ static READ32_HANDLER( port2_r )
|
||||
static READ32_HANDLER( midvunit_adc_r )
|
||||
{
|
||||
if (!(control_data & 0x40))
|
||||
{
|
||||
cpunum_set_input_line(0, 3, CLEAR_LINE);
|
||||
return adc_data << adc_shift;
|
||||
}
|
||||
else
|
||||
logerror("adc_r without enabling reads!\n");
|
||||
return 0xffffffff;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "cpu/adsp2100/adsp2100.h"
|
||||
#include "includes/midzeus.h"
|
||||
#include "machine/midwayic.h"
|
||||
#include "machine/timekpr.h"
|
||||
#include "audio/dcs.h"
|
||||
|
||||
|
||||
@ -54,17 +55,32 @@ static TIMER_CALLBACK( invasn_gun_callback );
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static MACHINE_RESET( midzeus )
|
||||
static MACHINE_START( midzeus )
|
||||
{
|
||||
memcpy(ram_base, memory_region(REGION_USER1), 0x40000*4);
|
||||
|
||||
*(UINT32 *)ram_base *= 2;
|
||||
|
||||
timer[0] = timer_alloc(NULL, NULL);
|
||||
timer[1] = timer_alloc(NULL, NULL);
|
||||
|
||||
gun_timer[0] = timer_alloc(invasn_gun_callback, NULL);
|
||||
gun_timer[1] = timer_alloc(invasn_gun_callback, NULL);
|
||||
|
||||
state_save_register_global(gun_control);
|
||||
state_save_register_global(gun_irq_state);
|
||||
state_save_register_global_array(gun_x);
|
||||
state_save_register_global_array(gun_y);
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_START( midzeus2 )
|
||||
{
|
||||
timekeeper_init(0, TIMEKEEPER_MIDZEUS2, NULL);
|
||||
machine_start_midzeus(machine);
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_RESET( midzeus )
|
||||
{
|
||||
memcpy(ram_base, memory_region(REGION_USER1), 0x40000*4);
|
||||
*ram_base <<= 1;
|
||||
|
||||
cmos_protected = TRUE;
|
||||
}
|
||||
@ -73,20 +89,14 @@ static MACHINE_RESET( midzeus )
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* CMOS access
|
||||
* CMOS access (Zeus only)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static WRITE32_HANDLER( cmos_protect_w )
|
||||
{
|
||||
cmos_protected = FALSE;
|
||||
}
|
||||
|
||||
|
||||
static WRITE32_HANDLER( cmos_w )
|
||||
{
|
||||
if (!cmos_protected)
|
||||
COMBINE_DATA(generic_nvram32 + offset);
|
||||
COMBINE_DATA(&generic_nvram32[offset]);
|
||||
cmos_protected = TRUE;
|
||||
}
|
||||
|
||||
@ -97,6 +107,45 @@ static READ32_HANDLER( cmos_r )
|
||||
}
|
||||
|
||||
|
||||
static WRITE32_HANDLER( cmos_protect_w )
|
||||
{
|
||||
cmos_protected = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Timekeeper access (Zeus 2 only)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static READ32_HANDLER( timekeeper_r )
|
||||
{
|
||||
UINT8 result = timekeeper_0_r(offset);
|
||||
// logerror("%06X:cmos_time_r(%X) = %02X\n", activecpu_get_pc(), offset, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static WRITE32_HANDLER( timekeeper_w )
|
||||
{
|
||||
if (!cmos_protected)
|
||||
{
|
||||
// logerror("%06X:cmos_time_w(%X) = %02X\n", activecpu_get_pc(), offset, data);
|
||||
timekeeper_0_w(offset, data);
|
||||
}
|
||||
cmos_protected = TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Zero-power RAM access (Zeus 2 only)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static WRITE32_HANDLER( zpram_w )
|
||||
{
|
||||
/* ZPRAM seems to use the same protection control as CMOS */
|
||||
@ -112,23 +161,23 @@ static READ32_HANDLER( zpram_r )
|
||||
}
|
||||
|
||||
|
||||
static NVRAM_HANDLER( zeus2_nvram )
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* NVRAM handler (Zeus 2 only)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static NVRAM_HANDLER( midzeus2 )
|
||||
{
|
||||
nvram_handler_timekeeper_0(machine, file, read_or_write);
|
||||
|
||||
if (read_or_write)
|
||||
{
|
||||
mame_fwrite(file, generic_nvram, generic_nvram_size);
|
||||
mame_fwrite(file, zpram, zpram_size);
|
||||
}
|
||||
else if (file)
|
||||
{
|
||||
mame_fread(file, generic_nvram, generic_nvram_size);
|
||||
mame_fread(file, zpram, zpram_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(generic_nvram, 0xff, generic_nvram_size);
|
||||
memset(zpram, 0xff, zpram_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -179,6 +228,44 @@ static WRITE32_HANDLER( tms32031_control_w )
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* 49-way joystick handling
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static UINT32 custom_49way_r(void *param)
|
||||
{
|
||||
static const UINT8 translate49[7] = { 0x8, 0xc, 0xe, 0xf, 0x3, 0x1, 0x0 };
|
||||
const char *namex = param;
|
||||
const char *namey = namex + strlen(namex) + 1;
|
||||
return (translate49[readinputportbytag(namey) >> 4] << 4) | translate49[readinputportbytag(namex) >> 4];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Analog input handling
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static READ32_HANDLER( analog_r )
|
||||
{
|
||||
static const char * const tags[] = { "ANALOG0", "ANALOG1", "ANALOG2", "ANALOG3" };
|
||||
if (offset < 8 || offset > 11)
|
||||
logerror("%06X:analog_r(%X)\n", activecpu_get_pc(), offset);
|
||||
return readinputportbytag(tags[offset & 3]);
|
||||
}
|
||||
|
||||
|
||||
static WRITE32_HANDLER( analog_w )
|
||||
{
|
||||
/* 16 writes to the location before a read */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Lightgun handling
|
||||
@ -290,7 +377,8 @@ static WRITE32_HANDLER( unknown_9d0000_w )
|
||||
|
||||
static WRITE32_HANDLER( rombank_select_w )
|
||||
{
|
||||
memory_set_bank(1, data);
|
||||
if (data >= 0 && data <= 2)
|
||||
memory_set_bank(1, data);
|
||||
}
|
||||
|
||||
static READ32_HANDLER( unknown_8a0000_r )
|
||||
@ -335,8 +423,9 @@ static ADDRESS_MAP_START( zeus2_map, ADDRESS_SPACE_PROGRAM, 32 )
|
||||
AM_RANGE(0x8d0005, 0x8d0005) AM_WRITE(rombank_select_w)
|
||||
AM_RANGE(0x900000, 0x91ffff) AM_READWRITE(zpram_r, zpram_w) AM_BASE(&zpram) AM_SIZE(&zpram_size) AM_MIRROR(0x020000)
|
||||
AM_RANGE(0x990000, 0x99000f) AM_READWRITE(midway_ioasic_r, midway_ioasic_w)
|
||||
AM_RANGE(0x9c0000, 0x9c000f) AM_READWRITE(analog_r, analog_w)
|
||||
AM_RANGE(0x9e0000, 0x9e0000) AM_WRITENOP // watchdog?
|
||||
AM_RANGE(0x9f0000, 0x9f7fff) AM_READWRITE(cmos_r, cmos_w) AM_BASE(&generic_nvram32) AM_SIZE(&generic_nvram_size)
|
||||
AM_RANGE(0x9f0000, 0x9f7fff) AM_READWRITE(timekeeper_r, timekeeper_w)
|
||||
AM_RANGE(0x9f8000, 0x9f8000) AM_WRITE(cmos_protect_w)
|
||||
AM_RANGE(0xa00000, 0xbfffff) AM_ROM AM_REGION(REGION_USER1, 0)
|
||||
AM_RANGE(0xc00000, 0xffffff) AM_ROMBANK(1) AM_REGION(REGION_USER2, 0)
|
||||
@ -652,6 +741,18 @@ static INPUT_PORTS_START( crusnexo )
|
||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_PLAYER(3) /* keypad 2 */
|
||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_PLAYER(3) /* keypad 2 */
|
||||
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START_TAG("ANALOG3")
|
||||
PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(25) PORT_KEYDELTA(20)
|
||||
|
||||
PORT_START_TAG("ANALOG2")
|
||||
PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(25) PORT_KEYDELTA(20)
|
||||
|
||||
PORT_START_TAG("ANALOG1")
|
||||
PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_SENSITIVITY(25) PORT_KEYDELTA(20)
|
||||
|
||||
PORT_START_TAG("ANALOG0")
|
||||
PORT_BIT( 0xff, 0x00, IPT_UNUSED )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
@ -740,7 +841,6 @@ static INPUT_PORTS_START( thegrid )
|
||||
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_VOLUME_UP )
|
||||
PORT_BIT( 0x6000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_BILL1 ) /* Bill */
|
||||
PORT_BIT (0xffff0000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START /* Listed "names" are via the manual's "JAMMA" pinout sheet" */
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY /* Not Used */
|
||||
@ -759,18 +859,16 @@ static INPUT_PORTS_START( thegrid )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) /* No Connection */
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) /* No Connection */
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT (0xffff0000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0xff80, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT (0xffff0000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM(custom_49way_r, "49WAYX\0" "49WAYY")
|
||||
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START_TAG("49WAYX")
|
||||
PORT_BIT( 0xff, 0x38, IPT_AD_STICK_X ) PORT_MINMAX(0x00,0x6f) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
|
||||
|
||||
PORT_START_TAG("49WAYY")
|
||||
PORT_BIT( 0xff, 0x38, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0x6f) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
@ -788,6 +886,7 @@ static MACHINE_DRIVER_START( midzeus )
|
||||
MDRV_CPU_PROGRAM_MAP(zeus_map,0)
|
||||
MDRV_CPU_VBLANK_INT(irq0_line_assert,1)
|
||||
|
||||
MDRV_MACHINE_START(midzeus)
|
||||
MDRV_MACHINE_RESET(midzeus)
|
||||
MDRV_NVRAM_HANDLER(generic_1fill)
|
||||
|
||||
@ -814,8 +913,9 @@ static MACHINE_DRIVER_START( midzeus2 )
|
||||
MDRV_CPU_PROGRAM_MAP(zeus2_map,0)
|
||||
MDRV_CPU_VBLANK_INT(irq0_line_assert,1)
|
||||
|
||||
MDRV_MACHINE_START(midzeus2)
|
||||
MDRV_MACHINE_RESET(midzeus)
|
||||
MDRV_NVRAM_HANDLER(zeus2_nvram)
|
||||
MDRV_NVRAM_HANDLER(midzeus2)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "driver.h"
|
||||
#include "eminline.h"
|
||||
#include "gaelco3d.h"
|
||||
#include "cpu/tms32031/tms32031.h"
|
||||
#include "video/rgbutil.h"
|
||||
#include "video/poly.h"
|
||||
|
||||
@ -98,43 +99,6 @@ VIDEO_START( gaelco3d )
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* TMS32031 floating point conversion
|
||||
*
|
||||
*************************************/
|
||||
|
||||
typedef union int_double
|
||||
{
|
||||
double d;
|
||||
float f[2];
|
||||
UINT32 i[2];
|
||||
} int_double;
|
||||
|
||||
|
||||
static float dsp_to_float(UINT32 val)
|
||||
{
|
||||
INT32 _mantissa = val << 8;
|
||||
INT8 _exponent = (INT32)val >> 24;
|
||||
int_double id;
|
||||
|
||||
if (_mantissa == 0 && _exponent == -128)
|
||||
return 0;
|
||||
else if (_mantissa >= 0)
|
||||
{
|
||||
int exponent = (_exponent + 127) << 23;
|
||||
id.i[0] = exponent + (_mantissa >> 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
int exponent = (_exponent + 127) << 23;
|
||||
INT32 man = -_mantissa;
|
||||
id.i[0] = 0x80000000 + exponent + ((man >> 8) & 0x00ffffff);
|
||||
}
|
||||
return id.f[0];
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Polygon rendering
|
||||
@ -166,16 +130,16 @@ static void render_poly(UINT32 *polydata)
|
||||
{
|
||||
float midx = Machine->screen[0].width / 2;
|
||||
float midy = Machine->screen[0].height / 2;
|
||||
float z0 = dsp_to_float(polydata[0]);
|
||||
float voz_dy = dsp_to_float(polydata[1]) * 256.0f;
|
||||
float voz_dx = dsp_to_float(polydata[2]) * 256.0f;
|
||||
float ooz_dy = dsp_to_float(polydata[3]);
|
||||
float ooz_dx = dsp_to_float(polydata[4]);
|
||||
float uoz_dy = dsp_to_float(polydata[5]) * 256.0f;
|
||||
float uoz_dx = dsp_to_float(polydata[6]) * 256.0f;
|
||||
float voz_base = dsp_to_float(polydata[7]) * 256.0f - midx * voz_dx - midy * voz_dy;
|
||||
float ooz_base = dsp_to_float(polydata[8]) - midx * ooz_dx - midy * ooz_dy;
|
||||
float uoz_base = dsp_to_float(polydata[9]) * 256.0f - midx * uoz_dx - midy * uoz_dy;
|
||||
float z0 = convert_tms3203x_fp_to_float(polydata[0]);
|
||||
float voz_dy = convert_tms3203x_fp_to_float(polydata[1]) * 256.0f;
|
||||
float voz_dx = convert_tms3203x_fp_to_float(polydata[2]) * 256.0f;
|
||||
float ooz_dy = convert_tms3203x_fp_to_float(polydata[3]);
|
||||
float ooz_dx = convert_tms3203x_fp_to_float(polydata[4]);
|
||||
float uoz_dy = convert_tms3203x_fp_to_float(polydata[5]) * 256.0f;
|
||||
float uoz_dx = convert_tms3203x_fp_to_float(polydata[6]) * 256.0f;
|
||||
float voz_base = convert_tms3203x_fp_to_float(polydata[7]) * 256.0f - midx * voz_dx - midy * voz_dy;
|
||||
float ooz_base = convert_tms3203x_fp_to_float(polydata[8]) - midx * ooz_dx - midy * ooz_dy;
|
||||
float uoz_base = convert_tms3203x_fp_to_float(polydata[9]) * 256.0f - midx * uoz_dx - midy * uoz_dy;
|
||||
poly_extra_data *extra = poly_get_extra_data(poly);
|
||||
int color = (polydata[10] & 0x7f) << 8;
|
||||
poly_vertex vert[MAX_VERTICES];
|
||||
@ -186,16 +150,16 @@ static void render_poly(UINT32 *polydata)
|
||||
{
|
||||
int t;
|
||||
logerror("poly: %12.2f %12.2f %12.2f %12.2f %12.2f %12.2f %12.2f %12.2f %12.2f %12.2f %08X %08X (%4d,%4d) %08X",
|
||||
(double)dsp_to_float(polydata[0]),
|
||||
(double)dsp_to_float(polydata[1]),
|
||||
(double)dsp_to_float(polydata[2]),
|
||||
(double)dsp_to_float(polydata[3]),
|
||||
(double)dsp_to_float(polydata[4]),
|
||||
(double)dsp_to_float(polydata[5]),
|
||||
(double)dsp_to_float(polydata[6]),
|
||||
(double)dsp_to_float(polydata[7]),
|
||||
(double)dsp_to_float(polydata[8]),
|
||||
(double)dsp_to_float(polydata[9]),
|
||||
(double)convert_tms3203x_fp_to_float(polydata[0]),
|
||||
(double)convert_tms3203x_fp_to_float(polydata[1]),
|
||||
(double)convert_tms3203x_fp_to_float(polydata[2]),
|
||||
(double)convert_tms3203x_fp_to_float(polydata[3]),
|
||||
(double)convert_tms3203x_fp_to_float(polydata[4]),
|
||||
(double)convert_tms3203x_fp_to_float(polydata[5]),
|
||||
(double)convert_tms3203x_fp_to_float(polydata[6]),
|
||||
(double)convert_tms3203x_fp_to_float(polydata[7]),
|
||||
(double)convert_tms3203x_fp_to_float(polydata[8]),
|
||||
(double)convert_tms3203x_fp_to_float(polydata[9]),
|
||||
polydata[10],
|
||||
polydata[11],
|
||||
(INT16)(polydata[12] >> 16), (INT16)(polydata[12] << 2) >> 2, polydata[12]);
|
||||
|
@ -56,9 +56,15 @@ struct _poly_extra_data
|
||||
static TIMER_CALLBACK( scanline_timer_cb )
|
||||
{
|
||||
int scanline = param;
|
||||
|
||||
cpunum_set_input_line(0, 0, ASSERT_LINE);
|
||||
timer_adjust(scanline_timer, video_screen_get_time_until_pos(0, scanline + 1, 0), scanline, attotime_zero);
|
||||
|
||||
if (scanline != -1)
|
||||
{
|
||||
cpunum_set_input_line(0, 0, ASSERT_LINE);
|
||||
timer_adjust(scanline_timer, video_screen_get_time_until_pos(0, scanline + 1, 0), scanline, attotime_zero);
|
||||
timer_set(video_screen_get_time_until_pos(0, video_screen_get_vpos(0) + 1, video_screen_get_hpos(0)), NULL, -1, scanline_timer_cb);
|
||||
}
|
||||
else
|
||||
cpunum_set_input_line(0, 0, CLEAR_LINE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1392,7 +1392,7 @@ static void log_waveram(UINT32 length_and_base)
|
||||
|
||||
UINT32 numoctets = (length_and_base >> 24) + 1;
|
||||
const UINT32 *ptr = waveram_ptr_from_block_addr(0, length_and_base);
|
||||
UINT64 checksum = length_and_base;
|
||||
UINT32 checksum = length_and_base;
|
||||
int foundit = FALSE;
|
||||
int i;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "driver.h"
|
||||
#include "eminline.h"
|
||||
#include "cpu/tms32031/tms32031.h"
|
||||
#include "includes/midzeus.h"
|
||||
#include "video/poly.h"
|
||||
#include "video/rgbutil.h"
|
||||
@ -18,10 +19,13 @@
|
||||
*
|
||||
*************************************/
|
||||
|
||||
#define DUMP_WAVE_RAM 0
|
||||
#define DUMP_WAVE_RAM 1
|
||||
|
||||
#define WAVERAM_WIDTH 1024
|
||||
#define WAVERAM_HEIGHT 2048
|
||||
#define WAVERAM0_WIDTH 1024
|
||||
#define WAVERAM0_HEIGHT 2048
|
||||
|
||||
#define WAVERAM1_WIDTH 512
|
||||
#define WAVERAM1_HEIGHT 1024
|
||||
|
||||
|
||||
|
||||
@ -62,9 +66,16 @@ static UINT8 zeus_fifo_words;
|
||||
static void *zeus_renderbase;
|
||||
static rectangle zeus_cliprect;
|
||||
|
||||
static void *waveram[2];
|
||||
static float zeus_matrix[3][3];
|
||||
static float zeus_point[3];
|
||||
static float zeus_point2[3];
|
||||
static UINT32 zeus_texbase;
|
||||
static UINT32 zeus_unknown_40;
|
||||
static int zeus_quad_size;
|
||||
|
||||
static UINT32 *waveram[2];
|
||||
static emu_timer *int_timer;
|
||||
|
||||
static UINT32 max_waveram[2][2];
|
||||
|
||||
|
||||
/*************************************
|
||||
@ -77,9 +88,14 @@ static void exit_handler(running_machine *machine);
|
||||
|
||||
static void zeus_register32_w(offs_t offset, UINT32 data, int logit);
|
||||
static void zeus_register_update(offs_t offset, UINT32 oldval, int logit);
|
||||
static void zeus_pointer_write(UINT8 which, UINT32 value);
|
||||
static int zeus_fifo_process(const UINT32 *data, int numwords);
|
||||
static void zeus_draw_model(UINT32 baseaddr, UINT16 count, int logit);
|
||||
static void zeus_draw_quad(const UINT32 *databuffer, UINT32 texoffs, int logit);
|
||||
static void render_poly_8bit(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid);
|
||||
|
||||
static void log_fifo_command(const UINT32 *data, int numwords, const char *suffix);
|
||||
static void log_waveram(UINT32 base, UINT16 length);
|
||||
|
||||
|
||||
|
||||
@ -89,7 +105,8 @@ static void log_fifo_command(const UINT32 *data, int numwords, const char *suffi
|
||||
*
|
||||
*************************************/
|
||||
|
||||
#define WAVERAM_BLOCK(bank, blocknum) ((void *)((UINT8 *)waveram[bank] + 16 * (blocknum)))
|
||||
#define WAVERAM_BLOCK0(blocknum) ((void *)((UINT8 *)waveram[0] + 8 * (blocknum)))
|
||||
#define WAVERAM_BLOCK1(blocknum) ((void *)((UINT8 *)waveram[1] + 12 * (blocknum)))
|
||||
|
||||
#define WAVERAM_PTR8(base, bytenum) ((UINT8 *)(base) + BYTE4_XOR_LE(bytenum))
|
||||
#define WAVERAM_READ8(base, bytenum) (*WAVERAM_PTR8(base, bytenum))
|
||||
@ -103,14 +120,14 @@ static void log_fifo_command(const UINT32 *data, int numwords, const char *suffi
|
||||
#define WAVERAM_READ32(base, dwordnum) (*WAVERAM_PTR32(base, dwordnum))
|
||||
#define WAVERAM_WRITE32(base, dwordnum, data) do { *WAVERAM_PTR32(base, dwordnum) = (data); } while (0)
|
||||
|
||||
#define PIXYX_TO_DWORDNUM(y, x) ((((y) & 0x1fe) << 11) | (((y) & 1) << 10) | (((x) & 0x1fe) << 1) | ((x) & 1))
|
||||
#define DEPTHYX_TO_DWORDNUM(y, x) (PIXYX_TO_DWORDNUM(y, x) | 2)
|
||||
#define PIXYX_TO_DWORDNUM(y, x) (((((y) & 0x1ff) << 8) | (((x) & 0x1fe) >> 1)) * 3 + ((x) & 1))
|
||||
#define DEPTHYX_TO_DWORDNUM(y, x) (PIXYX_TO_DWORDNUM(y, (x) & ~1) + 2)
|
||||
|
||||
#define WAVERAM_PTRPIX(base, y, x) WAVERAM_PTR32(base, PIXYX_TO_DWORDNUM(y, x))
|
||||
#define WAVERAM_READPIX(base, y, x) (*WAVERAM_PTRPIX(base, y, x))
|
||||
#define WAVERAM_WRITEPIX(base, y, x, color) do { *WAVERAM_PTRPIX(base, y, x) = (color); } while (0)
|
||||
|
||||
#define WAVERAM_PTRDEPTH(base, y, x) WAVERAM_PTR16(base, DEPTHYX_TO_DWORDNUM(y, x & ~1) * 2 + (x & 1))
|
||||
#define WAVERAM_PTRDEPTH(base, y, x) WAVERAM_PTR16(base, DEPTHYX_TO_DWORDNUM(y, x) * 2 + (x & 1))
|
||||
#define WAVERAM_READDEPTH(base, y, x) (*WAVERAM_PTRDEPTH(base, y, x))
|
||||
#define WAVERAM_WRITEDEPTH(base, y, x, color) do { *WAVERAM_PTRDEPTH(base, y, x) = (color); } while (0)
|
||||
|
||||
@ -122,22 +139,22 @@ static void log_fifo_command(const UINT32 *data, int numwords, const char *suffi
|
||||
*
|
||||
*************************************/
|
||||
|
||||
INLINE void *waveram_ptr_from_block_addr(UINT8 bank, UINT32 addr)
|
||||
INLINE void *waveram0_ptr_from_expanded_addr(UINT32 addr)
|
||||
{
|
||||
UINT32 blocknum = (addr % WAVERAM_WIDTH) + ((addr >> 12) % WAVERAM_HEIGHT) * WAVERAM_WIDTH;
|
||||
return WAVERAM_BLOCK(bank, blocknum);
|
||||
UINT32 blocknum = (addr % WAVERAM0_WIDTH) + ((addr >> 16) % WAVERAM0_HEIGHT) * WAVERAM0_WIDTH;
|
||||
return WAVERAM_BLOCK0(blocknum);
|
||||
}
|
||||
|
||||
INLINE void *waveram_ptr_from_expanded_addr(UINT8 bank, UINT32 addr)
|
||||
INLINE void *waveram1_ptr_from_expanded_addr(UINT32 addr)
|
||||
{
|
||||
UINT32 blocknum = (addr % WAVERAM_WIDTH) + ((addr >> 16) % WAVERAM_HEIGHT) * WAVERAM_WIDTH;
|
||||
return WAVERAM_BLOCK(bank, blocknum);
|
||||
UINT32 blocknum = (addr % WAVERAM1_WIDTH) + ((addr >> 16) % WAVERAM1_HEIGHT) * WAVERAM1_WIDTH;
|
||||
return WAVERAM_BLOCK1(blocknum);
|
||||
}
|
||||
|
||||
INLINE void *waveram_ptr_from_texture_addr(UINT8 bank, UINT32 addr, int width)
|
||||
INLINE void *waveram0_ptr_from_texture_addr(UINT32 addr, int width)
|
||||
{
|
||||
UINT32 blocknum = ((addr & ~1) * width) / 8;
|
||||
return WAVERAM_BLOCK(bank, blocknum);
|
||||
return WAVERAM_BLOCK0(blocknum);
|
||||
}
|
||||
|
||||
|
||||
@ -214,14 +231,18 @@ INLINE UINT8 get_texel_4bit(const void *base, int y, int x, int width)
|
||||
* Video startup
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static TIMER_CALLBACK( int_timer_callback )
|
||||
{
|
||||
cpunum_set_input_line(0, 2, ASSERT_LINE);
|
||||
}
|
||||
|
||||
|
||||
VIDEO_START( midzeus2 )
|
||||
{
|
||||
/* allocate memory for "wave" RAM */
|
||||
waveram[0] = auto_malloc(WAVERAM_WIDTH * WAVERAM_HEIGHT * 16);
|
||||
waveram[1] = auto_malloc(WAVERAM_WIDTH * WAVERAM_HEIGHT * 16);
|
||||
state_save_register_global_pointer(((UINT32 *)waveram[0]), WAVERAM_WIDTH * WAVERAM_HEIGHT * 16/4);
|
||||
state_save_register_global_pointer(((UINT32 *)waveram[1]), WAVERAM_WIDTH * WAVERAM_HEIGHT * 16/4);
|
||||
waveram[0] = auto_malloc(WAVERAM0_WIDTH * WAVERAM0_HEIGHT * 8);
|
||||
waveram[1] = auto_malloc(WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12);
|
||||
|
||||
/* initialize polygon engine */
|
||||
poly = poly_alloc(10000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS);
|
||||
@ -230,6 +251,21 @@ VIDEO_START( midzeus2 )
|
||||
add_exit_callback(machine, exit_handler);
|
||||
|
||||
zeus_renderbase = waveram[1];
|
||||
|
||||
int_timer = timer_alloc(int_timer_callback, NULL);
|
||||
|
||||
/* save states */
|
||||
state_save_register_global_pointer(waveram[0], WAVERAM0_WIDTH * WAVERAM0_HEIGHT * 8 / sizeof(waveram[0][0]));
|
||||
state_save_register_global_pointer(waveram[1], WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12 / sizeof(waveram[1][0]));
|
||||
state_save_register_global_array(zeus_fifo);
|
||||
state_save_register_global(zeus_fifo_words);
|
||||
state_save_register_global(zeus_cliprect.min_x);
|
||||
state_save_register_global(zeus_cliprect.max_x);
|
||||
state_save_register_global(zeus_cliprect.min_y);
|
||||
state_save_register_global(zeus_cliprect.max_y);
|
||||
state_save_register_global_2d_array(zeus_matrix);
|
||||
state_save_register_global_array(zeus_point);
|
||||
state_save_register_global(zeus_texbase);
|
||||
}
|
||||
|
||||
|
||||
@ -237,23 +273,20 @@ static void exit_handler(running_machine *machine)
|
||||
{
|
||||
#if DUMP_WAVE_RAM
|
||||
FILE *f = fopen("waveram.dmp", "w");
|
||||
int bank;
|
||||
int i;
|
||||
|
||||
for (bank = 0; bank < 2; bank++)
|
||||
for (i = 0; i < WAVERAM_WIDTH * WAVERAM_HEIGHT; i++)
|
||||
{
|
||||
if (i % 4 == 0) fprintf(f, "%03X%03X: ", i / WAVERAM_WIDTH, i % WAVERAM_WIDTH);
|
||||
fprintf(f, " %08X %08X ", (UINT32)(waveram[bank][i] >> 32), (UINT32)waveram[bank][i]);
|
||||
if (i % 4 == 3) fprintf(f, "\n");
|
||||
}
|
||||
for (i = 0; i < WAVERAM0_WIDTH * WAVERAM0_HEIGHT; i++)
|
||||
{
|
||||
if (i % 4 == 0) fprintf(f, "%03X%03X: ", i / WAVERAM0_WIDTH, i % WAVERAM0_WIDTH);
|
||||
fprintf(f, " %08X %08X ",
|
||||
WAVERAM_READ32(waveram[0], i*2+0),
|
||||
WAVERAM_READ32(waveram[0], i*2+1));
|
||||
if (i % 4 == 3) fprintf(f, "\n");
|
||||
}
|
||||
fclose(f);
|
||||
#endif
|
||||
|
||||
poly_free(poly);
|
||||
|
||||
printf("max[0] = %X, %X\n", max_waveram[0][0], max_waveram[0][1]);
|
||||
printf("max[1] = %X, %X\n", max_waveram[1][0], max_waveram[1][1]);
|
||||
}
|
||||
|
||||
|
||||
@ -273,7 +306,7 @@ VIDEO_UPDATE( midzeus2 )
|
||||
/* normal update case */
|
||||
if (!input_code_pressed(KEYCODE_W))
|
||||
{
|
||||
const void *base = waveram_ptr_from_expanded_addr(1, 0);//zeusbase[0xcc]);
|
||||
const void *base = waveram1_ptr_from_expanded_addr(zeusbase[0x38]);
|
||||
int xoffs = machine->screen[screen].visarea.min_x;
|
||||
for (y = cliprect->min_y; y <= cliprect->max_y; y++)
|
||||
{
|
||||
@ -296,15 +329,15 @@ VIDEO_UPDATE( midzeus2 )
|
||||
if (input_code_pressed(KEYCODE_RIGHT) && width < 512) { width <<= 1; while (input_code_pressed(KEYCODE_RIGHT)) ; }
|
||||
|
||||
if (yoffs < 0) yoffs = 0;
|
||||
base = waveram_ptr_from_block_addr(0, yoffs << 12);
|
||||
base = waveram0_ptr_from_expanded_addr(yoffs << 16);
|
||||
|
||||
for (y = cliprect->min_y; y <= cliprect->max_y; y++)
|
||||
{
|
||||
UINT16 *dest = (UINT16 *)bitmap->base + y * bitmap->rowpixels;
|
||||
UINT32 *dest = (UINT32 *)bitmap->base + y * bitmap->rowpixels;
|
||||
for (x = cliprect->min_x; x <= cliprect->max_x; x++)
|
||||
{
|
||||
UINT8 tex = get_texel_8bit(base, y, x, width);
|
||||
dest[x] = (tex << 8) | tex;
|
||||
dest[x] = (tex << 16) | (tex << 8) | tex;
|
||||
}
|
||||
}
|
||||
popmessage("offs = %06X", yoffs << 12);
|
||||
@ -350,8 +383,8 @@ READ32_HANDLER( zeus2_r )
|
||||
break;
|
||||
|
||||
case 0x54:
|
||||
/* lower 16 bits are masked when read -- is that the hpos? */
|
||||
result = video_screen_get_vpos(0) << 16;
|
||||
/* both upper 16 bits and lower 16 bits seem to be used as vertical counters */
|
||||
result = (video_screen_get_vpos(0) << 16) | video_screen_get_vpos(0);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -368,7 +401,9 @@ READ32_HANDLER( zeus2_r )
|
||||
|
||||
WRITE32_HANDLER( zeus2_w )
|
||||
{
|
||||
int logit = (offset != 0x40 && offset != 0x41 && offset != 0x48 && offset != 0x49 && offset != 0x4e &&
|
||||
int logit = (offset != 0x08 &&
|
||||
(offset != 0x20 || data != 0) &&
|
||||
offset != 0x40 && offset != 0x41 && offset != 0x48 && offset != 0x49 && offset != 0x4e &&
|
||||
offset != 0x50 && offset != 0x51 && offset != 0x57 && offset != 0x58 && offset != 0x59 && offset != 0x5a && offset != 0x5e);
|
||||
if (logit)
|
||||
logerror("%06X:zeus2_w", activecpu_get_pc());
|
||||
@ -419,6 +454,9 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
zeus_fifo[zeus_fifo_words++] = zeusbase[0x08];
|
||||
if (zeus_fifo_process(zeus_fifo, zeus_fifo_words))
|
||||
zeus_fifo_words = 0;
|
||||
|
||||
/* set the interrupt signal to indicate we can handle more */
|
||||
timer_adjust(int_timer, ATTOTIME_IN_NSEC(500), 0, attotime_zero);
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
@ -429,6 +467,7 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
0 $04000190 $00000000
|
||||
1 $04000000 $01900000
|
||||
*/
|
||||
zeus_pointer_write(zeusbase[0x20] >> 24, zeusbase[0x20]);
|
||||
break;
|
||||
|
||||
case 0x33:
|
||||
@ -461,6 +500,7 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
UINT32 temp = zeusbase[0x38];
|
||||
zeusbase[0x38] = oldval;
|
||||
video_screen_update_partial(0, video_screen_get_vpos(0));
|
||||
log_fifo = input_code_pressed(KEYCODE_L);
|
||||
zeusbase[0x38] = temp;
|
||||
}
|
||||
break;
|
||||
@ -469,7 +509,7 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
/* this is the address, except in read mode, where it latches values */
|
||||
if (zeusbase[0x4e] & 0x10)
|
||||
{
|
||||
const void *src = waveram_ptr_from_expanded_addr(0, oldval);
|
||||
const void *src = waveram0_ptr_from_expanded_addr(oldval);
|
||||
zeusbase[0x41] = oldval;
|
||||
zeusbase[0x48] = WAVERAM_READ32(src, 0);
|
||||
zeusbase[0x49] = WAVERAM_READ32(src, 1);
|
||||
@ -497,11 +537,9 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
*/
|
||||
if ((zeusbase[0x4e] & 0x08) && (offset & 3) == (zeusbase[0x4e] & 3))
|
||||
{
|
||||
void *dest = waveram_ptr_from_expanded_addr(0, zeusbase[0x41]);
|
||||
void *dest = waveram0_ptr_from_expanded_addr(zeusbase[0x41]);
|
||||
WAVERAM_WRITE32(dest, 0, zeusbase[0x48]);
|
||||
WAVERAM_WRITE32(dest, 1, zeusbase[0x49]);
|
||||
max_waveram[0][0] = MAX(max_waveram[0][0], zeusbase[0x41] & 0xffff);
|
||||
max_waveram[0][1] = MAX(max_waveram[0][1], zeusbase[0x41] >> 16);
|
||||
|
||||
if (zeusbase[0x4e] & 0x40)
|
||||
{
|
||||
@ -516,7 +554,7 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
else if (logit)
|
||||
logerror("\t[40]=%08X [4E]=%08X\n", zeusbase[0x40], zeusbase[0x4e]);
|
||||
break;
|
||||
|
||||
|
||||
case 0x51:
|
||||
|
||||
/* in this mode, crusnexo expects the reads to immediately latch */
|
||||
@ -526,7 +564,7 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
/* this is the address, except in read mode, where it latches values */
|
||||
if ((zeusbase[0x5e] & 0x10) || (zeusbase[0x50] == 0x00a20000))
|
||||
{
|
||||
const void *src = waveram_ptr_from_expanded_addr(1, oldval);
|
||||
const void *src = waveram1_ptr_from_expanded_addr(oldval);
|
||||
zeusbase[0x51] = oldval;
|
||||
zeusbase[0x58] = WAVERAM_READ32(src, 0);
|
||||
zeusbase[0x59] = WAVERAM_READ32(src, 1);
|
||||
@ -545,13 +583,11 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
/* thegrid uses this to write either left or right halves of pixels */
|
||||
if (zeusbase[0x50] == 0x00e90000)
|
||||
{
|
||||
void *dest = waveram_ptr_from_expanded_addr(1, zeusbase[0x51]);
|
||||
void *dest = waveram1_ptr_from_expanded_addr(zeusbase[0x51]);
|
||||
if (zeusbase[0x57] & 1)
|
||||
WAVERAM_WRITE32(dest, 0, zeusbase[0x58]);
|
||||
if (zeusbase[0x57] & 4)
|
||||
WAVERAM_WRITE32(dest, 1, zeusbase[0x59]);
|
||||
max_waveram[1][0] = MAX(max_waveram[1][0], zeusbase[0x51] & 0xffff);
|
||||
max_waveram[1][1] = MAX(max_waveram[1][1], zeusbase[0x51] >> 16);
|
||||
}
|
||||
|
||||
/* make sure we log anything else */
|
||||
@ -575,7 +611,7 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
*/
|
||||
if ((zeusbase[0x5e] & 0x08) && (offset & 3) == (zeusbase[0x5e] & 3))
|
||||
{
|
||||
void *dest = waveram_ptr_from_expanded_addr(1, zeusbase[0x51]);
|
||||
void *dest = waveram1_ptr_from_expanded_addr(zeusbase[0x51]);
|
||||
WAVERAM_WRITE32(dest, 0, zeusbase[0x58]);
|
||||
if (zeusbase[0x5e] & 0x20)
|
||||
WAVERAM_WRITE32(dest, 1, zeusbase[0x5a]);
|
||||
@ -584,8 +620,6 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
WAVERAM_WRITE32(dest, 1, zeusbase[0x59]);
|
||||
WAVERAM_WRITE32(dest, 2, zeusbase[0x5a]);
|
||||
}
|
||||
max_waveram[1][0] = MAX(max_waveram[1][0], zeusbase[0x51] & 0xffff);
|
||||
max_waveram[1][1] = MAX(max_waveram[1][1], zeusbase[0x51] >> 16);
|
||||
|
||||
if (zeusbase[0x5e] & 0x40)
|
||||
{
|
||||
@ -605,6 +639,33 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Process the FIFO
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void zeus_pointer_write(UINT8 which, UINT32 value)
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
case 0x04:
|
||||
zeus_renderbase = waveram1_ptr_from_expanded_addr(value << 16);
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
zeus_texbase = value % (WAVERAM0_HEIGHT * WAVERAM0_WIDTH);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
zeus_unknown_40 = value & 0xffffff;
|
||||
zeus_quad_size = (zeus_unknown_40 == 0) ? 10 : 14;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Process the FIFO
|
||||
@ -613,17 +674,141 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit)
|
||||
|
||||
static int zeus_fifo_process(const UINT32 *data, int numwords)
|
||||
{
|
||||
int dataoffs = 0;
|
||||
|
||||
/* handle logging */
|
||||
switch (data[0] >> 24)
|
||||
{
|
||||
/* 0x05: write 32-bit value to low registers */
|
||||
/* in model data, this is 0x19 */
|
||||
case 0x05:
|
||||
if (numwords < 2)
|
||||
return FALSE;
|
||||
if (log_fifo)
|
||||
log_fifo_command(data, numwords, " -- reg32");
|
||||
zeus_register32_w((data[0] >> 16) & 0x7f, data[1], log_fifo);
|
||||
if (((data[0] >> 16) & 0x7f) != 0x08)
|
||||
zeus_register32_w((data[0] >> 16) & 0x7f, data[1], log_fifo);
|
||||
break;
|
||||
|
||||
/* 0x08: set matrix and point (thegrid) */
|
||||
case 0x08:
|
||||
if (numwords < 14)
|
||||
return FALSE;
|
||||
dataoffs = 1;
|
||||
|
||||
/* 0x07: set matrix and point (crusnexo) */
|
||||
case 0x07:
|
||||
if (numwords < 13)
|
||||
return FALSE;
|
||||
|
||||
/* extract the matrix from the raw data */
|
||||
zeus_matrix[0][0] = convert_tms3203x_fp_to_float(data[dataoffs + 1]);
|
||||
zeus_matrix[0][1] = convert_tms3203x_fp_to_float(data[dataoffs + 2]);
|
||||
zeus_matrix[0][2] = convert_tms3203x_fp_to_float(data[dataoffs + 3]);
|
||||
zeus_matrix[1][0] = convert_tms3203x_fp_to_float(data[dataoffs + 4]);
|
||||
zeus_matrix[1][1] = convert_tms3203x_fp_to_float(data[dataoffs + 5]);
|
||||
zeus_matrix[1][2] = convert_tms3203x_fp_to_float(data[dataoffs + 6]);
|
||||
zeus_matrix[2][0] = convert_tms3203x_fp_to_float(data[dataoffs + 7]);
|
||||
zeus_matrix[2][1] = convert_tms3203x_fp_to_float(data[dataoffs + 8]);
|
||||
zeus_matrix[2][2] = convert_tms3203x_fp_to_float(data[dataoffs + 9]);
|
||||
|
||||
/* extract the translation point from the raw data */
|
||||
zeus_point[0] = convert_tms3203x_fp_to_float(data[dataoffs + 10]);
|
||||
zeus_point[1] = convert_tms3203x_fp_to_float(data[dataoffs + 11]);
|
||||
zeus_point[2] = convert_tms3203x_fp_to_float(data[dataoffs + 12]);
|
||||
|
||||
if (log_fifo)
|
||||
{
|
||||
log_fifo_command(data, numwords, "");
|
||||
logerror("\n\t\tmatrix ( %8.2f %8.2f %8.2f ) ( %8.2f %8.2f %8.2f ) ( %8.2f %8.2f %8.2f )\n\t\tvector %8.2f %8.2f %8.5f\n",
|
||||
zeus_matrix[0][0], zeus_matrix[0][1], zeus_matrix[0][2],
|
||||
zeus_matrix[1][0], zeus_matrix[1][1], zeus_matrix[1][2],
|
||||
zeus_matrix[2][0], zeus_matrix[2][1], zeus_matrix[2][2],
|
||||
zeus_point[0],
|
||||
zeus_point[1],
|
||||
zeus_point[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
/* 0x15: set point only (thegrid) */
|
||||
/* 0x16: set point only (crusnexo) */
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
if (numwords < 4)
|
||||
return FALSE;
|
||||
|
||||
/* extract the translation point from the raw data */
|
||||
zeus_point[0] = convert_tms3203x_fp_to_float(data[1]);
|
||||
zeus_point[1] = convert_tms3203x_fp_to_float(data[2]);
|
||||
zeus_point[2] = convert_tms3203x_fp_to_float(data[3]);
|
||||
|
||||
if (log_fifo)
|
||||
{
|
||||
log_fifo_command(data, numwords, "");
|
||||
logerror("\n\t\tvector %8.2f %8.2f %8.5f\n",
|
||||
zeus_point[0],
|
||||
zeus_point[1],
|
||||
zeus_point[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
/* 0x1c: */
|
||||
case 0x1c:
|
||||
if (numwords < 4)
|
||||
return FALSE;
|
||||
if (log_fifo)
|
||||
{
|
||||
log_fifo_command(data, numwords, " -- unknown control + hack clear screen\n");
|
||||
logerror("\t\tvector %8.2f %8.2f %8.5f\n",
|
||||
convert_tms3203x_fp_to_float(data[1]),
|
||||
convert_tms3203x_fp_to_float(data[2]),
|
||||
convert_tms3203x_fp_to_float(data[3]));
|
||||
|
||||
/* extract the translation point from the raw data */
|
||||
zeus_point2[0] = convert_tms3203x_fp_to_float(data[1]);
|
||||
zeus_point2[1] = convert_tms3203x_fp_to_float(data[2]);
|
||||
zeus_point2[2] = convert_tms3203x_fp_to_float(data[3]);
|
||||
}
|
||||
{
|
||||
/* not right -- just a hack */
|
||||
int x, y;
|
||||
for (y = zeus_cliprect.min_y; y <= zeus_cliprect.max_y; y++)
|
||||
for (x = zeus_cliprect.min_x; x <= zeus_cliprect.max_x; x++)
|
||||
waveram_plot_depth(y, x, 0, 0x7fff);
|
||||
}
|
||||
break;
|
||||
|
||||
/* 0x23: render model in waveram (thegrid) */
|
||||
/* 0x24: render model in waveram (crusnexo) */
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
if (numwords < 2)
|
||||
return FALSE;
|
||||
if (log_fifo)
|
||||
log_fifo_command(data, numwords, "");
|
||||
zeus_draw_model(data[1], data[0] & 0xffff, log_fifo);
|
||||
break;
|
||||
|
||||
/* 0x31: sync pipeline? (thegrid) */
|
||||
/* 0x32: sync pipeline? (crusnexo) */
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
if (log_fifo)
|
||||
log_fifo_command(data, numwords, "\n");
|
||||
zeus_quad_size = 10;
|
||||
break;
|
||||
|
||||
/* 0x38: direct render quad (crusnexo) */
|
||||
case 0x38:
|
||||
if (numwords < 12)
|
||||
return FALSE;
|
||||
if (log_fifo)
|
||||
log_fifo_command(data, numwords, "");
|
||||
break;
|
||||
|
||||
/* 0x40: ???? */
|
||||
case 0x40:
|
||||
if (log_fifo)
|
||||
log_fifo_command(data, numwords, "\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -640,6 +825,401 @@ static int zeus_fifo_process(const UINT32 *data, int numwords)
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Draw a model in waveram
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void zeus_draw_model(UINT32 baseaddr, UINT16 count, int logit)
|
||||
{
|
||||
UINT32 databuffer[32];
|
||||
int databufcount = 0;
|
||||
int model_done = FALSE;
|
||||
UINT32 texoffs = 0;
|
||||
int quadsize = zeus_quad_size;
|
||||
|
||||
if (logit)
|
||||
logerror(" -- model @ %08X, len %04X\n", baseaddr, count);
|
||||
|
||||
while (baseaddr != 0 && !model_done)
|
||||
{
|
||||
const void *base = waveram0_ptr_from_expanded_addr(baseaddr);
|
||||
int curoffs;
|
||||
|
||||
/* reset the objdata address */
|
||||
baseaddr = 0;
|
||||
|
||||
/* loop until we run out of data */
|
||||
for (curoffs = 0; curoffs <= count; curoffs++)
|
||||
{
|
||||
int countneeded = 2;
|
||||
UINT8 cmd;
|
||||
|
||||
/* accumulate 2 words of data */
|
||||
databuffer[databufcount++] = WAVERAM_READ32(base, curoffs * 2 + 0);
|
||||
databuffer[databufcount++] = WAVERAM_READ32(base, curoffs * 2 + 1);
|
||||
|
||||
/* if this is enough, process the command */
|
||||
cmd = databuffer[0] >> 24;
|
||||
if (cmd == 0x38)
|
||||
countneeded = quadsize;
|
||||
if (databufcount == countneeded)
|
||||
{
|
||||
/* handle logging of the command */
|
||||
if (logit)
|
||||
{
|
||||
int offs;
|
||||
logerror("\t");
|
||||
for (offs = 0; offs < databufcount; offs++)
|
||||
logerror("%08X ", databuffer[offs]);
|
||||
logerror("-- ");
|
||||
}
|
||||
|
||||
/* handle the command */
|
||||
switch (cmd)
|
||||
{
|
||||
case 0x21: /* thegrid */
|
||||
case 0x22: /* crusnexo */
|
||||
if (((databuffer[0] >> 16) & 0xff) == 0x9b)
|
||||
{
|
||||
texoffs = databuffer[1];
|
||||
if (logit)
|
||||
logerror("texture offset\n");
|
||||
}
|
||||
else if (logit)
|
||||
logerror("unknown offset\n");
|
||||
break;
|
||||
|
||||
case 0x31: /* thegrid */
|
||||
if (logit)
|
||||
logerror("sync?\n");
|
||||
break;
|
||||
|
||||
case 0x35: /* thegrid */
|
||||
case 0x36: /* crusnexo */
|
||||
if (logit)
|
||||
logerror("reg32");
|
||||
zeus_register32_w((databuffer[0] >> 16) & 0x7f, databuffer[1], logit);
|
||||
break;
|
||||
|
||||
case 0x38: /* crusnexo/thegrid */
|
||||
zeus_draw_quad(databuffer, texoffs, logit);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (quadsize == 10)
|
||||
{
|
||||
logerror("Correcting quad size\n");
|
||||
quadsize = 14;
|
||||
}
|
||||
if (logit)
|
||||
logerror("unknown model data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* reset the count */
|
||||
databufcount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Draw a quad
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void zeus_draw_quad(const UINT32 *databuffer, UINT32 texoffs, int logit)
|
||||
{
|
||||
poly_draw_scanline callback;
|
||||
poly_extra_data *extra;
|
||||
poly_vertex clipvert[8];
|
||||
poly_vertex vert[4];
|
||||
// float uscale, vscale;
|
||||
float maxy, maxx;
|
||||
// int val1, val2, texwshift;
|
||||
int numverts;
|
||||
int i;
|
||||
// INT16 normal[3];
|
||||
// INT32 rotnormal[3];
|
||||
int texmode = texoffs & 0xffff;
|
||||
|
||||
if (logit)
|
||||
logerror("quad\n");
|
||||
|
||||
if (input_code_pressed(KEYCODE_Q) && (texoffs & 0xffff) == 0x119) return;
|
||||
if (input_code_pressed(KEYCODE_E) && (texoffs & 0xffff) == 0x01d) return;
|
||||
if (input_code_pressed(KEYCODE_R) && (texoffs & 0xffff) == 0x11d) return;
|
||||
if (input_code_pressed(KEYCODE_T) && (texoffs & 0xffff) == 0x05d) return;
|
||||
if (input_code_pressed(KEYCODE_Y) && (texoffs & 0xffff) == 0x0dd) return;
|
||||
//if (input_code_pressed(KEYCODE_U) && (texoffs & 0xffff) == 0x119) return;
|
||||
//if (input_code_pressed(KEYCODE_I) && (texoffs & 0xffff) == 0x119) return;
|
||||
//if (input_code_pressed(KEYCODE_O) && (texoffs & 0xffff) == 0x119) return;
|
||||
//if (input_code_pressed(KEYCODE_L) && (texoffs & 0x100)) return;
|
||||
|
||||
callback = render_poly_8bit;
|
||||
|
||||
/*
|
||||
0 38800000
|
||||
1 x2 | x1
|
||||
2 v1 | u1
|
||||
3 y2 | y1
|
||||
4 v2 | u2
|
||||
5 z2 | z1
|
||||
6 v3 | u3
|
||||
7 v4 | u4
|
||||
8 ???
|
||||
9 x4 | x3
|
||||
10 y4 | y3
|
||||
11 z4 | z3
|
||||
|
||||
In memory:
|
||||
+0 = ???
|
||||
+1 = set via $05410000/value
|
||||
+2 = x1
|
||||
+3 = y1
|
||||
+4 = z1
|
||||
+5 = x2
|
||||
+6 = y2
|
||||
+7 = z2
|
||||
+8 = x3
|
||||
+9 = y3
|
||||
+10= z3
|
||||
+11= x4
|
||||
+12= y4
|
||||
+13= z4
|
||||
+14= uv1
|
||||
+15= uv2
|
||||
+16= uv3
|
||||
+17= uv4
|
||||
+18= set via $05200000/$05000000 | (value << 10) (uvoffset?)
|
||||
+19= ???
|
||||
|
||||
|
||||
38810000 00000000 00C7|FF38 FF5E|FF5E 15400154 11400114 00000000 00000000 FF38|00C7 00A3|00A3 -- quad
|
||||
xxxx|xxxx yyyy|yyyy xxxx|xxxx yyyy|yyyy
|
||||
*/
|
||||
|
||||
/* extract raw x,y,z */
|
||||
vert[0].x = (INT16)databuffer[2];
|
||||
vert[0].y = (INT16)databuffer[3];
|
||||
vert[0].p[0] = (INT16)databuffer[6];
|
||||
vert[0].p[1] = (databuffer[1] >> 2) & 0xff;
|
||||
vert[0].p[2] = (databuffer[1] >> 18) & 0xff;
|
||||
|
||||
vert[1].x = (INT16)(databuffer[2] >> 16);
|
||||
vert[1].y = (INT16)(databuffer[3] >> 16);
|
||||
vert[1].p[0] = (INT16)(databuffer[6] >> 16);
|
||||
vert[1].p[1] = (databuffer[4] >> 2) & 0xff;
|
||||
vert[1].p[2] = (databuffer[4] >> 12) & 0xff;
|
||||
|
||||
vert[2].x = (INT16)databuffer[8];
|
||||
vert[2].y = (INT16)databuffer[9];
|
||||
vert[2].p[0] = (INT16)databuffer[7];
|
||||
vert[2].p[1] = (databuffer[4] >> 22) & 0xff;
|
||||
vert[2].p[2] = (databuffer[5] >> 2) & 0xff;
|
||||
|
||||
vert[3].x = (INT16)(databuffer[8] >> 16);
|
||||
vert[3].y = (INT16)(databuffer[9] >> 16);
|
||||
vert[3].p[0] = (INT16)(databuffer[7] >> 16);
|
||||
vert[3].p[1] = (databuffer[5] >> 12) & 0xff;
|
||||
vert[3].p[2] = (databuffer[5] >> 22) & 0xff;
|
||||
|
||||
/*
|
||||
vert[0].x = (INT16)databuffer[1];
|
||||
vert[0].y = (INT16)databuffer[3];
|
||||
vert[0].p[0] = (INT16)databuffer[5];
|
||||
vert[0].p[1] = (UINT16)databuffer[2];
|
||||
vert[0].p[2] = (UINT16)(databuffer[2] >> 16);
|
||||
|
||||
vert[1].x = (INT16)(databuffer[1] >> 16);
|
||||
vert[1].y = (INT16)(databuffer[3] >> 16);
|
||||
vert[1].p[0] = (INT16)(databuffer[5] >> 16);
|
||||
vert[1].p[1] = (UINT16)databuffer[4];
|
||||
vert[1].p[2] = (UINT16)(databuffer[4] >> 16);
|
||||
|
||||
vert[2].x = (INT16)databuffer[9];
|
||||
vert[2].y = (INT16)databuffer[10];
|
||||
vert[2].p[0] = (INT16)databuffer[11];
|
||||
vert[2].p[1] = (UINT16)databuffer[6];
|
||||
vert[2].p[2] = (UINT16)(databuffer[6] >> 16);
|
||||
|
||||
vert[3].x = (INT16)(databuffer[9] >> 16);
|
||||
vert[3].y = (INT16)(databuffer[10] >> 16);
|
||||
vert[3].p[0] = (INT16)(databuffer[11] >> 16);
|
||||
vert[3].p[1] = (UINT16)databuffer[7];
|
||||
vert[3].p[2] = (UINT16)(databuffer[7] >> 16);
|
||||
*/
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
float x = vert[i].x;
|
||||
float y = vert[i].y;
|
||||
float z = vert[i].p[0];
|
||||
|
||||
vert[i].x = x * zeus_matrix[0][0] + y * zeus_matrix[0][1] + z * zeus_matrix[0][2] + zeus_point[0];
|
||||
vert[i].y = x * zeus_matrix[1][0] + y * zeus_matrix[1][1] + z * zeus_matrix[1][2] + zeus_point[1];
|
||||
vert[i].p[0] = x * zeus_matrix[2][0] + y * zeus_matrix[2][1] + z * zeus_matrix[2][2] + zeus_point[2];
|
||||
vert[i].p[2] += texoffs >> 16;
|
||||
vert[i].p[1] *= 256.0f;
|
||||
vert[i].p[2] *= 256.0f;
|
||||
|
||||
if (logit)
|
||||
{
|
||||
logerror("\t\t(%f,%f,%f) (%02X,%02X)\n",
|
||||
vert[i].x, vert[i].y, vert[i].p[0],
|
||||
(int)(vert[i].p[1] / 256.0f), (int)(vert[i].p[2] / 256.0f));
|
||||
}
|
||||
}
|
||||
|
||||
numverts = poly_zclip_if_less(4, &vert[0], &clipvert[0], 4, 1.0f / 512.0f / 4.0f);
|
||||
if (numverts < 3)
|
||||
return;
|
||||
|
||||
maxx = maxy = -1000.0f;
|
||||
for (i = 0; i < numverts; i++)
|
||||
{
|
||||
float ooz = 512.0f / clipvert[i].p[0];
|
||||
|
||||
// ooz *= 1.0f / (512.0f * 512.0f);
|
||||
|
||||
clipvert[i].x *= ooz;
|
||||
clipvert[i].y *= ooz;
|
||||
clipvert[i].x += 256.5f;
|
||||
clipvert[i].y += 200.5f;
|
||||
clipvert[i].p[0] *= 65536.0f * 16.0f;
|
||||
|
||||
maxx = MAX(maxx, clipvert[i].x);
|
||||
maxy = MAX(maxy, clipvert[i].y);
|
||||
if (logit)
|
||||
logerror("\t\t\tTranslated=(%f,%f)\n", clipvert[i].x, clipvert[i].y);
|
||||
}
|
||||
for (i = 0; i < numverts; i++)
|
||||
{
|
||||
if (clipvert[i].x == maxx)
|
||||
clipvert[i].x += 0.0005f;
|
||||
if (clipvert[i].y == maxy)
|
||||
clipvert[i].y += 0.0005f;
|
||||
}
|
||||
|
||||
extra = poly_get_extra_data(poly);
|
||||
switch (texmode)
|
||||
{
|
||||
case 0x01d: /* crusnexo: RHS of score bar */
|
||||
case 0x05d: /* crusnexo: background, road */
|
||||
case 0x0dd: /* crusnexo: license plate letters */
|
||||
case 0x11d: /* crusnexo: LHS of score bar */
|
||||
case 0x15d: /* crusnexo */
|
||||
case 0x85d: /* crusnexo */
|
||||
case 0x95d: /* crusnexo */
|
||||
case 0xc1d: /* crusnexo */
|
||||
case 0xc5d: /* crusnexo */
|
||||
extra->texwidth = 256;
|
||||
break;
|
||||
|
||||
case 0x059: /* crusnexo */
|
||||
case 0x0d9: /* crusnexo */
|
||||
case 0x119: /* crusnexo: license plates */
|
||||
case 0x159: /* crusnexo */
|
||||
extra->texwidth = 128;
|
||||
break;
|
||||
|
||||
case 0x055: /* crusnexo */
|
||||
case 0x155: /* crusnexo */
|
||||
extra->texwidth = 64;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
static UINT8 hits[0x10000];
|
||||
if (!hits[(texoffs & 0xffff)])
|
||||
{
|
||||
hits[(texoffs & 0xffff)] = 1;
|
||||
printf("format = %04X\n", (texoffs & 0xffff));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
extra->solidcolor = 0;//zeusbase[0x00] & 0x7fff;
|
||||
extra->zoffset = 0;//zeusbase[0x7e] >> 16;
|
||||
extra->alpha = 0;//zeusbase[0x4e];
|
||||
extra->transcolor = 0x100;//((databuffer[1] >> 16) & 1) ? 0 : 0x100;
|
||||
extra->texbase = WAVERAM_BLOCK0(zeus_texbase);
|
||||
extra->palbase = waveram0_ptr_from_expanded_addr(zeusbase[0x41]);
|
||||
|
||||
poly_render_quad_fan(poly, NULL, &zeus_cliprect, callback, 4, numverts, &clipvert[0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Rasterizers
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void render_poly_8bit(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
|
||||
{
|
||||
const poly_extra_data *extra = extradata;
|
||||
INT32 curz = extent->param[0].start;
|
||||
INT32 curu = extent->param[1].start;
|
||||
INT32 curv = extent->param[2].start;
|
||||
// INT32 curi = extent->param[3].start;
|
||||
INT32 dzdx = extent->param[0].dpdx;
|
||||
INT32 dudx = extent->param[1].dpdx;
|
||||
INT32 dvdx = extent->param[2].dpdx;
|
||||
// INT32 didx = extent->param[3].dpdx;
|
||||
const void *texbase = extra->texbase;
|
||||
const void *palbase = extra->palbase;
|
||||
UINT16 transcolor = extra->transcolor;
|
||||
int texwidth = extra->texwidth;
|
||||
int x;
|
||||
|
||||
for (x = extent->startx; x < extent->stopx; x++)
|
||||
{
|
||||
UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, scanline, x);
|
||||
INT32 depth = (curz >> 16) + extra->zoffset;
|
||||
if (depth > 0x7fff) depth = 0x7fff;
|
||||
if (depth >= 0 && depth <= *depthptr)
|
||||
{
|
||||
int u0 = (curu >> 8);// & (texwidth - 1);
|
||||
int v0 = (curv >> 8);// & 255;
|
||||
int u1 = (u0 + 1);
|
||||
int v1 = (v0 + 1);
|
||||
UINT8 texel0 = get_texel_8bit(texbase, v0, u0, texwidth);
|
||||
UINT8 texel1 = get_texel_8bit(texbase, v0, u1, texwidth);
|
||||
UINT8 texel2 = get_texel_8bit(texbase, v1, u0, texwidth);
|
||||
UINT8 texel3 = get_texel_8bit(texbase, v1, u1, texwidth);
|
||||
if (texel0 != transcolor)
|
||||
{
|
||||
rgb_t color0 = WAVERAM_READ16(palbase, texel0);
|
||||
rgb_t color1 = WAVERAM_READ16(palbase, texel1);
|
||||
rgb_t color2 = WAVERAM_READ16(palbase, texel2);
|
||||
rgb_t color3 = WAVERAM_READ16(palbase, texel3);
|
||||
rgb_t filtered;
|
||||
color0 = ((color0 & 0x7c00) << 9) | ((color0 & 0x3e0) << 6) | ((color0 & 0x1f) << 3);
|
||||
color1 = ((color1 & 0x7c00) << 9) | ((color1 & 0x3e0) << 6) | ((color1 & 0x1f) << 3);
|
||||
color2 = ((color2 & 0x7c00) << 9) | ((color2 & 0x3e0) << 6) | ((color2 & 0x1f) << 3);
|
||||
color3 = ((color3 & 0x7c00) << 9) | ((color3 & 0x3e0) << 6) | ((color3 & 0x1f) << 3);
|
||||
filtered = rgb_bilinear_filter(color0, color1, color2, color3, curu, curv);
|
||||
WAVERAM_WRITEPIX(zeus_renderbase, scanline, x, filtered);
|
||||
*depthptr = depth;
|
||||
}
|
||||
}
|
||||
|
||||
curz += dzdx;
|
||||
curu += dudx;
|
||||
curv += dvdx;
|
||||
// curi += didx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Debugging tools
|
||||
@ -655,3 +1235,45 @@ static void log_fifo_command(const UINT32 *data, int numwords, const char *suffi
|
||||
logerror(" %08X", data[wordnum]);
|
||||
logerror("%s", suffix);
|
||||
}
|
||||
|
||||
|
||||
static void log_waveram(UINT32 base, UINT16 length)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
UINT32 base;
|
||||
UINT16 length;
|
||||
UINT32 checksum;
|
||||
} recent_entries[100];
|
||||
|
||||
UINT32 numoctets = length + 1;
|
||||
const void *ptr = waveram0_ptr_from_expanded_addr(base);
|
||||
UINT32 checksum = base | ((UINT64)length << 32);
|
||||
int foundit = FALSE;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numoctets; i++)
|
||||
checksum += WAVERAM_READ32(ptr, i*2) + WAVERAM_READ32(ptr, i*2+1);
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(recent_entries); i++)
|
||||
if (recent_entries[i].base == base && recent_entries[i].length == length && recent_entries[i].checksum == checksum)
|
||||
{
|
||||
foundit = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_LENGTH(recent_entries))
|
||||
i--;
|
||||
if (i != 0)
|
||||
{
|
||||
memmove(&recent_entries[1], &recent_entries[0], i * sizeof(recent_entries[0]));
|
||||
recent_entries[0].base = base;
|
||||
recent_entries[0].length = length;
|
||||
recent_entries[0].checksum = checksum;
|
||||
}
|
||||
if (foundit)
|
||||
return;
|
||||
|
||||
for (i = 0; i < numoctets; i++)
|
||||
logerror("\t%02X: %08X %08X\n", i, WAVERAM_READ32(ptr, i*2), WAVERAM_READ32(ptr, i*2+1));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user