summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/i7220.h
blob: 51eaf3ce917f72766bbf2ffb8731e5cffa32979d (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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// license:BSD-3-Clause
// copyright-holders:Sergey Svishchev
/**********************************************************************

    Intel 7220 Bubble Memory Controller emulation

**********************************************************************
                            _____   _____
             /PWR.FAIL   1 |*    \_/     | 40  Vcc
            /RESET.OUT   2 |             | 39  /X+
                   CLK   3 |             | 38  /X-
                /RESET   4 |             | 37  /Y+
                   /RD   5 |             | 36  /Y-
                   /WR   6 |             | 35  /TM.A
                 /DACK   7 |             | 34  /TM.B
                   DRQ   8 |             | 33  /REP.EN
                   INT   9 |             | 32  /BOOT.EN
                    A0  10 |     7220    | 31  /SWAP.EN
                    D0  11 |             | 30  /BOOT.S.EN
                    D1  12 |             | 29  C/D
                    D2  13 |             | 28  /DET.ON
                    D3  14 |             | 27  /ERR.FLG
                    D4  15 |             | 26  /WAIT
                    D5  16 |             | 25  /BUS.RD
                    D6  17 |             | 24  /SHIFT.CLK
                    D7  18 |             | 23  /SYNC
                    D8  19 |             | 22  DIO
                   GND  20 |_____________| 21  /CS

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

#ifndef MAME_MACHINE_I7220_H
#define MAME_MACHINE_I7220_H

#pragma once

#define I7110_MBM_SIZE (128 * 1024) // 1 megabit
#define I7115_MBM_SIZE (512 * 1024) // 4 megabit


///*************************************************************************
//  INTERFACE CONFIGURATION MACROS
///*************************************************************************

#define MCFG_I7220_IRQ_CALLBACK(_write) \
	downcast<i7220_device &>(*device).set_intrq_wr_callback(DEVCB_##_write);

#define MCFG_I7220_DRQ_CALLBACK(_write) \
	downcast<i7220_device &>(*device).set_drq_wr_callback(DEVCB_##_write);

#define MCFG_I7220_DATA_SIZE(data_size) \
	downcast<i7220_device &>(*device).set_data_size(data_size);



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

// ======================> i7220_device

class i7220_device : public device_t,
					 public device_image_interface
{
public:
	// construction/destruction
	i7220_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	template <class Object> devcb_base &set_intrq_wr_callback(Object &&cb) { return intrq_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_drq_wr_callback(Object &&cb) { return drq_cb.set_callback(std::forward<Object>(cb)); }

	void set_data_size(int data_size) { m_data_size = data_size; }

	// image-level overrides
	virtual image_init_result call_load() override;

	virtual iodevice_t image_type() const override { return IO_MEMCARD; }

	virtual bool is_readable()  const override { return 1; }
	virtual bool is_writeable() const override { return 1; }
	virtual bool is_creatable() const override { return 0; }
	virtual bool must_be_loaded() const override { return 1; }
	virtual bool is_reset_on_load() const override { return 0; }
	virtual const char *file_extensions() const override { return "bubble"; }

	DECLARE_READ8_MEMBER(read);
	DECLARE_WRITE8_MEMBER(write);

protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

	int m_data_size;

private:
	enum {
		PHASE_IDLE, PHASE_CMD, PHASE_EXEC, PHASE_RESULT
	};

	enum {
		// General "doing nothing" state
		IDLE,

		// Main states
		INIT,
		READ_FSA,
		READ_DATA,
		WRITE_DATA,
		FAIL,

		// Sub-states
		INITIALIZE,

		WAIT_FSA_REPLY,
		WAIT_FSA_REPLY_DONE,

		WAIT_FIFO,
		WAIT_FIFO_DONE,

		COMMAND_DONE,

		SECTOR_READ,
		SECTOR_WRITTEN
	};

	enum {
		C_WRITE_BOOTLOOP_REG_MASKED,
		C_INIT,
		C_READ,
		C_WRITE,
		C_READ_SEEK,
		C_READ_BOOTLOOP_REG,
		C_WRITE_BOOTLOOP_REG,
		C_WRITE_BOOTLOOP,
		C_READ_FSA_STATUS,
		C_ABORT,
		C_WRITE_SEEK,
		C_READ_BOOTLOOP,
		C_READ_CORRECTED,
		C_RESET_FIFO,
		C_MBM_PURGE,
		C_RESET
	};

	enum {
		R_UR     = 0x0a,
		R_BLR_L  = 0x0b,
		R_BLR_M  = 0x0c,
		R_ER     = 0x0d,
		R_AR_L   = 0x0e,
		R_AR_M   = 0x0f,
	};

	enum {
		ER_IEN   = 0x01,
		ER_IEE   = 0x02,
		ER_DMAEN = 0x04,
		ER_MFBTR = 0x08,
		ER_WBE   = 0x10,
		ER_ERCD  = 0x20,
		ER_EICD  = 0x40,
		ER_EPI   = 0x80
	};

	enum {
		SR_FIFO  = 0x01,
		SR_PE    = 0x02,
		SR_UE    = 0x04,
		SR_CE    = 0x08,
		SR_TE    = 0x10,
		SR_FAIL  = 0x20,
		SR_DONE  = 0x40,
		SR_BUSY  = 0x80,

		SR_CLEAR = 0x7E
	};

	struct bubble_info {
		emu_timer *tm;
		int main_state, sub_state;
		int limit, counter;
	};

	void delay_cycles(emu_timer *tm, int cycles);
	void set_drq(bool state);
	void set_irq(bool state);

	void update_regs();
	void update_drq();

	void start_command(int cmd);
	void general_continue(bubble_info &bi);
	void command_end(bubble_info &bi, bool success);

	void command_fail_start(bubble_info &bi);
	void command_fail_continue(bubble_info &bi);

	void init_start(bubble_info &bi);
	void init_continue(bubble_info &bi);

	void read_fsa_start(bubble_info &bi);
	void read_fsa_continue(bubble_info &bi);

	void read_data_start(bubble_info &bi);
	void read_data_continue(bubble_info &bi);

	void write_data_start(bubble_info &bi);
	void write_data_continue(bubble_info &bi);

	void fifo_clear();
	void fifo_push(uint8_t val);
	uint8_t fifo_pop();

	int main_phase;
	bool drq, irq;
	bubble_info bi;

	uint8_t buf[32];
	int blr_count, blr_nfc, ar_addr, ar_mbm;

	devcb_write_line intrq_cb;
	devcb_write_line drq_cb;

	uint8_t m_regs[16];
	uint8_t m_rac;
	uint8_t m_cmdr;
	uint8_t m_str;
	uint16_t m_blr;
	uint16_t m_ar;
	int m_fifo_size;
	util::fifo<uint8_t, 40> m_fifo;
};


// device type definition
DECLARE_DEVICE_TYPE(I7220, i7220_device)

#endif // MAME_MACHINE_I7220_H