mirror of
https://github.com/holub/mame
synced 2025-04-22 00:11:58 +03:00
msx/msx_s1990.cpp, msx/msxtr.cpp: Added preliminary MSX-Engine S1990 device and started implementing MSX turbo R. (#12753)
Moved fsa1st and fsa1gt (Panasonic FSA-1 systems) to the new msx/msxtr.cpp source file.
This commit is contained in:
parent
f26d792959
commit
233a5e8279
91
src/mame/layout/msx_turbor.lay
Normal file
91
src/mame/layout/msx_turbor.lay
Normal file
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
license:CC0-1.0
|
||||
-->
|
||||
|
||||
<mamelayout version="2">
|
||||
<element name="green_led">
|
||||
<rect state="0">
|
||||
<color red="0.2" green="0.2" blue="0.2" />
|
||||
</rect>
|
||||
<rect state="1">
|
||||
<color red="0.0" green="1.0" blue="0.0" />
|
||||
</rect>
|
||||
</element>
|
||||
<element name="orange_led">
|
||||
<rect state="0">
|
||||
<color red="0.2" green="0.2" blue="0.2" />
|
||||
</rect>
|
||||
<rect state="1">
|
||||
<color red="1.0" green="0.6" blue="0.0" />
|
||||
</rect>
|
||||
</element>
|
||||
<element name="caps_name">
|
||||
<text string="Caps" align="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
</text>
|
||||
</element>
|
||||
<element name="code_name">
|
||||
<text string="かな" align="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
</text>
|
||||
</element>
|
||||
<element name="pause_name">
|
||||
<text string="Pause" align="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
</text>
|
||||
</element>
|
||||
<element name="r800_name">
|
||||
<text string="高速モード" align="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
</text>
|
||||
</element>
|
||||
<element name="drv0">
|
||||
<text string="Drive A" align="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
</text>
|
||||
</element>
|
||||
<element name="not_present" />
|
||||
|
||||
<view name="System LEDs">
|
||||
<screen index="0">
|
||||
<bounds x="75" y="0" width="1024" height="768" />
|
||||
</screen>
|
||||
<element name="caps_led_name" ref="caps_name">
|
||||
<bounds left="0" right="74" top="0" bottom="30" />
|
||||
</element>
|
||||
<element name="caps_led" ref="green_led">
|
||||
<bounds left="0" right="20" top="31" bottom="39" />
|
||||
</element>
|
||||
<element name="code_led_name" ref="code_name">
|
||||
<bounds left="0" right="74" top="40" bottom="70" />
|
||||
</element>
|
||||
<element name="code_led" ref="green_led">
|
||||
<bounds left="0" right="20" top="71" bottom="79" />
|
||||
</element>
|
||||
<element name="pause_led_name" ref="pause_name">
|
||||
<bounds left="0" right="74" top="80" bottom="110" />
|
||||
</element>
|
||||
<element name="pause_led" ref="green_led">
|
||||
<bounds left="0" right="20" top="111" bottom="119" />
|
||||
</element>
|
||||
<element name="r800_led_name" ref="r800_name">
|
||||
<bounds left="0" right="74" top="120" bottom="150" />
|
||||
</element>
|
||||
<element name="r800_led" ref="green_led">
|
||||
<bounds left="0" right="20" top="151" bottom="159" />
|
||||
</element>
|
||||
<element name="internal_drive0_name" ref="drv0">
|
||||
<bounds left="0" right="74" top="160" bottom="190" />
|
||||
</element>
|
||||
<element name="internal_drive0_led" ref="orange_led">
|
||||
<bounds left="0" right="20" top="191" bottom="199" />
|
||||
</element>
|
||||
<element name="internal_drive1_name" ref="not_present">
|
||||
<bounds left="0" right="74" top="200" bottom="230" />
|
||||
</element>
|
||||
<element name="internal_drive1_led" ref="not_present">
|
||||
<bounds left="0" right="20" top="231" bottom="239" />
|
||||
</element>
|
||||
</view>
|
||||
</mamelayout>
|
@ -32760,8 +32760,6 @@ expert3t //
|
||||
expertac //
|
||||
expertdx //
|
||||
fsa1fx // 1988 MSX2+ Japan
|
||||
fsa1gt //
|
||||
fsa1st //
|
||||
fsa1wsx // 1989 MSX2+ Japan
|
||||
fsa1wx // 1988 MSX2+ Japan
|
||||
fsa1wxa // 1988 MSX2+ Japan
|
||||
@ -32771,6 +32769,10 @@ phc35j // 1989 MSX2+ Japan
|
||||
phc70fd // 1988 MSX2+ Japan
|
||||
phc70fd2 // 1988 MSX2+ Japan
|
||||
|
||||
@source:msx/msxtr.cpp
|
||||
fsa1gt //
|
||||
fsa1st //
|
||||
|
||||
@source:msx/pengadvb.cpp
|
||||
pengadvb // (c) 1988 Screen
|
||||
pengadvb2 // (c) 1988 Comet
|
||||
|
@ -53,9 +53,6 @@ public:
|
||||
void phc35j(machine_config &config);
|
||||
void hbf1xdj(machine_config &config);
|
||||
void hbf1xv(machine_config &config);
|
||||
|
||||
void fsa1gt(machine_config &config);
|
||||
void fsa1st(machine_config &config);
|
||||
};
|
||||
|
||||
/******************************** MSX 2+ **********************************/
|
||||
@ -638,94 +635,6 @@ void msx2p_state::hbf1xv(machine_config &config)
|
||||
msx2plus(SND_YM2149, config, layout_msx_jp_1fdd);
|
||||
}
|
||||
|
||||
/* MSX Turbo-R - Panasonic FS-A1GT */
|
||||
|
||||
ROM_START(fsa1gt)
|
||||
ROM_REGION(0x46c000, "maincpu", 0)
|
||||
ROM_LOAD("a1gtbios.rom", 0x0000, 0x8000, CRC(937c8dbb) SHA1(242e73d8284a012b275c0a266844ebbc4269d787))
|
||||
ROM_LOAD("a1gtext.rom", 0x8000, 0x4000, CRC(70aea0fe) SHA1(018d7a5222f28514908fb1b1513286a6558a6d05))
|
||||
ROM_LOAD("a1gtdos.rom", 0xc000, 0x10000, CRC(bb2a0eae) SHA1(4880bf34f1c86fff5456ec2b4cf70d02339e2caa))
|
||||
ROM_LOAD("a1gtkdr.rom", 0x1c000, 0x8000, CRC(eaf0d125) SHA1(5b39c1ccd3a213b78e02927f56a9abc72cd8c28d))
|
||||
ROM_LOAD("a1gtmus.rom", 0x24000, 0x4000, CRC(f5f93437) SHA1(6aea1aef5ec31c1826c22edf580525f93baad425))
|
||||
ROM_LOAD("a1gtopt.rom", 0x28000, 0x4000, CRC(50d11f60) SHA1(b4433a3975c57dd440d6bf12dbd28b2ac1b90ef4))
|
||||
ROM_LOAD("a1gtkfn.rom", 0x2c000, 0x40000, CRC(1f6406fb) SHA1(5aff2d9b6efc723bc395b0f96f0adfa83cc54a49))
|
||||
ROM_LOAD("a1gtfirm.rom", 0x6c000, 0x400000, CRC(feefeadc) SHA1(e779c338eb91a7dea3ff75f3fde76b8af22c4a3a))
|
||||
ROM_END
|
||||
|
||||
void msx2p_state::fsa1gt(machine_config &config)
|
||||
{
|
||||
// AY8910 (in T9769)
|
||||
// FDC: tc8566af, 1 3.5" DSDD drive
|
||||
// 2 Cartridge slots
|
||||
// T9769C + S1990
|
||||
// FM built-in
|
||||
// Microphone
|
||||
// MIDI-in
|
||||
// MIDI-out
|
||||
// firmware switch
|
||||
// pause button
|
||||
// ren-sha turbo slider
|
||||
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "bios", 0, 0, 0, 2, "maincpu");
|
||||
add_internal_slot(config, MSX_SLOT_MUSIC, "mus", 0, 2, 1, 1, "maincpu", 0x24000).set_ym2413_tag(m_ym2413);
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "opt", 0, 3, 1, 1, "maincpu", 0x28000);
|
||||
add_cartridge_slot<1>(config, 1);
|
||||
add_cartridge_slot<2>(config, 2);
|
||||
add_internal_slot(config, MSX_SLOT_RAM_MM, "ram_mm", 3, 0, 0, 4).set_total_size(0x20000); // 128KB?? Mapper RAM
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "ext", 3, 1, 0, 1, "maincpu", 0x8000);
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "kdr", 3, 1, 1, 2, "maincpu", 0x1c000);
|
||||
add_internal_disk(config, MSX_SLOT_DISK4_TC8566, "dos", 3, 2, 1, 3, "maincpu", 0xc000);
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "firm", 3, 3, 0, 4, "maincpu", 0x6c000);
|
||||
MSX_SYSTEMFLAGS(config, "sysflags", m_maincpu, 0x00);
|
||||
|
||||
msx_ym2413(config);
|
||||
|
||||
turbor(SND_AY8910, config, layout_msx_jp_1fdd);
|
||||
}
|
||||
|
||||
/* MSX Turbo-R - Panasonic FS-A1ST */
|
||||
|
||||
ROM_START(fsa1st)
|
||||
ROM_REGION(0x46c000, "maincpu", 0)
|
||||
ROM_LOAD("a1stbios.rom", 0x0000, 0x8000, CRC(77b94ae0) SHA1(f078b5ec56884bfb81481d45c7151418770bff5a))
|
||||
ROM_LOAD("a1stext.rom", 0x8000, 0x4000, CRC(2c2c77a4) SHA1(373412f9c32762de1c3a7e27fc3d80614e0a0c8e))
|
||||
ROM_LOAD("a1stdos.rom", 0xc000, 0x10000, CRC(1fc71407) SHA1(5d2186658adcf4ce0c2d3232384b5712341108e5))
|
||||
ROM_LOAD("a1stkdr.rom", 0x1c000, 0x8000, CRC(eaf0d125) SHA1(5b39c1ccd3a213b78e02927f56a9abc72cd8c28d))
|
||||
ROM_LOAD("a1stmus.rom", 0x24000, 0x4000, CRC(fd7dec41) SHA1(e002a9b426732e6c2d31e548c40cf7c122348ce3))
|
||||
ROM_LOAD("a1stopt.rom", 0x28000, 0x4000, CRC(c6a4a2a1) SHA1(cb06dea7b025745f9d2b87dcf03ded615287ead3))
|
||||
ROM_LOAD("a1stkfn.rom", 0x2c000, 0x40000, CRC(1f6406fb) SHA1(5aff2d9b6efc723bc395b0f96f0adfa83cc54a49))
|
||||
ROM_LOAD("a1stfirm.rom", 0x6c000, 0x400000, CRC(139ac99c) SHA1(c212b11fda13f83dafed688c54d098e7e47ab225))
|
||||
ROM_END
|
||||
|
||||
void msx2p_state::fsa1st(machine_config &config)
|
||||
{
|
||||
// AY8910 (in T9769)
|
||||
// FDC: tc8566af, 1 3.5" DSDD drive
|
||||
// T9769C + S1990
|
||||
// 2 Cartridge slots
|
||||
// FM built-in
|
||||
// microphone
|
||||
// firmware switch
|
||||
// pause button
|
||||
// ren-sha turbo slider
|
||||
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "bios", 0, 0, 0, 2, "maincpu");
|
||||
add_internal_slot(config, MSX_SLOT_MUSIC, "mus", 0, 2, 1, 1, "maincpu", 0x24000).set_ym2413_tag(m_ym2413);
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "opt", 0, 3, 1, 1, "maincpu", 0x28000);
|
||||
add_cartridge_slot<1>(config, 1);
|
||||
add_cartridge_slot<2>(config, 2);
|
||||
add_internal_slot(config, MSX_SLOT_RAM_MM, "ram_mm", 3, 0, 0, 4).set_total_size(0x20000); // 128KB?? Mapper RAM
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "ext", 3, 1, 0, 1, "maincpu", 0x8000);
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "kdr", 3, 1, 1, 2, "maincpu", 0x1c000);
|
||||
add_internal_disk(config, MSX_SLOT_DISK4_TC8566, "dos", 3, 2, 1, 3, "maincpu", 0xc000);
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "firm", 3, 3, 0, 4, "maincpu", 0x6c000);
|
||||
MSX_SYSTEMFLAGS(config, "sysflags", m_maincpu, 0x00);
|
||||
|
||||
msx_ym2413(config);
|
||||
|
||||
turbor(SND_AY8910, config, layout_msx_jp_1fdd);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
COMP(19??, expert3i, 0, 0, expert3i, msx2, msx2p_state, empty_init, "Ciel", "Expert 3 IDE (MSX2+, Brazil)", MACHINE_NOT_WORKING) // Some hardware not emulated
|
||||
@ -741,8 +650,3 @@ COMP(1989, phc70fd2, 0, 0, phc70fd2, msx2jp, msx2p_state, empty
|
||||
COMP(1989, phc35j, 0, 0, phc35j, msx2jp, msx2p_state, empty_init, "Sanyo", "PHC-35J / Wavy35 (MSX2+, Japan)", 0)
|
||||
COMP(1988, hbf1xdj, 0, 0, hbf1xdj, msx2jp, msx2p_state, empty_init, "Sony", "HB-F1XDJ (MSX2+, Japan)", 0)
|
||||
COMP(1989, hbf1xv, 0, 0, hbf1xv, msx2jp, msx2p_state, empty_init, "Sony", "HB-F1XV (MSX2+, Japan)", 0)
|
||||
|
||||
/* MSX Turbo-R */
|
||||
/* Temporary placeholders, Turbo-R hardware is not supported yet */
|
||||
COMP(1991, fsa1gt, 0, 0, fsa1gt, msx2jp, msx2p_state, empty_init, "Panasonic", "FS-A1GT (MSX Turbo-R, Japan)", MACHINE_NOT_WORKING)
|
||||
COMP(1991, fsa1st, 0, 0, fsa1st, msx2jp, msx2p_state, empty_init, "Panasonic", "FS-A1ST (MSX Turbo-R, Japan)", MACHINE_NOT_WORKING)
|
||||
|
268
src/mame/msx/msx_s1990.cpp
Normal file
268
src/mame/msx/msx_s1990.cpp
Normal file
@ -0,0 +1,268 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Wilbert Pol
|
||||
#include "emu.h"
|
||||
#include "msx_s1990.h"
|
||||
|
||||
|
||||
#define LOG_CPU (1U << 1)
|
||||
#define LOG_PCM (1U << 2)
|
||||
//#define VERBOSE (LOG_CPU | LOG_PCM)
|
||||
#include "logmacro.h"
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
ASCII S1990 MSX-Engine
|
||||
|
||||
TODO:
|
||||
- Injection of wait states when accessing VDP when Z80 is active.
|
||||
- Injection of wait states when accessing VDP when R800 is active.
|
||||
- Injection of wait state to align 7MHz R800 bus with 3.5MHz MSX bus.
|
||||
- Unknown what the other internal registers do
|
||||
|
||||
Internal registers:
|
||||
- 0x00
|
||||
- 0x01
|
||||
- 0x02
|
||||
- 0x03
|
||||
- 0x04
|
||||
- 0x05 - Read only?
|
||||
Read
|
||||
7------- Unknown
|
||||
-6------ 1 - Firmware enabled
|
||||
--543210 Unknown
|
||||
- 0x06 - R/W - CPU Control
|
||||
Write
|
||||
76------ Unknown
|
||||
--5----- 0 - R800 active, 1 - Z80 active
|
||||
---43210 Unknown
|
||||
- 0x07
|
||||
- 0x08
|
||||
- 0x09
|
||||
- 0x0a
|
||||
- 0x0b
|
||||
- 0x0c
|
||||
- 0x0d
|
||||
- 0x0e - Byte before last byte written - read only?
|
||||
- 0x0f - Last byte written - read only?
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE(MSX_S1990, msx_s1990_device, "msx_s1990", "MSX-Engine S1990")
|
||||
|
||||
|
||||
msx_s1990_device::msx_s1990_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, MSX_S1990, tag, owner, clock)
|
||||
, device_memory_interface(mconfig, *this)
|
||||
, m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0)
|
||||
, m_io_config("io", ENDIANNESS_LITTLE, 8, 16, 0)
|
||||
, m_firmware_switch_cb(*this, 0)
|
||||
, m_pause_led_cb(*this)
|
||||
, m_r800_led_cb(*this)
|
||||
, m_dac_write_cb(*this)
|
||||
, m_sample_hold_cb(*this)
|
||||
, m_select_cb(*this)
|
||||
, m_filter_cb(*this)
|
||||
, m_muting_cb(*this)
|
||||
, m_comp_cb(*this, 0)
|
||||
, m_z80(*this, finder_base::DUMMY_TAG)
|
||||
, m_r800(*this, finder_base::DUMMY_TAG)
|
||||
, m_reg_index(0)
|
||||
, m_last_counter_reset(attotime::zero)
|
||||
, m_last_pcm_write_ticks(0)
|
||||
, m_pcm_control(0)
|
||||
, m_pcm_data(0x80)
|
||||
, m_dac_timer(nullptr)
|
||||
, m_z80_halt_enabled(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
device_memory_interface::space_config_vector msx_s1990_device::memory_space_config() const
|
||||
{
|
||||
return space_config_vector {
|
||||
std::make_pair(AS_PROGRAM, &m_program_config),
|
||||
std::make_pair(AS_IO, &m_io_config)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void msx_s1990_device::device_start()
|
||||
{
|
||||
space(AS_PROGRAM).specific(m_data);
|
||||
space(AS_IO).specific(m_io);
|
||||
|
||||
save_item(NAME(m_regs));
|
||||
save_item(NAME(m_reg_index));
|
||||
save_item(NAME(m_last_counter_reset));
|
||||
save_item(NAME(m_last_pcm_write_ticks));
|
||||
save_item(NAME(m_pcm_control));
|
||||
save_item(NAME(m_pcm_data));
|
||||
|
||||
m_dac_timer = timer_alloc(FUNC(msx_s1990_device::dac_write), this);
|
||||
}
|
||||
|
||||
|
||||
void msx_s1990_device::device_reset()
|
||||
{
|
||||
m_regs[6] = 0x20; // Z80 active
|
||||
m_last_counter_reset = attotime::zero;
|
||||
m_last_pcm_write_ticks = 0;
|
||||
m_z80->resume(SUSPEND_REASON_HALT);
|
||||
m_r800->suspend(SUSPEND_REASON_HALT, true);
|
||||
}
|
||||
|
||||
|
||||
INPUT_CHANGED_MEMBER(msx_s1990_device::pause_callback)
|
||||
{
|
||||
if (m_z80_halt_enabled && BIT(m_regs[0x06], 5))
|
||||
m_z80->set_input_line(Z80_INPUT_LINE_WAIT, BIT(newval, 0) ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
|
||||
void msx_s1990_device::pause_w(u8 data)
|
||||
{
|
||||
m_pause_led_cb(BIT(data, 0));
|
||||
m_z80_halt_enabled = BIT(data, 1);
|
||||
m_r800_led_cb(BIT(data, 7));
|
||||
}
|
||||
|
||||
|
||||
void msx_s1990_device::reg_index_write(u8 data)
|
||||
{
|
||||
m_reg_index = data;
|
||||
}
|
||||
|
||||
|
||||
u8 msx_s1990_device::regs_read()
|
||||
{
|
||||
if ((m_reg_index & 0x0f) == 0x05)
|
||||
return (m_firmware_switch_cb()) ? 0x40 : 0x00;
|
||||
return m_regs[m_reg_index & 0x0f];
|
||||
}
|
||||
|
||||
|
||||
void msx_s1990_device::regs_write(u8 data)
|
||||
{
|
||||
if ((m_reg_index & 0x0f) == 0x06)
|
||||
{
|
||||
if (BIT(data, 5))
|
||||
{
|
||||
LOGMASKED(LOG_CPU, "Enable Z80, disable R800\n");
|
||||
m_z80->resume(SUSPEND_REASON_HALT);
|
||||
m_r800->suspend(SUSPEND_REASON_HALT, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_CPU, "Disable Z80, enable R800\n");
|
||||
m_z80->suspend(SUSPEND_REASON_HALT, true);
|
||||
m_r800->resume(SUSPEND_REASON_HALT);
|
||||
}
|
||||
}
|
||||
|
||||
m_regs[m_reg_index & 0x0f] = data;
|
||||
}
|
||||
|
||||
|
||||
void msx_s1990_device::mem_write(offs_t offset, u8 data)
|
||||
{
|
||||
// TODO Clock syncing when in R800 mode
|
||||
m_regs[0x0e] = m_regs[0x0f];
|
||||
m_regs[0x0f] = data;
|
||||
m_data.write_byte(offset, data);
|
||||
}
|
||||
|
||||
|
||||
u8 msx_s1990_device::mem_read(offs_t offset)
|
||||
{
|
||||
// TODO Clock syncing when in R800 mode
|
||||
return m_data.read_byte(offset);
|
||||
}
|
||||
|
||||
|
||||
void msx_s1990_device::io_write(offs_t offset, u8 data)
|
||||
{
|
||||
// TODO Clock syncing/extra wait cycles
|
||||
// TODO Injection of wait states when accessing VDP
|
||||
m_io.write_byte(offset, data);
|
||||
}
|
||||
|
||||
|
||||
u8 msx_s1990_device::io_read(offs_t offset)
|
||||
{
|
||||
// TODO Clock syncing/extra wait cycles
|
||||
return m_io.read_byte(offset);
|
||||
}
|
||||
|
||||
|
||||
void msx_s1990_device::counter_write(u8 data)
|
||||
{
|
||||
// TODO: Round to last counter tick?
|
||||
m_last_counter_reset = machine().time();
|
||||
}
|
||||
|
||||
|
||||
u8 msx_s1990_device::counter_read(offs_t offset)
|
||||
{
|
||||
u64 counter = attotime_to_clocks(machine().time() - m_last_counter_reset) / 28;
|
||||
return (counter >> (8 * BIT(offset, 0))) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
TIMER_CALLBACK_MEMBER(msx_s1990_device::dac_write)
|
||||
{
|
||||
m_dac_write_cb(m_pcm_data);
|
||||
}
|
||||
|
||||
|
||||
void msx_s1990_device::pmdac(u8 data)
|
||||
{
|
||||
m_pcm_data = data;
|
||||
if (!BIT(m_pcm_control, 1))
|
||||
{
|
||||
// Round to last counter tick and schedule next dac write?
|
||||
m_last_pcm_write_ticks = machine().time().as_ticks(PCM_FREQUENCY);
|
||||
m_dac_timer->adjust(attotime::from_ticks(m_last_pcm_write_ticks + 1, PCM_FREQUENCY));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
u8 msx_s1990_device::pmcnt()
|
||||
{
|
||||
return (machine().time().as_ticks(PCM_FREQUENCY) - m_last_pcm_write_ticks) & 0x03;
|
||||
}
|
||||
|
||||
|
||||
void msx_s1990_device::pmcntl(u8 data)
|
||||
{
|
||||
// 7------- 0
|
||||
// -6------ 0
|
||||
// --5----- 0
|
||||
// ---4---- SMPL
|
||||
// ----3--- SEL
|
||||
// -----2-- FILT
|
||||
// ------1- MUTE
|
||||
// -------0 ADDA ??
|
||||
|
||||
LOGMASKED(LOG_PCM, "pmcntl: %02x\n", data);
|
||||
m_pcm_control = data & 0x1f;
|
||||
m_sample_hold_cb(BIT(m_pcm_control, 4));
|
||||
m_select_cb(BIT(m_pcm_control, 3));
|
||||
m_filter_cb(BIT(m_pcm_control, 2));
|
||||
m_muting_cb(BIT(m_pcm_control, 1));
|
||||
}
|
||||
|
||||
|
||||
u8 msx_s1990_device::pmstat()
|
||||
{
|
||||
// 7------- COMP
|
||||
// -6------ 0
|
||||
// --5----- 0
|
||||
// ---4---- SMPL
|
||||
// ----3--- SEL
|
||||
// -----2-- FILT
|
||||
// ------1- MUTE
|
||||
// -------0 BUFF ??
|
||||
|
||||
return (m_pcm_control & 0x1f) | (m_comp_cb() ? 0x80 : 0x00);
|
||||
}
|
93
src/mame/msx/msx_s1990.h
Normal file
93
src/mame/msx/msx_s1990.h
Normal file
@ -0,0 +1,93 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Wilbert Pol
|
||||
#ifndef MAME_MSX_MSX_S1990_H
|
||||
#define MAME_MSX_MSX_S1990_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/z80/r800.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
|
||||
DECLARE_DEVICE_TYPE(MSX_S1990, msx_s1990_device)
|
||||
|
||||
class msx_s1990_device : public device_t,
|
||||
public device_memory_interface
|
||||
{
|
||||
public:
|
||||
msx_s1990_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
static constexpr feature_type imperfect_features() { return feature::TIMING; }
|
||||
|
||||
// configuration
|
||||
template <typename T> void set_z80_tag(T &&tag) { m_z80.set_tag(std::forward<T>(tag)); }
|
||||
template <typename T> void set_r800_tag(T &&tag) { m_r800.set_tag(std::forward<T>(tag)); }
|
||||
auto firmware_switch_callback() { return m_firmware_switch_cb.bind(); }
|
||||
auto pause_led_callback() { return m_pause_led_cb.bind(); }
|
||||
auto r800_led_callback() { return m_r800_led_cb.bind(); }
|
||||
auto dac_write_callback() { return m_dac_write_cb.bind(); }
|
||||
auto sample_hold_callback() { return m_sample_hold_cb.bind(); }
|
||||
auto select_callback() { return m_select_cb.bind(); }
|
||||
auto filter_callback() { return m_filter_cb.bind(); }
|
||||
auto muting_callback() { return m_muting_cb.bind(); }
|
||||
auto comp_callback() { return m_comp_cb.bind(); }
|
||||
|
||||
void pause_w(u8 data);
|
||||
|
||||
void reg_index_write(u8 data);
|
||||
u8 regs_read();
|
||||
void regs_write(u8 data);
|
||||
|
||||
void mem_write(offs_t offset, u8 data);
|
||||
u8 mem_read(offs_t offset);
|
||||
void io_write(offs_t offset, u8 data);
|
||||
u8 io_read(offs_t offset);
|
||||
|
||||
void counter_write(u8 data);
|
||||
u8 counter_read(offs_t offset);
|
||||
|
||||
void pmdac(u8 data);
|
||||
u8 pmcnt();
|
||||
void pmcntl(u8 data);
|
||||
u8 pmstat();
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(pause_callback);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// device_memory_interface implementation
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
virtual u32 translate_memory_address(u16 address) { return address; }
|
||||
|
||||
private:
|
||||
TIMER_CALLBACK_MEMBER(dac_write);
|
||||
|
||||
static constexpr u32 PCM_FREQUENCY = 15750;
|
||||
const address_space_config m_program_config;
|
||||
const address_space_config m_io_config;
|
||||
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_data;
|
||||
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_io;
|
||||
devcb_read_line m_firmware_switch_cb;
|
||||
devcb_write_line m_pause_led_cb;
|
||||
devcb_write_line m_r800_led_cb;
|
||||
devcb_write8 m_dac_write_cb;
|
||||
devcb_write_line m_sample_hold_cb;
|
||||
devcb_write_line m_select_cb;
|
||||
devcb_write_line m_filter_cb;
|
||||
devcb_write_line m_muting_cb;
|
||||
devcb_read_line m_comp_cb;
|
||||
required_device<z80_device> m_z80;
|
||||
required_device<r800_device> m_r800;
|
||||
|
||||
u8 m_regs[16];
|
||||
u8 m_reg_index;
|
||||
attotime m_last_counter_reset;
|
||||
u64 m_last_pcm_write_ticks;
|
||||
u8 m_pcm_control;
|
||||
u8 m_pcm_data;
|
||||
emu_timer *m_dac_timer;
|
||||
bool m_z80_halt_enabled;
|
||||
};
|
||||
|
||||
#endif // MAME_MSX_MSX_S1990_H
|
463
src/mame/msx/msxtr.cpp
Normal file
463
src/mame/msx/msxtr.cpp
Normal file
@ -0,0 +1,463 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Wilbert Pol
|
||||
|
||||
#include "emu.h"
|
||||
#include "msx.h"
|
||||
#include "msx_keyboard.h"
|
||||
#include "msx_s1990.h"
|
||||
#include "msx_systemflags.h"
|
||||
#include "bus/midi/midi.h"
|
||||
#include "bus/msx/slot/disk.h"
|
||||
#include "bus/msx/slot/music.h"
|
||||
#include "bus/msx/slot/panasonic08r.h"
|
||||
#include "bus/msx/slot/ram_mm.h"
|
||||
#include "bus/msx/slot/rom.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "softlist_dev.h"
|
||||
|
||||
#include "msx_turbor.lh"
|
||||
|
||||
using namespace msx_keyboard;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
MSX Turbo-R machine drivers
|
||||
|
||||
The R800 and Z80 see exactly the same memory layouts, only one of the two CPUs
|
||||
is active at any one time. The S1990 controls which CPU is active and can inject
|
||||
wait states depending on which cpu is active.
|
||||
|
||||
TODO:
|
||||
- sfg extensions may not work due to irq callbacks being registered with the Z80 only.
|
||||
- v9958 commands seem to execute too fast. Several software items hang because of this.
|
||||
- verify midi interface operation on fsa1gt.
|
||||
- Implement DAC/PCM related hardware/filter and hook it up to the S1990.
|
||||
- Microphone input.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
namespace {
|
||||
|
||||
class msxtr_state : public msx2p_base_state
|
||||
{
|
||||
public:
|
||||
msxtr_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: msx2p_base_state(mconfig, type, tag, 21.477272_MHz_XTAL, 6)
|
||||
, m_r800(*this, "r800")
|
||||
, m_s1990(*this, "s1990")
|
||||
, m_pause_switch(*this, "PAUSE")
|
||||
, m_firmware_switch(*this, "FIRMWARE")
|
||||
, m_pause_led(*this, "pause_led")
|
||||
, m_r800_led(*this, "r800_led")
|
||||
, m_pcmdac(*this, "pcmdac")
|
||||
{
|
||||
}
|
||||
|
||||
void fsa1st(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
void turbor(ay8910_type ay8910_type, machine_config &config, const internal_layout &layout);
|
||||
void turbor_add_softlists(machine_config &config);
|
||||
void s1990_mem_map(address_map &map);
|
||||
void s1990_io_map(address_map &map);
|
||||
void cpu_mem_map(address_map &map);
|
||||
void cpu_io_map(address_map &map);
|
||||
|
||||
virtual void setup_slot_spaces(msx_internal_slot_interface &device) override;
|
||||
virtual address_space& get_io_space() override;
|
||||
|
||||
void pause_led_w(int state);
|
||||
void r800_led_w(int state);
|
||||
void pcm_dac_w(u8 data);
|
||||
void pcm_sample_hold_w(int state);
|
||||
void pcm_select_w(int state);
|
||||
void pcm_filter_w(int state);
|
||||
void muting_w(int state);
|
||||
int pcm_comp_r();
|
||||
|
||||
required_device<r800_device> m_r800;
|
||||
required_device<msx_s1990_device> m_s1990;
|
||||
required_ioport m_pause_switch;
|
||||
required_ioport m_firmware_switch;
|
||||
output_finder<> m_pause_led;
|
||||
output_finder<> m_r800_led;
|
||||
required_device<dac_8bit_r2r_device> m_pcmdac;
|
||||
u8 m_pcm_last_sample;
|
||||
u8 m_pcm_held_sample;
|
||||
u8 m_pcm_sample_hold;
|
||||
};
|
||||
|
||||
class fsa1gt_state : public msxtr_state
|
||||
{
|
||||
public:
|
||||
fsa1gt_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: msxtr_state(mconfig, type, tag)
|
||||
, m_i8251(*this, "i8251")
|
||||
, m_i8254(*this, "i8254")
|
||||
, m_midiin(*this, "midiin_port")
|
||||
, m_midiout(*this, "midiout_port")
|
||||
, m_dtr(false)
|
||||
, m_rts(false)
|
||||
, m_rxrdy(false)
|
||||
, m_timer2_ff(false)
|
||||
{
|
||||
}
|
||||
|
||||
void fsa1gt(machine_config &config);
|
||||
|
||||
private:
|
||||
required_device<i8251_device> m_i8251;
|
||||
required_device<pit8254_device> m_i8254;
|
||||
required_device<midi_port_device> m_midiin;
|
||||
required_device<midi_port_device> m_midiout;
|
||||
bool m_dtr;
|
||||
bool m_rts;
|
||||
bool m_rxrdy;
|
||||
bool m_timer2_ff;
|
||||
|
||||
void s1990_io_map(address_map &map);
|
||||
void dtr_w(int state);
|
||||
void rts_w(int state);
|
||||
void rxrdy_w(int state);
|
||||
void timer0_w(int state);
|
||||
void timer2_w(int state);
|
||||
void update_midi_int_state();
|
||||
void clear_timer2_ff(u8 data);
|
||||
};
|
||||
|
||||
|
||||
address_space& msxtr_state::get_io_space()
|
||||
{
|
||||
return m_s1990->space(AS_IO);
|
||||
}
|
||||
|
||||
void msxtr_state::setup_slot_spaces(msx_internal_slot_interface &device)
|
||||
{
|
||||
device.set_memory_space(m_s1990, AS_PROGRAM);
|
||||
device.set_io_space(m_s1990, AS_IO);
|
||||
// TODO: This is used for signalling irq vectors. But that should go to the currently active cpu not just the z80.
|
||||
device.set_maincpu(m_maincpu);
|
||||
}
|
||||
|
||||
void msxtr_state::machine_start()
|
||||
{
|
||||
msx2p_base_state::machine_start();
|
||||
m_pause_led.resolve();
|
||||
m_r800_led.resolve();
|
||||
|
||||
save_item(NAME(m_pcm_last_sample));
|
||||
save_item(NAME(m_pcm_held_sample));
|
||||
save_item(NAME(m_pcm_sample_hold));
|
||||
}
|
||||
|
||||
void msxtr_state::machine_reset()
|
||||
{
|
||||
msx2p_base_state::machine_reset();
|
||||
m_pause_led = 0;
|
||||
m_r800_led = 0;
|
||||
}
|
||||
|
||||
void msxtr_state::s1990_mem_map(address_map &map)
|
||||
{
|
||||
memory_map(map);
|
||||
}
|
||||
|
||||
void msxtr_state::s1990_io_map(address_map &map)
|
||||
{
|
||||
msx2plus_io_map(map);
|
||||
map(0xa4, 0xa4).rw(m_s1990, FUNC(msx_s1990_device::pmcnt), FUNC(msx_s1990_device::pmdac));
|
||||
map(0xa5, 0xa5).rw(m_s1990, FUNC(msx_s1990_device::pmstat), FUNC(msx_s1990_device::pmcntl));
|
||||
map(0xa7, 0xa7).portr(m_pause_switch.finder_tag());
|
||||
map(0xa7, 0xa7).w(m_s1990, FUNC(msx_s1990_device::pause_w));
|
||||
map(0xe4, 0xe4).w(m_s1990, FUNC(msx_s1990_device::reg_index_write));
|
||||
map(0xe5, 0xe5).rw(m_s1990, FUNC(msx_s1990_device::regs_read), FUNC(msx_s1990_device::regs_write));
|
||||
map(0xe6, 0xe6).w(m_s1990, FUNC(msx_s1990_device::counter_write));
|
||||
map(0xe6, 0xe7).r(m_s1990, FUNC(msx_s1990_device::counter_read));
|
||||
}
|
||||
|
||||
void msxtr_state::cpu_mem_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).rw(m_s1990, FUNC(msx_s1990_device::mem_read), FUNC(msx_s1990_device::mem_write));
|
||||
}
|
||||
|
||||
void msxtr_state::cpu_io_map(address_map &map)
|
||||
{
|
||||
map.global_mask(0xff);
|
||||
map(0x00, 0xff).rw(m_s1990, FUNC(msx_s1990_device::io_read), FUNC(msx_s1990_device::io_write));
|
||||
}
|
||||
|
||||
void msxtr_state::pause_led_w(int state)
|
||||
{
|
||||
m_pause_led = state;
|
||||
}
|
||||
|
||||
void msxtr_state::r800_led_w(int state)
|
||||
{
|
||||
m_r800_led = state;
|
||||
}
|
||||
|
||||
void msxtr_state::turbor(ay8910_type ay8910_type, machine_config &config, const internal_layout &layout)
|
||||
{
|
||||
msx2plus_base(ay8910_type, config, layout);
|
||||
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &msxtr_state::cpu_mem_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &msxtr_state::cpu_io_map);
|
||||
|
||||
R800(config, m_r800, 28.636363_MHz_XTAL);
|
||||
m_r800->set_addrmap(AS_PROGRAM, &msxtr_state::cpu_mem_map);
|
||||
m_r800->set_addrmap(AS_IO, &msxtr_state::cpu_io_map);
|
||||
|
||||
MSX_S1990(config, m_s1990, 28.636363_MHz_XTAL / 4);
|
||||
m_s1990->set_addrmap(AS_PROGRAM, &msxtr_state::s1990_mem_map);
|
||||
m_s1990->set_addrmap(AS_IO, &msxtr_state::s1990_io_map);
|
||||
m_s1990->set_z80_tag(m_maincpu);
|
||||
m_s1990->set_r800_tag(m_r800);
|
||||
m_s1990->pause_led_callback().set(FUNC(msxtr_state::pause_led_w));
|
||||
m_s1990->r800_led_callback().set(FUNC(msxtr_state::r800_led_w));
|
||||
m_s1990->firmware_switch_callback().set_ioport(m_firmware_switch);
|
||||
m_s1990->dac_write_callback().set(FUNC(msxtr_state::pcm_dac_w));
|
||||
m_s1990->sample_hold_callback().set(FUNC(msxtr_state::pcm_sample_hold_w));
|
||||
m_s1990->select_callback().set(FUNC(msxtr_state::pcm_select_w));
|
||||
m_s1990->filter_callback().set(FUNC(msxtr_state::pcm_filter_w));
|
||||
m_s1990->muting_callback().set(FUNC(msxtr_state::muting_w));
|
||||
m_s1990->comp_callback().set(FUNC(msxtr_state::pcm_comp_r));
|
||||
|
||||
// TODO: Do IRQ requests go to both cpus (only to be ignored by the inactive cpu) or only to the currently active cpu?
|
||||
m_mainirq->output_handler().append_inputline(m_r800, INPUT_LINE_IRQ0);
|
||||
|
||||
DAC_8BIT_R2R(config, m_pcmdac).add_route(ALL_OUTPUTS, m_speaker, 1.0); // Unknown DAC type
|
||||
|
||||
// Software lists
|
||||
turbor_add_softlists(config);
|
||||
}
|
||||
|
||||
void msxtr_state::pcm_dac_w(u8 data)
|
||||
{
|
||||
m_pcmdac->write(data);
|
||||
m_pcm_last_sample = data;
|
||||
}
|
||||
|
||||
void msxtr_state::pcm_sample_hold_w(int state)
|
||||
{
|
||||
if (!m_pcm_sample_hold && state)
|
||||
m_pcm_held_sample = m_pcm_last_sample;
|
||||
m_pcm_sample_hold = state;
|
||||
}
|
||||
|
||||
void msxtr_state::pcm_select_w(int state)
|
||||
{
|
||||
// TODO pcm select
|
||||
}
|
||||
|
||||
void msxtr_state::pcm_filter_w(int state)
|
||||
{
|
||||
// TODO enable pcm filter
|
||||
}
|
||||
|
||||
int msxtr_state::pcm_comp_r()
|
||||
{
|
||||
// TODO pcm output compare
|
||||
return 0;
|
||||
}
|
||||
|
||||
void msxtr_state::muting_w(int state)
|
||||
{
|
||||
// TODO mute all sound
|
||||
}
|
||||
|
||||
void msxtr_state::turbor_add_softlists(machine_config &config)
|
||||
{
|
||||
if (m_hw_def.has_cartslot())
|
||||
{
|
||||
SOFTWARE_LIST(config, "cart_list").set_original("msxr_cart");
|
||||
SOFTWARE_LIST(config, "msx2p_cart_list").set_compatible("msx2p_cart");
|
||||
SOFTWARE_LIST(config, "msx2_cart_list").set_compatible("msx2_cart");
|
||||
SOFTWARE_LIST(config, "msx1_cart_list").set_compatible("msx1_cart");
|
||||
}
|
||||
|
||||
if (m_hw_def.has_fdc())
|
||||
{
|
||||
SOFTWARE_LIST(config, "flop_list").set_original("msxr_flop");
|
||||
SOFTWARE_LIST(config, "msx2p_flop_list").set_compatible("msx2p_flop");
|
||||
SOFTWARE_LIST(config, "msx2_flop_list").set_compatible("msx2_flop");
|
||||
SOFTWARE_LIST(config, "msx1_flop_list").set_compatible("msx1_flop");
|
||||
}
|
||||
}
|
||||
|
||||
/* MSX Turbo-R - Panasonic FS-A1GT */
|
||||
|
||||
ROM_START(fsa1gt)
|
||||
ROM_REGION(0x400000, "firmware", 0)
|
||||
// This should be 2 1MB roms at locations IC20 and IC23.
|
||||
ROM_LOAD("a1gtfirm.rom", 0, 0x400000, CRC(feefeadc) SHA1(e779c338eb91a7dea3ff75f3fde76b8af22c4a3a) BAD_DUMP)
|
||||
|
||||
ROM_REGION(0x40000, "kanji", 0)
|
||||
ROM_LOAD("a1gtkfn.rom", 0, 0x40000, CRC(1f6406fb) SHA1(5aff2d9b6efc723bc395b0f96f0adfa83cc54a49))
|
||||
ROM_END
|
||||
|
||||
void fsa1gt_state::s1990_io_map(address_map &map)
|
||||
{
|
||||
msxtr_state::s1990_io_map(map);
|
||||
map(0xe8, 0xe9).rw(m_i8251, FUNC(i8251_device::read), FUNC(i8251_device::write));
|
||||
map(0xea, 0xea).w(FUNC(fsa1gt_state::clear_timer2_ff));
|
||||
map(0xec, 0xef).rw(m_i8254, FUNC(pit8254_device::read), FUNC(pit8254_device::write));
|
||||
}
|
||||
|
||||
void fsa1gt_state::fsa1gt(machine_config &config)
|
||||
{
|
||||
// AY8910 (in T9769)
|
||||
// FDC: tc8566af, 1 3.5" DSDD drive
|
||||
// 2 Cartridge slots
|
||||
// T9769C + S1990
|
||||
// FM built-in
|
||||
// Microphone
|
||||
// MIDI-in
|
||||
// MIDI-out
|
||||
// firmware switch
|
||||
// pause button
|
||||
// ren-sha turbo slider
|
||||
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "bios", 0, 0, 0, 2, "firmware", 0x050000);
|
||||
add_internal_slot(config, MSX_SLOT_MUSIC, "msxmusic", 0, 2, 1, 1, "firmware", 0x07c000).set_ym2413_tag(m_ym2413);
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "opt", 0, 3, 1, 1, "firmware", 0x048000);
|
||||
add_cartridge_slot<1>(config, 1);
|
||||
add_cartridge_slot<2>(config, 2);
|
||||
add_internal_slot(config, MSX_SLOT_RAM_MM, "ram_mm", 3, 0, 0, 4).set_total_size(0x80000); // 512KB Mapper RAM
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "ext", 3, 1, 0, 1, "firmware", 0x070000);
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "kdr", 3, 1, 1, 2, "firmware", 0x074000);
|
||||
add_internal_disk(config, MSX_SLOT_DISK4_TC8566, "dos", 3, 2, 1, 3, "firmware", 0x060000);
|
||||
add_internal_slot(config, MSX_SLOT_PANASONIC08R, "firmware", 3, 3, 0, 4, "firmware").set_sram_size(0x8000).set_mm_tag("ram_mm");
|
||||
|
||||
MSX_SYSTEMFLAGS(config, "sysflags", m_maincpu, 0x00);
|
||||
|
||||
msx_ym2413(config);
|
||||
|
||||
m_hw_def.has_cassette(false);
|
||||
turbor(SND_AY8910, config, layout_msx_turbor);
|
||||
m_s1990->set_addrmap(AS_IO, &fsa1gt_state::s1990_io_map);
|
||||
|
||||
I8251(config, m_i8251, 16_MHz_XTAL / 4); // Not sure about this
|
||||
m_i8251->txd_handler().set(m_midiout, FUNC(midi_port_device::write_txd));
|
||||
m_i8251->dtr_handler().set(*this, FUNC(fsa1gt_state::dtr_w));
|
||||
m_i8251->rts_handler().set(*this, FUNC(fsa1gt_state::rts_w));
|
||||
m_i8251->rxrdy_handler().set(*this, FUNC(fsa1gt_state::rxrdy_w));
|
||||
|
||||
PIT8254(config, m_i8254);
|
||||
m_i8254->set_clk<0>(16_MHz_XTAL / 4);
|
||||
m_i8254->set_clk<2>(16_MHz_XTAL/ 4);
|
||||
m_i8254->out_handler<0>().set(*this, FUNC(fsa1gt_state::timer0_w));
|
||||
m_i8254->out_handler<2>().set(*this, FUNC(fsa1gt_state::timer2_w));
|
||||
|
||||
MIDI_PORT(config, m_midiin, midiin_slot, "midiin").rxd_handler().set(m_i8251, FUNC(i8251_device::rx_w));
|
||||
MIDI_PORT(config, m_midiout, midiout_slot, "midiout");
|
||||
}
|
||||
|
||||
void fsa1gt_state::rts_w(int state)
|
||||
{
|
||||
m_rts = state;
|
||||
update_midi_int_state();
|
||||
}
|
||||
|
||||
void fsa1gt_state::rxrdy_w(int state)
|
||||
{
|
||||
m_rxrdy = state;
|
||||
update_midi_int_state();
|
||||
}
|
||||
|
||||
void fsa1gt_state::dtr_w(int state)
|
||||
{
|
||||
m_dtr = state;
|
||||
update_midi_int_state();
|
||||
}
|
||||
|
||||
void fsa1gt_state::timer0_w(int state)
|
||||
{
|
||||
m_i8251->tx_clock_w(state);
|
||||
m_i8251->rx_clock_w(state);
|
||||
}
|
||||
|
||||
void fsa1gt_state::timer2_w(int state)
|
||||
{
|
||||
m_timer2_ff = m_timer2_ff | state;
|
||||
m_i8254->write_clk1(state);
|
||||
update_midi_int_state();
|
||||
}
|
||||
|
||||
void fsa1gt_state::clear_timer2_ff(u8 data)
|
||||
{
|
||||
m_timer2_ff = false;
|
||||
update_midi_int_state();
|
||||
}
|
||||
|
||||
void fsa1gt_state::update_midi_int_state()
|
||||
{
|
||||
m_i8251->write_dsr(m_timer2_ff && m_dtr);
|
||||
m_mainirq->in_w<3>(!((m_timer2_ff && m_dtr) || (m_rts && m_rxrdy)));
|
||||
}
|
||||
|
||||
/* MSX Turbo-R - Panasonic FS-A1ST */
|
||||
|
||||
ROM_START(fsa1st)
|
||||
ROM_REGION(0x400000, "firmware", 0)
|
||||
// This should be either 3 512KB roms or 1 1MB and 1 512KB rom (at IC12 and IC18?). Both variants are known to exist.
|
||||
ROM_LOAD("a1stfirm.rom", 0, 0x400000, CRC(139ac99c) SHA1(c212b11fda13f83dafed688c54d098e7e47ab225) BAD_DUMP)
|
||||
|
||||
ROM_REGION(0x40000, "kanji", 0)
|
||||
ROM_LOAD("a1stkfn.rom", 0, 0x40000, CRC(1f6406fb) SHA1(5aff2d9b6efc723bc395b0f96f0adfa83cc54a49))
|
||||
ROM_END
|
||||
|
||||
void msxtr_state::fsa1st(machine_config &config)
|
||||
{
|
||||
// AY8910 (in T9769)
|
||||
// FDC: tc8566af, 1 3.5" DSDD drive
|
||||
// T9769C + S1990
|
||||
// 2 Cartridge slots
|
||||
// FM built-in
|
||||
// microphone
|
||||
// firmware switch
|
||||
// pause button
|
||||
// ren-sha turbo slider
|
||||
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "bios", 0, 0, 0, 2, "firmware", 0x050000);
|
||||
add_internal_slot(config, MSX_SLOT_MUSIC, "msxmusic", 0, 2, 1, 1, "firmware", 0x07c000).set_ym2413_tag(m_ym2413);
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "opt", 0, 3, 1, 1, "firmware", 0x048000);
|
||||
add_cartridge_slot<1>(config, 1);
|
||||
add_cartridge_slot<2>(config, 2);
|
||||
add_internal_slot(config, MSX_SLOT_RAM_MM, "ram_mm", 3, 0, 0, 4).set_total_size(0x40000); // 256KB Mapper RAM
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "ext", 3, 1, 0, 1, "firmware", 0x070000);
|
||||
add_internal_slot(config, MSX_SLOT_ROM, "kdr", 3, 1, 1, 2, "firmware", 0x074000);
|
||||
add_internal_disk(config, MSX_SLOT_DISK4_TC8566, "dos", 3, 2, 1, 3, "firmware", 0x060000);
|
||||
add_internal_slot(config, MSX_SLOT_PANASONIC08R, "firmware", 3, 3, 0, 4, "firmware").set_sram_size(0x4000).set_mm_tag("ram_mm");
|
||||
|
||||
MSX_SYSTEMFLAGS(config, "sysflags", m_maincpu, 0x00);
|
||||
|
||||
msx_ym2413(config);
|
||||
|
||||
m_hw_def.has_cassette(false);
|
||||
turbor(SND_AY8910, config, layout_msx_turbor);
|
||||
}
|
||||
|
||||
INPUT_PORTS_START(msxtr)
|
||||
PORT_INCLUDE(msx2jp)
|
||||
|
||||
PORT_START("PAUSE")
|
||||
PORT_CONFNAME(0x01, 0x00, "Pause") PORT_CHANGED_MEMBER("s1990", msx_s1990_device, pause_callback, 0)
|
||||
PORT_CONFSETTING(0x00, "off")
|
||||
PORT_CONFSETTING(0x01, "on")
|
||||
|
||||
PORT_START("FIRMWARE")
|
||||
PORT_CONFNAME(0x01, 0x01, "Firmware")
|
||||
PORT_CONFSETTING(0x01, "enabled")
|
||||
PORT_CONFSETTING(0x00, "disabled")
|
||||
INPUT_PORTS_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* MSX Turbo-R */
|
||||
COMP(1991, fsa1gt, 0, 0, fsa1gt, msxtr, fsa1gt_state, empty_init, "Panasonic", "FS-A1GT (MSX Turbo-R, Japan)", MACHINE_NOT_WORKING)
|
||||
COMP(1991, fsa1st, 0, 0, fsa1st, msxtr, msxtr_state, empty_init, "Panasonic", "FS-A1ST (MSX Turbo-R, Japan)", MACHINE_NOT_WORKING)
|
Loading…
Reference in New Issue
Block a user