Fix gstrik2 and add hyprduel (prelim)
This commit is contained in:
parent
354c780c5a
commit
708bd57d54
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue