mirror of
https://github.com/holub/mame
synced 2025-05-10 00:01:52 +03:00
(MESS) Half-way modernization for TI-990, removing usage of tokens.
Splitting driver to a video and simple terminal variant. (nw)
This commit is contained in:
parent
b57f9d5974
commit
fd38292291
@ -28,6 +28,7 @@
|
|||||||
Note that only interrupt levels 3-7 are supported by the board (8-15 are not wired).
|
Note that only interrupt levels 3-7 are supported by the board (8-15 are not wired).
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
* Split into two machines for either ASR or VDT
|
||||||
* finish ASR emulation
|
* finish ASR emulation
|
||||||
* programmer panel
|
* programmer panel
|
||||||
* emulate other devices: card reader, printer
|
* emulate other devices: card reader, printer
|
||||||
@ -36,17 +37,13 @@ TODO:
|
|||||||
Rewritten by Michael Zapf 2013
|
Rewritten by Michael Zapf 2013
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*if 1, use 911 VDT; if 0, use 733 ASR */
|
|
||||||
#define VIDEO_911 0
|
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "cpu/tms9900/tms9900.h"
|
#include "cpu/tms9900/tms9900.h"
|
||||||
#if VIDEO_911
|
|
||||||
#include "video/911_vdt.h"
|
#include "video/911_vdt.h"
|
||||||
#include "sound/beep.h"
|
#include "sound/beep.h"
|
||||||
#else
|
|
||||||
#include "video/733_asr.h"
|
#include "video/733_asr.h"
|
||||||
#endif
|
|
||||||
#include "imagedev/flopdrv.h"
|
#include "imagedev/flopdrv.h"
|
||||||
#include "machine/ti99/990_dk.h"
|
#include "machine/ti99/990_dk.h"
|
||||||
|
|
||||||
@ -55,23 +52,26 @@ class ti990_4_state : public driver_device
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ti990_4_state(const machine_config &mconfig, device_type type, const char *tag)
|
ti990_4_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
: driver_device(mconfig, type, tag) ,
|
: driver_device(mconfig, type, tag),
|
||||||
m_maincpu(*this, "maincpu") { }
|
m_maincpu(*this, "maincpu"),
|
||||||
|
m_fd800(*this, "fd800") { }
|
||||||
|
|
||||||
device_t *m_terminal;
|
device_t *m_terminal;
|
||||||
DECLARE_READ8_MEMBER( panel_read );
|
DECLARE_READ8_MEMBER( panel_read );
|
||||||
DECLARE_WRITE8_MEMBER( panel_write );
|
DECLARE_WRITE8_MEMBER( panel_write );
|
||||||
DECLARE_WRITE8_MEMBER( external_operation );
|
DECLARE_WRITE8_MEMBER( external_operation );
|
||||||
DECLARE_READ8_MEMBER( interrupt_level );
|
DECLARE_READ8_MEMBER( interrupt_level );
|
||||||
|
DECLARE_WRITE_LINE_MEMBER( fd_interrupt );
|
||||||
|
|
||||||
DECLARE_DRIVER_INIT(ti990_4);
|
DECLARE_DRIVER_INIT(ti990_4);
|
||||||
|
DECLARE_DRIVER_INIT(ti990_4v);
|
||||||
|
|
||||||
DECLARE_MACHINE_RESET(ti990_4);
|
DECLARE_MACHINE_RESET(ti990_4);
|
||||||
|
|
||||||
virtual void video_start();
|
virtual void video_start();
|
||||||
UINT32 screen_update_ti990_4(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
UINT32 screen_update_ti990_4(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||||
INTERRUPT_GEN_MEMBER(ti990_4_line_interrupt);
|
INTERRUPT_GEN_MEMBER(ti990_4_line_interrupt);
|
||||||
void idle_callback(int state);
|
void idle_callback(int state);
|
||||||
required_device<tms9900_device> m_maincpu;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void hold_load();
|
void hold_load();
|
||||||
@ -87,6 +87,12 @@ private:
|
|||||||
void set_int6(int state);
|
void set_int6(int state);
|
||||||
void set_int7(int state);
|
void set_int7(int state);
|
||||||
bool m_ckon_state;
|
bool m_ckon_state;
|
||||||
|
|
||||||
|
bool m_video;
|
||||||
|
|
||||||
|
// Connected devices
|
||||||
|
required_device<tms9900_device> m_maincpu;
|
||||||
|
required_device<fd800_legacy_device> m_fd800;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -96,16 +102,18 @@ enum
|
|||||||
|
|
||||||
void ti990_4_state::hold_load()
|
void ti990_4_state::hold_load()
|
||||||
{
|
{
|
||||||
m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
m_maincpu->set_input_line(INT_9900_LOAD, ASSERT_LINE);
|
||||||
|
logerror("ti990_4: Triggering LOAD interrupt\n");
|
||||||
m_nmi_timer->adjust(attotime::from_msec(100));
|
m_nmi_timer->adjust(attotime::from_msec(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NMI timer callback
|
LOAD interrupt trigger callback
|
||||||
*/
|
*/
|
||||||
void ti990_4_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
void ti990_4_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||||
{
|
{
|
||||||
m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
|
m_maincpu->set_input_line(INT_9900_LOAD, CLEAR_LINE);
|
||||||
|
logerror("ti990_4: Released LOAD interrupt\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
READ8_MEMBER( ti990_4_state::panel_read )
|
READ8_MEMBER( ti990_4_state::panel_read )
|
||||||
@ -131,7 +139,8 @@ void ti990_4_state::set_int_line(int line, int state)
|
|||||||
{
|
{
|
||||||
m_int_level = 0;
|
m_int_level = 0;
|
||||||
while ((m_intlines & (1 << m_int_level))==0) m_int_level++;
|
while ((m_intlines & (1 << m_int_level))==0) m_int_level++;
|
||||||
m_maincpu->set_input_line(INT_9900_INTREQ, ASSERT_LINE); /* interrupt it, baby */
|
logerror("ti990_4: Setting int level to %x\n", m_int_level);
|
||||||
|
m_maincpu->set_input_line(INT_9900_INTREQ, ASSERT_LINE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_maincpu->set_input_line(INT_9900_INTREQ, CLEAR_LINE);
|
m_maincpu->set_input_line(INT_9900_INTREQ, CLEAR_LINE);
|
||||||
@ -162,63 +171,65 @@ void ti990_4_state::line_interrupt()
|
|||||||
if (m_ckon_state) set_int_line(5, ASSERT_LINE);
|
if (m_ckon_state) set_int_line(5, ASSERT_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Callback from the floppy controller.
|
||||||
|
*/
|
||||||
|
WRITE_LINE_MEMBER(ti990_4_state::fd_interrupt)
|
||||||
|
{
|
||||||
|
set_int7(state);
|
||||||
|
}
|
||||||
|
|
||||||
INTERRUPT_GEN_MEMBER(ti990_4_state::ti990_4_line_interrupt)
|
INTERRUPT_GEN_MEMBER(ti990_4_state::ti990_4_line_interrupt)
|
||||||
{
|
{
|
||||||
#if VIDEO_911
|
if (m_video)
|
||||||
vdt911_keyboard(m_terminal);
|
vdt911_keyboard(m_terminal);
|
||||||
#else
|
else
|
||||||
asr733_keyboard(m_terminal);
|
asr733_keyboard(m_terminal);
|
||||||
#endif
|
|
||||||
|
|
||||||
line_interrupt();
|
line_interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if VIDEO_911
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TI990/4 video emulation.
|
TI990/4 video emulation.
|
||||||
|
|
||||||
We emulate a single VDT911 CRT terminal.
|
We emulate a single VDT911 CRT terminal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void ti990_vdt_int(running_machine &machine, int state)
|
||||||
|
{
|
||||||
|
// set_int3
|
||||||
|
}
|
||||||
|
|
||||||
static const vdt911_init_params_t vdt911_intf =
|
static const vdt911_init_params_t vdt911_intf =
|
||||||
{
|
{
|
||||||
char_1920,
|
char_1920,
|
||||||
vdt911_model_US,
|
vdt911_model_US,
|
||||||
ti990_set_int3
|
ti990_vdt_int
|
||||||
};
|
};
|
||||||
|
|
||||||
void ti990_4_state::video_start()
|
void ti990_4_state::video_start()
|
||||||
{
|
{
|
||||||
m_terminal = machine().device("vdt911");
|
if (m_video)
|
||||||
|
m_terminal = machine().device("vdt911");
|
||||||
|
else
|
||||||
|
m_terminal = machine().device("asr733");
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT32 ti990_4_state::screen_update_ti990_4(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
UINT32 ti990_4_state::screen_update_ti990_4(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||||
{
|
{
|
||||||
vdt911_refresh(m_terminal, bitmap, cliprect, 0, 0);
|
if (m_video)
|
||||||
|
vdt911_refresh(m_terminal, bitmap, cliprect, 0, 0);
|
||||||
|
else
|
||||||
|
asr733_refresh(m_terminal, bitmap, 0, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static const asr733_init_params_t asr733_intf =
|
static const asr733_init_params_t asr733_intf =
|
||||||
{
|
{
|
||||||
// set_int6
|
// set_int6
|
||||||
};
|
};
|
||||||
|
|
||||||
void ti990_4_state::video_start()
|
|
||||||
{
|
|
||||||
m_terminal = machine().device("asr733");
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 ti990_4_state::screen_update_ti990_4(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
|
||||||
{
|
|
||||||
asr733_refresh(m_terminal, bitmap, 0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WRITE8_MEMBER( ti990_4_state::external_operation )
|
WRITE8_MEMBER( ti990_4_state::external_operation )
|
||||||
{
|
{
|
||||||
static const char* extop[8] = { "inv1", "inv2", "IDLE", "RSET", "inv3", "CKON", "CKOF", "LREX" };
|
static const char* extop[8] = { "inv1", "inv2", "IDLE", "RSET", "inv3", "CKON", "CKOF", "LREX" };
|
||||||
@ -287,21 +298,28 @@ ADDRESS_MAP_END
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static ADDRESS_MAP_START(cru_map, AS_IO, 8, ti990_4_state )
|
static ADDRESS_MAP_START(cru_map, AS_IO, 8, ti990_4_state )
|
||||||
#if VIDEO_911
|
|
||||||
AM_RANGE(0x10, 0x11) AM_DEVREAD_LEGACY("vdt911", vdt911_cru_r)
|
|
||||||
AM_RANGE(0x80, 0x8f) AM_DEVWRITE_LEGACY("vdt911", vdt911_cru_w)
|
|
||||||
#else
|
|
||||||
AM_RANGE(0x00, 0x01) AM_DEVREAD_LEGACY("asr733", asr733_cru_r)
|
AM_RANGE(0x00, 0x01) AM_DEVREAD_LEGACY("asr733", asr733_cru_r)
|
||||||
AM_RANGE(0x00, 0x0f) AM_DEVWRITE_LEGACY("asr733", asr733_cru_w)
|
AM_RANGE(0x00, 0x0f) AM_DEVWRITE_LEGACY("asr733", asr733_cru_w)
|
||||||
#endif
|
|
||||||
|
|
||||||
AM_RANGE(0x08, 0x0b) AM_READ_LEGACY(fd800_cru_r)
|
AM_RANGE(0x08, 0x0b) AM_DEVREAD( "fd800", fd800_legacy_device, cru_r )
|
||||||
AM_RANGE(0x40, 0x5f) AM_WRITE_LEGACY(fd800_cru_w)
|
AM_RANGE(0x40, 0x5f) AM_DEVWRITE( "fd800", fd800_legacy_device, cru_w )
|
||||||
|
|
||||||
AM_RANGE(0x1fe, 0x1ff) AM_READ( panel_read )
|
AM_RANGE(0x1fe, 0x1ff) AM_READ( panel_read )
|
||||||
AM_RANGE(0xff0, 0xfff) AM_WRITE( panel_write )
|
AM_RANGE(0xff0, 0xfff) AM_WRITE( panel_write )
|
||||||
ADDRESS_MAP_END
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
|
static ADDRESS_MAP_START(cru_map_v, AS_IO, 8, ti990_4_state )
|
||||||
|
AM_RANGE(0x10, 0x11) AM_DEVREAD_LEGACY("vdt911", vdt911_cru_r)
|
||||||
|
AM_RANGE(0x80, 0x8f) AM_DEVWRITE_LEGACY("vdt911", vdt911_cru_w)
|
||||||
|
|
||||||
|
AM_RANGE(0x08, 0x0b) AM_DEVREAD( "fd800", fd800_legacy_device, cru_r )
|
||||||
|
AM_RANGE(0x40, 0x5f) AM_DEVWRITE( "fd800", fd800_legacy_device, cru_w )
|
||||||
|
|
||||||
|
AM_RANGE(0x1fe, 0x1ff) AM_READ( panel_read )
|
||||||
|
AM_RANGE(0xff0, 0xfff) AM_WRITE( panel_write )
|
||||||
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
|
|
||||||
static const floppy_interface ti990_4_floppy_interface =
|
static const floppy_interface ti990_4_floppy_interface =
|
||||||
{
|
{
|
||||||
DEVCB_NULL,
|
DEVCB_NULL,
|
||||||
@ -309,7 +327,7 @@ static const floppy_interface ti990_4_floppy_interface =
|
|||||||
DEVCB_NULL,
|
DEVCB_NULL,
|
||||||
DEVCB_NULL,
|
DEVCB_NULL,
|
||||||
DEVCB_NULL,
|
DEVCB_NULL,
|
||||||
FLOPPY_STANDARD_5_25_DSHD,
|
FLOPPY_STANDARD_8_DSSD,
|
||||||
LEGACY_FLOPPY_OPTIONS_NAME(fd800),
|
LEGACY_FLOPPY_OPTIONS_NAME(fd800),
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
@ -331,49 +349,80 @@ MACHINE_RESET_MEMBER(ti990_4_state,ti990_4)
|
|||||||
hold_load();
|
hold_load();
|
||||||
reset_int_lines();
|
reset_int_lines();
|
||||||
m_ckon_state = false;
|
m_ckon_state = false;
|
||||||
// fd800_machine_init(machine(), ti990_4_state::set_int7);
|
m_maincpu->set_ready(ASSERT_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DRIVER_INIT_MEMBER(ti990_4_state, ti990_4)
|
||||||
|
{
|
||||||
|
m_video = false;
|
||||||
|
m_nmi_timer = timer_alloc(NMI_TIMER_ID);
|
||||||
|
asr733_init(machine());
|
||||||
|
}
|
||||||
|
|
||||||
|
DRIVER_INIT_MEMBER(ti990_4_state, ti990_4v)
|
||||||
|
{
|
||||||
|
m_video = true;
|
||||||
|
m_nmi_timer = timer_alloc(NMI_TIMER_ID);
|
||||||
|
vdt911_init(machine());
|
||||||
|
}
|
||||||
|
|
||||||
|
static INPUT_PORTS_START(ti990_4)
|
||||||
|
ASR733_KEY_PORTS
|
||||||
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
static INPUT_PORTS_START(ti990_4v)
|
||||||
|
VDT911_KEY_PORTS
|
||||||
|
INPUT_PORTS_END
|
||||||
|
|
||||||
static MACHINE_CONFIG_START( ti990_4, ti990_4_state )
|
static MACHINE_CONFIG_START( ti990_4, ti990_4_state )
|
||||||
/* basic machine hardware */
|
/* basic machine hardware */
|
||||||
/* TMS9900 CPU @ 3.0(???) MHz */
|
/* TMS9900 CPU @ 3.0(???) MHz */
|
||||||
MCFG_TMS99xx_ADD("maincpu", TMS9900, 3000000, memmap, cru_map, cpuconf)
|
MCFG_TMS99xx_ADD("maincpu", TMS9900, 3000000, memmap, cru_map, cpuconf)
|
||||||
MCFG_CPU_PERIODIC_INT_DRIVER(ti990_4_state, ti990_4_line_interrupt, 120/*or TIME_IN_HZ(100) in Europe*/)
|
|
||||||
|
|
||||||
|
MCFG_CPU_PERIODIC_INT_DRIVER(ti990_4_state, ti990_4_line_interrupt, 120/*or TIME_IN_HZ(100) in Europe*/)
|
||||||
MCFG_MACHINE_RESET_OVERRIDE(ti990_4_state, ti990_4 )
|
MCFG_MACHINE_RESET_OVERRIDE(ti990_4_state, ti990_4 )
|
||||||
|
|
||||||
/* video hardware - we emulate a single 911 vdt display */
|
|
||||||
MCFG_SCREEN_ADD("screen", RASTER)
|
MCFG_SCREEN_ADD("screen", RASTER)
|
||||||
MCFG_SCREEN_REFRESH_RATE(60)
|
MCFG_SCREEN_REFRESH_RATE(60)
|
||||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
||||||
MCFG_SCREEN_UPDATE_DRIVER(ti990_4_state, screen_update_ti990_4)
|
MCFG_SCREEN_UPDATE_DRIVER(ti990_4_state, screen_update_ti990_4)
|
||||||
#if VIDEO_911
|
|
||||||
MCFG_SCREEN_SIZE(560, 280)
|
|
||||||
MCFG_SCREEN_VISIBLE_AREA(0, 560-1, 0, /*250*/280-1)
|
|
||||||
MCFG_SCREEN_PALETTE("vdt911:palette")
|
|
||||||
#else
|
|
||||||
MCFG_SCREEN_SIZE(640, 480)
|
MCFG_SCREEN_SIZE(640, 480)
|
||||||
MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
|
MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
|
||||||
MCFG_SCREEN_PALETTE("asr733:palette")
|
MCFG_SCREEN_PALETTE("asr733:palette")
|
||||||
#endif
|
|
||||||
|
|
||||||
#if VIDEO_911
|
|
||||||
MCFG_VDT911_VIDEO_ADD("vdt911", vdt911_intf)
|
|
||||||
#else
|
|
||||||
MCFG_ASR733_VIDEO_ADD("asr733", asr733_intf)
|
MCFG_ASR733_VIDEO_ADD("asr733", asr733_intf)
|
||||||
#endif
|
|
||||||
|
|
||||||
#if VIDEO_911
|
// Floppy controller
|
||||||
/* 911 VDT has a beep tone generator */
|
MCFG_FD800_ADD("fd800", WRITELINE(ti990_4_state, fd_interrupt))
|
||||||
|
MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(ti990_4_floppy_interface)
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
static MACHINE_CONFIG_START( ti990_4v, ti990_4_state )
|
||||||
|
/* basic machine hardware */
|
||||||
|
/* TMS9900 CPU @ 3.0(???) MHz */
|
||||||
|
MCFG_TMS99xx_ADD("maincpu", TMS9900, 3000000, memmap, cru_map_v, cpuconf)
|
||||||
|
|
||||||
|
MCFG_CPU_PERIODIC_INT_DRIVER(ti990_4_state, ti990_4_line_interrupt, 120/*or TIME_IN_HZ(100) in Europe*/)
|
||||||
|
MCFG_MACHINE_RESET_OVERRIDE(ti990_4_state, ti990_4 )
|
||||||
|
|
||||||
|
MCFG_SCREEN_ADD("screen", RASTER)
|
||||||
|
MCFG_SCREEN_REFRESH_RATE(60)
|
||||||
|
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
||||||
|
MCFG_SCREEN_UPDATE_DRIVER(ti990_4_state, screen_update_ti990_4)
|
||||||
|
|
||||||
|
MCFG_SCREEN_SIZE(560, 280)
|
||||||
|
MCFG_SCREEN_VISIBLE_AREA(0, 560-1, 0, /*250*/280-1)
|
||||||
|
MCFG_SCREEN_PALETTE("vdt911:palette")
|
||||||
|
MCFG_VDT911_VIDEO_ADD("vdt911", vdt911_intf)
|
||||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||||
MCFG_SOUND_ADD("beeper", BEEP, 0)
|
MCFG_SOUND_ADD("beeper", BEEP, 0)
|
||||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
|
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
|
||||||
#endif
|
|
||||||
|
// Floppy controller
|
||||||
|
MCFG_FD800_ADD("fd800", 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
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ROM loading
|
ROM loading
|
||||||
*/
|
*/
|
||||||
@ -398,41 +447,22 @@ ROM_START(ti990_4)
|
|||||||
ROMX_LOAD("94519116.u7", 0xFE01, 0x100, CRC(fa387bf3), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(1))
|
ROMX_LOAD("94519116.u7", 0xFE01, 0x100, CRC(fa387bf3), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(1))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* ROM set 945121-4(?): "Floppy disc loader with self test" (cf 945401-9701
|
/* ROM set 945121-4(?): "Floppy disc loader with self test" (cf 945401-9701 pp. 1-19) */
|
||||||
pp. 1-19) */
|
|
||||||
|
|
||||||
ROM_LOAD16_WORD("ti9904.rom", 0xFC00, 0x400, CRC(691e7d19) SHA1(58d9bed80490fdf71c743bfd3077c70840b7df8c))
|
ROM_LOAD16_WORD("ti9904.rom", 0xFC00, 0x400, CRC(691e7d19) SHA1(58d9bed80490fdf71c743bfd3077c70840b7df8c))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if VIDEO_911
|
|
||||||
/* VDT911 character definitions */
|
|
||||||
ROM_REGION(vdt911_chr_region_len, vdt911_chr_region, ROMREGION_ERASEFF)
|
|
||||||
#else
|
|
||||||
ROM_REGION(asr733_chr_region_len, asr733_chr_region, ROMREGION_ERASEFF)
|
ROM_REGION(asr733_chr_region_len, asr733_chr_region, ROMREGION_ERASEFF)
|
||||||
#endif
|
|
||||||
|
|
||||||
ROM_END
|
ROM_END
|
||||||
|
|
||||||
DRIVER_INIT_MEMBER(ti990_4_state,ti990_4)
|
ROM_START(ti990_4v)
|
||||||
{
|
/*CPU memory space*/
|
||||||
m_nmi_timer = timer_alloc(NMI_TIMER_ID);
|
ROM_REGION16_BE(0x10000, "maincpu",0)
|
||||||
|
ROM_LOAD16_WORD("ti9904.rom", 0xFC00, 0x400, CRC(691e7d19) SHA1(58d9bed80490fdf71c743bfd3077c70840b7df8c))
|
||||||
#if VIDEO_911
|
|
||||||
vdt911_init(machine());
|
|
||||||
#else
|
|
||||||
asr733_init(machine());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static INPUT_PORTS_START(ti990_4)
|
|
||||||
#if VIDEO_911
|
|
||||||
VDT911_KEY_PORTS
|
|
||||||
#else
|
|
||||||
ASR733_KEY_PORTS
|
|
||||||
#endif
|
|
||||||
INPUT_PORTS_END
|
|
||||||
|
|
||||||
|
/* VDT911 character definitions */
|
||||||
|
ROM_REGION(vdt911_chr_region_len, vdt911_chr_region, ROMREGION_ERASEFF)
|
||||||
|
ROM_END
|
||||||
|
|
||||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */
|
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */
|
||||||
COMP( 1976, ti990_4, 0, 0, ti990_4, ti990_4, ti990_4_state, ti990_4, "Texas Instruments", "TI Model 990/4 Microcomputer System" , GAME_NOT_WORKING | GAME_NO_SOUND )
|
COMP( 1976, ti990_4, 0, 0, ti990_4, ti990_4, ti990_4_state, ti990_4, "Texas Instruments", "TI 990/4 Minicomputer System" , GAME_NOT_WORKING | GAME_NO_SOUND )
|
||||||
|
COMP( 1976, ti990_4v, ti990_4, 0, ti990_4v, ti990_4v, ti990_4_state, ti990_4v, "Texas Instruments", "TI 990/4 Minicomputer System with Video Display Terminal" , GAME_NOT_WORKING | GAME_NO_SOUND )
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
This floppy disk controller supports IBM-format 8" SSSD and DSSD floppies.
|
This floppy disk controller supports IBM-format 8" SSSD and DSSD floppies.
|
||||||
|
|
||||||
Raphael Nabet 2003
|
Raphael Nabet 2003
|
||||||
|
|
||||||
|
Rewritten as class
|
||||||
|
Michael Zapf 2014
|
||||||
|
|
||||||
|
TODO: Make it work
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
@ -14,40 +19,6 @@
|
|||||||
#include "imagedev/flopdrv.h"
|
#include "imagedev/flopdrv.h"
|
||||||
#include "990_dk.h"
|
#include "990_dk.h"
|
||||||
|
|
||||||
#define MAX_FLOPPIES 4
|
|
||||||
|
|
||||||
enum buf_mode_t {
|
|
||||||
bm_off, bm_read, bm_write
|
|
||||||
};
|
|
||||||
static struct
|
|
||||||
{
|
|
||||||
running_machine *machine;
|
|
||||||
UINT16 recv_buf;
|
|
||||||
UINT16 stat_reg;
|
|
||||||
UINT16 xmit_buf;
|
|
||||||
UINT16 cmd_reg;
|
|
||||||
|
|
||||||
int interrupt_f_f;
|
|
||||||
void (*interrupt_callback)(running_machine &, int state);
|
|
||||||
|
|
||||||
UINT8 buf[128];
|
|
||||||
int buf_pos;
|
|
||||||
buf_mode_t buf_mode;
|
|
||||||
int unit;
|
|
||||||
int head;
|
|
||||||
int sector;
|
|
||||||
/*int non_seq_mode;*/
|
|
||||||
int ddam;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
device_image_interface *img;
|
|
||||||
int phys_cylinder;
|
|
||||||
int log_cylinder[2];
|
|
||||||
int seclen;
|
|
||||||
} drv[MAX_FLOPPIES];
|
|
||||||
} fd800;
|
|
||||||
|
|
||||||
/* status bits */
|
/* status bits */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -69,64 +40,57 @@ enum
|
|||||||
status_unit_shift = 13
|
status_unit_shift = 13
|
||||||
};
|
};
|
||||||
|
|
||||||
LEGACY_FLOPPY_OPTIONS_START(fd800)
|
const device_type FD800 = &device_creator<fd800_legacy_device>;
|
||||||
#if 1
|
|
||||||
/* SSSD 8" */
|
|
||||||
LEGACY_FLOPPY_OPTION(fd800, "dsk", "TI990 8\" SSSD disk image", basicdsk_identify_default, basicdsk_construct_default, NULL,
|
|
||||||
HEADS([1])
|
|
||||||
TRACKS([77])
|
|
||||||
SECTORS([26])
|
|
||||||
SECTOR_LENGTH([128])
|
|
||||||
FIRST_SECTOR_ID([1]))
|
|
||||||
#elif 0
|
|
||||||
/* DSSD 8" */
|
|
||||||
LEGACY_FLOPPY_OPTION(fd800, "dsk", "TI990 8\" DSSD disk image", basicdsk_identify_default, basicdsk_construct_default, NULL,
|
|
||||||
HEADS([2])
|
|
||||||
TRACKS([77])
|
|
||||||
SECTORS([26])
|
|
||||||
SECTOR_LENGTH([128])
|
|
||||||
FIRST_SECTOR_ID([1]))
|
|
||||||
#endif
|
|
||||||
LEGACY_FLOPPY_OPTIONS_END
|
|
||||||
|
|
||||||
static void fd800_field_interrupt(void)
|
fd800_legacy_device::fd800_legacy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, FD800, "TI FD800 Diablo floppy disk controller", tag, owner, clock, "fd800", __FILE__),
|
||||||
|
m_int_line(*this)
|
||||||
{
|
{
|
||||||
if (fd800.interrupt_callback)
|
|
||||||
(*fd800.interrupt_callback)(*fd800.machine, (fd800.stat_reg & status_interrupt) && ! fd800.interrupt_f_f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fd800_unload_proc(device_image_interface &image)
|
void fd800_legacy_device::set_interrupt_line()
|
||||||
{
|
{
|
||||||
int unit = floppy_get_drive(&image.device());
|
if ((m_stat_reg & status_interrupt) && ! m_interrupt_f_f)
|
||||||
|
m_int_line(ASSERT_LINE);
|
||||||
fd800.drv[unit].log_cylinder[0] = fd800.drv[unit].log_cylinder[1] = -1;
|
else
|
||||||
|
m_int_line(CLEAR_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fd800_machine_init(running_machine &machine, void (*interrupt_callback)(running_machine &machine, int state))
|
|
||||||
|
/* void fd800_legacy_device::unload_proc(device_image_interface &image)
|
||||||
{
|
{
|
||||||
int i;
|
int unit = floppy_get_drive(&image.device());
|
||||||
|
|
||||||
fd800.machine = &machine;
|
m_drv[unit].log_cylinder[0] = m_drv[unit].log_cylinder[1] = -1;
|
||||||
fd800.interrupt_callback = interrupt_callback;
|
|
||||||
|
|
||||||
fd800.stat_reg = 0;
|
|
||||||
fd800.interrupt_f_f = 1;
|
|
||||||
|
|
||||||
fd800.buf_pos = 0;
|
|
||||||
fd800.buf_mode = bm_off;
|
|
||||||
|
|
||||||
for (i=0; i<MAX_FLOPPIES; i++)
|
|
||||||
{
|
|
||||||
fd800.drv[i].img = dynamic_cast<device_image_interface *>(floppy_get_device(machine, i));
|
|
||||||
fd800.drv[i].phys_cylinder = -1;
|
|
||||||
fd800.drv[i].log_cylinder[0] = fd800.drv[i].log_cylinder[1] = -1;
|
|
||||||
fd800.drv[i].seclen = 64;
|
|
||||||
floppy_install_unload_proc(&fd800.drv[i].img->device(), fd800_unload_proc);
|
|
||||||
}
|
|
||||||
|
|
||||||
fd800_field_interrupt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fd800_machine_init(void (*interrupt_callback)(running_machine &machine, int state))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
m_machine = &machine;
|
||||||
|
m_interrupt_callback = interrupt_callback;
|
||||||
|
|
||||||
|
m_stat_reg = 0;
|
||||||
|
m_interrupt_f_f = 1;
|
||||||
|
|
||||||
|
m_buf_pos = 0;
|
||||||
|
m_buf_mode = bm_off;
|
||||||
|
|
||||||
|
for (i=0; i<MAX_FLOPPIES; i++)
|
||||||
|
{
|
||||||
|
m_drv[i].img = dynamic_cast<device_image_interface *>(floppy_get_device(machine, i));
|
||||||
|
m_drv[i].phys_cylinder = -1;
|
||||||
|
m_drv[i].log_cylinder[0] = m_drv[i].log_cylinder[1] = -1;
|
||||||
|
m_drv[i].seclen = 64;
|
||||||
|
floppy_install_unload_proc(&m_drv[i].img->device(), unload_proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_interrupt_line();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read the first id field that can be found on the floppy disk.
|
Read the first id field that can be found on the floppy disk.
|
||||||
|
|
||||||
@ -137,7 +101,7 @@ void fd800_machine_init(running_machine &machine, void (*interrupt_callback)(run
|
|||||||
|
|
||||||
Return TRUE if an ID was found
|
Return TRUE if an ID was found
|
||||||
*/
|
*/
|
||||||
static int fd800_read_id(int unit, int head, int *cylinder_id, int *sector_id)
|
int fd800_legacy_device::read_id(int unit, int head, int *cylinder_id, int *sector_id)
|
||||||
{
|
{
|
||||||
/*UINT8 revolution_count;*/
|
/*UINT8 revolution_count;*/
|
||||||
chrn_id id;
|
chrn_id id;
|
||||||
@ -146,7 +110,7 @@ static int fd800_read_id(int unit, int head, int *cylinder_id, int *sector_id)
|
|||||||
|
|
||||||
/*while (revolution_count < 2)*/
|
/*while (revolution_count < 2)*/
|
||||||
/*{*/
|
/*{*/
|
||||||
if (floppy_drive_get_next_id(&fd800.drv[unit].img->device(), head, &id))
|
if (floppy_drive_get_next_id(&m_drv[unit].img->device(), head, &id))
|
||||||
{
|
{
|
||||||
if (cylinder_id)
|
if (cylinder_id)
|
||||||
*cylinder_id = id.C;
|
*cylinder_id = id.C;
|
||||||
@ -169,7 +133,7 @@ static int fd800_read_id(int unit, int head, int *cylinder_id, int *sector_id)
|
|||||||
|
|
||||||
Return TRUE if the given sector ID was found
|
Return TRUE if the given sector ID was found
|
||||||
*/
|
*/
|
||||||
static int fd800_find_sector(int unit, int head, int sector, int *data_id)
|
int fd800_legacy_device::find_sector(int unit, int head, int sector, int *data_id)
|
||||||
{
|
{
|
||||||
UINT8 revolution_count;
|
UINT8 revolution_count;
|
||||||
chrn_id id;
|
chrn_id id;
|
||||||
@ -178,7 +142,7 @@ static int fd800_find_sector(int unit, int head, int sector, int *data_id)
|
|||||||
|
|
||||||
while (revolution_count < 2)
|
while (revolution_count < 2)
|
||||||
{
|
{
|
||||||
if (floppy_drive_get_next_id(&fd800.drv[unit].img->device(), head, &id))
|
if (floppy_drive_get_next_id(&m_drv[unit].img->device(), head, &id))
|
||||||
{
|
{
|
||||||
/* compare id */
|
/* compare id */
|
||||||
if ((id.R == sector) && (id.N == 0))
|
if ((id.R == sector) && (id.N == 0))
|
||||||
@ -203,58 +167,58 @@ static int fd800_find_sector(int unit, int head, int sector, int *data_id)
|
|||||||
|
|
||||||
Return FALSE if the seek was successful
|
Return FALSE if the seek was successful
|
||||||
*/
|
*/
|
||||||
static int fd800_do_seek(int unit, int cylinder, int head)
|
int fd800_legacy_device::do_seek(int unit, int cylinder, int head)
|
||||||
{
|
{
|
||||||
int retries;
|
int retries;
|
||||||
|
|
||||||
if (cylinder > 76)
|
if (cylinder > 76)
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_invalid_cmd;
|
m_stat_reg |= status_invalid_cmd;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fd800.drv[unit].img->exists())
|
if (m_drv[unit].img == NULL || !m_drv[unit].img->exists())
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_drv_not_ready; /* right??? */
|
m_stat_reg |= status_drv_not_ready; /* right??? */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd800.drv[unit].log_cylinder[head] == -1)
|
if (m_drv[unit].log_cylinder[head] == -1)
|
||||||
{ /* current track ID is unknown: read it */
|
{ /* current track ID is unknown: read it */
|
||||||
if (!fd800_read_id(unit, head, &fd800.drv[unit].log_cylinder[head], NULL))
|
if (!read_id(unit, head, &m_drv[unit].log_cylinder[head], NULL))
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_ID_not_found;
|
m_stat_reg |= status_ID_not_found;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* exit if we are already at the requested track */
|
/* exit if we are already at the requested track */
|
||||||
if (fd800.drv[unit].log_cylinder[head] == cylinder)
|
if (m_drv[unit].log_cylinder[head] == cylinder)
|
||||||
{
|
{
|
||||||
/*fd800.stat_reg |= status_OP_complete;*/
|
/*m_stat_reg |= status_OP_complete;*/
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
for (retries=0; retries<10; retries++)
|
for (retries=0; retries<10; retries++)
|
||||||
{ /* seek to requested track */
|
{ /* seek to requested track */
|
||||||
floppy_drive_seek(&fd800.drv[unit].img->device(), cylinder-fd800.drv[unit].log_cylinder[head]);
|
floppy_drive_seek(&m_drv[unit].img->device(), cylinder-m_drv[unit].log_cylinder[head]);
|
||||||
/* update physical track position */
|
/* update physical track position */
|
||||||
if (fd800.drv[unit].phys_cylinder != -1)
|
if (m_drv[unit].phys_cylinder != -1)
|
||||||
fd800.drv[unit].phys_cylinder += cylinder-fd800.drv[unit].log_cylinder[head];
|
m_drv[unit].phys_cylinder += cylinder-m_drv[unit].log_cylinder[head];
|
||||||
/* read new track ID */
|
/* read new track ID */
|
||||||
if (!fd800_read_id(unit, head, &fd800.drv[unit].log_cylinder[head], NULL))
|
if (!read_id(unit, head, &m_drv[unit].log_cylinder[head], NULL))
|
||||||
{
|
{
|
||||||
fd800.drv[unit].log_cylinder[head] = -1;
|
m_drv[unit].log_cylinder[head] = -1;
|
||||||
fd800.stat_reg |= status_ID_not_found;
|
m_stat_reg |= status_ID_not_found;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
/* exit if we have reached the requested track */
|
/* exit if we have reached the requested track */
|
||||||
if (fd800.drv[unit].log_cylinder[head] == cylinder)
|
if (m_drv[unit].log_cylinder[head] == cylinder)
|
||||||
{
|
{
|
||||||
/*fd800.stat_reg |= status_OP_complete;*/
|
/*m_stat_reg |= status_OP_complete;*/
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* track not found */
|
/* track not found */
|
||||||
fd800.stat_reg |= status_seek_err;
|
m_stat_reg |= status_seek_err;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,32 +229,32 @@ static int fd800_do_seek(int unit, int cylinder, int head)
|
|||||||
|
|
||||||
Return FALSE if the restore was successful
|
Return FALSE if the restore was successful
|
||||||
*/
|
*/
|
||||||
static int fd800_do_restore(int unit)
|
int fd800_legacy_device::do_restore(int unit)
|
||||||
{
|
{
|
||||||
int seek_count = 0;
|
int seek_count = 0;
|
||||||
int seek_complete;
|
int seek_complete;
|
||||||
|
|
||||||
if (!fd800.drv[unit].img->exists())
|
if (!m_drv[unit].img->exists())
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_drv_not_ready; /* right??? */
|
m_stat_reg |= status_drv_not_ready; /* right??? */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* limit iterations to 76 to prevent an endless loop if the disc is locked */
|
/* limit iterations to 76 to prevent an endless loop if the disc is locked */
|
||||||
while (!(seek_complete = !floppy_tk00_r(&fd800.drv[unit].img->device())) && (seek_count < 76))
|
while (!(seek_complete = !floppy_tk00_r(&m_drv[unit].img->device())) && (seek_count < 76))
|
||||||
{
|
{
|
||||||
floppy_drive_seek(&fd800.drv[unit].img->device(), -1);
|
floppy_drive_seek(&m_drv[unit].img->device(), -1);
|
||||||
seek_count++;
|
seek_count++;
|
||||||
}
|
}
|
||||||
if (! seek_complete)
|
if (! seek_complete)
|
||||||
{
|
{
|
||||||
fd800.drv[unit].phys_cylinder = -1;
|
m_drv[unit].phys_cylinder = -1;
|
||||||
fd800.stat_reg |= status_seek_err;
|
m_stat_reg |= status_seek_err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fd800.drv[unit].phys_cylinder = 0;
|
m_drv[unit].phys_cylinder = 0;
|
||||||
/*fd800.stat_reg |= status_OP_complete;*/
|
/*m_stat_reg |= status_OP_complete;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
return ! seek_complete;
|
return ! seek_complete;
|
||||||
@ -299,60 +263,60 @@ static int fd800_do_restore(int unit)
|
|||||||
/*
|
/*
|
||||||
Perform a read operation for one sector
|
Perform a read operation for one sector
|
||||||
*/
|
*/
|
||||||
static void fd800_do_read(void)
|
void fd800_legacy_device::do_read(void)
|
||||||
{
|
{
|
||||||
int data_id;
|
int data_id;
|
||||||
|
|
||||||
if ((fd800.sector == 0) || (fd800.sector > 26))
|
if ((m_sector == 0) || (m_sector > 26))
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_invalid_cmd;
|
m_stat_reg |= status_invalid_cmd;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fd800_find_sector(fd800.unit, fd800.head, fd800.sector, &data_id))
|
if (!find_sector(m_unit, m_head, m_sector, &data_id))
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_ID_not_found;
|
m_stat_reg |= status_ID_not_found;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
floppy_drive_read_sector_data(&fd800.drv[fd800.unit].img->device(), fd800.head, data_id, fd800.buf, 128);
|
floppy_drive_read_sector_data(&m_drv[m_unit].img->device(), m_head, data_id, m_buf, 128);
|
||||||
fd800.buf_pos = 0;
|
m_buf_pos = 0;
|
||||||
fd800.buf_mode = bm_read;
|
m_buf_mode = bm_read;
|
||||||
fd800.recv_buf = (fd800.buf[fd800.buf_pos<<1] << 8) | fd800.buf[(fd800.buf_pos<<1)+1];
|
m_recv_buf = (m_buf[m_buf_pos<<1] << 8) | m_buf[(m_buf_pos<<1)+1];
|
||||||
|
|
||||||
fd800.stat_reg |= status_XFER_ready;
|
m_stat_reg |= status_XFER_ready;
|
||||||
fd800.stat_reg |= status_OP_complete; /* right??? */
|
m_stat_reg |= status_OP_complete; /* right??? */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Perform a write operation for one sector
|
Perform a write operation for one sector
|
||||||
*/
|
*/
|
||||||
static void fd800_do_write(void)
|
void fd800_legacy_device::do_write(void)
|
||||||
{
|
{
|
||||||
int data_id;
|
int data_id;
|
||||||
|
|
||||||
if (fd800.drv[fd800.unit].seclen < 64)
|
if (m_drv[m_unit].seclen < 64)
|
||||||
/* fill with 0s */
|
/* fill with 0s */
|
||||||
memset(fd800.buf+(fd800.drv[fd800.unit].seclen<<1), 0, (64-fd800.drv[fd800.unit].seclen)<<1);
|
memset(m_buf+(m_drv[m_unit].seclen<<1), 0, (64-m_drv[m_unit].seclen)<<1);
|
||||||
|
|
||||||
if (!fd800_find_sector(fd800.unit, fd800.head, fd800.sector, &data_id))
|
if (!find_sector(m_unit, m_head, m_sector, &data_id))
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_ID_not_found;
|
m_stat_reg |= status_ID_not_found;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
floppy_drive_write_sector_data(&fd800.drv[fd800.unit].img->device(), fd800.head, data_id, fd800.buf, 128, fd800.ddam);
|
floppy_drive_write_sector_data(&m_drv[m_unit].img->device(), m_head, data_id, m_buf, 128, m_ddam);
|
||||||
fd800.buf_pos = 0;
|
m_buf_pos = 0;
|
||||||
fd800.buf_mode = bm_write;
|
m_buf_mode = bm_write;
|
||||||
|
|
||||||
fd800.stat_reg |= status_XFER_ready;
|
m_stat_reg |= status_XFER_ready;
|
||||||
fd800.stat_reg |= status_OP_complete; /* right??? */
|
m_stat_reg |= status_OP_complete; /* right??? */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Execute a fdc command
|
Execute a fdc command
|
||||||
*/
|
*/
|
||||||
static void fd800_do_cmd(void)
|
void fd800_legacy_device::do_cmd(void)
|
||||||
{
|
{
|
||||||
int unit;
|
int unit;
|
||||||
int cylinder;
|
int cylinder;
|
||||||
@ -361,43 +325,43 @@ static void fd800_do_cmd(void)
|
|||||||
int sector;
|
int sector;
|
||||||
|
|
||||||
|
|
||||||
if (fd800.buf_mode != bm_off)
|
if (m_buf_mode != bm_off)
|
||||||
{ /* All commands in the midst of read or write are interpreted as Stop */
|
{ /* All commands in the midst of read or write are interpreted as Stop */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
|
|
||||||
/* reset status */
|
/* reset status */
|
||||||
fd800.stat_reg = unit << status_unit_shift;
|
m_stat_reg = unit << status_unit_shift;
|
||||||
|
|
||||||
fd800.buf_pos = 0;
|
m_buf_pos = 0;
|
||||||
fd800.buf_mode = bm_off;
|
m_buf_mode = bm_off;
|
||||||
|
|
||||||
fd800.stat_reg |= status_OP_complete;
|
m_stat_reg |= status_OP_complete;
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (fd800.cmd_reg >> 12)
|
switch (m_cmd_reg >> 12)
|
||||||
{
|
{
|
||||||
case 0: /* select
|
case 0: /* select
|
||||||
bits 16-25: 0s
|
bits 16-25: 0s
|
||||||
bits 26-27: unit number (0-3) */
|
bits 26-27: unit number (0-3) */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
|
|
||||||
/* reset status */
|
/* reset status */
|
||||||
fd800.stat_reg = unit << status_unit_shift;
|
m_stat_reg = unit << status_unit_shift;
|
||||||
|
|
||||||
if (!fd800.drv[unit].img->exists())
|
if (!m_drv[unit].img->exists())
|
||||||
fd800.stat_reg |= status_drv_not_ready; /* right??? */
|
m_stat_reg |= status_drv_not_ready; /* right??? */
|
||||||
else if (fd800.drv[unit].img->is_readonly())
|
else if (m_drv[unit].img->is_readonly())
|
||||||
fd800.stat_reg |= status_write_prot;
|
m_stat_reg |= status_write_prot;
|
||||||
else
|
else
|
||||||
fd800.stat_reg |= status_OP_complete;
|
m_stat_reg |= status_OP_complete;
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: /* seek
|
case 1: /* seek
|
||||||
@ -405,57 +369,57 @@ static void fd800_do_cmd(void)
|
|||||||
bits 23-24: 0s
|
bits 23-24: 0s
|
||||||
bits 25: head number (1=upper)
|
bits 25: head number (1=upper)
|
||||||
bits 26-27: unit number (0-3) */
|
bits 26-27: unit number (0-3) */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
head = (fd800.cmd_reg >> 9) & 1;
|
head = (m_cmd_reg >> 9) & 1;
|
||||||
cylinder = fd800.cmd_reg & 0x7f;
|
cylinder = m_cmd_reg & 0x7f;
|
||||||
|
|
||||||
/* reset status */
|
/* reset status */
|
||||||
fd800.stat_reg = unit << status_unit_shift;
|
m_stat_reg = unit << status_unit_shift;
|
||||||
|
|
||||||
if (!fd800_do_seek(unit, cylinder, head))
|
if (!do_seek(unit, cylinder, head))
|
||||||
fd800.stat_reg |= status_OP_complete;
|
m_stat_reg |= status_OP_complete;
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /* restore
|
case 2: /* restore
|
||||||
bits 16-25: 0s
|
bits 16-25: 0s
|
||||||
bits 26-27: unit number (0-3) */
|
bits 26-27: unit number (0-3) */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
|
|
||||||
/* reset status */
|
/* reset status */
|
||||||
fd800.stat_reg = unit << status_unit_shift;
|
m_stat_reg = unit << status_unit_shift;
|
||||||
|
|
||||||
if (!fd800_do_restore(unit))
|
if (!do_restore(unit))
|
||||||
fd800.stat_reg |= status_OP_complete;
|
m_stat_reg |= status_OP_complete;
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: /* sector length
|
case 3: /* sector length
|
||||||
bits 16-22: sector word count (0-64)
|
bits 16-22: sector word count (0-64)
|
||||||
bits 23-25: 0s
|
bits 23-25: 0s
|
||||||
bits 26-27: unit number (0-3) */
|
bits 26-27: unit number (0-3) */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
seclen = fd800.cmd_reg & 0x7f;
|
seclen = m_cmd_reg & 0x7f;
|
||||||
|
|
||||||
/* reset status */
|
/* reset status */
|
||||||
fd800.stat_reg = unit << status_unit_shift;
|
m_stat_reg = unit << status_unit_shift;
|
||||||
|
|
||||||
if ((seclen > 64) || (seclen == 0))
|
if ((seclen > 64) || (seclen == 0))
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_invalid_cmd;
|
m_stat_reg |= status_invalid_cmd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fd800.drv[unit].seclen = seclen;
|
m_drv[unit].seclen = seclen;
|
||||||
fd800.stat_reg |= status_OP_complete;
|
m_stat_reg |= status_OP_complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: /* read
|
case 4: /* read
|
||||||
@ -464,47 +428,47 @@ static void fd800_do_cmd(void)
|
|||||||
bit 24: no sequential sectoring (1=active)
|
bit 24: no sequential sectoring (1=active)
|
||||||
bit 25: head number (1=upper)
|
bit 25: head number (1=upper)
|
||||||
bits 26-27: unit number (0-3) */
|
bits 26-27: unit number (0-3) */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
head = (fd800.cmd_reg >> 9) & 1;
|
head = (m_cmd_reg >> 9) & 1;
|
||||||
/*non_seq_mode = (fd800.cmd_reg >> 8) & 1;*/
|
/*non_seq_mode = (m_cmd_reg >> 8) & 1;*/
|
||||||
sector = fd800.cmd_reg & 0x1f;
|
sector = m_cmd_reg & 0x1f;
|
||||||
|
|
||||||
fd800.unit = unit;
|
m_unit = unit;
|
||||||
fd800.head = head;
|
m_head = head;
|
||||||
fd800.sector = sector;
|
m_sector = sector;
|
||||||
/*fd800.non_seq_mode = non_seq_mode;*/
|
/*m_non_seq_mode = non_seq_mode;*/
|
||||||
|
|
||||||
/* reset status */
|
/* reset status */
|
||||||
fd800.stat_reg = unit << status_unit_shift;
|
m_stat_reg = unit << status_unit_shift;
|
||||||
|
|
||||||
fd800_do_read();
|
do_read();
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: /* read ID
|
case 5: /* read ID
|
||||||
bits 16-24: 0s
|
bits 16-24: 0s
|
||||||
bit 25: head number (1=upper)
|
bit 25: head number (1=upper)
|
||||||
bits 26-27: unit number (0-3) */
|
bits 26-27: unit number (0-3) */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
head = (fd800.cmd_reg >> 9) & 1;
|
head = (m_cmd_reg >> 9) & 1;
|
||||||
|
|
||||||
/* reset status */
|
/* reset status */
|
||||||
fd800.stat_reg = unit << status_unit_shift;
|
m_stat_reg = unit << status_unit_shift;
|
||||||
|
|
||||||
if (!fd800_read_id(unit, head, &cylinder, §or))
|
if (!read_id(unit, head, &cylinder, §or))
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_ID_not_found;
|
m_stat_reg |= status_ID_not_found;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fd800.recv_buf = (cylinder << 8) | sector;
|
m_recv_buf = (cylinder << 8) | sector;
|
||||||
fd800.stat_reg |= status_OP_complete;
|
m_stat_reg |= status_OP_complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6: /* read unformatted
|
case 6: /* read unformatted
|
||||||
@ -520,32 +484,32 @@ static void fd800_do_cmd(void)
|
|||||||
bits 21-24: 0s
|
bits 21-24: 0s
|
||||||
bit 25: head number (1=upper)
|
bit 25: head number (1=upper)
|
||||||
bits 26-27: unit number (0-3) */
|
bits 26-27: unit number (0-3) */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
head = (fd800.cmd_reg >> 9) & 1;
|
head = (m_cmd_reg >> 9) & 1;
|
||||||
sector = fd800.cmd_reg & 0x1f;
|
sector = m_cmd_reg & 0x1f;
|
||||||
|
|
||||||
/* reset status */
|
/* reset status */
|
||||||
fd800.stat_reg = unit << status_unit_shift;
|
m_stat_reg = unit << status_unit_shift;
|
||||||
|
|
||||||
if ((fd800.sector == 0) || (fd800.sector > 26))
|
if ((m_sector == 0) || (m_sector > 26))
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_invalid_cmd;
|
m_stat_reg |= status_invalid_cmd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fd800.unit = unit;
|
m_unit = unit;
|
||||||
fd800.head = head;
|
m_head = head;
|
||||||
fd800.sector = sector;
|
m_sector = sector;
|
||||||
fd800.ddam = 0;
|
m_ddam = 0;
|
||||||
|
|
||||||
fd800.buf_pos = 0;
|
m_buf_pos = 0;
|
||||||
fd800.buf_mode = bm_write;
|
m_buf_mode = bm_write;
|
||||||
fd800.stat_reg |= status_XFER_ready;
|
m_stat_reg |= status_XFER_ready;
|
||||||
fd800.stat_reg |= status_OP_complete; /* right??? */
|
m_stat_reg |= status_OP_complete; /* right??? */
|
||||||
}
|
}
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8: /* write delete
|
case 8: /* write delete
|
||||||
@ -553,32 +517,32 @@ static void fd800_do_cmd(void)
|
|||||||
bits 21-24: 0s
|
bits 21-24: 0s
|
||||||
bit 25: head number (1=upper)
|
bit 25: head number (1=upper)
|
||||||
bits 26-27: unit number (0-3) */
|
bits 26-27: unit number (0-3) */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
head = (fd800.cmd_reg >> 9) & 1;
|
head = (m_cmd_reg >> 9) & 1;
|
||||||
sector = fd800.cmd_reg & 0x1f;
|
sector = m_cmd_reg & 0x1f;
|
||||||
|
|
||||||
/* reset status */
|
/* reset status */
|
||||||
fd800.stat_reg = unit << status_unit_shift;
|
m_stat_reg = unit << status_unit_shift;
|
||||||
|
|
||||||
if ((fd800.sector == 0) || (fd800.sector > 26))
|
if ((m_sector == 0) || (m_sector > 26))
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_invalid_cmd;
|
m_stat_reg |= status_invalid_cmd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fd800.unit = unit;
|
m_unit = unit;
|
||||||
fd800.head = head;
|
m_head = head;
|
||||||
fd800.sector = sector;
|
m_sector = sector;
|
||||||
fd800.ddam = 1;
|
m_ddam = 1;
|
||||||
|
|
||||||
fd800.buf_pos = 0;
|
m_buf_pos = 0;
|
||||||
fd800.buf_mode = bm_write;
|
m_buf_mode = bm_write;
|
||||||
fd800.stat_reg |= status_XFER_ready;
|
m_stat_reg |= status_XFER_ready;
|
||||||
fd800.stat_reg |= status_OP_complete; /* right??? */
|
m_stat_reg |= status_OP_complete; /* right??? */
|
||||||
}
|
}
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9: /* format track
|
case 9: /* format track
|
||||||
@ -592,49 +556,49 @@ static void fd800_do_cmd(void)
|
|||||||
case 10: /* load int mask
|
case 10: /* load int mask
|
||||||
bit 16: bad mask for interrupt (0 = unmask or enable interrupt)
|
bit 16: bad mask for interrupt (0 = unmask or enable interrupt)
|
||||||
bits 17-27: 0s */
|
bits 17-27: 0s */
|
||||||
fd800.interrupt_f_f = fd800.cmd_reg & 1;
|
m_interrupt_f_f = m_cmd_reg & 1;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 11: /* stop
|
case 11: /* stop
|
||||||
bits 16-25: 0s
|
bits 16-25: 0s
|
||||||
bits 26-27: unit number (0-3) */
|
bits 26-27: unit number (0-3) */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
|
|
||||||
/* reset status */
|
/* reset status */
|
||||||
fd800.stat_reg = unit << status_unit_shift;
|
m_stat_reg = unit << status_unit_shift;
|
||||||
|
|
||||||
fd800.stat_reg |= status_OP_complete;
|
m_stat_reg |= status_OP_complete;
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 12: /* step head
|
case 12: /* step head
|
||||||
bits 16-22: track number (0-76)
|
bits 16-22: track number (0-76)
|
||||||
bits 23-25: 0s
|
bits 23-25: 0s
|
||||||
bits 26-27: unit number (0-3) */
|
bits 26-27: unit number (0-3) */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
cylinder = fd800.cmd_reg & 0x7f;
|
cylinder = m_cmd_reg & 0x7f;
|
||||||
|
|
||||||
if (cylinder > 76)
|
if (cylinder > 76)
|
||||||
{
|
{
|
||||||
fd800.stat_reg |= status_invalid_cmd;
|
m_stat_reg |= status_invalid_cmd;
|
||||||
}
|
}
|
||||||
else if ((fd800.drv[unit].phys_cylinder != -1) || (!fd800_do_restore(unit)))
|
else if ((m_drv[unit].phys_cylinder != -1) || (!do_restore(unit)))
|
||||||
{
|
{
|
||||||
floppy_drive_seek(&fd800.drv[unit].img->device(), cylinder-fd800.drv[unit].phys_cylinder);
|
floppy_drive_seek(&m_drv[unit].img->device(), cylinder-m_drv[unit].phys_cylinder);
|
||||||
fd800.stat_reg |= status_OP_complete;
|
m_stat_reg |= status_OP_complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 13: /* maintenance commands
|
case 13: /* maintenance commands
|
||||||
bits 16-23: according to extended command code
|
bits 16-23: according to extended command code
|
||||||
bits 24-27: extended command code (0-7) */
|
bits 24-27: extended command code (0-7) */
|
||||||
switch ((fd800.cmd_reg >> 8) & 15)
|
switch ((m_cmd_reg >> 8) & 15)
|
||||||
{
|
{
|
||||||
case 0: /* reset
|
case 0: /* reset
|
||||||
bits 16-23: 0s */
|
bits 16-23: 0s */
|
||||||
@ -686,29 +650,29 @@ static void fd800_do_cmd(void)
|
|||||||
bit 24: no sequential sectoring (1=active)
|
bit 24: no sequential sectoring (1=active)
|
||||||
bit 25: head number (1=upper)
|
bit 25: head number (1=upper)
|
||||||
bits 26-27: unit number (0-3) */
|
bits 26-27: unit number (0-3) */
|
||||||
unit = (fd800.cmd_reg >> 10) & 3;
|
unit = (m_cmd_reg >> 10) & 3;
|
||||||
head = (fd800.cmd_reg >> 9) & 1;
|
head = (m_cmd_reg >> 9) & 1;
|
||||||
/*non_seq_mode = (fd800.cmd_reg >> 8) & 1;*/
|
/*non_seq_mode = (m_cmd_reg >> 8) & 1;*/
|
||||||
cylinder = fd800.cmd_reg & 0x7f;
|
cylinder = m_cmd_reg & 0x7f;
|
||||||
|
|
||||||
if (!fd800_do_seek(unit, cylinder, head))
|
if (!do_seek(unit, cylinder, head))
|
||||||
{
|
{
|
||||||
fd800.unit = unit;
|
m_unit = unit;
|
||||||
fd800.head = head;
|
m_head = head;
|
||||||
fd800.sector = 1;
|
m_sector = 1;
|
||||||
/*fd800.non_seq_mode = non_seq_mode;*/
|
/*m_non_seq_mode = non_seq_mode;*/
|
||||||
|
|
||||||
fd800_do_read();
|
do_read();
|
||||||
}
|
}
|
||||||
|
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 15: /* Clear Status port
|
case 15: /* Clear Status port
|
||||||
bits 16-27: 0s */
|
bits 16-27: 0s */
|
||||||
fd800.stat_reg = 0;
|
m_stat_reg = 0;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -735,7 +699,7 @@ static void fd800_do_cmd(void)
|
|||||||
30: unit MSB
|
30: unit MSB
|
||||||
31: Interrupt (CBUSY???) (1 -> controller is ready)
|
31: Interrupt (CBUSY???) (1 -> controller is ready)
|
||||||
*/
|
*/
|
||||||
READ8_HANDLER(fd800_cru_r)
|
READ8_MEMBER( fd800_legacy_device::cru_r )
|
||||||
{
|
{
|
||||||
int reply = 0;
|
int reply = 0;
|
||||||
|
|
||||||
@ -744,13 +708,13 @@ static void fd800_do_cmd(void)
|
|||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
/* receive buffer */
|
/* receive buffer */
|
||||||
reply = fd800.recv_buf >> (offset*8);
|
reply = m_recv_buf >> (offset*8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
/* status register */
|
/* status register */
|
||||||
reply = fd800.stat_reg >> ((offset-2)*8);
|
reply = m_stat_reg >> ((offset-2)*8);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,7 +733,7 @@ static void fd800_do_cmd(void)
|
|||||||
27: FD unit number MSB/extended command code
|
27: FD unit number MSB/extended command code
|
||||||
28-31: command code
|
28-31: command code
|
||||||
*/
|
*/
|
||||||
WRITE8_HANDLER(fd800_cru_w)
|
WRITE8_MEMBER( fd800_legacy_device::cru_w )
|
||||||
{
|
{
|
||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
@ -791,61 +755,61 @@ WRITE8_HANDLER(fd800_cru_w)
|
|||||||
case 15:
|
case 15:
|
||||||
/* transmit buffer */
|
/* transmit buffer */
|
||||||
if (data)
|
if (data)
|
||||||
fd800.xmit_buf |= 1 << offset;
|
m_xmit_buf |= 1 << offset;
|
||||||
else
|
else
|
||||||
fd800.xmit_buf &= ~(1 << offset);
|
m_xmit_buf &= ~(1 << offset);
|
||||||
if (offset == 15)
|
if (offset == 15)
|
||||||
{
|
{
|
||||||
switch (fd800.buf_mode)
|
switch (m_buf_mode)
|
||||||
{
|
{
|
||||||
case bm_off:
|
case bm_off:
|
||||||
break;
|
break;
|
||||||
case bm_read:
|
case bm_read:
|
||||||
fd800.buf_pos++;
|
m_buf_pos++;
|
||||||
if (fd800.buf_pos == fd800.drv[fd800.unit].seclen)
|
if (m_buf_pos == m_drv[m_unit].seclen)
|
||||||
{ /* end of sector */
|
{ /* end of sector */
|
||||||
if (fd800.sector == 26)
|
if (m_sector == 26)
|
||||||
{ /* end of track -> end command (right???) */
|
{ /* end of track -> end command (right???) */
|
||||||
fd800.stat_reg &= ~status_XFER_ready;
|
m_stat_reg &= ~status_XFER_ready;
|
||||||
fd800.stat_reg |= status_OP_complete;
|
m_stat_reg |= status_OP_complete;
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800.buf_mode = bm_off;
|
m_buf_mode = bm_off;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* read next sector */
|
{ /* read next sector */
|
||||||
fd800.sector++;
|
m_sector++;
|
||||||
fd800.stat_reg &= ~status_XFER_ready | status_OP_complete | status_interrupt;
|
m_stat_reg &= ~status_XFER_ready | status_OP_complete | status_interrupt;
|
||||||
fd800_do_read();
|
do_read();
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fd800.recv_buf = (fd800.buf[fd800.buf_pos<<1] << 8) | fd800.buf[(fd800.buf_pos<<1)+1];
|
m_recv_buf = (m_buf[m_buf_pos<<1] << 8) | m_buf[(m_buf_pos<<1)+1];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case bm_write:
|
case bm_write:
|
||||||
fd800.buf[fd800.buf_pos<<1] = fd800.xmit_buf >> 8;
|
m_buf[m_buf_pos<<1] = m_xmit_buf >> 8;
|
||||||
fd800.buf[(fd800.buf_pos<<1)+1] = fd800.xmit_buf & 0xff;
|
m_buf[(m_buf_pos<<1)+1] = m_xmit_buf & 0xff;
|
||||||
fd800.buf_pos++;
|
m_buf_pos++;
|
||||||
if (fd800.buf_pos == fd800.drv[fd800.unit].seclen)
|
if (m_buf_pos == m_drv[m_unit].seclen)
|
||||||
{ /* end of sector */
|
{ /* end of sector */
|
||||||
fd800_do_write();
|
do_write();
|
||||||
if (fd800.sector == 26)
|
if (m_sector == 26)
|
||||||
{
|
{
|
||||||
/* end of track -> end command (right???) */
|
/* end of track -> end command (right???) */
|
||||||
fd800.stat_reg &= ~status_XFER_ready;
|
m_stat_reg &= ~status_XFER_ready;
|
||||||
fd800.stat_reg |= status_OP_complete;
|
m_stat_reg |= status_OP_complete;
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800.buf_mode = bm_off;
|
m_buf_mode = bm_off;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* increment to next sector */
|
{ /* increment to next sector */
|
||||||
fd800.sector++;
|
m_sector++;
|
||||||
fd800.stat_reg |= status_interrupt;
|
m_stat_reg |= status_interrupt;
|
||||||
fd800_field_interrupt();
|
set_interrupt_line();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -871,11 +835,55 @@ WRITE8_HANDLER(fd800_cru_w)
|
|||||||
case 31:
|
case 31:
|
||||||
/* command register */
|
/* command register */
|
||||||
if (data)
|
if (data)
|
||||||
fd800.cmd_reg |= 1 << (offset-16);
|
m_cmd_reg |= 1 << (offset-16);
|
||||||
else
|
else
|
||||||
fd800.cmd_reg &= ~(1 << (offset-16));
|
m_cmd_reg &= ~(1 << (offset-16));
|
||||||
if (offset == 31)
|
if (offset == 31)
|
||||||
fd800_do_cmd();
|
do_cmd();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LEGACY_FLOPPY_OPTIONS_START(fd800)
|
||||||
|
#if 1
|
||||||
|
/* SSSD 8" */
|
||||||
|
LEGACY_FLOPPY_OPTION(fd800, "dsk", "TI990 8\" SSSD disk image", basicdsk_identify_default, basicdsk_construct_default, NULL,
|
||||||
|
HEADS([1])
|
||||||
|
TRACKS([77])
|
||||||
|
SECTORS([26])
|
||||||
|
SECTOR_LENGTH([128])
|
||||||
|
FIRST_SECTOR_ID([1]))
|
||||||
|
#elif 0
|
||||||
|
/* DSSD 8" */
|
||||||
|
LEGACY_FLOPPY_OPTION(fd800, "dsk", "TI990 8\" DSSD disk image", basicdsk_identify_default, basicdsk_construct_default, NULL,
|
||||||
|
HEADS([2])
|
||||||
|
TRACKS([77])
|
||||||
|
SECTORS([26])
|
||||||
|
SECTOR_LENGTH([128])
|
||||||
|
FIRST_SECTOR_ID([1]))
|
||||||
|
#endif
|
||||||
|
LEGACY_FLOPPY_OPTIONS_END
|
||||||
|
|
||||||
|
void fd800_legacy_device::device_start(void)
|
||||||
|
{
|
||||||
|
logerror("fd800: start\n");
|
||||||
|
m_int_line.resolve();
|
||||||
|
|
||||||
|
for (int i=0; i<MAX_FLOPPIES; i++)
|
||||||
|
{
|
||||||
|
m_drv[i].img = dynamic_cast<device_image_interface *>(floppy_get_device(machine(), i));
|
||||||
|
m_drv[i].phys_cylinder = -1;
|
||||||
|
m_drv[i].log_cylinder[0] = m_drv[i].log_cylinder[1] = -1;
|
||||||
|
m_drv[i].seclen = 64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fd800_legacy_device::device_reset(void)
|
||||||
|
{
|
||||||
|
logerror("fd800: reset\n");
|
||||||
|
m_stat_reg = 0;
|
||||||
|
m_interrupt_f_f = 1;
|
||||||
|
|
||||||
|
m_buf_pos = 0;
|
||||||
|
m_buf_mode = bm_off;
|
||||||
|
}
|
||||||
|
@ -1,9 +1,73 @@
|
|||||||
/*
|
/*
|
||||||
990_dk.h: include file for 990_dk.c
|
990_dk.h: include file for 990_dk.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __990_DK__
|
||||||
|
#define __990_DK__
|
||||||
|
|
||||||
|
extern const device_type FD800;
|
||||||
|
|
||||||
|
#define MAX_FLOPPIES 4
|
||||||
|
|
||||||
|
class fd800_legacy_device : public device_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
fd800_legacy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
DECLARE_READ8_MEMBER( cru_r );
|
||||||
|
DECLARE_WRITE8_MEMBER( cru_w );
|
||||||
|
template<class _Object> static devcb2_base &static_set_int_callback(device_t &device, _Object object)
|
||||||
|
{
|
||||||
|
return downcast<fd800_legacy_device &>(device).m_int_line.set_callback(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void device_start(void);
|
||||||
|
void device_reset(void);
|
||||||
|
void set_interrupt_line();
|
||||||
|
|
||||||
|
int read_id(int unit, int head, int *cylinder_id, int *sector_id);
|
||||||
|
int find_sector(int unit, int head, int sector, int *data_id);
|
||||||
|
int do_seek(int unit, int cylinder, int head);
|
||||||
|
int do_restore(int unit);
|
||||||
|
void do_read(void);
|
||||||
|
void do_write(void);
|
||||||
|
void do_cmd(void);
|
||||||
|
|
||||||
|
UINT16 m_recv_buf;
|
||||||
|
UINT16 m_stat_reg;
|
||||||
|
UINT16 m_xmit_buf;
|
||||||
|
UINT16 m_cmd_reg;
|
||||||
|
|
||||||
|
int m_interrupt_f_f;
|
||||||
|
devcb2_write_line m_int_line;
|
||||||
|
|
||||||
|
enum buf_mode_t {
|
||||||
|
bm_off, bm_read, bm_write
|
||||||
|
};
|
||||||
|
|
||||||
|
UINT8 m_buf[128];
|
||||||
|
int m_buf_pos;
|
||||||
|
buf_mode_t m_buf_mode;
|
||||||
|
int m_unit;
|
||||||
|
int m_head;
|
||||||
|
int m_sector;
|
||||||
|
/*int m_non_seq_mode;*/
|
||||||
|
int m_ddam;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
device_image_interface *img;
|
||||||
|
int phys_cylinder;
|
||||||
|
int log_cylinder[2];
|
||||||
|
int seclen;
|
||||||
|
} m_drv[MAX_FLOPPIES];
|
||||||
|
};
|
||||||
|
|
||||||
LEGACY_FLOPPY_OPTIONS_EXTERN(fd800);
|
LEGACY_FLOPPY_OPTIONS_EXTERN(fd800);
|
||||||
|
|
||||||
void fd800_machine_init(running_machine &machine, void (*interrupt_callback)(running_machine &machine, int state));
|
#define MCFG_FD800_ADD(_tag, _intcallb) \
|
||||||
|
MCFG_DEVICE_ADD(_tag, FD800, 0) \
|
||||||
|
devcb = &fd800_legacy_device::static_set_int_callback( *device, DEVCB2_##_intcallb );
|
||||||
|
|
||||||
extern DECLARE_READ8_HANDLER(fd800_cru_r);
|
#endif
|
||||||
extern DECLARE_WRITE8_HANDLER(fd800_cru_w);
|
|
||||||
|
@ -353,7 +353,7 @@ mu100 // 1997 MU-100
|
|||||||
mt32
|
mt32
|
||||||
cm32l
|
cm32l
|
||||||
d110
|
d110
|
||||||
sc55 // 1991 Sound Canvas SC-55
|
sc55 // 1991 Sound Canvas SC-55
|
||||||
|
|
||||||
//***************COMPUTERS**************************************************
|
//***************COMPUTERS**************************************************
|
||||||
|
|
||||||
@ -995,6 +995,7 @@ ip244415 // IP24: Indigo 2, R4400, 150MHz
|
|||||||
// Texas Instruments
|
// Texas Instruments
|
||||||
ti990_10 // 1975 TI 990/10
|
ti990_10 // 1975 TI 990/10
|
||||||
ti990_4 // 1976 TI 990/4
|
ti990_4 // 1976 TI 990/4
|
||||||
|
ti990_4v // 1976 TI 990/4 with video display terminal
|
||||||
990189 // 1978 TM 990/189
|
990189 // 1978 TM 990/189
|
||||||
990189v // 1980 TM 990/189 with Color Video Board
|
990189v // 1980 TM 990/189 with Color Video Board
|
||||||
|
|
||||||
@ -1939,7 +1940,7 @@ batmantv // The Batman, 2004
|
|||||||
harriet // 1990
|
harriet // 1990
|
||||||
|
|
||||||
// Fanuc
|
// Fanuc
|
||||||
fanucs15 // 1990
|
fanucs15 // 1990
|
||||||
|
|
||||||
//********** Misc **********************************************************
|
//********** Misc **********************************************************
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user