mirror of
https://github.com/holub/mame
synced 2025-06-08 05:44:09 +03:00
nec/pc9801.cpp: add 1.44MB floppy 3-mode support
This commit is contained in:
parent
49261a7dbc
commit
5a36097f04
@ -35,8 +35,7 @@
|
|||||||
fixing in some cases;
|
fixing in some cases;
|
||||||
- Export mouse support to an actual PC9871 device;
|
- Export mouse support to an actual PC9871 device;
|
||||||
- Implement IF-SEGA/98 support (Sega Saturn peripheral compatibility for Windows,
|
- Implement IF-SEGA/98 support (Sega Saturn peripheral compatibility for Windows,
|
||||||
available DOS C snippet clearly shows reading in direct mode, an actual SMPC
|
cfr. BeOS PnP driver);
|
||||||
sub-device sounds unlikely but possible);
|
|
||||||
- Incomplete SDIP support:
|
- Incomplete SDIP support:
|
||||||
- SDIP never returns a valid state and returns default values even if machine is
|
- SDIP never returns a valid state and returns default values even if machine is
|
||||||
soft resetted. By logic should read-back the already existing state, instead
|
soft resetted. By logic should read-back the already existing state, instead
|
||||||
@ -84,7 +83,12 @@
|
|||||||
TODO (PC-9801BX2)
|
TODO (PC-9801BX2)
|
||||||
- "SYSTEM SHUTDOWN" at POST, a soft reset fixes it?
|
- "SYSTEM SHUTDOWN" at POST, a soft reset fixes it?
|
||||||
- A non-fatal "MEMORY ERROR" is always thrown no matter the RAM size afterwards, related?
|
- A non-fatal "MEMORY ERROR" is always thrown no matter the RAM size afterwards, related?
|
||||||
- unemulated conventional or EMS RAM bank, definitely should have one given the odd minimum RAM size;
|
- unemulated conventional or EMS RAM bank, definitely should have one given the odd minimum RAM
|
||||||
|
size;
|
||||||
|
|
||||||
|
TODO: (PC-9801UX)
|
||||||
|
- "I/O Error" on any 3.5" floppy, specific to this romset (i.e. those works on pc9821).
|
||||||
|
It never access $4be, it must fail earlier than that.
|
||||||
|
|
||||||
===================================================================================================
|
===================================================================================================
|
||||||
|
|
||||||
@ -954,6 +958,17 @@ void pc9801vm_state::fdc_mode_w(uint8_t data)
|
|||||||
// logerror("FDC ctrl called with %02x\n",data);
|
// logerror("FDC ctrl called with %02x\n",data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TIMER_CALLBACK_MEMBER(pc9801vm_state::fdc_trigger)
|
||||||
|
{
|
||||||
|
// TODO: sorcer/hydlide definitely expects the XTMASK irq to be taken
|
||||||
|
// NOTE: should probably trigger the FDC irq depending on mode, i.e. use fdc_irq_w fn
|
||||||
|
if (BIT(m_fdc_2hd_ctrl, 2))
|
||||||
|
{
|
||||||
|
m_pic2->ir2_w(0);
|
||||||
|
m_pic2->ir2_w(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: undefined/disallow read/writes if I/F mode doesn't match
|
// TODO: undefined/disallow read/writes if I/F mode doesn't match
|
||||||
// (and that applies to FDC mapping too!)
|
// (and that applies to FDC mapping too!)
|
||||||
// id port 0 -> 2DD
|
// id port 0 -> 2DD
|
||||||
@ -969,17 +984,6 @@ template <unsigned port> u8 pc9801vm_state::fdc_2hd_2dd_ctrl_r()
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMER_CALLBACK_MEMBER(pc9801vm_state::fdc_trigger)
|
|
||||||
{
|
|
||||||
// TODO: sorcer/hydlide definitely expects the XTMASK irq to be taken
|
|
||||||
// NOTE: should probably trigger the FDC irq depending on mode, i.e. use fdc_irq_w fn
|
|
||||||
if (BIT(m_fdc_2hd_ctrl, 2))
|
|
||||||
{
|
|
||||||
m_pic2->ir2_w(0);
|
|
||||||
m_pic2->ir2_w(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <unsigned port> void pc9801vm_state::fdc_2hd_2dd_ctrl_w(u8 data)
|
template <unsigned port> void pc9801vm_state::fdc_2hd_2dd_ctrl_w(u8 data)
|
||||||
{
|
{
|
||||||
bool prev_trig = false;
|
bool prev_trig = false;
|
||||||
@ -1009,6 +1013,74 @@ template <unsigned port> void pc9801vm_state::fdc_2hd_2dd_ctrl_w(u8 data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: some machines (which?) mirror 0x00be to 0x04be
|
||||||
|
u8 pc9801vm_state::fdc_3mode_r(offs_t offset)
|
||||||
|
{
|
||||||
|
// freebsd21 expects 0-fill rather than the more logical 1-fill
|
||||||
|
// on 5.25" floppies/ext. drive id checks, open bus?
|
||||||
|
// TODO: external FDD
|
||||||
|
if (m_fdc_3mode.dev_sel & 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const bool is_35hd = m_fdc_2hd->subdevice<floppy_connector>(m_fdc_3mode.dev_sel ? "1" : "0")->get_device()->get_form_factor() == floppy_image::FF_35;
|
||||||
|
|
||||||
|
if (!is_35hd)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
u8 res = 0xee;
|
||||||
|
|
||||||
|
// Check if drive is in 2HD/1MB mode
|
||||||
|
if (BIT(m_fdc_mode, 1))
|
||||||
|
res |= 1 << 4;
|
||||||
|
|
||||||
|
if (m_fdc_3mode.access_144mb)
|
||||||
|
res |= 1 << 0;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -xx- ---- Drive specification
|
||||||
|
* -00- ---- First internal drive
|
||||||
|
* -01- ---- Second internal drive
|
||||||
|
* -10- ---- External drive
|
||||||
|
* ---x ---- Operation mode specification
|
||||||
|
* ---0 ---- no-op
|
||||||
|
* ---1 ---- Access Mode valid
|
||||||
|
* ---- ---x Access Mode specification
|
||||||
|
* ---- ---0 1MB/640KB
|
||||||
|
* ---- ---1 1.44MB
|
||||||
|
*/
|
||||||
|
void pc9801vm_state::fdc_3mode_w(offs_t offset, uint8_t data)
|
||||||
|
{
|
||||||
|
//logerror("$4be: W %02x\n", data);
|
||||||
|
m_fdc_3mode.dev_sel = (data & 0x60) >> 5;
|
||||||
|
|
||||||
|
// TODO: external FDD
|
||||||
|
if (m_fdc_3mode.dev_sel & 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (BIT(data, 4))
|
||||||
|
{
|
||||||
|
const bool is_35hd = m_fdc_2hd->subdevice<floppy_connector>(m_fdc_3mode.dev_sel ? "1" : "0")->get_device()->get_form_factor() == floppy_image::FF_35;
|
||||||
|
|
||||||
|
if (!is_35hd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
floppy_image_device *floppy = m_fdc_2hd->subdevice<floppy_connector>(m_fdc_3mode.dev_sel ? "1" : "0")->get_device();
|
||||||
|
m_fdc_3mode.access_144mb = !!(BIT(data, 0));
|
||||||
|
if (m_fdc_3mode.access_144mb)
|
||||||
|
{
|
||||||
|
floppy->set_rpm(300);
|
||||||
|
m_fdc_2hd->set_rate(500000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fdc_set_density_mode(!!BIT(m_fdc_mode, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pc9801vm_state::pc9801rs_video_ff_w(offs_t offset, uint8_t data)
|
void pc9801vm_state::pc9801rs_video_ff_w(offs_t offset, uint8_t data)
|
||||||
{
|
{
|
||||||
if(offset == 1)
|
if(offset == 1)
|
||||||
@ -1136,6 +1208,7 @@ void pc9801vm_state::pc9801ux_io(address_map &map)
|
|||||||
map(0x0439, 0x0439).rw(FUNC(pc9801vm_state::dma_access_ctrl_r), FUNC(pc9801vm_state::dma_access_ctrl_w));
|
map(0x0439, 0x0439).rw(FUNC(pc9801vm_state::dma_access_ctrl_r), FUNC(pc9801vm_state::dma_access_ctrl_w));
|
||||||
map(0x043c, 0x043f).w(FUNC(pc9801vm_state::pc9801rs_bank_w)); //ROM/RAM bank
|
map(0x043c, 0x043f).w(FUNC(pc9801vm_state::pc9801rs_bank_w)); //ROM/RAM bank
|
||||||
map(0x04a0, 0x04af).w(FUNC(pc9801vm_state::egc_w));
|
map(0x04a0, 0x04af).w(FUNC(pc9801vm_state::egc_w));
|
||||||
|
map(0x04be, 0x04be).rw(FUNC(pc9801vm_state::fdc_3mode_r), FUNC(pc9801vm_state::fdc_3mode_w));
|
||||||
map(0x3fd8, 0x3fdf).rw(m_pit, FUNC(pit8253_device::read), FUNC(pit8253_device::write)).umask16(0xff00);
|
map(0x3fd8, 0x3fdf).rw(m_pit, FUNC(pit8253_device::read), FUNC(pit8253_device::write)).umask16(0xff00);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1908,16 +1981,6 @@ void pc9801vm_state::mouse_freq_w(offs_t offset, u8 data)
|
|||||||
m_mouse.freq_index = 0;
|
m_mouse.freq_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// standard debug catch-all handler
|
|
||||||
// I/O mapping is byte smearing party, so logerror can possibly silently hide handler
|
|
||||||
// accesses if they are partially handled by an umask in the mapping.
|
|
||||||
uint8_t pc9801_state::unk_r(offs_t offset)
|
|
||||||
{
|
|
||||||
// printf("%04x\n",offset);
|
|
||||||
// logerror("%s: I/O read access %04x\n",offset);
|
|
||||||
return 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************
|
/****************************************
|
||||||
*
|
*
|
||||||
* UPD765 interface
|
* UPD765 interface
|
||||||
@ -2116,6 +2179,8 @@ MACHINE_RESET_MEMBER(pc9801vm_state,pc9801rs)
|
|||||||
|
|
||||||
m_gate_a20 = 0;
|
m_gate_a20 = 0;
|
||||||
m_fdc_mode = 3;
|
m_fdc_mode = 3;
|
||||||
|
m_fdc_3mode.dev_sel = 2;
|
||||||
|
m_fdc_3mode.access_144mb = false;
|
||||||
fdc_set_density_mode(true); // 2HD
|
fdc_set_density_mode(true); // 2HD
|
||||||
// 0xfb on PC98XL
|
// 0xfb on PC98XL
|
||||||
// TODO: breaks UART setup for pc9801rs
|
// TODO: breaks UART setup for pc9801rs
|
||||||
|
@ -213,7 +213,6 @@ protected:
|
|||||||
|
|
||||||
uint8_t pc9801_a0_r(offs_t offset);
|
uint8_t pc9801_a0_r(offs_t offset);
|
||||||
void pc9801_a0_w(offs_t offset, uint8_t data);
|
void pc9801_a0_w(offs_t offset, uint8_t data);
|
||||||
u8 unk_r(offs_t offset);
|
|
||||||
uint8_t f0_r(offs_t offset);
|
uint8_t f0_r(offs_t offset);
|
||||||
|
|
||||||
uint8_t m_nmi_ff = 0;
|
uint8_t m_nmi_ff = 0;
|
||||||
@ -481,11 +480,19 @@ private:
|
|||||||
emu_timer *m_fdc_timer = nullptr;
|
emu_timer *m_fdc_timer = nullptr;
|
||||||
|
|
||||||
u8 m_fdc_mode = 0;
|
u8 m_fdc_mode = 0;
|
||||||
|
struct {
|
||||||
|
u8 dev_sel;
|
||||||
|
bool access_144mb;
|
||||||
|
} m_fdc_3mode;
|
||||||
|
|
||||||
u8 fdc_mode_r();
|
u8 fdc_mode_r();
|
||||||
void fdc_mode_w(u8 data);
|
void fdc_mode_w(u8 data);
|
||||||
void fdc_set_density_mode(bool is_2hd);
|
void fdc_set_density_mode(bool is_2hd);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// $4be, roughly around UV model
|
||||||
|
u8 fdc_3mode_r(offs_t offset);
|
||||||
|
void fdc_3mode_w(offs_t offset, uint8_t data);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t pal_entry = 0;
|
uint8_t pal_entry = 0;
|
||||||
uint8_t r[16]{}, g[16]{}, b[16]{};
|
uint8_t r[16]{}, g[16]{}, b[16]{};
|
||||||
|
@ -476,7 +476,7 @@ void pc9821_state::pc9821_io(address_map &map)
|
|||||||
// map(0x043c, 0x043f) ROM/RAM bank (EPSON)
|
// map(0x043c, 0x043f) ROM/RAM bank (EPSON)
|
||||||
map(0x0460, 0x0463).rw(FUNC(pc9821_state::window_bank_r), FUNC(pc9821_state::window_bank_w));
|
map(0x0460, 0x0463).rw(FUNC(pc9821_state::window_bank_r), FUNC(pc9821_state::window_bank_w));
|
||||||
map(0x04a0, 0x04af).w(FUNC(pc9821_state::pc9821_egc_w));
|
map(0x04a0, 0x04af).w(FUNC(pc9821_state::pc9821_egc_w));
|
||||||
// map(0x04be, 0x04be) FDC "RPM" register
|
map(0x04be, 0x04be).rw(FUNC(pc9821_state::fdc_3mode_r), FUNC(pc9821_state::fdc_3mode_w));
|
||||||
// map(0x0640, 0x064f).rw(FUNC(pc9821_state::ide_cs0_r), FUNC(pc9821_state::ide_cs0_w));
|
// map(0x0640, 0x064f).rw(FUNC(pc9821_state::ide_cs0_r), FUNC(pc9821_state::ide_cs0_w));
|
||||||
// map(0x0740, 0x074f).rw(FUNC(pc9821_state::ide_cs1_r), FUNC(pc9821_state::ide_cs1_w));
|
// map(0x0740, 0x074f).rw(FUNC(pc9821_state::ide_cs1_r), FUNC(pc9821_state::ide_cs1_w));
|
||||||
// map(0x08e0, 0x08ea) <undefined> / EMM SIO registers
|
// map(0x08e0, 0x08ea) <undefined> / EMM SIO registers
|
||||||
|
Loading…
Reference in New Issue
Block a user