From f44732e5aff3007d3688028cfa851a42c043f887 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Sun, 13 Jan 2008 01:15:32 +0000 Subject: [PATCH] Added XTAL clocks to zaxxon.c. Cleaned up jaguar driver: * proper video timing, configured by the chipset * 32-bit rendering, removing 16bpp hacks * support for borders * proper object processor timing, including multiple passes per line * added R3041 as a clone of the R3000 * fixed XTALs based on documentation --- src/emu/cpu/cpu.mak | 3 +- src/emu/cpu/mips/r3000.c | 36 ++++++ src/emu/cpu/mips/r3000.h | 3 + src/emu/cpuexec.h | 2 + src/emu/cpuintrf.c | 6 + src/emu/drivers/xtal.h | 1 + src/mame/drivers/cojag.c | 76 ++++-------- src/mame/drivers/zaxxon.c | 4 +- src/mame/includes/jaguar.h | 3 + src/mame/mame.mak | 1 + src/mame/video/jagobj.c | 118 +++++++++--------- src/mame/video/jaguar.c | 237 ++++++++++++++++++++++++------------- 12 files changed, 286 insertions(+), 204 deletions(-) diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index 40ad3a3cb83..e788f0a9582 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -766,8 +766,9 @@ $(CPUOBJ)/pic16c5x/pic16c5x.o: $(CPUSRC)/pic16c5x/pic16c5x.c \ #------------------------------------------------- CPUDEFS += -DHAS_R3000=$(if $(filter R3000,$(CPUS)),1,0) +CPUDEFS += -DHAS_R3041=$(if $(filter R3041,$(CPUS)),1,0) -ifneq ($(filter R3000,$(CPUS)),) +ifneq ($(filter R3000 R3041,$(CPUS)),) OBJDIRS += $(CPUOBJ)/mips CPUOBJS += $(CPUOBJ)/mips/r3000.o DBGOBJS += $(CPUOBJ)/mips/r3kdasm.o diff --git a/src/emu/cpu/mips/r3000.c b/src/emu/cpu/mips/r3000.c index 4fbb8c8c3d1..e2e4bf3ad90 100644 --- a/src/emu/cpu/mips/r3000.c +++ b/src/emu/cpu/mips/r3000.c @@ -1377,3 +1377,39 @@ void r3000le_get_info(UINT32 state, cpuinfo *info) default: r3000_get_info(state, info); break; } } + + +void r3041be_get_info(UINT32 state, cpuinfo *info) +{ + switch (state) + { + /* --- the following bits of info are returned as 64-bit signed integers --- */ + case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; break; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case CPUINFO_PTR_RESET: info->reset = r3000be_reset; break; + + /* --- the following bits of info are returned as NULL-terminated strings --- */ + case CPUINFO_STR_NAME: strcpy(info->s, "R3041 (big)"); break; + + default: r3000_get_info(state, info); break; + } +} + + +void r3041le_get_info(UINT32 state, cpuinfo *info) +{ + switch (state) + { + /* --- the following bits of info are returned as 64-bit signed integers --- */ + case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case CPUINFO_PTR_RESET: info->reset = r3000le_reset; break; + + /* --- the following bits of info are returned as NULL-terminated strings --- */ + case CPUINFO_STR_NAME: strcpy(info->s, "R3041 (little)"); break; + + default: r3000_get_info(state, info); break; + } +} diff --git a/src/emu/cpu/mips/r3000.h b/src/emu/cpu/mips/r3000.h index 0a897274ffd..f26631549b2 100644 --- a/src/emu/cpu/mips/r3000.h +++ b/src/emu/cpu/mips/r3000.h @@ -62,4 +62,7 @@ struct r3000_config extern void r3000be_get_info(UINT32 state, cpuinfo *info); extern void r3000le_get_info(UINT32 state, cpuinfo *info); +extern void r3041be_get_info(UINT32 state, cpuinfo *info); +extern void r3041le_get_info(UINT32 state, cpuinfo *info); + #endif /* _JAGUAR_H */ diff --git a/src/emu/cpuexec.h b/src/emu/cpuexec.h index 181ddb62c06..4d13525d253 100644 --- a/src/emu/cpuexec.h +++ b/src/emu/cpuexec.h @@ -118,6 +118,8 @@ enum _cpu_type CPU_JAGUARDSP, CPU_R3000BE, CPU_R3000LE, + CPU_R3041BE, + CPU_R3041LE, CPU_R4600BE, CPU_R4600LE, CPU_R4650BE, diff --git a/src/emu/cpuintrf.c b/src/emu/cpuintrf.c index 744897f9649..e379647d3df 100644 --- a/src/emu/cpuintrf.c +++ b/src/emu/cpuintrf.c @@ -115,6 +115,8 @@ void jaguargpu_get_info(UINT32 state, cpuinfo *info); void jaguardsp_get_info(UINT32 state, cpuinfo *info); void r3000be_get_info(UINT32 state, cpuinfo *info); void r3000le_get_info(UINT32 state, cpuinfo *info); +void r3041be_get_info(UINT32 state, cpuinfo *info); +void r3041le_get_info(UINT32 state, cpuinfo *info); void r4600be_get_info(UINT32 state, cpuinfo *info); void r4600le_get_info(UINT32 state, cpuinfo *info); void r4650be_get_info(UINT32 state, cpuinfo *info); @@ -549,6 +551,10 @@ static const struct { CPU_R3000BE, r3000be_get_info }, { CPU_R3000LE, r3000le_get_info }, #endif +#if (HAS_R3041) + { CPU_R3041BE, r3041be_get_info }, + { CPU_R3041LE, r3041le_get_info }, +#endif #if (HAS_R4600) { CPU_R4600BE, r4600be_get_info }, { CPU_R4600LE, r4600le_get_info }, diff --git a/src/emu/drivers/xtal.h b/src/emu/drivers/xtal.h index 43dd28fb790..191c971dcfa 100644 --- a/src/emu/drivers/xtal.h +++ b/src/emu/drivers/xtal.h @@ -104,6 +104,7 @@ enum XTAL_45MHz = 45000000, /* Eolith with Hyperstone CPUs */ XTAL_45_158MHz = 45158000, /* Sega Model 2A video board, Model 3 CPU board */ XTAL_48MHz = 48000000, + XTAL_48_66MHz = 48660000, /* Zaxxon */ XTAL_49_152MHz = 49152000, /* Used on some Namco PCBs, Baraduke h/w, System 21, Super System 22 */ XTAL_50MHz = 50000000, XTAL_52MHz = 52000000, /* Cojag */ diff --git a/src/mame/drivers/cojag.c b/src/mame/drivers/cojag.c index 76c8b3f90a2..1d5008cf3e6 100644 --- a/src/mame/drivers/cojag.c +++ b/src/mame/drivers/cojag.c @@ -177,6 +177,11 @@ Notes: #include "jaguar.h" +#define JAGUAR_CLOCK XTAL_52MHz +#define R3000_CLOCK XTAL_40MHz +#define M68K_CLOCK XTAL_50MHz + + /************************************* * @@ -987,29 +992,27 @@ static const struct jaguar_config dsp_config = static MACHINE_DRIVER_START( cojagr3k ) /* basic machine hardware */ - MDRV_CPU_ADD(R3000BE, 66000000/2) + MDRV_CPU_ADD_TAG("main", R3041BE, R3000_CLOCK) MDRV_CPU_CONFIG(config) MDRV_CPU_PROGRAM_MAP(r3000_map,0) - MDRV_CPU_ADD(JAGUARGPU, 52000000/2) + MDRV_CPU_ADD(JAGUARGPU, JAGUAR_CLOCK/2) MDRV_CPU_CONFIG(gpu_config) MDRV_CPU_PROGRAM_MAP(gpu_map,0) - MDRV_CPU_ADD(JAGUARDSP, 52000000/2) + MDRV_CPU_ADD(JAGUARDSP, JAGUAR_CLOCK/2) MDRV_CPU_CONFIG(dsp_config) MDRV_CPU_PROGRAM_MAP(dsp_map,0) - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_MACHINE_RESET(cojag) MDRV_NVRAM_HANDLER(generic_1fill) /* video hardware */ MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_UPDATE_BEFORE_VBLANK) - MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_SIZE(42*8, 262) /* guess -- TOM registers should be used to configure screen */ - MDRV_SCREEN_VISIBLE_AREA(0*8, 42*8-1, 0*8, 30*8-1) - MDRV_PALETTE_LENGTH(65534) + + MDRV_SCREEN_ADD("main", 0) + MDRV_SCREEN_RAW_PARAMS(COJAG_PIXEL_CLOCK/2, 456, 42, 402, 262, 17, 257) + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) MDRV_VIDEO_START(cojag) MDRV_VIDEO_UPDATE(cojag) @@ -1025,51 +1028,12 @@ static MACHINE_DRIVER_START( cojagr3k ) MACHINE_DRIVER_END -static MACHINE_DRIVER_START( r3knarrow ) - MDRV_IMPORT_FROM(cojagr3k) - - /* video hardware */ - MDRV_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 0*8, 30*8-1) -MACHINE_DRIVER_END - - static MACHINE_DRIVER_START( cojag68k ) + MDRV_IMPORT_FROM(cojagr3k) /* basic machine hardware */ - MDRV_CPU_ADD(M68EC020, 50000000/2) + MDRV_CPU_REPLACE("main", M68EC020, M68K_CLOCK/2) MDRV_CPU_PROGRAM_MAP(m68020_map,0) - - MDRV_CPU_ADD(JAGUARGPU, 52000000/2) - MDRV_CPU_CONFIG(gpu_config) - MDRV_CPU_PROGRAM_MAP(gpu_map,0) - - MDRV_CPU_ADD(JAGUARDSP, 52000000/2) - MDRV_CPU_CONFIG(dsp_config) - MDRV_CPU_PROGRAM_MAP(dsp_map,0) - - MDRV_SCREEN_REFRESH_RATE(60) - - MDRV_MACHINE_RESET(cojag) - MDRV_NVRAM_HANDLER(generic_1fill) - - /* video hardware */ - MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_UPDATE_BEFORE_VBLANK) - MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_SIZE(42*8, 262) /* guess -- TOM registers should be used to configure screen */ - MDRV_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 0*8, 30*8-1) - MDRV_PALETTE_LENGTH(65534) - - MDRV_VIDEO_START(cojag) - MDRV_VIDEO_UPDATE(cojag) - - /* sound hardware */ - MDRV_SPEAKER_STANDARD_STEREO("left", "right") - - MDRV_SOUND_ADD(DAC, 0) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 1.0) - - MDRV_SOUND_ADD(DAC, 0) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 1.0) MACHINE_DRIVER_END @@ -1423,7 +1387,7 @@ ROM_END static void cojag_common_init(running_machine *machine, UINT16 gpu_jump_offs, UINT16 spin_pc) { /* copy over the ROM */ - cojag_is_r3000 = (machine->drv->cpu[0].type == CPU_R3000BE); + cojag_is_r3000 = (machine->drv->cpu[0].type == CPU_R3041BE); /* install synchronization hooks for GPU */ if (cojag_is_r3000) @@ -1560,7 +1524,7 @@ static DRIVER_INIT( vcircle ) * *************************************/ -GAME( 1996, area51, 0, r3knarrow, area51, area51, ROT0, "Atari Games", "Area 51 (R3000)", 0 ) +GAME( 1996, area51, 0, cojagr3k, area51, area51, ROT0, "Atari Games", "Area 51 (R3000)", 0 ) GAME( 1995, area51t, area51, cojag68k, area51, area51a, ROT0, "Time Warner", "Area 51 (Time Warner License)", 0 ) GAME( 1995, area51a, area51, cojag68k, area51, area51a, ROT0, "Atari Games", "Area 51 (Atari Games License)", 0 ) GAME( 1995, fishfren, 0, cojagr3k, fishfren, fishfren, ROT0, "Time Warner Interactive", "Fishin' Frenzy (prototype)", 0 ) @@ -1571,9 +1535,9 @@ GAME( 1996, freezea3, freezeat, cojagr3k, freezeat, freezea3, ROT0, "Atari Game GAME( 1996, freezea4, freezeat, cojagr3k, freezeat, freezea4, ROT0, "Atari Games", "Freeze (Atari) (prototype, 96/10/03)", 0 ) GAME( 1996, freezea5, freezeat, cojagr3k, freezeat, freezea5, ROT0, "Atari Games", "Freeze (Atari) (prototype, 96/09/20, AMOA-96)", 0 ) GAME( 1996, freezea6, freezeat, cojagr3k, freezeat, freezea6, ROT0, "Atari Games", "Freeze (Atari) (prototype, 96/09/07, Jamma-96)", 0 ) -GAME( 1996, maxforce, 0, r3knarrow, area51, maxforce, ROT0, "Atari Games", "Maximum Force v1.05", 0 ) -GAME( 1996, maxf_102, maxforce, r3knarrow, area51, maxforce, ROT0, "Atari Games", "Maximum Force v1.02", 0 ) -GAME( 1996, maxf_ng, maxforce, r3knarrow, area51, maxforce, ROT0, "Atari Games", "Maximum Force (No Gore version)", 0 ) +GAME( 1996, maxforce, 0, cojagr3k, area51, maxforce, ROT0, "Atari Games", "Maximum Force v1.05", 0 ) +GAME( 1996, maxf_102, maxforce, cojagr3k, area51, maxforce, ROT0, "Atari Games", "Maximum Force v1.02", 0 ) +GAME( 1996, maxf_ng, maxforce, cojagr3k, area51, maxforce, ROT0, "Atari Games", "Maximum Force (No Gore version)", 0 ) GAME( 1998, area51mx, 0, cojag68k, area51, area51mx, ROT0, "Atari Games", "Area 51 / Maximum Force Duo v2.0", 0 ) -GAME( 1998, a51mxr3k, area51mx, r3knarrow, area51, a51mxr3k, ROT0, "Atari Games", "Area 51 / Maximum Force Duo (R3000)", 0 ) +GAME( 1998, a51mxr3k, area51mx, cojagr3k, area51, a51mxr3k, ROT0, "Atari Games", "Area 51 / Maximum Force Duo (R3000)", 0 ) GAME( 1996, vcircle, 0, cojagr3k, vcircle, vcircle, ROT0, "Atari Games", "Vicious Circle (prototype)", 0 ) diff --git a/src/mame/drivers/zaxxon.c b/src/mame/drivers/zaxxon.c index bc452ff7da8..c8d93a26e29 100644 --- a/src/mame/drivers/zaxxon.c +++ b/src/mame/drivers/zaxxon.c @@ -316,8 +316,8 @@ * *************************************/ -#define MASTER_CLOCK 48660000 -#define SOUND_CLOCK 4000000 +#define MASTER_CLOCK XTAL_48_66MHz +#define SOUND_CLOCK XTAL_4MHz #define PIXEL_CLOCK (MASTER_CLOCK/8) diff --git a/src/mame/includes/jaguar.h b/src/mame/includes/jaguar.h index 35669213c19..351a455ea38 100644 --- a/src/mame/includes/jaguar.h +++ b/src/mame/includes/jaguar.h @@ -12,6 +12,9 @@ #endif /* MESS */ #endif +#define COJAG_PIXEL_CLOCK XTAL_14_31818MHz + + /*----------- defined in drivers/cojag.c -----------*/ diff --git a/src/mame/mame.mak b/src/mame/mame.mak index b08921bb433..325174d7ab0 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -126,6 +126,7 @@ CPUS += ARM CPUS += ARM7 CPUS += JAGUAR CPUS += R3000 +CPUS += R3041 CPUS += R4600 CPUS += R4650 CPUS += R4700 diff --git a/src/mame/video/jagobj.c b/src/mame/video/jagobj.c index f481eb2d42d..475343c9d67 100644 --- a/src/mame/video/jagobj.c +++ b/src/mame/video/jagobj.c @@ -12,7 +12,7 @@ #define LOG_OBJECTS 0 -static UINT16 scanline[360]; +static UINT16 *scanline; static UINT16 *clutbase; static UINT8 *blend_y, *blend_cc; @@ -900,87 +900,75 @@ static UINT32 *process_branch(UINT32 *objdata, int vc, int logit) * *************************************/ -static void process_object_list(mame_bitmap *bitmap, const rectangle *cliprect) +static void process_object_list(int vc, UINT16 *_scanline) { + int done = 0, count = 0; UINT32 *objdata; - int y, x, pass; int logit; + int x; - /* loop over all scanlines */ - for (y = cliprect->min_y; y <= cliprect->max_y; y++) - { - /* erase the scanline first */ - for (x = 0; x < 336; x++) - scanline[x] = gpu_regs[BG]; + /* erase the scanline first */ + scanline = _scanline; + for (x = 0; x < 336; x++) + scanline[x] = gpu_regs[BG]; #if LOG_OBJECTS - logit = (y == cliprect->min_y); + logit = (y == cliprect->min_y); #else - logit = 0; + logit = 0; #endif - /* two passes per scanline */ - for (pass = 0; pass < 1; pass++) + /* fetch the object pointer */ + objdata = (UINT32 *)get_jaguar_memory((gpu_regs[OLP_H] << 16) | gpu_regs[OLP_L]); + while (!done && objdata && count++ < 100) + { + /* the low 3 bits determine the command */ + switch (objdata[1] & 7) { - int vc = y * 2 + pass + gpu_regs[VBE]; - int done = 0, count = 0; + /* bitmap object */ + case 0: + if (logit) + logerror("bitmap = %08X-%08X %08X-%08X\n", objdata[0], objdata[1], objdata[2], objdata[3]); + objdata = process_bitmap(objdata, vc, logit); + break; - /* fetch the object pointer */ - objdata = (UINT32 *)get_jaguar_memory((gpu_regs[OLP_H] << 16) | gpu_regs[OLP_L]); - while (!done && objdata && count++ < 100) + /* scaled bitmap object */ + case 1: + if (logit) + logerror("scaled = %08X-%08X %08X-%08X %08X-%08X\n", objdata[0], objdata[1], objdata[2], objdata[3], objdata[4], objdata[5]); + objdata = process_scaled_bitmap(objdata, vc, logit); + break; + + /* branch */ + case 3: + if (logit) + logerror("branch = %08X-%08X\n", objdata[0], objdata[1]); + objdata = process_branch(objdata, vc, logit); + break; + + /* stop */ + case 4: { - /* the low 3 bits determine the command */ - switch (objdata[1] & 7) + int interrupt = (objdata[1] >> 3) & 1; + done = 1; + + if (logit) + logerror("stop = %08X-%08X\n", objdata[0], objdata[1]); + if (interrupt) { - /* bitmap object */ - case 0: - if (logit) - logerror("bitmap = %08X-%08X %08X-%08X\n", objdata[0], objdata[1], objdata[2], objdata[3]); - objdata = process_bitmap(objdata, vc, logit); - break; - - /* scaled bitmap object */ - case 1: - if (logit) - logerror("scaled = %08X-%08X %08X-%08X %08X-%08X\n", objdata[0], objdata[1], objdata[2], objdata[3], objdata[4], objdata[5]); - objdata = process_scaled_bitmap(objdata, vc, logit); - break; - - /* branch */ - case 3: - if (logit) - logerror("branch = %08X-%08X\n", objdata[0], objdata[1]); - objdata = process_branch(objdata, vc, logit); - break; - - /* stop */ - case 4: - { - int interrupt = (objdata[1] >> 3) & 1; - done = 1; - - if (logit) - logerror("stop = %08X-%08X\n", objdata[0], objdata[1]); - if (interrupt) - { #ifndef MESS - fprintf(stderr, "stop int=%d\n", interrupt); + fprintf(stderr, "stop int=%d\n", interrupt); #endif - cpu_irq_state |= 4; - update_cpu_irq(); - } - break; - } - - default: - fprintf(stderr, "%08X %08X\n", objdata[0], objdata[1]); - done = 1; - break; + cpu_irq_state |= 4; + update_cpu_irq(); } + break; } - } - /* render this scanline */ - draw_scanline16(bitmap, 0, y, 336, scanline, pen_table, -1); + default: + fprintf(stderr, "%08X %08X\n", objdata[0], objdata[1]); + done = 1; + break; + } } } diff --git a/src/mame/video/jaguar.c b/src/mame/video/jaguar.c index 3452e1c5b39..5ce4b072a52 100644 --- a/src/mame/video/jaguar.c +++ b/src/mame/video/jaguar.c @@ -143,6 +143,8 @@ #include "jagblit.h" +#define ENABLE_BORDERS 0 + #define LOG_BLITS 0 #define LOG_BAD_BLITS 0 #define LOG_BLITTER_STATS 0 @@ -190,9 +192,11 @@ enum static UINT32 blitter_regs[BLITTER_REGS]; static UINT16 gpu_regs[GPU_REGS]; -static emu_timer *vi_timer; +static emu_timer *object_timer; static UINT8 cpu_irq_state; +static mame_bitmap *screen_bitmap; + static pen_t *pen_table; @@ -205,7 +209,7 @@ static pen_t *pen_table; /* from jagobj.c */ static void jagobj_init(void); -static void process_object_list(mame_bitmap *bitmap, const rectangle *cliprect); +static void process_object_list(int vc, UINT16 *_scanline); /* from jagblit.c */ static void generic_blitter(UINT32 command, UINT32 a1flags, UINT32 a2flags); @@ -229,10 +233,65 @@ static void blitter_x1800x01_xxxxxx_xxxxxx(UINT32 command, UINT32 a1flags, UINT3 * *************************************/ -INLINE void get_crosshair_xy(int player, int *x, int *y) +INLINE void get_crosshair_xy(running_machine *machine, int player, int *x, int *y) { - *x = ((readinputport(3 + player * 2) & 0xff) * Machine->screen[0].width) >> 8; - *y = ((readinputport(4 + player * 2) & 0xff) * Machine->screen[0].height) >> 8; + int width = machine->screen[0].visarea.max_x + 1 - machine->screen[0].visarea.min_x; + int height = machine->screen[0].visarea.max_y + 1 - machine->screen[0].visarea.min_y; + *x = machine->screen[0].visarea.min_x + (((readinputport(3 + player * 2) & 0xff) * width) >> 8); + *y = machine->screen[0].visarea.min_y + (((readinputport(4 + player * 2) & 0xff) * height) >> 8); +} + + + +/************************************* + * + * Horizontal display values + * + *************************************/ + +INLINE int effective_hvalue(int value) +{ + if (!(value & 0x400)) + return value & 0x3ff; + else + return (value & 0x3ff) + (gpu_regs[HP] & 0x3ff) + 1; +} + + + +/************************************* + * + * Object processor timer + * + *************************************/ + +INLINE int adjust_object_timer(running_machine *machine, int vc) +{ + int hdbpix[2]; + int hdb = 0; + + /* extract the display begin registers */ + hdbpix[0] = (gpu_regs[HDB1] & 0x7ff) / 2; + hdbpix[1] = (gpu_regs[HDB2] & 0x7ff) / 2; + + /* sort */ + if (hdbpix[0] > hdbpix[1]) + { + int temp = hdbpix[0]; + hdbpix[0] = hdbpix[1]; + hdbpix[1] = temp; + } + + /* select the target one */ + hdb = hdbpix[vc % 2]; + + /* if setting the second one in a line, make sure we will ever actually hit it */ + if (vc % 2 == 1 && (hdbpix[1] == hdbpix[0] || hdbpix[1] >= machine->screen[0].width)) + return FALSE; + + /* adjust the timer */ + timer_adjust(object_timer, video_screen_get_time_until_pos(0, vc / 2, hdb), vc | (hdb << 16), attotime_never); + return TRUE; } @@ -271,16 +330,6 @@ static void update_cpu_irq(void) } -static TIMER_CALLBACK( vi_callback ) -{ - int scanline = param; - - cpu_irq_state |= 1; - update_cpu_irq(); - timer_adjust(vi_timer, video_screen_get_time_until_pos(0, scanline, 0), scanline, attotime_zero); -} - - void jaguar_gpu_cpu_int(void) { cpu_irq_state |= 2; @@ -364,45 +413,25 @@ static void jaguar_set_palette(UINT16 vmode) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - int i, colors = 0; + int i; /* switch off the mode */ switch (vmode & 0x106) { /* YCC full */ case 0x000: - { - /* set color 0 to black */ - palette_set_color(Machine, colors++, MAKE_RGB(0, 0, 0)); - - /* due to the way YCC colorspace maps onto RGB, there are multiple entries for black */ - /* take advantage of this so we don't have to use all 64k colors */ for (i = 0; i < 65536; i++) { UINT8 r = (red_lookup[i >> 8] * (i & 0xff)) >> 8; UINT8 g = (grn_lookup[i >> 8] * (i & 0xff)) >> 8; UINT8 b = (blu_lookup[i >> 8] * (i & 0xff)) >> 8; - - if (r == 0 && g == 0 && b == 0) - pen_table[i] = 0; - else - { - pen_table[i] = colors; - palette_set_color(Machine, colors++, MAKE_RGB(r, g, b)); - } + pen_table[i] = MAKE_RGB(r, g, b); } break; - } /* YCC/RGB VARMOD */ case 0x100: case 0x107: - { - /* set color 0 to black */ - palette_set_color(Machine, colors++, MAKE_RGB(0, 0, 0)); - - /* due to the way YCC colorspace maps onto RGB, there are multiple entries for black */ - /* take advantage of this so we don't have to use all 64k colors */ for (i = 0; i < 65536; i++) { UINT8 r = (red_lookup[i >> 8] * (i & 0xff)) >> 8; @@ -419,39 +448,15 @@ static void jaguar_set_palette(UINT16 vmode) g = (g << 3) | (g >> 2); b = (b << 3) | (b >> 2); } - - if (r == 0 && g == 0 && b == 0) - pen_table[i] = 0; - else - { - pen_table[i] = colors; - palette_set_color(Machine, colors++, MAKE_RGB(r, g, b)); - } + pen_table[i] = MAKE_RGB(r, g, b); } break; - } /* RGB full */ case 0x006: - { - /* we cheat a little here to squeeze into 65534 colors */ - palette_set_color(Machine, colors++, MAKE_RGB(0, 0, 0)); - palette_set_color(Machine, colors++, MAKE_RGB(0, 8, 0)); - palette_set_color(Machine, colors++, MAKE_RGB(0, 16, 0)); - pen_table[0] = 0; - pen_table[1] = 1; - pen_table[2] = 1; - pen_table[3] = 2; - pen_table[4] = 2; - - /* map the remaining colors normally */ - for (i = 5; i < 65536; i++) - { - pen_table[i] = colors; - palette_set_color_rgb(Machine, colors++, pal5bit(i >> 11), pal6bit(i >> 0), pal5bit(i >> 6)); - } + for (i = 0; i < 65536; i++) + pen_table[i] = MAKE_RGB(pal5bit(i >> 11), pal6bit(i >> 0), pal5bit(i >> 6)); break; - } /* others */ default: @@ -637,19 +642,12 @@ READ16_HANDLER( jaguar_tom_regs_r ) WRITE16_HANDLER( jaguar_tom_regs_w ) { - int scanline; - if (offset < GPU_REGS) { COMBINE_DATA(&gpu_regs[offset]); switch (offset) { - case VI: - scanline = (gpu_regs[VI] - gpu_regs[VBE]) / 2; - timer_adjust(vi_timer, video_screen_get_time_until_pos(0, scanline, 0), scanline, attotime_zero); - break; - case INT1: cpu_irq_state &= ~(gpu_regs[INT1] >> 8); update_cpu_irq(); @@ -658,6 +656,38 @@ WRITE16_HANDLER( jaguar_tom_regs_w ) case VMODE: jaguar_set_palette(gpu_regs[VMODE]); break; + + case HP: + case HBB: + case HBE: + case HDB1: + case HDB2: + case HDE: + case VP: + case VBB: + case VBE: + case VDB: + case VDE: + { + int hperiod = 2 * ((gpu_regs[HP] & 0x3ff) + 1); + int hbend = effective_hvalue(ENABLE_BORDERS ? gpu_regs[HBE] : MIN(gpu_regs[HDB1], gpu_regs[HDB2])); + int hbstart = effective_hvalue(gpu_regs[ENABLE_BORDERS ? HBB : HDE]); + int vperiod = (gpu_regs[VP] & 0x7ff) + 1; + int vbend = gpu_regs[VBE] & 0x7ff; + int vbstart = gpu_regs[VBB] & 0x7ff; + + /* adjust for the half-lines */ + if (hperiod != 0 && vperiod != 0 && hbend < hbstart && vbend < vbstart && hbstart < hperiod) + { + rectangle visarea; + visarea.min_x = hbend / 2; + visarea.max_x = hbstart / 2 - 1; + visarea.min_y = vbend / 2; + visarea.max_y = vbstart / 2 - 1; + video_screen_configure(0, hperiod / 2, vperiod / 2, &visarea, HZ_TO_ATTOSECONDS((double)COJAG_PIXEL_CLOCK * 2 / hperiod / vperiod)); + } + break; + } } } @@ -702,15 +732,11 @@ READ32_HANDLER( cojag_gun_input_r ) switch (offset) { case 0: - get_crosshair_xy(1, &beamx, &beamy); - beamx += 52; - beamy += 17; + get_crosshair_xy(Machine, 1, &beamx, &beamy); return (beamy << 16) | (beamx ^ 0x1ff); case 1: - get_crosshair_xy(0, &beamx, &beamy); - beamx += 52; - beamy += 17; + get_crosshair_xy(Machine, 0, &beamx, &beamy); return (beamy << 16) | (beamx ^ 0x1ff); case 2: @@ -727,14 +753,65 @@ READ32_HANDLER( cojag_gun_input_r ) * *************************************/ +static TIMER_CALLBACK( cojag_scanline_update ) +{ + int vc = param & 0xffff; + int hdb = param >> 16; + + /* only run if video is enabled and we are past the "display begin" */ + if ((gpu_regs[VMODE] & 1) && vc >= (gpu_regs[VDB] & 0x7ff)) + { + UINT32 *dest = BITMAP_ADDR32(screen_bitmap, vc / 2, 0); + int maxx = machine->screen[0].visarea.max_x; + int hde = effective_hvalue(gpu_regs[HDE]) / 2; + UINT16 scanline[360]; + int x; + + /* if we are first on this scanline, clear to the border color */ + if (ENABLE_BORDERS && vc % 2 == 0) + { + rgb_t border = MAKE_RGB(gpu_regs[BORD1] & 0xff, gpu_regs[BORD1] >> 8, gpu_regs[BORD2] & 0xff); + for (x = machine->screen[0].visarea.min_x; x <= machine->screen[0].visarea.max_x; x++) + dest[x] = border; + } + + /* process the object list for this counter value */ + process_object_list(vc, scanline); + + /* copy the data to the target, clipping */ + for (x = 0; x < 360 && hdb <= maxx && hdb < hde; x++, hdb++) + dest[hdb] = pen_table[scanline[x]]; + } + + /* adjust the timer in a loop, to handle missed cases */ + do + { + /* handle vertical interrupts */ + if (vc == gpu_regs[VI]) + { + cpu_irq_state |= 1; + update_cpu_irq(); + } + + /* point to the next counter value */ + if (++vc / 2 >= machine->screen[0].height) + vc = 0; + + } while (!adjust_object_timer(machine, vc)); +} + + VIDEO_START( cojag ) { + object_timer = timer_alloc(cojag_scanline_update, NULL); + adjust_object_timer(machine, 0); + + screen_bitmap = auto_bitmap_alloc(720, 512, BITMAP_FORMAT_RGB32); + jagobj_init(); pen_table = auto_malloc(65536 * sizeof(pen_t)); - vi_timer = timer_alloc(vi_callback, NULL); - state_save_register_global_pointer(pen_table, 65536); state_save_register_global_array(blitter_regs); state_save_register_global_array(gpu_regs); @@ -760,7 +837,7 @@ VIDEO_UPDATE( cojag ) } /* render the object list */ - process_object_list(bitmap, cliprect); + copybitmap(bitmap, screen_bitmap, 0, 0, 0, 0, cliprect, TRANSPARENCY_NONE, 0); return 0; }