diff --git a/makefile.burn_rules b/makefile.burn_rules index 1c4c25972..df96bf60d 100644 --- a/makefile.burn_rules +++ b/makefile.burn_rules @@ -62,7 +62,7 @@ drvobj = d_dodonpachi.o d_donpachi.o d_esprade.o d_feversos.o d_gaia.o d_guwang d_1945kiii.o d_aerofgt.o d_airbustr.o d_aquarium.o d_bestleag.o d_bigstrkb.o d_blmbycar.o d_bloodbro.o d_crospang.o d_crshrace.o d_dcon.o \ d_ddragon3.o d_deniam.o d_diverboy.o d_dooyong.o d_dreamwld.o d_drgnmst.o d_drtomy.o d_egghunt.o d_esd16.o d_f1gp.o d_funybubl.o d_fuukifg2.o \ d_fuukifg3.o d_gaelco.o d_gaelco2.o d_gaiden.o d_galpanic.o d_galspnbl.o d_gotcha.o d_gumbo.o d_hyperpac.o d_jchan.o d_kaneko16.o d_lordgun.o \ - d_macrossp.o d_mcatadv.o d_metro.o d_midas.o d_mugsmash.o d_mwarr.o d_news.o d_nmg5.o d_nmk16.o d_ohmygod.o d_onetwo.o d_pass.o d_pirates.o \ + d_macrossp.o d_mcatadv.o d_metro.o d_midas.o d_mugsmash.o d_mwarr.o d_namcos2.o d_news.o d_nmg5.o d_nmk16.o d_ohmygod.o d_onetwo.o d_pass.o d_pirates.o \ d_playmark.o d_powerins.o d_pushman.o d_raiden.o d_raiden2.o d_sandscrp.o d_seta.o d_seta2.o d_shadfrce.o d_silkroad.o d_silvmil.o d_speedspn.o \ d_ssv.o d_suna16.o d_suprnova.o d_taotaido.o d_tecmo16.o d_tecmosys.o d_tetrisp2.o d_tumbleb.o d_unico.o d_vmetal.o d_welltris.o d_wwfwfest.o \ d_xorworld.o d_yunsun16.o d_yunsung8.o d_zerozone.o \ @@ -92,8 +92,8 @@ depobj := $(drvobj) \ burn.o burn_gun.o burn_led.o burn_shift.o burn_memory.o burn_pal.o burn_sound.o burn_sound_c.o cheat.o debug_track.o hiscore.o load.o \ tilemap_generic.o tiles_generic.o timer.o vector.o \ \ - 6821pia.o 8255ppi.o 8257dma.o eeprom.o gaelco_crypt.o joyprocess.o nb1414m4.o nb1414m4_8bit.o nmk004.o nmk112.o kaneko_tmap.o mb87078.o mermaid.o \ - namcoio.o pandora.o resnet.o seibusnd.o sknsspr.o slapstic.o st0020.o t5182.o timekpr.o tms34061.o v3021.o vdc.o tms9928a.o \ + 6821pia.o 8255ppi.o 8257dma.o c169.0 eeprom.o gaelco_crypt.o joyprocess.o nb1414m4.o nb1414m4_8bit.o nmk004.o nmk112.o kaneko_tmap.o mb87078.o \ + mermaid.o namco_c45.o namcoio.o pandora.o resnet.o seibusnd.o sknsspr.o slapstic.o st0020.o t5182.o timekpr.o tms34061.o v3021.o vdc.o tms9928a.o \ \ ay8910.o burn_y8950.o burn_ym2151.o burn_ym2203.o burn_ym2413.o burn_ym2608.o burn_ym2610.o burn_ym2612.o \ burn_ym3526.o burn_ym3812.o burn_ymf278b.o c6280.o dac.o es5506.o es8712.o flt_rc.o fm.o fmopl.o gaelco.o ics2115.o iremga20.o \ diff --git a/src/burn/devices/c169.cpp b/src/burn/devices/c169.cpp new file mode 100644 index 000000000..34e9a86dc --- /dev/null +++ b/src/burn/devices/c169.cpp @@ -0,0 +1,158 @@ +#include "tiles_generic.h" + + +static UINT32 size; +static INT32 color; +static INT32 priority; + +static INT32 left; +static INT32 top; +static INT32 incxx; +static INT32 incxy; +static INT32 incyx; +static INT32 incyy; + +static INT32 startx=0; +static INT32 starty=0; + +static INT32 clip_min_y; +static INT32 clip_max_y; + +static UINT8 *roz_ram; +static UINT8 *roz_ctrl; +static UINT16 *roz_bitmap; + +void c169_roz_init(UINT8 *ram, UINT8 *control,UINT16 *bitmap) +{ + roz_ram = ram; + roz_ctrl = control; + roz_bitmap = bitmap; +} + +static void c169_roz_unpack_params(const UINT16 *source) +{ + const INT32 xoffset = 36, yoffset = 3; + + UINT16 temp = source[1]; + size = 512 << ((temp & 0x0300) >> 8); + color = (temp & 0x000f) * 256; + priority = (temp & 0x00f0) >> 4; + + temp = source[2]; + left = (temp & 0x7000) >> 3; + if (temp & 0x8000) temp |= 0xf000; else temp &= 0x0fff; // sign extend + incxx = (INT16)temp; + + temp = source[3]; + top = (temp&0x7000)>>3; + if (temp & 0x8000) temp |= 0xf000; else temp &= 0x0fff; // sign extend + incxy = (INT16)temp; + + temp = source[4]; + if (temp & 0x8000) temp |= 0xf000; else temp &= 0x0fff; // sign extend + incyx = (INT16)temp; + + temp = source[5]; + if (temp & 0x8000) temp |= 0xf000; else temp &= 0x0fff; // sign extend + incyy = (INT16)temp; + + startx = (INT16)source[6]; + starty = (INT16)source[7]; + startx <<= 4; + starty <<= 4; + + startx += xoffset * incxx + yoffset * incyx; + starty += xoffset * incxy + yoffset * incyy; + + startx <<= 8; + starty <<= 8; + incxx <<= 8; + incxy <<= 8; + incyx <<= 8; + incyy <<= 8; +} + +static void c169_roz_draw_helper() +{ + UINT32 size_mask = size - 1; + UINT16 *srcbitmap = roz_bitmap; + UINT32 hstartx = startx + 0 * incxx + clip_min_y * incyx; + UINT32 hstarty = starty + 0 * incxy + clip_min_y * incyy; + INT32 sx = 0; + INT32 sy = clip_min_y; + while (sy < clip_max_y) + { + INT32 x = sx; + UINT32 cx = hstartx; + UINT32 cy = hstarty; + UINT16 *dest = pTransDraw + (sy * nScreenWidth) + sx; + while (x < nScreenWidth) + { + UINT32 xpos = (((cx >> 16) & size_mask) + left) & 0xfff; + UINT32 ypos = (((cy >> 16) & size_mask) + top) & 0xfff; + INT32 pxl = srcbitmap[(ypos * 0x1000) + xpos]; + if ((pxl & 0x8000) == 0) + *dest = srcbitmap[(ypos * 0x1000) + xpos] + color; + cx += incxx; + cy += incxy; + x++; + dest++; + } + hstartx += incyx; + hstarty += incyy; + sy++; + } +} + +static void c169_roz_draw_scanline(int line, int pri) +{ + if (line >= 0 && line < nScreenHeight) + { + int row = line / 8; + int offs = row * 0x100 + (line & 7) * 0x10 + 0xe080; + UINT16 *source = (UINT16*)(roz_ram + offs); + + if ((source[1] & 0x8000) == 0) + { + if (pri == priority) + { + c169_roz_unpack_params(source); + + clip_min_y = line; + clip_max_y = line+1; + + c169_roz_draw_helper(); + } + } + } +} + +void c169_roz_draw(int pri) +{ + const UINT16 *source = (UINT16*)roz_ctrl; + + INT32 mode = source[0]; // 0x8000 or 0x1000 + + for (INT32 which = 1; which >= 0; which--) + { + UINT16 attrs = source[1 + (which*8)]; + if ((attrs & 0x8000) == 0) + { + if (which == 1 && mode == 0x8000) + { + for (INT32 line = 0; line < 224; line++) + c169_roz_draw_scanline(line, pri); + } + else + { + clip_min_y = 0; + clip_max_y = nScreenHeight; + + c169_roz_unpack_params(source + (which*8)); + if (priority == pri) + c169_roz_draw_helper(); + } + } + } +} + diff --git a/src/burn/devices/c169.h b/src/burn/devices/c169.h new file mode 100644 index 000000000..d4e20ba27 --- /dev/null +++ b/src/burn/devices/c169.h @@ -0,0 +1,2 @@ +void c169_roz_init(UINT8 *ram, UINT8 *control,UINT16 *bitmap); +void c169_roz_draw(int pri); diff --git a/src/burn/devices/namco_c45.cpp b/src/burn/devices/namco_c45.cpp new file mode 100644 index 000000000..30a84fa9f --- /dev/null +++ b/src/burn/devices/namco_c45.cpp @@ -0,0 +1,281 @@ +#include "tiles_generic.h" + + +UINT8 *c45RoadRAM; // external + +static UINT8 *c45RoadTiles = NULL; +static UINT16 *c45RoadBitmap = NULL; +static UINT8 *c45RoadBuffer = NULL; +static UINT8 *c45RoadClut = NULL; +static INT32 c45_road_force_update = 0; +static INT32 frame_decoded; +static UINT32 c45_road_transparent_color = 0; +static UINT8 c45_temp_clut[0x100]; + +void c45RoadReset() +{ + c45_road_force_update = 1; + frame_decoded = -1; +} + +void c45RoadInit(UINT32 trans_color, UINT8 *clut) +{ + c45RoadRAM = (UINT8*)BurnMalloc(0x20000); + c45RoadBuffer = (UINT8*)BurnMalloc(0x10000); + c45RoadTiles = (UINT8*)BurnMalloc(0x40000); + + c45RoadClut = clut; + c45RoadBitmap = (UINT16*)BurnMalloc(0x2000 * 0x400 * sizeof(UINT16)); + + c45_road_force_update = 1; + c45_road_transparent_color = trans_color; + + if (c45RoadClut == NULL) { + c45RoadClut = c45_temp_clut; + for (INT32 i = 0; i < 0x100; i++) c45RoadClut[i] = i; + } +} + +void c45RoadExit() +{ + if (c45RoadRAM != NULL) BurnFree(c45RoadRAM); + if (c45RoadBuffer != NULL) BurnFree(c45RoadBuffer); + if (c45RoadTiles != NULL) BurnFree(c45RoadTiles); + if (c45RoadBitmap != NULL) BurnFree(c45RoadBitmap); + + c45RoadClut = NULL; +} + +static void c45RoadGfxDecode() +{ + INT32 Planes[2] = { 0, 8 }; + INT32 XOffs[16] = { STEP8(0, 1), STEP8(16, 1) }; + INT32 YOffs[16] = { STEP16(0, 32) }; + + GfxDecode(0x0400, 2, 16, 16, Planes, XOffs, YOffs, 0x200, c45RoadRAM + 0x10000, c45RoadTiles); +} + +static void predraw_c45_road_tiles() +{ + UINT16 *ram = (UINT16*)c45RoadRAM; +// UINT16 *buf = (UINT16*)c45RoadBuffer; + + for (INT32 offs = 0; offs < 64 * 512; offs++) + { + INT32 sx = (offs & 0x3f) * 16; + INT32 sy = (offs / 0x40) * 16; + + // if ((ram[offs] == buf[offs]) && c45_road_force_update == 0) continue; + // buf[offs] = ram[offs]; + + INT32 code = (ram[offs] & 0x3ff) * 0x100; + INT32 color = ((ram[offs] >> 10) << 2) + 0xf00; + + UINT8 *gfx = c45RoadTiles + code; + UINT16 *dst = c45RoadBitmap + (sy * 1024) + sx; + + for (INT32 y = 0; y < 16; y++) + { + for (INT32 x = 0; x < 16; x++) + { + dst[x] = c45RoadClut[gfx[x]] + color; + } + + gfx += 16; + dst += 1024; + } + } + + c45_road_force_update = 0; +} + +#if 0 +void c45RoadDraw(int pri) +{ + if (frame_decoded != (INT32)(nCurrentFrame & 1)) { + c45RoadGfxDecode(); + predraw_c45_road_tiles(); + } + frame_decoded = (nCurrentFrame & 1); + + INT32 min_x, min_y, max_x, max_y; + + GenericTilesGetClip(&min_x, &max_x, &min_y, &max_y); + + max_x--; + max_y--; + + UINT16 *m_lineram = (UINT16*)(c45RoadRAM + 0x1fa00); + UINT32 yscroll = m_lineram[0x3fe/2]; + + static int ROAD_COLS = 64; + static int ROAD_ROWS = 512; + static int ROAD_TILE_SIZE = 16; + static int ROAD_TILEMAP_WIDTH = ROAD_TILE_SIZE * ROAD_COLS; + static int ROAD_TILEMAP_HEIGHT = ROAD_TILE_SIZE * ROAD_ROWS; + + for (int y = min_y; y <= max_y; y++) + { + int screenx = m_lineram[y + 15]; + if (pri != ((screenx & 0xf000) >> 12)) + continue; + + unsigned zoomx = m_lineram[0x400/2 + y + 15] & 0x3ff; + if (zoomx == 0) + continue; + + unsigned sourcey = m_lineram[0x200/2 + y + 15] + yscroll; + const UINT16 *source_gfx = c45RoadBitmap + (sourcey & (ROAD_TILEMAP_HEIGHT - 1)) * ROAD_TILEMAP_WIDTH; + unsigned dsourcex = (ROAD_TILEMAP_WIDTH << 16) / zoomx; + if (dsourcex == 0) + continue; + + screenx &= 0x0fff; + if (screenx & 0x0800) + screenx |= ~0x7ff; + + screenx -= 64; // needs adjustment to left + + int numpixels = (44 * (16 << 16)) / dsourcex; + unsigned sourcex = 0; + + int clip_pixels = min_x - screenx; + if (clip_pixels > 0) + { + numpixels -= clip_pixels; + sourcex += dsourcex*clip_pixels; + screenx = min_x; + } + + clip_pixels = (screenx + numpixels) - (max_x + 1); + if (clip_pixels > 0) + numpixels -= clip_pixels; + + UINT16 *dest = pTransDraw + y * nScreenWidth; + + while (numpixels-- > 0) + { + int pen = source_gfx[sourcex >> 16]; + if (c45RoadClut != NULL) + pen = (pen & ~0xff) | c45RoadClut[pen & 0xff]; + dest[screenx++] = pen; + sourcex += dsourcex; + } + + } +} +#endif + + +void c45RoadDraw(int pri) +{ + if (frame_decoded != (INT32)(nCurrentFrame & 1)) { + c45RoadGfxDecode(); + predraw_c45_road_tiles(); + } + frame_decoded = (nCurrentFrame & 1); + + INT32 min_x, min_y, max_x, max_y; + + min_x = min_y = 0; + max_y = nScreenHeight - 1; + max_x = nScreenWidth - 1; + + UINT16 *m_lineram = (UINT16*)(c45RoadRAM + 0x1fa00); + + static int ROAD_COLS = 64; + static int ROAD_ROWS = 512; + static int ROAD_TILE_SIZE = 16; + static int ROAD_TILEMAP_WIDTH = ROAD_TILE_SIZE * ROAD_COLS; + static int ROAD_TILEMAP_HEIGHT = ROAD_TILE_SIZE * ROAD_ROWS; + + static UINT8 *m_clut = c45RoadClut; +#define nullptr NULL + + static UINT32 m_transparent_color = c45_road_transparent_color; + + + + + + unsigned yscroll = m_lineram[0x3fe/2]; + + // loop over scanlines + for (int y = min_y; y <= max_y; y++) + { + // skip if we are not the right priority + int screenx = m_lineram[y + 15]; + if (pri != ((screenx & 0xf000) >> 12)) + continue; + + // skip if we don't have a valid zoom factor + unsigned zoomx = m_lineram[0x400/2 + y + 15] & 0x3ff; + if (zoomx == 0) + continue; + + // skip if we don't have a valid source increment + unsigned sourcey = m_lineram[0x200/2 + y + 15] + yscroll; +// const uint16_t *source_gfx = &source_bitmap.pix(sourcey & (ROAD_TILEMAP_HEIGHT - 1)); + const uint16_t *source_gfx = c45RoadBitmap + (sourcey & (ROAD_TILEMAP_HEIGHT - 1)) * ROAD_TILEMAP_WIDTH; + unsigned dsourcex = (ROAD_TILEMAP_WIDTH << 16) / zoomx; + if (dsourcex == 0) + continue; + + // mask off priority bits and sign-extend + screenx &= 0x0fff; + if (screenx & 0x0800) + screenx |= ~0x7ff; + + // adjust the horizontal placement + screenx -= 64; // needs adjustment to left + + int numpixels = (44 * ROAD_TILE_SIZE << 16) / dsourcex; + unsigned sourcex = 0; + + // crop left + int clip_pixels = min_x - screenx; + if (clip_pixels > 0) + { + numpixels -= clip_pixels; + sourcex += dsourcex*clip_pixels; + screenx = min_x; + } + + // crop right + clip_pixels = (screenx + numpixels) - (max_x + 1); + if (clip_pixels > 0) + numpixels -= clip_pixels; + + // TBA: work out palette mapping for Final Lap, Suzuka + + // BUT: support transparent color for Thunder Ceptor + // uint16_t *dest = &bitmap.pix(y); + uint16_t *dest = pTransDraw + y * nScreenWidth; + if (m_transparent_color != ~0) + { + while (numpixels-- > 0) + { + int pen = source_gfx[sourcex >> 16]; + // if (palette().pen_indirect(pen) != m_transparent_color) + { + if (m_clut != nullptr) + pen = (pen & ~0xff) | m_clut[pen & 0xff]; + dest[screenx] = pen; + } + screenx++; + sourcex += dsourcex; + } + } + else + { + while (numpixels-- > 0) + { + int pen = source_gfx[sourcex >> 16]; + if (m_clut != nullptr) + pen = (pen & ~0xff) | m_clut[pen & 0xff]; + dest[screenx++] = pen; + sourcex += dsourcex; + } + } + } +} diff --git a/src/burn/devices/namco_c45.h b/src/burn/devices/namco_c45.h new file mode 100644 index 000000000..627df7d77 --- /dev/null +++ b/src/burn/devices/namco_c45.h @@ -0,0 +1,6 @@ +extern UINT8 *c45RoadRAM; // external + +void c45RoadReset(); +void c45RoadInit(UINT32 trans_color, UINT8 *clut); +void c45RoadExit(); +void c45RoadDraw(INT32 pri); diff --git a/src/burn/drv/pst90s/d_namcos2.cpp b/src/burn/drv/pst90s/d_namcos2.cpp new file mode 100644 index 000000000..9cf25274d --- /dev/null +++ b/src/burn/drv/pst90s/d_namcos2.cpp @@ -0,0 +1,6416 @@ +// clipping not implimented +// only default inputs set up + + +// assault - +// bubbletr - ok, missing artwork (flipped) +// burnforc - roz layer not aligned correctly? +// cosmogng - +// dsaber - +// dirtfoxj - +// finallap - some bad gfx (sprites), bad sound +// finalap2 - bad sound +// finalap3 - bad sound +// finehour - missing graphics +// fourtrax - bad sound, road layer not wide enough?? +// gollygho - ok, missing artwork (flipped) +// kyukaidk - +// luckywld - road layer not wide enough? +// marvland - +// metlhawk - +// mirninja - +// ordyne - flipped! +// phelious - +// rthun2 - +// sgunner - +// sgunner2 - broken? was working... +// suzuk8h - +// suzuk8h2 - +// valkyrie - +// sws & clones - + + +#include "tiles_generic.h" +#include "m68000_intf.h" +#include "m6809_intf.h" +#include "m6805_intf.h" +#include "burn_ym2151.h" +#include "c140.h" +#include "c169.h" +#include "namco_c45.h" +#include "bitswap.h" + +// https://git.redump.net/mame/plain/src/mame/drivers/namcos2.cpp + +static UINT8 *AllMem; +static UINT8 *MemEnd; +static UINT8 *AllRam; +static UINT8 *RamEnd; +static UINT8 *Drv68KROM[2]; +static UINT8 *Drv68KData; +static UINT8 *DrvM6809ROM; +static UINT8 *DrvMCUROM; +static UINT8 *DrvGfxROM0; +static UINT8 *DrvGfxROM1; +static UINT8 *DrvGfxROM2; +static UINT8 *DrvGfxROM3; +static UINT8 *DrvGfxROM4; +static UINT8 *DrvGfxROM5; +static UINT8 *DrvSndROM; +static UINT8 *DrvEEPROM; +static UINT8 *DrvC45PROM; +static UINT8 *Drv68KRAM[2]; +static UINT8 *DrvC123RAM; +static UINT8 *DrvC139RAM; +static UINT8 *DrvRozRAM; +static UINT8 *DrvSprRAM; +static UINT8 *DrvPalRAM; +static UINT8 *DrvDPRAM; +static UINT8 *DrvMCURAM; +static UINT8 *DrvM6809RAM; +static UINT8 *DrvC123Ctrl; +static UINT8 *DrvRozCtrl; + +static UINT32 *DrvPalette; +static UINT8 DrvRecalc; + +static UINT16 gfx_ctrl; + +static UINT8 irq_reg[2]; +static UINT8 irq_cpu[2]; +static UINT8 irq_vblank[2]; +static UINT8 irq_ex[2]; +static UINT8 irq_pos[2]; +static UINT8 irq_sci[2]; +static UINT8 bus_reg[2]; + +static UINT16 c355_obj_position[4]; + +static INT32 audio_cpu_in_reset; +static INT32 sub_cpu_in_reset; // mcu & slave + +static INT32 layer_color; +static UINT8 *roz_dirty_tile; // 0x10000 +static UINT16 *roz_bitmap; // (256 * 8) * (256 * 8) +static INT32 roz_update_tiles = 0; // + +static UINT8 mcu_analog_ctrl; +static UINT8 mcu_analog_complete; +static UINT8 mcu_analog_data; + +static UINT32 maincpu_run_cycles = 0; +static UINT32 maincpu_run_ended = 0; + +static INT32 key_sendval; +static UINT16 (*key_prot_read)(UINT8 offset) = NULL; +static void (*key_prot_write)(UINT8 offset, UINT16 data) = NULL; + +static UINT8 DrvJoy1[8]; +static UINT8 DrvJoy2[8]; +static UINT8 DrvJoy3[8]; +static UINT8 DrvInputs[3]; +static UINT8 DrvDips[2]; +static UINT8 DrvReset; + +static struct BurnInputInfo DefaultInputList[] = { + {"P1 Coin", BIT_DIGITAL, DrvJoy2 + 5, "p1 coin" }, + {"P1 Start", BIT_DIGITAL, DrvJoy1 + 7, "p1 start" }, + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 5, "p1 up" }, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down" }, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left" }, + {"P1 Right", BIT_DIGITAL, DrvJoy3 + 7, "p1 right" }, + {"P1 Button 1", BIT_DIGITAL, DrvJoy3 + 5, "p1 fire 1" }, + {"P1 Button 2", BIT_DIGITAL, DrvJoy3 + 3, "p1 fire 2" }, + {"P1 Button 3", BIT_DIGITAL, DrvJoy3 + 1, "p1 fire 3" }, + + {"P2 Coin", BIT_DIGITAL, DrvJoy2 + 4, "p2 coin" }, + {"P2 Start", BIT_DIGITAL, DrvJoy1 + 6, "p2 start" }, + {"P2 Up", BIT_DIGITAL, DrvJoy1 + 4, "p2 up" }, + {"P2 Down", BIT_DIGITAL, DrvJoy1 + 2, "p2 down" }, + {"P2 Left", BIT_DIGITAL, DrvJoy1 + 0, "p2 left" }, + {"P2 Right", BIT_DIGITAL, DrvJoy3 + 6, "p2 right" }, + {"P2 Button 1", BIT_DIGITAL, DrvJoy3 + 4, "p2 fire 1" }, + {"P2 Button 2", BIT_DIGITAL, DrvJoy3 + 2, "p2 fire 2" }, + {"P2 Button 3", BIT_DIGITAL, DrvJoy3 + 0, "p2 fire 3" }, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset" }, + {"Service", BIT_DIGITAL, DrvJoy2 + 7, "service" }, + {"Service", BIT_DIGITAL, DrvJoy2 + 6, "service" }, + {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" }, + {"Debug", BIT_DIPSWITCH, DrvDips + 1, "dip" }, +}; + +STDINPUTINFO(Default) + +static struct BurnDIPInfo DefaultDIPList[]= +{ + {0x15, 0xff, 0xff, 0xff, NULL }, + {0x16, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2, "Video Display" }, + {0x15, 0x01, 0x01, 0x01, "Normal" }, + {0x15, 0x01, 0x01, 0x00, "Frozen" }, + + {0 , 0xfe, 0 , 2, "Service Mode" }, + {0x15, 0x01, 0x80, 0x80, "Off" }, + {0x15, 0x01, 0x80, 0x00, "On" }, +}; + +STDDIPINFO(Default) + + + +static void clear_all_irqs() +{ + for (INT32 i = 0; i < 8; i++) { + SekSetIRQLine(i, CPU_IRQSTATUS_NONE); + } +} + +static UINT16 c148_read_write(UINT32 offset, UINT16 data, INT32 w) +{ + INT32 a = SekGetActive(); + + switch (offset & 0x3e000) + { + case 0x00000: + return 0; + + case 0x04000: + if (w) bus_reg[a] = data & 7; + return bus_reg[a]; + + case 0x06000: + if (w) { irq_cpu[a] = data & 7; clear_all_irqs(); } + return irq_cpu[a]; + + case 0x08000: + if (w) { irq_ex[a] = data & 7; clear_all_irqs(); } + return irq_ex[a]; + + case 0x0a000: + if (w) { irq_pos[a] = data & 7; clear_all_irqs(); } + return irq_pos[a]; + + case 0x0c000: + if (w) { irq_sci[a] = data & 7; clear_all_irqs(); } + return irq_sci[a]; + + case 0x0e000: + if (w) { irq_vblank[a] = data & 7; clear_all_irqs(); } + return irq_vblank[a]; + + case 0x10000: + if (w) SekSetIRQLine(irq_cpu[a], CPU_IRQSTATUS_ACK); + return 0; + + case 0x16000: + SekSetIRQLine(irq_cpu[a], CPU_IRQSTATUS_NONE); + return 0; + + case 0x18000: + SekSetIRQLine(irq_ex[a], CPU_IRQSTATUS_NONE); + return 0; + + case 0x1a000: + SekSetIRQLine(irq_pos[a], CPU_IRQSTATUS_NONE); + return 0; + + case 0x1c000: + SekSetIRQLine(irq_sci[a], CPU_IRQSTATUS_NONE); + return 0; + + case 0x1e000: + SekSetIRQLine(irq_vblank[a], CPU_IRQSTATUS_NONE); + return 0; + + case 0x20000: + return 0xffff; // eeprom ready + + case 0x22000: // ext1_w -- callback + if (w && a == 0) + { + // if (data & 1) bprintf (0, _T("audio CPU on!\n")); + // if (!data & 1) bprintf (0, _T("audio CPU off!\n")); + audio_cpu_in_reset = ~data & 1; + if (audio_cpu_in_reset) M6809Reset(); + else { + maincpu_run_cycles = SekTotalCycles(); + maincpu_run_ended = 1; + SekRunEnd(); + } + } + return 0; + + case 0x24000: // ext2_w -- callback + if (w && a == 0) + { + sub_cpu_in_reset = ~data & 1; + if (sub_cpu_in_reset) + { + hd63705Reset(); + + SekClose(); + SekOpen(1); + SekReset(); + SekClose(); + SekOpen(0); + + // bprintf (0, _T("SUB CPUS off!\n")); + } + else + { + // bprintf (0, _T("SUB CPUS on!\n")); + maincpu_run_cycles = SekTotalCycles(); + maincpu_run_ended = 1; + SekRunEnd(); + } + } + return 0; + + case 0x26000: + return 0; // watchdog + } + + return 0; +} + +static UINT16 __fastcall namcos2_68k_read_word(UINT32 address) +{ + if ((address & 0xffc000) == 0x180000) { + return DrvEEPROM[(address / 2) & 0x1fff]; + } + + if ((address & 0xfc0000) == 0x1c0000) { // c148 + return c148_read_write(address, 0, 0); + } + + if ((address & 0xffffc0) == 0x420000) { + return *((UINT16*)(DrvC123Ctrl + (address & 0x3e))); + } + + if ((address & 0xff0000) == 0x440000) { + if ((address & 0x301e) > 0x3016) return 0xff; + return *((UINT16*)(DrvPalRAM + (address & 0x301e))); + } + + if ((address & 0xff0000) == 0x460000) { + return DrvDPRAM[(address & 0xffe)/2]; + } + + if ((address & 0xfffff0) == 0xcc0000) { + return *((UINT16*)(DrvRozCtrl + (address & 0x0e))); + } + + if ((address & 0xfffff0) == 0xd00000) { + if (key_prot_read != NULL) + return key_prot_read(address/2); + + return rand(); + } + + switch (address) + { + case 0x4a0000: + case 0x4a0001: + return 0x04; // c139 status + + case 0xc40000: + case 0xc40001: + return gfx_ctrl; + } + +// bprintf (0, _T("RW: %5.5x\n"), address); + + return 0; +} + +static UINT8 __fastcall namcos2_68k_read_byte(UINT32 address) +{ + if ((address & 0xffc000) == 0x180000) { + return DrvEEPROM[(address / 2) & 0x1fff]; + } + + if ((address & 0xffffc0) == 0x420000) { + return DrvC123Ctrl[(address & 0x3f)^1]; + } + + if ((address & 0xff0000) == 0x440000) { + if ((address & 0x301e) > 0x3016) return 0xff; + return *((UINT16*)(DrvPalRAM + (address & 0x301e))); + } + + if ((address & 0xff0000) == 0x460000) { + return DrvDPRAM[(address & 0xffe)/2]; + } + + if ((address & 0xfc0000) == 0x1c0000) { // c148 + return c148_read_write(address, 0, 0); + } + + bprintf (0, _T("RB: %5.5x\n"), address); + + return 0; +} + +static void __fastcall namcos2_68k_write_word(UINT32 address, UINT16 data) +{ + if ((address & 0xffc000) == 0x180000) { + DrvEEPROM[(address / 2) & 0x1fff] = data; + return; + } + + if ((address & 0xfc0000) == 0x1c0000) { + c148_read_write(address, data, 1); + return; + } + + if ((address & 0xffffc0) == 0x420000) { + *((UINT16*)(DrvC123Ctrl + (address & 0x3e))) = data; + return; + } + + if ((address & 0xff0000) == 0x440000) { + *((UINT16*)(DrvPalRAM + (address & 0x301e))) = data & 0xff; + return; + } + + if ((address & 0xff0000) == 0x460000) { + DrvDPRAM[(address & 0xffe)/2] = data; + return; + } + + if ((address & 0xfffff0) == 0xcc0000) { + *((UINT16*)(DrvRozCtrl + (address & 0x0e))) = data; + return; + } + + if ((address & 0xfffff0) == 0xd00000) { + if (key_prot_write != NULL) + return key_prot_write(address/2,data); + return; + } + + switch (address) + { + case 0xc40000: + gfx_ctrl = data; + return; + } + +// bprintf (0, _T("WW: %5.5x %4.4x\n"), address,data); +} + +static void __fastcall namcos2_68k_write_byte(UINT32 address, UINT8 data) +{ + if ((address & 0xffc000) == 0x180000) { + DrvEEPROM[(address / 2) & 0x1fff] = data; + return; + } + + if ((address & 0xff0000) == 0x440000) { + *((UINT16*)(DrvPalRAM + (address & 0x301e))) = data; + return; + } + + if ((address & 0xff0000) == 0x460000) { + DrvDPRAM[(address & 0xffe)/2] = data; + return; + } + + bprintf (0, _T("WB: %5.5x, %2.2x\n"),address,data); +} + + +static UINT16 __fastcall sgunner_68k_read_word(UINT32 address) +{ + if ((address & 0xfffff0) == 0xa00000) { + if (key_prot_read != NULL) + return key_prot_read(address/2); + + return rand(); + } + + return namcos2_68k_read_word(address); +} + +static UINT8 __fastcall sgunner_68k_read_byte(UINT32 address) +{ + if ((address & 0xfffff0) == 0xa00000) { + if (key_prot_read != NULL) + return key_prot_read(address/2); + + return rand(); + } + + return namcos2_68k_read_byte(address); +} + +static void __fastcall luckywld_68k_write_word(UINT32 address, UINT16 data) +{ + if ((address & 0xffffe0) == 0xd00000) { + *((UINT16*)(DrvRozCtrl + (address & 0x1e))) = data; + return; + } + + if ((address & 0xfffff8) == 0xf00000) { + if (key_prot_write != NULL) + key_prot_write(address/2,data); + return; + } + + if ((address & 0xfffff8) == 0x900000) { + c355_obj_position[(address/2) & 3] = data; + return; + } + + switch (address) + { + case 0x818000: + case 0x818001: + case 0x81a000: + case 0x81a001: + return; + } + + namcos2_68k_write_word(address, data); +} + + +static void __fastcall luckywld_68k_write_byte(UINT32 address, UINT8 data) +{ + if ((address & 0xffffe0) == 0xd00000) { + DrvRozCtrl[(address & 0x1f)^1] = data; + return; + } + + if ((address & 0xfffff8) == 0xf00000) { + if (key_prot_write != NULL) + key_prot_write(address/2,data); + return; + } + + switch (address) + { + case 0x818000: + case 0x818001: + case 0x81a000: + case 0x81a001: + return; + } + + namcos2_68k_write_byte(address, data); +} + +static UINT16 __fastcall luckywld_68k_read_word(UINT32 address) +{ + if ((address & 0xffffe0) == 0xd00000) { + return *((UINT16*)(DrvRozCtrl + (address & 0x1e))); + } + + if ((address & 0xfffff8) == 0xf00000) { + if (key_prot_read != NULL) + return key_prot_read(address/2); + + return rand(); + } + + if ((address & 0xfffff8) == 0x900000) { + return c355_obj_position[(address/2) & 3]; + } + + return namcos2_68k_read_word(address); +} + +static UINT8 __fastcall luckywld_68k_read_byte(UINT32 address) +{ + return namcos2_68k_read_byte(address); +} + +static void __fastcall metlhawk_68k_write_word(UINT32 address, UINT16 data) +{ + if ((address & 0xffffe0) == 0xd00000) { + *((UINT16*)(DrvRozCtrl + (address & 0x1e))) = data; + return; + } + + switch (address) + { + case 0xe00000: + gfx_ctrl = data; + return; + } + + namcos2_68k_write_word(address,data); +} + +static void __fastcall metlhawk_68k_write_byte(UINT32 address, UINT8 data) +{ + if ((address & 0xffffe0) == 0xd00000) { + DrvRozCtrl[(address & 0x1f)^1] = data; + return; + } + + namcos2_68k_write_word(address,data); +} + + +static UINT16 __fastcall metlhawk_68k_read_word(UINT32 address) +{ + if ((address & 0xffffe0) == 0xd00000) { + return *((UINT16*)(DrvRozCtrl + (address & 0x0e))); + } + + switch (address) + { + case 0xe00000: + case 0xe00001: + return gfx_ctrl; + } + + return namcos2_68k_read_word(address); +} + +static UINT8 __fastcall metlhawk_68k_read_byte(UINT32 address) +{ + if ((address & 0xffffe0) == 0xd00000) { + return DrvRozCtrl[(address & 0x1f)^1]; + } + + return namcos2_68k_read_byte(address); +} + +static INT32 m_finallap_prot_count = 0; + +static UINT16 namcos2_finallap_prot_read(INT32 offset) +{ + static const UINT16 table0[8] = { 0x0000,0x0040,0x0440,0x2440,0x2480,0xa080,0x8081,0x8041 }; + static const UINT16 table1[8] = { 0x0040,0x0060,0x0060,0x0860,0x0864,0x08e4,0x08e5,0x08a5 }; + + UINT16 data = 0; + + switch ((offset & 0x3ffff)/2) + { + case 0: + data = 0x0101; + break; + + case 1: + data = 0x3e55; + break; + + case 2: + data = table1[m_finallap_prot_count&7]; + data = (data&0xff00)>>8; + break; + + case 3: + data = table1[m_finallap_prot_count&7]; + m_finallap_prot_count++; + data = data&0x00ff; + break; + + case 0x3fffc/2: + data = table0[m_finallap_prot_count&7]; + data = data&0xff00; + break; + + case 0x3fffe/2: + data = table0[m_finallap_prot_count&7]; + m_finallap_prot_count++; + data = (data&0x00ff)<<8; + break; + + default: + data = 0; + } + return data; +} + +static void __fastcall finallap_68k_write_word(UINT32 address, UINT16 data) +{ + switch (address) + { + case 0x840000: + gfx_ctrl = data; + return; + } + + namcos2_68k_write_word(address,data); +} + +static void __fastcall finallap_68k_write_byte(UINT32 address, UINT8 data) +{ + namcos2_68k_write_byte(address,data); +} + +static UINT16 __fastcall finallap_68k_read_word(UINT32 address) +{ + if ((address & 0xfc0000) == 0x300000) { + return namcos2_finallap_prot_read(address); + } + + switch (address) + { + case 0x840000: + return gfx_ctrl; + } + + return namcos2_68k_read_word(address); +} + +static UINT8 __fastcall finallap_68k_read_byte(UINT32 address) +{ + if ((address & 0xfc0000) == 0x300000) { + return namcos2_finallap_prot_read(address) >> ((~address & 1) << 3); + } + + return namcos2_68k_read_byte(address); +} + +static void mcu_analog_ctrl_write(UINT8 data) +{ + mcu_analog_ctrl = data; + + if (data & 0x40) + { + mcu_analog_complete = 2; + + switch ((data >> 2) & 7) + { + case 0: mcu_analog_data = 0; break; // an0 + case 1: mcu_analog_data = 0; break; // an1 + case 2: mcu_analog_data = 0; break; // an2 + case 3: mcu_analog_data = 0; break; // an3 + case 4: mcu_analog_data = 0; break; // an4 + case 5: mcu_analog_data = 0; break; // an5 + case 6: mcu_analog_data = 0; break; // an6 + case 7: mcu_analog_data = 0; break; // an7 + } + } + + if (data & 0x20) + { + hd63705SetIrqLine(7, CPU_IRQSTATUS_ACK); + m6805Run(1); + hd63705SetIrqLine(7, CPU_IRQSTATUS_NONE); + } +} + +static UINT8 mcu_analog_ctrl_read() +{ + INT32 data = 0; + if (mcu_analog_complete == 2) mcu_analog_complete = 1; + if (mcu_analog_complete) data |= 0x80; + + return data | (mcu_analog_ctrl & 0x3f); +} + +static UINT8 mcu_port_d_r() +{ + INT32 threshold = 0x7f; + INT32 data = 0; + +// if(ioport("AN0")->read() > threshold) data |= 0x01; +// if(ioport("AN1")->read() > threshold) data |= 0x02; +// if(ioport("AN2")->read() > threshold) data |= 0x04; +// if(ioport("AN3")->read() > threshold) data |= 0x08; +// if(ioport("AN4")->read() > threshold) data |= 0x10; +// if(ioport("AN5")->read() > threshold) data |= 0x20; +// if(ioport("AN6")->read() > threshold) data |= 0x40; +// if(ioport("AN7")->read() > threshold) data |= 0x80; + + threshold &= 0xff; // iq_132 + + return data; +} + +static UINT8 namcos2_mcu_analog_port_r() +{ + if (mcu_analog_complete==1) mcu_analog_complete=0; + return mcu_analog_data; +} + +static void namcos2_mcu_write(UINT16 address, UINT8 data) +{ + if ((address & 0xf800) == 0x5000) { + DrvDPRAM[address & 0x7ff] = data; + return; + } + + switch (address) + { + case 0x0003: + // namcos2_mcu_port_d_w (unused) + return; + + case 0x0010: + mcu_analog_ctrl_write(data); + return; + + case 0x0011: + // mcu_analog_port_w (unused) + return; + } + + if (address < 0x1c0) { + DrvMCURAM[address] = data; + return; + } +} + +static UINT8 namcos2_mcu_read(UINT16 address) +{ + if ((address & 0xf000) == 0x6000) { + return 0; // watchdog + } + + if ((address & 0xf800) == 0x5000) { + return DrvDPRAM[address & 0x7ff]; + } + + switch (address) + { + case 0x0000: + return 0; + + case 0x0001: + return DrvInputs[0]; // mcub + + case 0x0002: + return DrvInputs[1]; // mcuc + + case 0x0003: + return mcu_port_d_r(); + + case 0x0007: + return DrvInputs[2]; // mcuh + + case 0x0010: + return mcu_analog_ctrl_read(); + + case 0x0011: + return namcos2_mcu_analog_port_r(); + + case 0x2000: + return DrvDips[0]; // dsw + + case 0x3000: + return 0xff; // MCUDI0 + + case 0x3001: + return 0xff; // MCUDI1 + + case 0x3002: + return 0xff; // MCUDI2 + + case 0x3003: + return 0xff; // MCUDI3 + } + + if (address < 0x1c0) { + return DrvMCURAM[address]; + } else if (address < 0x2000) { + return DrvMCUROM[address]; + } + + return 0; +} + +static void sound_bankswitch(INT32 data) +{ + INT32 bank = (data >> 4); + + M6809MapMemory(DrvM6809ROM + (bank * 0x4000), 0x0000, 0x3fff, MAP_ROM); +} + +static void namcos2_sound_write(UINT16 address, UINT8 data) +{ + if ((address & 0xf000) == 0x7000) { + DrvDPRAM[address & 0x7ff] = data; + return; + } + + if (address >= 0x5000 && address <= 0x6fff) { + c140_write(address,data); + return; + } + + if ((address & 0xe000) == 0xa000) { + // amplifier enable (unemulated) + return; + } + + switch (address) + { + case 0x4000: + BurnYM2151SelectRegister(data); + return; + + case 0x4001: + BurnYM2151WriteRegister(data); + return; + + case 0xc000: + case 0xc001: + sound_bankswitch(data); + return; + + case 0xd001: // watchdog + return; + + case 0xe000: // nop + return; + } +} + +static UINT8 namcos2_sound_read(UINT16 address) +{ + if ((address & 0xf000) == 0x7000) { + return DrvDPRAM[address & 0x7ff]; + } + + if (address >= 0x5000 && address <= 0x6fff) { + return c140_read(address); + } + + switch (address) + { + case 0x4000: + case 0x4001: + return BurnYM2151ReadStatus(); + } + + return 0; +} + + +static void __fastcall roz_write_word(UINT32 address, UINT16 data) +{ + UINT16 *ram = (UINT16*)DrvRozRAM; + + UINT16 offset = address / 2; + + if (ram[offset] != data) { + roz_dirty_tile[offset] = 1; + roz_update_tiles = 1; + ram[offset] = data; + } +} + +static void __fastcall roz_write_byte(UINT32 address, UINT8 data) +{ + INT32 offset = (address & 0x1ffff)^1; + + if (DrvRozRAM[offset] != data) { + roz_dirty_tile[offset/2] = 1; + roz_update_tiles = 1; + DrvRozRAM[offset] = data; + } +} + +static void default_68k_map(INT32 cpu) +{ + SekInit(cpu, 0x68000); + SekOpen(cpu); + SekMapMemory(Drv68KROM[cpu], 0x000000, 0x03ffff, MAP_ROM); + SekMapMemory(Drv68KRAM[cpu], 0x100000, 0x13ffff, MAP_RAM); + SekMapMemory(Drv68KData, 0x200000, 0x3fffff, MAP_ROM); + SekMapMemory(DrvC123RAM, 0x400000, 0x41ffff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x0000, 0x440000, 0x442fff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x4000, 0x444000, 0x446fff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x8000, 0x448000, 0x44afff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0xc000, 0x44c000, 0x44efff, MAP_RAM); + SekMapMemory(DrvC139RAM, 0x480000, 0x483fff, MAP_RAM); + SekMapMemory(DrvSprRAM, 0xc00000, 0xc03fff, MAP_RAM); + SekMapMemory(DrvRozRAM, 0xc80000, 0xc9ffff, MAP_RAM); + SekMapMemory(DrvRozRAM, 0xca0000, 0xcbffff, MAP_RAM); // mirror + SekSetWriteWordHandler(0, namcos2_68k_write_word); + SekSetWriteByteHandler(0, namcos2_68k_write_byte); + SekSetReadWordHandler(0, namcos2_68k_read_word); + SekSetReadByteHandler(0, namcos2_68k_read_byte); + + SekMapHandler(1, 0xc80000, 0xc9ffff, MAP_WRITE); + SekSetWriteByteHandler(1, roz_write_byte); + SekSetWriteWordHandler(1, roz_write_word); + + SekClose(); +} + +static void sgunner_68k_map(INT32 cpu) +{ + default_68k_map(cpu); + + SekOpen(cpu); + SekMapMemory(DrvSprRAM, 0x800000, 0x8143ff, MAP_RAM); // c355 + SekSetReadWordHandler(0, sgunner_68k_read_word); + SekSetReadByteHandler(0, sgunner_68k_read_byte); + SekClose(); +} + +static void metlhawk_68k_map(INT32 cpu) +{ + SekInit(cpu, 0x68000); + SekOpen(cpu); + SekMapMemory(Drv68KROM[cpu], 0x000000, 0x03ffff, MAP_ROM); + SekMapMemory(Drv68KRAM[cpu], 0x100000, 0x13ffff, MAP_RAM); + SekMapMemory(Drv68KData, 0x200000, 0x3fffff, MAP_ROM); + SekMapMemory(DrvC123RAM, 0x400000, 0x41ffff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x0000, 0x440000, 0x442fff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x4000, 0x444000, 0x446fff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x8000, 0x448000, 0x44afff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0xc000, 0x44c000, 0x44efff, MAP_RAM); + SekMapMemory(DrvC139RAM, 0x480000, 0x483fff, MAP_RAM); + SekMapMemory(DrvSprRAM, 0xc00000, 0xc03fff, MAP_RAM); + SekMapMemory(DrvRozRAM, 0xc40000, 0xc4ffff, MAP_RAM); + SekSetWriteWordHandler(0, metlhawk_68k_write_word); + SekSetWriteByteHandler(0, metlhawk_68k_write_byte); + SekSetReadWordHandler(0, metlhawk_68k_read_word); + SekSetReadByteHandler(0, metlhawk_68k_read_byte); + SekClose(); +} + +static void luckywld_68k_map(INT32 cpu) +{ + SekInit(cpu, 0x68000); + SekOpen(cpu); + SekMapMemory(Drv68KROM[cpu], 0x000000, 0x03ffff, MAP_ROM); + SekMapMemory(Drv68KRAM[cpu], 0x100000, 0x13ffff, MAP_RAM); + SekMapMemory(Drv68KData, 0x200000, 0x3fffff, MAP_ROM); + SekMapMemory(DrvC123RAM, 0x400000, 0x41ffff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x0000, 0x440000, 0x442fff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x4000, 0x444000, 0x446fff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x8000, 0x448000, 0x44afff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0xc000, 0x44c000, 0x44efff, MAP_RAM); + SekMapMemory(DrvC139RAM, 0x480000, 0x483fff, MAP_RAM); + SekMapMemory(DrvSprRAM, 0x800000, 0x8141ff, MAP_RAM); + SekMapMemory(c45RoadRAM, 0xa00000, 0xa1ffff, MAP_RAM); + SekMapMemory(DrvRozRAM, 0xc00000, 0xc0ffff, MAP_RAM); + SekSetWriteWordHandler(0, luckywld_68k_write_word); + SekSetWriteByteHandler(0, luckywld_68k_write_byte); + SekSetReadWordHandler(0, luckywld_68k_read_word); + SekSetReadByteHandler(0, luckywld_68k_read_byte); + SekClose(); +} + +static void finallap_68k_map(INT32 cpu) +{ + SekInit(cpu, 0x68000); + SekOpen(cpu); + SekMapMemory(Drv68KROM[cpu], 0x000000, 0x03ffff, MAP_ROM); + SekMapMemory(Drv68KRAM[cpu], 0x100000, 0x13ffff, MAP_RAM); +// SekMapMemory(Drv68KData, 0x200000, 0x2fffff, MAP_ROM); +// SekMapMemory(Drv68KData + 0x140000, 0x340000, 0x3fffff, MAP_ROM); + SekMapMemory(DrvC123RAM, 0x400000, 0x41ffff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x0000, 0x440000, 0x442fff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x4000, 0x444000, 0x446fff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0x8000, 0x448000, 0x44afff, MAP_RAM); + SekMapMemory(DrvPalRAM + 0xc000, 0x44c000, 0x44efff, MAP_RAM); + SekMapMemory(DrvC139RAM, 0x480000, 0x483fff, MAP_RAM); + SekMapMemory(DrvSprRAM, 0x800000, 0x80ffff, MAP_RAM); + SekMapMemory(c45RoadRAM, 0x880000, 0x89ffff, MAP_RAM); + SekSetWriteWordHandler(0, finallap_68k_write_word); + SekSetWriteByteHandler(0, finallap_68k_write_byte); + SekSetReadWordHandler(0, finallap_68k_read_word); + SekSetReadByteHandler(0, finallap_68k_read_byte); + SekClose(); +} + +static void namcos2_sound_init() +{ + M6809Init(1); + M6809Open(0); +// M6809MapMemory(DrvDPRAM, 0x7000, 0x77ff, MAP_RAM); +// M6809MapMemory(DrvDPRAM, 0x7800, 0x7fff, MAP_RAM); + M6809MapMemory(DrvM6809RAM, 0x8000, 0x9fff, MAP_RAM); + M6809MapMemory(DrvM6809ROM, 0xc000, 0xffff, MAP_ROM); + M6809SetWriteHandler(namcos2_sound_write); + M6809SetReadHandler(namcos2_sound_read); + M6809Close(); + + BurnYM2151Init(3579545); + BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_1, 1.00, BURN_SND_ROUTE_LEFT); + BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_2, 1.00, BURN_SND_ROUTE_RIGHT); + + c140_init(21333, C140_TYPE_SYSTEM2, DrvSndROM); +} + +static void namcos2_mcu_init() +{ + m6805Init(1, 1 << 16); + m6805Open(0); +// m6805MapMemory(DrvMCURAM + 0x0100, 0x0100, 0x01ff, MAP_RAM); + m6805MapMemory(DrvMCUROM + 0x0200, 0x0200, 0x1fff, MAP_ROM); +// m6805MapMemory(DrvDPRAM, 0x5000, 0x57ff, MAP_RAM); + m6805MapMemory(DrvMCUROM + 0x8000, 0x8000, 0xffff, MAP_ROM); + m6805SetWriteHandler(namcos2_mcu_write); + m6805SetReadHandler(namcos2_mcu_read); + m6805Close(); +} + +static INT32 DrvDoReset() +{ + memset (AllRam, 0, RamEnd - AllRam); + + memset (roz_dirty_tile, 1, 0x10000); + roz_update_tiles = 1; + + SekOpen(0); + SekReset(); + SekClose(); + + SekOpen(1); + SekReset(); + SekClose(); + + M6809Open(0); + M6809Reset(); + sound_bankswitch(0); + BurnYM2151Reset(); + c140_reset(); + M6809Close(); + + m6805Open(0); + hd63705Reset(); + m6805Close(); + + c45RoadReset(); + + gfx_ctrl = 0; + + irq_reg[1] = irq_reg[0] = 0; + irq_cpu[1] = irq_cpu[0] = 0; + irq_vblank[1] = irq_vblank[0] = 0; + irq_ex[1] = irq_ex[0] = 0; + irq_pos[1] = irq_pos[0] = 0; + irq_sci[1] = irq_sci[0] = 0; + bus_reg[1] = bus_reg[0] = 0; + + audio_cpu_in_reset = 1; + sub_cpu_in_reset = 1; // mcu & slave + + key_sendval = 0; + + mcu_analog_ctrl = 0; + mcu_analog_data = 0xaa; + mcu_analog_complete = 0; + + c355_obj_position[0] = c355_obj_position[1] = 0; + c355_obj_position[2] = c355_obj_position[3] = 0; + + return 0; +} + +static INT32 MemIndex() +{ + UINT8 *Next; Next = AllMem; + + Drv68KROM[0] = Next; Next += 0x040000; + Drv68KROM[1] = Next; Next += 0x040000; + Drv68KData = Next; Next += 0x200000; + DrvM6809ROM = Next; Next += 0x040000; + DrvMCUROM = Next; Next += 0x010000; + + DrvC45PROM = Next; Next += 0x000100; + + DrvGfxROM0 = Next; Next += 0x400000; // sprite 32x32 + DrvGfxROM1 = Next; Next += 0x400000; // sprite 16x16 + DrvGfxROM2 = Next; Next += 0x400000; // char + DrvGfxROM3 = Next; Next += 0x400000; // roz + + DrvGfxROM4 = Next; Next += 0x080000; // char mask + DrvGfxROM5 = Next; Next += 0x080000; // roz mask + + DrvSndROM = Next; Next += 0x100000; + + DrvEEPROM = Next; Next += 0x002000; + + roz_dirty_tile = Next; Next += 0x020000; + roz_bitmap = (UINT16*)Next; Next += ((256 * 16) * (256 * 16) * 2); + + DrvPalette = (UINT32*)Next; Next += 0x4001 * sizeof(UINT32); + + AllRam = Next; + + Drv68KRAM[0] = Next; Next += 0x040000; + Drv68KRAM[1] = Next; Next += 0x040000; + DrvC123RAM = Next; Next += 0x020000; + DrvC139RAM = Next; Next += 0x004000; + DrvRozRAM = Next; Next += 0x020000; + DrvSprRAM = Next; Next += 0x004000 + 0x10400; + DrvPalRAM = Next; Next += 0x010000; + DrvDPRAM = Next; Next += 0x000800; + DrvMCURAM = Next; Next += 0x000200; + DrvM6809RAM = Next; Next += 0x002000; + + DrvC123Ctrl = Next; Next += 0x000040; + DrvRozCtrl = Next; Next += 0x000010; + + RamEnd = Next; + + MemEnd = Next; + + return 0; +} + +static void DoMirror(UINT8 *rom, INT32 size, INT32 mirror_size) +{ + for (INT32 i = mirror_size; i < size; i+=mirror_size) + { + memcpy (rom + i, rom, mirror_size); + } +} + +static INT32 Namcos2GetRoms(INT32 gfx0_offset) +{ + char* pRomName; + struct BurnRomInfo ri; + struct BurnRomInfo pi; + + UINT8 *m6809 = DrvM6809ROM; + UINT8 *mcu = DrvMCUROM; + UINT8 *gfx[5] = { DrvGfxROM0 + gfx0_offset, DrvGfxROM2, DrvGfxROM3, DrvGfxROM4 }; + UINT8 *snd = DrvSndROM; + UINT8 *data = Drv68KData; + + memset (DrvEEPROM, 0xff, 0x002000); + memset (DrvGfxROM0, 0xff, 0x400000); + + for (INT32 i = 0; !BurnDrvGetRomName(&pRomName, i, 0); i++) + { + BurnDrvGetRomInfo(&ri, i); + BurnDrvGetRomInfo(&pi, i+1); + + INT32 use_size = ri.nType & 0x10; + + if ((ri.nType & BRF_PRG) && (ri.nType & 0x0f) < 3) { + INT32 c = (ri.nType - 1) & 1; + if (BurnLoadRom(Drv68KROM[c] + 0x000001, i + 0, 2)) return 1; + if (BurnLoadRom(Drv68KROM[c] + 0x000000, i + 1, 2)) return 1; + i++; + continue; + } + + if ((ri.nType & BRF_PRG) && (ri.nType & 0x0f) == 3) { + if (BurnLoadRom(m6809, i, 1)) return 1; + m6809 += ri.nLen; + continue; + } + + if ((ri.nType & BRF_PRG) && (ri.nType & 0x0f) == 4) { + if (BurnLoadRom(mcu, i, 1)) return 1; + mcu += 0x8000; + continue; + } + + if ((ri.nType & BRF_GRA) && ((ri.nType & 0x0f) >= 5 && (ri.nType & 0x0f) < 9)) { + if (BurnLoadRom(gfx[(ri.nType - 5) & 0xf], i, 1)) return 1; + + if (use_size) { + gfx[(ri.nType - 5) & 0xf] += ri.nLen; + } else { + if (ri.nLen < 0x80000) DoMirror(gfx[(ri.nType - 5) & 0xf], 0x80000, ri.nLen); + gfx[(ri.nType - 5) & 0xf] += 0x80000; + } + continue; + } + + if ((ri.nType & BRF_PRG) && (ri.nType & 0x0f) == 9) { + if (BurnLoadRom(data + 0x00001, i + 0, 2)) return 1; + + if ((pi.nType & BRF_PRG) && (pi.nType & 0x0f) == 9) { + if (BurnLoadRom(data + 0x00000, i + 1, 2)) return 1; + i++; + } + + if (ri.nLen < 0x80000) DoMirror(data, 0x100000, ri.nLen*2); + data += 0x100000; + continue; + } + + if ((ri.nType & BRF_SND) && (ri.nType & 0x0f) == 0x0a) { + if (BurnLoadRom(snd, i, 1)) return 1; + if (ri.nLen < 0x80000) DoMirror(snd, 0x80000, ri.nLen); + snd += 0x80000; + continue; + } + + if ((ri.nType & BRF_PRG) && (ri.nType & 0x0f) == 11) { + if (BurnLoadRom(DrvEEPROM, i, 1)) return 1; + continue; + } + + if ((ri.nType & BRF_GRA) && (ri.nType & 0x0f) == 12) { + if (BurnLoadRom(DrvC45PROM, i, 1)) return 1; + continue; + } + if ((ri.nType & BRF_GRA) && ((ri.nType & 0x0f) == 13)) { + if (BurnLoadRom(DrvGfxROM5, i, 1)) return 1; + continue; + } + } + + if ((m6809 - DrvM6809ROM) == 0x20000) memcpy (DrvM6809ROM + 0x20000, DrvM6809ROM, 0x20000); // mirror + + if (strncmp(BurnDrvGetTextA(DRV_NAME), "ordyne", 6) == 0) { + memmove (DrvGfxROM2 + 0x280000, DrvGfxROM2 + 0x180000, 0x180000); + memmove (DrvGfxROM2 + 0x180000, DrvGfxROM2 + 0x100000, 0x080000); + } + + return 0; +} + +static INT32 DrvGfxDecode() +{ + INT32 Plane0[8] = { + (0x400000*3),(0x400000*3)+4,(0x400000*2),(0x400000*2)+4, + (0x400000*1),(0x400000*1)+4,(0x400000*0),(0x400000*0)+4 + }; + INT32 XOffs0[32] = { + STEP4( 0,1), STEP4( 8,1), STEP4(16,1), STEP4(24,1), + STEP4(32,1), STEP4(40,1), STEP4(48,1), STEP4(56,1) + }; + INT32 YOffs0[32] = { STEP32(0,64) }; + + UINT8 *tmp = (UINT8*)BurnMalloc(0x400000); + if (tmp == NULL) { + return 1; + } + + memcpy (tmp, DrvGfxROM0, 0x400000); + + GfxDecode(0x0800, 8, 32, 32, Plane0, XOffs0, YOffs0, 0x800, tmp + 0x0000000, DrvGfxROM0 + 0x0000000); + GfxDecode(0x0800, 8, 32, 32, Plane0, XOffs0, YOffs0, 0x800, tmp + 0x0200000, DrvGfxROM0 + 0x0200000); + + BurnFree(tmp); + + for (INT32 i = 0; i < 0x400000; i++) + { + INT32 j = (i & 0xffffe0f) | ((i & 0x10) << 4) | ((i & 0x1e0) >> 1); + + DrvGfxROM1[j] = DrvGfxROM0[i]; + } + + return 0; +} + +static void decode_layer_tiles() +{ + UINT8 *tmp = (UINT8*)BurnMalloc(0x400000); + + for (INT32 i = 0; i < 0x400000/0x40; i++) + { + INT32 j = (i & 0x07ff) | ((i & 0xc000) >> 3) | ((i & 0x3800) << 2); + + memcpy (tmp + i * 0x40, DrvGfxROM2 + j * 0x40, 0x40); + } + + memcpy (DrvGfxROM2, tmp, 0x400000); + + BurnFree(tmp); +} + +static void decode_layer_tiles_finalap2() +{ + UINT8 *tmp = (UINT8*)BurnMalloc(0x400000); + + for (INT32 i = 0; i < 0x200000/0x40; i++) + { + INT32 j = (i & 0x07ff) | ((i & 0x4000) >> 3) | ((i & 0x3800) << 1); + + memcpy (tmp + i * 0x40, DrvGfxROM2 + j * 0x40, 0x40); + } + + memcpy (DrvGfxROM2, tmp, 0x400000); + + BurnFree(tmp); +} + +static INT32 Namcos2Init(void (*key_write)(UINT8,UINT16), UINT16 (*key_read)(UINT8)) +{ + AllMem = NULL; + MemIndex(); + INT32 nLen = MemEnd - (UINT8 *)0; + if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1; + memset(AllMem, 0, nLen); + MemIndex(); + + memset (DrvEEPROM, 0xff, 0x2000); // iq_132 remove me! + + { + if (Namcos2GetRoms(0)) return 1; + + DrvGfxDecode(); // decode sprites + decode_layer_tiles(); + } + + default_68k_map(0); + default_68k_map(1); + namcos2_sound_init(); + namcos2_mcu_init(); + + key_prot_read = key_read; + key_prot_write = key_write; + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static void LuckywldGfxDecode() +{ + for (INT32 i = 0 ; i < 0x400000; i++) { + DrvGfxROM1[i] = DrvGfxROM0[(i / 4) | ((i & 3) << 20)]; + } +} + +static INT32 SgunnerCommonInit(void (*key_write)(UINT8,UINT16), UINT16 (*key_read)(UINT8)) +{ + AllMem = NULL; + MemIndex(); + INT32 nLen = MemEnd - (UINT8 *)0; + if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1; + memset(AllMem, 0, nLen); + MemIndex(); + + memset (DrvEEPROM, 0xff, 0x2000); // iq_132 remove me! + + { + if (Namcos2GetRoms(0)) return 1; + + LuckywldGfxDecode(); + decode_layer_tiles(); + } + + sgunner_68k_map(0); + sgunner_68k_map(1); + namcos2_sound_init(); + namcos2_mcu_init(); + + key_prot_read = key_read; + key_prot_write = key_write; + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static INT32 Suzuka8hCommonInit(void (*key_write)(UINT8,UINT16), UINT16 (*key_read)(UINT8)) +{ + AllMem = NULL; + MemIndex(); + INT32 nLen = MemEnd - (UINT8 *)0; + if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1; + memset(AllMem, 0, nLen); + MemIndex(); + + memset (DrvEEPROM, 0xff, 0x2000); // iq_132 remove me! + + { + if (Namcos2GetRoms(0)) return 1; + + LuckywldGfxDecode(); + decode_layer_tiles(); + } + + c45RoadInit(~0, DrvC45PROM); + + luckywld_68k_map(0); + luckywld_68k_map(1); + namcos2_sound_init(); + namcos2_mcu_init(); + + key_prot_read = key_read; + key_prot_write = key_write; + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static void luckywld_roz_decode() +{ + UINT8 *tmp = (UINT8*)BurnMalloc(0x400000); + + for (INT32 i = 0; i < 0x4000; i++) + { + INT32 j = i & 0x1ff; + + switch (i >> 9) + { + case 0x00: j |= 0x1c00; break; + case 0x01: j |= 0x0800; break; + case 0x02: j |= 0x0000; break; + case 0x08: j |= 0x1e00; break; + case 0x09: j |= 0x0a00; break; + case 0x0a: j |= 0x0200; break; + case 0x10: j |= 0x2000; break; + case 0x11: j |= 0x0c00; break; + case 0x12: j |= 0x0400; break; + case 0x18: j |= 0x2200; break; + case 0x19: j |= 0x0e00; break; + case 0x1a: j |= 0x0600; break; + } + + memcpy (tmp + i * 0x100, DrvGfxROM3 + j * 0x100, 0x100); + } + + memcpy (DrvGfxROM3, tmp, 0x400000); + + BurnFree(tmp); +} + +static INT32 LuckywldInit() +{ + AllMem = NULL; + MemIndex(); + INT32 nLen = MemEnd - (UINT8 *)0; + if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1; + memset(AllMem, 0, nLen); + MemIndex(); + + memset (DrvEEPROM, 0xff, 0x2000); // iq_132 remove me! + + { + if (Namcos2GetRoms(0)) return 1; + + LuckywldGfxDecode(); + decode_layer_tiles(); + + for (INT32 i = 0; i < 0x80000; i++) { + DrvGfxROM5[i] = BITSWAP08(DrvGfxROM5[i], 0,1,2,3,4,5,6,7); + } + + memcpy (DrvGfxROM3 + 0x1c0000, DrvGfxROM3 + 0x180000, 0x080000); + + luckywld_roz_decode(); + } + + c45RoadInit(~0, DrvC45PROM); + + luckywld_68k_map(0); + luckywld_68k_map(1); + namcos2_sound_init(); + namcos2_mcu_init(); + + c169_roz_init(DrvRozRAM, DrvRozCtrl, roz_bitmap); + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static void metal_hawk_sprite_decode() +{ + UINT8 *data = DrvGfxROM0; + for (int i=0; i<0x200000; i+=32*32) + { + for (int j=0; j<32*32; j+=32*4) + { + for (int k=0; k<32; k+=4) + { + INT32 a = i+j+k+32; + UINT8 v = data[a]; + data[a] = data[a+3]; + data[a+3] = data[a+2]; + data[a+2] = data[a+1]; + data[a+1] = v; + + a += 32; + v = data[a]; + data[a] = data[a+2]; + data[a+2] = v; + v = data[a+1]; + data[a+1] = data[a+3]; + data[a+3] = v; + + a += 32; + data[a] = data[a+1]; + data[a+1] = data[a+2]; + data[a+2] = data[a+3]; + data[a+3] = v; + + a = i+j+k; + for (int l=0; l<4; l++) + { + v = data[a+l+32]; + data[a+l+32] = data[a+l+32*3]; + data[a+l+32*3] = v; + } + } + } + } + + for (int i=0; i<0x200000; i+=32*32) + { + for (int j=0; j<32; j++) + { + for (int k=0; k<32; k++) + { + data[0x200000+i+j*32+k] = data[i+j+k*32]; + } + } + } + + for (INT32 i = 0; i < 0x400000; i++) + { + INT32 j = (i & 0xffffe0f) | ((i & 0x10) << 4) | ((i & 0x1e0) >> 1); + + DrvGfxROM1[j] = DrvGfxROM0[i]; + } +} + +static void metal_hawk_roz_decode() +{ + UINT8 *tmp = (UINT8*)BurnMalloc(0x200000); + + for (INT32 i = 0; i < 0x200000/0x100; i++) + { + INT32 j = (i & 0x01ff) | ((i & 0xe00) << 1) | ((i & 0x1000) >> 3); + + memcpy (tmp + i * 0x100, DrvGfxROM3 + j * 0x100, 0x100); + } + + memcpy (DrvGfxROM3, tmp, 0x200000); + + BurnFree(tmp); +} + +static INT32 MetlhawkInit() +{ + AllMem = NULL; + MemIndex(); + INT32 nLen = MemEnd - (UINT8 *)0; + if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1; + memset(AllMem, 0, nLen); + MemIndex(); + + { + if (Namcos2GetRoms(0)) return 1; + + if (BurnLoadRom(DrvGfxROM0 + 0x000000, 7, 4)) return 1; + if (BurnLoadRom(DrvGfxROM0 + 0x000001, 8, 4)) return 1; + if (BurnLoadRom(DrvGfxROM0 + 0x000002, 9, 4)) return 1; + if (BurnLoadRom(DrvGfxROM0 + 0x000003, 10, 4)) return 1; + if (BurnLoadRom(DrvGfxROM0 + 0x100000, 11, 4)) return 1; + if (BurnLoadRom(DrvGfxROM0 + 0x100001, 12, 4)) return 1; + if (BurnLoadRom(DrvGfxROM0 + 0x100002, 13, 4)) return 1; + if (BurnLoadRom(DrvGfxROM0 + 0x100003, 14, 4)) return 1; + + + for (INT32 i = 0; i < 8; i++) { + BurnLoadRom(DrvGfxROM3 + i * 0x40000, 19+i, 1); + } + + metal_hawk_sprite_decode(); + decode_layer_tiles(); + metal_hawk_roz_decode(); + } + + metlhawk_68k_map(0); + metlhawk_68k_map(1); + namcos2_sound_init(); + namcos2_mcu_init(); + + c169_roz_init(DrvRozRAM, DrvRozCtrl, roz_bitmap); + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static INT32 FinallapInit() +{ + AllMem = NULL; + MemIndex(); + INT32 nLen = MemEnd - (UINT8 *)0; + if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1; + memset(AllMem, 0, nLen); + MemIndex(); + + { + if (Namcos2GetRoms(0x200000)) return 1; + + DrvGfxDecode(); // decode sprites + decode_layer_tiles(); + } + + c45RoadInit(~0, DrvC45PROM); + + finallap_68k_map(0); + finallap_68k_map(1); + namcos2_sound_init(); + namcos2_mcu_init(); + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static INT32 Finalap2Init() +{ + AllMem = NULL; + MemIndex(); + INT32 nLen = MemEnd - (UINT8 *)0; + if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1; + memset(AllMem, 0, nLen); + MemIndex(); + + { + if (Namcos2GetRoms(0)) return 1; + + DrvGfxDecode(); // decode sprites + decode_layer_tiles_finalap2(); + } + + c45RoadInit(~0, DrvC45PROM); + + finallap_68k_map(0); + finallap_68k_map(1); + namcos2_sound_init(); + namcos2_mcu_init(); + + SekOpen(0); + SekMapMemory(Drv68KData, 0x200000, 0x2fffff, MAP_ROM); + SekMapMemory(Drv68KData + 0x140000, 0x340000, 0x3fffff, MAP_ROM); + + SekClose(); + + SekOpen(1); + SekMapMemory(Drv68KData, 0x200000, 0x2fffff, MAP_ROM); + SekMapMemory(Drv68KData + 0x140000, 0x340000, 0x3fffff, MAP_ROM); + + SekClose(); + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static INT32 FourtraxInit() +{ + AllMem = NULL; + MemIndex(); + INT32 nLen = MemEnd - (UINT8 *)0; + if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1; + memset(AllMem, 0, nLen); + MemIndex(); + + { + if (Namcos2GetRoms(0)) return 1; + + DrvGfxDecode(); // decode sprites + decode_layer_tiles(); + } + + c45RoadInit(~0, DrvC45PROM); + + finallap_68k_map(0); + finallap_68k_map(1); + namcos2_sound_init(); + namcos2_mcu_init(); + + SekOpen(0); + SekMapMemory(Drv68KData, 0x200000, 0x3fffff, MAP_ROM); + SekClose(); + + SekOpen(1); + SekMapMemory(Drv68KData, 0x200000, 0x3fffff, MAP_ROM); + SekClose(); + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static INT32 Namcos2Exit() +{ + GenericTilesExit(); + + SekExit(); + M6809Exit(); + m6805Exit(); + + BurnYM2151Exit(); + c140_exit(); + + c45RoadExit(); + + BurnFree (AllMem); + + key_prot_read = NULL; + key_prot_write = NULL; + + return 0; +} + +#if 0 +static void apply_clip() +{ + UINT16 *p = (UINT16*)(DrvPalRAM + 0x3000); + + GenericTilesSetClip(p[0] - 0x4a, p[1] - 0x4a, p[2] - 0x21, p[3] - 0x21); +} +#endif + +static void DrvRecalcPalette() +{ + UINT16 *ram = (UINT16*)DrvPalRAM; + + for (INT32 bank = 0; bank < 0x20; bank++) + { + int pen = bank * 256; + int offset = ((pen & 0x1800) << 2) | (pen & 0x0700); + + for (INT32 i = 0; i < 256; i++) + { + UINT8 r = ram[offset + i + 0x0000]; + UINT8 g = ram[offset + i + 0x0800]; + UINT8 b = ram[offset + i + 0x1000]; + + DrvPalette[pen + i] = BurnHighCol(r,g,b,0); + + DrvPalette[pen + i + 0x2000] = BurnHighCol(r/2,g/2,b/2,0); // shadow + } + } +} + +static void draw_layer_with_masking(INT32 layer, INT32 color) +{ + if (layer >= 6) return; + + if ((nSpriteEnable & (1<= 4) { + scrollx = scrolly = 0; + } + + color = ((color & 7) * 256) + 0x1000; + + for (INT32 offs = 0; offs < sizex * sizey; offs++) + { + INT32 sx = (offs % sizex) * 8; + INT32 sy = (offs / sizex) * 8; + + sx -= scrollx; + sy -= scrolly; + if (sx < -7) sx += sizex_full; + if (sy < -7) sy += sizey_full; + + if (flipscreen) { + sx = (nScreenWidth - 8) - sx; + sy = (nScreenHeight - 8) - sy; + } + + if (sx >= nScreenWidth || sy >= nScreenHeight) continue; + + INT32 code = ram[offs]; + UINT8 *gfx = DrvGfxROM2 + (code * 8 * 8); + UINT8 *msk = DrvGfxROM4 + (code * 8); + + if (flipscreen) + { + gfx += 8 * 7; + msk += 7; + + for (INT32 y = 0; y < 8; y++, msk--, gfx-=8) + { + if ((sy+y) < 0) continue; + if ((sy+y) >= nScreenHeight) break; + + for (INT32 x = 0; x < 8; x++) + { + if ((sx + x) < 0 || (sx + x) >= nScreenWidth) continue; + + if (*msk & (0x01 << x)) + { + pTransDraw[(sy + y) * nScreenWidth + (sx + x)] = gfx[7 - x] + color; + } + } + } + } else { + for (INT32 y = 0; y < 8; y++, msk++, gfx+=8) + { + if ((sy+y) < 0) continue; + if ((sy+y) >= nScreenHeight) break; + + for (INT32 x = 0; x < 8; x++) + { + if ((sx + x) < 0 || (sx + x) >= nScreenWidth) continue; + + if (*msk & (0x80 >> x)) + { + pTransDraw[(sy + y) * nScreenWidth + (sx + x)] = gfx[x] + color; + } + } + } + } + } +} + +static void draw_layer(INT32 pri) +{ + UINT16 *ctrl = (UINT16*)DrvC123Ctrl; + + for (INT32 i = 0; i < 6; i++) + { + if((ctrl[0x10+i] & 0xf) == pri) + { + layer_color = ctrl[0x18 + i]; + draw_layer_with_masking(i, layer_color); + } + } +} + +static void predraw_roz_layer() +{ + if (roz_update_tiles == 0) return; // tiles not updated + + UINT16 *ram = (UINT16*)DrvRozRAM; + + for (INT32 offs = 0; offs < 256 * 256; offs++) + { + if (roz_dirty_tile[offs] == 0) continue; + roz_dirty_tile[offs] = 0; + + INT32 sx = (offs & 0xff) * 8; + INT32 sy = (offs / 256) * 8; + + UINT8 *gfx = DrvGfxROM3 + (ram[offs] * 0x40); + UINT16 *dst = roz_bitmap + (sy * 256 * 8) + sx; + + for (INT32 y = 0; y < 8; y++, dst += (256 * 8)) { + for (INT32 x = 0; x < 8; x++, gfx++) { + dst[x] = *gfx; + } + } + } + + roz_update_tiles = 0; +} + +static void zdrawgfxzoom(UINT8 *gfx,INT32 tile_size, uint32_t code,uint32_t color,int flipx,int flipy,int sx,int sy,int scalex, int scaley, int zpos ) +{ + if (!scalex || !scaley) return; + + INT32 min_x = 0; + INT32 max_x = nScreenWidth - 1; + INT32 min_y = 0; + INT32 max_y = nScreenHeight - 1; + + { + { + int shadow_offset = (1)?0x2000:0; + // const pen_t *pal = &m_palette->pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors())); + const uint8_t *source_base = gfx + (code * tile_size * tile_size); //gfx->get_data(code % gfx->elements()); + int sprite_screen_height = (scaley*tile_size+0x8000)>>16; + int sprite_screen_width = (scalex*tile_size+0x8000)>>16; + if (sprite_screen_width && sprite_screen_height) + { + /* compute sprite increment per screen pixel */ + int dx = (tile_size<<16)/sprite_screen_width; + int dy = (tile_size<<16)/sprite_screen_height; + + int ex = sx+sprite_screen_width; + int ey = sy+sprite_screen_height; + + int x_index_base; + int y_index; + + if( flipx ) + { + x_index_base = (sprite_screen_width-1)*dx; + dx = -dx; + } + else + { + x_index_base = 0; + } + + if( flipy ) + { + y_index = (sprite_screen_height-1)*dy; + dy = -dy; + } + else + { + y_index = 0; + } + + if( sx < min_x) + { /* clip left */ + int pixels = min_x-sx; + sx += pixels; + x_index_base += pixels*dx; + } + if( sy < min_y ) + { /* clip top */ + int pixels = min_y-sy; + sy += pixels; + y_index += pixels*dy; + } + if( ex > max_x+1 ) + { /* clip right */ + int pixels = ex-max_x-1; + ex -= pixels; + } + if( ey > max_y+1 ) + { /* clip bottom */ + int pixels = ey-max_y-1; + ey -= pixels; + } + + if( ex>sx ) + { /* skip if inner loop doesn't draw anything */ + int y; + UINT8 *priority_bitmap = pPrioDraw; + + { + for( y=sy; y>16) * tile_size; + uint16_t *dest = pTransDraw + y * nScreenWidth; //&dest_bmp.pix16(y); + uint8_t *pri = priority_bitmap + y * nScreenWidth; //&priority_bitmap.pix8(y); + int x, x_index = x_index_base; + if( 0 ) //m_c355_obj_palxor ) // iq_132 + { + for( x=sx; x>16]; + if( c != 0xff ) + { + if( pri[x]<=zpos ) + { + switch( c ) + { + case 0: + dest[x] = 0x4000|(dest[x]&0x1fff); + break; + case 1: + dest[x] = 0x6000|(dest[x]&0x1fff); + break; + default: + dest[x] = c|color; + break; + } + pri[x] = zpos; + } + } + x_index += dx; + } + y_index += dy; + } + else + { + for( x=sx; x>16]; + if( c != 0xff ) + { + if( pri[x]<=zpos ) + { + if( color == 0xf00 && c==0xfe ) + { + dest[x] |= shadow_offset; + } + else + { + dest[x] = c | color;; + } + pri[x] = zpos; + } + } + x_index += dx; + } + y_index += dy; + } + } + } + } + } + } + } +} /* zdrawgfxzoom */ + +static void draw_sprites_metalhawk(int pri) +{ + const uint16_t *pSource = (UINT16*)DrvSprRAM; + + for(INT32 loop=0; loop < 128; loop++ ) + { + int ypos = pSource[0]; + int tile = pSource[1]; + int xpos = pSource[3]; + int flags = pSource[6]; + int attrs = pSource[7]; + int sizey = ((ypos>>10)&0x3f)+1; + int sizex = (xpos>>10)&0x3f; + int sprn = tile&0x1fff; + + if( tile&0x2000 ) + { + sprn&=0xfff; + } + else + { + sprn|=0x1000; + } + + if( (sizey-1) && sizex && (attrs&0xf)==pri ) + { + int bBigSprite = (flags&8); + int color = (attrs>>4)&0xf; + int sx = (xpos&0x03ff)-0x50+0x07; + int sy = (0x1ff-(ypos&0x01ff))-0x50+0x02; + int flipx = flags&2; + int flipy = flags&4; + int scalex = (sizex<<16)/(bBigSprite?0x20:0x10); + int scaley = (sizey<<16)/(bBigSprite?0x20:0x10); + + if( (flags&0x01) ) + { + sprn |= 0x2000; + } + + if( bBigSprite ) + { + if( sizex < 0x20 ) + { + sx -= (0x20-sizex)/0x8; + } + if( sizey < 0x20 ) + { + sy += (0x20-sizey)/0xC; + } + } + + UINT8 *gfx; + + if( !bBigSprite ) + { + gfx = DrvGfxROM1; + + sizex = 16; + sizey = 16; + scalex = 1<<16; + scaley = 1<<16; + + sx -= (tile&1)?16:0; + sy -= (tile&2)?16:0; + } + else + { + gfx = DrvGfxROM0; + + sprn >>= 2; + } + + zdrawgfxzoom(gfx, bBigSprite ? 32 : 16, sprn, color * 256, flipx,flipy, sx, sy, scalex, scaley, loop ); + } + pSource += 8; + } +} + + +static void predraw_c169_roz_bitmap() +{ + UINT16 *ram = (UINT16*)DrvRozRAM; + UINT16 *dirty = (UINT16*)roz_dirty_tile; + + for (INT32 offs = 0; offs < 256 * 256; offs++) + { + INT32 sx = (offs & 0xff); + INT32 sy = (offs / 0x100); + + INT32 ofst; + if (sx >= 128) { + ofst = (sx & 0x7f) + ((sy + 0x100) * 0x80); + } else { + ofst = sx + (sy * 0x80); + } + + INT32 code = ram[ofst] & 0x3fff; + if (code == dirty[ofst] && roz_update_tiles == 0) { + continue; + } + dirty[ofst] = code; + + sx *= 16; + sy *= 16; + + UINT8 *gfx = DrvGfxROM3 + (code * 0x100); + UINT8 *msk = DrvGfxROM5 + (code * 0x020); + + UINT16 *dst = roz_bitmap + (sy * (256 * 16)) + sx; + + for (INT32 y = 0; y < 16; y++, gfx+=16,msk+=2) + { + for (INT32 x = 0; x < 16; x++) + { + if (msk[x/8] & (0x80 >> (x & 7))) + { + dst[x] = gfx[x]; + } else { + dst[x] = 0x8000; + } + } + + dst += (256 * 16); + } + } + + roz_update_tiles = 0; +} + +struct roz_param +{ + uint32_t size; + uint32_t startx,starty; + int incxx,incxy,incyx,incyy; + int color; + int wrap; +}; + + +static inline void draw_roz_helper_block(const struct roz_param *rozInfo, int destx, int desty, int srcx, int srcy, int width, int height,uint32_t size_mask) +{ + int desty_end = desty + height; + + int end_incrx = rozInfo->incyx - (width * rozInfo->incxx); + int end_incry = rozInfo->incyy - (width * rozInfo->incxy); + + uint16_t *dest = pTransDraw + (desty * nScreenWidth) + destx; + int dest_rowinc = nScreenWidth - width; + + while (desty < desty_end) + { + uint16_t *dest_end = dest + width; + while (dest < dest_end) + { + uint32_t xpos = (srcx >> 16); + uint32_t ypos = (srcy >> 16); + + if (rozInfo->wrap) + { + xpos &= size_mask; + ypos &= size_mask; + } + else if ((xpos > rozInfo->size) || (ypos >= rozInfo->size)) + { + srcx += rozInfo->incxx; + srcy += rozInfo->incxy; + dest++; + continue; + } + + INT32 pxl = roz_bitmap[(ypos * 256 * 8) + xpos]; + if (pxl != 0xff) *dest = pxl + rozInfo->color; + srcx += rozInfo->incxx; + srcy += rozInfo->incxy; + dest++; + } + srcx += end_incrx; + srcy += end_incry; + dest += dest_rowinc; + desty++; + } +} + +static void draw_roz_helper(const struct roz_param *rozInfo ) +{ + int min_x = 0; + int min_y = 0; + int max_y = nScreenHeight - 1; + int max_x = nScreenWidth - 1; + + { + +#define ROZ_BLOCK_SIZE 8 + + uint32_t size_mask = rozInfo->size - 1; + uint32_t srcx = (rozInfo->startx + (min_x * rozInfo->incxx) + + (min_y * rozInfo->incyx)); + uint32_t srcy = (rozInfo->starty + (min_x * rozInfo->incxy) + + (min_y * rozInfo->incyy)); + int destx = min_x; + int desty = min_y; + + int row_count = (max_y - desty) + 1; + int row_block_count = row_count / ROZ_BLOCK_SIZE; + int row_extra_count = row_count % ROZ_BLOCK_SIZE; + + int column_count = (max_x - destx) + 1; + int column_block_count = column_count / ROZ_BLOCK_SIZE; + int column_extra_count = column_count % ROZ_BLOCK_SIZE; + + int row_block_size_incxx = ROZ_BLOCK_SIZE * rozInfo->incxx; + int row_block_size_incxy = ROZ_BLOCK_SIZE * rozInfo->incxy; + int row_block_size_incyx = ROZ_BLOCK_SIZE * rozInfo->incyx; + int row_block_size_incyy = ROZ_BLOCK_SIZE * rozInfo->incyy; + + int i,j; + + // Do the block rows + for (i = 0; i < row_block_count; i++) + { + int sx = srcx; + int sy = srcy; + int dx = destx; + // Do the block columns + for (j = 0; j < column_block_count; j++) + { + draw_roz_helper_block(rozInfo, dx, desty, sx, sy, ROZ_BLOCK_SIZE, + ROZ_BLOCK_SIZE, size_mask); + // Increment to the next block column + sx += row_block_size_incxx; + sy += row_block_size_incxy; + dx += ROZ_BLOCK_SIZE; + } + // Do the extra columns + if (column_extra_count) + { + draw_roz_helper_block(rozInfo, dx, desty, sx, sy, column_extra_count, + ROZ_BLOCK_SIZE,size_mask); + } + // Increment to the next row block + srcx += row_block_size_incyx; + srcy += row_block_size_incyy; + desty += ROZ_BLOCK_SIZE; + } + // Do the extra rows + if (row_extra_count) + { + // Do the block columns + for (i = 0; i < column_block_count; i++) + { + draw_roz_helper_block(rozInfo, destx, desty, srcx, srcy, ROZ_BLOCK_SIZE, + row_extra_count, size_mask); + srcx += row_block_size_incxx; + srcy += row_block_size_incxy; + destx += ROZ_BLOCK_SIZE; + } + // Do the extra columns + if (column_extra_count) + { + draw_roz_helper_block(rozInfo, destx, desty, srcx, srcy, column_extra_count, + row_extra_count, size_mask); + } + } + } +} + +static void draw_roz() +{ + const int xoffset = 38,yoffset = 0; + struct roz_param rozParam; + + UINT16 *m_roz_ctrl = (UINT16*)DrvRozCtrl; + + rozParam.color = (gfx_ctrl & 0x0f00); + rozParam.incxx = (int16_t)m_roz_ctrl[0]; + rozParam.incxy = (int16_t)m_roz_ctrl[1]; + rozParam.incyx = (int16_t)m_roz_ctrl[2]; + rozParam.incyy = (int16_t)m_roz_ctrl[3]; + rozParam.startx = (int16_t)m_roz_ctrl[4]; + rozParam.starty = (int16_t)m_roz_ctrl[5]; + rozParam.size = 2048; + rozParam.wrap = 1; + + + switch( m_roz_ctrl[7] ) + { + case 0x4400: /* (2048x2048) */ + break; + + case 0x4488: /* attract mode */ + rozParam.wrap = 0; + break; + + case 0x44cc: /* stage1 demo */ + rozParam.wrap = 0; + break; + + case 0x44ee: /* (256x256) used in Dragon Saber */ + rozParam.wrap = 0; + rozParam.size = 256; + break; + } + + rozParam.startx <<= 4; + rozParam.starty <<= 4; + rozParam.startx += xoffset * rozParam.incxx + yoffset * rozParam.incyx; + rozParam.starty += xoffset * rozParam.incxy + yoffset * rozParam.incyy; + + rozParam.startx<<=8; + rozParam.starty<<=8; + rozParam.incxx<<=8; + rozParam.incxy<<=8; + rozParam.incyx<<=8; + rozParam.incyy<<=8; + + draw_roz_helper(&rozParam ); +} + + +static void draw_sprites(int pri, int control ) +{ + UINT16 *m_spriteram = (UINT16*)DrvSprRAM; + + + int offset = (control & 0x000f) * (128*4); + int loop; + if( pri==0 ) + { + //screen.priority().fill(0, cliprect ); + } + for( loop=0; loop <128; loop++ ) + { + int word3 = m_spriteram[offset+(loop*4)+3]; + if( (word3&0xf)==pri ) + { + int word0 = m_spriteram[offset+(loop*4)+0]; + int word1 = m_spriteram[offset+(loop*4)+1]; + int offset4 = m_spriteram[offset+(loop*4)+2]; + + int sizey=((word0>>10)&0x3f)+1; + int sizex=(word3>>10)&0x3f; + + if((word0&0x0200)==0) sizex>>=1; + + if((sizey-1) && sizex ) + { + int color = (word3>>4)&0x000f; + int code = word1 & 0x3fff; + int ypos = (0x1ff-(word0&0x01ff))-0x50+0x02; + int xpos = (offset4&0x03ff)-0x50+0x07; + int flipy = word1&0x8000; + int flipx = word1&0x4000; + int scalex = (sizex<<16)/((word0&0x0200)?0x20:0x10); + int scaley = (sizey<<16)/((word0&0x0200)?0x20:0x10); + if(scalex && scaley) + { + int size = (word0 >> 9) & 1; // 1 = 32x32, 0 = 16x16 + + if (size == 1) code >>= 2; + + zdrawgfxzoom( size ? DrvGfxROM0 : DrvGfxROM1, size ? 32 : 16, code, color * 256, flipx,flipy, xpos,ypos, scalex,scaley, loop ); + } + } + } + } +} /* namcos2_draw_sprites */ + +static INT32 DrvDraw() +{ + if (DrvRecalc) { + DrvRecalcPalette(); + DrvRecalc = 1; + } + +// apply_clip(); + + INT32 roz_enable = (gfx_ctrl & 0x7000) ? 1 : 0; + + if (roz_enable) predraw_roz_layer(); + + for (INT32 i = 0; i < nScreenWidth * nScreenHeight; i++) { + pTransDraw[i] = 0x4000; + pPrioDraw[i] = 0; + } + + for (INT32 pri = 0; pri < 8; pri++) + { + draw_layer(pri); + + if (((gfx_ctrl & 0x7000) >> 12) == pri ) + { + if (roz_enable) draw_roz(); + } + + draw_sprites(pri, gfx_ctrl); + } + + BurnTransferCopy(DrvPalette); + + return 0; +} + + +static void c355_obj_draw_sprite(const uint16_t *pSource, int pri, int zpos ) +{ + uint16_t *spriteram16 = (UINT16*)DrvSprRAM; //m_c355_obj_ram; + unsigned screen_height_remaining, screen_width_remaining; + unsigned source_height_remaining, source_width_remaining; + int hpos,vpos; + uint16_t hsize,vsize; + uint16_t palette; + uint16_t linkno; + uint16_t offset; + uint16_t format; + int tile_index; + int num_cols,num_rows; + int dx,dy; + int row,col; + int sx,sy,tile; + int flipx,flipy; + uint32_t zoomx, zoomy; + int tile_screen_width; + int tile_screen_height; + const uint16_t *spriteformat16 = &spriteram16[0x4000/2]; + const uint16_t *spritetile16 = &spriteram16[0x8000/2]; + int color; + const uint16_t *pWinAttr; + + int xscroll, yscroll; + + /** + * ----xxxx-------- window select + * --------xxxx---- priority + * ------------xxxx palette select + */ + palette = pSource[6]; + if( pri != ((palette>>4)&0xf) ) + { + return; + } + + linkno = pSource[0]; /* LINKNO */ + offset = pSource[1]; /* OFFSET */ + hpos = pSource[2]; /* HPOS 0x000..0x7ff (signed) */ + vpos = pSource[3]; /* VPOS 0x000..0x7ff (signed) */ + hsize = pSource[4]; /* HSIZE max 0x3ff pixels */ + vsize = pSource[5]; /* VSIZE max 0x3ff pixels */ + /* pSource[6] contains priority/palette */ + /* pSource[7] is used in Lucky & Wild, possibly for sprite-road priority */ + + if( linkno*4>=0x4000/2 ) return; /* avoid garbage memory reads */ + + xscroll = (INT16)c355_obj_position[1]; + yscroll = (INT16)c355_obj_position[0]; + + xscroll &= 0x1ff; if( xscroll & 0x100 ) xscroll |= ~0x1ff; + yscroll &= 0x1ff; if( yscroll & 0x100 ) yscroll |= ~0x1ff; + + if(nScreenWidth > 384 ) + { /* Medium Resolution: System21 adjust */ + xscroll = (INT16)c355_obj_position[1]; + xscroll &= 0x3ff; if( xscroll & 0x200 ) xscroll |= ~0x3ff; + if( yscroll<0 ) + { /* solvalou */ + yscroll += 0x20; + } + yscroll += 0x10; + } + else + { + // if ((m_gametype == NAMCOFL_SPEED_RACER) || (m_gametype == NAMCOFL_FINAL_LAP_R)) + // { /* Namco FL: don't adjust and things line up fine */ + // } + // else + // { /* Namco NB1, Namco System 2 */ + xscroll += 0x26; + yscroll += 0x19; + // } + } + + hpos -= xscroll; + vpos -= yscroll; + pWinAttr = &spriteram16[0x2400/2+((palette>>8)&0xf)*4]; +// clip.set(pWinAttr[0] - xscroll, pWinAttr[1] - xscroll, pWinAttr[2] - yscroll, pWinAttr[3] - yscroll); + + hpos&=0x7ff; if( hpos&0x400 ) hpos |= ~0x7ff; /* sign extend */ + vpos&=0x7ff; if( vpos&0x400 ) vpos |= ~0x7ff; /* sign extend */ + + tile_index = spriteformat16[linkno*4+0]; + format = spriteformat16[linkno*4+1]; + dx = spriteformat16[linkno*4+2]; + dy = spriteformat16[linkno*4+3]; + num_cols = (format>>4)&0xf; + num_rows = (format)&0xf; + + if( num_cols == 0 ) num_cols = 0x10; + flipx = (hsize&0x8000)?1:0; + hsize &= 0x3ff;//0x1ff; + if( hsize == 0 ) return; + zoomx = (hsize<<16)/(num_cols*16); + dx = (dx*zoomx+0x8000)>>16; + if( flipx ) + { + hpos += dx; + } + else + { + hpos -= dx; + } + + if( num_rows == 0 ) num_rows = 0x10; + flipy = (vsize&0x8000)?1:0; + vsize &= 0x3ff; + if( vsize == 0 ) return; + zoomy = (vsize<<16)/(num_rows*16); + dy = (dy*zoomy+0x8000)>>16; + if( flipy ) + { + vpos += dy; + } + else + { + vpos -= dy; + } + + color = (palette&0xf);//^m_c355_obj_palxor; + + source_height_remaining = num_rows*16; + screen_height_remaining = vsize; + sy = vpos; + for( row=0; row