diff options
Diffstat (limited to 'src/emu/bus/isa/num9rev.c')
-rw-r--r-- | src/emu/bus/isa/num9rev.c | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/src/emu/bus/isa/num9rev.c b/src/emu/bus/isa/num9rev.c new file mode 100644 index 00000000000..891c10600c9 --- /dev/null +++ b/src/emu/bus/isa/num9rev.c @@ -0,0 +1,318 @@ +// license:BSD-3-Clause +// Number Nine Revolution 512x32/1024x8 +// TODO: for 1024x768 mode the 7220 is programmed for 512x768, how does that work? + +#include "emu.h" +#include "num9rev.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type ISA8_NUM_9_REV = &device_creator<isa8_number_9_rev_device>; + +static ADDRESS_MAP_START( upd7220_map, AS_0, 8, isa8_number_9_rev_device ) + AM_RANGE(0x00000, 0x3ffff) AM_NOP +ADDRESS_MAP_END + +UPD7220_DISPLAY_PIXELS_MEMBER( isa8_number_9_rev_device::hgdc_display_pixels ) +{ + palette_t *pal = m_palette->palette(); + if(!m_1024) + { + rgb_t color(0); + UINT16 overlay; + if(((address << 3) + 0xc0008) > (1024*1024)) + return; + for(int i = 0; i < 8; i++) + { + UINT32 addr = (address << 3) + i; + overlay = m_ram[addr + 0xc0000] << 1; + overlay = m_overlay[overlay + ((m_mode & 8) ? 512 : 0)] | (m_overlay[overlay + 1 + ((m_mode & 8) ? 512 : 0)] << 8); + color.set_r(pal->entry_color(m_ram[addr] | ((overlay & 0xf) << 8)).r()); + color.set_g(pal->entry_color(m_ram[addr + 0x40000] | ((overlay & 0xf0) << 4)).g()); + color.set_b(pal->entry_color(m_ram[addr + 0x80000] | (overlay & 0xf00)).b()); + bitmap.pix32(y, x + i) = color; + } + } + else + { + if(((address << 3) + 8) > (1024*1024)) + return; + for(int i = 0; i < 8; i++) + bitmap.pix32(y, x + i) = pal->entry_color(m_ram[(address << 3) + i]); + } +} + +static MACHINE_CONFIG_FRAGMENT( num_9_rev ) + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_SIZE(512, 448) + MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 448-1) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_UPDATE_DRIVER(isa8_number_9_rev_device, screen_update) + MCFG_PALETTE_ADD("palette", 4096) + + MCFG_DEVICE_ADD("upd7220", UPD7220, XTAL_4_433619MHz/2) // unknown clock + MCFG_DEVICE_ADDRESS_MAP(AS_0, upd7220_map) + MCFG_UPD7220_DISPLAY_PIXELS_CALLBACK_OWNER(isa8_number_9_rev_device, hgdc_display_pixels) + MCFG_VIDEO_SET_SCREEN("screen") +MACHINE_CONFIG_END + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor isa8_number_9_rev_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( num_9_rev ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// isa16_vga_device - constructor +//------------------------------------------------- + +isa8_number_9_rev_device::isa8_number_9_rev_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, ISA8_NUM_9_REV, "Number Nine Revolution 512x32/1024x8", tag, owner, clock, "number_9_rev", __FILE__), + device_isa8_card_interface(mconfig, *this), + m_upd7220(*this, "upd7220"), + m_palette(*this, "palette"), + m_ram(1024*1024), + m_overlay(1024) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void isa8_number_9_rev_device::device_start() +{ + set_isa_device(); + + m_isa->install_memory(0xc0000, 0xc0001, 0, 0, read8_delegate(FUNC(upd7220_device::read), (upd7220_device *)m_upd7220), write8_delegate(FUNC(upd7220_device::write), (upd7220_device *)m_upd7220)); + m_isa->install_memory(0xc0100, 0xc03ff, 0, 0, read8_delegate(FUNC(isa8_number_9_rev_device::pal8_r), this), write8_delegate(FUNC(isa8_number_9_rev_device::pal8_w), this)); + m_isa->install_memory(0xc0400, 0xc0401, 0, 0, read8_delegate(FUNC(isa8_number_9_rev_device::bank_r), this), write8_delegate(FUNC(isa8_number_9_rev_device::bank_w), this)); + m_isa->install_memory(0xc0500, 0xc06ff, 0, 0, read8_delegate(FUNC(isa8_number_9_rev_device::overlay_r), this), write8_delegate(FUNC(isa8_number_9_rev_device::overlay_w), this)); + m_isa->install_memory(0xc0700, 0xc070f, 0, 0, read8_delegate(FUNC(isa8_number_9_rev_device::ctrl_r), this), write8_delegate(FUNC(isa8_number_9_rev_device::ctrl_w), this)); + m_isa->install_memory(0xc1000, 0xc3fff, 0, 0, read8_delegate(FUNC(isa8_number_9_rev_device::pal12_r), this), write8_delegate(FUNC(isa8_number_9_rev_device::pal12_w), this)); + m_isa->install_memory(0xa0000, 0xaffff, 0, 0, read8_delegate(FUNC(isa8_number_9_rev_device::read8), this), write8_delegate(FUNC(isa8_number_9_rev_device::write8), this)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void isa8_number_9_rev_device::device_reset() +{ + m_bank = 0; + m_mode = 0; + m_1024 = false; +} + +READ8_MEMBER(isa8_number_9_rev_device::read8) +{ + if((m_mode & 1) && !m_1024) + return m_ram[offset + ((m_mode & 0xc) << 14)]; + else if((m_mode & 4) && !m_1024) + { + UINT32 newoff = ((offset & 3) << 18) | (m_bank << 14) | ((offset >> 2) & 0x3fff); + return m_ram[newoff]; + } + else + return m_ram[offset + (m_bank << 16)]; +} + +WRITE8_MEMBER(isa8_number_9_rev_device::write8) +{ + if(m_1024 || ((m_mode & 6) == 0)) + m_ram[offset + (m_bank << 16)] = data; + else if((m_mode & 1) || ((m_mode & 6) == 2)) + { + UINT8 bank = m_bank; + if(m_mode & 1) + bank = (m_mode & 0xc) >> 2; + else + { + if(m_bank >= 12) + { + m_ram[offset + (m_bank << 16)] = data; + return; + } + bank &= 3; + } + + m_ram[offset + (bank << 16)] = data; + m_ram[offset + ((bank + 4) << 16)] = data; + m_ram[offset + ((bank + 8) << 16)] = data; + } + else if(m_mode & 4) + { + UINT32 newoff = ((offset & 3) << 18) | (m_bank << 14) | ((offset >> 2) & 0x3fff); + if((newoff >= 0xc0000) && ((m_mode & 6) == 6)) + return; + m_ram[newoff] = data; + } +} + +READ8_MEMBER(isa8_number_9_rev_device::pal8_r) +{ + offset += 0x100; + palette_t *pal = m_palette->palette(); + switch(offset & 0xf00) + { + case 0x100: + return pal->entry_color(offset).r(); + case 0x200: + return pal->entry_color(offset).g(); + case 0x300: + return pal->entry_color(offset).b(); + } + return 0; +} + +WRITE8_MEMBER(isa8_number_9_rev_device::pal8_w) +{ + offset += 0x100; + palette_t *pal = m_palette->palette(); + rgb_t pen = pal->entry_color(offset); + switch(offset & 0xf00) + { + case 0x100: + pen.set_r(data); + break; + case 0x200: + pen.set_g(data); + break; + case 0x300: + pen.set_b(data); + break; + } + pal->entry_set_color(offset, pen); +} + +READ8_MEMBER(isa8_number_9_rev_device::pal12_r) +{ + UINT16 color = offset & 0xfff; + palette_t *pal = m_palette->palette(); + switch(offset & 0xf000) + { + case 0x0000: + return pal->entry_color(color).r(); + case 0x1000: + return pal->entry_color(color).g(); + case 0x2000: + return pal->entry_color(color).b(); + } + return 0; +} + +WRITE8_MEMBER(isa8_number_9_rev_device::pal12_w) +{ + UINT16 color = offset & 0xfff; + palette_t *pal = m_palette->palette(); + rgb_t pen = pal->entry_color(color); + switch(offset & 0xf000) + { + case 0x0000: + pen.set_r(data); + break; + case 0x1000: + pen.set_g(data); + break; + case 0x2000: + pen.set_b(data); + break; + } + pal->entry_set_color(color, pen); +} + +READ8_MEMBER(isa8_number_9_rev_device::overlay_r) +{ + return m_overlay[offset + ((m_mode & 8) ? 512 : 0)]; +} +WRITE8_MEMBER(isa8_number_9_rev_device::overlay_w) +{ + m_overlay[offset + ((m_mode & 8) ? 512 : 0)] = data; +} + +READ8_MEMBER(isa8_number_9_rev_device::bank_r) +{ + return m_bank; +} + +WRITE8_MEMBER(isa8_number_9_rev_device::bank_w) +{ + m_bank = data & 0xf; +} + +READ8_MEMBER(isa8_number_9_rev_device::ctrl_r) +{ + switch(offset & 0xf) + { + case 0: + case 1: + case 2: + case 3: + // zoom, set to same value as 7220 external zoom factor + break; + case 4: + return (m_mode & 2) ? 0xff : 0; + case 5: + return (m_mode & 4) ? 0xff : 0; + case 6: + return (m_mode & 8) ? 0xff : 0; + case 15: + return (m_mode & 1) ? 0xff : 0; + } + return 0; +} + +WRITE8_MEMBER(isa8_number_9_rev_device::ctrl_w) +{ + switch(offset & 0xf) + { + case 0: + case 1: + case 2: + case 3: + // zoom + break; + case 4: + if(data & 0x80) + m_mode |= 2; + else + m_mode &= ~2; + break; + case 5: + if(data & 0x80) + m_mode |= 4; + else + m_mode &= ~4; + break; + case 6: + if(data & 0x80) + m_mode |= 8; + else + m_mode &= ~8; + break; + case 15: + if(data & 0x80) + m_mode |= 1; + else + m_mode &= ~1; + break; + } +} + +UINT32 isa8_number_9_rev_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + rectangle visarea = screen.visible_area(); + // try to support the 1024x8 or at least don't crash as there's no way to detect it + m_1024 = (visarea.width() * visarea.height()) > (512 * 512); + return m_upd7220->screen_update(screen, bitmap, cliprect); +} |