diff options
-rw-r--r-- | src/emu/cpu/adsp2100/adsp2100.c | 2 | ||||
-rw-r--r-- | src/emu/cpu/tms32031/32031ops.c | 24 | ||||
-rw-r--r-- | src/emu/cpu/tms32031/tms32031.c | 152 | ||||
-rw-r--r-- | src/emu/cpu/tms32031/tms32031.h | 7 | ||||
-rw-r--r-- | src/emu/machine/timekpr.c | 25 | ||||
-rw-r--r-- | src/emu/machine/timekpr.h | 6 | ||||
-rw-r--r-- | src/emu/video/poly.c | 17 | ||||
-rw-r--r-- | src/mame/audio/cage.c | 1 | ||||
-rw-r--r-- | src/mame/audio/dcs.c | 6 | ||||
-rw-r--r-- | src/mame/drivers/midvunit.c | 3 | ||||
-rw-r--r-- | src/mame/drivers/midzeus.c | 172 | ||||
-rw-r--r-- | src/mame/video/gaelco3d.c | 78 | ||||
-rw-r--r-- | src/mame/video/midvunit.c | 12 | ||||
-rw-r--r-- | src/mame/video/midzeus.c | 2 | ||||
-rw-r--r-- | src/mame/video/midzeus2.c | 728 |
15 files changed, 1028 insertions, 207 deletions
diff --git a/src/emu/cpu/adsp2100/adsp2100.c b/src/emu/cpu/adsp2100/adsp2100.c index 2d2d9a4b0da..d5e2788e700 100644 --- a/src/emu/cpu/adsp2100/adsp2100.c +++ b/src/emu/cpu/adsp2100/adsp2100.c @@ -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); diff --git a/src/emu/cpu/tms32031/32031ops.c b/src/emu/cpu/tms32031/32031ops.c index bc8e1e96e8b..f4c9d1e74eb 100644 --- a/src/emu/cpu/tms32031/32031ops.c +++ b/src/emu/cpu/tms32031/32031ops.c @@ -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(); } } diff --git a/src/emu/cpu/tms32031/tms32031.c b/src/emu/cpu/tms32031/tms32031.c index 6907cd1cc2f..b6de2ca1312 100644 --- a/src/emu/cpu/tms32031/tms32031.c +++ b/src/emu/cpu/tms32031/tms32031.c @@ -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); - - /* check for IRQs */ - if (state != CLEAR_LINE) - check_irqs(); + UINT16 oldstate = tms32031.irq_state; + UINT16 intmask = 1 << irqline; + + /* ignore anything out of range */ + if (irqline >= 12) + return; + + /* 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 --- */ diff --git a/src/emu/cpu/tms32031/tms32031.h b/src/emu/cpu/tms32031/tms32031.h index 3a19a6e93a7..1ecc7ce5fdc 100644 --- a/src/emu/cpu/tms32031/tms32031.h +++ b/src/emu/cpu/tms32031/tms32031.h @@ -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 */ diff --git a/src/emu/machine/timekpr.c b/src/emu/machine/timekpr.c index b54b2d22441..a8c5fce4ea1 100644 --- a/src/emu/machine/timekpr.c +++ b/src/emu/machine/timekpr.c @@ -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 ) diff --git a/src/emu/machine/timekpr.h b/src/emu/machine/timekpr.h index f651168fa80..b8d3bbd57ef 100644 --- a/src/emu/machine/timekpr.h +++ b/src/emu/machine/timekpr.h @@ -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 ); diff --git a/src/emu/video/poly.c b/src/emu/video/poly.c index adafbe6a47d..19604d900e3 100644 --- a/src/emu/video/poly.c +++ b/src/emu/video/poly.c @@ -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"); +} diff --git a/src/mame/audio/cage.c b/src/mame/audio/cage.c index 7db002f4669..6e5c79624bf 100644 --- a/src/mame/audio/cage.c +++ b/src/mame/audio/cage.c @@ -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; } diff --git a/src/mame/audio/dcs.c b/src/mame/audio/dcs.c index e3f61d00677..2ac84a2f825 100644 --- a/src/mame/audio/dcs.c +++ b/src/mame/audio/dcs.c @@ -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); } diff --git a/src/mame/drivers/midvunit.c b/src/mame/drivers/midvunit.c index c60b5d3a83b..2e68cadb7c3 100644 --- a/src/mame/drivers/midvunit.c +++ b/src/mame/drivers/midvunit.c @@ -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; diff --git a/src/mame/drivers/midzeus.c b/src/mame/drivers/midzeus.c index b239dd137c4..5a5ca058021 100644 --- a/src/mame/drivers/midzeus.c +++ b/src/mame/drivers/midzeus.c @@ -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,30 +89,63 @@ static MACHINE_RESET( midzeus ) /************************************* * - * CMOS access + * CMOS access (Zeus only) * *************************************/ +static WRITE32_HANDLER( cmos_w ) +{ + if (!cmos_protected) + COMBINE_DATA(&generic_nvram32[offset]); + cmos_protected = TRUE; +} + + +static READ32_HANDLER( cmos_r ) +{ + return generic_nvram32[offset]; +} + + static WRITE32_HANDLER( cmos_protect_w ) { cmos_protected = FALSE; } -static WRITE32_HANDLER( cmos_w ) + +/************************************* + * + * Timekeeper access (Zeus 2 only) + * + *************************************/ + +static READ32_HANDLER( timekeeper_r ) { - if (!cmos_protected) - COMBINE_DATA(generic_nvram32 + offset); - cmos_protected = TRUE; + UINT8 result = timekeeper_0_r(offset); +// logerror("%06X:cmos_time_r(%X) = %02X\n", activecpu_get_pc(), offset, result); + return result; } -static READ32_HANDLER( cmos_r ) +static WRITE32_HANDLER( timekeeper_w ) { - return generic_nvram32[offset]; + 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); - } } @@ -181,6 +230,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) diff --git a/src/mame/video/gaelco3d.c b/src/mame/video/gaelco3d.c index d346236242c..4bc4063d9f3 100644 --- a/src/mame/video/gaelco3d.c +++ b/src/mame/video/gaelco3d.c @@ -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" @@ -100,43 +101,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]); diff --git a/src/mame/video/midvunit.c b/src/mame/video/midvunit.c index 5d7094106b9..5960ea2fdd3 100644 --- a/src/mame/video/midvunit.c +++ b/src/mame/video/midvunit.c @@ -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); } diff --git a/src/mame/video/midzeus.c b/src/mame/video/midzeus.c index 16decd6669d..3ca73400e6a 100644 --- a/src/mame/video/midzeus.c +++ b/src/mame/video/midzeus.c @@ -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; diff --git a/src/mame/video/midzeus2.c b/src/mame/video/midzeus2.c index 83ed6276f5b..e70706cf256 100644 --- a/src/mame/video/midzeus2.c +++ b/src/mame/video/midzeus2.c @@ -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) { @@ -611,19 +645,170 @@ static void zeus_register_update(offs_t offset, UINT32 oldval, int logit) * *************************************/ +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 + * + *************************************/ + 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: @@ -642,6 +827,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)); +} |