Machines promoted to working

----------------------------
Monty Plays Scrabble [hap]
Master Monty [hap]
This commit is contained in:
hap 2020-05-08 21:38:58 +02:00
parent d983d9ec93
commit 623dc28919
11 changed files with 408 additions and 204 deletions

View File

@ -850,6 +850,17 @@ if (VIDEOS["SED1330"]~=null) then
}
end
--------------------------------------------------
--
--@src/devices/video/sed1500.h,VIDEOS["SED1500"] = true
--------------------------------------------------
if (VIDEOS["SED1500"]~=null) then
files {
MAME_DIR .. "src/devices/video/sed1500.cpp",
MAME_DIR .. "src/devices/video/sed1500.h",
}
end
--------------------------------------------------
--
--@src/devices/video/sed1520.h,VIDEOS["SED1520"] = true

View File

@ -354,6 +354,7 @@ VIDEOS["SCN2674"] = true
VIDEOS["PWM_DISPLAY"] = true
--VIDEOS["SED1200"] = true
--VIDEOS["SED1330"] = true
--VIDEOS["SED1500"] = true
--VIDEOS["SED1520"] = true
VIDEOS["SNES_PPU"] = true
VIDEOS["STVVDP"] = true

View File

@ -382,6 +382,7 @@ VIDEOS["PWM_DISPLAY"] = true
VIDEOS["SDA5708"] = true
VIDEOS["SED1200"] = true
VIDEOS["SED1330"] = true
VIDEOS["SED1500"] = true
VIDEOS["SED1520"] = true
VIDEOS["SNES_PPU"] = true
VIDEOS["STVVDP"] = true

View File

@ -68,6 +68,7 @@ public:
auto write_port5_callback() { return m_write_port[4].bind(); }
auto write_port6_callback() { return m_write_port[5].bind(); }
auto write_port7_callback() { return m_write_port[6].bind(); }
tms1024_device &set_ms(u8 i) { m_ms = i & 1; return *this; } // if hardwired, can just set MS pin state here
void write_h(u8 data);
u8 read_h();

View File

@ -0,0 +1,116 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Epson SED1500 series LCD Driver
128 bytes internal RAM.
SED1500: 8 commons, 42 segments
SED1501: 10 commons, 40 segments
SED1502: 16 commons, 34 segments
SED1503: 8 commons, 42 segments, needs multiple of 2 chips to function
The default input OSC frequency is 32768Hz, the frame output frequency is
divided by 64 and by number of commons, eg. 64Hz on a SED1500.
TODO:
- bus mode (only mode 3 now)
- EI pin (master/slave mode)
- SYNC pin, used for frame synchronizing if multiple chips are used
- SED1503 only has 8 COM pins, the extra 8 outputs are from the slave chip
*/
#include "emu.h"
#include "video/sed1500.h"
DEFINE_DEVICE_TYPE(SED1500, sed1500_device, "sed1500", "Epson SED1500 LCD Driver")
DEFINE_DEVICE_TYPE(SED1501, sed1501_device, "sed1501", "Epson SED1501 LCD Driver")
DEFINE_DEVICE_TYPE(SED1502, sed1502_device, "sed1502", "Epson SED1502 LCD Driver")
DEFINE_DEVICE_TYPE(SED1503, sed1503_device, "sed1503", "Epson SED1503 LCD Driver")
//-------------------------------------------------
// constructor
//-------------------------------------------------
sed1500_device::sed1500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 cmax, u8 smax) :
device_t(mconfig, type, tag, owner, clock),
m_cmax(cmax), m_smax(smax),
m_write_segs(*this)
{ }
sed1500_device::sed1500_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
sed1500_device(mconfig, SED1500, tag, owner, clock, 8, 42)
{ }
sed1501_device::sed1501_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
sed1500_device(mconfig, SED1501, tag, owner, clock, 10, 40)
{ }
sed1502_device::sed1502_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
sed1500_device(mconfig, SED1502, tag, owner, clock, 16, 34)
{ }
sed1503_device::sed1503_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
sed1500_device(mconfig, SED1503, tag, owner, clock, 8+8, 42)
{ }
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sed1500_device::device_start()
{
memset(m_ram, 0, sizeof(m_ram));
// resolve callbacks
m_write_segs.resolve_safe();
// timer
m_lcd_timer = timer_alloc();
attotime period = attotime::from_hz(clock() / 64);
m_lcd_timer->adjust(period, 0, period);
// register for savestates
save_item(NAME(m_mode));
save_item(NAME(m_cout));
save_item(NAME(m_ram));
}
//-------------------------------------------------
// handlers
//-------------------------------------------------
void sed1500_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
u64 data = 0;
for (int i = m_smax-1; i >= 0; i--)
data = data << 1 | BIT(m_ram[i | 0x40] << 8 | m_ram[i], m_cout);
// transfer segments to output
m_write_segs(m_cout, data);
m_cout = (m_cout + 1) % m_cmax;
}
void sed1500_device::write(offs_t offset, u8 data)
{
offset &= 0x7f;
m_ram[offset] = data;
// bus mode command:
// 0 = 4-bit addr, 4-bit data, combined
// 1 = 7-bit addr, 4-bit data, separate
// 2 = 7-bit addr, 8-bit data, combined
// 3 = 7-bit addr, 8-bit data, separate
if ((offset & 0x3f) == 0x3f && ~data & 1)
m_mode = data >> 1 & 3;
}
u8 sed1500_device::read(offs_t offset)
{
return m_ram[offset & 0x7f];
}

View File

@ -0,0 +1,85 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Epson SED1500 series LCD Driver
*/
#ifndef MAME_VIDEO_SED1500_H
#define MAME_VIDEO_SED1500_H
#pragma once
/*
pinout reference (brief)
OSC: oscillator (resistors or XTAL)
A0-A6: address
D0-D7: data (I/O)
WR/RD: write/read signal
CS: chip select
SYNC: frame synchronize (I/O)
CL: OSC output
COM: LCD commons
SEG: LCD segments
*/
class sed1500_device : public device_t
{
public:
sed1500_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configuration helpers
auto write_segs() { return m_write_segs.bind(); } // common number in offset, segment data in data
void write(offs_t offset, u8 data);
u8 read(offs_t offset);
protected:
sed1500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 cmax, u8 smax);
// device-level overrides
virtual void device_start() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
emu_timer *m_lcd_timer;
const u8 m_cmax; // number of COL pins
const u8 m_smax; // number of SEG pins
u8 m_mode = 0;
u8 m_cout = 0;
u8 m_ram[0x80];
// callbacks
devcb_write64 m_write_segs;
};
class sed1501_device : public sed1500_device
{
public:
sed1501_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class sed1502_device : public sed1500_device
{
public:
sed1502_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class sed1503_device : public sed1500_device
{
public:
sed1503_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
DECLARE_DEVICE_TYPE(SED1500, sed1500_device)
DECLARE_DEVICE_TYPE(SED1501, sed1501_device)
DECLARE_DEVICE_TYPE(SED1502, sed1502_device)
DECLARE_DEVICE_TYPE(SED1503, sed1503_device)
#endif // MAME_VIDEO_SED1500_H

View File

@ -5371,17 +5371,8 @@ public:
virtual DECLARE_WRITE16_MEMBER(write_o);
virtual DECLARE_READ8_MEMBER(read_k);
void ginv2000(machine_config &config);
protected:
virtual void machine_reset() override;
};
void ginv2000_state::machine_reset()
{
hh_tms1k_state::machine_reset();
m_expander->write_ms(1); // Vss
}
// handlers
void ginv2000_state::update_display()
@ -5453,7 +5444,7 @@ void ginv2000_state::ginv2000(machine_config &config)
m_maincpu->r().set(FUNC(ginv2000_state::write_r));
m_maincpu->o().set(FUNC(ginv2000_state::write_o));
TMS1024(config, m_expander);
TMS1024(config, m_expander).set_ms(1); // MS tied high
m_expander->write_port4_callback().set(FUNC(ginv2000_state::expander_w));
m_expander->write_port5_callback().set(FUNC(ginv2000_state::expander_w));
m_expander->write_port6_callback().set(FUNC(ginv2000_state::expander_w));
@ -11926,7 +11917,6 @@ void tbreakup_state::machine_reset()
{
hh_tms1k_state::machine_reset();
set_clock();
m_expander->write_ms(1); // Vss
}
// handlers
@ -12021,7 +12011,7 @@ void tbreakup_state::tbreakup(machine_config &config)
m_maincpu->r().set(FUNC(tbreakup_state::write_r));
m_maincpu->o().set(FUNC(tbreakup_state::write_o));
TMS1025(config, m_expander);
TMS1025(config, m_expander).set_ms(1); // MS tied high
m_expander->write_port1_callback().set(FUNC(tbreakup_state::expander_w));
m_expander->write_port2_callback().set(FUNC(tbreakup_state::expander_w));
m_expander->write_port3_callback().set(FUNC(tbreakup_state::expander_w));

View File

@ -1,38 +1,49 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
// copyright-holders:Andrew Gardner, hap
/***************************************************************************
2015-05-08 Skeleton driver for Ritam Monty Plays Scrabble BRAND crossword game
Driver for Ritam Monty Plays Scrabble BRAND crossword game
Scrabble computer that allows you play a game of Scrabble by yourself (or you
can play with up to 3 players). Has a built-in 12,000 vocabulary, expandable
to 44,000 by way of 2 expansion modules each containing 16,000 more obscure words.
You can use the included 'score cards' (which look like little Scrabble boards),
or you can use a real Scrabble board and tiles to play. Also note, Monty
apparently originally came with a little pen.
Scrabble computer that allows you play a game of Scrabble by yourself (or you
can play with up to 3 players). Has a built-in 12,000 vocabulary, expandable
to 44,000 by way of 2 expansion modules each containing 16,000 more obscure words.
You can use the included 'score cards' (which look like little Scrabble boards),
or you can use a real Scrabble board and tiles to play. Also note, Monty
apparently originally came with a little pen.
This game was later upgraded by Ritam to Master Monty which had 24,000 words
built-in (expandable to a total of 56,000 with the same 2 expansion modules).
Two variations on Master Monty have been seen: one looks exactly the same as the
Monty but the electronics on the inside have been upgraded. The later version
is blue and says Master Monty at the top. Both of these versions are hand-upgraded
by adding chips and wires to the inside of the game.
This game was later upgraded by Ritam to Master Monty which had 24,000 words
built-in (expandable to a total of 56,000 with the same 2 expansion modules).
Two variations on Master Monty have been seen: one looks exactly the same as the
Monty but the electronics on the inside have been upgraded. The later version
is blue and says Master Monty at the top. Both of these versions are hand-upgraded
by adding chips and wires to the inside of the game.
TODO:
- Need instructions
- Proper SED1503F emulation (it's simulated in-driver for now)
- When it wants tiles, put 64 into FD1B (monty), 7D1B (mmonty) and press
Enter.
Hardware notes:
- Z80 @ ~3.58MHz
- 2KB SRAM, 16KB ROM(32KB on mmonty)
- 2*16KB ROM sockets for vocabulary expansion
- 2*SED1503F, 40*32 LCD screen, beeper
TODO:
- put expansion roms in softwarelist? (note: slot #1 only accepts rom #1,
slot #2 only accepts rom #2)
****************************************************************************/
#include "emu.h"
#include "cpu/z80/z80.h"
#include "sound/spkrdev.h"
#include "video/sed1520.h"
#include "sound/dac.h"
#include "sound/volt_reg.h"
#include "video/sed1500.h"
#include "screen.h"
#include "speaker.h"
#include "monty.lh"
namespace {
class monty_state : public driver_device
{
@ -40,72 +51,109 @@ public:
monty_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_speaker(*this, "speaker")
, m_sed0(*this, "sed1520_0")
, m_writeUpper(false)
, m_halt(0)
{
for (auto & elem : m_pixels)
elem = 0xff000000;
}
, m_lcd(*this, "lcd%u", 0)
, m_dac(*this, "dac")
{ }
DECLARE_WRITE_LINE_MEMBER(key_pressed);
void monty(machine_config &config);
void mmonty(machine_config &config);
protected:
virtual void machine_start() override;
private:
DECLARE_WRITE8_MEMBER(sound_w);
DECLARE_WRITE8_MEMBER(ioDisplayWrite_w);
DECLARE_WRITE8_MEMBER(ioCommandWrite0_w);
DECLARE_WRITE8_MEMBER(ioCommandWrite1_w);
DECLARE_WRITE_LINE_MEMBER(halt_changed);
// screen updates
uint32_t lcd_update(screen_device& screen, bitmap_rgb32& bitmap, const rectangle& cliprect);
SED1520_UPDATE_CB(screen_update);
required_device<z80_device> m_maincpu;
required_device_array<sed1503_device, 2> m_lcd;
required_device<dac_bit_interface> m_dac;
void monty_mem(address_map &map);
void mmonty_mem(address_map &map);
void monty_io(address_map &map);
void monty_mem(address_map &map);
required_device<z80_device> m_maincpu;
required_device<speaker_sound_device> m_speaker;
required_device<sed1520_device> m_sed0; // TODO: This isn't actually a SED1520, it's a SED1503F
//required_device<sed1520_device> m_sed1; // TODO: Also, there are 2 SED1503Fs on the board - one is flipped upside down
template<int N> void lcd_output_w(offs_t offset, u64 data) { m_lcd_data[N << 4 | offset] = data; } // buffer for screen_update
u32 screen_update(screen_device& screen, bitmap_rgb32& bitmap, const rectangle& cliprect);
// Test
uint8_t m_writeUpper;
uint32_t m_pixels[42*32];
bool m_sound_sw;
bool m_dirty;
int m_halt;
DECLARE_WRITE8_MEMBER(control_w);
DECLARE_WRITE8_MEMBER(lcd_w) { m_lcd[m_lcd_cs]->write(offset, data); }
DECLARE_WRITE_LINE_MEMBER(halt_changed) { m_halt = state; }
u64 m_lcd_data[32];
int m_lcd_cs = 0;
int m_halt = 0;
};
void monty_state::machine_start()
{
save_item(NAME(m_lcd_data));
save_item(NAME(m_lcd_cs));
save_item(NAME(m_halt));
}
/******************************************************************************
Video
******************************************************************************/
u32 monty_state::screen_update(screen_device& screen, bitmap_rgb32& bitmap, const rectangle& cliprect)
{
bitmap.fill(0xffffff);
// letters with width 5 with space in between them
for (int y = 0; y < 32; y++)
for (int x = 0; x < 40; x++)
bitmap.pix32(y + 1, x + x/5 + 1) = BIT(m_lcd_data[y], x) ? 0 : 0xffffff;
return 0;
}
/******************************************************************************
I/O
******************************************************************************/
WRITE8_MEMBER(monty_state::control_w)
{
// a0: speaker out
m_dac->write(BIT(offset, 0));
// a1: lcd chip select
m_lcd_cs = BIT(offset, 1);
}
WRITE_LINE_MEMBER(monty_state::key_pressed)
{
if (!state && m_halt)
m_maincpu->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
}
/******************************************************************************
Address Maps
******************************************************************************/
void monty_state::monty_mem(address_map &map)
{
map(0x0000, 0xbfff).rom();
//map(0x4000, 0x4000) // The main rom checks to see if another program is here on startup
map(0xf800, 0xffff).ram();
}
void monty_state::mmonty_mem(address_map &map)
{
map(0x0000, 0x3fff).rom();
//map(0xc000, 0xc000) // The main rom checks to see if another program is here on startup
map(0x8000, 0xffff).rom();
map(0x0000, 0x77ff).rom();
map(0x7800, 0x7fff).ram();
map(0x8000, 0xffff).rom();
}
void monty_state::monty_io(address_map &map)
{
map.global_mask(0xff);
map(0x00, 0x00).w(FUNC(monty_state::ioCommandWrite0_w));
map(0x01, 0x01).w(FUNC(monty_state::sound_w));
map(0x02, 0x02).w(FUNC(monty_state::ioCommandWrite1_w));
map(0x80, 0xff).w(FUNC(monty_state::ioDisplayWrite_w));
map(0x00, 0x03).w(FUNC(monty_state::control_w));
map(0x80, 0xff).w(FUNC(monty_state::lcd_w));
// 7 reads from a bit shifted IO port
map(0x01, 0x01).portr("X1");
@ -118,13 +166,17 @@ void monty_state::monty_io(address_map &map)
}
// Input ports
/******************************************************************************
Input Ports
******************************************************************************/
static INPUT_PORTS_START( monty )
PORT_START("X1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Left") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Erase") PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Option") PORT_CODE(KEYCODE_SPACE) PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Blank") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )
@ -147,145 +199,61 @@ static INPUT_PORTS_START( monty )
PORT_START("X4")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CODE(KEYCODE_DOWN) PORT_CHAR('M') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("X5")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR('I') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_LEFT) PORT_CHAR('G') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("X6")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_UP) PORT_CHAR('C') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, monty_state, key_pressed)
PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("X7")
PORT_BIT( 0xFF, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END
WRITE8_MEMBER( monty_state::sound_w )
{
m_sound_sw ^= 1;
m_speaker->level_w(m_sound_sw);
}
/******************************************************************************
Machine Configs
******************************************************************************/
WRITE8_MEMBER( monty_state::ioCommandWrite0_w )
{
//printf("(%04x) Command Port 0 write : %02x\n", m_maincpu->pc(), data);
m_writeUpper = false;
}
WRITE8_MEMBER( monty_state::ioCommandWrite1_w )
{
//if (data == 0xfe)
// printf("---\n");
//printf("(%04x) Command Port 1 write : %02x\n", m_maincpu->pc(), data);
m_writeUpper = true;
}
WRITE8_MEMBER( monty_state::ioDisplayWrite_w )
{
m_dirty = true;
// Offset directly corresponds to sed1503, DD RAM address (offset 0x7f may be special?)
//printf("(%04x) %02x %02x\n", m_maincpu->pc(), offset, data);
uint8_t x = offset & 0x3f;
uint8_t y = (BIT(offset, 6) + (m_writeUpper ? 2 : 0)) << 3;
// Skip the controller and write straight to the LCD (pc=134f)
for (int i = 0; i < 8; i++)
{
// Pixel color
if (x < 42)
m_pixels[(y*42) + x] = BIT(data, i) ? 0xffffffff : 0xff000000;
y++;
}
}
WRITE_LINE_MEMBER( monty_state::halt_changed )
{
m_halt = state;
}
WRITE_LINE_MEMBER( monty_state::key_pressed )
{
if (!state && m_halt)
m_maincpu->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
}
uint32_t monty_state::lcd_update(screen_device& screen, bitmap_rgb32& bitmap, const rectangle& cliprect)
{
if (!m_dirty)
return 1;
uint8_t x,y,z;
m_dirty = false;
for (y = 0; y < 32; y++)
{
for (z = 0; z < 8; z++)
{
for (x = 0; x < 5; x++)
{
bitmap.pix32(y, x+z*6) = m_pixels[y*42 + z*5 + x];
}
bitmap.pix32(y, 5+z*6) = 0; // space between letters
}
bitmap.pix32(y, 48) = m_pixels[y*42 + 40];
bitmap.pix32(y, 49) = m_pixels[y*42 + 41];
}
return 0;
}
SED1520_UPDATE_CB(monty_state::screen_update)
{
// TODO: Not really a SED1520 - there are two SED1503s
return 0x00;
}
// TODO: Additional machine definition - Master Monty has a different memory layout
void monty_state::monty(machine_config &config)
{
// Basic machine hardware
Z80(config, m_maincpu, 3580000); // Ceramic resonator labeled 3.58MT
Z80(config, m_maincpu, 3.579545_MHz_XTAL); // Ceramic resonator labeled 3.58MT
m_maincpu->set_addrmap(AS_PROGRAM, &monty_state::monty_mem);
m_maincpu->set_addrmap(AS_IO, &monty_state::monty_io);
m_maincpu->halt_cb().set(FUNC(monty_state::halt_changed));
// Video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
screen.set_refresh_hz(50);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // Not accurate
screen.set_size(50, 32); // Two SED1503s (42x16 pixels) control the top and bottom halves
screen.set_visarea(0, 50-1, 0, 32-1);
screen.set_screen_update(FUNC(monty_state::lcd_update));
screen.set_refresh_hz(60);
screen.set_vblank_time(0);
screen.set_size(40+8+1, 32+1);
screen.set_visarea_full();
screen.set_screen_update(FUNC(monty_state::screen_update));
/* sound hardware */
SPEAKER(config, "mono").front_center();
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50);
SED1503(config, m_lcd[0], 32768).write_segs().set(FUNC(monty_state::lcd_output_w<0>));
SED1503(config, m_lcd[1], 32768).write_segs().set(FUNC(monty_state::lcd_output_w<1>));
config.set_default_layout(layout_monty);
// LCD controller interfaces
SED1520(config, m_sed0).set_screen_update_cb(FUNC(monty_state::screen_update));
// Sound hardware
SPEAKER(config, "speaker").front_center();
DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
VOLTAGE_REGULATOR(config, "vref").add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT);
}
void monty_state::mmonty(machine_config &config)
@ -295,23 +263,33 @@ void monty_state::mmonty(machine_config &config)
}
// ROM definitions
/******************************************************************************
ROM Definitions
******************************************************************************/
ROM_START( monty )
ROM_REGION(0xc000, "maincpu", 0)
ROM_LOAD( "monty_main.bin", 0x0000, 0x4000, CRC(720b4f55) SHA1(0106eb88d3fbbf25a745b9b6ee785ba13689d095) ) // 27128
ROM_LOAD( "monty_module1.bin", 0x4000, 0x4000, CRC(2725d8c3) SHA1(8273b9779c0915f9c7c43ea4fb460f43ce036358) ) // 27128
ROM_LOAD( "monty_module2.bin", 0x8000, 0x4000, CRC(db672e47) SHA1(bb14fe86df06cfa4b19625ba417d1a5bc8eae155) ) // 27128
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "monty_main.bin", 0x0000, 0x4000, CRC(720b4f55) SHA1(0106eb88d3fbbf25a745b9b6ee785ba13689d095) ) // 27128
ROM_LOAD( "monty_module1.bin", 0x4000, 0x4000, CRC(2725d8c3) SHA1(8273b9779c0915f9c7c43ea4fb460f43ce036358) ) // 27128
ROM_LOAD( "monty_module2.bin", 0x8000, 0x4000, CRC(db672e47) SHA1(bb14fe86df06cfa4b19625ba417d1a5bc8eae155) ) // 27128
ROM_END
ROM_START( mmonty )
ROM_REGION(0x10000, "maincpu", 0)
ROM_LOAD( "master_monty_main.bin", 0x0000, 0x8000, CRC(bb5ef4d4) SHA1(ba2c759e429f8740df419f9abb60832eddfba8ab) ) // 27C256
ROM_LOAD( "monty_module1.bin", 0x8000, 0x4000, CRC(2725d8c3) SHA1(8273b9779c0915f9c7c43ea4fb460f43ce036358) ) // 27128
ROM_LOAD( "monty_module2.bin", 0xc000, 0x4000, CRC(db672e47) SHA1(bb14fe86df06cfa4b19625ba417d1a5bc8eae155) ) // 27128
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "master_monty_main.bin", 0x0000, 0x8000, CRC(bb5ef4d4) SHA1(ba2c759e429f8740df419f9abb60832eddfba8ab) ) // 27C256
ROM_LOAD( "monty_module1.bin", 0x8000, 0x4000, CRC(2725d8c3) SHA1(8273b9779c0915f9c7c43ea4fb460f43ce036358) ) // 27128
ROM_LOAD( "monty_module2.bin", 0xc000, 0x4000, CRC(db672e47) SHA1(bb14fe86df06cfa4b19625ba417d1a5bc8eae155) ) // 27128
ROM_END
} // anonymous namespace
/******************************************************************************
Drivers
******************************************************************************/
// Drivers
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
COMP( 1980, monty, 0, 0, monty, monty, monty_state, empty_init, "Ritam", "Monty Plays Scrabble", MACHINE_NOT_WORKING )
COMP( 1982, mmonty, 0, 0, mmonty, monty, monty_state, empty_init, "Ritam", "Master Monty", MACHINE_NOT_WORKING )
COMP( 1983, monty, 0, 0, monty, monty, monty_state, empty_init, "Ritam", "Monty Plays Scrabble", MACHINE_SUPPORTS_SAVE )
COMP( 1987, mmonty, 0, 0, mmonty, monty, monty_state, empty_init, "Ritam", "Master Monty", MACHINE_SUPPORTS_SAVE )

View File

@ -22,7 +22,7 @@ The LCD screen is fairly large, it's the same one as in Saitek Simultano,
so a chessboard display + 7seg info.
TODO:
- LCD (need SED150x device + SVG screen)
- LCD (need SVG screen)
- not sure about comm/module leds
- make it a subdriver of saitek_leonardo.cpp? or too many differences
- same TODO list as saitek_leonardo.cpp
@ -36,6 +36,7 @@ TODO:
#include "sound/dac.h"
#include "sound/volt_reg.h"
#include "video/pwm.h"
#include "video/sed1500.h"
#include "speaker.h"
@ -211,7 +212,7 @@ void ren_state::main_map(address_map &map)
map(0x2400, 0x2400).w(FUNC(ren_state::leds_w));
map(0x2600, 0x2600).rw(FUNC(ren_state::control_r), FUNC(ren_state::control_w));
map(0x4000, 0x5fff).ram();
map(0x6000, 0x607f).nopw(); // lcd
map(0x6000, 0x607f).w("lcd", FUNC(sed1502_device::write));
map(0x8000, 0xffff).rom();
}
@ -291,6 +292,7 @@ void ren_state::ren(machine_config &config)
m_board->set_delay(attotime::from_msec(150));
/* video hardware */
SED1502(config, "lcd", 32768);
PWM_DISPLAY(config, m_display).set_size(9+1, 9);
config.set_default_layout(layout_saitek_renaissance);

View File

@ -122,20 +122,14 @@ private:
DECLARE_WRITE8_MEMBER(control_w);
DECLARE_READ8_MEMBER(control_r);
u8 m_inp_mux;
u8 m_control;
u8 m_shift;
u32 m_lcd_q;
u8 m_inp_mux = 0;
u8 m_control = 0;
u8 m_shift = 0;
u32 m_lcd_q = 0;
};
void ssystem3_state::machine_start()
{
// zerofill
m_inp_mux = 0;
m_control = 0;
m_shift = 0;
m_lcd_q = 0;
// register for savestates
save_item(NAME(m_inp_mux));
save_item(NAME(m_control));

25
src/mame/layout/monty.lay Normal file
View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<!--
license:CC0
-->
<mamelayout version="2">
<!-- define elements -->
<element name="lcdb"><rect><color red="1" green="1" blue="1" /></rect></element>
<element name="lcdm"><rect><color red="0.54" green="0.57" blue="0.58" /></rect></element>
<element name="lcda"><rect><color red="0.38" green="0.29" blue="0.28" /></rect></element>
<!-- build screen -->
<view name="Internal Layout">
<bounds left="0" right="59" top="0" bottom="35" />
<element ref="lcdb"><bounds x="0" y="0" width="59" height="35" /></element>
<screen index="0"><bounds x="5" y="1" width="49" height="33" /></screen>
<element ref="lcda" blend="add"><bounds x="0" y="0" width="59" height="35" /></element>
<element ref="lcdm" blend="multiply"><bounds x="0" y="0" width="59" height="35" /></element>
</view>
</mamelayout>