Modernized the micropolis device. Testing needed. (nw)

This commit is contained in:
Ivan Vangelista 2013-09-10 18:43:31 +00:00
parent 6ed90fc42a
commit 217d078f9b
3 changed files with 219 additions and 228 deletions

View File

@ -172,7 +172,7 @@ static ADDRESS_MAP_START( sorcererd_mem, AS_PROGRAM, 8, sorcerer_state)
AM_RANGE(0x0000, 0x07ff) AM_RAMBANK("boot") AM_RANGE(0x0000, 0x07ff) AM_RAMBANK("boot")
AM_RANGE(0x0800, 0xbbff) AM_RAM AM_RANGE(0x0800, 0xbbff) AM_RAM
AM_RANGE(0xbc00, 0xbcff) AM_ROM AM_RANGE(0xbc00, 0xbcff) AM_ROM
AM_RANGE(0xbe00, 0xbe03) AM_DEVREADWRITE_LEGACY("fdc", micropolis_r, micropolis_w) AM_RANGE(0xbe00, 0xbe03) AM_DEVREADWRITE("fdc", micropolis_device, read, write)
AM_RANGE(0xc000, 0xefff) AM_ROM /* rom pac and bios */ AM_RANGE(0xc000, 0xefff) AM_ROM /* rom pac and bios */
AM_RANGE(0xf000, 0xf7ff) AM_RAM AM_REGION("maincpu", 0xf000) /* screen ram */ AM_RANGE(0xf000, 0xf7ff) AM_RAM AM_REGION("maincpu", 0xf000) /* screen ram */
AM_RANGE(0xf800, 0xfbff) AM_ROM /* char rom */ AM_RANGE(0xf800, 0xfbff) AM_ROM /* char rom */

View File

@ -30,7 +30,6 @@ BE02 and BE03 - read data, write data
#include "emu.h" #include "emu.h"
#include "imagedev/flopdrv.h" #include "imagedev/flopdrv.h"
#include "machine/micropolis.h" #include "machine/micropolis.h"
#include "devlegcy.h"
/*************************************************************************** /***************************************************************************
@ -47,6 +46,7 @@ BE02 and BE03 - read data, write data
/* structure describing a single density track */ /* structure describing a single density track */
#define TRKSIZE_SD 16*270 #define TRKSIZE_SD 16*270
#if 0 #if 0
static const UINT8 track_SD[][2] = { static const UINT8 track_SD[][2] = {
{ 1, 0xff}, /* 1 * FF (marker) */ { 1, 0xff}, /* 1 * FF (marker) */
@ -58,37 +58,6 @@ static const UINT8 track_SD[][2] = {
}; };
#endif #endif
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
struct micropolis_state
{
/* register */
UINT8 data;
UINT8 drive_num;
UINT8 track;
UINT8 sector;
UINT8 command;
UINT8 status;
UINT8 write_cmd; /* last write command issued */
UINT8 buffer[6144]; /* I/O buffer (holds up to a whole track) */
UINT32 data_offset; /* offset into I/O buffer */
INT32 data_count; /* transfer count from/into I/O buffer */
UINT32 sector_length; /* sector length (byte) */
/* this is the drive currently selected */
device_t *drive;
/* Pointer to interface */
const micropolis_interface *intf;
};
/*************************************************************************** /***************************************************************************
DEFAULT INTERFACES DEFAULT INTERFACES
***************************************************************************/ ***************************************************************************/
@ -104,16 +73,113 @@ const micropolis_interface default_micropolis_interface_2_drives =
}; };
/***************************************************************************** /***************************************************************************
INLINE FUNCTIONS MAME DEVICE INTERFACE
*****************************************************************************/ ***************************************************************************/
INLINE micropolis_state *get_safe_token(device_t *device) const device_type MICROPOLIS = &device_creator<micropolis_device>;
micropolis_device::micropolis_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, MICROPOLIS, "MICROPOLIS", tag, owner, clock, "micropolis", __FILE__),
m_data(0),
m_drive_num(0),
m_track(0),
m_sector(0),
m_command(0),
m_status(0),
m_write_cmd(0),
m_data_offset(0),
m_data_count(0),
m_sector_length(0),
m_drive(NULL)
{ {
assert(device != NULL); for (int i = 0; i < 6144; i++)
assert(device->type() == MICROPOLIS); {
m_buffer[i] = 0;
}
}
return (micropolis_state *)downcast<micropolis_device *>(device)->token(); //-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void micropolis_device::device_config_complete()
{
// inherit a copy of the static data
const micropolis_interface *intf = reinterpret_cast<const micropolis_interface *>(static_config());
if (intf != NULL)
*static_cast<micropolis_interface *>(this) = *intf;
// or initialize to defaults if none provided
else
{
memset(&m_in_dden_cb, 0, sizeof(m_in_dden_cb));
memset(&m_out_intrq_cb, 0, sizeof(m_out_intrq_cb));
memset(&m_out_drq_cb, 0, sizeof(m_out_drq_cb));
m_floppy_drive_tags[0] = "";
m_floppy_drive_tags[1] = "";
m_floppy_drive_tags[2] = "";
m_floppy_drive_tags[3] = "";
}
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void micropolis_device::device_start()
{
m_in_dden_func.resolve(m_in_dden_cb, *this);
m_out_intrq_func.resolve(m_out_intrq_cb, *this);
m_out_drq_func.resolve(m_out_drq_cb, *this);
save_item(NAME(m_data));
save_item(NAME(m_drive_num));
save_item(NAME(m_track));
save_item(NAME(m_sector));
save_item(NAME(m_command));
save_item(NAME(m_status));
save_item(NAME(m_write_cmd));
save_item(NAME(m_buffer));
save_item(NAME(m_data_offset));
save_item(NAME(m_data_count));
save_item(NAME(m_sector_length));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void micropolis_device::device_reset()
{
int i;
for (i = 0; i < 4; i++)
{
if(m_floppy_drive_tags[i])
{
device_t *img = NULL;
img = siblingdevice(m_floppy_drive_tags[i]);
if (img)
{
floppy_drive_set_controller(img, this);
//floppy_drive_set_index_pulse_callback(img, wd17xx_index_pulse_callback);
floppy_drive_set_rpm( img, 300.);
}
}
}
set_drive(0);
m_drive_num = 0;
m_sector = 0;
m_track = 0;
m_sector_length = 270;
m_status = STAT_TRACK0;
} }
@ -123,31 +189,29 @@ INLINE micropolis_state *get_safe_token(device_t *device)
/* read a sector */ /* read a sector */
static void micropolis_read_sector(device_t *device) void micropolis_device::read_sector()
{ {
micropolis_state *w = get_safe_token(device); m_data_offset = 0;
w->data_offset = 0; m_data_count = m_sector_length;
w->data_count = w->sector_length;
/* read data */ /* read data */
floppy_drive_read_sector_data(w->drive, 0, w->sector, (char *)w->buffer, w->sector_length); floppy_drive_read_sector_data(m_drive, 0, m_sector, (char *)m_buffer, m_sector_length);
} }
static void micropolis_write_sector(device_t *device) void micropolis_device::write_sector()
{ {
#if 0 #if 0
micropolis_state *w = get_safe_token(device);
/* at this point, the disc is write enabled, and data /* at this point, the disc is write enabled, and data
* has been transfered into our buffer - now write it to * has been transfered into our buffer - now write it to
* the disc image or to the real disc * the disc image or to the real disc
*/ */
/* find sector */ /* find sector */
w->data_count = w->sector_length; m_data_count = m_sector_length;
/* write data */ /* write data */
floppy_drive_write_sector_data(w->drive, 0, w->sector, (char *)w->buffer, w->sector_length, w->write_cmd & 0x01); floppy_drive_write_sector_data(m_drive, 0, m_sector, (char *)m_buffer, m_sector_length, m_write_cmd & 0x01);
#endif #endif
} }
@ -159,15 +223,13 @@ static void micropolis_write_sector(device_t *device)
***************************************************************************/ ***************************************************************************/
/* select a drive */ /* select a drive */
void micropolis_set_drive(device_t *device, UINT8 drive) void micropolis_device::set_drive(UINT8 drive)
{ {
micropolis_state *w = get_safe_token(device);
if (VERBOSE) if (VERBOSE)
logerror("micropolis_set_drive: $%02x\n", drive); logerror("micropolis_set_drive: $%02x\n", drive);
if (w->intf->floppy_drive_tags[drive]) if (m_floppy_drive_tags[drive])
w->drive = device->siblingdevice(w->intf->floppy_drive_tags[drive]); m_drive = siblingdevice(m_floppy_drive_tags[drive]);
} }
@ -177,37 +239,34 @@ void micropolis_set_drive(device_t *device, UINT8 drive)
/* read the FDC status register. */ /* read the FDC status register. */
READ8_DEVICE_HANDLER( micropolis_status_r ) READ8_MEMBER( micropolis_device::status_r )
{ {
micropolis_state *w = get_safe_token(device);
static int inv = 0; static int inv = 0;
if (offset) if (offset)
return w->status | w->drive_num; return m_status | m_drive_num;
else else
{ {
// FIXME - find out what controls current sector // FIXME - find out what controls current sector
w->sector = (w->sector + 3 + inv) & 15; m_sector = (m_sector + 3 + inv) & 15;
micropolis_read_sector(device); read_sector();
inv ^= 1; inv ^= 1;
return (w->status & STAT_READY) | w->sector; return (m_status & STAT_READY) | m_sector;
} }
} }
/* read the FDC data register */ /* read the FDC data register */
READ8_DEVICE_HANDLER( micropolis_data_r ) READ8_MEMBER( micropolis_device::data_r )
{ {
micropolis_state *w = get_safe_token(device); if (m_data_offset >= m_sector_length)
m_data_offset = 0;
if (w->data_offset >= w->sector_length) return m_buffer[m_data_offset++];
w->data_offset = 0;
return w->buffer[w->data_offset++];
} }
/* write the FDC command register */ /* write the FDC command register */
WRITE8_DEVICE_HANDLER( micropolis_command_w ) WRITE8_MEMBER( micropolis_device::command_w )
{ {
/* List of commands: /* List of commands:
Command (bits 5,6,7) Options (bits 0,1,2,3,4) Command (bits 5,6,7) Options (bits 0,1,2,3,4)
@ -220,33 +279,32 @@ Command (bits 5,6,7) Options (bits 0,1,2,3,4)
6 Not used 6 Not used
7 Not used */ 7 Not used */
micropolis_state *w = get_safe_token(device);
int direction = 0; int direction = 0;
switch (data >> 5) switch (data >> 5)
{ {
case 1: case 1:
w->drive_num = data & 3; m_drive_num = data & 3;
floppy_mon_w(w->drive, 1); // turn off the old drive floppy_mon_w(m_drive, 1); // turn off the old drive
micropolis_set_drive(device, w->drive_num); // select new drive set_drive(m_drive_num); // select new drive
floppy_mon_w(w->drive, 0); // turn it on floppy_mon_w(m_drive, 0); // turn it on
break; break;
case 2: // not emulated, not used in sorcerer case 2: // not emulated, not used in sorcerer
break; break;
case 3: case 3:
if (BIT(data, 0)) if (BIT(data, 0))
{ {
if (w->track < 77) if (m_track < 77)
{ {
w->track++; m_track++;
direction = 1; direction = 1;
} }
} }
else else
{ {
if (w->track) if (m_track)
{ {
w->track--; m_track--;
direction = -1; direction = -1;
} }
} }
@ -258,39 +316,37 @@ Command (bits 5,6,7) Options (bits 0,1,2,3,4)
} }
w->status = STAT_RFC; m_status = STAT_RFC;
if (BIT(data, 5)) if (BIT(data, 5))
w->status |= STAT_READY; m_status |= STAT_READY;
floppy_drive_set_ready_state(w->drive, 1,0); floppy_drive_set_ready_state(m_drive, 1,0);
if (!w->track) if (!m_track)
w->status |= STAT_TRACK0; m_status |= STAT_TRACK0;
floppy_drive_seek(w->drive, direction); floppy_drive_seek(m_drive, direction);
} }
/* write the FDC data register */ /* write the FDC data register */
WRITE8_DEVICE_HANDLER( micropolis_data_w ) WRITE8_MEMBER( micropolis_device::data_w )
{ {
micropolis_state *w = get_safe_token(device); if (m_data_count > 0)
if (w->data_count > 0)
{ {
/* put byte into buffer */ /* put byte into buffer */
if (VERBOSE_DATA) if (VERBOSE_DATA)
logerror("micropolis_info buffered data: $%02X at offset %d.\n", data, w->data_offset); logerror("micropolis_info buffered data: $%02X at offset %d.\n", data, m_data_offset);
w->buffer[w->data_offset++] = data; m_buffer[m_data_offset++] = data;
if (--w->data_count < 1) if (--m_data_count < 1)
{ {
micropolis_write_sector(device); write_sector();
w->data_offset = 0; m_data_offset = 0;
} }
} }
else else
@ -298,117 +354,31 @@ WRITE8_DEVICE_HANDLER( micropolis_data_w )
if (VERBOSE) if (VERBOSE)
logerror("%s: micropolis_data_w $%02X\n", space.machine().describe_context(), data); logerror("%s: micropolis_data_w $%02X\n", space.machine().describe_context(), data);
} }
w->data = data; m_data = data;
} }
READ8_DEVICE_HANDLER( micropolis_r ) READ8_MEMBER( micropolis_device::read )
{ {
UINT8 data = 0; UINT8 data = 0;
switch (offset & 0x03) switch (offset & 0x03)
{ {
case 0: data = micropolis_status_r(device, space, 0); break; case 0: data = status_r(space, 0); break;
case 1: data = micropolis_status_r(device, space, 1); break; case 1: data = status_r(space, 1); break;
case 2: case 2:
case 3: data = micropolis_data_r(device, space, 0); break; case 3: data = data_r(space, 0); break;
} }
return data; return data;
} }
WRITE8_DEVICE_HANDLER( micropolis_w ) WRITE8_MEMBER( micropolis_device::write )
{ {
switch (offset & 0x03) switch (offset & 0x03)
{ {
case 0: case 0:
case 1: micropolis_command_w(device, space, 0, data); break; case 1: command_w(space, 0, data); break;
case 2: case 2:
case 3: micropolis_data_w(device, space, 0, data); break; case 3: data_w(space, 0, data); break;
} }
} }
/***************************************************************************
MAME DEVICE INTERFACE
***************************************************************************/
static DEVICE_START( micropolis )
{
micropolis_state *w = get_safe_token(device);
assert(device->static_config() != NULL);
w->intf = (const micropolis_interface*)device->static_config();
}
static DEVICE_RESET( micropolis )
{
micropolis_state *w = get_safe_token(device);
int i;
for (i = 0; i < 4; i++)
{
if(w->intf->floppy_drive_tags[i])
{
device_t *img = NULL;
img = device->siblingdevice(w->intf->floppy_drive_tags[i]);
if (img)
{
floppy_drive_set_controller(img,device);
//floppy_drive_set_index_pulse_callback(img, wd17xx_index_pulse_callback);
floppy_drive_set_rpm( img, 300.);
}
}
}
micropolis_set_drive(device, 0);
w->drive_num = 0;
w->sector = 0;
w->track = 0;
w->sector_length = 270;
w->status = STAT_TRACK0;
}
void micropolis_reset(device_t *device)
{
DEVICE_RESET_CALL( micropolis );
}
const device_type MICROPOLIS = &device_creator<micropolis_device>;
micropolis_device::micropolis_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, MICROPOLIS, "MICROPOLIS", tag, owner, clock, "micropolis", __FILE__)
{
m_token = global_alloc_clear(micropolis_state);
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void micropolis_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void micropolis_device::device_start()
{
DEVICE_START_NAME( micropolis )(this);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void micropolis_device::device_reset()
{
DEVICE_RESET_NAME( micropolis )(this);
}

View File

@ -13,33 +13,6 @@
#include "devcb.h" #include "devcb.h"
/***************************************************************************
MACROS
***************************************************************************/
class micropolis_device : public device_t
{
public:
micropolis_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~micropolis_device() { global_free(m_token); }
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
private:
// internal state
void *m_token;
};
extern const device_type MICROPOLIS;
/*************************************************************************** /***************************************************************************
TYPE DEFINITIONS TYPE DEFINITIONS
***************************************************************************/ ***************************************************************************/
@ -47,28 +20,76 @@ extern const device_type MICROPOLIS;
/* Interface */ /* Interface */
struct micropolis_interface struct micropolis_interface
{ {
devcb_read_line in_dden_func; devcb_read_line m_in_dden_cb;
devcb_write_line out_intrq_func; devcb_write_line m_out_intrq_cb;
devcb_write_line out_drq_func; devcb_write_line m_out_drq_cb;
const char *floppy_drive_tags[4]; const char *m_floppy_drive_tags[4];
}; };
/***************************************************************************
MACROS
***************************************************************************/
class micropolis_device : public device_t,
public micropolis_interface
{
public:
micropolis_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~micropolis_device() {}
void set_drive(UINT8 drive); // set current drive (0-3)
DECLARE_READ8_MEMBER( status_r );
DECLARE_READ8_MEMBER( data_r );
DECLARE_WRITE8_MEMBER( command_w );
DECLARE_WRITE8_MEMBER( data_w );
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
private:
// internal state
devcb_resolved_read_line m_in_dden_func;
devcb_resolved_write_line m_out_intrq_func;
devcb_resolved_write_line m_out_drq_func;
/* register */
UINT8 m_data;
UINT8 m_drive_num;
UINT8 m_track;
UINT8 m_sector;
UINT8 m_command;
UINT8 m_status;
UINT8 m_write_cmd; /* last write command issued */
UINT8 m_buffer[6144]; /* I/O buffer (holds up to a whole track) */
UINT32 m_data_offset; /* offset into I/O buffer */
INT32 m_data_count; /* transfer count from/into I/O buffer */
UINT32 m_sector_length; /* sector length (byte) */
/* this is the drive currently selected */
device_t *m_drive;
void read_sector();
void write_sector();
};
extern const device_type MICROPOLIS;
/*************************************************************************** /***************************************************************************
FUNCTION PROTOTYPES FUNCTION PROTOTYPES
***************************************************************************/ ***************************************************************************/
void micropolis_reset(device_t *device);
void micropolis_set_drive(device_t *device, UINT8); // set current drive (0-3)
DECLARE_READ8_DEVICE_HANDLER( micropolis_status_r );
DECLARE_READ8_DEVICE_HANDLER( micropolis_data_r );
DECLARE_WRITE8_DEVICE_HANDLER( micropolis_command_w );
DECLARE_WRITE8_DEVICE_HANDLER( micropolis_data_w );
DECLARE_READ8_DEVICE_HANDLER( micropolis_r );
DECLARE_WRITE8_DEVICE_HANDLER( micropolis_w );
extern const micropolis_interface default_micropolis_interface; extern const micropolis_interface default_micropolis_interface;