taitoair.c fixes and changes:

- Very preliminary Framebuffer DMA hook-up, mostly used for Top Landing to show Course Select on screen;
- Fixed analog inputs;
- Fixed color select for 3d;
- Fixed tilemap priority;

(I assume with this we can promote Top Landing as working)
This commit is contained in:
angelosa 2015-06-30 23:22:59 +02:00
parent de9c38923a
commit db079fd280
3 changed files with 139 additions and 52 deletions

View File

@ -220,6 +220,13 @@ cpu #2 (PC=00000609): unmapped memory word read from 00006838 & FFFF
cpu #2 (PC=0000060E): unmapped memory word read from 0000683A & FFFF
****************************************************************************/
/*!
@todo - Framebuffer DMA requires palette switch to be selected dynamically, see at first stage Course Select in Top Landing;
- Air Inferno: exception with DIVIDE BY ZERO after some time of gameplay;
- Air Inferno: Expert course has wrong 3d geometry;
- Top Landing: Night stages might have wrong priority for stars-above-sea;
- Input limiters / analog thresholds for both games;
*/
#include "emu.h"
#include "cpu/z80/z80.h"
@ -370,6 +377,33 @@ WRITE8_MEMBER(taitoair_state::sound_bankswitch_w)
membank("z80bank")->set_entry(data & 3);
}
/*!
@brief Framebuffer DMA control
@regs [0] x--- ---- ---- ---- copy framebuffer to the screen
[0] --x- ---- ---- ---- unknown, used on POST test
[0] 1001 1111 1111 1111 used by Air Inferno after erase op, erase -> copy?
[0] 0001 1111 1111 1111 erase op?
[1] xxxx xxxx xxxx xxxx fill value? 0xffff by Top Landing, 0x0000 Air Inferno
[2] (unused)
[3] both games uses 0xb7, most likely a register setting.
*/
WRITE16_MEMBER(taitoair_state::dma_regs_w)
{
printf("%08x %04x\n",offset,data);
if(offset == 0 && ACCESSING_BITS_8_15)
{
if(data == 0x1fff)
{
fb_erase_op();
}
else if(data & 0x8000)
{
/*! @todo it also flushes current palette. */
fb_copy_op();
}
}
}
/***********************************************************
MEMORY STRUCTURES
@ -382,7 +416,7 @@ static ADDRESS_MAP_START( airsys_map, AS_PROGRAM, 16, taitoair_state )
AM_RANGE(0x180000, 0x187fff) AM_RAM_WRITE(airsys_gradram_w) AM_SHARE("gradram") /* "gradiation ram (0/1)" */
AM_RANGE(0x188000, 0x189fff) AM_MIRROR(0x2000) AM_RAM_WRITE(airsys_paletteram16_w) AM_SHARE("paletteram")
AM_RANGE(0x800000, 0x820fff) AM_DEVREADWRITE("tc0080vco", tc0080vco_device, word_r, word_w) /* tilemaps, sprites */
// AM_RANGE(0x906000, 0x906007) AM_RAM // DMA?
AM_RANGE(0x906000, 0x906007) AM_WRITE(dma_regs_w) // DMA?
AM_RANGE(0x908000, 0x90ffff) AM_RAM AM_SHARE("line_ram") /* "line ram" */
AM_RANGE(0x910000, 0x91ffff) AM_RAM AM_SHARE("dsp_ram") /* "dsp common ram" (TMS320C25) */
AM_RANGE(0x980000, 0x98000f) AM_RAM AM_SHARE("tc0430grw") /* TC0430GRW roz transform coefficients */
@ -585,10 +619,10 @@ static INPUT_PORTS_START( topland )
PORT_BIT( 0x00ff, 0x0000, IPT_AD_STICK_Z ) PORT_MINMAX(0x0080,0x007f) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1) PORT_REVERSE
PORT_START(STICK2_PORT_TAG)
PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0xf800,0x07ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1)
PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1)
PORT_START(STICK3_PORT_TAG)
PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0xf800,0x07ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1)
PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1)
INPUT_PORTS_END
static INPUT_PORTS_START( ainferno )
@ -645,10 +679,10 @@ static INPUT_PORTS_START( ainferno )
PORT_BIT( 0x00ff, 0x0000, IPT_AD_STICK_Z ) PORT_MINMAX(0x0080,0x007f) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1) PORT_REVERSE
PORT_START(STICK2_PORT_TAG)
PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0xf800,0x7ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1)
PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1)
PORT_START(STICK3_PORT_TAG)
PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0xf800,0x7ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1)
PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1)
INPUT_PORTS_END
@ -953,6 +987,6 @@ ROM_END
/* ( YEAR NAME PARENT MACHINE INPUT INIT MONITOR COMPANY FULLNAME */
GAME( 1988, topland, 0, airsys, topland, driver_device, 0, ROT0, "Taito Corporation Japan", "Top Landing (World)", GAME_NOT_WORKING )
GAME( 1988, topland, 0, airsys, topland, driver_device, 0, ROT0, "Taito Corporation Japan", "Top Landing (World)", GAME_IMPERFECT_GRAPHICS )
GAME( 1990, ainferno, 0, airsys, ainferno, driver_device, 0, ROT0, "Taito America Corporation", "Air Inferno (US)", GAME_NOT_WORKING )
GAME( 1990, ainfernoj,ainferno, airsys, ainferno, driver_device, 0, ROT0, "Taito Corporation Japan", "Air Inferno (Japan)", GAME_NOT_WORKING )

View File

@ -119,6 +119,7 @@ public:
DECLARE_READ16_MEMBER(stick2_input_r);
DECLARE_WRITE8_MEMBER(sound_bankswitch_w);
DECLARE_WRITE16_MEMBER(dsp_flags_w);
DECLARE_WRITE16_MEMBER(dma_regs_w);
virtual void machine_start();
virtual void machine_reset();
@ -126,7 +127,10 @@ public:
UINT32 screen_update_taitoair(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
int draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
int draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect, int start_offset );
void fb_copy_op(void);
void fb_fill_op(void);
void fb_erase_op(void);
void fill_slope( bitmap_ind16 &bitmap, const rectangle &cliprect, UINT16 header, INT32 x1, INT32 x2, INT32 sl1, INT32 sl2, INT32 y1, INT32 y2, INT32 *nx1, INT32 *nx2 );
void fill_poly( bitmap_ind16 &bitmap, const rectangle &cliprect, const struct taitoair_poly *q );
int projectEyeCoordToScreen(float* projectionMatrix,const int Res,INT16* eyePoint3d,int type);

View File

@ -259,24 +259,26 @@ void taitoair_state::fill_slope( bitmap_ind16 &bitmap, const rectangle &cliprect
if (xx2 > cliprect.max_x)
xx2 = cliprect.max_x;
if(header & 0x4000 || machine().input().code_pressed(KEYCODE_Q))
if(header & 0x4000 && machine().input().code_pressed(KEYCODE_Q))
{
base_color = machine().rand() & 0x3fff;
grad_col = 0;
}
else if(header & 0x40)
{
/* Non-terrain elements are colored with this. */
base_color = (header & 0x3f) + 0x340;
grad_col = 0;
}
else
else if(m_paletteram[(header & 0xff)+0x300] & 0x8000)
{
/* Terrain elements, with a gradient applied. */
/*! @todo it's unknown if gradient color applies by global screen Y coordinate or there's a calculation to somewhere ... */
base_color = ((header & 0x3f) * 0x80) + 0x2040;
if(header & 0x3fe0)
base_color = machine().rand() & 0x3fff;
grad_col = (y1 >> 3) & 0x3f;
}
else
{
/* Non-terrain elements are colored with this. */
base_color = (header & 0xff) + 0x300;
grad_col = 0;
}
while (xx1 <= xx2)
{
@ -388,8 +390,84 @@ void taitoair_state::fill_poly( bitmap_ind16 &bitmap, const rectangle &cliprect,
dsp handlers
***************************************************************************/
/*
TODO: still don't know how this works. It calls three values (0x1fff-0x5fff-0xdfff), for two or three offsets.
void taitoair_state::fb_copy_op()
{
/*! @todo declare once */
rectangle cliprect;
/* printf("%04x -> %d\n",data,offset); */
cliprect.min_x = 0;
cliprect.min_y = 3*16;
cliprect.max_x = m_screen->width() - 1;
cliprect.max_y = m_screen->height() - 1;
/* clear screen fb */
m_framebuffer[1]->fill(0, cliprect);
/* copy buffer fb into screen fb (at this stage we are ready to draw) */
copybitmap_trans(*m_framebuffer[1], *m_framebuffer[0], 0, 0, 0, 0, cliprect, 0);
/* now clear buffer fb */
m_framebuffer[0]->fill(0, cliprect);
}
void taitoair_state::fb_erase_op()
{
/*! @todo declare once */
rectangle cliprect;
/* printf("%04x -> %d\n",data,offset); */
cliprect.min_x = 0;
cliprect.min_y = 3*16;
cliprect.max_x = m_screen->width() - 1;
cliprect.max_y = m_screen->height() - 1;
m_framebuffer[0]->fill(0, cliprect);
m_framebuffer[1]->fill(0, cliprect);
}
void taitoair_state::fb_fill_op()
{
/*! @todo declare once */
rectangle cliprect;
/* printf("%04x -> %d\n",data,offset); */
cliprect.min_x = 0;
cliprect.min_y = 3*16;
cliprect.max_x = m_screen->width() - 1;
cliprect.max_y = m_screen->height() - 1;
if (m_line_ram[0x3fff])
{
int adr = 0x3fff;
while (adr >= 0 && m_line_ram[adr] && m_line_ram[adr] != 0x4000)
{
int pcount = 0;
m_q.header = m_line_ram[adr--];
while (pcount < TAITOAIR_POLY_MAX_PT && adr >= 1 && !(m_line_ram[adr] & 0xc000))
{
m_q.p[pcount].y = m_line_ram[adr--] + 3 * 16;
m_q.p[pcount].x = m_line_ram[adr--];
pcount++;
}
adr--;
m_q.pcount = pcount;
if (!(m_line_ram[adr] & 0x8000))
{
m_q.header |= 0x4000;
logerror("special poly at %04x\n", adr);
while(adr >= 0 && !(m_line_ram[adr] & 0xc000))
adr--;
}
fill_poly(*m_framebuffer[0], cliprect, &m_q);
}
}
}
/*!
@todo still don't know how this works. It calls three values (0x1fff-0x5fff-0xdfff), for two or three offsets.
In theory this should fit into framebuffer draw, display, clear and swap in some way.
*/
WRITE16_MEMBER(taitoair_state::dsp_flags_w)
@ -407,43 +485,13 @@ WRITE16_MEMBER(taitoair_state::dsp_flags_w)
/* clear and copy operation if offset is 0x3001 */
if(offset == 1)
{
/* clear screen fb */
m_framebuffer[1]->fill(0, cliprect);
/* copy buffer fb into screen fb (at this stage we are ready to draw) */
copybitmap_trans(*m_framebuffer[1], *m_framebuffer[0], 0, 0, 0, 0, cliprect, 0);
/* now clear buffer fb */
m_framebuffer[0]->fill(0, cliprect);
fb_copy_op();
}
/* if offset 0x3001 OR 0x3002 we put data in the buffer fb */
if(offset)
{
if (m_line_ram[0x3fff])
{
int adr = 0x3fff;
while (adr >= 0 && m_line_ram[adr] && m_line_ram[adr] != 0x4000)
{
int pcount = 0;
m_q.header = m_line_ram[adr--];
while (pcount < TAITOAIR_POLY_MAX_PT && adr >= 1 && !(m_line_ram[adr] & 0xc000))
{
m_q.p[pcount].y = m_line_ram[adr--] + 3 * 16;
m_q.p[pcount].x = m_line_ram[adr--];
pcount++;
}
adr--;
m_q.pcount = pcount;
if (!(m_line_ram[adr] & 0x8000))
{
m_q.header |= 0x4000;
logerror("special poly at %04x\n", adr);
while(adr >= 0 && !(m_line_ram[adr] & 0xc000))
adr--;
}
fill_poly(*m_framebuffer[0], cliprect, &m_q);
}
}
fb_fill_op();
}
}
}
@ -505,13 +553,14 @@ UINT32 taitoair_state::screen_update_taitoair(screen_device &screen, bitmap_ind1
}
m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 0, 0, 0);
copybitmap_trans(bitmap, *m_framebuffer[1], 0, 0, 0, 0, cliprect, 0);
m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 0, 0, 0);
sprite_ptr = draw_sprites(bitmap, cliprect);
m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 1, 0, 0);
m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 1, 0, 0);
m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 2, 0, 0);