mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
ibm6580: floppy adapter LLE (WIP) (#9196)
This commit is contained in:
parent
62e5373535
commit
3637f4bc4d
@ -151,6 +151,7 @@ Notes on floppy drive:
|
||||
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/i8255.h"
|
||||
@ -210,10 +211,12 @@ public:
|
||||
, m_dma8257(*this, "dma8257")
|
||||
, m_screen(*this, "screen")
|
||||
, m_kbd(*this, "kbd")
|
||||
, m_fdc(*this, UPD765_TAG)
|
||||
, m_flop(*this, UPD765_TAG ":%u", 0U)
|
||||
, m_p_chargen(*this, "chargen")
|
||||
, m_leds(*this, "led%u", 5U)
|
||||
, m_mcu(*this, "mcu")
|
||||
, m_mcuppi(*this, "mcuppi")
|
||||
, m_fdc(*this, UPD765_TAG)
|
||||
, m_drive(*this, UPD765_TAG ":%u", 0U)
|
||||
{ }
|
||||
|
||||
void ibm6580(machine_config &config);
|
||||
@ -248,8 +251,6 @@ private:
|
||||
void floppy_w(offs_t offset, uint8_t data);
|
||||
uint8_t floppy_r(offs_t offset);
|
||||
static void floppy_formats(format_registration &fr);
|
||||
DECLARE_WRITE_LINE_MEMBER(floppy_intrq);
|
||||
DECLARE_WRITE_LINE_MEMBER(floppy_hdl);
|
||||
DECLARE_WRITE_LINE_MEMBER(hrq_w);
|
||||
uint8_t memory_read_byte(offs_t offset);
|
||||
void memory_write_byte(offs_t offset, uint8_t data);
|
||||
@ -259,20 +260,27 @@ private:
|
||||
void ibm6580_io(address_map &map);
|
||||
void ibm6580_mem(address_map &map);
|
||||
|
||||
void mcu_io(address_map &map);
|
||||
void mcu_mem(address_map &map);
|
||||
|
||||
uint16_t m_gate;
|
||||
uint8_t m_p40, m_p4a, m_p50, m_e000;
|
||||
uint8_t m_dma0pg;
|
||||
uint8_t m_p40, m_p4a, m_p50;
|
||||
uint8_t m_kb_data, m_ppi_c, m_led_state;
|
||||
bool m_e000;
|
||||
bool m_kb_data_bit, m_kb_strobe, m_kb_clock;
|
||||
|
||||
util::fifo<uint8_t, 4> m_floppy_mcu_sr, m_floppy_mcu_cr;
|
||||
int m_floppy_mcu_cr_fifo;
|
||||
uint8_t m_floppy_sr;
|
||||
floppy_image_device *m_floppies[2];
|
||||
floppy_image_device *m_floppy;
|
||||
bool m_floppy_intrq, m_floppy_hdl, m_floppy_idle;
|
||||
uint8_t m_dma0pg;
|
||||
uint8_t floppy_mcu_command();
|
||||
bool floppy_mcu_cr_full();
|
||||
uint8_t m_mcu_p1, m_mcu_p2;
|
||||
uint8_t m_mcuppi_a, m_mcuppi_b, m_mcuppi_c;
|
||||
|
||||
void mcu_io_w(offs_t offset, uint8_t data);
|
||||
uint8_t mcu_io_r(offs_t offset);
|
||||
|
||||
void mcuppi_c_w(uint8_t data);
|
||||
|
||||
bool m_floppy_intrq, m_floppy_idle;
|
||||
uint8_t m_floppy_mcu_wrap;
|
||||
struct { floppy_image_device *image; bool hdl; } m_floppy[2];
|
||||
|
||||
required_shared_ptr<uint16_t> m_p_videoram;
|
||||
required_device<ram_device> m_ram;
|
||||
@ -283,10 +291,12 @@ private:
|
||||
required_device<i8257_device> m_dma8257;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<dw_keyboard_device> m_kbd;
|
||||
required_device<upd765a_device> m_fdc;
|
||||
required_device_array<floppy_connector, 2> m_flop;
|
||||
required_region_ptr<u8> m_p_chargen;
|
||||
output_finder<4> m_leds;
|
||||
required_device<i8048_device> m_mcu;
|
||||
required_device<i8255_device> m_mcuppi;
|
||||
required_device<upd765a_device> m_fdc;
|
||||
required_device_array<floppy_connector, 2> m_drive;
|
||||
};
|
||||
|
||||
|
||||
@ -330,6 +340,9 @@ void ibm6580_state::p40_w(offs_t offset, uint8_t data)
|
||||
m_dma0pg = data;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
break;
|
||||
|
||||
case 8:
|
||||
m_p50 = data;
|
||||
break;
|
||||
@ -619,13 +632,6 @@ WRITE_LINE_MEMBER(ibm6580_state::kb_strobe_w)
|
||||
m_ppi8255->pc4_w(m_kb_strobe);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(ibm6580_state::floppy_intrq)
|
||||
{
|
||||
m_floppy_intrq = state;
|
||||
if (state)
|
||||
m_floppy_idle = true;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(ibm6580_state::hrq_w)
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
|
||||
@ -644,133 +650,71 @@ void ibm6580_state::memory_write_byte(offs_t offset, uint8_t data)
|
||||
prog_space.write_byte(offset | (m_dma0pg << 16), data);
|
||||
}
|
||||
|
||||
bool ibm6580_state::floppy_mcu_cr_full()
|
||||
{
|
||||
uint8_t command = m_floppy_mcu_cr.peek();
|
||||
// floppy adapter board
|
||||
|
||||
if ((command & 1) && m_floppy_mcu_cr_fifo == 1)
|
||||
return true;
|
||||
if (command == 0x0c && m_floppy_mcu_cr_fifo == 4)
|
||||
return true;
|
||||
if (m_floppy_mcu_cr_fifo == 3)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
void ibm6580_state::mcu_io_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
LOGDBG("MCU IO %02x(%d) <- %02x\n", m_mcu_p1, m_mcu_p1 & 7, data);
|
||||
|
||||
switch (m_mcu_p1 & 7)
|
||||
{
|
||||
case 0: case 1: case 2: case 3:
|
||||
m_mcuppi->write(m_mcu_p1, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ibm6580_state::floppy_mcu_command()
|
||||
uint8_t ibm6580_state::mcu_io_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0, command = m_floppy_mcu_cr.dequeue(), i;
|
||||
uint8_t data = 0;
|
||||
|
||||
LOG("Floppy mcu_command %02x\n", command);
|
||||
|
||||
m_floppy_mcu_sr.clear();
|
||||
m_floppy_idle = true;
|
||||
|
||||
switch (command)
|
||||
switch (m_mcu_p1 & 7)
|
||||
{
|
||||
case 0:
|
||||
m_fdc->soft_reset();
|
||||
break;
|
||||
|
||||
// 3 bytes
|
||||
case 4:
|
||||
break;
|
||||
|
||||
// 1 byte -- get status?
|
||||
case 5:
|
||||
m_floppy_mcu_sr.enqueue(0x00);
|
||||
if (m_flop[0]->get_device()->exists())
|
||||
m_floppy_mcu_sr.enqueue( m_flop[0]->get_device()->idx_r() ? 0x08 : 0);
|
||||
else
|
||||
m_floppy_mcu_sr.enqueue(0x08);
|
||||
break;
|
||||
|
||||
// 3 bytes, no return -- engage head
|
||||
case 6:
|
||||
m_floppy_mcu_cr.dequeue();
|
||||
i = m_floppy_mcu_cr.dequeue();
|
||||
m_floppy_hdl = i;
|
||||
break;
|
||||
|
||||
// 1 byte -- read head engage signal
|
||||
case 7:
|
||||
m_floppy_mcu_sr.enqueue(0x00);
|
||||
m_floppy_mcu_sr.enqueue(m_floppy_hdl);
|
||||
break;
|
||||
|
||||
// 3 bytes
|
||||
case 8:
|
||||
break;
|
||||
|
||||
// 4 bytes -- used by cp/m. drive select?
|
||||
case 0xc:
|
||||
break;
|
||||
|
||||
// 1 byte -- get drive ready status?
|
||||
case 0xd:
|
||||
m_floppy_mcu_sr.enqueue(0x00);
|
||||
i = 0;
|
||||
if (m_flop[0]->get_device()->exists())
|
||||
i |= m_flop[0]->get_device()->ready_r() ? 0 : 0x40;
|
||||
if (m_flop[1]->get_device()->exists())
|
||||
i |= m_flop[1]->get_device()->ready_r() ? 0 : 0x80;
|
||||
m_floppy_mcu_sr.enqueue(i);
|
||||
break;
|
||||
|
||||
// 3 bytes, no return -- recalibrate?
|
||||
case 0xe:
|
||||
m_floppy_mcu_cr.dequeue();
|
||||
i = m_floppy_mcu_cr.dequeue();
|
||||
#if 1
|
||||
if (i & 1)
|
||||
m_fdc->set_floppy(m_flop[0]->get_device());
|
||||
else if (i & 2)
|
||||
m_fdc->set_floppy(m_flop[1]->get_device());
|
||||
#endif
|
||||
break;
|
||||
|
||||
// 1 byte
|
||||
case 0x13:
|
||||
break;
|
||||
|
||||
// 1 byte
|
||||
case 0x15:
|
||||
case 0: case 1: case 2: case 3:
|
||||
data = m_mcuppi->read(m_mcu_p1);
|
||||
break;
|
||||
}
|
||||
|
||||
m_floppy_mcu_cr.clear();
|
||||
m_floppy_mcu_cr_fifo = 0;
|
||||
LOGDBG("MCU IO %02x(%d) == %02x at %s\n", m_mcu_p1, m_mcu_p1 & 7, data, machine().describe_context());
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void ibm6580_state::mcuppi_c_w(uint8_t data)
|
||||
{
|
||||
LOGDBG("MCU PPI PC <- %02x\n", data);
|
||||
m_mcuppi_c = data;
|
||||
m_mcu->set_input_line(MCS48_INPUT_IRQ, BIT(data, 3)); // invert?
|
||||
}
|
||||
|
||||
// what happens on access to odd address ?
|
||||
void ibm6580_state::floppy_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
LOG("Floppy %02x <- %02x\n", 0x8150 + (offset << 1), data);
|
||||
LOG("Floppy %s %02x <- %02x\n", machine().describe_context(), 0x8150 + (offset << 1), data);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0: // 8150 -- mcu reset?
|
||||
m_floppy_mcu_sr.enqueue(0x00);
|
||||
m_floppy_mcu_sr.enqueue(0x00);
|
||||
m_mcu->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
|
||||
break;
|
||||
|
||||
case 1: // 8152
|
||||
m_fdc->soft_reset();
|
||||
case 1: // 8152 -- fdc reset? status not checked
|
||||
// m_fdc->soft_reset();
|
||||
break;
|
||||
|
||||
case 2: // 8154
|
||||
if (BIT(m_gate, 14))
|
||||
m_floppy_mcu_wrap = data;
|
||||
break;
|
||||
|
||||
case 5: // 815A
|
||||
m_fdc->fifo_w(data);
|
||||
if (m_floppy_idle)
|
||||
m_floppy_idle = false;
|
||||
break;
|
||||
|
||||
case 6: // 815C
|
||||
m_floppy_mcu_cr.enqueue(data);
|
||||
m_floppy_mcu_cr_fifo++;
|
||||
if (floppy_mcu_cr_full())
|
||||
floppy_mcu_command();
|
||||
m_mcuppi_a = data;
|
||||
m_mcuppi->pc4_w(1);
|
||||
m_mcuppi->pc4_w(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -785,8 +729,12 @@ uint8_t ibm6580_state::floppy_r(offs_t offset)
|
||||
// bit 4 -- ?? ready
|
||||
// bit 5 -- mcu busy
|
||||
// bit 6 -- ?? idle
|
||||
if (m_floppy_mcu_sr.empty() && (m_floppy_idle || m_floppy_intrq))
|
||||
data |= 0x40;
|
||||
data = 8 | BIT(m_mcuppi_c, 7) << 6 | (m_mcuppi_c & 0x20);
|
||||
break;
|
||||
|
||||
case 3: // 8156
|
||||
if (BIT(m_gate, 14))
|
||||
data = m_floppy_mcu_wrap << 2;
|
||||
break;
|
||||
|
||||
case 4: // 8158
|
||||
@ -798,27 +746,11 @@ uint8_t ibm6580_state::floppy_r(offs_t offset)
|
||||
break;
|
||||
|
||||
case 6: // 815c
|
||||
if (!m_floppy_mcu_sr.empty())
|
||||
data = m_floppy_mcu_sr.dequeue();
|
||||
data = m_mcuppi->acka_r();
|
||||
break;
|
||||
}
|
||||
|
||||
if (offset)
|
||||
LOG("Floppy %02x == %02x\n", 0x8150 + (offset << 1), data);
|
||||
else {
|
||||
floppy_image_device *f = m_flop[0]->get_device();
|
||||
|
||||
if (f)
|
||||
LOG("Floppy %02x == %02x (empty %d hdl %d + idle %d irq %d drq %d + dskchg %d idx %d cyl %d)\n",
|
||||
0x8150 + (offset << 1), data,
|
||||
m_floppy_mcu_sr.empty(), m_floppy_hdl,
|
||||
m_floppy_idle, m_fdc->get_irq(), m_fdc->get_drq(),
|
||||
f->dskchg_r(), f->idx_r(), f->get_cyl());
|
||||
else
|
||||
LOG("Floppy %02x == %02x (idle %d irq %d drq %d)\n",
|
||||
0x8150 + (offset << 1), data,
|
||||
m_floppy_idle, m_fdc->get_irq(), m_fdc->get_drq());
|
||||
}
|
||||
LOG("Floppy %s %02x == %02x\n", machine().describe_context(), 0x8150 + (offset << 1), data);
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -844,8 +776,8 @@ void ibm6580_state::ibm6580_io(address_map &map)
|
||||
map(0x0120, 0x0127).rw(m_pit8253, FUNC(pit8253_device::read), FUNC(pit8253_device::write)).umask16(0x00ff);
|
||||
map(0x0140, 0x0143).rw("upd8251a", FUNC(i8251_device::read), FUNC(i8251_device::write)).umask16(0x00ff);
|
||||
map(0x0160, 0x0163).rw("upd8251b", FUNC(i8251_device::read), FUNC(i8251_device::write)).umask16(0x00ff);
|
||||
map(0x4000, 0x400f).unmaprw();
|
||||
map(0x5000, 0x500f).unmaprw();
|
||||
map(0x4000, 0x400f).unmaprw(); // bus error reporting?
|
||||
map(0x5000, 0x500f).unmaprw(); // bus error reporting?
|
||||
map(0x6000, 0x601f).unmaprw();
|
||||
map(0x8060, 0x807f).w(FUNC(ibm6580_state::gate_close_w)).umask16(0xff);
|
||||
map(0x8150, 0x815f).rw(FUNC(ibm6580_state::floppy_r), FUNC(ibm6580_state::floppy_w)).umask16(0x00ff); // HLE of floppy board
|
||||
@ -854,6 +786,17 @@ void ibm6580_state::ibm6580_io(address_map &map)
|
||||
map(0xe000, 0xe02f).rw(FUNC(ibm6580_state::video_r), FUNC(ibm6580_state::video_w)).umask16(0x00ff);
|
||||
}
|
||||
|
||||
void ibm6580_state::mcu_mem(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x000, 0x7ff).rom().region("mcu", 0);
|
||||
}
|
||||
|
||||
void ibm6580_state::mcu_io(address_map &map)
|
||||
{
|
||||
map(0x00, 0xff).rw(FUNC(ibm6580_state::mcu_io_r), FUNC(ibm6580_state::mcu_io_w));
|
||||
}
|
||||
|
||||
|
||||
uint32_t ibm6580_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
@ -970,6 +913,9 @@ void ibm6580_state::machine_start()
|
||||
|
||||
m_fdc->set_rate(500000); // FIXME: workaround
|
||||
|
||||
m_floppy[0].image = m_fdc->subdevice<floppy_connector>("0")->get_device();
|
||||
m_floppy[1].image = m_fdc->subdevice<floppy_connector>("1")->get_device();
|
||||
|
||||
m_leds.resolve();
|
||||
|
||||
memset(m_p_videoram, 0x0, 0x1000);
|
||||
@ -977,23 +923,22 @@ void ibm6580_state::machine_start()
|
||||
|
||||
void ibm6580_state::machine_reset()
|
||||
{
|
||||
m_p40 = m_p4a = m_p50 = m_gate = m_e000 = m_ppi_c = m_floppy_sr = m_led_state = 0;
|
||||
m_p40 = m_p4a = m_p50 = m_gate = m_ppi_c = m_led_state = 0;
|
||||
m_mcu_p1 = m_mcu_p2 = 0;
|
||||
m_mcuppi_a = m_mcuppi_b = m_mcuppi_c = 0;
|
||||
m_e000 = false;
|
||||
m_kb_data_bit = false;
|
||||
m_kb_clock = false;
|
||||
m_kb_strobe = true;
|
||||
m_kb_data = 0;
|
||||
m_floppy_idle = true;
|
||||
|
||||
m_pit8253->set_clockin(0, 0.0);
|
||||
|
||||
m_p40 |= m_kbd->memory_record_r();
|
||||
|
||||
m_flop[0]->get_device()->mon_w(!m_flop[0]->get_device()->exists());
|
||||
m_flop[1]->get_device()->mon_w(!m_flop[1]->get_device()->exists());
|
||||
m_fdc->set_floppy(m_flop[0]->get_device());
|
||||
m_floppy_mcu_sr.clear();
|
||||
m_floppy_mcu_cr.clear();
|
||||
m_floppy_mcu_cr_fifo = 0;
|
||||
m_floppy[0].hdl = m_floppy[1].hdl = false;
|
||||
|
||||
m_fdc->set_floppy(m_drive[0]->get_device());
|
||||
}
|
||||
|
||||
static void dw_floppies(device_slot_interface &device)
|
||||
@ -1049,13 +994,6 @@ void ibm6580_state::ibm6580(machine_config &config)
|
||||
m_dma8257->in_ior_cb<0>().set(m_fdc, FUNC(upd765a_device::dma_r));
|
||||
m_dma8257->out_iow_cb<0>().set(m_fdc, FUNC(upd765a_device::dma_w));
|
||||
|
||||
UPD765A(config, m_fdc, 24_MHz_XTAL / 3, false, false);
|
||||
m_fdc->intrq_wr_callback().set(FUNC(ibm6580_state::floppy_intrq));
|
||||
// m_fdc->intrq_wr_callback().append(m_pic8259, FUNC(pic8259_device::ir4_w));
|
||||
m_fdc->drq_wr_callback().set(m_dma8257, FUNC(i8257_device::dreq0_w));
|
||||
FLOPPY_CONNECTOR(config, UPD765_TAG ":0", dw_floppies, "8sssd", floppy_image_device::default_mfm_floppy_formats);
|
||||
FLOPPY_CONNECTOR(config, UPD765_TAG ":1", dw_floppies, "8sssd", floppy_image_device::default_mfm_floppy_formats);
|
||||
|
||||
i8251_device &upd8251a(I8251(config, "upd8251a", 0));
|
||||
upd8251a.txd_handler().set("rs232a", FUNC(rs232_port_device::write_txd));
|
||||
upd8251a.dtr_handler().set("rs232a", FUNC(rs232_port_device::write_dtr));
|
||||
@ -1080,6 +1018,29 @@ void ibm6580_state::ibm6580(machine_config &config)
|
||||
rs232b.dsr_handler().set("upd8251b", FUNC(i8251_device::write_dsr));
|
||||
rs232b.cts_handler().set("upd8251b", FUNC(i8251_device::write_cts));
|
||||
|
||||
// floppy adapter card (in the drive)
|
||||
|
||||
I8048(config, m_mcu, 24_MHz_XTAL / 6); // XTAL divisor unknown
|
||||
m_mcu->set_addrmap(AS_PROGRAM, &ibm6580_state::mcu_mem);
|
||||
m_mcu->set_addrmap(AS_IO, &ibm6580_state::mcu_io);
|
||||
m_mcu->p1_in_cb().set([this] () {
|
||||
return (m_mcu_p1 & ~0x18) | \
|
||||
(!m_floppy[0].image->idx_r() << 3) | (!m_floppy[1].image->idx_r() << 4);
|
||||
});
|
||||
m_mcu->p1_out_cb().set([this] (uint8_t data) { m_mcu_p1 = data; });
|
||||
|
||||
I8255(config, m_mcuppi);
|
||||
m_mcuppi->in_pa_callback().set([this] () { LOGDBG("MCU PPI read A: %02X\n", m_mcuppi_a); return m_mcuppi_a; });
|
||||
m_mcuppi->out_pb_callback().set([this] (uint8_t data) { m_mcuppi_b = data; });
|
||||
m_mcuppi->out_pc_callback().set(FUNC(ibm6580_state::mcuppi_c_w));
|
||||
|
||||
// NEC D765D. READY and SELECT likely not connected. SEEK, STEP and DIR likely connected to MCU.
|
||||
UPD765A(config, m_fdc, 24_MHz_XTAL / 3, false, false);
|
||||
m_fdc->intrq_wr_callback().set([this] (bool state) { m_floppy_intrq = state; });
|
||||
m_fdc->drq_wr_callback().set(m_dma8257, FUNC(i8257_device::dreq0_w));
|
||||
FLOPPY_CONNECTOR(config, UPD765_TAG ":0", dw_floppies, "8sssd", floppy_image_device::default_mfm_floppy_formats);
|
||||
FLOPPY_CONNECTOR(config, UPD765_TAG ":1", dw_floppies, "8sssd", floppy_image_device::default_mfm_floppy_formats);
|
||||
|
||||
SOFTWARE_LIST(config, "flop_list").set_original("ibm6580");
|
||||
}
|
||||
|
||||
@ -1111,6 +1072,9 @@ ROM_START( ibm6580 )
|
||||
|
||||
ROM_REGION( 0x2000, "chargen", 0 )
|
||||
ROM_LOAD( "8493383_chr.bin", 0x0000, 0x2000, CRC(779044df) SHA1(95ec46f9edf4d44c5dd3c955c73e00754d58e180))
|
||||
|
||||
ROM_REGION( 0x800, "mcu", 0 )
|
||||
ROM_LOAD( "4430030_flp_8041.bin", 0x0000, 0x0400, CRC(2bb96799) SHA1(e30b0f2d790197f290858eab74ad5e151ded78c3))
|
||||
ROM_END
|
||||
|
||||
/* Driver */
|
||||
|
Loading…
Reference in New Issue
Block a user