Modernized i8271 device.(nw)

This commit is contained in:
Ivan Vangelista 2014-01-18 08:00:32 +00:00
parent 033409474e
commit 31ea9e4a39
7 changed files with 629 additions and 594 deletions

View File

@ -244,14 +244,14 @@ WRITE8_MEMBER( atom_state::eprom_w )
static ADDRESS_MAP_START( atom_mem, AS_PROGRAM, 8, atom_state )
AM_RANGE(0x0000, 0x09ff) AM_RAM
AM_RANGE(0x0a00, 0x0a03) AM_MIRROR(0x1f8) AM_DEVREADWRITE_LEGACY(I8271_TAG, i8271_r, i8271_w)
AM_RANGE(0x0a04, 0x0a04) AM_MIRROR(0x1f8) AM_DEVREADWRITE_LEGACY(I8271_TAG, i8271_data_r, i8271_data_w)
AM_RANGE(0x0a00, 0x0a03) AM_MIRROR(0x1f8) AM_DEVREADWRITE(I8271_TAG, i8271_device, read, write)
AM_RANGE(0x0a04, 0x0a04) AM_MIRROR(0x1f8) AM_DEVREADWRITE(I8271_TAG, i8271_device, data_r, data_w)
AM_RANGE(0x0a05, 0x7fff) AM_RAM
AM_RANGE(0x8000, 0x97ff) AM_RAM AM_SHARE("video_ram")
AM_RANGE(0x9800, 0x9fff) AM_RAM
AM_RANGE(0xa000, 0xafff) AM_ROM AM_REGION(EXTROM_TAG, 0)
AM_RANGE(0xb000, 0xb003) AM_MIRROR(0x3fc) AM_DEVREADWRITE(INS8255_TAG, i8255_device, read, write)
// AM_RANGE(0xb400, 0xb403) AM_DEVREADWRITE_LEGACY(MC6854_TAG, mc6854_r, mc6854_w)
// AM_RANGE(0xb400, 0xb403) AM_DEVREADWRITE(MC6854_TAG, mc6854_device, read, write)
// AM_RANGE(0xb404, 0xb404) AM_READ_PORT("ECONET")
AM_RANGE(0xb800, 0xb80f) AM_MIRROR(0x3f0) AM_DEVREADWRITE(R6522_TAG, via6522_device, read, write)
AM_RANGE(0xc000, 0xffff) AM_ROM AM_REGION(SY6502_TAG, 0)
@ -577,31 +577,30 @@ WRITE8_MEMBER( atom_state::printer_data )
i8271_interface fdc_intf
-------------------------------------------------*/
static void atom_8271_interrupt_callback(device_t *device, int state)
WRITE_LINE_MEMBER( atom_state::atom_8271_interrupt_callback )
{
atom_state *drvstate = device->machine().driver_data<atom_state>();
/* I'm assuming that the nmi is edge triggered */
/* a interrupt from the fdc will cause a change in line state, and
the nmi will be triggered, but when the state changes because the int
is cleared this will not cause another nmi */
/* I'll emulate it like this to be sure */
if (state!=drvstate->m_previous_i8271_int_state)
if (state!=m_previous_i8271_int_state)
{
if (state)
{
/* I'll pulse it because if I used hold-line I'm not sure
it would clear - to be checked */
drvstate->m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
}
}
drvstate->m_previous_i8271_int_state = state;
m_previous_i8271_int_state = state;
}
static const i8271_interface fdc_intf =
{
atom_8271_interrupt_callback,
DEVCB_DRIVER_LINE_MEMBER(atom_state, atom_8271_interrupt_callback),
NULL,
{ FLOPPY_0, FLOPPY_1 }
};

View File

@ -45,8 +45,8 @@ void esqmr_state::machine_reset()
static ADDRESS_MAP_START( mr_map, AS_PROGRAM, 32, esqmr_state )
AM_RANGE(0x00000000, 0x000fffff) AM_ROM AM_REGION("maincpu", 0)
// AM_RANGE(0x200000, 0x20003f) AM_DEVREADWRITE8_LEGACY("ensoniq", es5506_r, es5506_w, 0xffffffff)
// AM_RANGE(0x240000, 0x24003f) AM_DEVREADWRITE8_LEGACY("ensoniq2", es5506_r, es5506_w, 0xffffffff)
// AM_RANGE(0x200000, 0x20003f) AM_DEVREADWRITE8("ensoniq", es5506_device, read, write, 0xffffffff)
// AM_RANGE(0x240000, 0x24003f) AM_DEVREADWRITE8("ensoniq2", es5506_device, read, write, 0xffffffff)
// AM_RANGE(0xff0000, 0xffffff) AM_RAM AM_SHARE("osram")
ADDRESS_MAP_END

View File

@ -97,6 +97,7 @@ public:
DECLARE_WRITE8_MEMBER( printer_data );
DECLARE_READ8_MEMBER( vdg_videoram_r );
DECLARE_INPUT_CHANGED_MEMBER( trigger_reset );
DECLARE_WRITE_LINE_MEMBER( atom_8271_interrupt_callback );
/* eprom state */
int m_eprom;

View File

@ -45,6 +45,7 @@ public:
m_via6522_0(*this, "via6522_0"),
m_via6522_1(*this, "via6522_1"),
m_upd7002(*this, "upd7002"),
m_i8271(*this, "i8271"),
m_ACCCON_IRR(CLEAR_LINE),
m_via_system_irq(CLEAR_LINE),
m_via_user_irq(CLEAR_LINE),
@ -74,6 +75,7 @@ public:
required_device<via6522_device> m_via6522_0;
optional_device<via6522_device> m_via6522_1;
optional_device<upd7002_device> m_upd7002;
optional_device<i8271_device> m_i8271;
void check_interrupts();
@ -355,6 +357,8 @@ public:
DECLARE_WRITE_LINE_MEMBER(write_dcd_serial);
DECLARE_WRITE_LINE_MEMBER(write_cts_serial);
DECLARE_INPUT_CHANGED_MEMBER( trigger_reset );
DECLARE_WRITE_LINE_MEMBER(bbc_i8271_interrupt);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( bbcb_cart );
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( bbcm_cart );

View File

@ -18,7 +18,6 @@
#include "machine/wd17xx.h"
#include "imagedev/flopdrv.h"
#include "includes/bbc.h"
#include "machine/i8271.h"
#include "machine/mc146818.h"
#include "bus/centronics/ctronics.h"
#include "imagedev/cassette.h"
@ -1457,32 +1456,31 @@ WRITE8_MEMBER(bbc_state::bbc_SerialULA_w)
***************************************/
static void bbc_i8271_interrupt(device_t *device, int state)
WRITE_LINE_MEMBER(bbc_state::bbc_i8271_interrupt)
{
bbc_state *drvstate = device->machine().driver_data<bbc_state>();
/* I'm assuming that the nmi is edge triggered */
/* a interrupt from the fdc will cause a change in line state, and
the nmi will be triggered, but when the state changes because the int
is cleared this will not cause another nmi */
/* I'll emulate it like this to be sure */
if (state!=drvstate->m_previous_i8271_int_state)
if (state!=m_previous_i8271_int_state)
{
if (state)
{
/* I'll pulse it because if I used hold-line I'm not sure
it would clear - to be checked */
drvstate->m_maincpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE);
m_maincpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE);
}
}
drvstate->m_previous_i8271_int_state = state;
m_previous_i8271_int_state = state;
}
const i8271_interface bbc_i8271_interface=
{
bbc_i8271_interrupt,
DEVCB_DRIVER_LINE_MEMBER(bbc_state, bbc_i8271_interrupt),
NULL,
{FLOPPY_0, FLOPPY_1}
};
@ -1491,7 +1489,6 @@ const i8271_interface bbc_i8271_interface=
READ8_MEMBER(bbc_state::bbc_i8271_read)
{
int ret;
device_t *i8271 = machine().device("i8271");
logerror("i8271 read %d ",offset);
switch (offset)
{
@ -1500,11 +1497,11 @@ READ8_MEMBER(bbc_state::bbc_i8271_read)
case 2:
case 3:
/* 8271 registers */
ret=i8271_r(i8271, space, offset);
ret=m_i8271->read(space, offset);
logerror(" %d\n",ret);
break;
case 4:
ret=i8271_data_r(i8271, space, offset);
ret=m_i8271->data_r(space, offset);
logerror(" %d\n",ret);
break;
default:
@ -1517,7 +1514,6 @@ READ8_MEMBER(bbc_state::bbc_i8271_read)
WRITE8_MEMBER(bbc_state::bbc_i8271_write)
{
device_t *i8271 = machine().device("i8271");
logerror("i8271 write %d %d\n",offset,data);
switch (offset)
@ -1527,10 +1523,10 @@ WRITE8_MEMBER(bbc_state::bbc_i8271_write)
case 2:
case 3:
/* 8271 registers */
i8271_w(i8271, space, offset, data);
m_i8271->write(space, offset, data);
return;
case 4:
i8271_data_w(i8271, space, offset, data);
m_i8271->data_w(space, offset, data);
return;
default:
break;

File diff suppressed because it is too large Load Diff

View File

@ -7,55 +7,152 @@
#ifndef I8271_H_
#define I8271_H_
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
typedef void (*i8271_dma_request)(device_t &device, int state, int read_);
#define I8271_DMA_REQUEST(name) void name(device_t &device, int state, int read_)
struct i8271_interface
{
devcb_write_line m_interrupt_cb;
i8271_dma_request m_dma_request;
const char *m_floppy_drive_tags[2];
};
/***************************************************************************
MACROS
***************************************************************************/
class i8271_device : public device_t
class i8271_device : public device_t,
public i8271_interface
{
public:
i8271_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~i8271_device() { global_free(m_token); }
~i8271_device() {}
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
DECLARE_READ8_MEMBER(dack_r);
DECLARE_WRITE8_MEMBER(dack_w);
DECLARE_READ8_MEMBER(data_r);
DECLARE_WRITE8_MEMBER(data_w);
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
private:
// internal state
void *m_token;
enum
{
TIMER_DATA_CALLBACK,
TIMER_TIMED_COMMAND_COMPLETE
};
int m_flags;
int m_state;
unsigned char m_Command;
unsigned char m_StatusRegister;
unsigned char m_CommandRegister;
unsigned char m_ResultRegister;
unsigned char m_ParameterRegister;
unsigned char m_ResetRegister;
unsigned char m_data;
/* number of parameters required after command is specified */
unsigned long m_ParameterCount;
/* number of parameters written so far */
unsigned long m_ParameterCountWritten;
unsigned char m_CommandParameters[8];
/* current track for each drive */
unsigned long m_CurrentTrack[2];
/* 2 bad tracks for drive 0, followed by 2 bad tracks for drive 1 */
unsigned long m_BadTracks[4];
/* mode special register */
unsigned long m_Mode;
/* drive outputs */
int m_drive;
int m_side;
/* drive control output special register */
int m_drive_control_output;
/* drive control input special register */
int m_drive_control_input;
unsigned long m_StepRate;
unsigned long m_HeadSettlingTime;
unsigned long m_IndexCountBeforeHeadUnload;
unsigned long m_HeadLoadTime;
/* id on disc to find */
int m_ID_C;
int m_ID_H;
int m_ID_R;
int m_ID_N;
/* id of data for read/write */
int m_data_id;
int m_ExecutionPhaseTransferCount;
char *m_pExecutionPhaseData;
int m_ExecutionPhaseCount;
/* sector counter and id counter */
int m_Counter;
/* ==0, to cpu, !=0 =from cpu */
int m_data_direction;
emu_timer *m_data_timer;
emu_timer *m_command_complete_timer;
devcb_resolved_write_line m_interrupt_func;
device_t *current_image();
void seek_to_track(int track);
void load_bad_tracks(int surface);
void write_bad_track(int surface, int track, int data);
void write_current_track(int surface, int track);
int read_current_track(int surface);
int read_bad_track(int surface, int track);
void get_drive();
void check_all_parameters_written();
void update_state();
void initialise_execution_phase_read(int transfer_size);
void initialise_execution_phase_write(int transfer_size);
void command_execute();
void command_continue();
void command_complete(int result, int int_rq);
void timed_command_complete();
void data_request();
void clear_data_request();
void timed_data_request();
/* locate sector for read/write operation */
int find_sector();
/* do a read operation */
void do_read();
void do_write();
void do_read_id();
void set_irq_state(int);
void set_dma_drq();
};
extern const device_type I8271;
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
struct i8271_interface
{
void (*interrupt)(device_t *device, int state);
void (*dma_request)(device_t *device, int state, int read_);
const char *floppy_drive_tags[2];
};
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
DECLARE_READ8_DEVICE_HANDLER (i8271_r);
DECLARE_WRITE8_DEVICE_HANDLER(i8271_w);
DECLARE_READ8_DEVICE_HANDLER (i8271_dack_r);
DECLARE_WRITE8_DEVICE_HANDLER(i8271_dack_w);
DECLARE_READ8_DEVICE_HANDLER (i8271_data_r);
DECLARE_WRITE8_DEVICE_HANDLER(i8271_data_w);
/***************************************************************************
DEVICE CONFIGURATION MACROS
***************************************************************************/