mirror of
https://github.com/holub/mame
synced 2025-04-24 01:11:11 +03:00
bus/multibus: Added Robotron K7071 text-only video card for the A7100 series. (#12188)
This commit is contained in:
parent
23ac5bbc20
commit
c895c5e198
@ -5265,6 +5265,8 @@ if (BUSES["MULTIBUS"]~=null) then
|
||||
MAME_DIR .. "src/devices/bus/multibus/labtam_z80sbc.h",
|
||||
MAME_DIR .. "src/devices/bus/multibus/robotron_k7070.cpp",
|
||||
MAME_DIR .. "src/devices/bus/multibus/robotron_k7070.h",
|
||||
MAME_DIR .. "src/devices/bus/multibus/robotron_k7071.cpp",
|
||||
MAME_DIR .. "src/devices/bus/multibus/robotron_k7071.h",
|
||||
}
|
||||
end
|
||||
|
||||
|
222
src/devices/bus/multibus/robotron_k7071.cpp
Normal file
222
src/devices/bus/multibus/robotron_k7071.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
|
||||
/*
|
||||
* Robotron K7071 (ABS) text-only video
|
||||
*
|
||||
* Reference: http://www.tiffe.de/Robotron/MMS16/
|
||||
*
|
||||
* To do:
|
||||
* - fix screen corruption (DMA reprogramming timing?)
|
||||
* - loadable font - CRTC LA0 connected to NMI via gate
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "robotron_k7071.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
#include "logmacro.h"
|
||||
|
||||
enum kgs_st : u8
|
||||
{
|
||||
KGS_ST_OBF = 0x01,
|
||||
KGS_ST_IBF = 0x02,
|
||||
KGS_ST_INT = 0x04,
|
||||
KGS_ST_ERR = 0x80,
|
||||
};
|
||||
|
||||
DEFINE_DEVICE_TYPE(ROBOTRON_K7071, robotron_k7071_device, "robotron_k7071", "Robotron K7071 ABS")
|
||||
|
||||
robotron_k7071_device::robotron_k7071_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, ROBOTRON_K7071, tag, owner, clock)
|
||||
, device_multibus_interface(mconfig, *this)
|
||||
, m_cpu(*this, "cpu")
|
||||
, m_dma(*this, "dma")
|
||||
, m_crtc(*this, "crtc")
|
||||
, m_screen(*this, "screen")
|
||||
, m_palette(*this, "palette")
|
||||
, m_ram(*this, "ram")
|
||||
, m_p_chargen(*this, "chargen")
|
||||
{
|
||||
}
|
||||
|
||||
ROM_START(robotron_k7071)
|
||||
ROM_REGION(0x1000, "eprom", ROMREGION_ERASEFF)
|
||||
ROM_LOAD("q209.bin", 0x0000, 0x0800, CRC(efc4aac0) SHA1(2cb4db3572e6ec7f3d3ae8e70d61b509b1fa3203))
|
||||
ROM_LOAD("q210.bin", 0x0800, 0x0800, CRC(d23e00ed) SHA1(eaca53ed784cf263323e9abba24a364b2aadac44))
|
||||
|
||||
ROM_REGION(0x2000, "chargen", ROMREGION_ERASE00)
|
||||
ROM_LOAD("q211.bin", 0x0000, 0x0800, CRC(b6241bc5) SHA1(8428e344df95451a34ad01322e245d2357712010))
|
||||
ROM_END
|
||||
|
||||
const tiny_rom_entry *robotron_k7071_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(robotron_k7071);
|
||||
}
|
||||
|
||||
void robotron_k7071_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_kgs_datao));
|
||||
save_item(NAME(m_kgs_datai));
|
||||
save_item(NAME(m_kgs_ctrl));
|
||||
save_item(NAME(m_nmi_enable));
|
||||
|
||||
m_cpu->space(AS_PROGRAM).specific(m_program);
|
||||
m_bus->space(AS_IO).install_readwrite_handler(0x200, 0x203, read16s_delegate(*this, FUNC(robotron_k7071_device::io_r)), write16s_delegate(*this, FUNC(robotron_k7071_device::io_w)));
|
||||
}
|
||||
|
||||
void robotron_k7071_device::device_reset()
|
||||
{
|
||||
m_kgs_ctrl = KGS_ST_IBF | KGS_ST_OBF;
|
||||
m_kgs_datao = m_kgs_datai = m_nmi_enable = 0;
|
||||
}
|
||||
|
||||
void robotron_k7071_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
Z80(config, m_cpu, XTAL(16'000'000) / 6);
|
||||
m_cpu->set_addrmap(AS_PROGRAM, &robotron_k7071_device::cpu_mem);
|
||||
m_cpu->set_addrmap(AS_IO, &robotron_k7071_device::cpu_pio);
|
||||
|
||||
I8257(config, m_dma, XTAL(16'000'000) / 6);
|
||||
m_dma->out_hrq_cb().set(FUNC(robotron_k7071_device::hrq_w));
|
||||
m_dma->in_memr_cb().set([this] (offs_t offset) { return m_program.read_byte(offset); });
|
||||
m_dma->out_iow_cb<0>().set(m_crtc, FUNC(i8275_device::dack_w));
|
||||
|
||||
I8275(config, m_crtc, XTAL(16'000'000) / 8);
|
||||
m_crtc->set_screen(m_screen);
|
||||
m_crtc->set_character_width(8);
|
||||
m_crtc->set_display_callback(FUNC(robotron_k7071_device::display_pixels));
|
||||
m_crtc->drq_wr_callback().set(m_dma, FUNC(i8257_device::dreq0_w));
|
||||
m_crtc->lc_wr_callback().set([this] (int data) { m_cpu->set_input_line(INPUT_LINE_IRQ0, data == 15 ? ASSERT_LINE : CLEAR_LINE); });
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_color(rgb_t::green());
|
||||
m_screen->set_raw(XTAL(16'000'000), 736, 0, 640, 432, 0, 416);
|
||||
m_screen->set_screen_update(m_crtc, FUNC(i8275_device::screen_update));
|
||||
|
||||
PALETTE(config, m_palette, palette_device::MONOCHROME_HIGHLIGHT);
|
||||
}
|
||||
|
||||
void robotron_k7071_device::cpu_mem(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
|
||||
map(0x0000, 0x0fff).rom().region("eprom", 0);
|
||||
map(0x1400, 0x1fff).ram().share("ram").mirror(0x8000);
|
||||
}
|
||||
|
||||
void robotron_k7071_device::cpu_pio(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map.global_mask(0xff);
|
||||
|
||||
map(0x00, 0x08).rw(m_dma, FUNC(i8257_device::read), FUNC(i8257_device::write));
|
||||
map(0x20, 0x21).rw(m_crtc, FUNC(i8275_device::read), FUNC(i8275_device::write));
|
||||
map(0x30, 0x30).noprw(); // chargen ram access
|
||||
map(0x40, 0x40).nopw(); // line counter input for sync generator
|
||||
map(0x50, 0x50).lw8(NAME([this] (u8 data) { m_kgs_ctrl |= KGS_ST_INT; int_w(7, ASSERT_LINE); }));
|
||||
map(0x60, 0x60).lw8(NAME([this] (u8 data) { m_kgs_ctrl |= KGS_ST_ERR; }));
|
||||
map(0x70, 0x71).rw(FUNC(robotron_k7071_device::kgs_host_r), FUNC(robotron_k7071_device::kgs_host_w));
|
||||
map(0x80, 0x80).lw8(NAME([this] (u8 data) { m_nmi_enable = BIT(data, 7); }));
|
||||
map(0xdf, 0xdf).nopw(); // used by IRQ handler
|
||||
}
|
||||
|
||||
uint16_t robotron_k7071_device::io_r(offs_t offset, uint16_t mem_mask)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
data = m_kgs_ctrl;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
data = m_kgs_datai;
|
||||
if (!machine().side_effects_disabled())
|
||||
m_kgs_ctrl &= ~KGS_ST_OBF;
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void robotron_k7071_device::io_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
m_kgs_ctrl &= ~(KGS_ST_ERR | KGS_ST_INT);
|
||||
int_w(7, CLEAR_LINE);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (m_kgs_ctrl & KGS_ST_IBF)
|
||||
{
|
||||
m_kgs_ctrl |= KGS_ST_ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_kgs_datao = data;
|
||||
m_kgs_ctrl |= KGS_ST_IBF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t robotron_k7071_device::kgs_host_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
data = m_kgs_ctrl;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
data = m_kgs_datao;
|
||||
if (!machine().side_effects_disabled())
|
||||
m_kgs_ctrl &= ~(KGS_ST_ERR | KGS_ST_IBF);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void robotron_k7071_device::kgs_host_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
m_kgs_datai = data;
|
||||
m_kgs_ctrl |= KGS_ST_OBF;
|
||||
}
|
||||
}
|
||||
|
||||
void robotron_k7071_device::hrq_w(int state)
|
||||
{
|
||||
// since our Z80 has no support for BUSACK, we assume it is granted immediately
|
||||
m_cpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state);
|
||||
m_cpu->set_input_line(INPUT_LINE_HALT, state); // do we need this?
|
||||
m_dma->hlda_w(state);
|
||||
}
|
||||
|
||||
I8275_DRAW_CHARACTER_MEMBER(robotron_k7071_device::display_pixels)
|
||||
{
|
||||
using namespace i8275_attributes;
|
||||
|
||||
rgb_t const *const palette = m_palette->palette()->entry_list_raw();
|
||||
u8 gfx = (BIT(attrcode, LTEN)) ? 0xff : 0;
|
||||
if (!BIT(attrcode, VSP))
|
||||
gfx = m_p_chargen[linecount | (charcode << 4)];
|
||||
|
||||
if (BIT(attrcode, RVV))
|
||||
gfx ^= 0xff;
|
||||
|
||||
for (u8 i = 0; i < 8; i++)
|
||||
bitmap.pix(y, x + i) = palette[BIT(gfx, 7-i) ? (BIT(attrcode, HLGT) ? 2 : 1) : 0];
|
||||
}
|
61
src/devices/bus/multibus/robotron_k7071.h
Normal file
61
src/devices/bus/multibus/robotron_k7071.h
Normal file
@ -0,0 +1,61 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
|
||||
#ifndef MAME_BUS_MULTIBUS_ROBOTRON_K7071_H
|
||||
#define MAME_BUS_MULTIBUS_ROBOTRON_K7071_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "multibus.h"
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/i8257.h"
|
||||
#include "video/i8275.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
class robotron_k7071_device
|
||||
: public device_t
|
||||
, public device_multibus_interface
|
||||
{
|
||||
public:
|
||||
robotron_k7071_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
|
||||
void cpu_mem(address_map &map);
|
||||
virtual void cpu_pio(address_map &map);
|
||||
|
||||
private:
|
||||
required_device<z80_device> m_cpu;
|
||||
required_device<i8257_device> m_dma;
|
||||
required_device<i8275_device> m_crtc;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_shared_ptr<u8> m_ram;
|
||||
required_region_ptr<u8> m_p_chargen;
|
||||
|
||||
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_program;
|
||||
|
||||
uint8_t m_kgs_datao, m_kgs_datai, m_kgs_ctrl;
|
||||
bool m_nmi_enable;
|
||||
|
||||
I8275_DRAW_CHARACTER_MEMBER(display_pixels);
|
||||
void hrq_w(int state);
|
||||
|
||||
uint8_t kgs_host_r(offs_t offset);
|
||||
void kgs_host_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint16_t io_r(offs_t offset, uint16_t mem_mask);
|
||||
void io_w(offs_t offset, uint16_t data, uint16_t mem_mask);
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(ROBOTRON_K7071, robotron_k7071_device)
|
||||
|
||||
#endif // MAME_BUS_MULTIBUS_ROBOTRON_K7071_H
|
@ -34,6 +34,7 @@ To do:
|
||||
|
||||
#include "bus/multibus/multibus.h"
|
||||
#include "bus/multibus/robotron_k7070.h"
|
||||
#include "bus/multibus/robotron_k7071.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "machine/i8087.h"
|
||||
@ -140,6 +141,7 @@ void a7150_state::machine_start()
|
||||
static void a7150_cards(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("kgs", ROBOTRON_K7070);
|
||||
device.option_add("abs", ROBOTRON_K7071);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user