summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <salese_corp_ltd@email.it>2015-06-30 23:22:59 +0200
committer angelosa <salese_corp_ltd@email.it>2015-06-30 23:22:59 +0200
commitdb079fd280ec776d686cc414889d304a149eb6e9 (patch)
treec9bc758b3c20249ea88279607b9f1912a1620da7
parentde9c38923a440b678bcf4b8918e27e58c61a5457 (diff)
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)
-rw-r--r--src/mame/drivers/taitoair.c46
-rw-r--r--src/mame/includes/taitoair.h6
-rw-r--r--src/mame/video/taitoair.c139
3 files changed, 139 insertions, 52 deletions
diff --git a/src/mame/drivers/taitoair.c b/src/mame/drivers/taitoair.c
index e893b439f4c..5dfc0f29f6b 100644
--- a/src/mame/drivers/taitoair.c
+++ b/src/mame/drivers/taitoair.c
@@ -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 )
diff --git a/src/mame/includes/taitoair.h b/src/mame/includes/taitoair.h
index b5536f6cfa9..356801eede6 100644
--- a/src/mame/includes/taitoair.h
+++ b/src/mame/includes/taitoair.h
@@ -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);
diff --git a/src/mame/video/taitoair.c b/src/mame/video/taitoair.c
index fc231c09c69..600beaf048c 100644
--- a/src/mame/video/taitoair.c
+++ b/src/mame/video/taitoair.c
@@ -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);