Fix gstrik2 and add hyprduel (prelim)

This commit is contained in:
iq_132 2020-04-21 05:08:50 -04:00
parent 354c780c5a
commit 708bd57d54
6 changed files with 2169 additions and 1045 deletions

View File

@ -73,8 +73,8 @@ drvsrc = d_akkaarrh.o d_arcadecl.o d_atarig1.o d_badlands.o d_batman.o d_blstro
\
d_3x3puzzl.o d_1945kiii.o d_20pacgal.o d_aerofgt.o d_airbustr.o d_aquarium.o d_bestleag.o d_bigstrkb.o d_blackt96.o d_blmbycar.o d_bloodbro.o \
d_crospang.o d_crshrace.o d_cultures.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_galpani3.o d_galpanic.o d_galspnbl.o d_glass.o d_go2000.o \
d_gotcha.o d_gstream.o d_gumbo.o d_hyperpac.o d_itech32.o d_inufuku.o d_jchan.o d_kaneko16.o d_kickgoal.o d_legionna.o d_limenko.o d_lordgun.o d_macrossp.o d_mcatadv.o d_metro.o d_midas.o d_mirage.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_galpani3.o d_galpanic.o d_galspnbl.o d_glass.o d_go2000.o d_gotcha.o d_gstream.o d_gumbo.o \
d_hyperpac.od_hyprduel.o d_itech32.o d_inufuku.o d_jchan.o d_kaneko16.o d_kickgoal.o d_legionna.o d_limenko.o d_lordgun.o d_macrossp.o d_mcatadv.o d_metro.o d_midas.o d_mirage.o \
d_missb2.o d_mosaic.o d_mugsmash.o d_mwarr.o d_namcos2.o d_news.o d_nmg5.o d_nmk16.o d_ohmygod.o d_oneshot.o d_onetwo.o d_pass.o d_patapata.o \
d_pipedrm.o d_pirates.o d_pkscram.o d_playmark.o d_powerins.o d_ppmast93.o d_pushman.o d_rabbit.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_supduck.o d_suprnova.o d_taotaido.o d_targeth.o d_tecmo16.o d_tecmosys.o \
@ -99,8 +99,8 @@ drvsrc = d_akkaarrh.o d_arcadecl.o d_atarig1.o d_badlands.o d_batman.o d_blstro
depobj = burn.o burn_bitmap.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 c169.o atariic.o atarijsa.o atarimo.o atarirle.o atarivad.o avgdvg.o bsmt2000.o decobsmt.o earom.o eeprom.o \
gaelco_crypt.o joyprocess.o nb1414m4.o nb1414m4_8bit.o nmk004.o nmk112.o kaneko_tmap.o mathbox.o mb87078.o mermaid.o midcsd.o midsat.o midsg.o midssio.o midtcs.o \
6821pia.o 8255ppi.o 8257dma.o c169.o atariic.o atarijsa.o atarimo.o atarirle.o atarivad.o avgdvg.o bsmt2000.o decobsmt.o earom.o eeprom.o gaelco_crypt.o i4x00.o \
joyprocess.o nb1414m4.o nb1414m4_8bit.o nmk004.o nmk112.o kaneko_tmap.o mathbox.o mb87078.o mermaid.o midcsd.o midsat.o midsg.o midssio.o midtcs.o \
namco_c45.o namcoio.o pandora.o qs1000.o resnet.o seibucop.o seibusnd.o sknsspr.o slapstic.o st0020.o t5182.o timekpr.o tms34061.o v3021.o vdc.o tms9928a.o watchdog.o x2212.o \
\
asteroids.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_md2612.o \

780
src/burn/devices/i4x00.cpp Normal file
View File

@ -0,0 +1,780 @@
#include "tiles_generic.h"
#include "m68000_intf.h"
#include "burn_pal.h"
static UINT8 *AllRam;
static UINT8 *RamEnd;
static UINT8 *VideoRAM[3];
static UINT8 *SpriteRAM;
static UINT8 *TileRAM;
static UINT8 *VideoRegs;
static UINT8 *SpriteRegs;
static UINT8 *ScrollRegs;
static UINT8 *WindowRegs;
static UINT8 *BlitRegs;
INT32 i4x00_irq_enable;
INT32 i4x00_blitter_timer = -1;
static INT32 rombank;
static INT32 screen_control;
static INT32 flipscreen;
static UINT8 *gfx8x8x8;
static UINT8 *gfx4x8x8;
static UINT32 graphics_length;
static INT32 support_16x16 = 0;
static INT32 support_8bpp = 1;
static INT32 tilemap_scrolldx[3] = { 0,0,0 };
static UINT16 (*irq_cause_read_cb)() = NULL;
static void (*irq_cause_write_cb)(UINT16 data) = NULL;
static void (*soundlatch_write_cb)(UINT16 data) = NULL;
static void (*additional_video_chips_cb)() = NULL;
static void palette_update()
{
UINT16 *p = (UINT16*)(BurnPalRAM + 0x2000);
for (INT32 i = 0; i < 0x2000 / 2; i++)
{
BurnPalette[i] = BurnHighCol(pal5bit(p[i] >> 6), pal5bit(p[i] >> 11), pal5bit(p[i] >> 1), 0);
}
}
static inline void palette_write(INT32 offset)
{
UINT16 p = *((UINT16*)(BurnPalRAM + (offset & 0x3ffe)));
BurnPalette[(offset / 2) & 0xfff] = BurnHighCol(pal5bit(p >> 6), pal5bit(p >> 11), pal5bit(p >> 1), 0);
}
static void draw_sprites()
{
UINT16 *m_spriteram = (UINT16*)SpriteRAM;
UINT16 *m_videoregs = (UINT16*)VideoRegs;
UINT16 *m_spriteregs = (UINT16*)SpriteRegs;
int max_x = (m_spriteregs[1]+1) * 2;
int max_y = (m_spriteregs[0]+1) * 2;
INT32 m_sprite_xoffs = m_videoregs[0x06 / 2] - (m_spriteregs[1]+1);
INT32 m_sprite_yoffs = m_videoregs[0x04 / 2] - (m_spriteregs[0]+1);
UINT32 gfx_size = graphics_length;
INT32 max_sprites = 0x1000 / 8;
INT32 sprites = m_videoregs[0x00/2] % max_sprites;
INT32 color_start = (m_videoregs[0x08/2] & 0x0f) << 4;
INT32 i, j, pri;
static const INT32 primask[4] = { 0x0000, 0xff00, 0xff00 | 0xf0f0, 0xff00 | 0xf0f0 | 0xcccc };
UINT16 *src;
INT32 inc;
if (sprites == 0)
return;
for (i = 0; i < 0x20; i++)
{
if (!(m_videoregs[0x02/2] & 0x8000))
{
src = m_spriteram + (sprites - 1) * (8 / 2);
inc = -(8 / 2);
} else {
src = m_spriteram;
inc = (8 / 2);
}
for (j = 0; j < sprites; j++)
{
INT32 x, y, attr, code, color, flipx, flipy, zoom, curr_pri, width, height;
static const INT32 zoomtable[0x40] = {
0xAAC,0x800,0x668,0x554,0x494,0x400,0x390,0x334,0x2E8,0x2AC,0x278,0x248,0x224,0x200,0x1E0,0x1C8,
0x1B0,0x198,0x188,0x174,0x164,0x154,0x148,0x13C,0x130,0x124,0x11C,0x110,0x108,0x100,0x0F8,0x0F0,
0x0EC,0x0E4,0x0DC,0x0D8,0x0D4,0x0CC,0x0C8,0x0C4,0x0C0,0x0BC,0x0B8,0x0B4,0x0B0,0x0AC,0x0A8,0x0A4,
0x0A0,0x09C,0x098,0x094,0x090,0x08C,0x088,0x080,0x078,0x070,0x068,0x060,0x058,0x050,0x048,0x040
};
x = src[0];
curr_pri = (x & 0xf800) >> 11;
if ((curr_pri == 0x1f) || (curr_pri != i))
{
src += inc;
continue;
}
pri = (m_videoregs[0x02/2] & 0x0300) >> 8;
if (!(m_videoregs[0x02/2] & 0x8000))
{
if (curr_pri > (m_videoregs[0x02/2] & 0x1f))
pri = (m_videoregs[0x02/2] & 0x0c00) >> 10;
}
y = src[1];
attr = src[2];
code = src[3];
flipx = attr & 0x8000;
flipy = attr & 0x4000;
color = (attr & 0xf0) >> 4;
zoom = zoomtable[(y & 0xfc00) >> 10] << (16 - 8);
x = (x & 0x07ff) - m_sprite_xoffs;
y = (y & 0x03ff) - m_sprite_yoffs;
width = (((attr >> 11) & 0x7) + 1) * 8;
height = (((attr >> 8) & 0x7) + 1) * 8;
UINT32 gfxstart = (8 * 8 * 4 / 8) * (((attr & 0x000f) << 16) + code);
if (flipscreen)
{
flipx = !flipx; x = max_x - x - width;
flipy = !flipy; y = max_y - y - height;
}
if (color == 0xf) /* 8bpp */
{
if ((gfxstart + width * height - 1) >= gfx_size)
continue;
RenderZoomedPrioSprite(pTransDraw, gfx8x8x8 + gfxstart, 0, (color_start >> 4) << 8, 0xff, x, y, flipx, flipy, width, height, zoom, zoom, primask[pri]);
}
else
{
if ((gfxstart + width / 2 * height - 1) >= gfx_size)
continue;
RenderZoomedPrioSprite(pTransDraw, gfx4x8x8 + 2 * gfxstart, 0, (color + color_start) << 4, 0xf, x, y, flipx, flipy, width, height, zoom, zoom, primask[pri]);
}
src += inc;
}
}
}
static inline UINT8 get_tile_pix(UINT16 code, UINT8 x, UINT8 y, INT32 big, UINT16 *pix)
{
UINT16 *tiletable = (UINT16*)TileRAM;
INT32 table_index = (code & 0x1ff0) >> 3;
UINT32 tile = (tiletable[table_index + 0] << 16) + tiletable[table_index + 1];
if (code & 0x8000)
{
*pix = code & 0x0fff;
if ((*pix & 0xf) != 0xf)
return 1;
else
return 0;
}
else if (((tile & 0x00f00000) == 0x00f00000) && (support_8bpp))
{
UINT32 tile2 = big ? ((((tile & 0xfffff) + (8*(code & 0xf))))) : ((((tile & 0xfffff) + (2*(code & 0xf)))));
tile2 *= (big) ? 0x80 : 0x20; // big is a guess
if (tile2 >= graphics_length) {
return 0;
}
const UINT8 *data = gfx8x8x8 + tile2;
switch (code & 0x6000)
{
case 0x0000: *pix = data[(y * (big?16:8)) + x]; break;
case 0x2000: *pix = data[(((big?15:7)-y) * (big?16:8)) + x]; break;
case 0x4000: *pix = data[(y * (big?16:8)) + ((big?15:7)-x)]; break;
case 0x6000: *pix = data[(((big?15:7)-y) * (big?16:8)) + ((big?15:7)-x)]; break;
}
if (*pix == 0xff) {
return 0;
}
*pix |= (tile & 0x0f000000) >> 16;
return 1;
}
else
{
UINT32 tile2 = big ? ((((tile & 0xfffff) + 4*(code & 0xf))) * 0x100) : ((((tile & 0xfffff) + (code & 0xf))) * 0x40);
if (tile2 >= (graphics_length*2)) {
return 0;
}
const UINT8 *data = gfx4x8x8 + tile2;
switch (code & 0x6000)
{
case 0x0000: *pix = data[(y * (big?16:8)) + x]; break;
case 0x2000: *pix = data[(((big?15:7)-y) * (big?16:8)) + x]; break;
case 0x4000: *pix = data[(y * (big?16:8)) + ((big?15:7)-x)]; break;
case 0x6000: *pix = data[(((big?15:7)-y) * (big?16:8)) + ((big?15:7)-x)]; break;
}
if (*pix == 0xf) {
return 0;
}
*pix |= (tile & 0x0ff00000) >> 16;
return 1;
}
}
static void draw_tilemap(UINT32 ,UINT32 pcode,int sx, int sy, int wx, int wy, int big, UINT16 *tilemapram, int layer)
{
UINT8 * priority_bitmap = pPrioDraw;
int width = big ? 4096 : 2048;
int height = big ? 4096 : 2048;
int scrwidth = nScreenWidth;
int scrheight = nScreenHeight;
int windowwidth = width >> 2;
int windowheight = height >> 3;
sx += tilemap_scrolldx[layer] * (flipscreen ? 1 : -1);
for (INT32 y = 0; y < scrheight; y++)
{
int scrolly = (sy+y-wy)&(windowheight-1);
int x;
UINT16 *dst;
UINT8 *priority_baseaddr;
int srcline = (wy+scrolly)&(height-1);
int srctilerow = srcline >> (big ? 4 : 3);
if (!flipscreen)
{
dst = pTransDraw + (y * nScreenWidth);
priority_baseaddr = priority_bitmap + (y * nScreenWidth);
for (x = 0; x < scrwidth; x++)
{
int scrollx = (sx+x-wx)&(windowwidth-1);
int srccol = (wx+scrollx)&(width-1);
int srctilecol = srccol >> (big ? 4 : 3);
int tileoffs = srctilecol + srctilerow * 0x100;
UINT16 dat = 0;
UINT16 tile = tilemapram[tileoffs];
UINT8 draw = get_tile_pix(tile, big ? (srccol&0xf) : (srccol&0x7), big ? (srcline&0xf) : (srcline&0x7), big, &dat);
if (draw)
{
dst[x] = dat;
priority_baseaddr[x] = (priority_baseaddr[x] & (pcode >> 8)) | pcode;
}
}
}
else // flipped case
{
dst = pTransDraw + ((scrheight-y-1) * nScreenWidth);
priority_baseaddr = priority_bitmap + ((scrheight-y-1) * nScreenWidth);
for (x = 0; x < scrwidth; x++)
{
int scrollx = (sx+x-wx)&(windowwidth-1);
int srccol = (wx+scrollx)&(width-1);
int srctilecol = srccol >> (big ? 4 : 3);
int tileoffs = srctilecol + srctilerow * 0x100;
UINT16 dat = 0;
UINT16 tile = tilemapram[tileoffs];
UINT8 draw = get_tile_pix(tile, big ? (srccol&0xf) : (srccol&0x7), big ? (srcline&0xf) : (srcline&0x7), big, &dat);
if (draw)
{
dst[x] = dat;
priority_baseaddr[scrwidth-x-1] = (priority_baseaddr[scrwidth-x-1] & (pcode >> 8)) | pcode;
}
}
}
}
}
static void draw_layers(int pri)
{
UINT16 *m_videoregs = (UINT16*)VideoRegs;
UINT16 *m_scroll = (UINT16*)ScrollRegs;
UINT16 *m_window = (UINT16*)WindowRegs;
UINT16 layers_pri = m_videoregs[0x10 / 2];
int layer;
for (layer = 2; layer >= 0; layer--)
{
if (pri == ((layers_pri >> (layer * 2)) & 3))
{
UINT16 sy = m_scroll[layer * 2 + 0];
UINT16 sx = m_scroll[layer * 2 + 1];
UINT16 wy = m_window[layer * 2 + 0];
UINT16 wx = m_window[layer * 2 + 1];
UINT16 *tilemapram = (UINT16*)(VideoRAM[layer]);
int big = support_16x16 && (screen_control & (0x0020 << layer));
draw_tilemap(0, 1 << (3 - pri), sx, sy, wx, wy, big, tilemapram, layer);
}
}
}
INT32 i4x00_draw()
{
// if (DrvRecalc) {
// palette_update();
// DrvRecalc = 0;
// }
UINT16 *m_videoregs = (UINT16*)VideoRegs;
BurnTransferClear((m_videoregs[0x12 / 2] & 0x0fff));
if ((screen_control & 2) == 0)
{
flipscreen = screen_control & 1;
if (additional_video_chips_cb) {
additional_video_chips_cb();
}
for (INT32 pri = 3; pri >= 0; pri--)
{
if (nBurnLayer & 2) draw_layers(pri);
}
if (nSpriteEnable & 1) draw_sprites();
}
BurnTransferCopy(BurnPalette);
return 0;
}
static void blitter_write()
{
{
UINT16 *m_blitter_regs = (UINT16*)BlitRegs;
UINT8 *ramdst[4] = { NULL, VideoRAM[0], VideoRAM[1], VideoRAM[2] };
UINT8 *src = gfx8x8x8;
UINT32 src_len = graphics_length;
UINT32 tmap = (m_blitter_regs[0x00 / 2] << 16) + m_blitter_regs[0x02 / 2];
UINT32 src_offs = (m_blitter_regs[0x04 / 2] << 16) + m_blitter_regs[0x06 / 2];
UINT32 dst_offs = (m_blitter_regs[0x08 / 2] << 16) + m_blitter_regs[0x0a / 2];
UINT8 *dst = ramdst[tmap];
INT32 offs2 = (~dst_offs >> 7) & 1;
dst_offs >>= 8;
while (1)
{
UINT16 b1, b2, count;
src_offs %= src_len;
b1 = src[src_offs];
src_offs++;
count = ((~b1) & 0x3f) + 1;
switch ((b1 & 0xc0) >> 6)
{
case 0:
{
if (b1 == 0)
{
i4x00_blitter_timer = 5000; // 500usec -> (10000000 / 1000000) * 500;
return;
}
while (count--)
{
src_offs %= src_len;
b2 = src[src_offs];
src_offs++;
dst_offs &= 0xffff;
dst[dst_offs*2+offs2] = b2;
dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1)));
}
break;
}
case 1:
{
src_offs %= src_len;
b2 = src[src_offs];
src_offs++;
while (count--)
{
dst_offs &= 0xffff;
dst[dst_offs*2+offs2] = b2;
dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1)));
b2++;
}
break;
}
case 2:
{
src_offs %= src_len;
b2 = src[src_offs];
src_offs++;
while (count--)
{
dst_offs &= 0xffff;
dst[dst_offs*2+offs2] = b2;
dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1)));
}
break;
}
case 3:
{
if (b1 == 0xc0)
{
dst_offs += 0x100;
dst_offs &= ~(0x100 - 1);
dst_offs |= (0x100 - 1) & (m_blitter_regs[0x0a / 2] >> (7 + 1));
}
else
{
dst_offs += count;
}
break;
}
}
}
}
}
static void __fastcall i4x00_write_word(UINT32 address, UINT16 data)
{
address &= 0x7fffe;
if ((address & 0xfff0000) == 0x60000) { //blazing tornado
return; // nop
}
if ((address & 0xfffe000) == 0x72000) {
*((UINT16*)(BurnPalRAM + (address & 0x3ffe))) = data;
palette_write(address);
return;
}
if ((address & 0xffff000) == 0x75000) {
UINT16 *dst = (UINT16*)VideoRAM[0];
dst[((address & 0x7f) + ((address & 0xf80) * 4)) / 2] = data;
return;
}
if ((address & 0xffff000) == 0x76000) {
UINT16 *dst = (UINT16*)VideoRAM[1];
dst[((address & 0x7f) + ((address & 0xf80) * 4)) / 2] = data;
return;
}
if ((address & 0xffff000) == 0x77000) {
UINT16 *dst = (UINT16*)VideoRAM[2];
dst[((address & 0x7f) + ((address & 0xf80) * 4)) / 2] = data;
return;
}
if (address >= 0x78840 && address <= 0x7884d) {
*((UINT16*)(BlitRegs + (address & 0xf))) = data;
if (address == 0x7884c) blitter_write();
return;
}
if (address >= 0x78850 && address <= 0x78853) {
*((UINT16*)(SpriteRegs + (address & 0x03))) = data;
return;
}
if (address >= 0x78860 && address <= 0x7886b) {
*((UINT16*)(WindowRegs + (address & 0xf))) = data;
return;
}
if (address >= 0x78870 && address <= 0x7887b) {
*((UINT16*)(ScrollRegs + (address & 0xf))) = data;
return;
}
if ((address >= 0x78800 && address <= 0x78813) || (address >= 0x079700 && address <= 0x79713)) {
if (address != 0x78802) // breaks blazing tornado
*((UINT16*)(VideoRegs + (address & 0x1f))) = data;
return;
}
switch (address)
{
case 0x7887c:
return;
case 0x78880:
case 0x78890:
case 0x788a0:
return; // crtc regs
case 0x788a2:
if (irq_cause_write_cb) {
irq_cause_write_cb(data);
}
return;
case 0x788a4:
i4x00_irq_enable = data;
return;
case 0x788a6:
return; // nop?
case 0x788a8: // metro...
if (soundlatch_write_cb) {
soundlatch_write_cb(data);
}
return;
case 0x788aa:
rombank = data;
return;
case 0x788ac:
screen_control = data;
return;
}
bprintf (0, _T("i4x00 unmapped word write (%5.5x, %4.4x)\n"), address, data);
}
static void __fastcall i4x00_write_byte(UINT32 address, UINT8 data)
{
address &= 0x7ffff;
if ((address & 0xfffe000) == 0x072000) {
BurnPalRAM[(address & 0x3fff) ^ 1] = data;
palette_write(address);
return;
}
switch (address)
{
case 0x788a3:
if (irq_cause_write_cb) {
irq_cause_write_cb(data);
}
return;
case 0x788a5:
i4x00_irq_enable = data;
return;
}
bprintf (0, _T("i4x00 unmapped byte write (%5.5x, %2.2x)\n"), address, data);
}
static UINT16 __fastcall i4x00_read_word(UINT32 address)
{
address &= 0x7fffe;
if ((address & 0xfff0000) == 0x60000) {
INT32 offset = (rombank * 0x10000) + (address & 0xfffe);
if (offset >= graphics_length) return 0xffff;
return gfx8x8x8[offset + 0] * 256 + gfx8x8x8[offset + 1];
}
if ((address & 0xffff000) == 0x75000) {
UINT16 *dst = (UINT16*)VideoRAM[0];
return dst[((address & 0x7f) + ((address & 0xf80) * 4)) / 2];
}
if ((address & 0xffff000) == 0x76000) {
UINT16 *dst = (UINT16*)VideoRAM[0];
return dst[((address & 0x7f) + ((address & 0xf80) * 4)) / 2];
}
if ((address & 0xffff000) == 0x77000) {
UINT16 *dst = (UINT16*)VideoRAM[2];
return dst[((address & 0x7f) + ((address & 0xf80) * 4)) / 2];
}
if ((address >= 0x078800 && address <= 0x078813) || (address >= 0x079700 && address <= 0x079713)) {
return *((UINT16*)(VideoRegs + (address & 0x1f)));
}
switch (address)
{
case 0x788a2:
if (!irq_cause_read_cb) return 0;
return irq_cause_read_cb();
}
bprintf (0, _T("ix400 unmapped word read (%5.5x)\n"), address);
return 0;
}
static UINT8 __fastcall i4x00_read_byte(UINT32 address)
{
address &= 0x7ffff;
if ((address & 0xfff0000) == 0x60000) {
INT32 offset = (rombank * 0x10000) + (address & 0xffff);
if (offset >= graphics_length) return 0xff;
return gfx8x8x8[offset];
}
switch (address)
{
case 0x788a3:
if (!irq_cause_read_cb) return 0;
return irq_cause_read_cb();
}
bprintf (0, _T("i4x00 unmapped byte read (%5.5x)!\n"), address);
return 0;
}
static INT32 MemIndex()
{
UINT8 *Next; Next = AllRam;
VideoRAM[0] = Next; Next += 0x020000;
VideoRAM[1] = Next; Next += 0x020000;
VideoRAM[2] = Next; Next += 0x020000;
BurnPalRAM = Next; Next += 0x004000;
SpriteRAM = Next; Next += 0x004000;
TileRAM = Next; Next += 0x000800;
BlitRegs = Next; Next += 0x000010;
WindowRegs = Next; Next += 0x000010;
ScrollRegs = Next; Next += 0x000010;
VideoRegs = Next; Next += 0x000020;
SpriteRegs = Next; Next += 0x000004;
RamEnd = Next;
return 0;
}
void i4x00_reset()
{
memset (AllRam, 0, RamEnd - AllRam);
flipscreen = 0;
rombank = 0;
screen_control = 0;
i4x00_irq_enable = 0xff;
i4x00_blitter_timer = -1;
}
void i4x00_set_offsets(INT32 layer0, INT32 layer1, INT32 layer2)
{
tilemap_scrolldx[0] = layer0;
tilemap_scrolldx[1] = layer1;
tilemap_scrolldx[2] = layer2;
}
void i4x00_set_extrachip_callback(void (*callback)())
{
additional_video_chips_cb = callback;
}
void i4x00_init(UINT32 address, UINT8 *gfx8, UINT8 *gfx4, UINT32 gfxlen, void (*irqcausewrite)(UINT16), UINT16 (*irqcauseread)(), void (*soundlatch)(UINT16), INT32 has_8bpp, INT32 has_16bpp)
{
AllRam = NULL;
MemIndex();
INT32 nLen = RamEnd - (UINT8 *)0;
if ((AllRam = (UINT8 *)BurnMalloc(nLen)) == NULL) return;
memset(AllRam, 0, nLen);
MemIndex();
BurnPalette = (UINT32*)BurnMalloc(0x1000 * sizeof(UINT32));
// catch anything not mapped to ram/rom
SekMapHandler(5, 0x00000 + address, 0x7ffff + address, MAP_READ | MAP_WRITE);
SekSetWriteWordHandler(5, i4x00_write_word);
SekSetWriteByteHandler(5, i4x00_write_byte);
SekSetReadWordHandler(5, i4x00_read_word);
SekSetReadByteHandler(5, i4x00_read_byte);
SekMapMemory(VideoRAM[0], 0x00000 + address, 0x1ffff + address, MAP_RAM);
SekMapMemory(VideoRAM[1], 0x20000 + address, 0x3ffff + address, MAP_RAM);
SekMapMemory(VideoRAM[2], 0x40000 + address, 0x5ffff + address, MAP_RAM);
SekMapMemory(BurnPalRAM, 0x70000 + address, 0x71fff + address, MAP_RAM);
SekMapMemory(BurnPalRAM + 0x2000, 0x72000 + address, 0x73fff + address, MAP_ROM); // write through handler
SekMapMemory(SpriteRAM, 0x74000 + address, 0x74fff + address, MAP_RAM); // 0-fff
SekMapMemory(TileRAM, 0x78000 + address, 0x787ff + address, MAP_RAM);
irq_cause_read_cb = irqcauseread;
irq_cause_write_cb = irqcausewrite;
soundlatch_write_cb = soundlatch;
support_16x16 = has_16bpp;
support_8bpp = has_8bpp;
gfx8x8x8 = gfx8 ? gfx8 : gfx4;
gfx4x8x8 = gfx4;
graphics_length = gfxlen;
}
void i4x00_exit()
{
BurnFree(AllRam);
BurnFree(BurnPalette);
irq_cause_read_cb = NULL;
irq_cause_write_cb = NULL;
soundlatch_write_cb = NULL;
additional_video_chips_cb = NULL;
i4x00_set_offsets(0,0,0);
}
void i4x00_scan(INT32 nAction, INT32 *pnMin)
{
struct BurnArea ba;
if (pnMin != NULL) {
*pnMin = 0x029698;
}
if (nAction & ACB_MEMORY_RAM) {
memset(&ba, 0, sizeof(ba));
ba.Data = AllRam;
ba.nLen = RamEnd-AllRam;
ba.szName = "All Ram";
BurnAcb(&ba);
}
if (nAction & ACB_DRIVER_DATA) {
SCAN_VAR(rombank);
SCAN_VAR(i4x00_irq_enable);
SCAN_VAR(screen_control);
SCAN_VAR(i4x00_blitter_timer);
}
}

10
src/burn/devices/i4x00.h Normal file
View File

@ -0,0 +1,10 @@
extern INT32 i4x00_irq_enable;
extern INT32 i4x00_blitter_timer;
INT32 i4x00_draw();
void i4x00_reset();
void i4x00_init(UINT32 address, UINT8 *gfx8, UINT8 *gfx4, UINT32 gfxlen, void (*irqcausewrite)(UINT16), UINT16 (*irqcauseread)(), void (*soundlatch)(UINT16), INT32 has_8bpp, INT32 has_16bpp);
void i4x00_set_offsets(INT32 layer0, INT32 layer1, INT32 layer2);
void i4x00_set_extrachip_callback(void (*callback)());
void i4x00_exit();
void i4x00_scan(INT32 nAction, INT32 *pnMin);

View File

@ -227,7 +227,7 @@ void K053936PredrawTiles(INT32 chip, UINT8 *gfx, INT32 transparent, INT32 tcol)
}
}
static inline void copy_roz(INT32 chip, INT32 minx, INT32 maxx, INT32 miny, INT32 maxy, UINT32 startx, UINT32 starty, INT32 incxx, INT32 incxy, INT32 incyx, INT32 incyy, INT32 transp, INT32 priority)
static inline void copy_roz32(INT32 chip, INT32 minx, INT32 maxx, INT32 miny, INT32 maxy, UINT32 startx, UINT32 starty, INT32 incxx, INT32 incxy, INT32 incyx, INT32 incyy, INT32 transp, INT32 priority)
{
if (incxx == (1 << 16) && incxy == 0 && incyx == 0 && incyy == (1 << 16) && K053936Wrap[chip])
{
@ -260,7 +260,9 @@ static inline void copy_roz(INT32 chip, INT32 minx, INT32 maxx, INT32 miny, INT3
INT32 wmask = nWidth[chip] - 1;
INT32 wrap = K053936Wrap[chip];
dst += maxx * miny; // right?
for (INT32 sy = miny; sy < maxy; sy++, startx+=incyx, starty+=incyy)
{
UINT32 cx = startx;
@ -314,56 +316,168 @@ static inline void copy_roz(INT32 chip, INT32 minx, INT32 maxx, INT32 miny, INT3
}
}
static inline void copy_roz16(INT32 chip, INT32 minx, INT32 maxx, INT32 miny, INT32 maxy, UINT32 startx, UINT32 starty, INT32 incxx, INT32 incxy, INT32 incyx, INT32 incyy, INT32 transp, INT32 transp_mask, INT32 priority)
{
INT32 clip_minx, clip_maxx, clip_miny, clip_maxy;
BurnBitmapGetClipDims(1, &clip_minx, &clip_maxx, &clip_miny, &clip_maxy);
if (incxx == (1 << 16) && incxy == 0 && incyx == 0 && incyy == (1 << 16) && K053936Wrap[chip])
{
INT32 scrollx = startx >> 16;
INT32 scrolly = starty >> 16;
for (INT32 sy = 0; sy < nScreenHeight; sy++) {
UINT8 *pri = pPrioDraw + (sy * nScreenWidth);
UINT16 *src = BurnBitmapGetBitmap(1) + (((scrolly + sy) % clip_maxy) * clip_maxx);
UINT16 *dst = pTransDraw + (sy * nScreenWidth);
for (INT32 sx = 0; sx < nScreenWidth; sx++) {
INT32 pxl = src[(scrollx+sx)%clip_maxx];
if ((pxl & transp_mask) == transp) continue;
dst[sx] = pxl;
pri[sx] = priority;
}
}
return;
}
UINT8 *pri = pPrioDraw;
UINT16 *dst = pTransDraw;
UINT16 *src = BurnBitmapGetBitmap(1);
INT32 width = clip_maxx;
INT32 hmask = clip_maxy - 1;
INT32 wmask = clip_maxx - 1;
INT32 wrap = K053936Wrap[chip];
dst += maxx * miny; // right?
for (INT32 sy = miny; sy < maxy; sy++, startx+=incyx, starty+=incyy)
{
UINT32 cx = startx;
UINT32 cy = starty;
if (transp_mask) {
if (wrap) {
for (INT32 x = minx; x < maxx; x++, cx+=incxx, cy+=incxy, dst++, pri++)
{
INT32 pxl = src[(((cy >> 16) & hmask) * width) + ((cx >> 16) & wmask)];
if ((pxl & transp_mask) != transp) {
*dst = pxl;
*pri = priority;
}
}
} else {
for (INT32 x = minx; x < maxx; x++, cx+=incxx, cy+=incxy, dst++, pri++)
{
INT32 yy = cy >> 16;
if (yy > hmask || yy < 0) continue;
INT32 xx = cx >> 16;
if (xx > wmask || xx < 0) continue;
INT32 pxl = src[(yy * width) + xx];
if ((pxl & transp_mask) != transp) {
*dst = pxl;
*pri = priority;
}
}
}
} else {
if (wrap) {
for (INT32 x = minx; x < maxx; x++, cx+=incxx, cy+=incxy, dst++, pri++) {
*dst = src[(((cy >> 16) & hmask) * width) + ((cx >> 16) & wmask)] & 0x7fff;
*pri = priority;
}
} else {
for (INT32 x = minx; x < maxx; x++, cx+=incxx, cy+=incxy, dst++, pri++) {
INT32 yy = cy >> 16;
if (yy > hmask || yy < 0) continue;
INT32 xx = cx >> 16;
if (xx > wmask || xx < 0) continue;
*dst = src[(yy * width) + xx] & 0x7fff;
*pri = priority;
}
}
}
}
}
void K053936Draw(INT32 chip, UINT16 *ctrl, UINT16 *linectrl, INT32 flags)
{
INT32 transp = flags & 0xff;
INT32 priority = (flags >> 8) & 0xff;
INT32 transp_mask = (flags >> 16) & 0xff;
INT32 is_16bit_indexed = flags & (1 << 24);
if (ctrl[0x07] & 0x0040 && linectrl) // Super!
if ((ctrl[0x07] & 0x0040) && linectrl)
{
UINT32 startx,starty;
INT32 incxx,incxy;
UINT32 startx, starty;
int incxx, incxy;
int y, maxy;
INT32 clip_minx = 0, clip_maxx = 0;
INT32 minx, maxx, maxy, miny, y;
// Racin' Force will get to here if glfgreat_hack is enabled, and it ends
// up setting a maximum y value of '13', thus causing nothing to be drawn.
// It looks like the roz output should be flipped somehow as it seems to be
// displaying the wrong areas of the tilemap and is rendered upside down,
// although due to the additional post-processing the voxel renderer performs
// it's difficult to know what the output SHOULD be. (hold W in Racin' Force
// to see the chip output)
if ((ctrl[0x07] & 0x0002) && ctrl[0x09] && glfgreat_mode) // glfgreat
if (((ctrl[0x07] & 0x0002) && ctrl[0x09]) && (glfgreat_mode)) /* wrong, but fixes glfgreat */
{
minx = ctrl[0x08] + K053936Offset[chip][0]+2;
maxx = ctrl[0x09] + K053936Offset[chip][0]+2 - 1;
if (minx < 0) minx = 0;
if (maxx > nScreenWidth) maxx = nScreenWidth;
clip_minx = ctrl[0x08] + K053936Offset[chip][0] + 2;
clip_maxx = ctrl[0x09] + K053936Offset[chip][0] + 2 - 1;
if (clip_minx < 0)
clip_minx = 0;
if (clip_maxx >= nScreenWidth)
clip_maxx = nScreenWidth;
y = ctrl[0x0a] + K053936Offset[chip][1]-2;
if (y < 0) y = 0;
maxy = ctrl[0x0b] + K053936Offset[chip][1]-2 - 1;
if (maxy > nScreenHeight) maxy = nScreenHeight;
y = ctrl[0x0a] + K053936Offset[chip][1] - 2;
if (y < 0)
y = 0;
maxy = ctrl[0x0b] + K053936Offset[chip][1] - 2 - 1;
if (maxy >= nScreenHeight)
maxy = nScreenHeight;
}
else
{
minx = 0;
maxx = nScreenWidth;
clip_minx = 0;
clip_maxx = nScreenWidth;
y = 0;
maxy = nScreenHeight;
}
while (y <= maxy)
while (y < maxy)
{
UINT16 *lineaddr = linectrl + 4*((y - K053936Offset[chip][1]) & 0x1ff);
miny = maxy = y;
UINT16 *lineaddr = linectrl + 4 * ((y - K053936Offset[chip][1]) & 0x1ff);
startx = 256 * (INT16)(lineaddr[0] + ctrl[0x00]);
starty = 256 * (INT16)(lineaddr[1] + ctrl[0x01]);
incxx = (INT16)(lineaddr[2]);
incxy = (INT16)(lineaddr[3]);
if (ctrl[0x06] & 0x8000) incxx *= 256;
if (ctrl[0x06] & 0x0080) incxy *= 256;
if (ctrl[0x06] & 0x8000)
incxx *= 256;
if (ctrl[0x06] & 0x0080)
incxy *= 256;
startx -= K053936Offset[chip][0] * incxx;
starty -= K053936Offset[chip][0] * incxy;
copy_roz(chip, minx, maxx, miny, maxy, startx << 5, starty << 5, incxx << 5, incxy << 5, 0, 0, transp, priority);
if (is_16bit_indexed)
copy_roz16(chip, clip_minx, clip_maxx, y, y + 1, startx << 5, starty << 5, incxx << 5, incxy << 5, 0, 0, transp, transp_mask, priority);
else
copy_roz32(chip, clip_minx, clip_maxx, y, y + 1, startx << 5, starty << 5, incxx << 5, incxy << 5, 0, 0, transp, priority);
y++;
}
@ -398,7 +512,10 @@ void K053936Draw(INT32 chip, UINT16 *ctrl, UINT16 *linectrl, INT32 flags)
startx -= K053936Offset[chip][0] * incxx;
starty -= K053936Offset[chip][0] * incxy;
copy_roz(chip, 0, nScreenWidth, 0, nScreenHeight, startx << 5, starty << 5, incxx << 5, incxy << 5, incyx << 5, incyy << 5, transp, priority);
if (is_16bit_indexed)
copy_roz16(chip, 0, nScreenWidth, 0, nScreenHeight, startx << 5, starty << 5, incxx << 5, incxy << 5, incyx << 5, incyy << 5, transp, transp_mask, priority);
else
copy_roz32(chip, 0, nScreenWidth, 0, nScreenHeight, startx << 5, starty << 5, incxx << 5, incxy << 5, incyx << 5, incyy << 5, transp, priority);
}
}

View File

@ -0,0 +1,945 @@
// FinalBurn Neo Hyper Duel / Magical Error wo Sagase driver module
// Based on MAME driver by Lucia Elia / Hau
#include "tiles_generic.h"
#include "m68000_intf.h"
#include "i4x00.h"
#include "burn_ym2151.h"
#include "burn_ym2413.h"
#include "msm6295.h"
static UINT8 *AllMem;
static UINT8 *AllRam;
static UINT8 *RamEnd;
static UINT8 *MemEnd;
static UINT8 *Drv68KROM[1];
static UINT8 *DrvGfxROM[4];
static UINT8 *DrvSndROM;
static UINT8 *DrvShareRAM[3];
static UINT8 DrvRecalc;
static INT32 cpu_trigger;
static INT32 requested_int;
static INT32 vblank_end_timer;
static INT32 game_select = 0;
static INT32 int_num;
static UINT8 DrvJoy1[16];
static UINT8 DrvJoy2[16];
static UINT8 DrvDips[4];
static UINT16 DrvInputs[2];
static UINT8 DrvReset;
static struct BurnInputInfo HyprduelInputList[] = {
{"P1 Coin", BIT_DIGITAL, DrvJoy2 + 0, "p1 coin" },
{"P1 Start", BIT_DIGITAL, DrvJoy2 + 4, "p1 start" },
{"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up" },
{"P1 Down", BIT_DIGITAL, DrvJoy1 + 1, "p1 down" },
{"P1 Left", BIT_DIGITAL, DrvJoy1 + 2, "p1 left" },
{"P1 Right", BIT_DIGITAL, DrvJoy1 + 3, "p1 right" },
{"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire 1" },
{"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 5, "p1 fire 2" },
{"P1 Button 3", BIT_DIGITAL, DrvJoy1 + 6, "p1 fire 3" },
{"P2 Coin", BIT_DIGITAL, DrvJoy2 + 1, "p2 coin" },
{"P2 Start", BIT_DIGITAL, DrvJoy2 + 5, "p2 start" },
{"P2 Up", BIT_DIGITAL, DrvJoy1 + 8, "p2 up" },
{"P2 Down", BIT_DIGITAL, DrvJoy1 + 9, "p2 down" },
{"P2 Left", BIT_DIGITAL, DrvJoy1 + 10, "p2 left" },
{"P2 Right", BIT_DIGITAL, DrvJoy1 + 11, "p2 right" },
{"P2 Button 1", BIT_DIGITAL, DrvJoy1 + 12, "p2 fire 1" },
{"P2 Button 2", BIT_DIGITAL, DrvJoy1 + 13, "p2 fire 2" },
{"P2 Button 3", BIT_DIGITAL, DrvJoy1 + 14, "p2 fire 3" },
{"Reset", BIT_DIGITAL, &DrvReset, "reset" },
{"Service", BIT_DIGITAL, DrvJoy2 + 2, "service" },
{"Service", BIT_DIGITAL, DrvJoy2 + 3, "service" },
{"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
{"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
{"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip" },
{"Dip D", BIT_DIPSWITCH, DrvDips + 3, "dip" },
};
STDINPUTINFO(Hyprduel)
static struct BurnDIPInfo HyprduelDIPList[]=
{
{0x15, 0xff, 0xff, 0x00, NULL },
{0x16, 0xff, 0xff, 0xbf, NULL },
{0x17, 0xff, 0xff, 0x01, NULL },
{0x18, 0xff, 0xff, 0x00, NULL },
{0 , 0xfe, 0 , 2, "Show Warning" },
{0x15, 0x01, 0x40, 0x40, "Off" },
{0x15, 0x01, 0x40, 0x00, "On" },
{0 , 0xfe, 0 , 2, "Service Mode" },
{0x15, 0x01, 0x80, 0x80, "Off" },
{0x15, 0x01, 0x80, 0x00, "On" },
{0 , 0xfe, 0 , 8, "Coin A" },
{0x16, 0x01, 0x07, 0x01, "4 Coins 1 Credits" },
{0x16, 0x01, 0x07, 0x02, "3 Coins 1 Credits" },
{0x16, 0x01, 0x07, 0x03, "2 Coins 1 Credits" },
{0x16, 0x01, 0x07, 0x07, "1 Coin 1 Credits" },
{0x16, 0x01, 0x07, 0x06, "1 Coin 2 Credits" },
{0x16, 0x01, 0x07, 0x05, "1 Coin 3 Credits" },
{0x16, 0x01, 0x07, 0x04, "1 Coin 4 Credits" },
{0x16, 0x01, 0x07, 0x00, "Free Play" },
{0 , 0xfe, 0 , 8, "Coin B" },
{0x16, 0x01, 0x38, 0x08, "4 Coins 1 Credits" },
{0x16, 0x01, 0x38, 0x10, "3 Coins 1 Credits" },
{0x16, 0x01, 0x38, 0x18, "2 Coins 1 Credits" },
{0x16, 0x01, 0x38, 0x38, "1 Coin 1 Credits" },
{0x16, 0x01, 0x38, 0x30, "1 Coin 2 Credits" },
{0x16, 0x01, 0x38, 0x28, "1 Coin 3 Credits" },
{0x16, 0x01, 0x38, 0x20, "1 Coin 4 Credits" },
{0x16, 0x01, 0x38, 0x00, "Free Play" },
{0 , 0xfe, 0 , 2, "Demo Sounds" },
{0x16, 0x01, 0x40, 0x40, "Off" },
{0x16, 0x01, 0x40, 0x00, "On" },
{0 , 0xfe, 0 , 2, "Start Up Mode" },
{0x16, 0x01, 0x80, 0x80, "Off" },
{0x16, 0x01, 0x80, 0x00, "On" },
{0 , 0xfe, 0 , 2, "Flip Screen" },
{0x17, 0x01, 0x01, 0x01, "Off" },
{0x17, 0x01, 0x01, 0x00, "On" },
{0 , 0xfe, 0 , 4, "Difficulty" },
{0x17, 0x01, 0x0c, 0x08, "Easy" },
{0x17, 0x01, 0x0c, 0x0c, "Normal" },
{0x17, 0x01, 0x0c, 0x04, "Hard" },
{0x17, 0x01, 0x0c, 0x00, "Very Hard" },
{0 , 0xfe, 0 , 4, "Lives" },
{0x17, 0x01, 0x30, 0x20, "2" },
{0x17, 0x01, 0x30, 0x30, "3" },
{0x17, 0x01, 0x30, 0x10, "4" },
{0x17, 0x01, 0x30, 0x00, "5" },
};
STDDIPINFO(Hyprduel)
static struct BurnDIPInfo MagerrorDIPList[] = {
{0 , 0xfe, 0 , 2, "Start Up Mode" },
{0x16, 0x01, 0x80, 0x80, "Game Mode" },
{0x16, 0x01, 0x80, 0x00, "Test Mode" },
{0 , 0xfe, 0 , 4, "Region (Hack)" },
{0x18, 0x01, 0x03, 0x00, "Japan" },
{0x18, 0x01, 0x03, 0x01, "USA (English)" },
{0x18, 0x01, 0x03, 0x02, "China" },
{0x18, 0x01, 0x03, 0x03, "Korea" },
};
STDDIPINFOEXT(Magerror, Hyprduel, Magerror )
static void update_irq_state()
{
INT32 irq = requested_int & (~i4x00_irq_enable) & int_num;
SekSetIRQLine(3, irq ? CPU_IRQSTATUS_ACK : CPU_IRQSTATUS_NONE);
}
static void subcpu_control_write(INT32 data)
{
switch (data)
{
case 0x0d:
case 0x0f:
case 0x01:
if (SekGetRESETLine(1) == 0) {
SekSetRESETLine(1, 1);
}
break;
case 0x00:
if (SekGetRESETLine(1) != 0) {
SekSetRESETLine(1, 0);
}
SekBurnUntilInt();
break;
case 0x0c:
case 0x80:
SekSetIRQLine(1, 2, CPU_IRQSTATUS_AUTO);
break;
}
}
static void __fastcall hyperduel_main_write_word(UINT32 address, UINT16 data)
{
// if (address != 0x478890) bprintf (0, _T("WW: %5.5x, %4.4x\n"), address, data);
switch (address)
{
case 0x400000: // magerror
case 0x800000: // hyprduel
subcpu_control_write(data);
return;
case 0xe00000:
return; // nop
}
bprintf (0, _T("Missed write (word) %5.5x\n"), address);
}
static void __fastcall hyperduel_main_write_byte(UINT32 address, UINT8 data)
{
// bprintf (0, _T("WB: %5.5x, %2.2x\n"), address, data);
switch (address)
{
case 0xe00001:
return; // nop
}
bprintf (0, _T("Missed write (byte) %5.5x\n"), address);
}
static UINT16 __fastcall hyperduel_main_read_word(UINT32 address)
{
// if (address != 0x4788a2) bprintf (0, _T("RW: %5.5x\n"), address);
switch (address)
{
case 0xe00000:
return (DrvDips[0] << 8) | 0xff;
case 0xe00002:
return (DrvDips[2] << 8) | (DrvDips[1] << 0);
case 0xe00004:
return DrvInputs[0];
case 0xe00006:
return DrvInputs[1];
}
// bprintf (0, _T("Missed read %5.5x\n"), address);
return 0;
}
static UINT8 __fastcall hyperduel_main_read_byte(UINT32 address)
{
// bprintf (0, _T("RB: %5.5x\n"), address);
return SekReadWord(address & ~1) >> ((~address & 1) * 8);
}
static void __fastcall hyperduel_main_sync_write_word(UINT32 address, UINT16 data)
{
if ((address & 0xff8000) == 0xc00000) {
address &= 0x7ffe;
UINT16 *ram = (UINT16*)DrvShareRAM[0];
ram[address / 2] = data;
if (address == 0x040e)
{
if (ram[0x40e/2] || ram[0x410/2])
{
if (cpu_trigger == 0 && SekGetRESETLine(1) == 0)
{
SekSetHALT(0, 1); // or idle??
cpu_trigger = 1001; // ??
}
}
return;
}
if (address == 0x0408)
{
if (cpu_trigger == 0 && SekGetRESETLine(1) == 0)
{
SekSetHALT(0, 1); // or idle??
cpu_trigger = 1002;
}
return;
}
}
}
static void __fastcall hyperduel_main_sync_write_byte(UINT32 address, UINT8 data)
{
if ((address & 0xff8000) == 0xc00000) {
address &= 0x7fff;
UINT16 *ram = (UINT16*)DrvShareRAM[0];
DrvShareRAM[0][address ^ 1] = data;
if ((address & ~1) == 0x040e)
{
if (ram[0x40e/2] || ram[0x410/2])
{
if (cpu_trigger == 0 && SekGetRESETLine(1) == 0)
{
SekSetHALT(0, 1);
cpu_trigger = 1001;
}
}
return;
}
if (address == 0x0408)
{
// if (ACCESSING_BITS_8_15) // iq_132
if (cpu_trigger == 0 && SekGetRESETLine(1) == 0)
{
SekSetHALT(0, 1);
cpu_trigger = 1002;
}
return;
}
}
}
static UINT16 __fastcall hyperduel_sub_sync_read_word(UINT32 address)
{
if ((address & 0xfffc00) == 0xc00400) {
if (address == 0xc00408)
{
if (cpu_trigger == 1001)
{
SekSetHALT(0, 0);
cpu_trigger = 0;
}
return *((UINT16*)(DrvShareRAM[0] + (address & 0x7ffe)));
}
}
if ((address & 0xfffc00) == 0xfff000)
{
if (address == 0xfff34c)
{
if (cpu_trigger == 1002)
{
SekSetHALT(0, 0);
cpu_trigger = 0;
}
return *((UINT16*)(DrvShareRAM[2] + (address - 0xfe4000)));
}
}
return 0;
}
static UINT8 __fastcall hyperduel_sub_sync_read_byte(UINT32 address)
{
if ((address & 0xfffc00) == 0xc00400)
{
if (address == 0xc00408)
{
if (cpu_trigger == 1001)
{
SekSetHALT(0, 0);
cpu_trigger = 0;
}
return DrvShareRAM[0][(address & 0x7fff) ^ 1];
}
}
if ((address & 0xfffc00) == 0xfff000)
{
if (address == 0xfff34c)
{
if (cpu_trigger == 1002)
{
SekSetHALT(0, 0);
cpu_trigger = 0;
}
return DrvShareRAM[2][(address - 0xfe4000) ^ 1];
}
}
return 0;
}
static void __fastcall hyperduel_sub_write_word(UINT32 address, UINT16 data)
{
switch (address)
{
// hyprduel
case 0x400000:
case 0x400002:
if (game_select == 0) BurnYM2151Write((address / 2) & 1, data);
return;
// magerror
case 0x800000:
case 0x800002:
if (game_select == 1) BurnYM2413Write((address / 2) & 1, data);
return;
// both
case 0x400004:
case 0x800004:
MSM6295Write(0, data & 0xff);
return;
}
}
static void __fastcall hyperduel_sub_write_byte(UINT32 address, UINT8 data)
{
switch (address)
{
case 0x400000:
case 0x400001:
case 0x400002:
case 0x400003:
if (game_select == 0) BurnYM2151Write((address / 2) & 1, data);
return;
case 0x800000:
case 0x800001:
case 0x800002:
case 0x800003:
if (game_select == 1) BurnYM2413Write((address / 2) & 1, data);
return;
// both
case 0x400004:
case 0x400005:
case 0x800004:
case 0x800005:
MSM6295Write(0, data & 0xff);
return;
}
}
static UINT16 __fastcall hyperduel_sub_read_word(UINT32 address)
{
switch (address)
{
case 0x400000:
case 0x400002:
return (game_select == 0) ? BurnYM2151Read() : 0;
case 0x800000:
case 0x800002:
return 0;
case 0x400004:
case 0x800004:
return MSM6295Read(0);
}
return 0;
}
static UINT8 __fastcall hyperduel_sub_read_byte(UINT32 address)
{
switch (address)
{
case 0x400000:
case 0x400001:
case 0x400002:
case 0x400003:
return (game_select == 0) ? BurnYM2151Read() : 0;
case 0x800000:
case 0x800001:
case 0x800002:
case 0x800003:
return 0;
case 0x400004:
case 0x400005:
case 0x800004:
case 0x800005:
return MSM6295Read(0);
}
return 0;
}
static void irq_cause_write(UINT16 data)
{
if (data == int_num)
requested_int &= ~(int_num & ~i4x00_irq_enable);
else
requested_int &= ~(data & i4x00_irq_enable);
update_irq_state();
}
static UINT16 irq_cause_read()
{
return requested_int;
}
static void DrvYM2151IrqHandler(INT32 state)
{
SekSetIRQLine(1, state ? CPU_IRQSTATUS_ACK : CPU_IRQSTATUS_NONE);
}
static INT32 DrvDoReset()
{
memset (AllRam, 0, RamEnd - AllRam);
SekReset(0);
SekReset(1);
i4x00_reset();
MSM6295Reset(0);
if (game_select) {
BurnYM2413Reset();
} else {
BurnYM2151Reset();
}
SekSetRESETLine(1, 1); // start in reset
cpu_trigger = 0;
requested_int = 0;
vblank_end_timer = -1;
return 0;
}
static INT32 MemIndex()
{
UINT8 *Next; Next = AllMem;
Drv68KROM[0] = Next; Next += 0x080000;
DrvGfxROM[0] = Next; Next += 0x410000;
DrvGfxROM[1] = Next; Next += 0x800000;
DrvGfxROM[2] = Next; Next += 0x000400;
MSM6295ROM = Next;
DrvSndROM = Next; Next += 0x040000;
AllRam = Next;
DrvShareRAM[0] = Next; Next += 0x020000;
DrvShareRAM[1] = Next; Next += 0x004000;
DrvShareRAM[2] = Next; Next += 0x01c000;
RamEnd = Next;
MemEnd = Next;
return 0;
}
static INT32 HyprduelInit()
{
BurnAllocMemIndex();
{
INT32 k = 0;
if (BurnLoadRomExt(Drv68KROM[0] + 0x0000001, k++, 2, 0)) return 1;
if (BurnLoadRomExt(Drv68KROM[0] + 0x0000000, k++, 2, 0)) return 1;
if (BurnLoadRomExt(DrvGfxROM[0] + 0x0000000, k++, 8, LD_GROUP(2))) return 1;
if (BurnLoadRomExt(DrvGfxROM[0] + 0x0000002, k++, 8, LD_GROUP(2))) return 1;
if (BurnLoadRomExt(DrvGfxROM[0] + 0x0000004, k++, 8, LD_GROUP(2))) return 1;
if (BurnLoadRomExt(DrvGfxROM[0] + 0x0000006, k++, 8, LD_GROUP(2))) return 1;
memset (DrvGfxROM[0] + 0x400000, 0xff, 0x10000);
if (BurnLoadRomExt(DrvSndROM + 0x0000000, k++, 1, 0)) return 1;
BurnNibbleExpand(DrvGfxROM[0], DrvGfxROM[1], 0x400000, 1, 0);
}
SekInit(0, 0x68000);
SekOpen(0);
SekMapMemory(Drv68KROM[0], 0x000000, 0x07ffff, MAP_ROM);
SekMapMemory(Drv68KROM[0], 0x080000, 0x0fffff, MAP_ROM);
SekMapMemory(DrvShareRAM[0], 0xc00000, 0xc07fff, MAP_RAM);
SekMapMemory(DrvShareRAM[1], 0xfe0000, 0xfe3fff, MAP_RAM);
SekMapMemory(DrvShareRAM[2], 0xfe4000, 0xffffff, MAP_RAM);
SekSetWriteWordHandler(0, hyperduel_main_write_word);
SekSetWriteByteHandler(0, hyperduel_main_write_byte);
SekSetReadWordHandler(0, hyperduel_main_read_word);
SekSetReadByteHandler(0, hyperduel_main_read_byte);
if (0)
{
SekMapHandler(1, 0xc00400, 0xc007ff, MAP_WRITE);
SekSetWriteWordHandler(1, hyperduel_main_sync_write_word);
SekSetWriteByteHandler(1, hyperduel_main_sync_write_byte);
}
i4x00_init(0x400000, DrvGfxROM[0], DrvGfxROM[1], 0x400000, irq_cause_write, irq_cause_read, NULL, 1, 0);
SekClose();
SekInit(1, 0x68000);
SekOpen(1);
SekMapMemory(DrvShareRAM[0], 0x000000, 0x003fff, MAP_RAM);
SekMapMemory(DrvShareRAM[2], 0x004000, 0x007fff, MAP_ROM); // read only
SekMapMemory(DrvShareRAM[0], 0xc00000, 0xc07fff, MAP_RAM);
SekMapMemory(DrvShareRAM[1], 0xfe0000, 0xfe3fff, MAP_RAM);
SekMapMemory(DrvShareRAM[2], 0xfe4000, 0xffffff, MAP_RAM);
SekSetWriteWordHandler(0, hyperduel_sub_write_word);
SekSetWriteByteHandler(0, hyperduel_sub_write_byte);
SekSetReadWordHandler(0, hyperduel_sub_read_word);
SekSetReadByteHandler(0, hyperduel_sub_read_byte);
if (0)
{
SekMapHandler(1, 0xc00400, 0xc007ff, MAP_READ);
SekMapHandler(1, 0xfff000, 0xfff3ff, MAP_READ);
SekSetReadWordHandler(1, hyperduel_sub_sync_read_word);
SekSetReadByteHandler(1, hyperduel_sub_sync_read_byte);
}
SekClose();
int_num = 0x02;
BurnYM2151Init(4000000);
BurnYM2151SetIrqHandler(&DrvYM2151IrqHandler);
BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_1, 0.45, BURN_SND_ROUTE_LEFT);
BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_2, 0.45, BURN_SND_ROUTE_RIGHT);
MSM6295Init(0, 2062500 / MSM6295_PIN7_HIGH, 1);
MSM6295SetRoute(0, 0.47, BURN_SND_ROUTE_BOTH);
GenericTilesInit();
DrvDoReset();
return 0;
}
static INT32 MagerrorInit()
{
game_select = 1;
BurnAllocMemIndex();
{
INT32 k = 0;
if (BurnLoadRomExt(Drv68KROM[0] + 0x0000001, k++, 2, 0)) return 1;
if (BurnLoadRomExt(Drv68KROM[0] + 0x0000000, k++, 2, 0)) return 1;
if (BurnLoadRomExt(DrvGfxROM[0] + 0x0000000, k++, 8, LD_GROUP(2))) return 1;
if (BurnLoadRomExt(DrvGfxROM[0] + 0x0000002, k++, 8, LD_GROUP(2))) return 1;
if (BurnLoadRomExt(DrvGfxROM[0] + 0x0000004, k++, 8, LD_GROUP(2))) return 1;
if (BurnLoadRomExt(DrvGfxROM[0] + 0x0000006, k++, 8, LD_GROUP(2))) return 1;
memset (DrvGfxROM[0] + 0x400000, 0xff, 0x10000);
if (BurnLoadRomExt(DrvSndROM + 0x0000000, k++, 1, 0)) return 1;
BurnNibbleExpand(DrvGfxROM[0], DrvGfxROM[1], 0x400000, 1, 0);
}
SekInit(0, 0x68000);
SekOpen(0);
SekMapMemory(Drv68KROM[0], 0x000000, 0x07ffff, MAP_ROM);
SekMapMemory(DrvShareRAM[0], 0xc00000, 0xc1ffff, MAP_RAM);
SekMapMemory(DrvShareRAM[1], 0xfe0000, 0xfe3fff, MAP_RAM);
SekMapMemory(DrvShareRAM[2], 0xfe4000, 0xffffff, MAP_RAM);
SekSetWriteWordHandler(0, hyperduel_main_write_word);
SekSetWriteByteHandler(0, hyperduel_main_write_byte);
SekSetReadWordHandler(0, hyperduel_main_read_word);
SekSetReadByteHandler(0, hyperduel_main_read_byte);
i4x00_init(0x800000, DrvGfxROM[0], DrvGfxROM[1], 0x400000, irq_cause_write, irq_cause_read, NULL, 1, 0);
SekClose();
SekInit(1, 0x68000);
SekOpen(1);
SekMapMemory(DrvShareRAM[0], 0x000000, 0x003fff, MAP_RAM);
SekMapMemory(DrvShareRAM[2], 0x004000, 0x007fff, MAP_ROM); // read only
SekMapMemory(DrvShareRAM[0], 0xc00000, 0xc1ffff, MAP_RAM);
SekMapMemory(DrvShareRAM[1], 0xfe0000, 0xfe3fff, MAP_RAM);
SekMapMemory(DrvShareRAM[2], 0xfe4000, 0xffffff, MAP_RAM);
SekSetWriteWordHandler(0, hyperduel_sub_write_word);
SekSetWriteByteHandler(0, hyperduel_sub_write_byte);
SekSetReadWordHandler(0, hyperduel_sub_read_word);
SekSetReadByteHandler(0, hyperduel_sub_read_byte);
SekClose();
int_num = 0x01;
BurnYM2413Init(3579545);
BurnYM2413SetAllRoutes(1.00, BURN_SND_ROUTE_BOTH);
MSM6295Init(0, 2062500 / MSM6295_PIN7_HIGH, 1);
MSM6295SetRoute(0, 0.47, BURN_SND_ROUTE_BOTH);
GenericTilesInit();
DrvDoReset();
return 0;
}
static INT32 DrvExit()
{
GenericTilesExit();
if (game_select) {
BurnYM2413Exit();
} else {
BurnYM2151Exit();
}
MSM6295Exit(0);
SekExit();
BurnFree (AllMem);
MSM6295ROM = NULL;
game_select = 0;
return 0;
}
static void interrupt_callback(INT32 line)
{
if (line == 0) /* TODO: fix this! */
{
requested_int |= 0x01;
requested_int |= 0x20;
SekSetIRQLine(2, CPU_IRQSTATUS_AUTO);
vblank_end_timer = (10000000 / 1000000) * 2500;
}
else
requested_int |= 0x12; /* hsync */
update_irq_state();
}
static INT32 DrvFrame()
{
// magerror region hack based on http://sudden-desu.net/entry/level-select-in-magical-error-wo-sagase
if (game_select == 1 && 0) {
if (DrvDips[3] != 0)
{
SekOpen(0);
if (SekReadWord(0xc0e29a) != (DrvDips[3] & 3)) {
bprintf (0, _T("hack: %4.4x\n"), SekReadWord(0xc0e29a));
SekWriteWord(0xc0e29a, DrvDips[3] & 3);
}
SekClose();
}
}
if (DrvReset) {
DrvDoReset();
}
// SekNewFrame();
{
memset (DrvInputs, 0xff, sizeof(DrvInputs));
for (INT32 i = 0; i < 16; i++) {
DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
}
}
INT32 nSegment;
INT32 nInterleave = 512;
INT32 nSoundBufferPos = 0;
INT32 nCyclesTotal[2] = { 10000000 / 60, 10000000 / 60 };
INT32 nCyclesDone[2] = { 0, 0 };
for (INT32 i = 0; i < nInterleave; i++)
{
SekOpen(0);
INT32 cycles = SekTotalCycles();
CPU_RUN(0, Sek);
interrupt_callback(i);
if (i4x00_blitter_timer > 0) {
i4x00_blitter_timer -= SekTotalCycles() - cycles;
if (i4x00_blitter_timer < 0) {
requested_int |= 1 << 2; //blitter_bit;
update_irq_state();
}
}
if (vblank_end_timer > 0) {
vblank_end_timer -= SekTotalCycles() - cycles;
if (vblank_end_timer < 0) {
requested_int &= ~0x20;
}
}
cycles = SekTotalCycles();
SekClose();
SekOpen(1);
nCyclesDone[1] += SekRun(cycles - SekTotalCycles());
if (game_select == 1) {
if ((i & 0x1f) == 0x1f) SekSetIRQLine(1, CPU_IRQSTATUS_AUTO);
}
if (pBurnSoundOut && (i & 3) == 3 && game_select == 0) {
nSegment = nBurnSoundLen /( nInterleave / 4);
BurnYM2151Render(pBurnSoundOut + (nSoundBufferPos << 1), nSegment);
MSM6295Render(0, pBurnSoundOut + (nSoundBufferPos << 1), nSegment);
nSoundBufferPos += nSegment;
}
SekClose();
}
SekOpen(1);
if (pBurnSoundOut && game_select == 0) {
nSegment = nBurnSoundLen - nSoundBufferPos;
if (nSegment > 0) {
BurnYM2151Render(pBurnSoundOut + (nSoundBufferPos << 1), nSegment);
MSM6295Render(0, pBurnSoundOut + (nSoundBufferPos << 1), nSegment);
}
}
if (pBurnSoundOut && game_select == 1) {
BurnYM2413Render(pBurnSoundOut, nBurnSoundLen);
MSM6295Render(pBurnSoundOut, nBurnSoundLen);
}
SekClose();
if (pBurnDraw) {
BurnDrvRedraw();
}
return 0;
}
static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
{
struct BurnArea ba;
if (pnMin != NULL) {
*pnMin = 0x029698;
}
if (nAction & ACB_MEMORY_RAM) {
memset(&ba, 0, sizeof(ba));
ba.Data = AllRam;
ba.nLen = RamEnd-AllRam;
ba.szName = "All Ram";
BurnAcb(&ba);
}
if (nAction & ACB_DRIVER_DATA) {
SekScan(nAction);
i4x00_scan(nAction, pnMin);
if (game_select == 1) {
BurnYM2413Scan(nAction, pnMin);
} else {
BurnYM2151Scan(nAction, pnMin);
}
MSM6295Scan(nAction, pnMin);
SCAN_VAR(cpu_trigger);
SCAN_VAR(requested_int);
SCAN_VAR(vblank_end_timer);
}
return 0;
}
// Hyper Duel (Japan set 1)
static struct BurnRomInfo hyprduelRomDesc[] = {
{ "24.u24", 0x040000, 0xc7402722, 1 | BRF_PRG | BRF_ESS }, // 0 68K Code
{ "23.u23", 0x040000, 0xd8297c2b, 1 | BRF_PRG | BRF_ESS }, // 1
{ "ts_hyper-1.u74", 0x100000, 0x4b3b2d3c, 2 | BRF_GRA }, // 2 Graphics
{ "ts_hyper-2.u75", 0x100000, 0xdc230116, 2 | BRF_GRA }, // 3
{ "ts_hyper-3.u76", 0x100000, 0x2d770dd0, 2 | BRF_GRA }, // 4
{ "ts_hyper-4.u77", 0x100000, 0xf88c6d33, 2 | BRF_GRA }, // 5
{ "97.u97", 0x040000, 0xbf3f8574, 3 | BRF_SND }, // 6 Samples
};
STD_ROM_PICK(hyprduel)
STD_ROM_FN(hyprduel)
struct BurnDriver BurnDrvHyprduel = {
"hyprduel", NULL, NULL, NULL, "1993",
"Hyper Duel (Japan set 1)\0", NULL, "Technosoft", "Miscellaneous",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_HORSHOOT, 0,
NULL, hyprduelRomInfo, hyprduelRomName, NULL, NULL, NULL, NULL, HyprduelInputInfo, HyprduelDIPInfo,
HyprduelInit, DrvExit, DrvFrame, i4x00_draw, DrvScan, &DrvRecalc, 0x1000,
320, 224, 4, 3
};
// Hyper Duel (Japan set 2)
static struct BurnRomInfo hyprduel2RomDesc[] = {
{ "24a.u24", 0x040000, 0x2458f91d, 1 | BRF_PRG | BRF_ESS }, // 0 68K Code
{ "23a.u23", 0x040000, 0x98aedfca, 1 | BRF_PRG | BRF_ESS }, // 1
{ "ts_hyper-1.u74", 0x100000, 0x4b3b2d3c, 2 | BRF_GRA }, // 2 Graphics
{ "ts_hyper-2.u75", 0x100000, 0xdc230116, 2 | BRF_GRA }, // 3
{ "ts_hyper-3.u76", 0x100000, 0x2d770dd0, 2 | BRF_GRA }, // 4
{ "ts_hyper-4.u77", 0x100000, 0xf88c6d33, 2 | BRF_GRA }, // 5
{ "97.u97", 0x040000, 0xbf3f8574, 3 | BRF_SND }, // 6 Samples
};
STD_ROM_PICK(hyprduel2)
STD_ROM_FN(hyprduel2)
struct BurnDriver BurnDrvHyprduel2 = {
"hyprduel2", "hyprduel", NULL, NULL, "1993",
"Hyper Duel (Japan set 2)\0", NULL, "Technosoft", "Miscellaneous",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_POST90S, GBF_HORSHOOT, 0,
NULL, hyprduel2RomInfo, hyprduel2RomName, NULL, NULL, NULL, NULL, HyprduelInputInfo, HyprduelDIPInfo,
HyprduelInit, DrvExit, DrvFrame, i4x00_draw, DrvScan, &DrvRecalc, 0x1000,
320, 224, 4, 3
};
// Magical Error wo Sagase
static struct BurnRomInfo magerrorRomDesc[] = {
{ "24.u24", 0x040000, 0x5e78027f, 1 | BRF_PRG | BRF_ESS }, // 0 68K Code
{ "23.u23", 0x040000, 0x7271ec70, 1 | BRF_PRG | BRF_ESS }, // 1
{ "mr93046-02.u74", 0x100000, 0xf7ba06fb, 2 | BRF_GRA }, // 2 Graphics
{ "mr93046-04.u75", 0x100000, 0x8c114d15, 2 | BRF_GRA }, // 3
{ "mr93046-01.u76", 0x100000, 0x6cc3b928, 2 | BRF_GRA }, // 4
{ "mr93046-03.u77", 0x100000, 0x6b1eb0ea, 2 | BRF_GRA }, // 5
{ "97.u97", 0x040000, 0x2e62bca8, 3 | BRF_SND }, // 6 Samples
};
STD_ROM_PICK(magerror)
STD_ROM_FN(magerror)
struct BurnDriver BurnDrvMagerror = {
"magerror", NULL, NULL, NULL, "1994",
"Magical Error wo Sagase\0", NULL, "Technosoft / Jaleco", "Miscellaneous",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_PUZZLE, 0,
NULL, magerrorRomInfo, magerrorRomName, NULL, NULL, NULL, NULL, HyprduelInputInfo, MagerrorDIPInfo,
MagerrorInit, DrvExit, DrvFrame, i4x00_draw, DrvScan, &DrvRecalc, 0x1000,
320, 224, 4, 3
};

File diff suppressed because it is too large Load Diff