(MESS) corvushd: Converted to a device. (nw)

This commit is contained in:
Curt Coder 2014-03-20 20:24:48 +00:00
parent b4d9e6ee63
commit 759bf2287c
10 changed files with 621 additions and 619 deletions

View File

@ -43,11 +43,6 @@
#include "hardbox.h"
#include "cpu/z80/z80.h"
#include "machine/i8251.h"
#include "machine/i8255.h"
#include "imagedev/harddriv.h"
#include "includes/corvushd.h"
@ -58,6 +53,7 @@
#define Z80_TAG "z80"
#define I8255_0_TAG "ic17"
#define I8255_1_TAG "ic16"
#define CORVUS_HDC_TAG "corvus"
@ -126,7 +122,7 @@ static ADDRESS_MAP_START( hardbox_io, AS_IO, 8, hardbox_device )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x10, 0x13) AM_DEVREADWRITE(I8255_0_TAG, i8255_device, read, write)
AM_RANGE(0x14, 0x17) AM_DEVREADWRITE(I8255_1_TAG, i8255_device, read, write)
AM_RANGE(0x18, 0x18) AM_READWRITE_LEGACY(corvus_hdc_data_r, corvus_hdc_data_w)
AM_RANGE(0x18, 0x18) AM_DEVREADWRITE(CORVUS_HDC_TAG, corvus_hdc_t, read, write)
ADDRESS_MAP_END
@ -247,7 +243,7 @@ READ8_MEMBER( hardbox_device::ppi1_pc_r )
*/
UINT8 status = corvus_hdc_status_r(space, 0);
UINT8 status = m_hdc->status_r(space, 0);
UINT8 data = 0;
data |= (status & CONTROLLER_BUSY) ? 0 : 0x10;
@ -302,6 +298,8 @@ static MACHINE_CONFIG_FRAGMENT( hardbox )
// devices
MCFG_I8255A_ADD(I8255_0_TAG, ppi0_intf)
MCFG_I8255A_ADD(I8255_1_TAG, ppi1_intf)
MCFG_DEVICE_ADD(CORVUS_HDC_TAG, CORVUS_HDC, 0)
MCFG_HARDDISK_ADD("harddisk1")
MCFG_HARDDISK_ADD("harddisk2")
MCFG_HARDDISK_ADD("harddisk3")
@ -365,7 +363,8 @@ ioport_constructor hardbox_device::device_input_ports() const
hardbox_device::hardbox_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, HARDBOX, "HardBox", tag, owner, clock, "hardbox", __FILE__),
device_ieee488_interface(mconfig, *this),
m_maincpu(*this, Z80_TAG)
m_maincpu(*this, Z80_TAG),
m_hdc(*this, CORVUS_HDC_TAG)
{
}
@ -376,7 +375,6 @@ hardbox_device::hardbox_device(const machine_config &mconfig, const char *tag, d
void hardbox_device::device_start()
{
corvus_hdc_init(this);
}

View File

@ -15,6 +15,11 @@
#define __PET_HARDBOX__
#include "ieee488.h"
#include "cpu/z80/z80.h"
#include "machine/i8251.h"
#include "machine/i8255.h"
#include "imagedev/harddriv.h"
#include "includes/corvushd.h"
@ -62,6 +67,7 @@ private:
};
required_device<cpu_device> m_maincpu;
required_device<corvus_hdc_t> m_hdc;
int m_ifc; // Tracks previous state of IEEE-488 IFC line
};

View File

@ -18,12 +18,6 @@
#include "softbox.h"
#include "bus/rs232/rs232.h"
#include "cpu/z80/z80.h"
#include "imagedev/harddriv.h"
#include "includes/corvushd.h"
#include "machine/i8251.h"
#include "machine/i8255.h"
//**************************************************************************
@ -36,6 +30,7 @@
#define I8255_1_TAG "ic16"
#define COM8116_TAG "ic14"
#define RS232_TAG "rs232"
#define CORVUS_HDC_TAG "corvus"
@ -93,7 +88,7 @@ static ADDRESS_MAP_START( softbox_io, AS_IO, 8, softbox_device )
AM_RANGE(0x0c, 0x0c) AM_WRITE(dbrg_w)
AM_RANGE(0x10, 0x13) AM_DEVREADWRITE(I8255_0_TAG, i8255_device, read, write)
AM_RANGE(0x14, 0x17) AM_DEVREADWRITE(I8255_1_TAG, i8255_device, read, write)
AM_RANGE(0x18, 0x18) AM_READWRITE_LEGACY(corvus_hdc_data_r, corvus_hdc_data_w)
AM_RANGE(0x18, 0x18) AM_DEVREADWRITE(CORVUS_HDC_TAG, corvus_hdc_t, read, write)
ADDRESS_MAP_END
@ -202,7 +197,7 @@ READ8_MEMBER( softbox_device::ppi1_pc_r )
*/
UINT8 status = corvus_hdc_status_r(space, 0);
UINT8 status = m_hdc->status_r(space, 0);
UINT8 data = 0;
data |= (status & CONTROLLER_BUSY) ? 0 : 0x10;
@ -282,6 +277,7 @@ static MACHINE_CONFIG_FRAGMENT( softbox )
MCFG_COM8116_FR_HANDLER(DEVWRITELINE(I8251_TAG, i8251_device, write_rxc))
MCFG_COM8116_FT_HANDLER(DEVWRITELINE(I8251_TAG, i8251_device, write_txc))
MCFG_DEVICE_ADD(CORVUS_HDC_TAG, CORVUS_HDC, 0)
MCFG_HARDDISK_ADD("harddisk1")
MCFG_HARDDISK_ADD("harddisk2")
MCFG_HARDDISK_ADD("harddisk3")
@ -345,7 +341,8 @@ softbox_device::softbox_device(const machine_config &mconfig, const char *tag, d
: device_t(mconfig, SOFTBOX, "PET SoftBox", tag, owner, clock, "pet_softbox", __FILE__),
device_ieee488_interface(mconfig, *this),
m_maincpu(*this, Z80_TAG),
m_dbrg(*this, COM8116_TAG)
m_dbrg(*this, COM8116_TAG),
m_hdc(*this, CORVUS_HDC_TAG)
{
}
@ -356,7 +353,6 @@ softbox_device::softbox_device(const machine_config &mconfig, const char *tag, d
void softbox_device::device_start()
{
corvus_hdc_init(this);
}

View File

@ -15,7 +15,13 @@
#define __PET_SOFTBOX__
#include "ieee488.h"
#include "bus/rs232/rs232.h"
#include "cpu/z80/z80.h"
#include "imagedev/harddriv.h"
#include "includes/corvushd.h"
#include "machine/com8116.h"
#include "machine/i8251.h"
#include "machine/i8255.h"
@ -65,6 +71,7 @@ private:
required_device<cpu_device> m_maincpu;
required_device<com8116_device> m_dbrg;
required_device<corvus_hdc_t> m_hdc;
int m_ifc; // Tracks previous state of IEEE-488 IFC line
};

View File

@ -138,7 +138,7 @@ static ADDRESS_MAP_START( softbox_io, AS_IO, 8, softbox_state )
AM_RANGE(0x0c, 0x0c) AM_WRITE(dbrg_w)
AM_RANGE(0x10, 0x13) AM_DEVREADWRITE(I8255_0_TAG, i8255_device, read, write)
AM_RANGE(0x14, 0x17) AM_DEVREADWRITE(I8255_1_TAG, i8255_device, read, write)
AM_RANGE(0x18, 0x18) AM_READWRITE_LEGACY(corvus_hdc_data_r, corvus_hdc_data_w)
AM_RANGE(0x18, 0x18) AM_DEVREADWRITE(CORVUS_HDC_TAG, corvus_hdc_t, read, write)
ADDRESS_MAP_END
@ -276,7 +276,7 @@ READ8_MEMBER( softbox_state::ppi1_pc_r )
*/
UINT8 status = corvus_hdc_status_r(space, 0);
UINT8 status = m_hdc->status_r(space, 0);
UINT8 data = 0;
data |= (status & CONTROLLER_BUSY) ? 0 : 0x10;
@ -339,7 +339,6 @@ DEVICE_INPUT_DEFAULTS_END
void softbox_state::machine_start()
{
corvus_hdc_init(machine());
}
@ -414,6 +413,8 @@ static MACHINE_CONFIG_START( softbox, softbox_state )
MCFG_COM8116_FT_HANDLER(DEVWRITELINE(I8251_TAG, i8251_device, write_txc))
MCFG_CBM_IEEE488_ADD("c8050")
MCFG_DEVICE_ADD(CORVUS_HDC_TAG, CORVUS_HDC, 0)
MCFG_HARDDISK_ADD("harddisk1")
MCFG_HARDDISK_ADD("harddisk2")
MCFG_HARDDISK_ADD("harddisk3")

View File

@ -13,6 +13,9 @@
#ifndef CORVUSHD_H_
#define CORVUSHD_H_
#include "emu.h"
#include "imagedev/harddriv.h"
#include <ctype.h>
//
// Controller Commands
@ -171,17 +174,330 @@
#define CONTROLLER_BUSY 0x80 // Set = Busy, Clear = Ready
#define CONTROLLER_DIRECTION 0x40 // Set = Controller->Host, Clear = Host->Controller
#define MAX_COMMAND_SIZE 4096 // The maximum size of a command packet (the controller only has 5K of RAM...)
/*----------- defined in machine/corvushd.c -----------*/
class corvus_hdc_t : public device_t
{
public:
// construction/destruction
corvus_hdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
//
// Prototypes
//
UINT8 corvus_hdc_init( running_machine &machine );
UINT8 corvus_hdc_init( device_t *device );
DECLARE_READ8_HANDLER ( corvus_hdc_status_r );
DECLARE_READ8_HANDLER ( corvus_hdc_data_r );
DECLARE_WRITE8_HANDLER ( corvus_hdc_data_w );
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
DECLARE_READ8_MEMBER( status_r );
protected:
// device-level overrides
virtual void device_start();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
private:
enum
{
TIMER_TIMEOUT,
TIMER_COMMAND
};
// Sector addressing scheme for Rev B/H drives used in various commands (Called a DADR in the docs)
struct dadr_t {
UINT8 address_msn_and_drive;// Most significant nibble: Most signficant nibble of sector address, Least significant nibble: Drive #
UINT8 address_lsb; // Least significant byte of sector address
UINT8 address_mid; // Middle byte of sector address
};
UINT8 m_status; // Controller status byte (DIRECTION + BUSY/READY)
bool m_prep_mode; // Whether the controller is in Prep Mode or not
// Physical drive info
UINT8 m_sectors_per_track; // Number of sectors per track for this drive
UINT8 m_tracks_per_cylinder;// Number of tracks per cylinder (heads)
UINT16 m_cylinders_per_drive;// Number of cylinders per drive
// Command Processing
UINT16 m_offset; // Current offset into raw_data buffer
bool m_awaiting_modifier; // We've received a two-byte command and we're waiting for the mod
UINT16 m_recv_bytes; // Number of bytes expected to be received from Host
UINT16 m_xmit_bytes; // Number of bytes expected to be transmitted to host
// Timing-related values
UINT16 m_last_cylinder; // Last cylinder accessed - for calculating seek times
UINT32 m_delay; // Delay in microseconds for callback
emu_timer *m_timeout_timer; // Four-second timer for timeouts
emu_timer *m_cmd_timer;
bool m_invalid_command_flag; // I hate this, but it saves a lot more tests
//
// Union below represents both an input and output buffer and interpretations of it
//
union {
//
// Raw Buffer
//
UINT8 raw_data[MAX_COMMAND_SIZE];
//
// Basic interpretation of code and modifier
//
struct {
UINT8 code; // First byte of data is the code (command)
UINT8 modifier; // Second byte of data is the modifier
} command;
//
// Basic response code
//
struct {
UINT8 status; // Status code returned by the command executed
} single_byte_response;
//
// Read sector command
//
struct {
UINT8 code; // Command code
dadr_t dadr; // Encoded drive and sector to read
} read_sector_command;
//
// 128-byte Read Sector response
//
struct {
UINT8 status; // Status code returned by command executed
UINT8 data[128]; // Data returned from read
} read_128_response;
//
// 256-byte Read Sector response
//
struct {
UINT8 status; // Status code returned by command executed
UINT8 data[256]; // Data returned from read
} read_256_reponse;
//
// 512-byte Read Sector response
//
struct {
UINT8 status; // Status code returned by command executed
UINT8 data[512]; // Data returned by read
} read_512_response;
//
// Write 128-byte sector command
//
struct {
UINT8 code; // Command code
dadr_t dadr; // Encoded drive and sector to write
UINT8 data[128]; // Data to be written
} write_128_command;
//
// Write 256-byte sector command
//
struct {
UINT8 code; // Command code
dadr_t dadr; // Encoded drive and sector to write
UINT8 data[256]; // Data to be written
} write_256_command;
//
// Write 512-byte sector command
//
struct {
UINT8 code; // Command Code
dadr_t dadr; // Encoded drive and sector to write
UINT8 data[512]; // Data to be written
} write_512_command;
//
// Semaphore Lock command
//
struct {
UINT8 code; // Command code
UINT8 modifier; // Command code modifier
UINT8 name[8]; // Semaphore name
} lock_semaphore_command;
//
// Semaphore Unlock command
//
struct {
UINT8 code; // Command code
UINT8 modifier; // Command code modifier
UINT8 name[8]; // Semaphore name
} unlock_semaphore_command;
//
// Semaphore Lock/Unlock response
//
struct {
UINT8 status; // Disk access status
UINT8 result; // Semaphore action status
UINT8 unused[10]; // Unused
} semaphore_locking_response;
//
// Initialize Semaphore table command
//
struct {
UINT8 code; // Command code
UINT8 modifier; // Command code modifier
UINT8 unused[3]; // Unused
} init_semaphore_command;
//
// Semaphore Status command
//
struct {
UINT8 code; // Command code
UINT8 modifier; // Command code modifier
UINT8 zero_three; // Don't ask me...
UINT8 unused[2]; // Unused
} semaphore_status_command;
//
// Semaphore Status response
//
struct {
UINT8 status; // Disk access status
UINT8 table[256]; // Contents of the semaphore table
} semaphore_status_response;
//
// Get Drive Parameters command (0x10)
//
struct {
UINT8 code; // Command code
UINT8 drive; // Drive number (starts at 1)
} get_drive_parameters_command;
//
// Get Drive Parameters command response
//
struct {
UINT8 status; // Status code returned by command executed
UINT8 firmware[33]; // Firmware message
UINT8 rom_version; // ROM Version
struct {
UINT8 sectors_per_track; // Sectors/Track
UINT8 tracks_per_cylinder; // Tracks/Cylinder (heads)
struct {
UINT8 lsb;
UINT8 msb;
} cylinders_per_drive; // Byte-flipped Cylinders/Drive
} track_info;
struct {
UINT8 lsb; // Least significant byte
UINT8 midb; // Middle byte
UINT8 msb; // Most significant byte
} capacity; // 24-bit value, byte-flipped (lsb..msb)
UINT8 unused[16];
UINT8 interleave; // Interleave factor
struct {
UINT8 mux_parameters[12];
UINT8 pipe_name_table_ptr[2]; // Pointer to table of 64 entries, 8 bytes each (table of names)
UINT8 pipe_ptr_table_ptr[2]; // Pointer to table of 64 entries, 8 bytes each. See pp. 29 - Mass Storage GTI
UINT8 pipe_area_size[2]; // Size of pipe area (lsb, msb)
struct {
UINT8 track_offset[2];
} vdo_table[7]; // Virtual drive table
UINT8 lsi11_vdo_table[8];
UINT8 lsi11_spare_table[8];
} table_info;
UINT8 drive_number; // Physical drive number
struct {
UINT8 lsb; // Least
UINT8 midb; // Middle
UINT8 msb; // Most
} physical_capacity; // Physical capacity of drive
} drive_param_response;
//
// 2-byte Boot command (0x14)
//
struct {
UINT8 code; // Command code
UINT8 boot_block; // Which boot block to read (0-7)
} old_boot_command;
//
// Read Firmware command (Prep Mode 0x32)
//
struct {
UINT8 code; // Command Code
UINT8 encoded_h_s;// Encoded Head (bits 7-5) / Sector (bits 4-0)
} read_firmware_command;
//
// Write Firmware command (Prep Mode 0x33)
//
struct {
UINT8 code; // Command Code
UINT8 encoded_h_s; // Encoded Head (bits 7-5) / Sector (bits 4-0)
UINT8 data[512]; // Data to be written
} write_firmware_command;
//
// Format Drive command (Prep Mode 0x01)
//
// Note that the following is a BLATANT ASSUMPTION. Technically, the Format Drive command
// uses a variable-length buffer for the pattern. Unfortunately, the docs don't explain how to determine the
// length of the buffer passed. I assume it's a timeout; however, the docs happen to say that
// all Corvus diagnostic programs send 513 bytes total, including the command, so I'm going with that.
//
struct {
UINT8 code; // Command Code
UINT8 pattern[512]; // Pattern to be written
} format_drive_revbh_command;
} m_buffer;
// Structure of Block #1, the Disk Parameter Block
struct disk_parameter_block_t {
struct {
UINT8 lsb;
UINT8 msb;
} spared_track[8]; // Spared track table (0xffff indicates end)
UINT8 interleave; // Interleave factor
UINT8 reserved;
struct {
UINT8 track_offset[2]; // Virtual drive offsets (lsb, msb) 0xffff indicates unused
} vdo_table[7];
UINT8 lsi11_vdo_table[8];
UINT8 lsi11_spare_table[8];
UINT8 reserved2[432];
struct {
UINT8 lsb;
UINT8 msb;
} revh_spare_table[16];
};
// Structure of Block #3, the Constellation Parameter Block
struct constellation_parameter_block_t {
UINT8 mux_parameters[12];
UINT8 pipe_name_table_ptr[2];
UINT8 pipe_ptr_table_ptr[2];
UINT8 pipe_area_size[2];
UINT8 reserved[470];
UINT8 software_protection[12];
UINT8 serial_number[12];
};
// Structure of Block #7, the Semaphore Table Block
struct semaphore_table_block_t {
union {
UINT8 semaphore_table[256]; // Table consists of 256 bytes
struct {
UINT8 semaphore_name[8]; // Each semaphore name is 8 bytes
} semaphore_entry[32]; // 32 Entries
} semaphore_block;
UINT8 unused[256]; // Remaining half of block is unused
};
// Command size structure (number of bytes to xmit and recv for each command)
struct corvus_cmd_t {
UINT16 recv_bytes; // Number of bytes from host for this command
UINT16 xmit_bytes; // Number of bytes to return to host
};
void dump_buffer(UINT8 *buffer, UINT16 length);
bool parse_hdc_command(UINT8 data);
UINT8 corvus_write_sector(UINT8 drv, UINT32 sector, UINT8 *buffer, int len);
UINT8 corvus_write_logical_sector(dadr_t *dadr, UINT8 *buffer, int len);
UINT8 corvus_read_sector(UINT8 drv, UINT32 sector, UINT8 *buffer, int len);
UINT8 corvus_read_logical_sector(dadr_t *dadr, UINT8 *buffer, int len);
UINT8 corvus_lock_semaphore(UINT8 *name);
UINT8 corvus_unlock_semaphore(UINT8 *name);
UINT8 corvus_init_semaphore_table();
UINT8 corvus_get_drive_parameters(UINT8 drv);
UINT8 corvus_read_boot_block(UINT8 block);
UINT8 corvus_read_firmware_block(UINT8 head, UINT8 sector);
UINT8 corvus_write_firmware_block(UINT8 head, UINT8 sector, UINT8 *buffer);
UINT8 corvus_format_drive(UINT8 *pattern, UINT16 len);
hard_disk_file *corvus_hdc_file(int id);
void corvus_process_command_packet(bool local_invalid_command_flag);
corvus_cmd_t corvus_cmd[0xf5][0xc1]; // Command sizes and their return sizes
corvus_cmd_t corvus_prep_cmd[0x82]; // Prep Command sizes and their return sizes
};
// device type definition
extern const device_type CORVUS_HDC;
#endif /* CORVUSHD_H_ */

View File

@ -21,6 +21,7 @@
#define I8255_1_TAG "ic16"
#define COM8116_TAG "ic14"
#define RS232_TAG "rs232"
#define CORVUS_HDC_TAG "corvus"
class softbox_state : public driver_device
{
@ -29,12 +30,14 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, Z80_TAG),
m_dbrg(*this, COM8116_TAG),
m_ieee(*this, IEEE488_TAG)
m_ieee(*this, IEEE488_TAG),
m_hdc(*this, CORVUS_HDC_TAG)
{ }
required_device<cpu_device> m_maincpu;
required_device<com8116_device> m_dbrg;
required_device<ieee488_device> m_ieee;
required_device<corvus_hdc_t> m_hdc;
virtual void machine_start();
virtual void device_reset_after_children();

View File

@ -18,7 +18,6 @@
#include "formats/basicdsk.h"
// HDC controller
#include "includes/corvushd.h"
#include "imagedev/harddriv.h"
//**************************************************************************
@ -123,7 +122,8 @@ concept_fdc_device::concept_fdc_device(const machine_config &mconfig, const char
concept_hdc_device::concept_hdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, CONCEPT_HDC, "Corvus Concept HDC controller", tag, owner, clock, "concept_hdc", __FILE__),
concept_exp_card_device( mconfig, *this )
concept_exp_card_device( mconfig, *this ),
m_hdc(*this, "hdc")
{
}
@ -343,7 +343,6 @@ machine_config_constructor concept_fdc_device::device_mconfig_additions() const
void concept_hdc_device::device_start()
{
corvus_hdc_init(machine());
}
@ -358,10 +357,10 @@ READ8_MEMBER(concept_hdc_device::reg_r)
switch (offset)
{
case 0: // HDC Data Register
return corvus_hdc_data_r(space, offset);
return m_hdc->read(space, offset);
case 1: // HDC Status Register
return corvus_hdc_status_r(space, offset);
return m_hdc->status_r(space, offset);
}
return 0;
@ -373,7 +372,7 @@ WRITE8_MEMBER(concept_hdc_device::reg_w)
switch (offset)
{
case 0: // HDC Data Register
corvus_hdc_data_w(space, offset, data);
m_hdc->write(space, offset, data);
break;
}
}
@ -388,6 +387,7 @@ READ8_MEMBER(concept_hdc_device::rom_r)
static MACHINE_CONFIG_FRAGMENT( hdc )
MCFG_DEVICE_ADD("hdc", CORVUS_HDC, 0)
MCFG_HARDDISK_ADD( "harddisk1" )
MACHINE_CONFIG_END

View File

@ -3,6 +3,7 @@
#include "emu.h"
#include "machine/wd17xx.h"
#include "includes/corvushd.h"
// FIXME: Concept expansion ports should just use the Apple II Bus device!
// The code below is outdated and inaccurate!
@ -110,6 +111,7 @@ public:
virtual machine_config_constructor device_mconfig_additions() const;
protected:
required_device<corvus_hdc_t> m_hdc;
};

File diff suppressed because it is too large Load Diff