diff options
Diffstat (limited to 'trunk/src/emu/machine/k053252.c')
-rw-r--r-- | trunk/src/emu/machine/k053252.c | 256 |
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); + |