diff options
author | Aaron Giles <aaron@aarongiles.com> | 2007-12-28 06:11:52 +0000 |
---|---|---|
committer | Aaron Giles <aaron@aarongiles.com> | 2007-12-28 06:11:52 +0000 |
commit | 2f8231e10a29484f8af05ff396e3842e558a0c57 (patch) | |
tree | 1f55a4e382171bf0db48c71e4aa259db68dd560b /src/emu | |
parent | 8d6c62b976d1f9190f5c776646f01cd76ede65e9 (diff) |
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
Diffstat (limited to 'src/emu')
-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 |
7 files changed, 177 insertions, 56 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"); +} |