nec/pc98: convert SDIP to device

This commit is contained in:
angelosa 2025-04-15 00:18:01 +02:00
parent 0855f614ed
commit f6d743b937
10 changed files with 183 additions and 135 deletions

View File

@ -656,7 +656,7 @@ void pc9801_state::pc9801_common_io(address_map &map)
// map.unmap_value_high();
map(0x0000, 0x001f).rw(m_dmac, FUNC(am9517a_device::read), FUNC(am9517a_device::write)).umask16(0xff00);
map(0x0000, 0x001f).rw(FUNC(pc9801_state::pic_r), FUNC(pc9801_state::pic_w)).umask16(0x00ff); // i8259 PIC (bit 3 ON slave / master) / i8237 DMA
map(0x0020, 0x002f).w(FUNC(pc9801_state::rtc_w)).umask16(0x00ff);
map(0x0020, 0x0020).w(FUNC(pc9801_state::rtc_w));
map(0x0030, 0x0037).rw(m_ppi_sys, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0xff00);
map(0x0030, 0x0033).rw(m_sio_rs, FUNC(i8251_device::read), FUNC(i8251_device::write)).umask16(0x00ff); //i8251 RS232c / i8255 system port
map(0x0040, 0x0047).rw(m_ppi_prn, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0x00ff);
@ -1248,47 +1248,23 @@ void pc9801vm_state::pc9801rs_io(address_map &map)
map(0xe0d0, 0xe0d3).r(FUNC(pc9801vm_state::midi_r));
}
// SDIP handling
// TODO: move to device
template<unsigned port> u8 pc9801us_state::sdip_r(offs_t offset)
{
u8 sdip_offset = port + (m_sdip_bank * 12);
return m_sdip[sdip_offset];
}
template<unsigned port> void pc9801us_state::sdip_w(offs_t offset, u8 data)
{
u8 sdip_offset = port + (m_sdip_bank * 12);
m_sdip[sdip_offset] = data;
}
void pc9801us_state::sdip_bank_w(offs_t offset, u8 data)
{
// TODO: depending on model type this is hooked up differently
// (or be not hooked up at all like in 9801US case)
m_sdip_bank = (data & 0x40) >> 6;
}
void pc9801us_state::pc9801us_io(address_map &map)
{
pc9801rs_io(map);
map(0x0430, 0x0433).rw(FUNC(pc9801us_state::ide_ctrl_r), FUNC(pc9801us_state::ide_ctrl_w)).umask16(0x00ff);
map(0x841e, 0x841e).rw(FUNC(pc9801us_state::sdip_r<0x0>), FUNC(pc9801us_state::sdip_w<0x0>));
map(0x851e, 0x851e).rw(FUNC(pc9801us_state::sdip_r<0x1>), FUNC(pc9801us_state::sdip_w<0x1>));
map(0x861e, 0x861e).rw(FUNC(pc9801us_state::sdip_r<0x2>), FUNC(pc9801us_state::sdip_w<0x2>));
map(0x871e, 0x871e).rw(FUNC(pc9801us_state::sdip_r<0x3>), FUNC(pc9801us_state::sdip_w<0x3>));
map(0x881e, 0x881e).rw(FUNC(pc9801us_state::sdip_r<0x4>), FUNC(pc9801us_state::sdip_w<0x4>));
map(0x891e, 0x891e).rw(FUNC(pc9801us_state::sdip_r<0x5>), FUNC(pc9801us_state::sdip_w<0x5>));
map(0x8a1e, 0x8a1e).rw(FUNC(pc9801us_state::sdip_r<0x6>), FUNC(pc9801us_state::sdip_w<0x6>));
map(0x8b1e, 0x8b1e).rw(FUNC(pc9801us_state::sdip_r<0x7>), FUNC(pc9801us_state::sdip_w<0x7>));
map(0x8c1e, 0x8c1e).rw(FUNC(pc9801us_state::sdip_r<0x8>), FUNC(pc9801us_state::sdip_w<0x8>));
map(0x8d1e, 0x8d1e).rw(FUNC(pc9801us_state::sdip_r<0x9>), FUNC(pc9801us_state::sdip_w<0x9>));
map(0x8e1e, 0x8e1e).rw(FUNC(pc9801us_state::sdip_r<0xa>), FUNC(pc9801us_state::sdip_w<0xa>));
map(0x8f1e, 0x8f1e).rw(FUNC(pc9801us_state::sdip_r<0xb>), FUNC(pc9801us_state::sdip_w<0xb>));
map(0x8f1f, 0x8f1f).w(FUNC(pc9801us_state::sdip_bank_w));
map(0x841e, 0x841e).rw(m_sdip, FUNC(pc98_sdip_device::read<0x0>), FUNC(pc98_sdip_device::write<0x0>));
map(0x851e, 0x851e).rw(m_sdip, FUNC(pc98_sdip_device::read<0x1>), FUNC(pc98_sdip_device::write<0x1>));
map(0x861e, 0x861e).rw(m_sdip, FUNC(pc98_sdip_device::read<0x2>), FUNC(pc98_sdip_device::write<0x2>));
map(0x871e, 0x871e).rw(m_sdip, FUNC(pc98_sdip_device::read<0x3>), FUNC(pc98_sdip_device::write<0x3>));
map(0x881e, 0x881e).rw(m_sdip, FUNC(pc98_sdip_device::read<0x4>), FUNC(pc98_sdip_device::write<0x4>));
map(0x891e, 0x891e).rw(m_sdip, FUNC(pc98_sdip_device::read<0x5>), FUNC(pc98_sdip_device::write<0x5>));
map(0x8a1e, 0x8a1e).rw(m_sdip, FUNC(pc98_sdip_device::read<0x6>), FUNC(pc98_sdip_device::write<0x6>));
map(0x8b1e, 0x8b1e).rw(m_sdip, FUNC(pc98_sdip_device::read<0x7>), FUNC(pc98_sdip_device::write<0x7>));
map(0x8c1e, 0x8c1e).rw(m_sdip, FUNC(pc98_sdip_device::read<0x8>), FUNC(pc98_sdip_device::write<0x8>));
map(0x8d1e, 0x8d1e).rw(m_sdip, FUNC(pc98_sdip_device::read<0x9>), FUNC(pc98_sdip_device::write<0x9>));
map(0x8e1e, 0x8e1e).rw(m_sdip, FUNC(pc98_sdip_device::read<0xa>), FUNC(pc98_sdip_device::write<0xa>));
map(0x8f1e, 0x8f1e).rw(m_sdip, FUNC(pc98_sdip_device::read<0xb>), FUNC(pc98_sdip_device::write<0xb>));
map(0x8f1f, 0x8f1f).w(m_sdip, FUNC(pc98_sdip_device::bank_w));
}
void pc9801bx_state::pc9801bx2_map(address_map &map)
@ -2137,8 +2113,6 @@ MACHINE_START_MEMBER(pc9801vm_state,pc9801rs)
MACHINE_START_MEMBER(pc9801us_state,pc9801us)
{
MACHINE_START_CALL_MEMBER(pc9801rs);
save_pointer(NAME(m_sdip), 24);
}
MACHINE_START_MEMBER(pc9801bx_state,pc9801bx2)
@ -2630,6 +2604,8 @@ void pc9801us_state::pc9801us(machine_config &config)
m_maincpu->set_irq_acknowledge_callback("pic8259_master", FUNC(pic8259_device::inta_cb));
config_floppy_35hd(config);
PC98_SDIP(config, "sdip", 0);
}
void pc9801us_state::pc9801fs(machine_config &config)
@ -2641,13 +2617,14 @@ void pc9801us_state::pc9801fs(machine_config &config)
m_maincpu->set_addrmap(AS_IO, &pc9801us_state::pc9801us_io);
m_maincpu->set_irq_acknowledge_callback("pic8259_master", FUNC(pic8259_device::inta_cb));
// optional 3'5 floppies x2
config_floppy_525hd(config);
// optional SCSI HDD
pit_clock_config(config, xtal / 4);
PC98_SDIP(config, "sdip", 0);
}
void pc9801bx_state::pc9801bx2(machine_config &config)
@ -2664,6 +2641,8 @@ void pc9801bx_state::pc9801bx2(machine_config &config)
pit_clock_config(config, xtal / 4); // unknown, fixes timer error at POST, /4 ~ /7
PC98_SDIP(config, "sdip", 0);
// minimum RAM: 1.8 / 3.6 MB (?)
// maximum RAM: 19.6 MB
// GDC & EGC, DAC1BIT built-in

View File

@ -57,6 +57,7 @@
#include "pc98_cd.h"
#include "pc98_kbd.h"
#include "pc98_memsw.h"
#include "pc98_sdip.h"
#include "bus/ata/atadev.h"
#include "bus/ata/ataintf.h"
@ -538,6 +539,7 @@ class pc9801us_state : public pc9801vm_state
public:
pc9801us_state(const machine_config &mconfig, device_type type, const char *tag)
: pc9801vm_state(mconfig, type, tag)
, m_sdip(*this, "sdip")
{
}
void pc9801us(machine_config &config);
@ -551,12 +553,7 @@ protected:
// SDIP, PC9801DA onward
protected:
u8 m_sdip[24];
private:
u8 m_sdip_bank;
template<unsigned port> u8 sdip_r(offs_t offset);
template<unsigned port> void sdip_w(offs_t offset, u8 data);
void sdip_bank_w(offs_t offset, u8 data);
required_device<pc98_sdip_device> m_sdip;
};
/**********************************************************

View File

@ -446,7 +446,13 @@ void pc9821_state::pc9821_io(address_map &map)
map(0x0000, 0x001f).rw(m_dmac, FUNC(am9517a_device::read), FUNC(am9517a_device::write)).umask32(0xff00ff00);
map(0x0000, 0x001f).lr8(NAME([this] (offs_t o) { return BIT(o, 1) ? 0xff : pic_r(o); })).umask32(0x00ff00ff);
map(0x0000, 0x001f).w(FUNC(pc9821_state::pic_w)).umask32(0x00ff00ff); // i8259 PIC (bit 3 ON slave / master) / i8237 DMA
map(0x0020, 0x002f).w(FUNC(pc9821_state::rtc_w)).umask32(0x000000ff);
map(0x0020, 0x0020).w(FUNC(pc9821_state::rtc_w));
map(0x0022, 0x0022).lw8(NAME([this] (offs_t offset, u8 data) {
// TODO: r/w to both ports, superset of uPD4990A
// Reportedly buggy with DOS/Win95 off the bat, can use HRTIMER.SYS/BCKWHEAT.SYS as fallback
if (BIT(data, 4))
popmessage("rtc_w: extended uPD4993(A) mode enable %02x", data);
}));
map(0x0020, 0x002f).w(FUNC(pc9821_state::dmapg8_w)).umask32(0xff00ff00);
map(0x0030, 0x0037).rw(m_ppi_sys, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask32(0xff00ff00); //i8251 RS232c / i8255 system port
map(0x0040, 0x0047).rw(m_ppi_prn, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask32(0x00ff00ff);
@ -497,7 +503,7 @@ void pc9821_state::pc9821_io(address_map &map)
map(0x0ca0, 0x0ca0).lr8(NAME([] () { return 0xff; })); // high reso detection
// map(0x0cc0, 0x0cc7) SCSI interface / <undefined>
// map(0x0cfc, 0x0cff) PCI bus
map(0x1e8c, 0x1e8f).noprw(); // IDE RAM switch
map(0x1e8c, 0x1e8f).noprw(); // TODO: IDE RAM switch
map(0x2ed0, 0x2edf).lr8(NAME([] (address_space &s, offs_t o, u8 mm) { return 0xff; })).umask32(0xffffffff); // unknown sound related
map(0x3fd8, 0x3fdf).r(m_pit, FUNC(pit8253_device::read)).umask16(0xff00);
map(0x3fd8, 0x3fdf).w(FUNC(pc9821_state::pit_latch_delay)).umask16(0xff00);
@ -846,6 +852,8 @@ void pc9821_state::pc9821(machine_config &config)
PALETTE(config.replace(), m_palette, FUNC(pc9821_state::pc9801_palette), 16 + 16 + 256);
// m_hgdc[1]->set_display_pixels(FUNC(pc9821_state::pegc_display_pixels));
PC98_SDIP(config, "sdip", 0);
}
void pc9821_mate_a_state::pc9821as(machine_config &config)
@ -1224,7 +1232,8 @@ ROM_END
ROM_START( pc9821ce2 )
ROM_REGION16_LE( 0x30000, "ipl", ROMREGION_ERASEFF )
ROM_LOAD( "itf_ce2.rom", 0x10000, 0x008000, CRC(273e9e88) SHA1(9bca7d5116788776ed0f297bccb4dfc485379b41) )
// baddump: missing setup menu bank
ROM_LOAD( "itf_ce2.rom", 0x10000, 0x008000, BAD_DUMP CRC(273e9e88) SHA1(9bca7d5116788776ed0f297bccb4dfc485379b41) )
ROM_LOAD( "bios_ce2.rom", 0x18000, 0x018000, BAD_DUMP CRC(76affd90) SHA1(910fae6763c0cd59b3957b6cde479c72e21f33c1) )
ROM_REGION( 0x80000, "chargen", 0 )

View File

@ -28,22 +28,8 @@ TODO:
#include "pc98_kbd.h"
#include "machine/keyboard.ipp"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// device type definition
DEFINE_DEVICE_TYPE(PC98_KBD, pc98_kbd_device, "pc98_kbd", "NEC PC-98 Keyboard")
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// pc98_kbd_device - constructor
//-------------------------------------------------
pc98_kbd_device::pc98_kbd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, PC98_KBD, tag, owner, clock)
, device_buffered_serial_interface(mconfig, *this)
@ -54,30 +40,17 @@ pc98_kbd_device::pc98_kbd_device(const machine_config &mconfig, const char *tag,
{
}
//-------------------------------------------------
// device_validity_check - perform validity checks
// on this device
//-------------------------------------------------
void pc98_kbd_device::device_validity_check(validity_checker &valid) const
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void pc98_kbd_device::device_start()
{
// ...
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void pc98_kbd_device::device_reset()
{
clear_fifo();

View File

@ -1,10 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
/***************************************************************************
PC-9801 Keyboard simulation
***************************************************************************/
#ifndef MAME_NEC_PC98_KBD_H
#define MAME_NEC_PC98_KBD_H

View File

@ -1,6 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
/***************************************************************************
/**************************************************************************************************
PC-9801 MEMSW interface
@ -74,51 +74,27 @@
- Is the mapping truly aligned to 2 bytes? Looks more like 4, needs real
HW verification.
***************************************************************************/
**************************************************************************************************/
#include "emu.h"
#include "pc98_memsw.h"
#include "coreutil.h"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// device type definition
DEFINE_DEVICE_TYPE(PC98_MEMSW, pc98_memsw_device, "pc98_memsw", "NEC PC-98 Memory Switch device")
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// pc98_memsw_device - constructor
//-------------------------------------------------
pc98_memsw_device::pc98_memsw_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, PC98_MEMSW, tag, owner, clock),
device_nvram_interface(mconfig, *this)
: device_t(mconfig, PC98_MEMSW, tag, owner, clock)
, device_nvram_interface(mconfig, *this)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void pc98_memsw_device::device_start()
{
save_pointer(NAME(m_bram), m_bram_size);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void pc98_memsw_device::device_reset()
{
}
@ -154,16 +130,13 @@ bool pc98_memsw_device::nvram_write(util::write_stream &file)
return !err;
}
//**************************************************************************
// READ/WRITE HANDLERS
//**************************************************************************
uint8_t pc98_memsw_device::read(uint8_t offset)
uint8_t pc98_memsw_device::read(offs_t offset)
{
return m_bram[offset];
}
void pc98_memsw_device::write( uint8_t offset, uint8_t data )
void pc98_memsw_device::write(offs_t offset, uint8_t data )
{
m_bram[offset] = data;
}

View File

@ -1,10 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
/***************************************************************************
Template for skeleton device
***************************************************************************/
#ifndef MAME_NEC_PC98_MEMSW_H
#define MAME_NEC_PC98_MEMSW_H
@ -14,26 +9,14 @@ Template for skeleton device
#include "machine/nvram.h"
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> pc98_memsw_device
class pc98_memsw_device : public device_t,
public device_nvram_interface
public device_nvram_interface
{
public:
pc98_memsw_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
uint8_t read(uint8_t offset);
void write(uint8_t offset, uint8_t data);
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
protected:
virtual void device_start() override ATTR_COLD;

View File

@ -0,0 +1,99 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
/**************************************************************************************************
PC-9801 S[oftware]DIP interface
TODO:
- Discards saved settings;
**************************************************************************************************/
#include "emu.h"
#include "pc98_sdip.h"
DEFINE_DEVICE_TYPE(PC98_SDIP, pc98_sdip_device, "pc98_sdip", "NEC PC-98 SDIP device")
pc98_sdip_device::pc98_sdip_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, PC98_SDIP, tag, owner, clock)
, device_nvram_interface(mconfig, *this)
{
}
void pc98_sdip_device::device_start()
{
save_pointer(NAME(m_sdip_ram), m_sdip_size);
save_item(NAME(m_bank));
}
void pc98_sdip_device::device_reset()
{
m_bank = 0;
}
void pc98_sdip_device::nvram_default()
{
std::fill(std::begin(m_sdip_ram), std::end(m_sdip_ram), 0xff);
}
bool pc98_sdip_device::nvram_read(util::read_stream &file)
{
auto const [err, actual_size] = util::read(file, m_sdip_ram, m_sdip_size);
return !err && (actual_size == m_sdip_size);
}
bool pc98_sdip_device::nvram_write(util::write_stream &file)
{
auto const [err, actual_size] = util::write(file, m_sdip_ram, m_sdip_size);
return !err;
}
template<unsigned port> u8 pc98_sdip_device::read(offs_t offset)
{
u8 sdip_offset = port + (m_bank * 12);
return m_sdip_ram[sdip_offset];
}
template<unsigned port> void pc98_sdip_device::write(offs_t offset, u8 data)
{
u8 sdip_offset = port + (m_bank * 12);
m_sdip_ram[sdip_offset] = data;
}
void pc98_sdip_device::bank_w(offs_t offset, u8 data)
{
// TODO: depending on model type this is hooked up differently
// (or be not hooked up at all like in 9801US case)
m_bank = !!(BIT(data, 6));
}
template u8 pc98_sdip_device::read<0>(offs_t offset);
template u8 pc98_sdip_device::read<1>(offs_t offset);
template u8 pc98_sdip_device::read<2>(offs_t offset);
template u8 pc98_sdip_device::read<3>(offs_t offset);
template u8 pc98_sdip_device::read<4>(offs_t offset);
template u8 pc98_sdip_device::read<5>(offs_t offset);
template u8 pc98_sdip_device::read<6>(offs_t offset);
template u8 pc98_sdip_device::read<7>(offs_t offset);
template u8 pc98_sdip_device::read<8>(offs_t offset);
template u8 pc98_sdip_device::read<9>(offs_t offset);
template u8 pc98_sdip_device::read<10>(offs_t offset);
template u8 pc98_sdip_device::read<11>(offs_t offset);
template void pc98_sdip_device::write<0>(offs_t offset, u8 data);
template void pc98_sdip_device::write<1>(offs_t offset, u8 data);
template void pc98_sdip_device::write<2>(offs_t offset, u8 data);
template void pc98_sdip_device::write<3>(offs_t offset, u8 data);
template void pc98_sdip_device::write<4>(offs_t offset, u8 data);
template void pc98_sdip_device::write<5>(offs_t offset, u8 data);
template void pc98_sdip_device::write<6>(offs_t offset, u8 data);
template void pc98_sdip_device::write<7>(offs_t offset, u8 data);
template void pc98_sdip_device::write<8>(offs_t offset, u8 data);
template void pc98_sdip_device::write<9>(offs_t offset, u8 data);
template void pc98_sdip_device::write<10>(offs_t offset, u8 data);
template void pc98_sdip_device::write<11>(offs_t offset, u8 data);

39
src/mame/nec/pc98_sdip.h Normal file
View File

@ -0,0 +1,39 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
#ifndef MAME_NEC_PC98_SDIP_H
#define MAME_NEC_PC98_SDIP_H
#pragma once
#include "machine/nvram.h"
class pc98_sdip_device : public device_t,
public device_nvram_interface
{
public:
pc98_sdip_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <unsigned port> u8 read(offs_t offset);
template <unsigned port> void write(offs_t offset, u8 data);
void bank_w(offs_t offset, u8 data);
protected:
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
virtual void nvram_default() override;
virtual bool nvram_read(util::read_stream &file) override;
virtual bool nvram_write(util::write_stream &file) override;
private:
u8 m_sdip_ram[24];
const u8 m_sdip_size = 24;
bool m_bank = 0;
};
// device type definition
DECLARE_DEVICE_TYPE(PC98_SDIP, pc98_sdip_device)
#endif // MAME_NEC_PC98_SDIP_H

View File

@ -150,7 +150,7 @@ void pc98lt_state::lt_io(address_map &map)
{
map.unmap_value_high();
// map(0x0000, 0x001f) // PIC (bit 3 ON slave / master), V50 internal / <undefined>
map(0x0020, 0x002f).w(FUNC(pc98lt_state::rtc_w)).umask16(0x00ff);
map(0x0020, 0x0020).w(FUNC(pc98lt_state::rtc_w));
map(0x0030, 0x0037).rw(m_ppi_sys, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0xff00);
map(0x0030, 0x0033).rw(m_sio_rs, FUNC(i8251_device::read), FUNC(i8251_device::write)).umask16(0x00ff); //i8251 RS232c / i8255 system port
map(0x0040, 0x0047).rw(m_ppi_prn, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0x00ff);