diff options
Diffstat (limited to 'src/mame/midway/midtunit_v.h')
-rw-r--r-- | src/mame/midway/midtunit_v.h | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/src/mame/midway/midtunit_v.h b/src/mame/midway/midtunit_v.h new file mode 100644 index 00000000000..17e714a4614 --- /dev/null +++ b/src/mame/midway/midtunit_v.h @@ -0,0 +1,233 @@ +// license:BSD-3-Clause +// copyright-holders:Alex Pasadyn, Zsolt Vasvari, Ernesto Corvi, Aaron Giles +// thanks-to:Kurt Mahan +/************************************************************************* + + Video Emulation for Midway T-unit, W-unit, and X-unit games. + +**************************************************************************/ + +#ifndef MAME_MIDWAY_MIDTUNIT_V_H +#define MAME_MIDWAY_MIDTUNIT_V_H + +#pragma once + +#include "emu.h" +#include "cpu/tms34010/tms34010.h" +#include "emupal.h" + +#define DEBUG_MIDTUNIT_BLITTER (0) + +class midtunit_video_device : public device_t +{ +public: + // construction/destruction + template <typename T> + midtunit_video_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&palette_tag) + : midtunit_video_device(mconfig, tag, owner, (uint32_t)0) + { + m_palette.set_tag(std::forward<T>(palette_tag)); + } + + midtunit_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + // configuration + auto dma_irq_cb() { return m_dma_irq_cb.bind(); } + void set_gfx_rom_large(bool gfx_rom_large) { m_gfx_rom_large = gfx_rom_large; } + + TMS340X0_TO_SHIFTREG_CB_MEMBER(to_shiftreg); + TMS340X0_FROM_SHIFTREG_CB_MEMBER(from_shiftreg); + TMS340X0_SCANLINE_IND16_CB_MEMBER(scanline_update); + + uint16_t midtunit_vram_r(offs_t offset); + void midtunit_vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t midtunit_gfxrom_r(offs_t offset); + void midtunit_vram_data_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void midtunit_vram_color_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t midtunit_vram_data_r(offs_t offset); + uint16_t midtunit_vram_color_r(offs_t offset); + + uint16_t dma_r(offs_t offset); + void dma_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + + void midtunit_control_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + + enum op_type_t + { + PIXEL_SKIP = 0, + PIXEL_COLOR = 1, + PIXEL_COPY = 2 + }; + +protected: + // construction/destruction + midtunit_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 0); + + virtual void device_start() override ATTR_COLD; + + TIMER_CALLBACK_MEMBER(dma_done); + + required_device<palette_device> m_palette; + required_region_ptr<uint8_t> m_gfxrom; + + emu_timer *m_dma_timer; + + // constants for the DMA chip + static constexpr uint32_t XPOSMASK = 0x3ff; + static constexpr uint32_t YPOSMASK = 0x1ff; + + template <int BitsPerPixel, bool XFlip, bool Skip, bool Scale, op_type_t Zero, op_type_t NonZero> void dma_draw(); + void dma_draw_none() {} + + typedef void (midtunit_video_device::*draw_func)(); + draw_func m_dma_draw_skip_scale[8*32]; + draw_func m_dma_draw_noskip_scale[8*32]; + draw_func m_dma_draw_skip_noscale[8*32]; + draw_func m_dma_draw_noskip_noscale[8*32]; + + enum + { + DMA_LRSKIP = 0, + DMA_COMMAND, + DMA_OFFSETLO, + DMA_OFFSETHI, + DMA_XSTART, + DMA_YSTART, + DMA_WIDTH, + DMA_HEIGHT, + DMA_PALETTE, + DMA_COLOR, + DMA_SCALE_X, + DMA_SCALE_Y, + DMA_TOPCLIP, + DMA_BOTCLIP, + DMA_UNKNOWN_E, // MK1/2 never write here; NBA only writes 0 + DMA_CONFIG, + DMA_LEFTCLIP, // pseudo-register + DMA_RIGHTCLIP // pseudo-register + }; + + // graphics-related variables + uint16_t m_midtunit_control; + bool m_gfx_rom_large; + + // videoram-related variables + uint32_t m_gfxbank_offset[2]; + std::unique_ptr<uint16_t[]> m_local_videoram; + uint8_t m_videobank_select; + + // DMA-related variables + uint16_t m_dma_register[18]; + struct dma_state + { + uint8_t * gfxrom; + + uint32_t offset; // source offset, in bits + int32_t rowbits; // source bits to skip each row + int32_t xpos; // x position, clipped + int32_t ypos; // y position, clipped + int32_t width; // horizontal pixel count + int32_t height; // vertical pixel count + uint16_t palette; // palette base + uint16_t color; // current foreground color with palette + + uint8_t yflip; // yflip? + uint8_t preskip; // preskip scale + uint8_t postskip; // postskip scale + int32_t topclip; // top clipping scanline + int32_t botclip; // bottom clipping scanline + int32_t leftclip; // left clipping column + int32_t rightclip; // right clipping column + int32_t startskip; // pixels to skip at start + int32_t endskip; // pixels to skip at end + uint16_t xstep; // 8.8 fixed number scale x factor + uint16_t ystep; // 8.8 fixed number scale y factor + }; + dma_state m_dma_state; + + devcb_write_line m_dma_irq_cb; + +#if DEBUG_MIDTUNIT_BLITTER + virtual void device_reset() override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + + uint32_t debug_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + void do_debug_blit(); + void do_dma_debug_inputs(); + + required_device<palette_device> m_debug_palette; + std::unique_ptr<uint16_t[]> m_debug_videoram; + bool m_dma_debug; + bool m_doing_debug_dma; + dma_state m_debug_dma_state; + int32_t m_debug_dma_bpp; + int32_t m_debug_dma_mode; + int32_t m_debug_dma_command; +#endif + + std::string m_log_path; + bool m_log_png; + bool m_log_json; + std::unique_ptr<uint64_t[]> m_logged_rom; + bitmap_argb32 m_log_bitmap; + + void debug_init(); + void debug_commands(const std::vector<std::string_view> ¶ms); + void debug_help_command(const std::vector<std::string_view> ¶ms); + void debug_png_dma_command(const std::vector<std::string_view> ¶ms); + void log_bitmap(int command, int bpp, bool skip); +}; + +class midwunit_video_device : public midtunit_video_device +{ +public: + // construction/destruction + template <typename T> + midwunit_video_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&palette_tag) + : midwunit_video_device(mconfig, tag, owner, (uint32_t)0) + { + m_palette.set_tag(std::forward<T>(palette_tag)); + } + midwunit_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + uint16_t midwunit_gfxrom_r(offs_t offset); + + void midwunit_control_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t midwunit_control_r(); + +protected: + midwunit_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 0); + +#if DEBUG_MIDTUNIT_BLITTER + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; +#endif +}; + +class midxunit_video_device : public midwunit_video_device +{ +public: + // construction/destruction + template <typename T> + midxunit_video_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&palette_tag) + : midwunit_video_device(mconfig, tag, owner, (uint32_t)0) + { + m_palette.set_tag(std::forward<T>(palette_tag)); + } + + midxunit_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + void midxunit_paletteram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t midxunit_paletteram_r(offs_t offset); + + TMS340X0_SCANLINE_IND16_CB_MEMBER(scanline_update); + +protected: + virtual void device_start() override ATTR_COLD; +}; + +DECLARE_DEVICE_TYPE(MIDTUNIT_VIDEO, midtunit_video_device) +DECLARE_DEVICE_TYPE(MIDWUNIT_VIDEO, midwunit_video_device) +DECLARE_DEVICE_TYPE(MIDXUNIT_VIDEO, midxunit_video_device) + +#endif // MAME_MIDWAY_MIDTUNIT_V_H |