diff options
author | 2025-04-09 06:37:45 +0900 | |
---|---|---|
committer | 2025-04-09 07:37:45 +1000 | |
commit | 69b45ce25c98063df99c8b4f8f4ef4c5fb7e0b50 (patch) | |
tree | a1ff050a7583321f08add7d9b6b2fb6da302a037 | |
parent | 7214b1d7485050a6bb227cc7a7d2d4a6548bda6b (diff) |
stern/mazerbla.cpp, video/mb_vcu.cpp: Updates/Cleanups: (#13569)
* video/mb_vcu.cpp:
- Implement device_palette_interface for palette functionality.
- Use an address space finder to access the host address space.
- Use logmacro.h helpers for configurable logging.
- Added a VRAM addressing helper.
- Suppress side effects for debugger reads.
- Cleanup 2bpp graphics drawing and screen update function.
* stern/mazerbla.cpp:
- Reduced run-time tag lookups and preprocessor macros.
- Reduced duplication and unnecessary trampolines.
- Updated comments.
-rw-r--r-- | src/devices/video/mb_vcu.cpp | 483 | ||||
-rw-r--r-- | src/devices/video/mb_vcu.h | 35 | ||||
-rw-r--r-- | src/mame/stern/mazerbla.cpp | 142 |
3 files changed, 293 insertions, 367 deletions
diff --git a/src/devices/video/mb_vcu.cpp b/src/devices/video/mb_vcu.cpp index de84566fc64..486fe03e044 100644 --- a/src/devices/video/mb_vcu.cpp +++ b/src/devices/video/mb_vcu.cpp @@ -28,6 +28,19 @@ TODO: #include "video/resnet.h" +#define LOG_PARAMS (1 << 1) +#define LOG_DRAW (1 << 2) +#define LOG_CLEAR (1 << 3) + +#define LOG_ALL (LOG_PARAMS | LOG_DRAW | LOG_CLEAR) + +#define VERBOSE (0) + +#include "logmacro.h" + +#define LOGPARAMS(...) LOGMASKED(LOG_PARAMS, __VA_ARGS__) +#define LOGDRAW(...) LOGMASKED(LOG_DRAW, __VA_ARGS__) +#define LOGCLEAR(...) LOGMASKED(LOG_CLEAR, __VA_ARGS__) //************************************************************************** // GLOBAL VARIABLES @@ -37,53 +50,33 @@ TODO: DEFINE_DEVICE_TYPE(MB_VCU, mb_vcu_device, "mb_vcu", "Mazer Blazer custom VCU") -void mb_vcu_device::mb_vcu_vram(address_map &map) +void mb_vcu_device::vram(address_map &map) { if (!has_configured_map(0)) map(0x00000, 0x7ffff).ram(); // enough for a 256x256x4 x 2 pages of framebuffer with 4 layers (TODO: doubled for simplicity) } -void mb_vcu_device::mb_vcu_pal_ram(address_map &map) +void mb_vcu_device::pal_ram(address_map &map) { if (!has_configured_map(1)) { map(0x0000, 0x00ff).ram(); map(0x0200, 0x02ff).ram(); map(0x0400, 0x04ff).ram(); - map(0x0600, 0x06ff).rw(FUNC(mb_vcu_device::mb_vcu_paletteram_r), FUNC(mb_vcu_device::mb_vcu_paletteram_w)); + map(0x0600, 0x06ff).rw(FUNC(mb_vcu_device::paletteram_r), FUNC(mb_vcu_device::paletteram_w)); } } -uint8_t mb_vcu_device::mb_vcu_paletteram_r(offs_t offset) +uint8_t mb_vcu_device::paletteram_r(offs_t offset) { return m_palram[offset]; } -void mb_vcu_device::mb_vcu_paletteram_w(offs_t offset, uint8_t data) +void mb_vcu_device::paletteram_w(offs_t offset, uint8_t data) { - int r,g,b, bit0, bit1, bit2; - m_palram[offset] = data; - - /* red component */ - bit1 = (m_palram[offset] >> 7) & 0x01; - bit0 = (m_palram[offset] >> 6) & 0x01; - r = combine_weights(m_weights_r, bit0, bit1); - - /* green component */ - bit2 = (m_palram[offset] >> 5) & 0x01; - bit1 = (m_palram[offset] >> 4) & 0x01; - bit0 = (m_palram[offset] >> 3) & 0x01; - g = combine_weights(m_weights_g, bit0, bit1, bit2); - - /* blue component */ - bit2 = (m_palram[offset] >> 2) & 0x01; - bit1 = (m_palram[offset] >> 1) & 0x01; - bit0 = (m_palram[offset] >> 0) & 0x01; - b = combine_weights(m_weights_b, bit0, bit1, bit2); - - m_palette->set_pen_color(offset, rgb_t(r, g, b)); + set_pen_indirect(offset, m_palram[offset]); } //------------------------------------------------- @@ -152,10 +145,23 @@ mb_vcu_device::mb_vcu_device(const machine_config &mconfig, const char *tag, dev : device_t(mconfig, MB_VCU, tag, owner, clock) , device_memory_interface(mconfig, *this) , device_video_interface(mconfig, *this) - , m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 19, 0, address_map_constructor(FUNC(mb_vcu_device::mb_vcu_vram), this)) - , m_paletteram_space_config("palram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(mb_vcu_device::mb_vcu_pal_ram), this)) - , m_cpu(*this, finder_base::DUMMY_TAG) - , m_palette(*this, finder_base::DUMMY_TAG) + , device_palette_interface(mconfig, *this) + , m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 19, 0, address_map_constructor(FUNC(mb_vcu_device::vram), this)) + , m_paletteram_space_config("palram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(mb_vcu_device::pal_ram), this)) + , m_host_space(*this, finder_base::DUMMY_TAG, 0, 8) + , m_status(1) + , m_ram(nullptr) + , m_palram(nullptr) + , m_param_offset_latch(0) + , m_xpos(0) + , m_ypos(0) + , m_color(0) + , m_mode(0) + , m_pix_xsize(0) + , m_pix_ysize(0) + , m_vregs{0} + , m_bk_color(0) + , m_vbank(0) { } @@ -175,19 +181,45 @@ void mb_vcu_device::device_validity_check(validity_checker &valid) const void mb_vcu_device::device_start() { - // TODO: m_screen_tag + m_host_space->cache(m_memory); m_ram = make_unique_clear<uint8_t[]>(0x800); m_palram = make_unique_clear<uint8_t[]>(0x100); + // setup palette + double weights_r[2]{}; + double weights_g[3]{}; + double weights_b[3]{}; + + static const int resistances_r[2] = { 4700, 2200 }; + static const int resistances_gb[3] = { 10000, 4700, 2200 }; + + compute_resistor_weights(0, 255, -1.0, + 3, resistances_gb, weights_g, 3600, 0, + 3, resistances_gb, weights_b, 3600, 0, + 2, resistances_r, weights_r, 3600, 0); + + for (int i = 0; i < 256; i++) { - static const int resistances_r[2] = { 4700, 2200 }; - static const int resistances_gb[3] = { 10000, 4700, 2200 }; - - /* just to calculate coefficients for later use */ - compute_resistor_weights(0, 255, -1.0, - 3, resistances_gb, m_weights_g, 3600, 0, - 3, resistances_gb, m_weights_b, 3600, 0, - 2, resistances_r, m_weights_r, 3600, 0); + int bit0, bit1, bit2; + + /* red component */ + bit1 = BIT(i, 7); + bit0 = BIT(i, 6); + const int r = combine_weights(weights_r, bit0, bit1); + + /* green component */ + bit2 = BIT(i, 5); + bit1 = BIT(i, 4); + bit0 = BIT(i, 3); + const int g = combine_weights(weights_g, bit0, bit1, bit2); + + /* blue component */ + bit2 = BIT(i, 2); + bit1 = BIT(i, 1); + bit0 = BIT(i, 0); + const int b = combine_weights(weights_b, bit0, bit1, bit2); + + set_indirect_color(i, rgb_t(r, g, b)); } save_item(NAME(m_status)); @@ -196,17 +228,13 @@ void mb_vcu_device::device_start() save_item(NAME(m_param_offset_latch)); save_item(NAME(m_xpos)); save_item(NAME(m_ypos)); - save_item(NAME(m_color1)); - save_item(NAME(m_color2)); + save_item(NAME(m_color)); save_item(NAME(m_mode)); save_item(NAME(m_pix_xsize)); save_item(NAME(m_pix_ysize)); save_item(NAME(m_vregs)); save_item(NAME(m_bk_color)); save_item(NAME(m_vbank)); - save_item(NAME(m_weights_r)); - save_item(NAME(m_weights_g)); - save_item(NAME(m_weights_b)); } @@ -218,9 +246,9 @@ void mb_vcu_device::device_reset() { m_status = 1; - for(int i=0;i<0x80000;i++) + for (int i = 0; i < 0x80000; i++) { - write_byte(i,0x0f); + write_byte(i, 0x0f); } } @@ -228,7 +256,11 @@ void mb_vcu_device::device_reset() //************************************************************************** // READ/WRITE HANDLERS //************************************************************************** -// uint8_t *pcg = memregion("sub2")->base(); + +static inline uint32_t get_vram_addr(uint8_t x, uint8_t y, uint8_t layer, uint8_t bank) +{ + return x | (y << 8) | (layer << 16) | (bank << 18); +} uint8_t mb_vcu_device::read_ram(offs_t offset) { @@ -248,136 +280,110 @@ void mb_vcu_device::write_vregs(offs_t offset, uint8_t data) /* latches RAM offset to send to params */ uint8_t mb_vcu_device::load_params(offs_t offset) { - m_param_offset_latch = offset; - - m_xpos = m_ram[m_param_offset_latch + 1] | (m_ram[m_param_offset_latch + 2]<<8); - m_ypos = m_ram[m_param_offset_latch + 3] | (m_ram[m_param_offset_latch + 4]<<8); - m_color1 = m_ram[m_param_offset_latch + 5]; - m_color2 = m_ram[m_param_offset_latch + 6]; - m_mode = m_ram[m_param_offset_latch + 7]; - m_pix_xsize = m_ram[m_param_offset_latch + 8] + 1; - m_pix_ysize = m_ram[m_param_offset_latch + 9] + 1; - - if(0) + if (!machine().side_effects_disabled()) { - printf("[0] %02x ",m_ram[m_param_offset_latch]); - printf("X: %04x ",m_xpos); - printf("Y: %04x ",m_ypos); - printf("C1:%02x ",m_color1); - printf("C2:%02x ",m_color2); - printf("M :%02x ",m_mode); - printf("XS:%02x ",m_pix_xsize); - printf("YS:%02x ",m_pix_ysize); - printf("\n"); + m_param_offset_latch = offset; + + m_xpos = m_ram[m_param_offset_latch + 1] | (m_ram[m_param_offset_latch + 2] << 8); + m_ypos = m_ram[m_param_offset_latch + 3] | (m_ram[m_param_offset_latch + 4] << 8); + m_color = m_ram[m_param_offset_latch + 5] | (m_ram[m_param_offset_latch + 6] << 8); + m_mode = m_ram[m_param_offset_latch + 7]; + m_pix_xsize = m_ram[m_param_offset_latch + 8] + 1; + m_pix_ysize = m_ram[m_param_offset_latch + 9] + 1; + + LOGPARAMS("[0] %02x ", m_ram[m_param_offset_latch]); + LOGPARAMS("X: %04x ", m_xpos); + LOGPARAMS("Y: %04x ", m_ypos); + LOGPARAMS("C :%04x ", m_color); + LOGPARAMS("M :%02x ", m_mode); + LOGPARAMS("XS:%02x ", m_pix_xsize); + LOGPARAMS("YS:%02x ", m_pix_ysize); + LOGPARAMS("\n"); } - return 0; // open bus? } uint8_t mb_vcu_device::load_gfx(offs_t offset) { - int xi,yi; - int dstx,dsty; - uint8_t dot; - int bits = 0; - uint8_t pen = 0; - uint8_t cur_layer; - uint8_t opaque_pen; + if (!machine().side_effects_disabled()) + { + int bits = 0; -// printf("%02x %02x\n",m_mode >> 2,m_mode & 3); + LOGDRAW("%02x %02x\n", m_mode >> 2, m_mode & 3); -// cur_layer = (m_mode & 0x3); - cur_layer = (m_mode & 2) >> 1; - opaque_pen = (cur_layer == 1); + // const uint8_t cur_layer = (m_mode & 0x3); + const uint8_t cur_layer = BIT(m_mode, 1); + const uint8_t opaque_pen = (cur_layer == 1); - switch(m_mode >> 2) - { - case 0x00: // 4bpp - for(yi=0;yi<m_pix_ysize;yi++) - { - for(xi=0;xi<m_pix_xsize;xi++) + switch (m_mode >> 2) + { + case 0x00: // 4bpp + for (int yi = 0; yi < m_pix_ysize; yi++) { - dstx = (m_xpos + xi); - dsty = (m_ypos + yi); - - if(dstx >= 0 && dsty >= 0 && dstx < 256 && dsty < 256) + for (int xi = 0; xi < m_pix_xsize; xi++) { - dot = m_cpu->space(AS_PROGRAM).read_byte(((offset + (bits >> 3)) & 0x1fff) + 0x4000) >> (4-(bits & 7)); - dot&= 0xf; + const int dstx = (m_xpos + xi); + const int dsty = (m_ypos + yi); + if (dstx >= 0 && dsty >= 0 && dstx < 256 && dsty < 256) + { + const uint8_t dot = (m_memory.read_byte(((offset + (bits >> 3)) & 0x1fff) + 0x4000) >> (4 - (bits & 7))) & 0xf; - if(dot != 0xf || opaque_pen) - write_byte(dstx|dsty<<8|cur_layer<<16|m_vbank<<18, dot); + if (dot != 0xf || opaque_pen) + write_byte(get_vram_addr(dstx, dsty, cur_layer, m_vbank), dot); + } + bits += 4; } - bits += 4; } - } - break; + break; - case 0x02: // 1bpp - for(yi=0;yi<m_pix_ysize;yi++) - { - for(xi=0;xi<m_pix_xsize;xi++) + case 0x02: // 1bpp + for (int yi = 0; yi < m_pix_ysize; yi++) { - dstx = (m_xpos + xi); - dsty = (m_ypos + yi); - - if(dstx >= 0 && dsty >= 0 && dstx < 256 && dsty < 256) + for (int xi = 0; xi < m_pix_xsize; xi++) { - dot = m_cpu->space(AS_PROGRAM).read_byte(((offset + (bits >> 3)) & 0x1fff) + 0x4000) >> (7-(bits & 7)); - dot&= 1; + const int dstx = (m_xpos + xi); + const int dsty = (m_ypos + yi); - pen = dot ? (m_color1 >> 4) : (m_color1 & 0xf); + if (dstx >= 0 && dsty >= 0 && dstx < 256 && dsty < 256) + { + const uint8_t dot = (m_memory.read_byte(((offset + (bits >> 3)) & 0x1fff) + 0x4000) >> (7 - (bits & 7))) & 1; + const uint8_t pen = (m_color >> (dot << 2)) & 0xf; - if(pen != 0xf || opaque_pen) - write_byte(dstx|dsty<<8|cur_layer<<16|m_vbank<<18, pen); + if (pen != 0xf || opaque_pen) + write_byte(get_vram_addr(dstx, dsty, cur_layer, m_vbank), pen); + } + bits++; } - bits++; } - } - break; - case 0x03: //2bpp - for (yi = 0; yi < m_pix_ysize; yi++) - { - for (xi = 0; xi < m_pix_xsize; xi++) + break; + case 0x03: //2bpp + for (int yi = 0; yi < m_pix_ysize; yi++) { - dstx = (m_xpos + xi); - dsty = (m_ypos + yi); - - if(dstx >= 0 && dsty >= 0 && dstx < 256 && dsty < 256) + for (int xi = 0; xi < m_pix_xsize; xi++) { - dot = m_cpu->space(AS_PROGRAM).read_byte(((offset + (bits >> 3)) & 0x1fff) + 0x4000) >> (6-(bits & 7)); + const int dstx = (m_xpos + xi); + const int dsty = (m_ypos + yi); - switch(dot & 3) + if (dstx >= 0 && dsty >= 0 && dstx < 256 && dsty < 256) { - case 0: - pen = m_color1 & 0xf; - break; - case 1: - pen = m_color1 >> 4; - break; - case 2: - pen = m_color2 & 0xf; - break; - case 3: - pen = m_color2 >> 4; - break; + const uint8_t dot = (m_memory.read_byte(((offset + (bits >> 3)) & 0x1fff) + 0x4000) >> (6 - (bits & 7))) & 3; + const uint8_t pen = (m_color >> (dot << 2)) & 0xf; + + if (pen != 0xf || opaque_pen) + write_byte(get_vram_addr(dstx, dsty, cur_layer, m_vbank), pen); } - if(pen != 0xf || opaque_pen) - write_byte(dstx|dsty<<8|cur_layer<<16|m_vbank<<18, pen); + bits += 2; } - - bits+=2; } - } - break; + break; - default: - popmessage("Unsupported draw mode"); - break; + default: + popmessage("Unsupported draw mode"); + break; + } } - return 0; // open bus? } @@ -391,109 +397,89 @@ Read-Modify-Write operations */ uint8_t mb_vcu_device::load_set_clr(offs_t offset) { - int xi,yi; - int dstx,dsty; -// uint8_t dot; - - switch(m_mode) + if (!machine().side_effects_disabled()) { - case 0x13: - { - //int16_t srcx = m_ram[m_param_offset_latch + 1]; - //int16_t srcy = m_ram[m_param_offset_latch + 3]; - //uint16_t src_xsize = m_ram[m_param_offset_latch + 18] + 1; - //uint16_t src_ysize = m_ram[m_param_offset_latch + 19] + 1; - int collision_flag = 0; + //uint8_t dot; - for (yi = 0; yi < m_pix_ysize; yi++) + switch (m_mode) + { + case 0x13: { - for (xi = 0; xi < m_pix_xsize; xi++) - { - dstx = (m_xpos + xi); - dsty = (m_ypos + yi); + //int16_t srcx = m_ram[m_param_offset_latch + 1]; + //int16_t srcy = m_ram[m_param_offset_latch + 3]; + //uint16_t src_xsize = m_ram[m_param_offset_latch + 18] + 1; + //uint16_t src_ysize = m_ram[m_param_offset_latch + 19] + 1; + int collision_flag = 0; - if(dstx < 256 && dsty < 256) + for (int yi = 0; yi < m_pix_ysize; yi++) + { + for (int xi = 0; xi < m_pix_xsize; xi++) { - uint8_t res = read_byte(dstx|dsty<<8|0<<16|(m_vbank)<<18); - //uint8_t res2 = read_byte(srcx|srcy<<8|0<<16|(m_vbank)<<18); + const int dstx = (m_xpos + xi); + const int dsty = (m_ypos + yi); - //printf("%02x %02x\n",res,res2); - - // TODO: how it calculates the pen? Might use the commented out stuff and/or the offset somehow - if(res == 5) + if (dstx >= 0 && dsty >= 0 && dstx < 256 && dsty < 256) { - collision_flag++; -// test++; + const uint8_t res = read_byte(get_vram_addr(dstx, dsty, 0, m_vbank)); + //uint8_t res2 = read_byte(srcx|srcy<<8|0<<16|(m_vbank)<<18); + + //LOG_CLEAR("%02x %02x\n",res,res2); + + // TODO: how it calculates the pen? Might use the commented out stuff and/or the offset somehow + if (res == 5) + { + collision_flag++; + // test++; + } } - } - //srcx++; + //srcx++; + } + //srcy++; } - //srcy++; - } - // threshold for collision, necessary to avoid bogus collision hits - // the typical test scenario is to shoot near the top left hatch for stage 1 then keep shooting, - // at some point the top right hatch will bogusly detect a collision without this. - // It's also unlikely that game tests 1x1 targets anyway, as the faster moving targets are quite too easy to hit that way. - // TODO: likely it works differently (checks area?) - if(collision_flag > 5) - m_ram[m_param_offset_latch] |= 8; - else - m_ram[m_param_offset_latch] &= ~8; - break; - } + // threshold for collision, necessary to avoid bogus collision hits + // the typical test scenario is to shoot near the top left hatch for stage 1 then keep shooting, + // at some point the top right hatch will bogusly detect a collision without this. + // It's also unlikely that game tests 1x1 targets anyway, as the faster moving targets are quite too easy to hit that way. + // TODO: likely it works differently (checks area?) + if (collision_flag > 5) + m_ram[m_param_offset_latch] |= 8; + else + m_ram[m_param_offset_latch] &= ~8; + break; + } - case 0x03: - { - for (yi = 0; yi < m_pix_ysize; yi++) + case 0x03: { - for (xi = 0; xi < m_pix_xsize; xi++) + for (int yi = 0; yi < m_pix_ysize; yi++) { - dstx = (m_xpos + xi); - dsty = (m_ypos + yi); + for (int xi = 0; xi < m_pix_xsize; xi++) + { + const int dstx = (m_xpos + xi); + const int dsty = (m_ypos + yi); - if(dstx < 256 && dsty < 256) - write_byte(dstx|dsty<<8|0<<16|(m_vbank)<<18, 0xf); + if (dstx >= 0 && dsty >= 0 && dstx < 256 && dsty < 256) + write_byte(get_vram_addr(dstx, dsty, 0, m_vbank), 0xf); + } } + break; } - break; - } - case 0x07: - for(int i=0;i<m_pix_xsize;i++) - write_io(i+(m_ypos<<8),m_ram[offset + i]); + case 0x07: + for (int i = 0; i < m_pix_xsize; i++) + write_io(i + (m_ypos << 8), m_ram[offset + i]); - break; + break; + } } - return 0; // open bus? } void mb_vcu_device::background_color_w(uint8_t data) { - int bit0,bit1,bit2; - int r,g,b; m_bk_color = data; - - /* red component */ - bit1 = (m_bk_color >> 7) & 0x01; - bit0 = (m_bk_color >> 6) & 0x01; - r = combine_weights(m_weights_r, bit0, bit1); - - /* green component */ - bit2 = (m_bk_color >> 5) & 0x01; - bit1 = (m_bk_color >> 4) & 0x01; - bit0 = (m_bk_color >> 3) & 0x01; - g = combine_weights(m_weights_g, bit0, bit1, bit2); - - /* blue component */ - bit2 = (m_bk_color >> 2) & 0x01; - bit1 = (m_bk_color >> 1) & 0x01; - bit0 = (m_bk_color >> 0) & 0x01; - b = combine_weights(m_weights_b, bit0, bit1, bit2); - - m_palette->set_pen_color(0x100, rgb_t(r, g, b)); + set_pen_indirect(0x100, m_bk_color); } uint8_t mb_vcu_device::status_r() @@ -506,18 +492,18 @@ uint8_t mb_vcu_device::status_r() void mb_vcu_device::vbank_w(uint8_t data) { - m_vbank = (data & 0x40) >> 6; + m_vbank = BIT(data, 6); } void mb_vcu_device::vbank_clear_w(uint8_t data) { - m_vbank = (data & 0x40) >> 6; + vbank_w(data & 0x40); // setting vbank clears VRAM in the setted bank, applies to Great Guns only since it never ever access the RMW stuff - for(int i=0;i<0x10000;i++) + for (int i = 0; i < 0x10000; i++) { - write_byte(i|0x00000|m_vbank<<18,0x0f); - write_byte(i|0x10000|m_vbank<<18,0x0f); + write_byte(i | 0x00000 | (m_vbank << 18), 0x0f); + write_byte(i | 0x10000 | (m_vbank << 18), 0x0f); } } @@ -527,48 +513,37 @@ void mb_vcu_device::vbank_clear_w(uint8_t data) uint32_t mb_vcu_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - bitmap.fill(m_palette->pen(0x100),cliprect); + bitmap.fill(pen(0x100), cliprect); - for(int y=0;y<256;y++) + for (int y = cliprect.top(); y <= cliprect.bottom(); y++) { - for(int x=0;x<256;x++) + uint32_t *const dst = &bitmap.pix(y); + for (int x = cliprect.left(); x <= cliprect.right(); x++) { - uint8_t dot = read_byte((x >> 0)|(y<<8)|1<<16|(m_vbank ^ 1)<<18); - //if(dot != 0xf) - { - dot|= m_vregs[1] << 4; + const uint8_t dot[2] = {read_byte(get_vram_addr(x, y, 0, m_vbank ^ 1)), read_byte(get_vram_addr(x, y, 1, m_vbank ^ 1))}; + uint8_t dot_sel = uint8_t(~0); - bitmap.pix(y,x) = m_palette->pen(dot); - } - } - } - - for(int y=0;y<256;y++) - { - for(int x=0;x<256;x++) - { - uint8_t dot = read_byte((x >> 0)|(y<<8)|0<<16|(m_vbank ^ 1)<<18); - - if(dot != 0xf) - { - dot|= m_vregs[1] << 4; + if (dot[0] != 0xf) + dot_sel = 0; + else/* if (dot[1] != 0xf) */ + dot_sel = 1; - bitmap.pix(y,x) = m_palette->pen(dot); - } + if (dot_sel <= 1) + dst[x] = pen(dot[dot_sel] | (m_vregs[1] << 4)); } } return 0; } -void mb_vcu_device::screen_eof(void) +void mb_vcu_device::screen_eof() { #if 0 - for(int i=0;i<0x10000;i++) + for (int i = 0; i < 0x10000; i++) { - write_byte(i|0x00000|m_vbank<<18,0x0f); - //write_byte(i|0x10000|m_vbank<<18,0x0f); - //write_byte(i|0x30000|m_vbank<<18,0x0f); + write_byte(i | 0x00000 | m_vbank << 18, 0x0f); + //write_byte(i | 0x10000 | m_vbank << 18, 0x0f); + //write_byte(i | 0x30000 | m_vbank << 18, 0x0f); } #endif } diff --git a/src/devices/video/mb_vcu.h b/src/devices/video/mb_vcu.h index e7be843de5f..e296cf57beb 100644 --- a/src/devices/video/mb_vcu.h +++ b/src/devices/video/mb_vcu.h @@ -5,8 +5,6 @@ #pragma once -#include "emupal.h" - //************************************************************************** // TYPE DEFINITIONS @@ -16,15 +14,15 @@ class mb_vcu_device : public device_t, public device_memory_interface, - public device_video_interface + public device_video_interface, + public device_palette_interface { public: // construction/destruction mb_vcu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // configuration - template <typename T> void set_palette_tag(T &&tag) { m_palette.set_tag(std::forward<T>(tag)); } - template <typename T> void set_cpu_tag(T &&tag) { m_cpu.set_tag(std::forward<T>(tag)); } + template <typename T> void set_host_space(T &&tag, int spacenum) { m_host_space.set_tag(std::forward<T>(tag), spacenum); } // I/O operations void write_vregs(offs_t offset, uint8_t data); @@ -39,7 +37,7 @@ public: void vbank_clear_w(uint8_t data); uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - void screen_eof(void); + void screen_eof(); protected: // device-level overrides @@ -48,38 +46,39 @@ protected: virtual void device_reset() override ATTR_COLD; virtual space_config_vector memory_space_config() const override; + virtual uint32_t palette_entries() const noexcept override { return 256 + 1; } + virtual uint32_t palette_indirect_entries() const noexcept override { return 256; } + private: inline uint8_t read_byte(offs_t address); inline void write_byte(offs_t address, uint8_t data); inline uint8_t read_io(offs_t address); inline void write_io(offs_t address, uint8_t data); - uint8_t mb_vcu_paletteram_r(offs_t offset); - void mb_vcu_paletteram_w(offs_t offset, uint8_t data); + uint8_t paletteram_r(offs_t offset); + void paletteram_w(offs_t offset, uint8_t data); + + void pal_ram(address_map &map) ATTR_COLD; + void vram(address_map &map) ATTR_COLD; - void mb_vcu_pal_ram(address_map &map) ATTR_COLD; - void mb_vcu_vram(address_map &map) ATTR_COLD; + const address_space_config m_videoram_space_config; + const address_space_config m_paletteram_space_config; + required_address_space m_host_space; + memory_access<16, 0, 0, ENDIANNESS_LITTLE>::cache m_memory; - const address_space_config m_videoram_space_config; - const address_space_config m_paletteram_space_config; uint8_t m_status; std::unique_ptr<uint8_t[]> m_ram; std::unique_ptr<uint8_t[]> m_palram; uint16_t m_param_offset_latch; int16_t m_xpos, m_ypos; - uint8_t m_color1, m_color2; + uint16_t m_color; uint8_t m_mode; uint16_t m_pix_xsize, m_pix_ysize; uint8_t m_vregs[4]; uint8_t m_bk_color; uint8_t m_vbank; - double m_weights_r[2]; - double m_weights_g[3]; - double m_weights_b[3]; - required_device<cpu_device> m_cpu; - required_device<palette_device> m_palette; }; diff --git a/src/mame/stern/mazerbla.cpp b/src/mame/stern/mazerbla.cpp index ae3de68077c..a41b6fcf27a 100644 --- a/src/mame/stern/mazerbla.cpp +++ b/src/mame/stern/mazerbla.cpp @@ -22,7 +22,7 @@ ZPU-2000 - main cpu board (Zentral (sic) Processor Unit) - four 'test button' style switches - one 4Mhz xtal @A1 - one PAL16R8? @7D (UNDUMPED, if present) - - this same board is shared with cliff hanger (cliffhgr.c) + - this same board is shared with cliff hanger (stern/cliffhgr.cpp) CFB-1000 - video/subcpu board (Color Frame Board) - this board has a sub-cpu on it and four roms (six sockets for roms, two empty) @@ -49,7 +49,7 @@ VSB-2000 - sound/speech/subcpu board (Voice and Sound Board) - PROMS: 82s123: @B8 @B9; 82s129: @G8 @G9 (all dumped) CRF-1001 - RF Filter board for video/audio output - - this same board is shared with cliff hanger (cliffhgr.c) + - this same board is shared with cliff hanger (stern/cliffhgr.cpp) UIB-1000 - coin inputs, start/fire buttons and gun ADCs (Vin(-) and Vref/2 are calibrated by potentiometers) @@ -113,9 +113,7 @@ video z80 #include "machine/nvram.h" #include "machine/rescap.h" #include "sound/ay8910.h" -#include "video/resnet.h" #include "video/mb_vcu.h" -#include "emupal.h" #include "screen.h" #include "speaker.h" @@ -123,8 +121,8 @@ video z80 namespace { -#define MASTER_CLOCK XTAL(4'000'000) -#define SOUND_CLOCK XTAL(14'318'181) +static constexpr XTAL MASTER_CLOCK = XTAL(4'000'000); +static constexpr XTAL SOUND_CLOCK = XTAL(14'318'181); class mazerbla_state : public driver_device @@ -134,11 +132,12 @@ public: : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_subcpu(*this, "sub") - , m_vcu(*this,"vcu") + , m_vcu(*this, "vcu") , m_screen(*this, "screen") , m_soundlatch(*this, "soundlatch") , m_uib_adc(*this, "adc%u", 0U) , m_digital_inputs(*this, { "ZPU", "DSW0", "DSW1", "DSW2", "DSW3", "BUTTONS" }) + , m_gfx_bank(*this, "gfx_bank") , m_leds(*this, "led%u", 0U) , m_lamps(*this, "lamp%u", 0U) { } @@ -149,14 +148,17 @@ public: void init_mazerbla(); void init_greatgun(); +protected: + virtual void machine_start() override ATTR_COLD; + virtual void machine_reset() override ATTR_COLD; + virtual void video_start() override ATTR_COLD; + private: void cfb_rom_bank_sel_w(uint8_t data); void cfb_zpu_int_req_set_w(uint8_t data); uint8_t cfb_zpu_int_req_clr(); - uint8_t ls670_0_r(offs_t offset); - void ls670_0_w(offs_t offset, uint8_t data); - uint8_t ls670_1_r(offs_t offset); - void ls670_1_w(offs_t offset, uint8_t data); + template <unsigned Chip> uint8_t ls670_r(offs_t offset); + template <unsigned Chip> void ls670_w(offs_t offset, uint8_t data); void zpu_bcd_decoder_w(uint8_t data); uint8_t zpu_inputs_r(); void zpu_led_w(offs_t offset, uint8_t data); @@ -166,12 +168,9 @@ private: void vsb_ls273_audio_control_w(uint8_t data); void sound_int_clear_w(uint8_t data); void gg_led_ctrl_w(uint8_t data); - void mazerbla_palette(palette_device &palette); - uint32_t screen_update_mazerbla(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void screen_vblank(int state); INTERRUPT_GEN_MEMBER(sound_interrupt); - TIMER_CALLBACK_MEMBER(deferred_ls670_0_w); - TIMER_CALLBACK_MEMBER(deferred_ls670_1_w); + TIMER_CALLBACK_MEMBER(deferred_ls670_w); IRQ_CALLBACK_MEMBER(irq_callback); void greatgun_cpu3_io_map(address_map &map) ATTR_COLD; void greatgun_io_map(address_map &map) ATTR_COLD; @@ -183,10 +182,6 @@ private: void mazerbla_io_map(address_map &map) ATTR_COLD; void mazerbla_map(address_map &map) ATTR_COLD; - virtual void machine_start() override ATTR_COLD; - virtual void machine_reset() override ATTR_COLD; - virtual void video_start() override ATTR_COLD; - /* devices */ required_device<cpu_device> m_maincpu; required_device<cpu_device> m_subcpu; @@ -195,19 +190,15 @@ private: optional_device<generic_latch_8_device> m_soundlatch; optional_device_array<adc0804_device, 4> m_uib_adc; required_ioport_array<6> m_digital_inputs; + required_memory_bank m_gfx_bank; output_finder<3> m_leds; output_finder<2> m_lamps; uint8_t m_port02_status = 0; uint32_t m_gfx_rom_bank = 0; /* graphics ROMs are banked */ - double m_weights_r[2]; - double m_weights_g[3]; - double m_weights_b[3]; - /* misc */ - uint8_t m_ls670_0[4]; - uint8_t m_ls670_1[4]; + uint8_t m_ls670[2][4]; uint8_t m_zpu_int_vector = 0; @@ -236,30 +227,12 @@ private: ***************************************************************************/ -void mazerbla_state::mazerbla_palette(palette_device &palette) -{ - static constexpr int resistances_r[2] = { 4700, 2200 }; - static constexpr int resistances_gb[3] = { 10000, 4700, 2200 }; - - // just to calculate coefficients for later use - compute_resistor_weights(0, 255, -1.0, - 3, resistances_gb, m_weights_g, 3600, 0, - 3, resistances_gb, m_weights_b, 3600, 0, - 2, resistances_r, m_weights_r, 3600, 0); -} - void mazerbla_state::video_start() { // ... } -uint32_t mazerbla_state::screen_update_mazerbla(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - m_vcu->screen_update(screen,bitmap,cliprect); - return 0; -} - void mazerbla_state::screen_vblank(int state) { if (state) @@ -272,7 +245,7 @@ void mazerbla_state::cfb_rom_bank_sel_w(uint8_t data) { m_gfx_rom_bank = data; - membank("bank1")->set_entry(m_gfx_rom_bank); + m_gfx_bank->set_entry(m_gfx_rom_bank); } /************************************* @@ -290,55 +263,39 @@ void mazerbla_state::cfb_zpu_int_req_set_w(uint8_t data) uint8_t mazerbla_state::cfb_zpu_int_req_clr() { - // this clears all interrupts - m_zpu_int_vector = 0xff; - m_maincpu->set_input_line(0, CLEAR_LINE); + if (!machine().side_effects_disabled()) + { + // this clears all interrupts + m_zpu_int_vector = 0xff; + m_maincpu->set_input_line(0, CLEAR_LINE); + } return 0; } -uint8_t mazerbla_state::ls670_0_r(offs_t offset) +template <unsigned Chip> +uint8_t mazerbla_state::ls670_r(offs_t offset) { /* set a timer to force synchronization after the read */ machine().scheduler().synchronize(); - return m_ls670_0[offset]; + return m_ls670[Chip][offset]; } -TIMER_CALLBACK_MEMBER(mazerbla_state::deferred_ls670_0_w) +TIMER_CALLBACK_MEMBER(mazerbla_state::deferred_ls670_w) { - int offset = (param >> 8) & 255; - int data = param & 255; + int const chip = (param >> 16) & 1; + int const offset = (param >> 8) & 3; + int const data = param & 255; - m_ls670_0[offset] = data; + m_ls670[chip][offset] = data; } -void mazerbla_state::ls670_0_w(offs_t offset, uint8_t data) +template <unsigned Chip> +void mazerbla_state::ls670_w(offs_t offset, uint8_t data) { /* do this on a timer to let the CPUs synchronize */ - machine().scheduler().synchronize(timer_expired_delegate(FUNC(mazerbla_state::deferred_ls670_0_w),this), (offset << 8) | data); -} - -uint8_t mazerbla_state::ls670_1_r(offs_t offset) -{ - /* set a timer to force synchronization after the read */ - machine().scheduler().synchronize(); - - return m_ls670_1[offset]; -} - -TIMER_CALLBACK_MEMBER(mazerbla_state::deferred_ls670_1_w) -{ - int offset = (param >> 8) & 255; - int data = param & 255; - - m_ls670_1[offset] = data; -} - -void mazerbla_state::ls670_1_w(offs_t offset, uint8_t data) -{ - /* do this on a timer to let the CPUs synchronize */ - machine().scheduler().synchronize(timer_expired_delegate(FUNC(mazerbla_state::deferred_ls670_1_w),this), (offset << 8) | data); + machine().scheduler().synchronize(timer_expired_delegate(FUNC(mazerbla_state::deferred_ls670_w),this), (Chip << 16) | (offset << 8) | data); } @@ -491,7 +448,7 @@ void mazerbla_state::mazerbla_map(address_map &map) void mazerbla_state::mazerbla_io_map(address_map &map) { map.global_mask(0xff); - map(0x4c, 0x4f).rw(FUNC(mazerbla_state::ls670_1_r), FUNC(mazerbla_state::ls670_0_w)); + map(0x4c, 0x4f).rw(FUNC(mazerbla_state::ls670_r<1>), FUNC(mazerbla_state::ls670_w<0>)); map(0x60, 0x60).w(FUNC(mazerbla_state::zpu_bcd_decoder_w)); // r(FUNC(mazerbla_state::) from protection pal, if populated map(0x62, 0x62).r(FUNC(mazerbla_state::zpu_inputs_r)); // 64 is some sort of output latch, unpopulated? @@ -515,14 +472,14 @@ void mazerbla_state::mazerbla_cpu2_io_map(address_map &map) map.global_mask(0xff); map(0x00, 0x00).w(FUNC(mazerbla_state::vsb_ls273_audio_control_w)); map(0x40, 0x41).nopw(); - map(0x80, 0x83).rw(FUNC(mazerbla_state::ls670_0_r), FUNC(mazerbla_state::ls670_1_w)); + map(0x80, 0x83).rw(FUNC(mazerbla_state::ls670_r<0>), FUNC(mazerbla_state::ls670_w<1>)); } void mazerbla_state::mazerbla_cpu3_map(address_map &map) { map(0x0000, 0x37ff).rom(); map(0x3800, 0x3fff).ram().share("share1"); - map(0x4000, 0x5fff).bankr("bank1"); /* GFX roms */ + map(0x4000, 0x5fff).bankr(m_gfx_bank); /* GFX roms */ map(0x4000, 0x4003).w(m_vcu, FUNC(mb_vcu_device::write_vregs)); map(0x6000, 0x67ff).rw(m_vcu, FUNC(mb_vcu_device::read_ram), FUNC(mb_vcu_device::write_ram)); map(0xa000, 0xa7ff).r(m_vcu, FUNC(mb_vcu_device::load_params)); @@ -939,13 +896,12 @@ void mazerbla_state::machine_start() m_leds.resolve(); m_lamps.resolve(); - membank("bank1")->configure_entries(0, 256, memregion("sub2")->base() + 0x10000, 0x2000); + m_gfx_bank->configure_entries(0, 256, memregion("sub2")->base() + 0x10000, 0x2000); save_item(NAME(m_port02_status)); save_item(NAME(m_gfx_rom_bank)); - save_item(NAME(m_ls670_0)); - save_item(NAME(m_ls670_1)); + save_item(NAME(m_ls670)); save_item(NAME(m_zpu_int_vector)); @@ -972,8 +928,8 @@ void mazerbla_state::machine_reset() for (int i = 0; i < 4; i++) { - m_ls670_0[i] = 0; - m_ls670_1[i] = 0; + for (int j = 0; j < 2; j++) + m_ls670[j][i] = 0; } zpu_bcd_decoder_w(0); @@ -1008,8 +964,8 @@ void mazerbla_state::mazerbla(machine_config &config) /* synchronization forced on the fly */ MB_VCU(config, m_vcu, SOUND_CLOCK/4); - m_vcu->set_cpu_tag("sub2"); - m_vcu->set_palette_tag("palette"); + m_vcu->set_screen(m_screen); + m_vcu->set_host_space("sub2", AS_PROGRAM); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); @@ -1019,11 +975,9 @@ void mazerbla_state::mazerbla(machine_config &config) m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */); m_screen->set_size(40*8, 32*8); m_screen->set_visarea(0*8, 32*8-1, 0*8, 28*8-1); - m_screen->set_screen_update(FUNC(mazerbla_state::screen_update_mazerbla)); + m_screen->set_screen_update(m_vcu, FUNC(mb_vcu_device::screen_update)); m_screen->screen_vblank().set(FUNC(mazerbla_state::screen_vblank)); - PALETTE(config, "palette", FUNC(mazerbla_state::mazerbla_palette), 256+1); - /* sound hardware */ } @@ -1057,8 +1011,8 @@ void mazerbla_state::greatgun(machine_config &config) m_uib_adc[3]->vin_callback().set_ioport("STICK1_Y"); MB_VCU(config, m_vcu, SOUND_CLOCK/4); - m_vcu->set_cpu_tag("sub2"); - m_vcu->set_palette_tag("palette"); + m_vcu->set_screen(m_screen); + m_vcu->set_host_space("sub2", AS_PROGRAM); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); @@ -1068,11 +1022,9 @@ void mazerbla_state::greatgun(machine_config &config) m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */); m_screen->set_size(40*8, 32*8); m_screen->set_visarea(0*8, 32*8-1, 0*8, 28*8-1); - m_screen->set_screen_update(FUNC(mazerbla_state::screen_update_mazerbla)); + m_screen->set_screen_update(m_vcu, FUNC(mb_vcu_device::screen_update)); m_screen->screen_vblank().set(FUNC(mazerbla_state::screen_vblank)); - PALETTE(config, "palette", FUNC(mazerbla_state::mazerbla_palette), 256+1); - /* sound hardware */ SPEAKER(config, "mono").front_center(); |