mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +03:00
Machines promoted to working
---------------------------- Monty Plays Scrabble [hap] Master Monty [hap]
This commit is contained in:
parent
d983d9ec93
commit
623dc28919
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
116
src/devices/video/sed1500.cpp
Normal file
116
src/devices/video/sed1500.cpp
Normal 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];
|
||||
}
|
85
src/devices/video/sed1500.h
Normal file
85
src/devices/video/sed1500.h
Normal 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
|
@ -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));
|
||||
|
@ -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 )
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
25
src/mame/layout/monty.lay
Normal 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>
|
Loading…
Reference in New Issue
Block a user