summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
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
commit2f8231e10a29484f8af05ff396e3842e558a0c57 (patch)
tree1f55a4e382171bf0db48c71e4aa259db68dd560b /src/emu
parent8d6c62b976d1f9190f5c776646f01cd76ede65e9 (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.c2
-rw-r--r--src/emu/cpu/tms32031/32031ops.c24
-rw-r--r--src/emu/cpu/tms32031/tms32031.c152
-rw-r--r--src/emu/cpu/tms32031/tms32031.h7
-rw-r--r--src/emu/machine/timekpr.c25
-rw-r--r--src/emu/machine/timekpr.h6
-rw-r--r--src/emu/video/poly.c17
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");
+}