diff options
Diffstat (limited to 'trunk/src/emu/machine/8237dma.h')
-rw-r--r-- | trunk/src/emu/machine/8237dma.h | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/8237dma.h b/trunk/src/emu/machine/8237dma.h new file mode 100644 index 00000000000..864aba746ad --- /dev/null +++ b/trunk/src/emu/machine/8237dma.h @@ -0,0 +1,210 @@ +/*************************************************************************** + + Intel 8237 Programmable DMA Controller emulation + + Copyright Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**************************************************************************** + _____ _____ + _I/OR 1 |* \_/ | 40 A7 + _I/OW 2 | | 39 A6 + _MEMR 3 | | 38 A5 + _MEMW 4 | | 37 A4 + 5 | | 36 _EOP + READY 6 | | 35 A3 + HLDA 7 | | 34 A2 + ADSTB 8 | | 33 A1 + AEN 9 | | 32 A0 + HRQ 10 | 8237 | 31 Vcc + _CS 11 | | 30 DB0 + CLK 12 | | 29 DB1 + RESET 13 | | 28 DB2 + DACK2 14 | | 27 DB3 + DACK3 15 | | 26 DB4 + DREQ3 16 | | 25 DACK0 + DREQ2 17 | | 24 DACK1 + DREQ1 18 | | 23 DB5 + DREQ0 19 | | 22 DB6 + GND 20 |_____________| 21 DB7 + +***************************************************************************/ + +#pragma once + +#ifndef __I8237__ +#define __I8237__ + +#include "emu.h" + + + +/*************************************************************************** + DEVICE CONFIGURATION MACROS +***************************************************************************/ + +#define MCFG_I8237_ADD(_tag, _clock, _config) \ + MCFG_DEVICE_ADD(_tag, I8237, _clock) \ + MCFG_DEVICE_CONFIG(_config) + +#define I8237_INTERFACE(_name) \ + const i8237_interface (_name) = + + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + + +// ======================> i8237_interface + +struct i8237_interface +{ + devcb_write_line m_out_hrq_cb; + devcb_write_line m_out_eop_cb; + + /* accessors to main memory */ + devcb_read8 m_in_memr_cb; + devcb_write8 m_out_memw_cb; + + /* channel accessors */ + devcb_read8 m_in_ior_cb[4]; + devcb_write8 m_out_iow_cb[4]; + devcb_write_line m_out_dack_cb[4]; +}; + + + +// ======================> i8237_device + +class i8237_device : public device_t, + public i8237_interface +{ +public: + // construction/destruction + i8237_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + /* register access */ + UINT8 i8237_r(UINT32 offset); + void i8237_w(UINT32 offset, UINT8 data); + + /* hold acknowledge */ + void i8237_hlda_w(UINT8 state) { m_hlda = state; } + + /* data request */ + void i8237_drq_write(int channel, int state); + + void i8237_timerproc(); + +protected: + // device-level overrides + virtual void device_config_complete(); + virtual void device_start(); + virtual void device_reset(); + virtual void device_post_load() { } + virtual void device_clock_changed() { } + + static TIMER_CALLBACK( i8237_timerproc_callback ); + static TIMER_CALLBACK( receive_event_callback ); + +private: + + void i8237_do_read(); + void i8237_do_write(); + void i8237_advance(); + void i8327_set_dack(int channel); + + /* States that the i8237 device can be in */ + enum dma8237_state + { + DMA8237_SI, /* Idle state */ + DMA8237_S0, /* HRQ has been triggered, waiting to receive HLDA */ + // DMA8237_SW, /* Wait state */ + DMA8237_SC, /* Cascade mode, waiting for peripheral */ + + /* Normal transfer states */ + DMA8237_S1, /* Output A8-A15; only used when A8-A15 really needs to be output */ + DMA8237_S2, /* Output A0-A7 */ + DMA8237_S3, /* Initiate read; skipped in compressed timing. On the S2->S3 transition DACK is set. */ + DMA8237_S4, /* Perform read/write */ + + /* Memory to memory transfer states */ + DMA8237_S11, /* Output A8-A15 */ + // DMA8237_S12, /* Output A0-A7 */ + // DMA8237_S13, /* Initiate read */ + // DMA8237_S14, /* Perform read/write */ + // DMA8237_S21, /* Output A8-A15 */ + // DMA8237_S22, /* Output A0-A7 */ + // DMA8237_S23, /* Initiate read */ + // DMA8237_S24, /* Perform read/write */ + }; + + devcb_resolved_write_line m_out_hrq_func; + devcb_resolved_write_line m_out_eop_func; + devcb_resolved_read8 m_in_memr_func; + devcb_resolved_write8 m_out_memw_func; + + emu_timer *m_timer; + + struct + { + devcb_resolved_read8 m_in_ior_func; + devcb_resolved_write8 m_out_iow_func; + devcb_resolved_write_line m_out_dack_func; + UINT16 m_base_address; + UINT16 m_base_count; + UINT16 m_address; + UINT16 m_count; + UINT8 m_mode; + int m_high_address_changed; + } m_chan[4]; + + UINT32 m_msb : 1; + UINT32 m_eop : 1; + UINT8 m_temp; + UINT8 m_temporary_data; + UINT8 m_command; + UINT8 m_drq; + UINT8 m_mask; + UINT8 m_hrq; + UINT8 m_hlda; + + /* bits 0- 3 : Terminal count for channels 0-3 + * bits 4- 7 : Transfer in progress for channels 0-3 */ + UINT8 m_status; + + dma8237_state m_state; /* State the device is currently in */ + int m_service_channel; /* Channel we will be servicing */ + int m_last_service_channel; /* Previous channel we serviced; used to determine channel priority. */ +}; + + +// device type definition +extern const device_type I8237; + + + +/*************************************************************************** + PROTOTYPES +***************************************************************************/ + +/* register access */ +READ8_DEVICE_HANDLER( i8237_r ); +WRITE8_DEVICE_HANDLER( i8237_w ); + +/* hold acknowledge */ +WRITE_LINE_DEVICE_HANDLER( i8237_hlda_w ); + +/* ready */ +WRITE_LINE_DEVICE_HANDLER( i8237_ready_w ); + +/* data request */ +WRITE_LINE_DEVICE_HANDLER( i8237_dreq0_w ); +WRITE_LINE_DEVICE_HANDLER( i8237_dreq1_w ); +WRITE_LINE_DEVICE_HANDLER( i8237_dreq2_w ); +WRITE_LINE_DEVICE_HANDLER( i8237_dreq3_w ); + +/* end of process */ +WRITE_LINE_DEVICE_HANDLER( i8237_eop_w ); + +#endif |