summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/drivers/mycom.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/drivers/mycom.c')
-rw-r--r--src/mess/drivers/mycom.c633
1 files changed, 633 insertions, 0 deletions
diff --git a/src/mess/drivers/mycom.c b/src/mess/drivers/mycom.c
new file mode 100644
index 00000000000..df15c075c7f
--- /dev/null
+++ b/src/mess/drivers/mycom.c
@@ -0,0 +1,633 @@
+/******************************************************************************
+
+ MYCOMZ-80A (c) 1981 Japan Electronics College
+
+ preliminary driver by Angelo Salese
+ additions by Robbbert
+
+ THE KEYBOARD
+ - Uses a 4MO1003A custom mcu.
+ - Every combination is documented in the manual, including the unused ones.
+ - All commands must be in uppercase - lowercase will produce errors.
+ - There are 5 special keys which do crude editing functions. These are in
+ the range 0x61 to 0x75. Kana characters occupy the range 0xa0 to 0xff.
+ Graphics characters are found in 0x00 to 0x1f, and 0x80 to 0x9f.
+ - Editing characters (hold down shift to get them):
+ a - shiftlock (toggle). You can then enter any lowercase character.
+ c - clear screen and home cursor
+ d - insert
+ f - vertical tab (cursor up) You can scroll backwards with this,
+ and you can reuse old input lines.
+ u - cursor right
+ - There are switches on the right-hand side which are connected directly
+ to one of the PIAs. The switches (not emulated):
+ s2 - ?unknown
+ s3 - ?unknown but must be high for the keyboard to function
+ s4 - cassette motor on/off
+ s5 - ?unknown
+ - There is also switch s1 which it is not known what it connects to.
+ - Please note: The Takeda 80-column monitor expects the enter key to be the
+ line feed key. This is the numpad-enter in our emulation. Strangely, the
+ standard monitor, and Basic, will also respond to this key.
+ - The keyboard has a "English" key on the left, and a "Japan" key on the
+ right. Pressing the appropriate key toggles the input language mode.
+ Internally, this turns the Kana bit off/on. On our keyboard, the ALT key
+ toggles between English and Kana.
+
+ TODO/info:
+ - Sound not working. The info makes its way to the audio chip but for
+ some unknown reason, nothing is heard.
+ - FDC, type 1771, single sided, capacity 143KBytes, not connected up
+ - Cassette doesn't load
+ - Printer
+ - Keyboard lookup table for Kana and Shifted Kana
+ - Keyboard autorepeat
+
+*******************************************************************************/
+
+#include "emu.h"
+#include "cpu/z80/z80.h"
+#include "video/mc6845.h"
+#include "machine/i8255.h"
+#include "sound/sn76496.h"
+#include "imagedev/cassette.h"
+#include "sound/wave.h"
+#include "machine/wd17xx.h"
+#include "machine/msm5832.h"
+#include "imagedev/flopdrv.h"
+#include "formats/basicdsk.h"
+
+#define MACHINE_RESET_MEMBER(name) void name::machine_reset()
+#define MACHINE_START_MEMBER(name) void name::machine_start()
+#define VIDEO_START_MEMBER(name) void name::video_start()
+#define MSM5832RS_TAG "rtc"
+
+class mycom_state : public driver_device
+{
+public:
+ mycom_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_ppi0(*this, "ppi8255_0"),
+ m_ppi1(*this, "ppi8255_1"),
+ m_ppi2(*this, "ppi8255_2"),
+ m_cass(*this, CASSETTE_TAG),
+ m_wave(*this, WAVE_TAG),
+ m_crtc(*this, "crtc"),
+ m_fdc(*this, "fdc"),
+ m_audio(*this, "sn1"),
+ m_rtc(*this, MSM5832RS_TAG)
+ { }
+
+ required_device<cpu_device> m_maincpu;
+ required_device<i8255_device> m_ppi0;
+ required_device<i8255_device> m_ppi1;
+ required_device<i8255_device> m_ppi2;
+ required_device<cassette_image_device> m_cass;
+ required_device<device_t> m_wave;
+ required_device<mc6845_device> m_crtc;
+ required_device<device_t> m_fdc;
+ required_device<device_t> m_audio;
+ required_device<msm5832_device> m_rtc;
+ DECLARE_READ8_MEMBER( mycom_upper_r );
+ DECLARE_WRITE8_MEMBER( mycom_upper_w );
+ DECLARE_READ8_MEMBER( vram_data_r );
+ DECLARE_WRITE8_MEMBER( vram_data_w );
+ DECLARE_WRITE8_MEMBER( mycom_00_w );
+ DECLARE_WRITE8_MEMBER( mycom_04_w );
+ DECLARE_WRITE8_MEMBER( mycom_06_w );
+ DECLARE_WRITE8_MEMBER( mycom_0a_w );
+ DECLARE_READ8_MEMBER( mycom_05_r );
+ DECLARE_READ8_MEMBER( mycom_06_r );
+ DECLARE_READ8_MEMBER( mycom_08_r );
+ UINT8 *m_p_videoram;
+ UINT8 *m_p_chargen;
+ UINT16 m_i_videoram;
+ UINT8 m_keyb_press;
+ UINT8 m_keyb_press_flag;
+ UINT8 m_0a;
+ UINT8 m_sn_we;
+ UINT32 m_upper_sw;
+ UINT8 *m_p_ram;
+ virtual void machine_reset();
+ virtual void machine_start();
+ virtual void video_start();
+ DECLARE_DRIVER_INIT(mycom);
+};
+
+
+
+VIDEO_START_MEMBER( mycom_state )
+{
+ m_p_videoram = memregion("vram")->base();
+ m_p_chargen = memregion("chargen")->base();
+}
+
+static MC6845_UPDATE_ROW( mycom_update_row )
+{
+ mycom_state *state = device->machine().driver_data<mycom_state>();
+ const rgb_t *palette = palette_entry_list_raw(bitmap.palette());
+ UINT8 chr,gfx=0,z;
+ UINT16 mem,x;
+ UINT32 *p = &bitmap.pix32(y);
+
+ if (state->m_0a & 0x40)
+ {
+ for (x = 0; x < x_count; x++) // lores pixels
+ {
+ UINT8 dbit=1;
+ if (x == cursor_x) dbit=0;
+ mem = (ma + x) & 0x7ff;
+ chr = state->m_p_videoram[mem];
+ z = ra / 3;
+ *p++ = palette[BIT( chr, z ) ? dbit: dbit^1];
+ *p++ = palette[BIT( chr, z ) ? dbit: dbit^1];
+ *p++ = palette[BIT( chr, z ) ? dbit: dbit^1];
+ *p++ = palette[BIT( chr, z ) ? dbit: dbit^1];
+ z += 4;
+ *p++ = palette[BIT( chr, z ) ? dbit: dbit^1];
+ *p++ = palette[BIT( chr, z ) ? dbit: dbit^1];
+ *p++ = palette[BIT( chr, z ) ? dbit: dbit^1];
+ *p++ = palette[BIT( chr, z ) ? dbit: dbit^1];
+ }
+ }
+ else
+ {
+ for (x = 0; x < x_count; x++) // text
+ {
+ UINT8 inv=0;
+ if (x == cursor_x) inv=0xff;
+ mem = (ma + x) & 0x7ff;
+ if (ra > 7)
+ gfx = inv; // some blank spacing lines
+ else
+ {
+ chr = state->m_p_videoram[mem];
+ gfx = state->m_p_chargen[(chr<<3) | ra] ^ inv;
+ }
+
+ /* Display a scanline of a character */
+ *p++ = palette[BIT(gfx, 7)];
+ *p++ = palette[BIT(gfx, 6)];
+ *p++ = palette[BIT(gfx, 5)];
+ *p++ = palette[BIT(gfx, 4)];
+ *p++ = palette[BIT(gfx, 3)];
+ *p++ = palette[BIT(gfx, 2)];
+ *p++ = palette[BIT(gfx, 1)];
+ *p++ = palette[BIT(gfx, 0)];
+ }
+ }
+}
+
+WRITE8_MEMBER( mycom_state::mycom_00_w )
+{
+ switch(data)
+ {
+ case 0x00: membank("boot")->set_entry(1); break;
+ case 0x01: membank("boot")->set_entry(0); break;
+ case 0x02: m_upper_sw = 0x10000; break;
+ case 0x03: m_upper_sw = 0x0c000; break;
+ }
+}
+
+READ8_MEMBER( mycom_state::mycom_upper_r )
+{
+ return m_p_ram[offset | m_upper_sw];
+}
+
+WRITE8_MEMBER( mycom_state::mycom_upper_w )
+{
+ m_p_ram[offset | 0xc000] = data;
+}
+
+READ8_MEMBER( mycom_state::vram_data_r )
+{
+ return m_p_videoram[m_i_videoram];
+}
+
+WRITE8_MEMBER( mycom_state::vram_data_w )
+{
+ m_p_videoram[m_i_videoram] = data;
+}
+
+static ADDRESS_MAP_START(mycom_map, AS_PROGRAM, 8, mycom_state)
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE(0x0000, 0x0fff) AM_RAMBANK("boot")
+ AM_RANGE(0x1000, 0xbfff) AM_RAM
+ AM_RANGE(0xc000, 0xffff) AM_READWRITE(mycom_upper_r,mycom_upper_w)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(mycom_io, AS_IO, 8, mycom_state)
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x00, 0x00) AM_WRITE(mycom_00_w)
+ AM_RANGE(0x01, 0x01) AM_READWRITE(vram_data_r,vram_data_w)
+ AM_RANGE(0x02, 0x02) AM_DEVREADWRITE("crtc", mc6845_device, status_r, address_w)
+ AM_RANGE(0x03, 0x03) AM_DEVREADWRITE("crtc", mc6845_device, register_r, register_w)
+ AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write)
+ AM_RANGE(0x08, 0x0b) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write)
+ AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE("ppi8255_2", i8255_device, read, write)
+ AM_RANGE(0x10, 0x13) AM_DEVREADWRITE_LEGACY("fdc", wd17xx_r, wd17xx_w)
+ADDRESS_MAP_END
+
+/* Input ports */
+static INPUT_PORTS_START( mycom )
+ PORT_START("X0")
+ PORT_BIT(0x001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ESC") PORT_CHAR(27)
+ PORT_BIT(0x100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
+
+ PORT_START("X1")
+ PORT_BIT(0x002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
+ PORT_BIT(0x004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"')
+ PORT_BIT(0x008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
+ PORT_BIT(0x010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
+ PORT_BIT(0x020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
+ PORT_BIT(0x040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
+ PORT_BIT(0x080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7 '") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')
+ PORT_BIT(0x100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8 (") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
+ PORT_BIT(0x200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
+
+ PORT_START("X2")
+ PORT_BIT(0x002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') PORT_CHAR(17)
+ PORT_BIT(0x004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') PORT_CHAR(23)
+ PORT_BIT(0x008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') PORT_CHAR(5)
+ PORT_BIT(0x010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') PORT_CHAR(18)
+ PORT_BIT(0x020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') PORT_CHAR(20)
+ PORT_BIT(0x040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') PORT_CHAR(25)
+ PORT_BIT(0x080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') PORT_CHAR(21)
+ PORT_BIT(0x100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') PORT_CHAR(9)
+ PORT_BIT(0x200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') PORT_CHAR(15)
+
+ PORT_START("X3")
+ PORT_BIT(0x002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') PORT_CHAR(1)
+ PORT_BIT(0x004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') PORT_CHAR(19)
+ PORT_BIT(0x008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') PORT_CHAR(4)
+ PORT_BIT(0x010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') PORT_CHAR(6)
+ PORT_BIT(0x020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') PORT_CHAR(7)
+ PORT_BIT(0x040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') PORT_CHAR(8)
+ PORT_BIT(0x080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') PORT_CHAR(10)
+ PORT_BIT(0x100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') PORT_CHAR(11)
+ PORT_BIT(0x200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') PORT_CHAR(12)
+
+ PORT_START("X4")
+ PORT_BIT(0x001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9)
+ PORT_BIT(0x002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') PORT_CHAR(26)
+ PORT_BIT(0x004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') PORT_CHAR(24)
+ PORT_BIT(0x008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') PORT_CHAR(3)
+ PORT_BIT(0x010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') PORT_CHAR(22)
+ PORT_BIT(0x020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') PORT_CHAR(2)
+ PORT_BIT(0x040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') PORT_CHAR(14)
+ PORT_BIT(0x080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') PORT_CHAR(13)
+ PORT_BIT(0x100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("< ,") PORT_CODE(KEYCODE_COMMA) PORT_CHAR('<') PORT_CHAR(',')
+ PORT_BIT(0x200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("> .") PORT_CODE(KEYCODE_STOP) PORT_CHAR('>') PORT_CHAR('.')
+
+ PORT_START("X5")
+ PORT_BIT(0x020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("(u)") PORT_CHAR('u')
+ PORT_BIT(0x200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("(c)") PORT_CHAR('c')
+
+ PORT_START("X6")
+ PORT_BIT(0x001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0')
+ PORT_BIT(0x002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("- =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=')
+ PORT_BIT(0x004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("^ ~") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') PORT_CHAR('~') PORT_CHAR(30)
+ PORT_BIT(0x008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("\\ _") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('_') PORT_CHAR(28)
+ PORT_BIT(0x020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("(d)") PORT_CHAR('d')
+ PORT_BIT(0x200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("(f)") PORT_CHAR('f')
+
+ PORT_START("X7")
+ PORT_BIT(0x001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') PORT_CHAR(16)
+ PORT_BIT(0x002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("@ `") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('@') PORT_CHAR('`') PORT_CHAR(0)
+ PORT_BIT(0x004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') PORT_CHAR(27)
+ PORT_BIT(0x008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("LineFeed") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(10)
+ PORT_BIT(0x010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
+ PORT_BIT(0x200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("(a)") PORT_CHAR('a')
+
+ PORT_START("X8")
+ PORT_BIT(0x001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("; +") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+')
+ PORT_BIT(0x002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(": *") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*')
+ PORT_BIT(0x004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(29)
+ PORT_BIT(0x020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
+ PORT_BIT(0x200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
+
+ PORT_START("XX")
+ PORT_BIT(0x001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL)
+ PORT_BIT(0x002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT)
+ PORT_BIT(0x004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("KANA") PORT_CODE(KEYCODE_LALT) PORT_CODE(KEYCODE_RALT) PORT_TOGGLE
+INPUT_PORTS_END
+
+
+/* F4 Character Displayer */
+static const gfx_layout mycom_charlayout =
+{
+ 8, 8, /* 8 x 8 characters */
+ 256, /* 256 characters */
+ 1, /* 1 bits per pixel */
+ { 0 }, /* no bitplanes */
+ /* x offsets */
+ { 0, 1, 2, 3, 4, 5, 6, 7 },
+ /* y offsets */
+ { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
+ 8*8 /* every char takes 8 bytes */
+};
+
+static GFXDECODE_START( mycom )
+ GFXDECODE_ENTRY( "chargen", 0x0000, mycom_charlayout, 0, 1 )
+GFXDECODE_END
+
+static const mc6845_interface mc6845_intf =
+{
+ "screen", /* screen we are acting on */
+ 8, /* number of pixels per video memory address */
+ NULL, /* before pixel update callback */
+ mycom_update_row, /* row update callback */
+ NULL, /* after pixel update callback */
+ DEVCB_NULL, /* callback for display state changes */
+ DEVCB_NULL, /* callback for cursor state changes */
+ DEVCB_NULL, /* HSYNC callback */
+ DEVCB_NULL, /* VSYNC callback */
+ NULL /* update address callback */
+};
+
+WRITE8_MEMBER( mycom_state::mycom_04_w )
+{
+ m_i_videoram = (m_i_videoram & 0x700) | data;
+
+ m_sn_we = data;
+}
+
+WRITE8_MEMBER( mycom_state::mycom_06_w )
+{
+ m_i_videoram = (m_i_videoram & 0x0ff) | ((data & 0x007) << 8);
+}
+
+READ8_MEMBER( mycom_state::mycom_08_r )
+{
+ /*
+ x--- ---- display flag
+ ---- --x- keyboard shift
+ ---- ---x keyboard strobe
+ */
+ UINT8 data = 0;
+
+ data = m_keyb_press_flag; //~m_keyb_press_flag & 1;
+
+ if ((m_cass)->input() > 0.03) // not working
+ data+=4;
+
+ return data;
+}
+
+READ8_MEMBER( mycom_state::mycom_06_r )
+{
+ /*
+ x--- ---- keyboard s5
+ -x-- ---- keyboard s4 (motor on/off)
+ --x- ---- keyboard s3 (must be high)
+ ---x ---- keyboard s2
+ */
+ return 0xff;
+}
+
+READ8_MEMBER( mycom_state::mycom_05_r )
+{
+ return m_keyb_press;
+}
+
+WRITE8_MEMBER( mycom_state::mycom_0a_w )
+{
+ /*
+ x--- ---- width 80/40 (0 = 80, 1 = 40)
+ -x-- ---- video mode (0= tile, 1 = bitmap)
+ --x- ---- PSG Chip Select bit
+ ---x ---- PSG Write Enable bit
+ ---- x--- cmt remote (defaults to on)
+ ---- -x-- cmt output
+ ---- --x- printer reset
+ ---- ---x printer strobe
+ */
+
+ if ( (BIT(m_0a, 3)) != (BIT(data, 3)) )
+ m_cass->change_state(
+ BIT(data,3) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
+
+ if (BIT(data, 3)) // motor on
+ m_cass->output( BIT(data, 2) ? -1.0 : +1.0);
+
+ if ( (BIT(data, 7)) != (BIT(m_0a, 7)) )
+ m_crtc->set_clock(BIT(data, 7) ? 1008000 : 2016000);
+
+ m_0a = data;
+
+ // if WE & CE are low, pass sound command to audio chip
+ if ((data & 0x30)==0)
+ sn76496_w(m_audio, 0, m_sn_we);
+}
+
+static WRITE8_DEVICE_HANDLER( mycom_rtc_w )
+{
+ mycom_state *state = device->machine().driver_data<mycom_state>();
+
+ state->m_rtc->address_w(data & 0x0f);
+
+ state->m_rtc->hold_w(BIT(data, 4));
+ state->m_rtc->read_w(BIT(data, 5));
+ state->m_rtc->write_w(BIT(data, 6));
+ state->m_rtc->cs_w(BIT(data, 7));
+}
+
+static I8255_INTERFACE( ppi8255_intf_0 )
+{
+ DEVCB_NULL, /* Port A read */
+ DEVCB_DRIVER_MEMBER(mycom_state, mycom_04_w), /* Port A write */
+ DEVCB_DRIVER_MEMBER(mycom_state, mycom_05_r), /* Port B read */
+ DEVCB_NULL, /* Port B write */
+ DEVCB_DRIVER_MEMBER(mycom_state, mycom_06_r), /* Port C read */
+ DEVCB_DRIVER_MEMBER(mycom_state, mycom_06_w) /* Port C write */
+};
+
+static I8255_INTERFACE( ppi8255_intf_1 )
+{
+ DEVCB_DRIVER_MEMBER(mycom_state, mycom_08_r), /* Port A read */
+ DEVCB_NULL, /* Port A write */
+ DEVCB_NULL, /* Port B read */
+ DEVCB_NULL, /* Port B write */
+ DEVCB_NULL, /* Port C read */
+ DEVCB_DRIVER_MEMBER(mycom_state, mycom_0a_w) /* Port C write */
+};
+
+static I8255_INTERFACE( ppi8255_intf_2 )
+{
+ DEVCB_NULL, /* Port A read */
+ DEVCB_NULL, /* Port A write */
+ DEVCB_DEVICE_MEMBER(MSM5832RS_TAG, msm5832_device, data_r), /* Port B read */
+ DEVCB_DEVICE_MEMBER(MSM5832RS_TAG, msm5832_device, data_w), /* Port B write */
+ DEVCB_NULL, /* Port C read */
+ DEVCB_HANDLER(mycom_rtc_w) /* Port C write */
+};
+
+static const UINT8 mycom_keyval[] = { 0,
+0x1b,0x1b,0x7c,0x7c,0x18,0x18,0x0f,0x0f,0x09,0x09,0x1c,0x1c,0x30,0x00,0x50,0x70,0x3b,0x2b,
+0x00,0x00,0x31,0x21,0x51,0x71,0x41,0x61,0x5a,0x7a,0x17,0x17,0x2d,0x3d,0x40,0x60,0x3a,0x2a,
+0x0b,0x0b,0x32,0x22,0x57,0x77,0x53,0x73,0x58,0x78,0x03,0x03,0x5e,0x7e,0x5b,0x7b,0x5d,0x7d,
+0x1f,0x1f,0x33,0x23,0x45,0x65,0x44,0x64,0x43,0x63,0x0c,0x0c,0x5c,0x7c,0x0a,0x0a,0x00,0x00,
+0x01,0x01,0x34,0x24,0x52,0x72,0x46,0x66,0x56,0x76,0x04,0x04,0x7f,0x7f,0x08,0x08,0x0e,0x0e,
+0x02,0x02,0x35,0x25,0x54,0x74,0x47,0x67,0x42,0x62,0x75,0x75,0x64,0x64,0x00,0x00,0x20,0x20,
+0x1e,0x1e,0x36,0x26,0x59,0x79,0x48,0x68,0x4e,0x6e,0x37,0x37,0x34,0x34,0x31,0x31,0x30,0x30,
+0x1d,0x1d,0x37,0x27,0x55,0x75,0x4a,0x6a,0x4d,0x6d,0x38,0x38,0x35,0x35,0x32,0x32,0x11,0x11,
+0x0d,0x0d,0x38,0x28,0x49,0x69,0x4b,0x6b,0x2c,0x3c,0x39,0x39,0x36,0x36,0x33,0x33,0x12,0x12,
+0x07,0x07,0x39,0x29,0x4f,0x6f,0x4c,0x6c,0x2e,0x3e,0x63,0x63,0x66,0x66,0x61,0x61,0x2f,0x3f };
+
+static TIMER_DEVICE_CALLBACK( mycom_kbd )
+{
+ mycom_state *state = timer.machine().driver_data<mycom_state>();
+ UINT8 x, y, scancode = 0;
+ UINT16 pressed[9];
+ char kbdrow[3];
+ UINT8 modifiers = timer.machine().root_device().ioport("XX")->read();
+ UINT8 shift_pressed = (modifiers & 2) >> 1;
+ state->m_keyb_press_flag = 0;
+
+ /* see what is pressed */
+ for (x = 0; x < 9; x++)
+ {
+ sprintf(kbdrow,"X%d",x);
+ pressed[x] = (timer.machine().root_device().ioport(kbdrow)->read());
+ }
+
+ /* find what has changed */
+ for (x = 0; x < 9; x++)
+ {
+ if (pressed[x])
+ {
+ /* get scankey value */
+ for (y = 0; y < 10; y++)
+ {
+ if (BIT(pressed[x], y))
+ {
+ scancode = ((x + y * 9) << 1) + shift_pressed + 1;
+ state->m_keyb_press_flag = 1;
+ state->m_keyb_press = mycom_keyval[scancode];
+ }
+ }
+ }
+ }
+
+ if (state->m_keyb_press_flag)
+ {
+ if (modifiers & 1) state->m_keyb_press &= 0xbf;
+ if (modifiers & 4) state->m_keyb_press |= 0x80;
+ }
+}
+
+// The floppy parameters are unknown, the below is copied from another driver
+static LEGACY_FLOPPY_OPTIONS_START(mycom)
+ LEGACY_FLOPPY_OPTION(mycom, "fdd", "mycom disk image", basicdsk_identify_default, basicdsk_construct_default, NULL,
+ HEADS([2])
+ TRACKS([82])
+ SECTORS([5])
+ SECTOR_LENGTH([1024])
+ FIRST_SECTOR_ID([1]))
+LEGACY_FLOPPY_OPTIONS_END
+
+static const floppy_interface mycom_floppy_interface =
+{
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ FLOPPY_STANDARD_5_25_DSHD,
+ LEGACY_FLOPPY_OPTIONS_NAME(mycom),
+ NULL,
+ NULL
+};
+
+static const wd17xx_interface wd1771_intf =
+{
+ DEVCB_NULL,
+ DEVCB_NULL, // no information available
+ DEVCB_NULL,
+ {FLOPPY_0, FLOPPY_1, NULL, NULL}
+};
+
+
+MACHINE_START_MEMBER(mycom_state)
+{
+ m_p_ram = memregion("maincpu")->base();
+}
+
+MACHINE_RESET_MEMBER(mycom_state)
+{
+ membank("boot")->set_entry(1);
+ m_upper_sw = 0x10000;
+ m_0a = 0;
+}
+
+DRIVER_INIT_MEMBER(mycom_state,mycom)
+{
+ UINT8 *RAM = memregion("maincpu")->base();
+ membank("boot")->configure_entries(0, 2, &RAM[0x0000], 0x10000);
+}
+
+static MACHINE_CONFIG_START( mycom, mycom_state )
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu",Z80, XTAL_10MHz / 4)
+ MCFG_CPU_PROGRAM_MAP(mycom_map)
+ MCFG_CPU_IO_MAP(mycom_io)
+
+ MCFG_I8255_ADD( "ppi8255_0", ppi8255_intf_0 )
+ MCFG_I8255_ADD( "ppi8255_1", ppi8255_intf_1 )
+ MCFG_I8255_ADD( "ppi8255_2", ppi8255_intf_2 )
+
+ /* video hardware */
+ MCFG_SCREEN_ADD("screen", RASTER)
+ MCFG_SCREEN_REFRESH_RATE(60)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
+ MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update)
+ MCFG_SCREEN_SIZE(640, 480)
+ MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 192-1)
+ MCFG_PALETTE_LENGTH(2)
+ MCFG_PALETTE_INIT(black_and_white)
+ MCFG_GFXDECODE(mycom)
+
+ /* Manual states clock is 1.008mhz for 40 cols, and 2.016 mhz for 80 cols.
+ The CRTC is a HD46505S - same as a 6845. The start registers need to be readable. */
+ MCFG_MC6845_ADD("crtc", MC6845, 1008000, mc6845_intf)
+
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_WAVE_ADD(WAVE_TAG, CASSETTE_TAG)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
+ MCFG_SOUND_ADD("sn1", SN76489, XTAL_10MHz / 4)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.50)
+
+ /* Devices */
+ MCFG_MSM5832_ADD(MSM5832RS_TAG, XTAL_32_768kHz)
+ MCFG_CASSETTE_ADD( CASSETTE_TAG, default_cassette_interface )
+ MCFG_FD1771_ADD("fdc", wd1771_intf)
+ MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(mycom_floppy_interface)
+
+ MCFG_TIMER_ADD_PERIODIC("keyboard_timer", mycom_kbd, attotime::from_hz(20))
+MACHINE_CONFIG_END
+
+/* ROM definition */
+ROM_START( mycom )
+ ROM_REGION( 0x14000, "maincpu", ROMREGION_ERASEFF )
+ ROM_DEFAULT_BIOS("mycom")
+ ROM_SYSTEM_BIOS(0, "mycom", "40 column")
+ ROMX_LOAD( "bios0.rom", 0x10000, 0x3000, CRC(e6f50355) SHA1(5d3acea360c0a8ab547db03a43e1bae5125f9c2a), ROM_BIOS(1))
+ ROMX_LOAD( "basic0.rom",0x13000, 0x1000, CRC(3b077465) SHA1(777427182627f371542c5e0521ed3ca1466a90e1), ROM_BIOS(1))
+ ROM_SYSTEM_BIOS(1, "Takeda", "80 column")
+ ROMX_LOAD( "bios1.rom", 0x10000, 0x3000, CRC(c51d7fcb) SHA1(31d39db43b77cca4d49ff9814d531e056924e716), ROM_BIOS(2))
+ ROMX_LOAD( "basic1.rom",0x13000, 0x1000, CRC(30a573f1) SHA1(e3fe2e73644e831b52e2789dc7c181989cc30b82), ROM_BIOS(2))
+ /* Takeda bios has no cursor. Use the next lines to turn on cursor, but you must comment out when done. */
+ //ROM_FILL( 0x11eb6, 1, 0x47 )
+ //ROM_FILL( 0x11eb7, 1, 0x07 )
+
+ ROM_REGION( 0x0800, "vram", ROMREGION_ERASE00 )
+
+ ROM_REGION( 0x0800, "chargen", 0 )
+ ROM_LOAD( "font.rom", 0x0000, 0x0800, CRC(4039bb6f) SHA1(086ad303bf4bcf983fd6472577acbf744875fea8) )
+ROM_END
+
+/* Driver */
+
+/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
+COMP( 1981, mycom, 0, 0, mycom, mycom, mycom_state, mycom, "Japan Electronics College", "MYCOMZ-80A", GAME_NOT_WORKING | GAME_NO_SOUND )