(MESS) ti99: Removed legacy wd17xx controllers

This commit is contained in:
Michael Zapf 2015-06-03 21:59:26 +02:00
parent 381d3dd572
commit c01ee6740e
9 changed files with 443 additions and 1447 deletions

View File

@ -31,7 +31,7 @@
Known issues (Feb 2014): Known issues (Feb 2014):
1. The BwG controller cannot run with the Geneve or other non-9900 computers. - The BwG controller cannot run with the Geneve or other non-9900 computers.
The reason for that is the wait state logic. It assumes that when The reason for that is the wait state logic. It assumes that when
executing MOVB @>5FF6,*R2, first a value from 5FF7 is attempted to be read, executing MOVB @>5FF6,*R2, first a value from 5FF7 is attempted to be read,
just as the TI console does. In that case, wait states are inserted if just as the TI console does. In that case, wait states are inserted if
@ -39,12 +39,6 @@
only and therefore circumvent the wait state generation. This is in fact only and therefore circumvent the wait state generation. This is in fact
not an emulation glitch but the behavior of the real expansion card. not an emulation glitch but the behavior of the real expansion card.
Resolved issues (Feb 2014):
1. The BwG controller failed to read single-density disks. This only occurs
with the legacy implementation because the modern floppy implementation
reproduces the correct recording format on the medium, so the controller
actually detects FM or MFM.
*******************************************************************************/ *******************************************************************************/
@ -704,498 +698,3 @@ const rom_entry *snug_bwg_device::device_rom_region() const
} }
const device_type TI99_BWG = &device_creator<snug_bwg_device>; const device_type TI99_BWG = &device_creator<snug_bwg_device>;
// ==========================================================================
#define FDCLEG_TAG "wd1773"
/*
Legacy implementation
*/
snug_bwg_legacy_device::snug_bwg_legacy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ti_expansion_card_device(mconfig, TI99_BWG_LEG, "SNUG BwG Floppy Controller LEGACY", tag, owner, clock, "ti99_bwg_leg", __FILE__),
m_wd1773(*this, FDCLEG_TAG),
m_clock(*this, CLOCK_TAG) { }
/*
Callback called at the end of DVENA pulse
*/
void snug_bwg_legacy_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
m_DVENA = CLEAR_LINE;
set_ready_line();
}
/*
Operate the wait state logic.
*/
void snug_bwg_legacy_device::set_ready_line()
{
// This is the wait state logic
if (TRACE_SIGNALS) logerror("bwg: address=%04x, DRQ=%d, INTRQ=%d, MOTOR=%d\n", m_address & 0xffff, m_DRQ, m_IRQ, m_DVENA);
line_state nready = (m_dataregLB && // Are we accessing 5ff7
m_WAITena && // and the wait state generation is active (SBO 2)
(m_DRQ==CLEAR_LINE) && // and we are waiting for a byte
(m_IRQ==CLEAR_LINE) && // and there is no interrupt yet
(m_DVENA==ASSERT_LINE) // and the motor is turning?
)? ASSERT_LINE : CLEAR_LINE; // In that case, clear READY and thus trigger wait states
if (TRACE_READY) if (nready==ASSERT_LINE) logerror("bwg: READY line = %d\n", (nready==CLEAR_LINE)? 1:0);
m_slot->set_ready((nready==CLEAR_LINE)? ASSERT_LINE : CLEAR_LINE);
}
/*
Callback, called from the controller chip whenever DRQ/IRQ state change
*/
WRITE_LINE_MEMBER( snug_bwg_legacy_device::intrq_w )
{
if (TRACE_SIGNALS) logerror("bwg: set intrq = %d\n", state);
m_IRQ = (line_state)state;
// Note that INTB is actually not used in the TI-99 family. But the
// controller asserts the line nevertheless, probably intended for
// use in another planned TI system
m_slot->set_intb(state==ASSERT_LINE);
// We need to explicitly set the READY line to release the datamux
set_ready_line();
}
WRITE_LINE_MEMBER( snug_bwg_legacy_device::drq_w )
{
if (TRACE_SIGNALS) logerror("bwg: set drq = %d\n", state);
m_DRQ = (line_state)state;
// We need to explicitly set the READY line to release the datamux
set_ready_line();
}
SETADDRESS_DBIN_MEMBER( snug_bwg_legacy_device::setaddress_dbin )
{
// Selection login in the PAL and some circuits on the board
// Is the card being selected?
m_address = offset;
m_inDsrArea = ((m_address & m_select_mask)==m_select_value);
if (!m_inDsrArea) return;
if (TRACE_ADDRESS) logerror("bwg: set address = %04x\n", offset & 0xffff);
// Is the WD chip on the card being selected?
// We need the even and odd addresses for the wait state generation,
// but only the even addresses when we access it
m_WDsel0 = m_inDsrArea && !m_rtc_enabled
&& ((state==ASSERT_LINE && ((m_address & 0x1ff8)==0x1ff0)) // read
|| (state==CLEAR_LINE && ((m_address & 0x1ff8)==0x1ff8))); // write
m_WDsel = m_WDsel0 && ((m_address & 1)==0);
// Is the RTC selected on the card? (even addr)
m_RTCsel = m_inDsrArea && m_rtc_enabled && ((m_address & 0x1fe1)==0x1fe0);
// RTC disabled:
// 5c00 - 5fef: RAM
// 5ff0 - 5fff: Controller (f0 = status, f2 = track, f4 = sector, f6 = data)
// RTC enabled:
// 5c00 - 5fdf: RAM
// 5fe0 - 5fff: Clock (even addr)
// Is RAM selected? We just check for the last 1K and let the RTC or WD
// just take control before
m_lastK = m_inDsrArea && ((m_address & 0x1c00)==0x1c00);
// Is the data register port of the WD being selected?
// In fact, the address to read the data from is 5FF6, but the TI-99 datamux
// fetches both bytes from 5FF7 and 5FF6, the odd one first. The BwG uses
// the odd address to operate the READY line
m_dataregLB = m_WDsel0 && ((m_address & 0x07)==0x07);
// Clear or assert the outgoing READY line
set_ready_line();
}
/*
Read a byte from ROM, RAM, FDC, or RTC. See setaddress_dbin for selection
logic.
*/
READ8Z_MEMBER(snug_bwg_legacy_device::readz)
{
if (m_inDsrArea && m_selected)
{
// 010x xxxx xxxx xxxx
if (m_lastK)
{
// ...1 11xx xxxx xxxx
if (m_rtc_enabled)
{
if (m_RTCsel)
{
// .... ..11 111x xxx0
if (!space.debugger_access()) *value = m_clock->read(space, (m_address & 0x001e) >> 1);
if (TRACE_RW) logerror("bwg: read RTC: %04x -> %02x\n", m_address & 0xffff, *value);
}
else
{
*value = m_buffer_ram[(m_ram_page<<10) | (m_address & 0x03ff)];
if (TRACE_RW) logerror("bwg: read ram: %04x (page %d)-> %02x\n", m_address & 0xffff, m_ram_page, *value);
}
}
else
{
if (m_WDsel)
{
// .... ..11 1111 0xx0
// Note that the value is inverted again on the board,
// so we can drop the inversion
if (!space.debugger_access()) *value = m_wd1773->read(space, (m_address >> 1)&0x03);
if (TRACE_RW) logerror("bwg: read FDC: %04x -> %02x\n", m_address & 0xffff, *value);
if (TRACE_DATA)
{
if ((m_address & 0xffff)==0x5ff6) logerror("%02x ", *value);
else logerror("\n%04x: %02x", m_address&0xffff, *value);
}
}
else
{
*value = m_buffer_ram[(m_ram_page<<10) | (m_address & 0x03ff)];
if (TRACE_RW) logerror("bwg: read ram: %04x (page %d)-> %02x\n", m_address & 0xffff, m_ram_page, *value);
}
}
}
else
{
*value = m_dsrrom[(m_rom_page<<13) | (m_address & 0x1fff)];
if (TRACE_RW) logerror("bwg: read dsr: %04x (page %d)-> %02x\n", m_address & 0xffff, m_rom_page, *value);
}
}
}
/*
Resets the drive geometry. This is required because the heuristic of
the default implementation sets the drive geometry to the geometry
of the medium.
*/
void snug_bwg_legacy_device::set_geometry(legacy_floppy_image_device *drive, floppy_type_t type)
{
// This assertion may fail when the names of the floppy devices change.
// Unfortunately, the wd17xx device assumes the floppy drives at root
// level, so we use an explicitly qualified tag. See peribox.h.
assert(drive != NULL);
drive->floppy_drive_set_geometry(type);
}
void snug_bwg_legacy_device::set_all_geometries(floppy_type_t type)
{
set_geometry(machine().device<legacy_floppy_image_device>(PFLOPPY_0), type);
set_geometry(machine().device<legacy_floppy_image_device>(PFLOPPY_1), type);
set_geometry(machine().device<legacy_floppy_image_device>(PFLOPPY_2), type);
}
/*
Write a byte
4000 - 5bff: ROM, ignore write (4 banks)
rtc disabled:
5c00 - 5fef: RAM
5ff0 - 5fff: Controller (f8 = command, fa = track, fc = sector, fe = data)
rtc enabled:
5c00 - 5fdf: RAM
5fe0 - 5fff: Clock (even addr)
*/
WRITE8_MEMBER(snug_bwg_legacy_device::write)
{
if (m_inDsrArea && m_selected)
{
if (m_lastK)
{
if (m_rtc_enabled)
{
if (m_RTCsel)
{
// .... ..11 111x xxx0
if (TRACE_RW) logerror("bwg: write RTC: %04x <- %02x\n", m_address & 0xffff, data);
if (!space.debugger_access()) m_clock->write(space, (m_address & 0x001e) >> 1, data);
}
else
{
if (TRACE_RW) logerror("bwg: write ram: %04x (page %d) <- %02x\n", m_address & 0xffff, m_ram_page, data);
m_buffer_ram[(m_ram_page<<10) | (m_address & 0x03ff)] = data;
}
}
else
{
if (m_WDsel)
{
// .... ..11 1111 1xx0
// Note that the value is inverted again on the board,
// so we can drop the inversion
if (TRACE_RW) logerror("bwg: write FDC: %04x <- %02x\n", m_address & 0xffff, data);
if (!space.debugger_access()) m_wd1773->write(space, (m_address >> 1)&0x03, data);
}
else
{
if (TRACE_RW) logerror("bwg: write ram: %04x (page %d) <- %02x\n", m_address & 0xffff, m_ram_page, data);
m_buffer_ram[(m_ram_page<<10) | (m_address & 0x03ff)] = data;
}
}
}
}
}
/*
CRU read handler. *=inverted.
bit 0: DSK4 connected*
bit 1: DSK1 connected*
bit 2: DSK2 connected*
bit 3: DSK3 connected*
bit 4: Dip 1
bit 5: Dip 2
bit 6: Dip 3
bit 7: Dip 4
*/
READ8Z_MEMBER(snug_bwg_legacy_device::crureadz)
{
UINT8 reply = 0;
if ((offset & 0xff00)==m_cru_base)
{
if ((offset & 0x00ff)==0)
{
// Assume that we have 4 drives connected
// If we want to do that properly, we need to check the actually
// available drives (not the images!). But why should we connect less?
reply = 0x00;
// DIP switches. Note that a closed switch means 0
// xx01 1111 11 = only dsk1; 10 = 1+2, 01=1/2/3, 00=1-4
if (m_dip1 != 0) reply |= 0x10;
if (m_dip2 != 0) reply |= 0x20;
reply |= (m_dip34 << 6);
*value = ~reply;
}
else
*value = 0;
if (TRACE_CRU) logerror("bwg: Read CRU = %02x\n", *value);
}
}
WRITE8_MEMBER(snug_bwg_legacy_device::cruwrite)
{
int drive, drivebit;
if ((offset & 0xff00)==m_cru_base)
{
int bit = (offset >> 1) & 0x0f;
switch (bit)
{
case 0:
/* (De)select the card. Indicated by a LED on the board. */
m_selected = (data != 0);
if (TRACE_CRU) logerror("bwg: Map DSR (bit 0) = %d\n", m_selected);
break;
case 1:
/* Activate motor */
if (data && !m_strobe_motor)
{ /* on rising edge, set motor_running for 4.23s */
if (TRACE_CRU) logerror("bwg: trigger motor (bit 1)\n");
m_DVENA = ASSERT_LINE;
m_motor_on_timer->adjust(attotime::from_msec(4230));
}
m_strobe_motor = (data != 0);
break;
case 2:
/* Set disk ready/hold (bit 2) */
// 0: ignore IRQ and DRQ
// 1: TMS9900 is stopped until IRQ or DRQ are set
// OR the motor stops rotating - rotates for 4.23s after write
// to CRU bit 1
if (TRACE_CRU) logerror("bwg: arm wait state logic (bit 2) = %d\n", data);
m_WAITena = (data != 0);
break;
case 4:
case 5:
case 6:
case 8:
/* Select drive 0-2 (DSK1-DSK3) (bits 4-6) */
/* Select drive 3 (DSK4) (bit 8) */
drive = (bit == 8) ? 3 : (bit - 4); /* drive # (0-3) */
if (TRACE_CRU) logerror("bwg: set drive (bit %d) = %d\n", bit, data);
drivebit = 1<<drive;
if (data != 0)
{
if ((m_DSEL & drivebit) == 0) /* select drive */
{
if (m_DSEL != 0)
logerror("bwg: Multiple drives selected, %02x\n", m_DSEL);
m_DSEL |= drivebit;
m_wd1773->set_drive(drive);
}
}
else
m_DSEL &= ~drivebit;
break;
case 7:
/* Select side of disk (bit 7) */
m_SIDE = data;
if (TRACE_CRU) logerror("bwg: set side (bit 7) = %d\n", data);
m_wd1773->set_side(m_SIDE);
break;
case 10:
/* double density enable (active low) */
if (TRACE_CRU) logerror("bwg: set double density (bit 10) = %d\n", data);
m_wd1773->dden_w((data != 0) ? ASSERT_LINE : CLEAR_LINE);
break;
case 11:
/* EPROM A13 */
if (data != 0)
m_rom_page |= 1;
else
m_rom_page &= 0xfe; // 11111110
if (TRACE_CRU) logerror("bwg: set ROM page (bit 11) = %d, page = %d\n", bit, m_rom_page);
break;
case 13:
/* RAM A10 */
m_ram_page = data;
if (TRACE_CRU) logerror("bwg: set RAM page (bit 13) = %d, page = %d\n", bit, m_ram_page);
break;
case 14:
/* Override FDC with RTC (active high) */
if (TRACE_CRU) logerror("bwg: turn on RTC (bit 14) = %d\n", data);
m_rtc_enabled = (data != 0);
break;
case 15:
/* EPROM A14 */
if (data != 0)
m_rom_page |= 2;
else
m_rom_page &= 0xfd; // 11111101
if (TRACE_CRU) logerror("bwg: set ROM page (bit 15) = %d, page = %d\n", bit, m_rom_page);
break;
case 3:
if (TRACE_CRU) logerror("bwg: set head load (bit 3) = %d\n", data);
break;
case 9:
case 12:
/* Unused (bit 3, 9 & 12) */
if (TRACE_CRU) logerror("bwg: set unknown bit %d = %d\n", bit, data);
break;
}
}
}
void snug_bwg_legacy_device::device_start(void)
{
logerror("bwg: BWG start\n");
m_dsrrom = memregion(DSRROM)->base();
m_buffer_ram = memregion(BUFFER)->base();
m_motor_on_timer = timer_alloc(MOTOR_TIMER);
m_cru_base = 0x1100;
}
void snug_bwg_legacy_device::device_reset()
{
logerror("bwg: BWG reset\n");
if (m_genmod)
{
m_select_mask = 0x1fe000;
m_select_value = 0x174000;
}
else
{
m_select_mask = 0x7e000;
m_select_value = 0x74000;
}
m_strobe_motor = false;
m_DVENA = CLEAR_LINE;
m_DSEL = 0;
m_SIDE = 0;
ti99_set_80_track_drives(FALSE);
floppy_type_t type = FLOPPY_STANDARD_5_25_DSDD_40;
set_all_geometries(type);
m_DRQ = CLEAR_LINE;
m_IRQ = CLEAR_LINE;
m_WAITena = false;
m_rtc_enabled = false;
m_selected = false;
m_dataregLB = false;
m_inDsrArea = false;
m_dip1 = ioport("BWGDIP1")->read();
m_dip2 = ioport("BWGDIP2")->read();
m_dip34 = ioport("BWGDIP34")->read();
m_rom_page = 0;
m_ram_page = 0;
}
INPUT_PORTS_START( bwg_fdc_legacy )
PORT_START( "BWGDIP1" )
PORT_DIPNAME( 0x01, 0x00, "BwG step rate" )
PORT_DIPSETTING( 0x00, "6 ms")
PORT_DIPSETTING( 0x01, "20 ms")
PORT_START( "BWGDIP2" )
PORT_DIPNAME( 0x01, 0x00, "BwG date/time display" )
PORT_DIPSETTING( 0x00, "Hide")
PORT_DIPSETTING( 0x01, "Show")
PORT_START( "BWGDIP34" )
PORT_DIPNAME( 0x03, 0x03, "BwG drives" )
PORT_DIPSETTING( 0x00, "DSK1 only")
PORT_DIPSETTING( 0x01, "DSK1-DSK2")
PORT_DIPSETTING( 0x02, "DSK1-DSK3")
PORT_DIPSETTING( 0x03, "DSK1-DSK4")
INPUT_PORTS_END
MACHINE_CONFIG_FRAGMENT( bwg_fdc_legacy )
MCFG_DEVICE_ADD(FDCLEG_TAG, WD1773, 0)
MCFG_WD17XX_DEFAULT_DRIVE4_TAGS
MCFG_WD17XX_INTRQ_CALLBACK(WRITELINE(snug_bwg_legacy_device, intrq_w))
MCFG_WD17XX_DRQ_CALLBACK(WRITELINE(snug_bwg_legacy_device, drq_w))
MCFG_DEVICE_ADD(CLOCK_TAG, MM58274C, 0)
MCFG_MM58274C_MODE24(1) // 24 hour
MCFG_MM58274C_DAY1(0) // sunday
MACHINE_CONFIG_END
ROM_START( bwg_fdc_legacy )
ROM_REGION(0x8000, DSRROM, 0)
ROM_LOAD("bwg.bin", 0x0000, 0x8000, CRC(06f1ec89) SHA1(6ad77033ed268f986d9a5439e65f7d391c4b7651)) /* BwG disk DSR ROM */
ROM_REGION(0x0800, BUFFER, 0) /* BwG RAM buffer */
ROM_FILL(0x0000, 0x0400, 0x00)
ROM_END
machine_config_constructor snug_bwg_legacy_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( bwg_fdc_legacy );
}
const rom_entry *snug_bwg_legacy_device::device_rom_region() const
{
return ROM_NAME( bwg_fdc_legacy );
}
ioport_constructor snug_bwg_legacy_device::device_input_ports() const
{
return INPUT_PORTS_NAME( bwg_fdc_legacy );
}
const device_type TI99_BWG_LEG = &device_creator<snug_bwg_legacy_device>;

View File

@ -20,9 +20,6 @@
extern const device_type TI99_BWG; extern const device_type TI99_BWG;
/*
Implementation for modern floppy system.
*/
class snug_bwg_device : public ti_expansion_card_device class snug_bwg_device : public ti_expansion_card_device
{ {
public: public:
@ -142,109 +139,4 @@ private:
// Debugging // Debugging
bool m_debug_dataout; bool m_debug_dataout;
}; };
// =========================================================================
/*
Legacy implementation.
*/
#include "machine/wd17xx.h"
extern const device_type TI99_BWG_LEG;
class snug_bwg_legacy_device : public ti_expansion_card_device
{
public:
snug_bwg_legacy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_READ8Z_MEMBER(readz);
DECLARE_WRITE8_MEMBER(write);
DECLARE_SETADDRESS_DBIN_MEMBER(setaddress_dbin);
DECLARE_WRITE_LINE_MEMBER( intrq_w );
DECLARE_WRITE_LINE_MEMBER( drq_w );
DECLARE_READ8Z_MEMBER(crureadz);
DECLARE_WRITE8_MEMBER(cruwrite);
protected:
virtual void device_start(void);
virtual void device_reset(void);
virtual const rom_entry *device_rom_region() const;
virtual machine_config_constructor device_mconfig_additions() const;
virtual ioport_constructor device_input_ports() const;
private:
void set_ready_line();
void set_all_geometries(floppy_type_t type);
void set_geometry(legacy_floppy_image_device *drive, floppy_type_t type);
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
// Holds the status of the DRQ and IRQ lines.
line_state m_DRQ, m_IRQ;
// DIP switch state
int m_dip1, m_dip2, m_dip34;
// Page selection for ROM and RAM
int m_ram_page; // 0-1
int m_rom_page; // 0-3
// When true, the READY line will be cleared (create wait states) when
// waiting for data from the controller.
bool m_WAITena;
// Address in card area
bool m_inDsrArea;
// WD selected
bool m_WDsel, m_WDsel0;
// RTC selected
bool m_RTCsel;
// last 1K area selected
bool m_lastK;
// Data register +1 selected
bool m_dataregLB;
/* Indicates whether the clock is mapped into the address space. */
bool m_rtc_enabled;
/* When TRUE, keeps DVENA high. */
bool m_strobe_motor;
// Signal DVENA. When TRUE, makes some drive turning.
line_state m_DVENA;
// Recent address
int m_address;
/* Indicates which drive has been selected. Values are 0, 1, 2, and 4. */
// 000 = no drive
// 001 = drive 1
// 010 = drive 2
// 100 = drive 3
int m_DSEL;
/* Signal SIDSEL. 0 or 1, indicates the selected head. */
int m_SIDE;
// Link to the WD1773 controller on the board.
required_device<wd1773_device> m_wd1773;
// Link to the real-time clock on the board.
required_device<mm58274c_device> m_clock;
// count 4.23s from rising edge of motor_on
emu_timer* m_motor_on_timer;
// DSR ROM
UINT8* m_dsrrom;
// Buffer RAM
UINT8* m_buffer_ram;
};
#endif #endif

View File

@ -431,16 +431,13 @@ SLOT_INTERFACE_END
SLOT_INTERFACE_START( peribox_slot7 ) SLOT_INTERFACE_START( peribox_slot7 )
SLOT_INTERFACE("ide", TI99_IDE) SLOT_INTERFACE("ide", TI99_IDE)
SLOT_INTERFACE("usbsm", TI99_USBSM) SLOT_INTERFACE("usbsm", TI99_USBSM)
SLOT_INTERFACE("bwgleg", TI99_BWG_LEG)
SLOT_INTERFACE("bwg", TI99_BWG) SLOT_INTERFACE("bwg", TI99_BWG)
SLOT_INTERFACE("hfdc", TI99_HFDC_LEG) SLOT_INTERFACE("hfdc", TI99_HFDC_LEG)
SLOT_INTERFACE("hfdcnew", TI99_HFDC) SLOT_INTERFACE("hfdcnew", TI99_HFDC)
SLOT_INTERFACE_END SLOT_INTERFACE_END
SLOT_INTERFACE_START( peribox_slot8 ) SLOT_INTERFACE_START( peribox_slot8 )
SLOT_INTERFACE("tifdcleg", TI99_FDC_LEG)
SLOT_INTERFACE("tifdc", TI99_FDC) SLOT_INTERFACE("tifdc", TI99_FDC)
SLOT_INTERFACE("bwgleg", TI99_BWG_LEG)
SLOT_INTERFACE("bwg", TI99_BWG) SLOT_INTERFACE("bwg", TI99_BWG)
SLOT_INTERFACE("hfdc", TI99_HFDC_LEG) SLOT_INTERFACE("hfdc", TI99_HFDC_LEG)
SLOT_INTERFACE("hfdcnew", TI99_HFDC) SLOT_INTERFACE("hfdcnew", TI99_HFDC)
@ -497,7 +494,6 @@ SLOT_INTERFACE_START( peribox_slot7nobwg )
SLOT_INTERFACE_END SLOT_INTERFACE_END
SLOT_INTERFACE_START( peribox_slot8nobwg ) SLOT_INTERFACE_START( peribox_slot8nobwg )
SLOT_INTERFACE("tifdcleg", TI99_FDC_LEG)
SLOT_INTERFACE("tifdc", TI99_FDC) SLOT_INTERFACE("tifdc", TI99_FDC)
SLOT_INTERFACE("hfdc", TI99_HFDC_LEG) SLOT_INTERFACE("hfdc", TI99_HFDC_LEG)
SLOT_INTERFACE("hfdcnew", TI99_HFDC) SLOT_INTERFACE("hfdcnew", TI99_HFDC)

View File

@ -427,313 +427,3 @@ const rom_entry *ti_fdc_device::device_rom_region() const
} }
const device_type TI99_FDC = &device_creator<ti_fdc_device>; const device_type TI99_FDC = &device_creator<ti_fdc_device>;
//===========================================================================
/***********************************************
Legacy implementation, to be removed
***********************************************/
#define TI_FDCLEG_TAG "ti_dssd_controller_legacy"
#define FDCLEG_TAG "wd1771"
ti_fdc_legacy_device::ti_fdc_legacy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ti_expansion_card_device(mconfig, TI99_FDC_LEG, "TI-99 Standard DSSD Floppy Controller LEGACY", tag, owner, clock, "ti99_fdc_leg", __FILE__),
m_fd1771(*this, FDCLEG_TAG) { }
/*
callback called at the end of DVENA pulse
*/
void ti_fdc_legacy_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
m_DVENA = CLEAR_LINE;
if (TRACE_MOTOR) logerror("tifdc: Motor off\n");
set_ready_line();
}
/*
Operate the wait state logic.
*/
void ti_fdc_legacy_device::set_ready_line()
{
// This is the wait state logic
if (TRACE_SIGNALS) logerror("tifdc: address=%04x, DRQ=%d, INTRQ=%d, MOTOR=%d\n", m_address & 0xffff, m_DRQ, m_IRQ, m_DVENA);
line_state nready = (m_WDsel && // Are we accessing 5ffx (even addr)?
m_WAITena && // and the wait state generation is active (SBO 2)
(m_DRQ==CLEAR_LINE) && // and we are waiting for a byte
(m_IRQ==CLEAR_LINE) && // and there is no interrupt yet
(m_DVENA==ASSERT_LINE) // and the motor is turning?
)? ASSERT_LINE : CLEAR_LINE; // In that case, clear READY and thus trigger wait states
if (TRACE_READY) logerror("tifdc: READY line = %d\n", (nready==CLEAR_LINE)? 1:0);
m_slot->set_ready((nready==CLEAR_LINE)? ASSERT_LINE : CLEAR_LINE);
}
SETADDRESS_DBIN_MEMBER( ti_fdc_legacy_device::setaddress_dbin )
{
// Selection login in the PAL and some circuits on the board
// Is the card being selected?
m_address = offset;
m_inDsrArea = ((m_address & m_select_mask)==m_select_value);
if (!m_inDsrArea) return;
if (TRACE_ADDRESS) logerror("tifdc: set address = %04x\n", offset & 0xffff);
// Is the WD chip on the card being selected?
m_WDsel = m_inDsrArea && ((m_address & 0x1ff1)==0x1ff0);
// Clear or assert the outgoing READY line
set_ready_line();
}
READ8Z_MEMBER(ti_fdc_legacy_device::readz)
{
if (m_inDsrArea && m_selected)
{
// only use the even addresses from 1ff0 to 1ff6.
// Note that data is inverted.
// 0101 1111 1111 0xx0
UINT8 reply = 0;
if (m_WDsel && ((m_address & 9)==0))
{
if (!space.debugger_access()) reply = m_fd1771->read(space, (offset >> 1)&0x03);
if (TRACE_DATA)
{
if ((m_address & 0xffff)==0x5ff6) logerror("%02x ", ~reply & 0xff);
else logerror("\n%04x: %02x", m_address&0xffff, ~reply & 0xff);
}
}
else
{
reply = m_dsrrom[m_address & 0x1fff];
}
*value = reply;
if (TRACE_RW) logerror("ti_fdc: %04x -> %02x\n", offset & 0xffff, *value);
}
}
WRITE8_MEMBER(ti_fdc_legacy_device::write)
{
if (m_inDsrArea && m_selected)
{
if (TRACE_RW) logerror("ti_fdc: %04x <- %02x\n", offset & 0xffff, ~data & 0xff);
// only use the even addresses from 1ff8 to 1ffe.
// Note that data is inverted.
// 0101 1111 1111 1xx0
if (m_WDsel && ((m_address & 9)==8))
{
if (!space.debugger_access()) m_fd1771->write(space, (offset >> 1)&0x03, data);
}
}
}
/*
The CRU read handler.
bit 0: HLD pin
bit 1-3: drive n active
bit 4: 0: motor strobe on
bit 5: always 0
bit 6: always 1
bit 7: selected side
*/
READ8Z_MEMBER(ti_fdc_legacy_device::crureadz)
{
if ((offset & 0xff00)==m_cru_base)
{
int addr = offset & 0x07;
UINT8 reply = 0;
if (addr == 0)
{
// deliver bits 0-7
// TODO: HLD pin
// The DVENA state is returned inverted
if (m_DVENA==ASSERT_LINE) reply |= ((m_DSEL)<<1);
else reply |= 0x10;
reply |= 0x40;
if (m_SIDSEL) reply |= 0x80;
}
*value = reply;
if (TRACE_CRU) logerror("tifdc: Read CRU = %02x\n", *value);
}
}
WRITE8_MEMBER(ti_fdc_legacy_device::cruwrite)
{
int drive, drivebit;
if ((offset & 0xff00)==m_cru_base)
{
int bit = (offset >> 1) & 0x07;
switch (bit)
{
case 0:
/* (De)select the card. Indicated by a LED on the board. */
m_selected = (data!=0);
if (TRACE_CRU) logerror("tifdc: Map DSR (bit 0) = %d\n", m_selected);
break;
case 1:
/* Activate motor */
if (data==1 && m_lastval==0)
{ /* on rising edge, set motor_running for 4.23s */
if (TRACE_CRU) logerror("tifdc: trigger motor (bit 1)\n");
m_DVENA = ASSERT_LINE;
if (TRACE_MOTOR) logerror("tifdc: motor on\n");
set_ready_line();
m_motor_on_timer->adjust(attotime::from_msec(4230));
}
m_lastval = data;
break;
case 2:
/* Set disk ready/hold (bit 2) */
// 0: ignore IRQ and DRQ
// 1: TMS9900 is stopped until IRQ or DRQ are set
// OR the motor stops rotating - rotates for 4.23s after write
// to CRU bit 1
m_WAITena = (data != 0);
if (TRACE_CRU) logerror("tifdc: arm wait state logic (bit 2) = %d\n", data);
break;
case 3:
/* Load disk heads (HLT pin) (bit 3). Not implemented. */
if (TRACE_CRU) logerror("tifdc: set head load (bit 3) = %d\n", data);
break;
case 4:
case 5:
case 6:
/* Select drive X (bits 4-6) */
drive = bit-4; /* drive # (0-2) */
if (TRACE_CRU) logerror("tifdc: set drive (bit %d) = %d\n", bit, data);
drivebit = 1<<drive;
if (data != 0)
{
if ((m_DSEL & drivebit) == 0) /* select drive */
{
if (m_DSEL != 0)
logerror("tifdc: Multiple drives selected, %02x\n", m_DSEL);
m_DSEL |= drivebit;
m_fd1771->set_drive(drive);
}
}
else
m_DSEL &= ~drivebit;
break;
case 7:
/* Select side of disk (bit 7) */
m_SIDSEL = data;
if (TRACE_CRU) logerror("tifdc: set side (bit 7) = %d\n", data);
m_fd1771->set_side(data);
break;
}
}
}
/*
Resets the drive geometry. This is required because the heuristic of
the default implementation sets the drive geometry to the geometry
of the medium.
*/
void ti_fdc_legacy_device::set_geometry(legacy_floppy_image_device *drive, floppy_type_t type)
{
// This assertion may fail when the names of the floppy devices change.
// Unfortunately, the wd17xx device assumes the floppy drives at root
// level, so we use an explicitly qualified tag. See peribox.h.
assert (drive!=NULL);
drive->floppy_drive_set_geometry(type);
}
void ti_fdc_legacy_device::set_all_geometries(floppy_type_t type)
{
set_geometry(machine().device<legacy_floppy_image_device>(PFLOPPY_0), type);
set_geometry(machine().device<legacy_floppy_image_device>(PFLOPPY_1), type);
set_geometry(machine().device<legacy_floppy_image_device>(PFLOPPY_2), type);
}
/*
Callback, called from the controller chip whenever DRQ/IRQ state change
*/
WRITE_LINE_MEMBER( ti_fdc_legacy_device::intrq_w )
{
if (TRACE_SIGNALS) logerror("ti_fdc: set irq = %d\n", state);
m_IRQ = (line_state)state;
// Note that INTB is actually not used in the TI-99 family. But the
// controller asserts the line nevertheless, probably intended for
// use in another planned TI system
m_slot->set_intb(state);
set_ready_line();
}
WRITE_LINE_MEMBER( ti_fdc_legacy_device::drq_w )
{
if (TRACE_SIGNALS) logerror("ti_fdc: set drq = %d\n", state);
m_DRQ = (line_state)state;
set_ready_line();
}
void ti_fdc_legacy_device::device_start(void)
{
logerror("ti_fdc: TI FDC (legacy) start\n");
m_dsrrom = memregion(DSRROM)->base();
m_motor_on_timer = timer_alloc(MOTOR_TIMER);
m_cru_base = 0x1100;
}
void ti_fdc_legacy_device::device_reset(void)
{
logerror("ti_fdc: TI FDC (legacy) reset\n");
m_DSEL = 0;
m_SIDSEL = 0;
m_DVENA = CLEAR_LINE;
m_lastval = 0;
if (m_genmod)
{
m_select_mask = 0x1fe000;
m_select_value = 0x174000;
}
else
{
m_select_mask = 0x7e000;
m_select_value = 0x74000;
}
m_DRQ = CLEAR_LINE;
m_IRQ = CLEAR_LINE;
m_WAITena = false;
m_selected = false;
m_inDsrArea = false;
m_WDsel = false;
ti99_set_80_track_drives(FALSE);
floppy_type_t type = FLOPPY_STANDARD_5_25_DSDD_40;
set_all_geometries(type);
}
MACHINE_CONFIG_FRAGMENT( ti_fdc_legacy )
MCFG_DEVICE_ADD(FDCLEG_TAG, FD1771, 0)
MCFG_WD17XX_DRIVE_TAGS(PFLOPPY_0, PFLOPPY_1, PFLOPPY_2, NULL)
MCFG_WD17XX_INTRQ_CALLBACK(WRITELINE(ti_fdc_legacy_device, intrq_w))
MCFG_WD17XX_DRQ_CALLBACK(WRITELINE(ti_fdc_legacy_device, drq_w))
MACHINE_CONFIG_END
ROM_START( ti_fdc_legacy )
ROM_REGION(0x2000, DSRROM, 0)
ROM_LOAD("disk.bin", 0x0000, 0x2000, CRC(8f7df93f) SHA1(ed91d48c1eaa8ca37d5055bcf67127ea51c4cad5)) /* TI disk DSR ROM */
ROM_END
machine_config_constructor ti_fdc_legacy_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( ti_fdc_legacy );
}
const rom_entry *ti_fdc_legacy_device::device_rom_region() const
{
return ROM_NAME( ti_fdc_legacy );
}
const device_type TI99_FDC_LEG = &device_creator<ti_fdc_legacy_device>;

View File

@ -108,85 +108,4 @@ private:
// Debugging // Debugging
bool m_debug_dataout; bool m_debug_dataout;
}; };
//===========================================================================
/***********************************************
Legacy implementation
***********************************************/
#include "machine/wd17xx.h"
#include "imagedev/flopdrv.h"
extern const device_type TI99_FDC_LEG;
class ti_fdc_legacy_device : public ti_expansion_card_device
{
public:
ti_fdc_legacy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_READ8Z_MEMBER(readz);
DECLARE_WRITE8_MEMBER(write);
DECLARE_SETADDRESS_DBIN_MEMBER(setaddress_dbin);
DECLARE_WRITE_LINE_MEMBER( intrq_w );
DECLARE_WRITE_LINE_MEMBER( drq_w );
DECLARE_READ8Z_MEMBER(crureadz);
DECLARE_WRITE8_MEMBER(cruwrite);
protected:
virtual void device_start(void);
virtual void device_reset(void);
virtual const rom_entry *device_rom_region() const;
virtual machine_config_constructor device_mconfig_additions() const;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
private:
void set_ready_line();
void set_all_geometries(floppy_type_t type);
void set_geometry(legacy_floppy_image_device *drive, floppy_type_t type);
// Recent address
int m_address;
// Holds the status of the DRQ and IRQ lines.
line_state m_DRQ, m_IRQ;
// Needed for triggering the motor monoflop
UINT8 m_lastval;
// Signal DVENA. When TRUE, makes some drive turning.
line_state m_DVENA;
// When TRUE the CPU is halted while DRQ/IRQ are true.
bool m_WAITena;
// WD chip selected
bool m_WDsel;
// Set when address is in card area
bool m_inDsrArea;
// Indicates which drive has been selected. Values are 0, 1, 2, and 4.
// 000 = no drive
// 001 = drive 1
// 010 = drive 2
// 100 = drive 3
int m_DSEL;
// Signal SIDSEL. 0 or 1, indicates the selected head.
int m_SIDSEL;
// count 4.23s from rising edge of motor_on
emu_timer* m_motor_on_timer;
// Link to the FDC1771 controller on the board.
required_device<fd1771_device> m_fd1771;
// DSR ROM
UINT8* m_dsrrom;
};
#endif #endif

View File

@ -24,37 +24,37 @@
#include "hdc9234.h" #include "hdc9234.h"
// Per-command debugging // Per-command debugging
#define TRACE_SELECT 1 #define TRACE_SELECT 0
#define TRACE_STEP 1 #define TRACE_STEP 0
#define TRACE_RESTORE 1 #define TRACE_RESTORE 0
#define TRACE_SUBSTATES 1 #define TRACE_SUBSTATES 0
#define TRACE_READ 1 #define TRACE_READ 0
#define TRACE_WRITE 1 #define TRACE_WRITE 0
#define TRACE_READREG 1 #define TRACE_READREG 0
#define TRACE_SETREG 1 #define TRACE_SETREG 0
#define TRACE_SETPTR 1 #define TRACE_SETPTR 0
#define TRACE_FORMAT 1 #define TRACE_FORMAT 0
#define TRACE_READTRACK 1 #define TRACE_READTRACK 0
// Common states // Common states
#define TRACE_READID 1 #define TRACE_READID 0
#define TRACE_VERIFY 1 #define TRACE_VERIFY 0
#define TRACE_TRANSFER 1 #define TRACE_TRANSFER 0
// Live states debugging // Live states debugging
#define TRACE_LIVE 1 #define TRACE_LIVE 0
#define TRACE_SHIFT 1 #define TRACE_SHIFT 0
#define TRACE_SYNC 1 #define TRACE_SYNC 0
// Misc debugging // Misc debugging
#define TRACE_DELAY 0 #define TRACE_DELAY 0
#define TRACE_INT 1 #define TRACE_INT 0
#define TRACE_LINES 1 #define TRACE_LINES 0
#define TRACE_INDEX 1 #define TRACE_INDEX 0
#define TRACE_DMA 1 #define TRACE_DMA 0
#define TRACE_DONE 1 #define TRACE_DONE 0
#define TRACE_FAIL 1 #define TRACE_FAIL 0
#define TRACE_AUXBUS 1 #define TRACE_AUXBUS 0
#define TRACE_DETAIL 0 #define TRACE_DETAIL 0

View File

@ -44,7 +44,6 @@ TODO:
#include "sound/beep.h" #include "sound/beep.h"
#include "video/733_asr.h" #include "video/733_asr.h"
#include "imagedev/flopdrv.h"
#include "machine/ti99/990_dk.h" #include "machine/ti99/990_dk.h"
@ -262,12 +261,12 @@ static ADDRESS_MAP_START(cru_map_v, AS_IO, 8, ti990_4_state )
ADDRESS_MAP_END ADDRESS_MAP_END
static const floppy_interface ti990_4_floppy_interface = /* static const floppy_interface ti990_4_floppy_interface =
{ {
FLOPPY_STANDARD_8_DSSD, FLOPPY_STANDARD_8_DSSD,
LEGACY_FLOPPY_OPTIONS_NAME(fd800), LEGACY_FLOPPY_OPTIONS_NAME(fd800),
NULL NULL
}; }; */
MACHINE_RESET_MEMBER(ti990_4_state,ti990_4) MACHINE_RESET_MEMBER(ti990_4_state,ti990_4)
{ {
@ -300,7 +299,7 @@ static MACHINE_CONFIG_START( ti990_4, ti990_4_state )
MCFG_DEVICE_ADD("fd800", FD800, 0) MCFG_DEVICE_ADD("fd800", FD800, 0)
MCFG_FD800_INT_HANDLER(WRITELINE(ti990_4_state, fd_interrupt)) MCFG_FD800_INT_HANDLER(WRITELINE(ti990_4_state, fd_interrupt))
MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(ti990_4_floppy_interface) // MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(ti990_4_floppy_interface)
MACHINE_CONFIG_END MACHINE_CONFIG_END
static MACHINE_CONFIG_START( ti990_4v, ti990_4_state ) static MACHINE_CONFIG_START( ti990_4v, ti990_4_state )
@ -320,7 +319,7 @@ static MACHINE_CONFIG_START( ti990_4v, ti990_4_state )
MCFG_DEVICE_ADD("fd800", FD800, 0) MCFG_DEVICE_ADD("fd800", FD800, 0)
MCFG_FD800_INT_HANDLER(WRITELINE(ti990_4_state, fd_interrupt)) MCFG_FD800_INT_HANDLER(WRITELINE(ti990_4_state, fd_interrupt))
MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(ti990_4_floppy_interface) // MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(ti990_4_floppy_interface)
MACHINE_CONFIG_END MACHINE_CONFIG_END
/* /*

File diff suppressed because it is too large Load Diff

View File

@ -7,8 +7,6 @@
#ifndef __990_DK__ #ifndef __990_DK__
#define __990_DK__ #define __990_DK__
#include "imagedev/flopdrv.h"
extern const device_type FD800; extern const device_type FD800;
#define MAX_FLOPPIES 4 #define MAX_FLOPPIES 4
@ -61,14 +59,14 @@ private:
struct struct
{ {
legacy_floppy_image_device *img; // legacy_floppy_image_device *img;
int phys_cylinder; int phys_cylinder;
int log_cylinder[2]; int log_cylinder[2];
int seclen; int seclen;
} m_drv[MAX_FLOPPIES]; } m_drv[MAX_FLOPPIES];
}; };
LEGACY_FLOPPY_OPTIONS_EXTERN(fd800); // LEGACY_FLOPPY_OPTIONS_EXTERN(fd800);
#define MCFG_FD800_INT_HANDLER( _intcallb ) \ #define MCFG_FD800_INT_HANDLER( _intcallb ) \
devcb = &fd800_legacy_device::static_set_int_callback( *device, DEVCB_##_intcallb ); devcb = &fd800_legacy_device::static_set_int_callback( *device, DEVCB_##_intcallb );