mirror of
https://github.com/holub/mame
synced 2025-05-12 17:14:19 +03:00
649 lines
24 KiB
C
649 lines
24 KiB
C
/******************************************************************************
|
|
|
|
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 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"),
|
|
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<wave_device> m_wave;
|
|
required_device<mc6845_device> m_crtc;
|
|
required_device<fd1771_device> m_fdc;
|
|
required_device<sn76489_device> 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);
|
|
TIMER_DEVICE_CALLBACK_MEMBER(mycom_kbd);
|
|
DECLARE_WRITE8_MEMBER(mycom_rtc_w);
|
|
};
|
|
|
|
|
|
|
|
void mycom_state::video_start()
|
|
{
|
|
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 MC6845_INTERFACE( mc6845_intf )
|
|
{
|
|
"screen", /* screen we are acting on */
|
|
false, /* show border area */
|
|
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)
|
|
m_audio->write(space, 0, m_sn_we);
|
|
}
|
|
|
|
WRITE8_MEMBER(mycom_state::mycom_rtc_w)
|
|
{
|
|
m_rtc->address_w(data & 0x0f);
|
|
|
|
m_rtc->hold_w(BIT(data, 4));
|
|
m_rtc->read_w(BIT(data, 5));
|
|
m_rtc->write_w(BIT(data, 6));
|
|
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_DRIVER_MEMBER(mycom_state,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 };
|
|
|
|
TIMER_DEVICE_CALLBACK_MEMBER(mycom_state::mycom_kbd)
|
|
{
|
|
UINT8 x, y, scancode = 0;
|
|
UINT16 pressed[9];
|
|
char kbdrow[3];
|
|
UINT8 modifiers = ioport("XX")->read();
|
|
UINT8 shift_pressed = (modifiers & 2) >> 1;
|
|
m_keyb_press_flag = 0;
|
|
|
|
/* see what is pressed */
|
|
for (x = 0; x < 9; x++)
|
|
{
|
|
sprintf(kbdrow,"X%d",x);
|
|
pressed[x] = (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;
|
|
m_keyb_press_flag = 1;
|
|
m_keyb_press = mycom_keyval[scancode];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_keyb_press_flag)
|
|
{
|
|
if (modifiers & 1) m_keyb_press &= 0xbf;
|
|
if (modifiers & 4) 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}
|
|
};
|
|
|
|
|
|
/*************************************
|
|
*
|
|
* Sound interface
|
|
*
|
|
*************************************/
|
|
|
|
|
|
//-------------------------------------------------
|
|
// sn76496_config psg_intf
|
|
//-------------------------------------------------
|
|
|
|
static const sn76496_config psg_intf =
|
|
{
|
|
DEVCB_NULL
|
|
};
|
|
|
|
|
|
void mycom_state::machine_start()
|
|
{
|
|
m_p_ram = memregion("maincpu")->base();
|
|
}
|
|
|
|
void mycom_state::machine_reset()
|
|
{
|
|
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")
|
|
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
|
MCFG_SOUND_ADD("sn1", SN76489, XTAL_10MHz / 4)
|
|
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.50)
|
|
MCFG_SOUND_CONFIG(psg_intf)
|
|
|
|
/* Devices */
|
|
MCFG_MSM5832_ADD(MSM5832RS_TAG, XTAL_32_768kHz)
|
|
MCFG_CASSETTE_ADD( "cassette", default_cassette_interface )
|
|
MCFG_FD1771_ADD("fdc", wd1771_intf)
|
|
MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(mycom_floppy_interface)
|
|
|
|
MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard_timer", mycom_state, 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 )
|