summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame')
-rw-r--r--src/mame/drivers/p8k.cpp9
1 files changed, 5 insertions, 4 deletions
diff --git a/src/mame/drivers/p8k.cpp b/src/mame/drivers/p8k.cpp
index 2f959add48d..e6940f28eef 100644
--- a/src/mame/drivers/p8k.cpp
+++ b/src/mame/drivers/p8k.cpp
@@ -327,15 +327,16 @@ void p8k_state::init_p8k()
void p8k_state::p8k_16_memmap(address_map &map)
{
- map(0x00000, 0x03fff).rom();
- map(0x04000, 0x07fff).ram();
- map(0x08000, 0xfffff).ram();
+ map(0x00000, 0x03fff).rom().region("maincpu",0);
+ map(0x04000, 0x07fff).ram().share("share1");
+ map(0x08000, 0xfffff).ram().share("share2");
}
void p8k_state::p8k_16_datamap(address_map &map)
{
map(0x00000, 0x03fff).rom().region("maincpu",0);
- map(0x04000, 0x07fff).ram();
+ map(0x04000, 0x07fff).ram().share("share1");
+ map(0x08000, 0xfffff).ram().share("share2");
}
#8f5902; font-style: italic } /* Comment.Single */ .highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ .highlight .gd { color: #a40000 } /* Generic.Deleted */ .highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ .highlight .gr { color: #ef2929 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .highlight .gi { color: #00A000 } /* Generic.Inserted */ .highlight .go { color: #000000; font-style: italic } /* Generic.Output */ .highlight .gp { color: #8f5902 } /* Generic.Prompt */ .highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ .highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ .highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ .highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ .highlight .ld { color: #000000 } /* Literal.Date */ .highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */ .highlight .s { color: #4e9a06 } /* Literal.String */ .highlight .na { color: #c4a000 } /* Name.Attribute */ .highlight .nb { color: #204a87 } /* Name.Builtin */ .highlight .nc { color: #000000 } /* Name.Class */ .highlight .no { color: #000000 } /* Name.Constant */ .highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ .highlight .ni { color: #ce5c00 } /* Name.Entity */ .highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #000000 } /* Name.Function */ .highlight .nl { color: #f57900 } /* Name.Label */ .highlight .nn { color: #000000 } /* Name.Namespace */ .highlight .nx { color: #000000 } /* Name.Other */ .highlight .py { color: #000000 } /* Name.Property */ .highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #000000 } /* Name.Variable */ .highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */ .highlight .pm { color: #000000; font-weight: bold } /* Punctuation.Marker */ .highlight .w { color: #f8f8f8 } /* Text.Whitespace */ .highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ .highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ .highlight .sc { color: #4e9a06 } /* Literal.String.Char */ .highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ .highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ .highlight .se { color: #4e9a06 } /* Literal.String.Escape */ .highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ .highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ .highlight .sx { color: #4e9a06 } /* Literal.String.Other */ .highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ .highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ .highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ .highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #000000 } /* Name.Function.Magic */ .highlight .vc { color: #000000 } /* Name.Variable.Class */ .highlight .vg { color: #000000 } /* Name.Variable.Global */ .highlight .vi { color: #000000 } /* Name.Variable.Instance */ .highlight .vm { color: #000000 } /* Name.Variable.Magic */ .highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************

    Model Racing Dribbling hardware

*************************************************************************/

#include "machine/i8255.h"


class dribling_state : public driver_device
{
public:
	dribling_state(const machine_config &mconfig, device_type type, std::string tag)
		: driver_device(mconfig, type, tag),
		m_maincpu(*this, "maincpu"),
		m_ppi8255_0(*this, "ppi8255_0"),
		m_ppi8255_1(*this, "ppi8255_1"),
		m_videoram(*this, "videoram"),
		m_colorram(*this, "colorram"){ }

	/* devices */
	required_device<cpu_device> m_maincpu;
	optional_device<i8255_device>  m_ppi8255_0;
	optional_device<i8255_device>  m_ppi8255_1;
	/* memory pointers */
	required_shared_ptr<UINT8> m_videoram;
	required_shared_ptr<UINT8> m_colorram;

	/* misc */
	UINT8    m_abca;
	UINT8    m_dr;
	UINT8    m_ds;
	UINT8    m_sh;
	UINT8    m_input_mux;
	UINT8    m_di;

	DECLARE_READ8_MEMBER(ioread);
	DECLARE_WRITE8_MEMBER(iowrite);
	DECLARE_WRITE8_MEMBER(dribling_colorram_w);
	DECLARE_READ8_MEMBER(dsr_r);
	DECLARE_READ8_MEMBER(input_mux0_r);
	DECLARE_WRITE8_MEMBER(misc_w);
	DECLARE_WRITE8_MEMBER(sound_w);
	DECLARE_WRITE8_MEMBER(pb_w);
	DECLARE_WRITE8_MEMBER(shr_w);
	virtual void machine_start() override;
	virtual void machine_reset() override;
	DECLARE_PALETTE_INIT(dribling);
	UINT32 screen_update_dribling(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
	INTERRUPT_GEN_MEMBER(dribling_irq_gen);
};
60' href='#n460'>460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
// license:BSD-3-Clause
// copyright-holders:Sandro Ronco
/***************************************************************************

        IQ-151

        12/05/2009 Skeleton driver.

        07/June/2011 Added screen & keyboard (by looking at the Z80 code)


This computer depends on RAM just happening to be certain values at powerup.
If the conditions are not met, it may crash.

Monitor Commands:
C Call (address)
D Dump memory, any key to dump more, Return to finish
F Fill memory (start, end, withwhat)
G Goto (address)
L Cassette load
M Move (source start, source end, destination)
R Run
S Edit memory
W Cassette save (start, end, goto (0 for null))
X Display/Edit registers


ToDo:
- Add whatever devices may exist.

- Line 32 does not scroll, should it show?
  (could be reserved for a status line in a terminal mode)

- Note that the system checks for 3E at C000, if exist, jump to C000;
  otherwise then checks for non-FF at C800, if so, jumps to C800. Could be
  extra roms or some sort of boot device.

- Key beep sounds better if clock speed changed to 1MHz, but it is still
  highly annoying. Press Ctrl-G to hear the 2-tone bell.

- Cassette support is tested only in the emulator (monitor, BASIC and AMOS),
  needs to be tested with a real cassette dump.

****************************************************************************/

#include "emu.h"

#include "cpu/i8085/i8085.h"
#include "imagedev/cassette.h"
#include "machine/i8255.h"
#include "machine/pic8259.h"
#include "machine/timer.h"
#include "sound/spkrdev.h"

// cartridge slot
#include "bus/iq151/iq151.h"
#include "bus/iq151/rom.h"
#include "bus/iq151/disc2.h"
#include "bus/iq151/minigraf.h"
#include "bus/iq151/ms151a.h"
#include "bus/iq151/staper.h"
#include "bus/iq151/grafik.h"
#include "bus/iq151/video32.h"
#include "bus/iq151/video64.h"

#include "emupal.h"
#include "screen.h"
#include "softlist.h"
#include "speaker.h"


class iq151_state : public driver_device
{
public:
	iq151_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag)
		, m_maincpu(*this, "maincpu")
		, m_pic(*this, "pic8259")
		, m_speaker(*this, "speaker")
		, m_cassette(*this, "cassette")
		, m_carts(*this, "slot%u", 1U)
		, m_boot_bank(*this, "boot")
	{ }

	void iq151(machine_config &config);

	DECLARE_INPUT_CHANGED_MEMBER(iq151_break);

private:
	uint8_t keyboard_row_r();
	uint8_t keyboard_column_r();
	uint8_t ppi_portc_r();
	void ppi_portc_w(uint8_t data);
	void boot_bank_w(uint8_t data);
	uint8_t cartslot_r(offs_t offset);
	void cartslot_w(offs_t offset, uint8_t data);
	uint8_t cartslot_io_r(offs_t offset);
	void cartslot_io_w(offs_t offset, uint8_t data);
	virtual void machine_start() override;
	virtual void machine_reset() override;
	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);

	INTERRUPT_GEN_MEMBER(iq151_vblank_interrupt);
	TIMER_DEVICE_CALLBACK_MEMBER(cassette_timer);
	void iq151_io(address_map &map);
	void iq151_mem(address_map &map);

	required_device<i8080_cpu_device> m_maincpu;
	required_device<pic8259_device> m_pic;
	required_device<speaker_sound_device> m_speaker;
	required_device<cassette_image_device> m_cassette;
	required_device_array<iq151cart_slot_device, 5> m_carts;
	required_memory_bank m_boot_bank;

	uint8_t m_vblank_irq_state;
	uint8_t m_cassette_clk;
	uint8_t m_cassette_data;
};

uint8_t iq151_state::keyboard_row_r()
{
	char kbdrow[6];
	uint8_t data = 0xff;

	for (int i = 0; i < 8; i++)
	{
		sprintf(kbdrow,"X%X",i);
		data &= ioport(kbdrow)->read();
	}

	return data;
}

uint8_t iq151_state::keyboard_column_r()
{
	char kbdrow[6];
	uint8_t data = 0x00;

	for (int i = 0; i < 8; i++)
	{
		sprintf(kbdrow,"X%X",i);
		if (ioport(kbdrow)->read() == 0xff)
			data |= (1 << i);
	}

	return data;
}

uint8_t iq151_state::ppi_portc_r()
{
	uint8_t data = 0x00;

	if (m_cassette_data & 0x06)
	{
		// cassette read
		data |= ((m_cassette_clk & 1) << 5);
		data |= (m_cassette->input() > 0.00 ? 0x80 : 0x00);
	}
	else
	{
		// kb read
		data = ioport("X8")->read();
	}

	return (data & 0xf0) | (m_cassette_data & 0x0f);
}


void iq151_state::ppi_portc_w(uint8_t data)
{
	m_speaker->level_w(BIT(data, 3));
	m_cassette_data = data;
}

void iq151_state::boot_bank_w(uint8_t data)
{
	m_boot_bank->set_entry(data & 1);
}


//**************************************************************************
//  Cartridge slot emulation
//**************************************************************************

uint8_t iq151_state::cartslot_r(offs_t offset)
{
	uint8_t data = 0xff;

	for (auto & elem : m_carts)
		elem->read(offset, data);

	return data;
}

void iq151_state::cartslot_w(offs_t offset, uint8_t data)
{
	for (auto & elem : m_carts)
		elem->write(offset, data);
}

uint8_t iq151_state::cartslot_io_r(offs_t offset)
{
	uint8_t data = 0xff;

	for (auto & elem : m_carts)
		elem->io_read(offset, data);

	return data;
}

void iq151_state::cartslot_io_w(offs_t offset, uint8_t data)
{
	for (auto & elem : m_carts)
		elem->io_write(offset, data);
}

void iq151_state::iq151_mem(address_map &map)
{
	map.unmap_value_high();
	map(0x0000, 0xffff).rw(FUNC(iq151_state::cartslot_r), FUNC(iq151_state::cartslot_w));

	map(0x0000, 0x07ff).bankrw("boot");
	map(0x0800, 0x7fff).ram();
	map(0xf000, 0xffff).rom();
}

void iq151_state::iq151_io(address_map &map)
{
	map.unmap_value_high();
	map.global_mask(0xff);
	map(0x00, 0xff).rw(FUNC(iq151_state::cartslot_io_r), FUNC(iq151_state::cartslot_io_w));

	map(0x80, 0x80).w(FUNC(iq151_state::boot_bank_w));
	map(0x84, 0x87).rw("ppi8255", FUNC(i8255_device::read), FUNC(i8255_device::write));
	map(0x88, 0x89).rw(m_pic, FUNC(pic8259_device::read), FUNC(pic8259_device::write));
}


INPUT_CHANGED_MEMBER(iq151_state::iq151_break)
{
	m_pic->ir5_w(newval & 1);
}

/* Input ports */
static INPUT_PORTS_START( iq151 )
	PORT_START("X0")
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1)       PORT_CHAR('1') PORT_CHAR('!')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2)      PORT_CHAR('2') PORT_CHAR('"')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3)       PORT_CHAR('3') PORT_CHAR('#')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4)       PORT_CHAR('4') PORT_CHAR('$')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5)       PORT_CHAR('5') PORT_CHAR('%')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 &") PORT_CODE(KEYCODE_6)       PORT_CHAR('6') PORT_CHAR('&')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 '") PORT_CODE(KEYCODE_7)       PORT_CHAR('7') PORT_CHAR('\'')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 (") PORT_CODE(KEYCODE_8)       PORT_CHAR('8') PORT_CHAR('(')

	PORT_START("X1")
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q)     PORT_CHAR('Q') PORT_CHAR('q')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W)     PORT_CHAR('W') PORT_CHAR('w')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E)     PORT_CHAR('E') PORT_CHAR('e')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R)     PORT_CHAR('R') PORT_CHAR('r')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T)     PORT_CHAR('T') PORT_CHAR('t')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y)     PORT_CHAR('Y') PORT_CHAR('y')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U)     PORT_CHAR('U') PORT_CHAR('u')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I)     PORT_CHAR('I') PORT_CHAR('i')

	PORT_START("X2")
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A)     PORT_CHAR('A') PORT_CHAR('a')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S)     PORT_CHAR('S') PORT_CHAR('s')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D)     PORT_CHAR('D') PORT_CHAR('d')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F)     PORT_CHAR('F') PORT_CHAR('f')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G)     PORT_CHAR('G') PORT_CHAR('g')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H)     PORT_CHAR('H') PORT_CHAR('h')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J)     PORT_CHAR('J') PORT_CHAR('j')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K)     PORT_CHAR('K') PORT_CHAR('k')

	PORT_START("X3")
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z)     PORT_CHAR('Z') PORT_CHAR('z')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X)     PORT_CHAR('X') PORT_CHAR('x')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C)     PORT_CHAR('C') PORT_CHAR('c')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V)     PORT_CHAR('V') PORT_CHAR('v')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B)     PORT_CHAR('B') PORT_CHAR('b')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N)     PORT_CHAR('N') PORT_CHAR('n')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M)     PORT_CHAR('M') PORT_CHAR('m')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA)       PORT_CHAR(',') PORT_CHAR('<')

	PORT_START("X4")
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 )") PORT_CODE(KEYCODE_9)       PORT_CHAR('9') PORT_CHAR(')')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O)     PORT_CHAR('O') PORT_CHAR('o')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L)     PORT_CHAR('L') PORT_CHAR('l')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP)        PORT_CHAR('.') PORT_CHAR('>')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER)     PORT_CHAR(13)
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Del") PORT_CODE(KEYCODE_DEL)     PORT_CHAR(UCHAR_MAMEKEY(DEL))
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ins") PORT_CODE(KEYCODE_INSERT)      PORT_CHAR(UCHAR_MAMEKEY(INSERT))
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1)           PORT_CHAR(UCHAR_MAMEKEY(F1))

	PORT_START("X5")
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0)     PORT_CHAR('0')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P)     PORT_CHAR('P') PORT_CHAR('p')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("; +") PORT_CODE(KEYCODE_COLON)       PORT_CHAR(';') PORT_CHAR('+')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH)       PORT_CHAR('/') PORT_CHAR('?')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ |") PORT_CODE(KEYCODE_BACKSLASH)  PORT_CHAR('\\') PORT_CHAR('|')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DL") PORT_CODE(KEYCODE_F6)
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT)       PORT_CHAR(UCHAR_MAMEKEY(LEFT))
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2") PORT_CODE(KEYCODE_F2)           PORT_CHAR(UCHAR_MAMEKEY(F2))

	PORT_START("X6")
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("^ ~") PORT_CODE(KEYCODE_EQUALS)      PORT_CHAR('^') PORT_CHAR('~')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE)   PORT_CHAR('[') PORT_CHAR('{')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE)  PORT_CHAR(']') PORT_CHAR('}')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN)       PORT_CHAR(UCHAR_MAMEKEY(DOWN))
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5") PORT_CODE(KEYCODE_F5)           PORT_CHAR(UCHAR_MAMEKEY(F5))
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("IL") PORT_CODE(KEYCODE_F7)
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Home") PORT_CODE(KEYCODE_HOME)       PORT_CHAR(UCHAR_MAMEKEY(HOME))
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4") PORT_CODE(KEYCODE_F4)           PORT_CHAR(UCHAR_MAMEKEY(F4))

	PORT_START("X7")
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- =") PORT_CODE(KEYCODE_MINUS)       PORT_CHAR('-') PORT_CHAR('=')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@ `") PORT_CODE(KEYCODE_TILDE)       PORT_CHAR('@') PORT_CHAR('`')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(": *") PORT_CODE(KEYCODE_QUOTE)       PORT_CHAR(':') PORT_CHAR('*')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE)     PORT_CHAR(' ')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("_") PORT_CODE(KEYCODE_END) // its actually some sort of graphic character
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Up") PORT_CODE(KEYCODE_UP)       PORT_CHAR(UCHAR_MAMEKEY(UP))
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3") PORT_CODE(KEYCODE_F3)           PORT_CHAR(UCHAR_MAMEKEY(F3))

	PORT_START("X8")
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT)  PORT_CHAR(UCHAR_SHIFT_1)
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FA") PORT_CODE(KEYCODE_RSHIFT)       // Function A
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FB") PORT_CODE(KEYCODE_RCONTROL)     // Function B

	PORT_START("BREAK")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("BREAK") PORT_CODE(KEYCODE_ESC)   PORT_CHANGED_MEMBER(DEVICE_SELF, iq151_state, iq151_break, 0)  PORT_CHAR(UCHAR_MAMEKEY(ESC))
INPUT_PORTS_END


INTERRUPT_GEN_MEMBER(iq151_state::iq151_vblank_interrupt)
{
	m_pic->ir6_w(m_vblank_irq_state & 1);
	m_vblank_irq_state ^= 1;
}

TIMER_DEVICE_CALLBACK_MEMBER(iq151_state::cassette_timer)
{
	m_cassette_clk ^= 1;

	m_cassette->output((m_cassette_data & 1) ^ (m_cassette_clk & 1) ? +1 : -1);
}

void iq151_state::machine_start()
{
	uint8_t *RAM = memregion("maincpu")->base();
	m_boot_bank->configure_entry(0, RAM + 0xf800);
	m_boot_bank->configure_entry(1, RAM + 0x0000);
}

void iq151_state::machine_reset()
{
	m_boot_bank->set_entry(0);

	m_vblank_irq_state = 0;
}

// this machine don't have a built-in video controller, but uses external cartridge
uint32_t iq151_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	bitmap.fill(0, cliprect);

	for (auto & elem : m_carts)
		elem->video_update(bitmap, cliprect);

	return 0;
}

static void iq151_cart(device_slot_interface &device)
{
	device.option_add("video32",  IQ151_VIDEO32);       // video32
	device.option_add("video64",  IQ151_VIDEO64);       // video64
	device.option_add("grafik",   IQ151_GRAFIK);        // Grafik
	device.option_add("disc2",    IQ151_DISC2);         // Disc 2
	device.option_add("minigraf", IQ151_MINIGRAF);      // Aritma Minigraf 0507
	device.option_add("ms151a",   IQ151_MS151A);        // MS151A XY Plotter
	device.option_add("staper",   IQ151_STAPER);        // STAPER
	device.option_add("basic6",   IQ151_BASIC6);        // BASIC6
	device.option_add("basicg",   IQ151_BASICG);        // BASICG
	device.option_add("amos1",    IQ151_AMOS1);         // AMOS cart 1
	device.option_add("amos2",    IQ151_AMOS2);         // AMOS cart 2
	device.option_add("amos3",    IQ151_AMOS3);         // AMOS cart 3
}

void iq151_state::iq151(machine_config &config)
{
	/* basic machine hardware */
	I8080(config, m_maincpu, XTAL(2'000'000));
	m_maincpu->set_addrmap(AS_PROGRAM, &iq151_state::iq151_mem);
	m_maincpu->set_addrmap(AS_IO, &iq151_state::iq151_io);
	m_maincpu->set_vblank_int("screen", FUNC(iq151_state::iq151_vblank_interrupt));
	m_maincpu->in_inta_func().set("pic8259", FUNC(pic8259_device::acknowledge));

	/* video hardware */
	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER, rgb_t::green()));
	screen.set_refresh_hz(50);
	screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
	screen.set_screen_update(FUNC(iq151_state::screen_update));
	screen.set_size(64*8, 32*8);
	screen.set_visarea(0, 32*8-1, 0, 32*8-1);
	screen.set_palette("palette");

	PALETTE(config, "palette", palette_device::MONOCHROME);

	/* sound hardware */
	SPEAKER(config, "mono").front_center();
	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50);

	PIC8259(config, m_pic, 0);
	m_pic->out_int_callback().set_inputline(m_maincpu, 0);

	i8255_device &ppi(I8255(config, "ppi8255"));
	ppi.in_pa_callback().set(FUNC(iq151_state::keyboard_row_r));
	ppi.in_pb_callback().set(FUNC(iq151_state::keyboard_column_r));
	ppi.in_pc_callback().set(FUNC(iq151_state::ppi_portc_r));
	ppi.out_pc_callback().set(FUNC(iq151_state::ppi_portc_w));

	CASSETTE(config, m_cassette);
	m_cassette->set_default_state(CASSETTE_STOPPED);
	m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05);
	m_cassette->set_interface("iq151_cass");

	TIMER(config, "cassette_timer").configure_periodic(FUNC(iq151_state::cassette_timer), attotime::from_hz(2000));

	/* cartridge */
	IQ151CART_SLOT(config, m_carts[0], iq151_cart, nullptr);
	m_carts[0]->set_screen_tag("screen");
	m_carts[0]->out_irq0_callback().set(m_pic, FUNC(pic8259_device::ir0_w));
	m_carts[0]->out_irq1_callback().set(m_pic, FUNC(pic8259_device::ir1_w));
	m_carts[0]->out_irq2_callback().set(m_pic, FUNC(pic8259_device::ir2_w));
	m_carts[0]->out_irq3_callback().set(m_pic, FUNC(pic8259_device::ir3_w));
	m_carts[0]->out_irq4_callback().set(m_pic, FUNC(pic8259_device::ir4_w));
	IQ151CART_SLOT(config, m_carts[1], iq151_cart, nullptr);
	m_carts[1]->set_screen_tag("screen");
	m_carts[1]->out_irq0_callback().set(m_pic, FUNC(pic8259_device::ir0_w));
	m_carts[1]->out_irq1_callback().set(m_pic, FUNC(pic8259_device::ir1_w));
	m_carts[1]->out_irq2_callback().set(m_pic, FUNC(pic8259_device::ir2_w));
	m_carts[1]->out_irq3_callback().set(m_pic, FUNC(pic8259_device::ir3_w));
	m_carts[1]->out_irq4_callback().set(m_pic, FUNC(pic8259_device::ir4_w));
	IQ151CART_SLOT(config, m_carts[2], iq151_cart, nullptr);
	m_carts[2]->set_screen_tag("screen");
	m_carts[2]->out_irq0_callback().set(m_pic, FUNC(pic8259_device::ir0_w));
	m_carts[2]->out_irq1_callback().set(m_pic, FUNC(pic8259_device::ir1_w));
	m_carts[2]->out_irq2_callback().set(m_pic, FUNC(pic8259_device::ir2_w));
	m_carts[2]->out_irq3_callback().set(m_pic, FUNC(pic8259_device::ir3_w));
	m_carts[2]->out_irq4_callback().set(m_pic, FUNC(pic8259_device::ir4_w));
	IQ151CART_SLOT(config, m_carts[3], iq151_cart, nullptr);
	m_carts[3]->set_screen_tag("screen");
	m_carts[3]->out_irq0_callback().set(m_pic, FUNC(pic8259_device::ir0_w));
	m_carts[3]->out_irq1_callback().set(m_pic, FUNC(pic8259_device::ir1_w));
	m_carts[3]->out_irq2_callback().set(m_pic, FUNC(pic8259_device::ir2_w));
	m_carts[3]->out_irq3_callback().set(m_pic, FUNC(pic8259_device::ir3_w));
	m_carts[3]->out_irq4_callback().set(m_pic, FUNC(pic8259_device::ir4_w));
	IQ151CART_SLOT(config, m_carts[4], iq151_cart, "video32");
	m_carts[4]->set_screen_tag("screen");
	m_carts[4]->out_irq0_callback().set(m_pic, FUNC(pic8259_device::ir0_w));
	m_carts[4]->out_irq1_callback().set(m_pic, FUNC(pic8259_device::ir1_w));
	m_carts[4]->out_irq2_callback().set(m_pic, FUNC(pic8259_device::ir2_w));
	m_carts[4]->out_irq3_callback().set(m_pic, FUNC(pic8259_device::ir3_w));
	m_carts[4]->out_irq4_callback().set(m_pic, FUNC(pic8259_device::ir4_w));

	/* Software lists */
	SOFTWARE_LIST(config, "cart_list").set_original("iq151_cart");
	SOFTWARE_LIST(config, "flop_list").set_original("iq151_flop");
}

/* ROM definition */
ROM_START( iq151 )
	ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE )
	/* A number of bios versions here. The load address is shown for each */
	ROM_SYSTEM_BIOS( 0, "orig", "Original" )
	ROMX_LOAD( "iq151_monitor_orig.rom", 0xf000, 0x1000, CRC(acd10268) SHA1(4d75c73f155ed4dc2ac51a9c22232f869cca95e2), ROM_BIOS(0))
	ROM_SYSTEM_BIOS( 1, "disasm", "Disassembler" )
	ROMX_LOAD( "iq151_monitor_disasm.rom", 0xf000, 0x1000, CRC(45c2174e) SHA1(703e3271a124c3ef9330ae399308afd903316ab9), ROM_BIOS(1))
	ROM_SYSTEM_BIOS( 2, "cpm", "CPM" )
	ROMX_LOAD( "iq151_monitor_cpm.rom", 0xf000, 0x1000, CRC(26f57013) SHA1(4df396edc375dd2dd3c82c4d2affb4f5451066f1), ROM_BIOS(2))
	ROM_SYSTEM_BIOS( 3, "cpmold", "CPM (old)" )
	ROMX_LOAD( "iq151_monitor_cpm_old.rom", 0xf000, 0x1000, CRC(6743e1b7) SHA1(ae4f3b1ba2511a1f91c4e8afdfc0e5aeb0fb3a42), ROM_BIOS(3))
ROM_END

/* Driver */

//    YEAR  NAME   PARENT  COMPAT  MACHINE  INPUT  STATE        INIT        COMPANY         FULLNAME  FLAGS
COMP( 198?, iq151, 0,      0,      iq151,   iq151, iq151_state, empty_init, "ZPA Novy Bor", "IQ-151", 0 )