From ce92a4bde01edf38e6912319b720a1f604766339 Mon Sep 17 00:00:00 2001 From: Ville Linde Date: Thu, 24 Jun 2021 04:47:49 +0300 Subject: k001604: Major rewrite and documentation update [Ville Linde] --- src/mame/drivers/cobra.cpp | 6 +- src/mame/drivers/gticlub.cpp | 22 +- src/mame/drivers/nwk-tr.cpp | 12 -- src/mame/drivers/zr107.cpp | 8 +- src/mame/video/k001005.cpp | 54 +++-- src/mame/video/k001604.cpp | 482 ++++++++++++++++++++++++------------------- src/mame/video/k001604.h | 35 +--- 7 files changed, 309 insertions(+), 310 deletions(-) diff --git a/src/mame/drivers/cobra.cpp b/src/mame/drivers/cobra.cpp index 541d27aeaf0..cc5694215d3 100644 --- a/src/mame/drivers/cobra.cpp +++ b/src/mame/drivers/cobra.cpp @@ -1132,7 +1132,7 @@ uint32_t cobra_state::screen_update_cobra(screen_device &screen, bitmap_rgb32 &b { if (m_has_psac) { - m_k001604->draw_back_layer(bitmap, cliprect); + m_k001604->draw_back_layer(screen, bitmap, cliprect); m_k001604->draw_front_layer(screen, bitmap, cliprect); } @@ -3314,10 +3314,6 @@ void cobra_state::cobra(machine_config &config) M48T58(config, "m48t58", 0); K001604(config, m_k001604, 0); // on the LAN board in Racing Jam DX - m_k001604->set_layer_size(0); - m_k001604->set_roz_size(1); - m_k001604->set_txt_mem_offset(0); // correct? - m_k001604->set_roz_mem_offset(0); // correct? m_k001604->set_palette(m_palette); COBRA_JVS_HOST(config, m_jvs_host, 4000000); diff --git a/src/mame/drivers/gticlub.cpp b/src/mame/drivers/gticlub.cpp index 2f48600b04c..83bc7908d0a 100644 --- a/src/mame/drivers/gticlub.cpp +++ b/src/mame/drivers/gticlub.cpp @@ -762,7 +762,7 @@ void gticlub_state::machine_reset() uint32_t gticlub_state::screen_update_gticlub(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - m_k001604[0]->draw_back_layer(bitmap, cliprect); + m_k001604[0]->draw_back_layer(screen, bitmap, cliprect); m_k001005->draw(bitmap, cliprect); @@ -870,17 +870,13 @@ void gticlub_state::gticlub(machine_config &config) // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); - screen.set_size(512, 384); - screen.set_visarea(0, 511, 0, 383); + screen.set_size(1024, 1024); + screen.set_visarea(40, 511+40, 28, 383+28); // needs CRTC emulation screen.set_screen_update(FUNC(gticlub_state::screen_update_gticlub)); PALETTE(config, m_palette).set_entries(65536); K001604(config, m_k001604[0], 0); - m_k001604[0]->set_layer_size(1); - m_k001604[0]->set_roz_size(1); - m_k001604[0]->set_txt_mem_offset(0); - m_k001604[0]->set_roz_mem_offset(0); m_k001604[0]->set_palette(m_palette); K001005(config, m_k001005, 0, m_k001006[0]); @@ -925,10 +921,6 @@ void gticlub_state::slrasslt(machine_config &config) gticlub(config); m_adc1038->set_gti_club_hack(false); - - m_k001604[0]->set_layer_size(0); - m_k001604[0]->set_roz_size(0); - m_k001604[0]->set_txt_mem_offset(16384); } void gticlub_state::hangplt(machine_config &config) @@ -992,17 +984,9 @@ void gticlub_state::hangplt(machine_config &config) rscreen.set_screen_update(FUNC(gticlub_state::screen_update_two_screens<1>)); K001604(config, m_k001604[0], 0); - m_k001604[0]->set_layer_size(0); - m_k001604[0]->set_roz_size(1); - m_k001604[0]->set_txt_mem_offset(0); - m_k001604[0]->set_roz_mem_offset(16384); m_k001604[0]->set_palette(m_palette); K001604(config, m_k001604[1], 0); - m_k001604[1]->set_layer_size(0); - m_k001604[1]->set_roz_size(1); - m_k001604[1]->set_txt_mem_offset(0); - m_k001604[1]->set_roz_mem_offset(16384); m_k001604[1]->set_palette(m_palette); K056800(config, m_k056800, XTAL(33'868'800)/2); diff --git a/src/mame/drivers/nwk-tr.cpp b/src/mame/drivers/nwk-tr.cpp index fead2fd0c0c..56d54d2c228 100644 --- a/src/mame/drivers/nwk-tr.cpp +++ b/src/mame/drivers/nwk-tr.cpp @@ -709,17 +709,9 @@ void nwktr_state::nwktr(machine_config &config) PALETTE(config, m_palette).set_entries(65536); K001604(config, m_k001604[0], 0); - m_k001604[0]->set_layer_size(0); - m_k001604[0]->set_roz_size(1); - m_k001604[0]->set_txt_mem_offset(0); // correct? - m_k001604[0]->set_roz_mem_offset(0); // correct? m_k001604[0]->set_palette(m_palette); K001604(config, m_k001604[1], 0); - m_k001604[1]->set_layer_size(0); - m_k001604[1]->set_roz_size(1); - m_k001604[1]->set_txt_mem_offset(0); // correct? - m_k001604[1]->set_roz_mem_offset(0); // correct? m_k001604[1]->set_palette(m_palette); SPEAKER(config, "lspeaker").front_left(); @@ -742,10 +734,6 @@ void nwktr_state::nwktr(machine_config &config) void nwktr_state::thrilld(machine_config &config) { nwktr(config); - - m_k001604[0]->set_layer_size(1); - - m_k001604[1]->set_layer_size(1); } /*****************************************************************************/ diff --git a/src/mame/drivers/zr107.cpp b/src/mame/drivers/zr107.cpp index 83841a6eee5..76034d0c8f6 100644 --- a/src/mame/drivers/zr107.cpp +++ b/src/mame/drivers/zr107.cpp @@ -307,7 +307,7 @@ uint32_t jetwave_state::screen_update(screen_device &screen, bitmap_rgb32 &bitma { bitmap.fill(m_palette->pen(0), cliprect); - m_k001604->draw_back_layer(bitmap, cliprect); + m_k001604->draw_back_layer(screen, bitmap, cliprect); m_k001005->draw(bitmap, cliprect); m_k001604->draw_front_layer(screen, bitmap, cliprect); @@ -811,13 +811,11 @@ void jetwave_state::jetwave(machine_config &config) config.set_maximum_quantum(attotime::from_hz(2000000)); // Very high sync needed to prevent lockups - why? // video hardware + m_screen->set_size(1024, 1024); + m_screen->set_visarea(40, 511 + 40, 27, 383 + 27); // needs CRTC emulation m_screen->set_screen_update(FUNC(jetwave_state::screen_update)); K001604(config, m_k001604, 0); - m_k001604->set_layer_size(0); - m_k001604->set_roz_size(0); - m_k001604->set_txt_mem_offset(0); - m_k001604->set_roz_mem_offset(0x4000); m_k001604->set_palette(m_palette); // The second K001006 chip connects to the second K001005 chip. diff --git a/src/mame/video/k001005.cpp b/src/mame/video/k001005.cpp index 4491546bcca..984b0abbee2 100644 --- a/src/mame/video/k001005.cpp +++ b/src/mame/video/k001005.cpp @@ -28,8 +28,8 @@ k001005_renderer::k001005_renderer(device_t &parent, screen_device &screen, devi { m_k001006 = k001006; - int width = screen.width(); - int height = screen.height(); + int width = 512; + int height = 384; m_fb[0] = std::make_unique( width, height); m_fb[1] = std::make_unique( width, height); @@ -40,7 +40,7 @@ k001005_renderer::k001005_renderer(device_t &parent, screen_device &screen, devi m_3dfifo_ptr = 0; m_fb_page = 0; - m_cliprect = screen.cliprect(); + m_cliprect = rectangle(0, width-1, 0, height-1); for (int k=0; k < 8; k++) { @@ -144,8 +144,6 @@ void k001005_renderer::render_polygons() uint32_t *fifo = m_3dfifo.get(); - const rectangle& visarea = screen().visible_area(); - int index = 0; float fog_density = 1.5f; @@ -331,8 +329,8 @@ void k001005_renderer::render_polygons() vertex4 = &v[3]; } - render_triangle(visarea, rd_scan_tex, 6, *vertex1, *vertex2, *vertex3); - render_triangle(visarea, rd_scan_tex, 6, *vertex3, *vertex4, *vertex1); + render_triangle(m_cliprect, rd_scan_tex, 6, *vertex1, *vertex2, *vertex3); + render_triangle(m_cliprect, rd_scan_tex, 6, *vertex3, *vertex4, *vertex1); memcpy(&m_prev_v[0], vertex1, sizeof(vertex_t)); memcpy(&m_prev_v[1], vertex2, sizeof(vertex_t)); @@ -419,7 +417,7 @@ void k001005_renderer::render_polygons() if (new_verts == 1) { - render_triangle(visarea, rd_scan_tex, 6, v[0], v[1], v[2]); + render_triangle(m_cliprect, rd_scan_tex, 6, v[0], v[1], v[2]); memcpy(&m_prev_v[1], &v[0], sizeof(vertex_t)); memcpy(&m_prev_v[2], &v[1], sizeof(vertex_t)); @@ -427,8 +425,8 @@ void k001005_renderer::render_polygons() } else if (new_verts == 2) { - render_triangle(visarea, rd_scan_tex, 6, v[0], v[1], v[2]); - render_triangle(visarea, rd_scan_tex, 6, v[2], v[3], v[0]); + render_triangle(m_cliprect, rd_scan_tex, 6, v[0], v[1], v[2]); + render_triangle(m_cliprect, rd_scan_tex, 6, v[2], v[3], v[0]); memcpy(&m_prev_v[0], &v[0], sizeof(vertex_t)); memcpy(&m_prev_v[1], &v[1], sizeof(vertex_t)); @@ -516,7 +514,7 @@ void k001005_renderer::render_polygons() vertex3 = &v[2]; } - render_triangle(visarea, rd_scan, 3, *vertex1, *vertex2, *vertex3); + render_triangle(m_cliprect, rd_scan, 3, *vertex1, *vertex2, *vertex3); memcpy(&m_prev_v[1], vertex1, sizeof(vertex_t)); memcpy(&m_prev_v[2], vertex2, sizeof(vertex_t)); @@ -553,8 +551,8 @@ void k001005_renderer::render_polygons() vertex4 = &v[3]; } - render_triangle(visarea, rd_scan, 3, *vertex1, *vertex2, *vertex3); - render_triangle(visarea, rd_scan, 3, *vertex3, *vertex4, *vertex1); + render_triangle(m_cliprect, rd_scan, 3, *vertex1, *vertex2, *vertex3); + render_triangle(m_cliprect, rd_scan, 3, *vertex3, *vertex4, *vertex1); memcpy(&m_prev_v[0], vertex1, sizeof(vertex_t)); memcpy(&m_prev_v[1], vertex2, sizeof(vertex_t)); @@ -623,7 +621,7 @@ void k001005_renderer::render_polygons() if (new_verts == 1) { - render_triangle(visarea, rd_scan, 3, v[0], v[1], v[2]); + render_triangle(m_cliprect, rd_scan, 3, v[0], v[1], v[2]); memcpy(&m_prev_v[1], &v[0], sizeof(vertex_t)); memcpy(&m_prev_v[2], &v[1], sizeof(vertex_t)); @@ -631,8 +629,8 @@ void k001005_renderer::render_polygons() } else if (new_verts == 2) { - render_triangle(visarea, rd_scan, 3, v[0], v[1], v[2]); - render_triangle(visarea, rd_scan, 3, v[2], v[3], v[0]); + render_triangle(m_cliprect, rd_scan, 3, v[0], v[1], v[2]); + render_triangle(m_cliprect, rd_scan, 3, v[2], v[3], v[0]); memcpy(&m_prev_v[0], &v[0], sizeof(vertex_t)); memcpy(&m_prev_v[1], &v[1], sizeof(vertex_t)); @@ -685,12 +683,12 @@ void k001005_renderer::render_polygons() if (poly_type == 0) { - render_triangle(visarea, rd_scan_2d, 0, v[0], v[1], v[2]); + render_triangle(m_cliprect, rd_scan_2d, 0, v[0], v[1], v[2]); } else { - render_triangle(visarea, rd_scan_2d, 0, v[0], v[1], v[2]); - render_triangle(visarea, rd_scan_2d, 0, v[2], v[3], v[0]); + render_triangle(m_cliprect, rd_scan_2d, 0, v[0], v[1], v[2]); + render_triangle(m_cliprect, rd_scan_2d, 0, v[2], v[3], v[0]); } } else if (cmd == 0x8000008b) @@ -774,12 +772,12 @@ void k001005_renderer::render_polygons() if (poly_type == 0) { - render_triangle(visarea, rd_scan_tex2d, 5, v[0], v[1], v[2]); + render_triangle(m_cliprect, rd_scan_tex2d, 5, v[0], v[1], v[2]); } else { - render_triangle(visarea, rd_scan_tex2d, 5, v[0], v[1], v[2]); - render_triangle(visarea, rd_scan_tex2d, 5, v[2], v[3], v[0]); + render_triangle(m_cliprect, rd_scan_tex2d, 5, v[0], v[1], v[2]); + render_triangle(m_cliprect, rd_scan_tex2d, 5, v[2], v[3], v[0]); } } else if (cmd == 0x80000106 || cmd == 0x80000121 || cmd == 0x80000126) @@ -827,12 +825,12 @@ void k001005_renderer::render_polygons() if (poly_type == 0) { - render_triangle(visarea, rd_scan_gour_blend, 6, v[0], v[1], v[2]); + render_triangle(m_cliprect, rd_scan_gour_blend, 6, v[0], v[1], v[2]); } else { - render_triangle(visarea, rd_scan_gour_blend, 6, v[0], v[1], v[2]); - render_triangle(visarea, rd_scan_gour_blend, 6, v[2], v[3], v[0]); + render_triangle(m_cliprect, rd_scan_gour_blend, 6, v[0], v[1], v[2]); + render_triangle(m_cliprect, rd_scan_gour_blend, 6, v[2], v[3], v[0]); } // TODO: can this poly type form strips? @@ -1163,13 +1161,13 @@ void k001005_renderer::draw(bitmap_rgb32 &bitmap, const rectangle &cliprect) for (int j = cliprect.min_y; j <= cliprect.max_y; j++) { uint32_t *const bmp = &bitmap.pix(j); - uint32_t const *const src = &m_fb[m_fb_page^1]->pix(j); + uint32_t const *const src = &m_fb[m_fb_page^1]->pix(j-cliprect.min_y); for (int i = cliprect.min_x; i <= cliprect.max_x; i++) { - if (src[i] & 0xff000000) + if (src[i-cliprect.min_x] & 0xff000000) { - bmp[i] = src[i]; + bmp[i] = src[i-cliprect.min_x]; } } } diff --git a/src/mame/video/k001604.cpp b/src/mame/video/k001604.cpp index bb00c46e75c..6dd1f98ff8b 100644 --- a/src/mame/video/k001604.cpp +++ b/src/mame/video/k001604.cpp @@ -3,6 +3,7 @@ #include "emu.h" #include "k001604.h" +#include "screen.h" /***************************************************************************/ @@ -11,6 +12,140 @@ /* */ /***************************************************************************/ +/* + Character RAM: + * Foreground tiles 2x 1Mbit SRAM in a 16-bit bus (256KB = 4096 8x8 tiles or 1024 16x16 tiles). + * Background tiles 4x 1Mbit SRAM in a 16-bit bus (512KB = 8192 8x8 tiles or 2048 16x16 tiles). Empty solder pads on NWK-TR. + + Tile RAM: + * 3x 256Kbit SRAMs in a 24-bit bus + * Each tile entry is 24 bits, 32768 total + + CLUT RAM: + * 2x 256KBit SRAMs on NWK-TR in a 16-bit bus (32768 colors) + * 2x 64Kbit SRAMs on "GTI Club" in a 16-bit bus (8192 colors) + + Background and foreground layer with ROZ capabilities + Both tilemaps are 128x128 tiles, with ability to use smaller sub-tilemaps + Foreground seems to use 8x8 tiles only, background can select 8x8 or 16x16 tiles + + Registers: + + Offset Bits + 00 sxxxxxxxxxxxxxxx ---------------- Foreground X start (13.3 fixed point) + ---------------- sxxxxxxxxxxxxxxx Foreground Y start (13.3 fixed point) + 04 sxxxxxxxxxxxxxxx ---------------- Foreground ROZ XY (5.11 fixed point) Tilemap Y-increment per screen pixel increment + ---------------- sxxxxxxxxxxxxxxx Foreground ROZ YY (5.11 fixed point) Tilemap Y-increment per screen line increment + 08 sxxxxxxxxxxxxxxx ---------------- Foreground ROZ XX (5.11 fixed point) Tilemap X-increment per screen pixel increment + ---------------- sxxxxxxxxxxxxxxx Foreground ROZ YX (5.11 fixed point) Tilemap X-increment per screen line increment + 0c ???????????????? ---------------- + ---------------- ???????????????? + 20 sxxxxxxxxxxxxxxx ---------------- Background X start (13.3 fixed point) + ---------------- sxxxxxxxxxxxxxxx Background Y start (13.3 fixed point) + 24 sxxxxxxxxxxxxxxx ---------------- Background ROZ XX (5.11 fixed point) + ---------------- sxxxxxxxxxxxxxxx Background ROZ YX (5.11 fixed point) + 28 sxxxxxxxxxxxxxxx ---------------- Background ROZ YY (5.11 fixed point) + ---------------- sxxxxxxxxxxxxxxx Background ROZ XY (5.11 fixed point) + 2c ???????????????? ---------------- + ---------------- ???????????????? + 40 xxxxxxxxxxxxxxxx ---------------- + ---------------- xxxxxxxxxxxxxxxx + 44 xxxxxxxxxxxxxxxx ---------------- + ---------------- xxxxxxxxxxxxxxxx + 48 xxxxxxxxxxxxxxxx ---------------- + ---------------- xxxxxxxxxxxxxxxx + 50 xxxxxxxxxxxxxxxx ---------------- + ---------------- xxxxxxxxxxxxxxxx + 54 xxxxxxxxxxxxxxxx ---------------- + ---------------- xxxxxxxxxxxxxxxx + 60 x--------------- ---------------- FG tilemap enable? + -x-------------- ---------------- BG tilemap enable? + -------x-------- ---------------- Select FG/BG tiles for character RAM read/write access + -------0-------- ---------------- FG character RAM + -------1-------- ---------------- BG character RAM + ---------x------ ---------------- BG tile size + ---------0------ ---------------- 16x16 + ---------1------ ---------------- 8x8 + ---------------- --------------xx Character bank for FG tiles + ---------------- ------xx-------- Character bank for BG tiles + ------------xx-- ---------------- Tilemap layout (both bits either set or unset) + ------------00-- ---------------- "landscape", 256 tiles wide + ------------11-- ---------------- "portrait", 128 tiles wide + 6c -x-------------- ---------------- Swap FG/BG tilemap location in portrait mode? (used by Solar Assault) Might also swap left/right in landscape mode but nothing uses this. + -0-------------- ---------------- FG Tilemap at 0x0000, BG at 0x4000 + -1-------------- ---------------- FG Tilemap at 0x4000, BG at 0x0000 + --------x------- ---------------- ? + ---------xx----- ---------------- FG sub tilemap width? + ------------x--- ---------------- ? + -------------xx- ---------------- FG sub tilemap height? + ---------------- ----x----------- Enable BG sub tilemap? + ---------------- -----xx--------- BG sub tilemap width? + ---------------- -----00--------- 128 tiles + ---------------- -----10--------- 64 tiles + ---------------- -----11--------- 32 tiles + ---------------- --------x------- ? + ---------------- ---------xx----- BG sub tilemap height? + ---------------- ---------00----- 128 tiles + ---------------- ---------10----- 64 tiles + ---------------- ---------11----- 32 tiles + ---------------- ------------x--- ? + ---------------- -------------xx- BG sub tilemap X (in units of 32 tiles) + + + Tilemap layout: + "landscape" mode: + + 0 128 256 + 0x0000 +----------------+----------------+ + | | | + | | | + | Foreground | Background | + | 128x128 tiles | 128x128 tiles | + | | | + | | | + 0x8000 +----------------+----------------+ + + "portrait" mode: + + 0 128 + 0x0000 +----------------+ + | | + | | + | Foreground | + | 128x128 tiles | + | | + | | + 0x4000 +----------------+ + | | + | | + | Background | + | 128x128 tiles | + | | + | | + +----------------+ + + Tilemap sub-split: + Tilemap can be split in X and Y direction into 32/64/128 x 32/64/128 sub-tilemaps + Sub-tilemap selection works in units of 32 tiles + + 0 32 64 96 128 + +-----+-----+-----+-----+ + | | | | | + | 0,0 | 1,0 | 2,0 | 3,0 | + 32 +-----+-----+-----+-----+ + | | | | | + | 0,1 | 1,1 | 2,1 | 3,1 | + 64 +-----+-----+-----+-----+ + | | | | | + | 0,2 | 1,2 | 2,2 | 3,2 | + 96 +-----+-----+-----+-----+ + | | | | | + | 0,3 | 1,3 | 2,3 | 3,3 | + 128 +-----+-----+-----+-----+ + + + +*/ #define K001604_NUM_TILES_LAYER0 16384 #define K001604_NUM_TILES_LAYER1 4096 @@ -20,11 +155,6 @@ DEFINE_DEVICE_TYPE(K001604, k001604_device, "k001604_device", "K001604 2D tilema k001604_device::k001604_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, K001604, tag, owner, clock), device_gfx_interface(mconfig, *this, nullptr), - m_layer_size(0), - m_roz_size(0), - m_txt_mem_offset(0), - m_roz_mem_offset(0), - m_layer_roz(nullptr), m_tile_ram(nullptr), m_char_ram(nullptr), m_reg(nullptr) @@ -62,32 +192,19 @@ void k001604_device::device_start() 16*256 }; - int roz_tile_size; - m_char_ram = make_unique_clear(0x200000 / 4); m_tile_ram = make_unique_clear(0x20000 / 4); m_reg = make_unique_clear(0x400 / 4); /* create tilemaps */ - roz_tile_size = m_roz_size ? 16 : 8; - - if (m_layer_size) - { - m_layer_8x8[0] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_8x8)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_8x8_0_size1)), 8, 8, 64, 64); - m_layer_8x8[1] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_8x8)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_8x8_1_size1)), 8, 8, 64, 64); - - m_layer_roz = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_roz)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_roz_256)), roz_tile_size, roz_tile_size, 128, 64); - } - else - { - m_layer_8x8[0] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_8x8)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_8x8_0_size0)), 8, 8, 64, 64); - m_layer_8x8[1] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_8x8)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_8x8_1_size0)), 8, 8, 64, 64); + m_fg_tilemap = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_fg)), TILEMAP_SCAN_ROWS, 8, 8, 128, 128); + m_fg_tilemap->set_transparent_pen(0); - m_layer_roz = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_roz)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_roz_128)), roz_tile_size, roz_tile_size, 128, 64); - } + m_bg_tilemap8 = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_bg8)), TILEMAP_SCAN_ROWS, 8, 8, 128, 128); + m_bg_tilemap8->set_transparent_pen(0); - m_layer_8x8[0]->set_transparent_pen(0); - m_layer_8x8[1]->set_transparent_pen(0); + m_bg_tilemap16 = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_bg16)), TILEMAP_SCAN_ROWS, 16, 16, 128, 128); + m_bg_tilemap16->set_transparent_pen(0); set_gfx(0, std::make_unique(&palette(), k001604_char_layout_layer_8x8, (uint8_t*)&m_char_ram[0], 0, palette().entries() / 16, 0)); set_gfx(1, std::make_unique(&palette(), k001604_char_layout_layer_16x16, (uint8_t*)&m_char_ram[0], 0, palette().entries() / 16, 0)); @@ -113,50 +230,35 @@ void k001604_device::device_reset() DEVICE HANDLERS *****************************************************************************/ -/* FIXME: The TILEMAP_MAPPER below depends on parameters passed by the device interface (being game dependent). -we might simplify the code, by passing the whole TILEMAP_MAPPER as a callback in the interface, but is it really worth? */ - -TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_8x8_0_size0) -{ - /* logical (col,row) -> memory offset */ - return (row * 128) + col + m_txt_mem_offset; -} - -TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_8x8_0_size1) +TILE_GET_INFO_MEMBER(k001604_device::tile_info_fg) { - /* logical (col,row) -> memory offset */ - return (row * 256) + col + m_txt_mem_offset; -} - -TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_8x8_1_size0) -{ - /* logical (col,row) -> memory offset */ - return (row * 128) + col + 64 + m_txt_mem_offset; -} - -TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_8x8_1_size1) -{ - /* logical (col,row) -> memory offset */ - return (row * 256) + col + 64 + m_txt_mem_offset; -} + uint32_t tilebase = (m_reg[0x18] & 0x40000) ? ((m_reg[0x1b] & 0x40000000) ? 0x4000 : 0x0000) : 0x0000; + uint32_t x = tile_index & 0x7f; + uint32_t y = tile_index / 128; + uint32_t tilemap_pitch = (m_reg[0x18] & 0x40000) ? 128 : 256; + uint32_t val = m_tile_ram[(y * tilemap_pitch) + x + tilebase]; + int color = (val >> 17) & 0x1f; + int tile = val & 0x3fff; + int flags = 0; -TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_roz_128) -{ - /* logical (col,row) -> memory offset */ - return (row * 128) + col + m_roz_mem_offset; -} + if (val & 0x400000) + flags |= TILE_FLIPX; + if (val & 0x800000) + flags |= TILE_FLIPY; -TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_roz_256) -{ - /* logical (col,row) -> memory offset */ - return (row * 256) + col + 128 + m_roz_mem_offset; + tileinfo.set(0, tile, color, flags); } -TILE_GET_INFO_MEMBER(k001604_device::tile_info_layer_8x8) +TILE_GET_INFO_MEMBER(k001604_device::tile_info_bg8) { - uint32_t val = m_tile_ram[tile_index]; + uint32_t tilebase = (m_reg[0x18] & 0x40000) ? ((m_reg[0x1b] & 0x40000000) ? 0x0000 : 0x4000) : 0x0000; + uint32_t x = tile_index & 0x7f; + uint32_t y = tile_index / 128; + uint32_t tilemap_pitch = (m_reg[0x18] & 0x40000) ? 128 : 256; + uint32_t tilemap_xstart = (m_reg[0x18] & 0x40000) ? 0 : 128; + uint32_t val = m_tile_ram[(y * tilemap_pitch) + x + tilemap_xstart + tilebase]; int color = (val >> 17) & 0x1f; - int tile = (val & 0x7fff); + int tile = 0x2000 + (val & 0x1fff); int flags = 0; if (val & 0x400000) @@ -167,51 +269,56 @@ TILE_GET_INFO_MEMBER(k001604_device::tile_info_layer_8x8) tileinfo.set(0, tile, color, flags); } -TILE_GET_INFO_MEMBER(k001604_device::tile_info_layer_roz) -{ - uint32_t val = m_tile_ram[tile_index]; - int flags = 0; +TILE_GET_INFO_MEMBER(k001604_device::tile_info_bg16) +{ + uint32_t tilebase = (m_reg[0x18] & 0x40000) ? ((m_reg[0x1b] & 0x40000000) ? 0x0000 : 0x4000) : 0x0000; + uint32_t x = tile_index & 0x7f; + uint32_t y = tile_index / 128; + uint32_t tilemap_pitch = (m_reg[0x18] & 0x40000) ? 128 : 256; + uint32_t tilemap_xstart = (m_reg[0x18] & 0x40000) ? 0 : 128; + uint32_t val = m_tile_ram[(y * tilemap_pitch) + x + tilemap_xstart + tilebase]; int color = (val >> 17) & 0x1f; - int tile = m_roz_size ? (val & 0x7ff) : (val & 0x1fff); + int tile = 0x800 + (val & 0x7ff); + int flags = 0; if (val & 0x400000) flags |= TILE_FLIPX; if (val & 0x800000) flags |= TILE_FLIPY; - tile += m_roz_size ? 0x800 : 0x2000; - - tileinfo.set(m_roz_size, tile, color, flags); + tileinfo.set(1, tile, color, flags); } -void k001604_device::draw_back_layer( bitmap_rgb32 &bitmap, const rectangle &cliprect ) -{ - bitmap.fill(0, cliprect); - - if ((m_reg[0x60 / 4] & 0x40000000) == 0) - return; - - int tile_size = m_roz_size ? 16 : 8; - int32_t x = (int16_t)((m_reg[0x08] >> 16) & 0xffff); - int32_t y = (int16_t)((m_reg[0x08] >> 0) & 0xffff); - int32_t xx = (int16_t)((m_reg[0x09] >> 0) & 0xffff); - int32_t xy = (int16_t)((m_reg[0x09] >> 16) & 0xffff); - int32_t yx = (int16_t)((m_reg[0x0a] >> 0) & 0xffff); - int32_t yy = (int16_t)((m_reg[0x0a] >> 16) & 0xffff); +void k001604_device::draw_tilemap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, bool front, tilemap_t* tilemap) +{ + const rectangle& visarea = screen.visible_area(); + static const int SUBTILEMAP_DIMENSION[4] = { 128, 128, 64, 32 }; // entry 1 seems unused - int pivotx = (int16_t)((m_reg[0x00] >> 16) & 0xffff); - int pivoty = (int16_t)((m_reg[0x00] >> 0) & 0xffff); + int32_t startx, starty, incxx, incyx, incxy, incyy; - int startx = ((x - pivotx) * 256) * 32; - int starty = ((y - pivoty) * 256) * 32; - int incxx = (xx) * 32; - int incxy = (-xy) * 32; - int incyx = (-yx) * 32; - int incyy = (yy) * 32; + if (front) + { + startx = (int32_t)((int16_t)(m_reg[0x00] >> 16)) << 13; + starty = (int32_t)((int16_t)(m_reg[0x00])) << 13; + incyy = (int32_t)((int16_t)(m_reg[0x01])) << 5; + incxy = (int32_t)((int16_t)(m_reg[0x01] >> 16)) << 5; + incyx = (int32_t)((int16_t)(m_reg[0x02])) << 5; + incxx= (int32_t)((int16_t)(m_reg[0x02] >> 16)) << 5; + } + else + { + startx = (int32_t)((int16_t)(m_reg[0x08] >> 16)) << 13; + starty = (int32_t)((int16_t)(m_reg[0x08])) << 13; + incxx = (int32_t)((int16_t)(m_reg[0x09])) << 5; + incyx = (int32_t)((int16_t)(m_reg[0x09] >> 16)) << 5; + incxy = (int32_t)((int16_t)(m_reg[0x0a])) << 5; + incyy = (int32_t)((int16_t)(m_reg[0x0a] >> 16)) << 5; + } - bitmap_ind16& pixmap = m_layer_roz->pixmap(); + bitmap_ind16& pixmap = tilemap->pixmap(); + const rgb_t* clut = palette().palette()->entry_list_raw(); // extract start/end points int sx = cliprect.min_x; @@ -219,30 +326,36 @@ void k001604_device::draw_back_layer( bitmap_rgb32 &bitmap, const rectangle &cli int ex = cliprect.max_x; int ey = cliprect.max_y; - const rgb_t *clut = palette().palette()->entry_list_raw(); - - int window_x, window_y, window_xmask, window_ymask; - - int layer_size = (m_reg[0x1b] >> 9) & 3; - - if (m_roz_size) - window_x = ((m_reg[0x1b] >> 1) & 3) * 512; - else - window_x = ((m_reg[0x1b] >> 1) & 1) * 512; - - window_y = 0; - - switch (layer_size) + uint32_t sub_x, sub_y, sub_xmask, sub_ymask; + if (front) { - case 0: window_xmask = (128 * tile_size) - 1; break; - case 2: window_xmask = (64 * tile_size) - 1; break; - case 3: window_xmask = (32 * tile_size) - 1; break; - default: fatalerror("k001604_draw_back_layer(): layer_size %d\n", layer_size); + sub_xmask = (128 * 8) - 1; + sub_ymask = (128 * 8) - 1; + sub_x = 0; + sub_y = 0; } + else + { + int tile_size = (m_reg[0x18] & 0x400000) ? 8 : 16; - window_ymask = pixmap.height() - 1; - + if (m_reg[0x1b] & 0x800) + { + sub_xmask = (SUBTILEMAP_DIMENSION[(m_reg[0x1b] >> 9) & 0x3] * tile_size) - 1; + sub_ymask = (SUBTILEMAP_DIMENSION[(m_reg[0x1b] >> 5) & 0x3] * tile_size) - 1; + sub_x = (((m_reg[0x1b] >> 1) & 0x3) * 32)* tile_size; + sub_y = 0 * tile_size; + } + else + { + sub_xmask = (128 * tile_size) - 1; + sub_ymask = (128 * tile_size) - 1; + sub_x = 0; + sub_y = 0; + } + } + // draw the tilemap + // // loop over rows while (sy <= ey) { @@ -251,12 +364,16 @@ void k001604_device::draw_back_layer( bitmap_rgb32 &bitmap, const rectangle &cli uint32_t cx = startx; uint32_t cy = starty; - uint32_t *dest = &bitmap.pix(sy, sx); + uint32_t* dest = &bitmap.pix(sy, sx); // loop over columns while (x <= ex) { - *dest = clut[pixmap.pix(((cy >> 16) & window_ymask) + window_y, ((cx >> 16) & window_xmask) + window_x)]; + uint16_t pen = pixmap.pix((((cy >> 16) + visarea.min_y) & sub_ymask) + sub_y, (((cx >> 16) + visarea.min_x) & sub_xmask) + sub_x); + if ((pen & 0xff) != 0 || !front) + { + *dest = clut[pen]; + } // advance in X cx += incxx; @@ -272,74 +389,24 @@ void k001604_device::draw_back_layer( bitmap_rgb32 &bitmap, const rectangle &cli } } -void k001604_device::draw_front_layer( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect ) -{ - int32_t x = (int16_t)((m_reg[0x00] >> 16) & 0xffff); - int32_t y = (int16_t)((m_reg[0x00] >> 0) & 0xffff); - int32_t yy = (int16_t)((m_reg[0x01] >> 0) & 0xffff); - int32_t xy = (int16_t)((m_reg[0x01] >> 16) & 0xffff); - int32_t yx = (int16_t)((m_reg[0x02] >> 0) & 0xffff); - int32_t xx = (int16_t)((m_reg[0x02] >> 16) & 0xffff); - - int pivotx = (int16_t)(0xfec0); - int pivoty = (int16_t)(0xff28); - - int startx = ((x - pivotx) * 256) * 32; - int starty = ((y - pivoty) * 256) * 32; - int incxx = (xx) * 32; - int incxy = (-xy) * 32; - int incyx = (-yx) * 32; - int incyy = (yy) * 32; - - bitmap_ind16& pixmap = m_layer_8x8[0]->pixmap(); - - // extract start/end points - int sx = cliprect.min_x; - int sy = cliprect.min_y; - int ex = cliprect.max_x; - int ey = cliprect.max_y; - - const rgb_t *clut = palette().palette()->entry_list_raw(); - - int window_x, window_y, window_xmask, window_ymask; - window_x = 0; - window_y = 0; - window_xmask = pixmap.width() - 1; - window_ymask = pixmap.height() - 1; +void k001604_device::draw_back_layer(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect ) +{ + bitmap.fill(0, cliprect); - // loop over rows - while (sy <= ey) - { - // initialize X counters - int x = sx; - uint32_t cx = startx; - uint32_t cy = starty; - - uint32_t *dest = &bitmap.pix(sy, sx); + if ((m_reg[0x60 / 4] & 0x40000000) == 0) + return; - // loop over columns - while (x <= ex) - { - uint16_t pix = pixmap.pix(((cy >> 16) & window_ymask) + window_y, ((cx >> 16) & window_xmask) + window_x); - if ((pix & 0xff) != 0) - { - *dest = clut[pix]; - } + draw_tilemap(screen, bitmap, cliprect, false, (m_reg[0x18] & 0x400000) ? m_bg_tilemap8 : m_bg_tilemap16); +} - // advance in X - cx += incxx; - cy += incxy; - x++; - dest++; - } +void k001604_device::draw_front_layer( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect ) +{ + if ((m_reg[0x60 / 4] & 0x80000000) == 0) + return; - // advance in Y - startx += incyx; - starty += incyy; - sy++; - } + draw_tilemap(screen, bitmap, cliprect, true, m_fg_tilemap); } uint32_t k001604_device::tile_r(offs_t offset) @@ -377,47 +444,42 @@ uint32_t k001604_device::reg_r(offs_t offset) void k001604_device::tile_w(offs_t offset, uint32_t data, uint32_t mem_mask) { - int x/*, y*/; COMBINE_DATA(m_tile_ram.get() + offset); - if (m_layer_size) - { - x = offset & 0xff; - /*y = offset / 256;*/ - } - else + if (m_reg[0x18] & 0x40000) { - x = offset & 0x7f; - /*y = offset / 128;*/ - } - - if (m_layer_size) - { - if (x < 64) - { - m_layer_8x8[0]->mark_tile_dirty(offset); + // portrait + uint32_t fg_tilebase = (m_reg[0x1b] & 0x40000000) ? 0x4000 : 0x0000; + uint32_t bg_tilebase = (m_reg[0x1b] & 0x40000000) ? 0x0000 : 0x4000; + + if (offset >= fg_tilebase && offset < fg_tilebase + 0x4000) + { + m_fg_tilemap->mark_tile_dirty(offset - fg_tilebase); } - else if (x < 128) + if (offset >= bg_tilebase && offset < bg_tilebase + 0x4000) { - m_layer_8x8[1]->mark_tile_dirty(offset); - } - else - { - m_layer_roz->mark_tile_dirty(offset); + if (m_reg[0x18] & 0x400000) + m_bg_tilemap8->mark_tile_dirty(offset - bg_tilebase); + else + m_bg_tilemap16->mark_tile_dirty(offset - bg_tilebase); } } else { - if (x < 64) + // landscape + uint32_t x = offset & 0xff; + uint32_t y = offset / 256; + if (x < 128) { - m_layer_8x8[0]->mark_tile_dirty(offset); + m_fg_tilemap->mark_tile_dirty((y * 128) + x); } else { - m_layer_8x8[1]->mark_tile_dirty(offset); + if (m_reg[0x18] & 0x400000) + m_bg_tilemap8->mark_tile_dirty((y * 128) + (x - 128)); + else + m_bg_tilemap16->mark_tile_dirty((y * 128) + (x - 128)); } - - m_layer_roz->mark_tile_dirty(offset); } } @@ -444,18 +506,4 @@ void k001604_device::char_w(offs_t offset, uint32_t data, uint32_t mem_mask) void k001604_device::reg_w(offs_t offset, uint32_t data, uint32_t mem_mask) { COMBINE_DATA(m_reg.get() + offset); - - switch (offset) - { - case 0x8: - case 0x9: - case 0xa: - //printf("K001604_reg_w %02X, %08X, %08X\n", offset, data, mem_mask); - break; - } - - if (offset != 0x08 && offset != 0x09 && offset != 0x0a /*&& offset != 0x17 && offset != 0x18*/) - { - //printf("K001604_reg_w (%d), %02X, %08X, %08X at %s\n", chip, offset, data, mem_mask, m_maincpu->pc()); - } } diff --git a/src/mame/video/k001604.h b/src/mame/video/k001604.h index 744ff33816e..8c87d571dd5 100644 --- a/src/mame/video/k001604.h +++ b/src/mame/video/k001604.h @@ -13,14 +13,10 @@ class k001604_device : public device_t, public device_gfx_interface public: k001604_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // configuration - void set_layer_size(int size) { m_layer_size = size; } - void set_roz_size(int size) { m_roz_size = size; } - void set_txt_mem_offset(int offs) { m_txt_mem_offset = offs; } - void set_roz_mem_offset(int offs) { m_roz_mem_offset = offs; } - - void draw_back_layer( bitmap_rgb32 &bitmap, const rectangle &cliprect ); - void draw_front_layer( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect ); + void draw_tilemap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, bool front, tilemap_t* tilemap); + + void draw_back_layer(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + void draw_front_layer(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void tile_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); uint32_t tile_r(offs_t offset); void char_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); @@ -33,27 +29,18 @@ protected: virtual void device_start() override; virtual void device_reset() override; private: - // internal state - int m_layer_size; // 0 -> width = 128 tiles, 1 -> width = 256 tiles - int m_roz_size; // 0 -> 8x8, 1 -> 16x16 - int m_txt_mem_offset; - int m_roz_mem_offset; - - tilemap_t *m_layer_8x8[2]; - tilemap_t *m_layer_roz; + // internal state + tilemap_t* m_fg_tilemap; + tilemap_t* m_bg_tilemap8; + tilemap_t* m_bg_tilemap16; std::unique_ptr m_tile_ram; std::unique_ptr m_char_ram; std::unique_ptr m_reg; - TILEMAP_MAPPER_MEMBER(scan_layer_8x8_0_size0); - TILEMAP_MAPPER_MEMBER(scan_layer_8x8_0_size1); - TILEMAP_MAPPER_MEMBER(scan_layer_8x8_1_size0); - TILEMAP_MAPPER_MEMBER(scan_layer_8x8_1_size1); - TILEMAP_MAPPER_MEMBER(scan_layer_roz_256); - TILEMAP_MAPPER_MEMBER(scan_layer_roz_128); - TILE_GET_INFO_MEMBER(tile_info_layer_8x8); - TILE_GET_INFO_MEMBER(tile_info_layer_roz); + TILE_GET_INFO_MEMBER(tile_info_fg); + TILE_GET_INFO_MEMBER(tile_info_bg8); + TILE_GET_INFO_MEMBER(tile_info_bg16); }; DECLARE_DEVICE_TYPE(K001604, k001604_device) -- cgit v1.2.3