summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/alphatpx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/alphatpx.cpp')
-rw-r--r--src/mame/drivers/alphatpx.cpp473
1 files changed, 428 insertions, 45 deletions
diff --git a/src/mame/drivers/alphatpx.cpp b/src/mame/drivers/alphatpx.cpp
index 5c31f58cae0..c31480b3d96 100644
--- a/src/mame/drivers/alphatpx.cpp
+++ b/src/mame/drivers/alphatpx.cpp
@@ -1,11 +1,54 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
+// test / modify oct-2017 begin: rfka01 + helwie44
/***************************************************************************
Triumph-Adler Alphatronic Px series
TODO: Doesn't do much more than showing the initial boot message
-
+
+ The Px series was designed by SKS, like the ITT3030 and the SKS Nano,
+ the boards are closely related.
+
+ Keyboard and floppy stuff was copypasted from ITT3030 and adapted to the best of knowledge.
+
+P1, P2 and P2S: no paging
+Lower 16K for P1, P2 and P2 S
+
+0x0000 - 0x17ff ROM monitor (MOS)
+0x1800 - 0x1bff 1K RAM
+0x1c00 - 0x1fff reserved
+0x2000 - 0x2fff reserved, belonging to the video card's memory space (video ROM?)
+0x3000 - 0x3fff actual video memory
+
+P1
+Upper 32K
+0x4000 - 0x400a reserved
+0x4010 - 0xc000 32K RAM
+
+P2, P2S
+Upper 48K
+0x4000 - 0x400a reserved
+0x4010 - 0xfff 48K RAM
+
+P2 U, paging via
+An adapter with RAM at 0x0000 and 0x3fff and the banking logic (see above) is added to the the standard 48K memory card.
+16K memory card
+
+P3, P4
+0x0000 - 0x0fff ROM monitor (MOS)
+0x1000 - 0x17ff free
+0x1800 - 0x1bff monitor stack (RAM)
+0x1c00 - 0x2fff free
+0x3000 - 0x3fff video memory
+0x4000 - 0xffff RAM
+
+
+P2 U and P3 support regular CP/M use with a full 64K RAM complement.
+Still, the video RAM is at 0x3000 and 0x3ffff even for these machines, and from what I've read they also use the routine present in the ROM monitor, the MOS.
+That means, that in order to update the video RAM and probably other I/O the lower 16K (page 0) are constantly paged in and paged out.
+
+This is accomplished by writing 2FH to port 0x78 in order to switch in the ROM (and assorted, see below) area and by writing 63H to port 0x78 in order to swap the full 64K RAM back in.
***************************************************************************/
#include "emu.h"
@@ -28,25 +71,60 @@ class alphatpx_state : public driver_device
{
public:
alphatpx_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_bankdev(*this, "bankdev"),
- m_palette(*this, "palette"),
- m_vram(*this, "vram"),
- m_gfx(*this, "gfx")
+ driver_device(mconfig, type, tag),
+ m_bankdev(*this, "bankdev"),
+ m_kbdmcu(*this, "kbdmcu"),
+ m_crtc(*this, "crtc"),
+ m_fdc (*this, "fdc"),
+ m_floppy0(*this, "fdc:0"),
+ m_floppy1(*this, "fdc:1"),
+ m_keycols(*this, "COL.%u", 0),
+ m_palette(*this, "palette"),
+ m_vram(*this, "vram"),
+ m_gfx(*this, "gfx"),
+ m_ram(*this, "ram")
+
{ }
- uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+public:
+ DECLARE_READ_LINE_MEMBER(kbd_matrix_r);
+ DECLARE_WRITE8_MEMBER(kbd_matrix_w);
+ DECLARE_READ8_MEMBER(kbd_port2_r);
+ DECLARE_WRITE8_MEMBER(kbd_port2_w);
+
+ DECLARE_READ8_MEMBER(fdc_r);
+ DECLARE_WRITE8_MEMBER(fdc_w);
+ DECLARE_READ8_MEMBER(fdc_stat_r);
+ DECLARE_WRITE8_MEMBER(fdc_cmd_w);
+
+ DECLARE_WRITE_LINE_MEMBER(fdcirq_w);
+ DECLARE_WRITE_LINE_MEMBER(fdcdrq_w);
+ DECLARE_WRITE_LINE_MEMBER(fdchld_w);
+ DECLARE_WRITE8_MEMBER(bank_w);
protected:
virtual void machine_start() override;
+ virtual void machine_reset() override;
+ required_device<address_map_bank_device> m_bankdev;
+ required_device<i8041_device> m_kbdmcu;
+ required_device<crt5037_device> m_crtc;
+ required_device<fd1791_device> m_fdc;
+ required_device<floppy_connector> m_floppy0;
+ required_device<floppy_connector> m_floppy1;
+ required_ioport_array<16> m_keycols;
private:
- required_device<address_map_bank_device> m_bankdev;
+
+ uint8_t m_kbdclk, m_kbdread, m_kbdport2, m_kbdrow, m_kbdcol;
required_device<palette_device> m_palette;
- required_shared_ptr<uint8_t> m_vram;
+ required_shared_ptr<u8> m_vram;
required_region_ptr<u8> m_gfx;
-
- std::unique_ptr<uint8_t[]> m_ram;
+ required_shared_ptr<u8> m_ram;
+ floppy_image_device *m_curfloppy;
+ bool m_fdc_irq, m_fdc_drq, m_fdc_hld;
+ floppy_connector *m_con1, *m_con2;
+
};
@@ -59,26 +137,187 @@ static ADDRESS_MAP_START( alphatp3_mem, AS_PROGRAM, 8, alphatpx_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START( alphatp3_map, AS_PROGRAM, 8, alphatpx_state )
- AM_RANGE(0x00000, 0x00fff) AM_READ_BANK("rom") AM_WRITE_BANK("ram_0000")
- AM_RANGE(0x01000, 0x02fff) AM_RAMBANK("ram_1000")
- AM_RANGE(0x03000, 0x037ef) AM_MIRROR(0x800) AM_RAM AM_SHARE("vram")
- AM_RANGE(0x037f0, 0x037ff) AM_MIRROR(0x800) AM_DEVREADWRITE("crtc", crt5037_device, read, write)
- AM_RANGE(0x04000, 0x0ffff) AM_RAMBANK("ram_4000")
- AM_RANGE(0x10000, 0x1ffff) AM_RAMBANK("ram")
+ AM_RANGE(0x00000, 0x017ff) AM_ROM AM_REGION("boot", 0) // P2 0x0000 , 0x17ff -hw 6kB, P3 only 4 kB
+ AM_RANGE(0x01800, 0x01c00) AM_RAM // boot rom variables
+ AM_RANGE(0x03000, 0x03bff) AM_WRITEONLY AM_SHARE("vram") // test 2017 hw, MOS directly writes to display RAM
+ AM_RANGE(0x03FF0, 0x03fff) AM_DEVWRITE("crtc", crt5037_device, write) //test hw, mem-mapped registers, cursor position can be determined through this range
+ AM_RANGE(0x00000, 0x0ffff) AM_RAMBANK("ram_0000")
+
+ AM_RANGE(0x10000, 0x1ffff) AM_RAM AM_SHARE("ram")
ADDRESS_MAP_END
static ADDRESS_MAP_START( alphatp3_io, AS_IO, 8, alphatpx_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x04, 0x04) AM_DEVREADWRITE("uart", i8251_device, data_r, data_w)
AM_RANGE(0x05, 0x05) AM_DEVREADWRITE("uart", i8251_device, status_r, control_w)
+ AM_RANGE(0x10, 0x11) AM_DEVREADWRITE("kbdmcu", i8041_device, upi41_master_r, upi41_master_w)
+ AM_RANGE(0x50, 0x53) AM_READWRITE(fdc_r, fdc_w)
+ AM_RANGE(0x54, 0x54) AM_READWRITE(fdc_stat_r, fdc_cmd_w)
+ AM_RANGE(0x78, 0x78) AM_WRITE(bank_w)
ADDRESS_MAP_END
+WRITE8_MEMBER(alphatpx_state::bank_w)
+{
+ m_bankdev->set_bank(BIT(data, 6));
+}
//**************************************************************************
// INPUTS
//**************************************************************************
-INPUT_PORTS_START( alphatp3 )
+READ_LINE_MEMBER(alphatpx_state::kbd_matrix_r)
+{
+ return m_kbdread;
+}
+
+WRITE8_MEMBER(alphatpx_state::kbd_matrix_w)
+{
+ int rd_masks[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 };
+ int tmp_read;
+
+ // printf("matrix_w: %02x (col %d row %d clk %d)\n", data, m_kbdcol, m_kbdrow, (data & 0x80) ? 1 : 0);
+
+ if ((data & 0x80) && (!m_kbdclk))
+ {
+ tmp_read = m_keycols[(data >> 3) & 0xf]->read() & rd_masks[data & 0x7];
+ m_kbdread = (tmp_read != 0) ? 1 : 0;
+ }
+
+ m_kbdclk = (data & 0x80) ? 1 : 0;
+
+}
+
+// bit 2 is UPI-41 host IRQ to Z80
+WRITE8_MEMBER(alphatpx_state::kbd_port2_w)
+{
+ m_kbdport2 = data;
+
+}
+
+READ8_MEMBER(alphatpx_state::kbd_port2_r)
+{
+ return m_kbdport2;
+}
+
+// translation table at offset 0xdc0 in the main rom
+static INPUT_PORTS_START( alphatp3 )
+ PORT_START("COL.0")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0xc4
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
+ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
+
+ PORT_START("COL.1")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
+ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x8a
+
+ PORT_START("COL.2")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x82
+ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x8c
+
+ PORT_START("COL.3")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('@')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x8b
+ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
+
+ PORT_START("COL.4")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
+ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0xc0
+
+ PORT_START("COL.5")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('5') PORT_CHAR('%')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x89
+ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
+
+ PORT_START("COL.6")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('k')
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';')
+ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR('<') PORT_CHAR('>')
+
+ PORT_START("COL.7")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('/')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR(':')
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x8f
+ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0xc1
+
+ PORT_START("COL.8")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|')
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x84
+ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
+
+ PORT_START("COL.9")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{')
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0xc1
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD))
+
+ PORT_START("COL.10")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('=')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('+') PORT_CHAR('*')
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('#') PORT_CHAR('^')
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x7f
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD))
+
+ PORT_START("COL.11")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('~') PORT_CHAR('?')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_MAMEKEY(TAB))
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD))
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD))
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD))
+
+ PORT_START("COL.12")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('`')
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD))
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD))
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD))
+
+ PORT_START("COL.13")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x93
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD))
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD))
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK))
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0xc2
+
+ PORT_START("COL.14")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x92
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD))
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD))
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD))
+
+ PORT_START("COL.15")
+ PORT_BIT(0x0000, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x91
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD))
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD))
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD))
+ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x90
+
INPUT_PORTS_END
@@ -113,18 +352,17 @@ GFXDECODE_END
uint32_t alphatpx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
const pen_t *pen = m_palette->pens();
-
+ int start = m_crtc->upscroll_offset();
for (int y = 0; y < 24; y++)
{
+ int vramy = (start + y) % 24;
for (int x = 0; x < 80; x++)
{
- uint8_t code = m_vram[(y * 24) + x] & 0x7f;
-
+ uint8_t code = m_vram[(vramy * 128) + x]; // helwie44 must be 128d is 080h physical display-ram step line
// draw 12 lines of the character
for (int line = 0; line < 12; line++)
{
- uint8_t data = m_gfx[(code * 16) + line];
-
+ uint8_t data = m_gfx[((code & 0x7f) * 16) + line];
bitmap.pix32(y * 12 + line, x * 8 + 0) = pen[BIT(data, 0) ^ BIT(code, 7)];
bitmap.pix32(y * 12 + line, x * 8 + 1) = pen[BIT(data, 1) ^ BIT(code, 7)];
bitmap.pix32(y * 12 + line, x * 8 + 2) = pen[BIT(data, 2) ^ BIT(code, 7)];
@@ -147,6 +385,103 @@ uint32_t alphatpx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitm
// Beeper
+// FLOPPY
+WRITE_LINE_MEMBER(alphatpx_state::fdcirq_w)
+{
+ m_fdc_irq = state;
+}
+
+#include "debugger.h"
+
+WRITE_LINE_MEMBER(alphatpx_state::fdcdrq_w)
+{
+ m_fdc_drq = state;
+}
+
+WRITE_LINE_MEMBER(alphatpx_state::fdchld_w)
+{
+ m_fdc_hld = state;
+}
+
+/*
+ 7 Data Request (DRQ - inverted 1791-Signal)
+ 6 Interrupt Request (INTRQ - 1791-Signal)
+ 5 Head Load (HLD - inverted 1791-Signal)
+ 4 Ready 3 (Drive 3 ready)
+ 3 Ready 2 (Drive 2 ready)
+ 2 Ready l (Drive 1 ready)
+ 1 Write protect (the disk in the selected drive is write protected)
+ 0 HLT (Halt signal during head load and track change)
+*/
+READ8_MEMBER(alphatpx_state::fdc_stat_r)
+{
+ uint8_t res = 0;
+ floppy_image_device *floppy1 = m_con1 ? m_con1->get_device() : nullptr;
+ floppy_image_device *floppy2 = m_con2 ? m_con2->get_device() : nullptr;
+
+ res = m_fdc_drq ? 0x80 : 0x00;
+ res |= m_fdc_irq ? 0x40 : 0x00;
+ res |= m_fdc_hld ? 0x00 : 0x20;
+ if (floppy2) res |= floppy2->ready_r() ? 0x08 : 0;
+ if (floppy1) res |= floppy1->ready_r() ? 0x04 : 0;
+ if (m_curfloppy) res |= m_curfloppy->wpt_r() ? 0x02 : 0;
+
+ return res;
+}
+
+/* As far as we can tell, the mess of ttl de-inverts the bus */
+READ8_MEMBER(alphatpx_state::fdc_r)
+{
+ return m_fdc->gen_r(offset) ^ 0xff;
+}
+
+WRITE8_MEMBER(alphatpx_state::fdc_w)
+{
+ m_fdc->gen_w(offset, data ^ 0xff);
+}
+
+/*
+ 7 SEL1 - Select drive 1
+ 6 SEL2 - Select drive 2
+ 5 SEL3 - Select drive 3
+ 4 MOTOR - Motor on
+ 3 DOOR - Drive door lock drives 1 + 2 (not possible with all drives)
+ 2 SIDESEL - Select disk side
+ 1 KOMP - write comp on/off
+ 0 RG J - Change separator stage to read
+*/
+WRITE8_MEMBER(alphatpx_state::fdc_cmd_w)
+{
+ floppy_image_device *floppy = nullptr;
+
+ logerror("%02x to fdc_cmd_w: motor %d side %d\n", data, (data & 0x10)>>4, (data & 4)>>2);
+
+ // select drive
+ if (!(data & 0x80))
+ {
+ floppy = m_con1 ? m_con1->get_device() : nullptr;
+ }
+ else if (!(data & 0x40))
+ {
+ floppy = m_con2 ? m_con2->get_device() : nullptr;
+ }
+
+ // selecting a new drive?
+ if (floppy != m_curfloppy)
+ {
+ m_fdc->set_floppy(floppy);
+ m_curfloppy = floppy;
+ }
+
+ if (floppy != nullptr)
+ {
+ // side select
+ floppy->ss_w((data & 4) ? 0 : 1);
+
+ // motor control (active low)
+ floppy->mon_w((data & 0x10) ? 1 : 0);
+ }
+}
//**************************************************************************
// MACHINE
@@ -154,20 +489,23 @@ uint32_t alphatpx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitm
void alphatpx_state::machine_start()
{
- // allocate memory
- m_ram = std::make_unique<uint8_t[]>(0x10000);
-
// setup banking
- membank("rom")->set_base(memregion("boot")->base());
- membank("ram_0000")->set_base(m_ram.get() + 0x0000);
- membank("ram_1000")->set_base(m_ram.get() + 0x1000);
- membank("ram_4000")->set_base(m_ram.get() + 0x4000);
- membank("ram")->set_base(m_ram.get());
-
- // register for save states
- save_pointer(NAME(m_ram.get()), 0x10000);
+ membank("ram_0000")->set_base(m_ram.target());
+
+
+ m_kbdclk = 0; // must be initialized here b/c mcs48_reset() causes write of 0xff to all ports
}
+void alphatpx_state::machine_reset()
+{
+ m_kbdread = 1;
+ m_kbdclk = 1; m_fdc_irq = m_fdc_drq = m_fdc_hld = 0;
+ m_curfloppy = nullptr;
+
+ // look up floppies in advance
+ m_con1 = machine().device<floppy_connector>("fdc:0");
+ m_con2 = machine().device<floppy_connector>("fdc:1");
+}
//**************************************************************************
// MACHINE DEFINITIONS
@@ -178,14 +516,17 @@ static MACHINE_CONFIG_START( alphatp3 )
MCFG_CPU_PROGRAM_MAP(alphatp3_mem)
MCFG_CPU_IO_MAP(alphatp3_io)
- MCFG_CPU_ADD("mcu", I8041, XTAL_6MHz)
- MCFG_DEVICE_DISABLE()
+ MCFG_CPU_ADD("kbdmcu", I8041, XTAL_12_8544MHz/2)
+ MCFG_MCS48_PORT_T0_IN_CB(READLINE(alphatpx_state, kbd_matrix_r))
+ MCFG_MCS48_PORT_P1_OUT_CB(WRITE8(alphatpx_state, kbd_matrix_w))
+ MCFG_MCS48_PORT_P2_IN_CB(READ8(alphatpx_state, kbd_port2_r))
+ MCFG_MCS48_PORT_P2_OUT_CB(WRITE8(alphatpx_state, kbd_port2_w))
MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(alphatp3_map)
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8)
- MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(17)
+ MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000)
// video hardware
@@ -197,6 +538,7 @@ static MACHINE_CONFIG_START( alphatp3 )
MCFG_DEVICE_ADD("crtc", CRT5037, XTAL_12_8544MHz)
MCFG_TMS9927_CHAR_WIDTH(8)
+
MCFG_TMS9927_VSYN_CALLBACK(INPUTLINE("maincpu", I8085_RST65_LINE)) MCFG_DEVCB_XOR(1)
MCFG_VIDEO_SET_SCREEN("screen")
@@ -210,7 +552,10 @@ static MACHINE_CONFIG_START( alphatp3 )
MCFG_DEVICE_ADD("uart", I8251, 0)
// XTAL_4_9152MHz serial clock
- MCFG_FD1791_ADD("fdc", XTAL_4MHz / 2)
+ MCFG_FD1791_ADD("fdc", XTAL_4MHz / 4)
+ MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(alphatpx_state, fdcirq_w))
+ MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(alphatpx_state, fdcdrq_w))
+ MCFG_WD_FDC_HLD_CALLBACK(WRITELINE(alphatpx_state, fdchld_w))
MCFG_FLOPPY_DRIVE_ADD("fdc:0", alphatp3_floppies, "525qd", floppy_image_device::default_floppy_formats)
MCFG_FLOPPY_DRIVE_ADD("fdc:1", alphatp3_floppies, "525qd", floppy_image_device::default_floppy_formats)
MACHINE_CONFIG_END
@@ -220,21 +565,59 @@ MACHINE_CONFIG_END
// ROM DEFINITIONS
//**************************************************************************
+// Alphatronic P2
+ROM_START( alphatp2 ) // P2 ROM space 0x1800
+ ROM_REGION(0x1800, "boot", 0)
+ ROM_SYSTEM_BIOS(0, "p2_es", "p2_es")
+ ROMX_LOAD("caap_p2_es.bin", 0x0000, 0x1800, CRC(FBA85CD3) SHA1(E82482AF6D39F892B88868677572898945E02581), ROM_BIOS(1) ) // P2 SPANIEN
+ ROM_SYSTEM_BIOS(1, "p2_sks", "p2_sks")
+ ROMX_LOAD("mos3-p2_sks.bin", 0x0000, 0x1800, CRC(C045AADB) SHA1(1478530894E1DA53CC96DDB765DD1E03FF3ADEF1), ROM_BIOS(2) ) // P2 sks
+ ROM_SYSTEM_BIOS(2, "p2_ta", "p2_ta")
+ ROMX_LOAD("prom2p00.bin", 0x0000, 0x0800, CRC(c98d2982) SHA1(11e98ae441b7a9c8dfd22795f8208667959f1d1c), ROM_BIOS(3) ) // P2 TA
+ ROMX_LOAD("prom2p01.bin", 0x0800, 0x0800, CRC(14f19693) SHA1(7ecb66818a3e352fede1857a18cd12bf742603a9), ROM_BIOS(3) )
+ ROMX_LOAD("prom2p02.bin", 0x1000, 0x0800, CRC(f304c3aa) SHA1(92213e77e4e6de12a4eaee25a9c1ec0ab54e93d4), ROM_BIOS(3) )
+
+ ROM_REGION(0x400, "kbdmcu", 0)
+ ROM_LOAD("p3_keyboard_8278.bin", 0x000, 0x400, CRC(5DB00D85) SHA1(0DC8E274A5AECE261EF60494901601C0D8B1EB51)) // borrowed from rfka01 machine #2 until we have a proper dump from a P2
+
+ ROM_REGION(0x800, "gfx", 0)
+ ROM_LOAD("cajp08_01_15.bin", 0x000, 0x800, CRC(4ed11dac) SHA1(9db9b8e0edf471faaddbb5521d6223121146bab8)) // borrowed from rfka01 machine #1 until we have a proper dump from a P2
+ROM_END
+
+// Alphatronic P3
ROM_START( alphatp3 )
- ROM_REGION(0x1000, "boot", 0)
- ROM_LOAD("caap36_02_19.bin", 0x0000, 0x1000, CRC(23df6666) SHA1(5ea04cd299dec9951425eb91ecceb4818c4c6378))
+ ROM_REGION(0x1800, "boot", 0) // P3 ROM space 0x1000
+ ROM_LOAD("caap36_02_19.bin", 0x0000, 0x1000, CRC(23df6666) SHA1(5ea04cd299dec9951425eb91ecceb4818c4c6378)) // identical between rfka01 #1 and #2
- ROM_REGION(0x400, "mcu", 0)
- ROM_LOAD("p3_8041.bin", 0x000, 0x400, NO_DUMP)
+ ROM_REGION(0x400, "kbdmcu", 0)
+// ROM_LOAD("p3_keyboard_mab8041a.bin", 0x000, 0x400, CRC(4fd60dc1) SHA1(165f0c5afdef37385d06cf5caeae8422536de7fc)) // rfka01 machine #1
+ ROM_LOAD("p3_keyboard_8278.bin", 0x000, 0x400, CRC(5DB00D85) SHA1(0DC8E274A5AECE261EF60494901601C0D8B1EB51)) // rfka01 machine #2
ROM_REGION(0x800, "gfx", 0)
- ROM_LOAD("cajp08_01_15.bin", 0x000, 0x800, CRC(4ed11dac) SHA1(9db9b8e0edf471faaddbb5521d6223121146bab8))
+ // ROM_LOAD("cajp08_00_15.bin", 0x000, 0x800, CRC(d6248209) SHA1(21689703de7183ecffb410eb8a6d516efe27da9d)) // rfka01 machine #2
+ ROM_LOAD("cajp08_01_15.bin", 0x000, 0x800, CRC(4ed11dac) SHA1(9db9b8e0edf471faaddbb5521d6223121146bab8)) // rfka01 machine #1
ROM_END
+// Alphatronic P30
+ROM_START( alphatp30 ) // P30 add-on card with 8088 needs to be emulated to boot DOS
+ ROM_REGION(0x1800, "boot", 0)
+ ROM_LOAD("hasl17.07.84.bin", 0x0000, 0x1000, CRC(6A91701B) SHA1(8A4F925D0FABAB37852A54D04E06DEB2AEAA349C)) // netmercer EPRom P30 ...wait for INT6.5 or INT5.5 with RIM to write char in hsync or hsync GAP-time !!
+
+ ROM_REGION(0x400, "kbdmcu", 0)
+ ROM_LOAD("p3_keyboard_8278.bin", 0x000, 0x400, CRC(5DB00D85) SHA1(0DC8E274A5AECE261EF60494901601C0D8B1EB51)) // borrowed from rfka01 machine #2
+
+ ROM_REGION(0x800, "gfx", 0)
+ ROM_LOAD("cajp08_01_15.bin", 0x000, 0x800, CRC(4ed11dac) SHA1(9db9b8e0edf471faaddbb5521d6223121146bab8)) // borrowed from rfka01 machine #1
+
+// ROM_LOAD("p30_8088.bin", 0x000, 0x4000, CRC(e6bf6dd5) SHA1(dc87210bbcd96f3c1370565174a45199e3c1bc70)) // P30 ROM from 8088 card
+ROM_END
+
//**************************************************************************
// SYSTEM DRIVERS
//**************************************************************************
-// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
-COMP( 1982, alphatp3, 0, 0, alphatp3, alphatp3, alphatpx_state, 0, "Triumph-Adler", "alphatronic P3", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
+// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
+COMP( 198?, alphatp2, alphatp3, 0, alphatp3, alphatp3, alphatpx_state, 0, "Triumph-Adler", "alphatronic P2", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
+COMP( 1982, alphatp3, 0, 0, alphatp3, alphatp3, alphatpx_state, 0, "Triumph-Adler", "alphatronic P3", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
+COMP( 198?, alphatp30, alphatp3, 0, alphatp3, alphatp3, alphatpx_state, 0, "Triumph-Adler", "alphatronic P30",MACHINE_NOT_WORKING | MACHINE_NO_SOUND )