summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/idectrl.h
blob: 91bf0cca397b84e783ef189592cb07d272a1e7a1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/***************************************************************************

    idectrl.h

    Generic (PC-style) IDE controller implementation.

    Copyright Nicola Salmoria and the MAME Team.
    Visit http://mamedev.org for licensing and usage restrictions.

***************************************************************************/

#pragma once

#ifndef __IDECTRL_H__
#define __IDECTRL_H__

#include "idehd.h"
#include "harddisk.h"

/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/

// ======================> ide_slot_device

class ide_slot_device : public device_t,
						public device_slot_interface
{
public:
	// construction/destruction
	ide_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);

	ide_device_interface *dev() { return m_dev; }
protected:
	// device-level overrides
	virtual void device_start();
	virtual void device_config_complete();
private:
	ide_device_interface *m_dev;
};

// device type definition
extern const device_type IDE_SLOT;

/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/

#define MCFG_IDE_CONTROLLER_IRQ_HANDLER(_devcb) \
	devcb = &ide_controller_device::set_irq_handler(*device, DEVCB2_##_devcb);

#define MCFG_IDE_CONTROLLER_BUS_MASTER(bmcpu, bmspace) \
	ide_controller_device::set_bus_master(*device, bmcpu, bmspace);

SLOT_INTERFACE_EXTERN(ide_devices);
SLOT_INTERFACE_EXTERN(ide_devices);

/***************************************************************************
    DEVICE CONFIGURATION MACROS
***************************************************************************/

#define MCFG_IDE_CONTROLLER_ADD(_tag, _slotintf, _master, _slave, _fixed) \
	MCFG_IDE_SLOT_ADD("drive_0", _slotintf, _master, _fixed) \
	MCFG_IDE_SLOT_ADD("drive_1", _slotintf, _slave, _fixed) \
	MCFG_DEVICE_ADD(_tag, IDE_CONTROLLER, 0)

#define MCFG_IDE_SLOT_ADD(_tag, _slot_intf, _def_slot, _fixed) \
	MCFG_DEVICE_ADD(_tag, IDE_SLOT, 0) \
	MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed)

/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/

#define IDE_CONFIG_REGISTERS                0x10

/* ----- device interface ----- */

class ide_controller_device : public device_t
{
public:
	ide_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);

	// static configuration helpers
	template<class _Object> static devcb2_base &set_irq_handler(device_t &device, _Object object) { return downcast<ide_controller_device &>(device).m_irq_handler.set_callback(object); }
	static void set_bus_master(device_t &device, const char *bmcpu, UINT32 bmspace) {ide_controller_device &ide = downcast<ide_controller_device &>(device); ide.bmcpu = bmcpu; ide.bmspace = bmspace; }

	UINT8 *ide_get_features(int drive);
	void ide_set_gnet_readlock(const UINT8 onoff);
	void ide_set_master_password(const UINT8 *password);
	void ide_set_user_password(const UINT8 *password);

	DECLARE_READ8_MEMBER(read_via_config);
	DECLARE_WRITE8_MEMBER(write_via_config);
	DECLARE_READ16_MEMBER(read_cs0);
	DECLARE_READ16_MEMBER(read_cs1);
	DECLARE_WRITE16_MEMBER(write_cs0);
	DECLARE_WRITE16_MEMBER(write_cs1);

	DECLARE_READ16_MEMBER(read_cs0_pc);
	DECLARE_READ16_MEMBER(read_cs1_pc);
	DECLARE_WRITE16_MEMBER(write_cs0_pc);
	DECLARE_WRITE16_MEMBER(write_cs1_pc);
	
	DECLARE_READ32_MEMBER( ide_bus_master32_r );
	DECLARE_WRITE32_MEMBER( ide_bus_master32_w );

	UINT32 ide_bus_master_read(offs_t offset, int size);
	void ide_bus_master_write(offs_t offset, int size, UINT32 data);
	void signal_interrupt();
	void clear_interrupt();
	void read_sector_done();
	void write_sector_done();

	UINT8           status;

protected:
	// device-level overrides
	virtual void device_start();
	virtual void device_reset();

private:
	void signal_delayed_interrupt(attotime time, int buffer_ready);
	void next_sector();
	void security_error();
	void continue_read();
	void write_buffer_to_dma();
	void read_first_sector();
	void read_next_sector();
	void read_buffer_from_dma();
	void handle_command(UINT8 _command);
	void continue_write();

	UINT8           adapter_control;
	UINT8           error;
	UINT8           command;
	UINT8           interrupt_pending;
	UINT8           precomp_offset;

	UINT8           buffer[IDE_DISK_SECTOR_SIZE];
	UINT16          buffer_offset;
	UINT16          sector_count;

	UINT16          block_count;
	UINT16          sectors_until_int;
	UINT8           verify_only;

	UINT8           dma_active;
	address_space *dma_space;
	UINT8           dma_address_xor;
	UINT8           dma_last_buffer;
	offs_t          dma_address;
	offs_t          dma_descriptor;
	UINT32          dma_bytes_left;

	UINT8           bus_master_command;
	UINT8           bus_master_status;
	UINT32          bus_master_descriptor;

	UINT8           config_unknown;
	UINT8           config_register[IDE_CONFIG_REGISTERS];
	UINT8           config_register_num;

	emu_timer *     last_status_timer;
	emu_timer *     reset_timer;

	UINT8           master_password_enable;
	UINT8           user_password_enable;
	const UINT8 *   master_password;
	const UINT8 *   user_password;

	UINT8           gnetreadlock;

	UINT8           cur_drive;
	ide_slot_device *slot[2];

	devcb2_write_line m_irq_handler;
	const char *bmcpu;
	UINT32 bmspace;
};

extern const device_type IDE_CONTROLLER;

#endif  /* __IDECTRL_H__ */