Skip to content

Commit 73079b4

Browse files
committed
msx2_cart.xml: Add FS-SR021 MSX2 Word Processor.
1 parent b5832f7 commit 73079b4

File tree

7 files changed

+279
-0
lines changed

7 files changed

+279
-0
lines changed

hash/msx2_cart.xml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2873,6 +2873,44 @@ LZ93A13 (32 pin) - 8KB banks
28732873
</part>
28742874
</software>
28752875

2876+
<software name="fs_sr021" supported="no">
2877+
<description>FS-SR021 MSX2 Word Processor (Japan)</description>
2878+
<year>1988</year>
2879+
<publisher>Panasonic</publisher>
2880+
<notes>Cartridge hardware is partially emulated.</notes>
2881+
<info name="alt_title" value="FS-SR021 MSX2用ワープロカートリッジ" />
2882+
<info name="serial" value="FS-SR021"/>
2883+
<info name="barcode" value="4902704652515"/>
2884+
<part name="cart" interface="msx_cart">
2885+
<!-- IC1? - MB834000A-20 - 512KB ROM -->
2886+
<!-- IC2? - MB834000-25 - 512KB ROM -->
2887+
<!-- IC3? - DA532391-S - possibly kanji font, also 512KB ROM? -->
2888+
<!-- IC4? - MB8464-15L-SK - 8KB SRAM -->
2889+
<!-- IC5 - MB8464A-15-SK - 8KB SRAM -->
2890+
<!-- IC6 - SLA7220F - gate array -->
2891+
<!-- battery -->
2892+
<feature name="slot" value="fs_sr021" />
2893+
<!-- writes to 6c00 - 8kb bank at 6000-7fff? -->
2894+
<!-- writes to 7ff9 - some kind of control? -->
2895+
<!-- writes to 7000 - 8kb bank at 8000-9fff? -->
2896+
<!-- writes to 7800 - 8kb bank at a000-bfff? -->
2897+
<dataarea name="rom" size="0x200000">
2898+
<rom name="mb834000a.ic1" size="0x80000" status="nodump"/>
2899+
<rom name="mb834000.ic2" size="0x80000" status="nodump"/>
2900+
<rom name="da532391.ic3" size="0x80000" status="nodump"/>
2901+
<!-- Last 512KB is empty/FFs. Should be 3 dumps, with at least 2 of 512KB. -->
2902+
<rom name="fs-sr021.rom" size="0x200000" crc="c3cdb67a" sha1="13007f9340670deda42c4b53c06c19d3d3c09704" status="baddump"/>
2903+
</dataarea>
2904+
<dataarea name="sram" size="0x4000">
2905+
</dataarea>
2906+
</part>
2907+
<part name="flop1" interface="floppy_3_5">
2908+
<dataarea name="flop" size="737280">
2909+
<rom name="fs-sr021 msx2 word processor - panasonic.dsk" size="737280" crc="a1ef5c89" sha1="f47f225b75784bb4d2ee533fa8fb57d9525c0029"/>
2910+
</dataarea>
2911+
</part>
2912+
</software>
2913+
28762914
<software name="nekkejud">
28772915
<description>Nekketsu Juudou (Japan)</description>
28782916
<year>1989</year>

scripts/src/bus.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,6 +1952,8 @@ if (BUSES["MSX_SLOT"]~=null) then
19521952
MAME_DIR .. "src/devices/bus/msx/cart/easi_speech.h",
19531953
MAME_DIR .. "src/devices/bus/msx/cart/fmpac.cpp",
19541954
MAME_DIR .. "src/devices/bus/msx/cart/fmpac.h",
1955+
MAME_DIR .. "src/devices/bus/msx/cart/fs_sr021.cpp",
1956+
MAME_DIR .. "src/devices/bus/msx/cart/fs_sr021.h",
19551957
MAME_DIR .. "src/devices/bus/msx/cart/fs_sr022.cpp",
19561958
MAME_DIR .. "src/devices/bus/msx/cart/fs_sr022.h",
19571959
MAME_DIR .. "src/devices/bus/msx/cart/halnote.cpp",

src/devices/bus/msx/cart/cartridge.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "dooly.h"
1414
#include "easi_speech.h"
1515
#include "fmpac.h"
16+
#include "fs_sr021.h"
1617
#include "fs_sr022.h"
1718
#include "halnote.h"
1819
#include "hbi55.h"
@@ -59,6 +60,7 @@ void msx_cart(device_slot_interface &device, bool is_in_subslot)
5960
device.option_add_internal(slotoptions::DOOLY, MSX_CART_DOOLY);
6061
device.option_add_internal(slotoptions::EASISPEECH, MSX_CART_EASISPEECH);
6162
device.option_add_internal(slotoptions::FMPAC, MSX_CART_FMPAC);
63+
device.option_add_internal(slotoptions::FS_SR021, MSX_CART_FS_SR021);
6264
device.option_add_internal(slotoptions::FS_SR022, MSX_CART_FS_SR022);
6365
device.option_add_internal(slotoptions::GAMEMASTER2, MSX_CART_GAMEMASTER2);
6466
device.option_add_internal(slotoptions::HALNOTE, MSX_CART_HALNOTE);

src/devices/bus/msx/cart/fs_sr021.cpp

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
// license:BSD-3-Clause
2+
// copyright-holders:Wilbert Pol
3+
/***********************************************************************************
4+
5+
Emulation of the FS-SR021 MSX2 Word Processor Cartridge.
6+
7+
TODO:
8+
- Display of JIS level 1 characters might not be fully correct, the tools do seem to display fine.
9+
- Unknown how JIS level 2 characters are input/displayed.
10+
11+
***********************************************************************************/
12+
#include "emu.h"
13+
#include "fs_sr021.h"
14+
15+
namespace {
16+
17+
class msx_cart_fs_sr021_device : public device_t, public msx_cart_interface
18+
{
19+
public:
20+
msx_cart_fs_sr021_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
21+
: device_t(mconfig, MSX_CART_FS_SR021, tag, owner, clock)
22+
, msx_cart_interface(mconfig, *this)
23+
, m_bank(*this, "bank%u", 0U)
24+
, m_view_0000(*this, "view0000")
25+
, m_view_2000(*this, "view2000")
26+
, m_view_4000(*this, "view4000")
27+
, m_view_6000(*this, "view6000")
28+
, m_view_8000(*this, "view8000")
29+
, m_view_a000(*this, "viewa000")
30+
{ }
31+
32+
virtual std::error_condition initialize_cartridge(std::string &message) override;
33+
34+
protected:
35+
// device_t implementation
36+
virtual void device_start() override;
37+
virtual void device_reset() override;
38+
39+
private:
40+
static constexpr size_t BANK_SIZE = 0x2000;
41+
42+
template <int Bank> void bank_w(u8 data);
43+
template <int Bank> void set_view();
44+
void control_w(u8 data);
45+
u8 bank_r(offs_t offset);
46+
u8 kanji_r(offs_t offset);
47+
void kanji_w(offs_t offset, u8 data);
48+
49+
memory_bank_array_creator<6> m_bank;
50+
memory_view m_view_0000;
51+
memory_view m_view_2000;
52+
memory_view m_view_4000;
53+
memory_view m_view_6000;
54+
memory_view m_view_8000;
55+
memory_view m_view_a000;
56+
u8 m_selected_bank[6];
57+
u8 m_control;
58+
u32 m_kanji_latch;
59+
};
60+
61+
void msx_cart_fs_sr021_device::device_start()
62+
{
63+
save_item(NAME(m_selected_bank));
64+
save_item(NAME(m_control));
65+
save_item(NAME(m_kanji_latch));
66+
}
67+
68+
void msx_cart_fs_sr021_device::device_reset()
69+
{
70+
m_control = 0;
71+
m_view_0000.select(0);
72+
m_view_2000.select(0);
73+
m_view_4000.select(0);
74+
m_view_6000.select(0);
75+
m_view_8000.select(0);
76+
m_view_a000.select(0);
77+
m_bank[2]->set_entry(0);
78+
}
79+
80+
std::error_condition msx_cart_fs_sr021_device::initialize_cartridge(std::string &message)
81+
{
82+
if (!cart_rom_region())
83+
{
84+
message = "msx_cart_fs_sr021_device: Required region 'rom' was not found.";
85+
return image_error::INTERNAL;
86+
}
87+
88+
if (cart_rom_region()->bytes() != 0x200000)
89+
{
90+
message = "msx_cart_fs_sr021_device: Region 'rom' has unsupported size.";
91+
return image_error::INVALIDLENGTH;
92+
}
93+
94+
if (!cart_sram_region())
95+
{
96+
message = "msx_cart_fs_sr021_device: Required region 'sram' was not found.";
97+
return image_error::INTERNAL;
98+
}
99+
100+
if (cart_sram_region()->bytes() != 0x4000)
101+
{
102+
message = "msx_cart_fs_sr021_device: Region 'sram' has unsupported size.";
103+
return image_error::BADSOFTWARE;
104+
}
105+
106+
const u32 size = cart_rom_region()->bytes();
107+
const u16 banks = size / BANK_SIZE;
108+
109+
for (int i = 0; i < 6; i++)
110+
{
111+
m_bank[i]->configure_entries(0, banks, cart_rom_region()->base(), BANK_SIZE);
112+
m_bank[i]->configure_entry(0x80, cart_sram_region()->base());
113+
m_bank[i]->configure_entry(0x81, cart_sram_region()->base() + BANK_SIZE);
114+
}
115+
116+
page(0)->install_view(0x0000, 0x1fff, m_view_0000);
117+
m_view_0000[0].install_read_bank(0x0000, 0x1fff, m_bank[0]);
118+
m_view_0000[1].install_readwrite_bank(0x0000, 0x1fff, m_bank[0]);
119+
page(0)->install_view(0x2000, 0x3fff, m_view_2000);
120+
m_view_2000[0].install_read_bank(0x2000, 0x3fff, m_bank[1]);
121+
m_view_2000[1].install_readwrite_bank(0x2000, 0x3fff, m_bank[1]);
122+
123+
page(1)->install_view(0x4000, 0x5fff, m_view_4000);
124+
m_view_4000[0].install_read_bank(0x4000, 0x5fff, m_bank[2]);
125+
m_view_4000[1].install_readwrite_bank(0x4000, 0x5fff, m_bank[2]);
126+
page(1)->install_view(0x6000, 0x7fff, m_view_6000);
127+
m_view_6000[0].install_read_bank(0x6000, 0x7fff, m_bank[3]);
128+
m_view_6000[1].install_readwrite_bank(0x6000, 0x7fff, m_bank[3]);
129+
m_view_6000[2].install_read_bank(0x6000, 0x7fff, m_bank[3]);
130+
m_view_6000[2].install_read_handler(0x7ff0, 0x7ff5, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::bank_r)));
131+
m_view_6000[3].install_readwrite_bank(0x6000, 0x7fff, m_bank[3]);
132+
m_view_6000[3].install_read_handler(0x7ff0, 0x7ff5, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::bank_r)));
133+
134+
page(2)->install_view(0x8000, 0x9fff, m_view_8000);
135+
m_view_8000[0].install_read_bank(0x8000, 0x9fff, m_bank[4]);
136+
m_view_8000[1].install_readwrite_bank(0x8000, 0x9fff, m_bank[4]);
137+
page(2)->install_view(0xa000, 0xbfff, m_view_a000);
138+
m_view_a000[0].install_read_bank(0xa000, 0xbfff, m_bank[5]);
139+
m_view_a000[1].install_readwrite_bank(0xa000, 0xbfff, m_bank[5]);
140+
141+
page(1)->install_write_handler(0x6000, 0x6000, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::bank_w<0>))); // 0000-1fff
142+
page(1)->install_write_handler(0x6400, 0x6400, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::bank_w<1>))); // 2000-3fff
143+
page(1)->install_write_handler(0x6800, 0x6800, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::bank_w<2>))); // 4000-5fff
144+
page(1)->install_write_handler(0x6c00, 0x6c00, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::bank_w<3>))); // 6000-7fff
145+
page(1)->install_write_handler(0x7000, 0x7000, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::bank_w<4>))); // 8000-9fff
146+
page(1)->install_write_handler(0x7800, 0x7800, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::bank_w<5>))); // a000-bfff
147+
page(1)->install_write_handler(0x7ff9, 0x7ff9, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::control_w)));
148+
149+
// Takes over kanji from base system?
150+
io_space().install_write_handler(0xd8, 0xd9, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::kanji_w)));
151+
io_space().install_read_handler(0xd9, 0xd9, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::kanji_r)));
152+
153+
return std::error_condition();
154+
}
155+
156+
template <int Bank>
157+
void msx_cart_fs_sr021_device::set_view()
158+
{
159+
bool ram_active = (m_selected_bank[Bank] >= 0x80 && m_selected_bank[Bank] < 0x82);
160+
if (Bank == 0)
161+
m_view_0000.select(ram_active ? 1 : 0);
162+
if (Bank == 1)
163+
m_view_2000.select(ram_active ? 1 : 0);
164+
if (Bank == 2)
165+
m_view_4000.select(ram_active ? 1 : 0);
166+
if (Bank == 3)
167+
m_view_6000.select((BIT(m_control, 2) ? 2 : 0) | (ram_active ? 1 : 0));
168+
if (Bank == 4)
169+
m_view_8000.select(ram_active ? 1 : 0);
170+
if (Bank == 5)
171+
m_view_a000.select(ram_active ? 1 : 0);
172+
}
173+
174+
template <int Bank>
175+
void msx_cart_fs_sr021_device::bank_w(u8 data)
176+
{
177+
m_selected_bank[Bank] = data;
178+
m_bank[Bank]->set_entry(data);
179+
set_view<Bank>();
180+
}
181+
182+
void msx_cart_fs_sr021_device::control_w(u8 data)
183+
{
184+
m_control = data;
185+
set_view<3>();
186+
}
187+
188+
u8 msx_cart_fs_sr021_device::bank_r(offs_t offset)
189+
{
190+
return m_selected_bank[offset];
191+
}
192+
193+
u8 msx_cart_fs_sr021_device::kanji_r(offs_t offset)
194+
{
195+
u8 result = 0xff;
196+
197+
u32 latch = bitswap<17>(m_kanji_latch, 4, 3, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 2, 1, 0);
198+
// This might not be correct, fixes most characters on the menu screen.
199+
if (!(latch & 0x18000))
200+
{
201+
latch |= 0x40000;
202+
}
203+
result = cart_rom_region()->base()[0x100000 | latch];
204+
205+
if (!machine().side_effects_disabled())
206+
{
207+
m_kanji_latch = (m_kanji_latch & ~0x1f) | ((m_kanji_latch + 1) & 0x1f);
208+
}
209+
return result;
210+
}
211+
212+
void msx_cart_fs_sr021_device::kanji_w(offs_t offset, u8 data)
213+
{
214+
if (offset)
215+
m_kanji_latch = (m_kanji_latch & 0x007e0) | ((data & 0x3f) << 11);
216+
else
217+
m_kanji_latch = (m_kanji_latch & 0x1f800) | ((data & 0x3f) << 5);
218+
}
219+
220+
} // anonymous namespace
221+
222+
DEFINE_DEVICE_TYPE_PRIVATE(MSX_CART_FS_SR021, msx_cart_interface, msx_cart_fs_sr021_device, "msx_cart_fs_sr021", "MSX Cartridge - FS-SR021")

src/devices/bus/msx/cart/fs_sr021.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// license:BSD-3-Clause
2+
// copyright-holders:Wilbert Pol
3+
#ifndef MAME_BUS_MSX_CART_FS_SR021_H
4+
#define MAME_BUS_MSX_CART_FS_SR021_H
5+
6+
#pragma once
7+
8+
#include "bus/msx/slot/cartridge.h"
9+
10+
11+
DECLARE_DEVICE_TYPE(MSX_CART_FS_SR021, msx_cart_interface)
12+
13+
#endif // MAME_BUS_MSX_CART_FS_SR021_H

src/devices/bus/msx/cart/slotoptions.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ char const *const DOOLY = "dooly";
3434
char const *const EC701 = "ec701";
3535
char const *const EASISPEECH = "easispeech";
3636
char const *const FMPAC = "fmpac";
37+
char const *const FS_SR021 = "fs_sr021";
3738
char const *const FS_SR022 = "fs_sr022";
3839
char const *const GAMEMASTER2 = "gamemaster2";
3940
char const *const HALNOTE = "halnote";

src/devices/bus/msx/cart/slotoptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ extern char const *const DOOLY;
3737
extern char const *const EC701;
3838
extern char const *const EASISPEECH;
3939
extern char const *const FMPAC;
40+
extern char const *const FS_SR021;
4041
extern char const *const FS_SR022;
4142
extern char const *const GAMEMASTER2;
4243
extern char const *const HALNOTE;

0 commit comments

Comments
 (0)