(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):
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
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
@ -39,12 +39,6 @@
only and therefore circumvent the wait state generation. This is in fact
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>;
// ==========================================================================
#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;
/*
Implementation for modern floppy system.
*/
class snug_bwg_device : public ti_expansion_card_device
{
public:
@ -142,109 +139,4 @@ private:
// Debugging
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

View File

@ -431,16 +431,13 @@ SLOT_INTERFACE_END
SLOT_INTERFACE_START( peribox_slot7 )
SLOT_INTERFACE("ide", TI99_IDE)
SLOT_INTERFACE("usbsm", TI99_USBSM)
SLOT_INTERFACE("bwgleg", TI99_BWG_LEG)
SLOT_INTERFACE("bwg", TI99_BWG)
SLOT_INTERFACE("hfdc", TI99_HFDC_LEG)
SLOT_INTERFACE("hfdcnew", TI99_HFDC)
SLOT_INTERFACE_END
SLOT_INTERFACE_START( peribox_slot8 )
SLOT_INTERFACE("tifdcleg", TI99_FDC_LEG)
SLOT_INTERFACE("tifdc", TI99_FDC)
SLOT_INTERFACE("bwgleg", TI99_BWG_LEG)
SLOT_INTERFACE("bwg", TI99_BWG)
SLOT_INTERFACE("hfdc", TI99_HFDC_LEG)
SLOT_INTERFACE("hfdcnew", TI99_HFDC)
@ -497,7 +494,6 @@ SLOT_INTERFACE_START( peribox_slot7nobwg )
SLOT_INTERFACE_END
SLOT_INTERFACE_START( peribox_slot8nobwg )
SLOT_INTERFACE("tifdcleg", TI99_FDC_LEG)
SLOT_INTERFACE("tifdc", TI99_FDC)
SLOT_INTERFACE("hfdc", TI99_HFDC_LEG)
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>;
//===========================================================================
/***********************************************
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
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

View File

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

View File

@ -44,7 +44,6 @@ TODO:
#include "sound/beep.h"
#include "video/733_asr.h"
#include "imagedev/flopdrv.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
static const floppy_interface ti990_4_floppy_interface =
/* static const floppy_interface ti990_4_floppy_interface =
{
FLOPPY_STANDARD_8_DSSD,
LEGACY_FLOPPY_OPTIONS_NAME(fd800),
NULL
};
FLOPPY_STANDARD_8_DSSD,
LEGACY_FLOPPY_OPTIONS_NAME(fd800),
NULL
}; */
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_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
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_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
/*

File diff suppressed because it is too large Load Diff

View File

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