summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/machine/k053252.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/machine/k053252.c')
-rw-r--r--trunk/src/emu/machine/k053252.c256
1 files changed, 256 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/k053252.c b/trunk/src/emu/machine/k053252.c
new file mode 100644
index 00000000000..76437b56eba
--- /dev/null
+++ b/trunk/src/emu/machine/k053252.c
@@ -0,0 +1,256 @@
+/***************************************************************************************************************************
+
+ Konami 053252 chip emulation, codenamed "CCU"
+
+ device emulation by Angelo Salese, based off notes by Olivier Galibert
+
+============================================================================================================================
+
+left res = current in game, right res = computed
+
+hexion: 02 FF 00 4D 00 73 00 00 01 1F 05 0E B7 7C 00 00 512x256 ~ 512x256 <- writes to e and f regs, in an irq ack fashion
+overdriv: 01 7F 00 22 00 0D 00 03 01 07 10 0F 73 00 00 00 304x256 ~ 305x224
+esckids: 01 7F 00 12 00 0D 00 01 01 07 08 07 73 00 00 00 304x224 ~ 321x240
+rollerg: 01 7F 00 23 00 1D 02 00 01 07 10 0F 73 00 02 00 288x224 ~ 288x224 <- writes to 6 and e regs, in an irq ack fashion
+gaiapols: 01 FB 00 19 00 37 00 00 01 06 10 0E 75 00 D1 00 376x224 ~ 380x224
+mmaulers: 01 7F 00 19 00 27 00 00 01 07 10 0F 73 00 00 00 288x224 ~ 288x224
+mystwarr: 01 7F 00 12 00 2E 00 00 01 07 11 0E 73 00 00 00 288x224 ~ 288x224
+metamrph: 01 7F 00 11 00 27 01 00 01 07 10 0F 74 00 00 00 288x224 ~ 288x224
+viostorm: 01 FF 00 16 00 39 00 00 01 07 11 0E 75 00 00 00 384x224 ~ 385x224
+mtlchamp: 01 FF 00 21 00 37 00 00 01 07 11 0E 74 00 00 00 384x224 ~ 384x224
+dbz: 01 FF 00 21 00 37 00 00 01 20 0C 0E 54 00 00 00 384x256 ~ 384x256
+dbz2: 01 FF 00 21 00 37 00 00 01 20 0C 0E 54 00 00 00 384x256 ~ 384x256
+xexex: 01 FF 00 21 00 37 01 00 00 20 0C 0E 54 00 00 00 384x256 ~ 384x256 (*)
+(all konamigx, cowboys of moo mesa, run & gun, dj main)
+
+(*) hblank duration 512 (0x200), hdisp 384 (0x180), vblank duration 288 (0x120), vdisp 256 (0x100)
+
+ Definitions from GX, look similar, all values big-endian, write-only:
+
+ 0-1: bits 9-0: HC - Total hblank duration (-1) Hres ~ (HC+1) - HFP - HBP - 8*(HSW+1)
+ 2-3: bits 8-0: HFP - HBlank front porch
+ 4-5: bits 8-0: HBP - HBlank back porch
+ 6 : bits 7-0: INT1EN
+ 7 : bits 7-0: INT2EN
+ 8-9: bits 8-0: VC - Total vblank duration
+ a : bits 7-0: VFP - VBlank front porch Vres ~ VC - VFP - VBP - (VSW+1)
+ b : bits 7-0: VBP - VBlank back porch
+ c : bits 7-4: VSW - V-Sync Width
+ c : bits 3-0: HSW - H-Sync Width
+ d : bits 7-0: INT-TIME
+ e : bits 7-0: INT1ACK
+ f : bits 7-0: INT2ACK
+
+ Read-only:
+ e-f: bits 8-0: VCT
+
+TODO:
+- xexex sets up 0x20 as the VC? default value?
+- xexex layers are offsetted if you try to use the CCU
+- understand how to interpret the back / front porch values, and remove the offset x/y hack
+
+***************************************************************************************************************************/
+
+
+#include "emu.h"
+#include "k053252.h"
+
+typedef struct _k053252_state k053252_state;
+struct _k053252_state
+{
+ UINT8 regs[16];
+ UINT16 hc,hfp,hbp;
+ UINT16 vc,vfp,vbp;
+ UINT8 vsw,hsw;
+
+ screen_device *screen;
+ devcb_resolved_write_line int1_en;
+ devcb_resolved_write_line int2_en;
+ devcb_resolved_write_line int1_ack;
+ devcb_resolved_write_line int2_ack;
+ //devcb_resolved_write8 int_time;
+ int offsx,offsy;
+};
+
+
+/*****************************************************************************
+ INLINE FUNCTIONS
+*****************************************************************************/
+
+INLINE k053252_state *k053252_get_safe_token( device_t *device )
+{
+ assert(device != NULL);
+ assert(device->type() == K053252);
+
+ return (k053252_state *)downcast<legacy_device_base *>(device)->token();
+}
+
+INLINE const k053252_interface *k053252_get_interface( device_t *device )
+{
+ assert(device != NULL);
+ assert(device->type() == K053252);
+
+ return (const k053252_interface *) device->static_config();
+}
+
+/*****************************************************************************
+ DEVICE HANDLERS
+*****************************************************************************/
+
+READ8_DEVICE_HANDLER( k053252_r )
+{
+ k053252_state *k053252 = k053252_get_safe_token(device);
+
+ //TODO: debugger_access()
+ popmessage("Warning: k053252 read %02x, contact MAMEdev",offset);
+
+ return k053252->regs[offset];
+}
+
+static void k053252_res_change( device_t *device )
+{
+ k053252_state *k053252 = k053252_get_safe_token(device);
+
+ if(k053252->screen != NULL)
+ {
+ if(k053252->hc && k053252->vc &&
+ k053252->hbp && k053252->hfp &&
+ k053252->vbp && k053252->vfp &&
+ k053252->hsw && k053252->vsw) //safety checks
+ {
+ rectangle visarea;
+ //(HC+1) - HFP - HBP - 8*(HSW+1)
+ //VC - VFP - VBP - (VSW+1)
+ attoseconds_t refresh = HZ_TO_ATTOSECONDS(device->clock()) * (k053252->hc) * k053252->vc;
+
+ //printf("H %d %d %d %d\n",k053252->hc,k053252->hfp,k053252->hbp,k053252->hsw);
+ //printf("V %d %d %d %d\n",k053252->vc,k053252->vfp,k053252->vbp,k053252->vsw);
+
+ visarea.min_x = k053252->offsx;
+ visarea.min_y = k053252->offsy;
+ visarea.max_x = k053252->offsx + k053252->hc - k053252->hfp - k053252->hbp - 8*(k053252->hsw) - 1;
+ visarea.max_y = k053252->offsy + k053252->vc - k053252->vfp - k053252->vbp - (k053252->vsw) - 1;
+
+ k053252->screen->configure(k053252->hc, k053252->vc, visarea, refresh);
+ }
+ }
+}
+
+WRITE8_DEVICE_HANDLER( k053252_w )
+{
+ k053252_state *k053252 = k053252_get_safe_token(device);
+
+ k053252->regs[offset] = data;
+
+ switch(offset)
+ {
+ case 0x00:
+ case 0x01:
+ k053252->hc = (k053252->regs[1]&0xff);
+ k053252->hc |= ((k053252->regs[0]&0x03)<<8);
+ k053252->hc ++;
+ logerror("%d (%04x) HC set\n",k053252->hc,k053252->hc);
+ k053252_res_change(device);
+ break;
+ case 0x02:
+ case 0x03:
+ k053252->hfp = (k053252->regs[3]&0xff);
+ k053252->hfp |= ((k053252->regs[2]&0x01)<<8);
+ logerror("%d (%04x) HFP set\n",k053252->hfp,k053252->hfp);
+ k053252_res_change(device);
+ break;
+ case 0x04:
+ case 0x05:
+ k053252->hbp = (k053252->regs[5]&0xff);
+ k053252->hbp |= ((k053252->regs[4]&0x01)<<8);
+ logerror("%d (%04x) HBP set\n",k053252->hbp,k053252->hbp);
+ k053252_res_change(device);
+ break;
+ case 0x06: k053252->int1_en(data); break;
+ case 0x07: k053252->int2_en(data); break;
+ case 0x08:
+ case 0x09:
+ k053252->vc = (k053252->regs[9]&0xff);
+ k053252->vc |= ((k053252->regs[8]&0x01)<<8);
+ logerror("%d (%04x) VC set\n",k053252->vc,k053252->vc);
+ k053252_res_change(device);
+ break;
+ case 0x0a:
+ k053252->vfp = (k053252->regs[0x0a]&0xff);
+ logerror("%d (%04x) VFP set\n",k053252->vfp,k053252->vfp);
+ k053252_res_change(device);
+ break;
+ case 0x0b:
+ k053252->vbp = (k053252->regs[0x0b]&0xff);
+ logerror("%d (%04x) VBP set\n",k053252->vbp,k053252->vbp);
+ k053252_res_change(device);
+ break;
+ case 0x0c:
+ k053252->vsw = ((k053252->regs[0x0c]&0xf0) >> 4) + 1;
+ k053252->hsw = ((k053252->regs[0x0c]&0x0f) >> 0) + 1;
+ logerror("%02x VSW / %02x HSW set\n",k053252->vsw,k053252->hsw);
+ k053252_res_change(device);
+ break;
+ //case 0x0d: k053252->int_time(data); break;
+ case 0x0e: k053252->int1_ack(1); break;
+ case 0x0f: k053252->int2_ack(1); break;
+ }
+}
+
+
+
+/*****************************************************************************
+ DEVICE INTERFACE
+*****************************************************************************/
+
+static DEVICE_START( k053252 )
+{
+ k053252_state *k053252 = k053252_get_safe_token(device);
+ const k053252_interface *intf = k053252_get_interface(device);
+
+ device->save_item(NAME(k053252->regs));
+ k053252->screen = device->machine().device<screen_device>(intf->screen);
+ k053252->int1_en.resolve(intf->int1_en, *device);
+ k053252->int2_en.resolve(intf->int2_en, *device);
+ k053252->int1_ack.resolve(intf->int1_ack, *device);
+ k053252->int2_ack.resolve(intf->int2_ack, *device);
+ //k053252->int_time.resolve(intf->int_time, *device);
+ k053252->offsx = intf->offsx;
+ k053252->offsy = intf->offsy;
+}
+
+static DEVICE_RESET( k053252 )
+{
+ k053252_state *k053252 = k053252_get_safe_token(device);
+ int i;
+
+ for (i = 0; i < 16; i++)
+ k053252->regs[i] = 0;
+
+ k053252->regs[0x08] = 1; // Xexex apparently does a wrong assignment for VC (sets up the INT enable register instead)
+}
+
+
+DEVICE_GET_INFO( k053252 )
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(k053252_state); break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(k053252); break;
+ case DEVINFO_FCT_STOP: /* Nothing */ break;
+ case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(k053252); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "Konami 053252"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "Konami Video IC"); break;
+ case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
+ case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright MAME Team"); break;
+ }
+}
+
+DEFINE_LEGACY_DEVICE(K053252, k053252);
+