/*************************************************************************************************************************** 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(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(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);