summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <salese_corp_ltd@email.it>2018-03-12 03:25:20 +0100
committer angelosa <salese_corp_ltd@email.it>2018-03-12 03:27:24 +0100
commit8f9e31f01382874370d7a2753590d6a8fb9708ea (patch)
tree50ef710482519cff83409304e9f10e52e71293d1
parenta8d7ce5fc65038c628df7ca2146ee2223dca30ad (diff)
model2.cpp: added direct framebuffer drawing, used by Last Bronx title screen [Angelo Salese]
-rw-r--r--src/mame/drivers/model2.cpp16
-rw-r--r--src/mame/includes/model2.h15
-rw-r--r--src/mame/video/model2.cpp50
3 files changed, 65 insertions, 16 deletions
diff --git a/src/mame/drivers/model2.cpp b/src/mame/drivers/model2.cpp
index 11c5e3c4948..9ab2a19fcd2 100644
--- a/src/mame/drivers/model2.cpp
+++ b/src/mame/drivers/model2.cpp
@@ -1347,7 +1347,7 @@ WRITE32_MEMBER(model2_state::copro_w)
READ32_MEMBER(model2_state::render_mode_r)
{
- return (m_render_unk << 14) | (m_render_mode << 2);
+ return (m_render_unk << 14) | (m_render_mode << 2) | (m_render_test_mode << 0);
}
WRITE32_MEMBER(model2_state::render_mode_w)
@@ -1355,6 +1355,9 @@ WRITE32_MEMBER(model2_state::render_mode_w)
// ---- -x-- (1) 60 Hz mode
// (0) 30 Hz mode - skytargt, desert, vstriker, vcop
// ---- ---x Test Mode (Host can "access memories that are always being reloaded")
+ // Effectively used by Last Bronx to r/w to the framebuffer
+ m_render_test_mode = bool(BIT(data,0));
+
m_render_mode = bool(BIT(data,2));
// undocumented, unknown purpose
@@ -1408,6 +1411,11 @@ READ8_MEMBER(model2_state::tgpid_r)
return ID[offset];
}
+READ16_MEMBER(model2_state::fbvram_bankA_r) { return m_fbvramA[offset]; }
+READ16_MEMBER(model2_state::fbvram_bankB_r) { return m_fbvramB[offset]; }
+WRITE16_MEMBER(model2_state::fbvram_bankA_w) { COMBINE_DATA(&m_fbvramA[offset]); }
+WRITE16_MEMBER(model2_state::fbvram_bankB_w) { COMBINE_DATA(&m_fbvramB[offset]); }
+
/* common map for all Model 2 versions */
ADDRESS_MAP_START(model2_state::model2_base_mem)
AM_RANGE(0x00000000, 0x001fffff) AM_ROM AM_WRITENOP
@@ -1460,9 +1468,9 @@ ADDRESS_MAP_START(model2_state::model2_base_mem)
// AM_RANGE(0x10a00000, 0x10bfffff) fill memory ping
// AM_RANGE(0x10c00000, 0x10dfffff) fill memory pong
- // format is xGGGGGBBBBBRRRRR (512x400)
- AM_RANGE(0x11600000, 0x1167ffff) AM_RAM AM_SHARE("fbvram1") // framebuffer A (last bronx title screen)
- AM_RANGE(0x11680000, 0x116fffff) AM_RAM AM_SHARE("fbvram2") // framebuffer B
+ // format is xGGGGGRRRRRBBBBB (512x400)
+ AM_RANGE(0x11600000, 0x1167ffff) AM_READWRITE16(fbvram_bankA_r,fbvram_bankA_w,0xffffffff) // framebuffer A (last bronx title screen)
+ AM_RANGE(0x11680000, 0x116fffff) AM_READWRITE16(fbvram_bankB_r,fbvram_bankB_w,0xffffffff) AM_SHARE("fbvram2") // framebuffer B
AM_RANGE(0x12800000, 0x1281ffff) AM_READWRITE16(lumaram_r,lumaram_w,0x0000ffff) // polygon "luma" RAM
ADDRESS_MAP_END
diff --git a/src/mame/includes/model2.h b/src/mame/includes/model2.h
index 8c5ce3aaffb..3c87a157537 100644
--- a/src/mame/includes/model2.h
+++ b/src/mame/includes/model2.h
@@ -28,8 +28,6 @@ public:
m_bufferram(*this, "bufferram"),
m_textureram0(*this, "textureram0"),
m_textureram1(*this, "textureram1"),
- m_fbvram1(*this, "fbvram1"),
- m_fbvram2(*this, "fbvram2"),
m_soundram(*this, "soundram"),
m_tgp_program(*this, "tgp_program"),
m_tgpx4_program(*this, "tgpx4_program"),
@@ -66,8 +64,8 @@ public:
required_shared_ptr<uint32_t> m_textureram0;
required_shared_ptr<uint32_t> m_textureram1;
std::unique_ptr<uint16_t[]> m_lumaram;
- required_shared_ptr<uint32_t> m_fbvram1;
- required_shared_ptr<uint32_t> m_fbvram2;
+ std::unique_ptr<uint16_t[]> m_fbvramA;
+ std::unique_ptr<uint16_t[]> m_fbvramB;
optional_shared_ptr<uint16_t> m_soundram;
optional_shared_ptr<uint32_t> m_tgp_program;
optional_shared_ptr<uint64_t> m_tgpx4_program;
@@ -181,6 +179,10 @@ public:
DECLARE_WRITE32_MEMBER(model2o_tex_w1);
DECLARE_READ16_MEMBER(lumaram_r);
DECLARE_WRITE16_MEMBER(lumaram_w);
+ DECLARE_READ16_MEMBER(fbvram_bankA_r);
+ DECLARE_WRITE16_MEMBER(fbvram_bankA_w);
+ DECLARE_READ16_MEMBER(fbvram_bankB_r);
+ DECLARE_WRITE16_MEMBER(fbvram_bankB_w);
DECLARE_WRITE32_MEMBER(model2_3d_zclip_w);
DECLARE_WRITE16_MEMBER(model2snd_ctrl);
DECLARE_READ32_MEMBER(copro_sharc_input_fifo_r);
@@ -236,9 +238,9 @@ public:
void model2_3d_frame_start( void );
void geo_parse( void );
-
void model2_3d_frame_end( bitmap_rgb32 &bitmap, const rectangle &cliprect );
-
+ void draw_framebuffer(bitmap_rgb32 &bitmap, const rectangle &cliprect );
+
void model2_timers(machine_config &config);
void model2_screen(machine_config &config);
void model2_scsp(machine_config &config);
@@ -283,6 +285,7 @@ private:
bool m_render_unk;
bool m_render_mode;
+ bool m_render_test_mode;
int16 m_crtc_xoffset, m_crtc_yoffset;
uint32_t *geo_process_command( geo_state *geo, uint32_t opcode, uint32_t *input, bool *end_code );
diff --git a/src/mame/video/model2.cpp b/src/mame/video/model2.cpp
index b48d1bec8d3..899f370e296 100644
--- a/src/mame/video/model2.cpp
+++ b/src/mame/video/model2.cpp
@@ -997,6 +997,32 @@ void model2_state::model2_3d_frame_end( bitmap_rgb32 &bitmap, const rectangle &c
copybitmap_trans(bitmap, m_poly->destmap(), 0, 0, 0, 0, cliprect, 0x00000000);
}
+// direct framebuffer drawing (enabled with render test mode, Last Bronx title screen)
+// pretty sure test mode cuts off DSP framebuffer drawing/clear, according to the manual description too
+void model2_state::draw_framebuffer( bitmap_rgb32 &bitmap, const rectangle &cliprect )
+{
+ uint16_t *fbvram = &(m_screen->frame_number() & 1 ? m_fbvramB[0] : m_fbvramA[0]);
+ // TODO: halved crtc values?
+ int xoffs = (-m_crtc_xoffset)/2;
+ int yoffs = m_crtc_yoffset/2;
+
+ for (int y = cliprect.min_y; y <= cliprect.max_y; ++y)
+ {
+ for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
+ {
+ int r,g,b;
+ int offset = (x + xoffs) + (y + yoffs)*512;
+ b = (fbvram[offset] >> 0) & 0x1f;
+ r = (fbvram[offset] >> 5) & 0x1f;
+ g = (fbvram[offset] >> 10) & 0x1f;
+ r = pal5bit(r);
+ g = pal5bit(g);
+ b = pal5bit(b);
+ bitmap.pix32(y, x) = r << 16 | g << 8 | b;
+ }
+ }
+}
+
/* 3D Rasterizer main data input port */
void model2_state::model2_3d_push( raster_state *raster, uint32_t input )
{
@@ -2606,7 +2632,9 @@ void model2_state::video_start()
m_palram = make_unique_clear<uint16_t[]>(0x4000/2);
m_colorxlat = make_unique_clear<uint16_t[]>(0xc000/2);
m_lumaram = make_unique_clear<uint16_t[]>(0x10000/2);
-
+ m_fbvramA = make_unique_clear<uint16_t[]>(0x80000/2);
+ m_fbvramB = make_unique_clear<uint16_t[]>(0x80000/2);
+
// convert (supposedly) 3d sRGB color space into linear
// TODO: might be slightly different algorithm (Daytona USA road/cars, VF2 character skins)
for(int i=0;i<256;i++)
@@ -2616,6 +2644,10 @@ void model2_state::video_start()
m_gamma_table[i] = (uint8_t)raw_value;
// printf("%02x: %02x %lf\n",i,m_gamma_table[i],raw_value);
}
+
+ save_item(NAME(m_render_test_mode));
+ save_item(NAME(m_render_unk));
+ save_item(NAME(m_render_mode));
}
uint32_t model2_state::screen_update_model2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@@ -2634,13 +2666,19 @@ uint32_t model2_state::screen_update_model2(screen_device &screen, bitmap_rgb32
copybitmap_trans(bitmap, m_sys24_bitmap, 0, 0, 0, 0, cliprect, 0);
/* tell the rasterizer we're starting a frame */
- model2_3d_frame_start();
+ if(m_render_test_mode == true)
+ draw_framebuffer( bitmap, cliprect );
+ else
+ {
+ model2_3d_frame_start();
- /* let the geometry engine do it's thing */ /* TODO: don't do it here! */
- geo_parse();
+ /* let the geometry engine do it's thing */
+ // TODO: move it from here
+ geo_parse();
- /* have the rasterizer output the frame */
- model2_3d_frame_end( bitmap, cliprect );
+ /* have the rasterizer output the frame */
+ model2_3d_frame_end( bitmap, cliprect );
+ }
m_sys24_bitmap.fill(0, cliprect);