summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/ti99_hd.h
blob: b31f5420fb309a7af97f6a7117949e33bf9646b0 (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
// license:MAME|LGPL-2.1+
// copyright-holders:Michael Zapf
/****************************************************************************

    Hard disk support
    See ti99_hd.c for documentation

    Michael Zapf

    February 2012: Rewritten as class

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

#ifndef __TI99_HD__
#define __TI99_HD__

#include "emu.h"
#include "imagedev/harddriv.h"

class mfm_harddisk_device : public harddisk_image_device,
                            public device_slot_card_interface
{
public:
	mfm_harddisk_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);

	typedef delegate<void (mfm_harddisk_device*, int)> index_pulse_cb;
	typedef delegate<void (mfm_harddisk_device*, int)> seek_complete_cb;

	void setup_index_pulse_cb(index_pulse_cb cb);
	void setup_seek_complete_cb(seek_complete_cb cb);

	// Active low lines. We're using ASSERT=0 / CLEAR=1
	line_state		ready_r() { return m_ready? ASSERT_LINE : CLEAR_LINE; }
	line_state		seek_complete_r() { return m_seek_complete? ASSERT_LINE : CLEAR_LINE; } ;
	line_state		trk00_r() { return m_current_cylinder==0? ASSERT_LINE : CLEAR_LINE; } 

	// Step
	void 			step_w(line_state line);
	void 			direction_in_w(line_state line);
	
protected:
	void        		device_start();
	void				device_reset();
	emu_timer    	  	*m_index_timer, *m_spinup_timer, *m_seek_timer;
	index_pulse_cb 		m_index_pulse_cb;
	seek_complete_cb	m_seek_complete_cb;
	void           		device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);

private:
	bool		m_ready;
	int			m_current_cylinder;
	int 		m_track_delta;
	int			m_step_phase;
	bool 		m_seek_complete;
	bool		m_seek_inward;
	//bool		m_seeking;
	bool		m_autotruncation;
	line_state	m_step_line;	// keep the last state
	
	void 		head_move();
};

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

extern const device_type MFM_HD_GENERIC;

// ===========================================================================
// Legacy implementation
// ===========================================================================
#define MFMHD_0 "mfmhd0"
#define MFMHD_1 "mfmhd1"
#define MFMHD_2 "mfmhd2"

extern const device_type TI99_MFMHD_LEG;

/*
    Needed to adapt to higher cylinder numbers. Floppies do not have such
    high numbers.
*/
struct chrn_id_hd
{
	UINT16 C;
	UINT8 H;
	UINT8 R;
	UINT8 N;
	int data_id;            // id for read/write data command
	unsigned long flags;
};

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

	void    read_sector(int cylinder, int head, int sector, UINT8 *buf);
	void    write_sector(int cylinder, int head, int sector, UINT8 *buf);
	void    read_track(int head, UINT8 *buffer);
	void    write_track(int head, UINT8 *buffer, int data_count);
	UINT8   get_status();
	void    seek(int direction);
	void    get_next_id(int head, chrn_id_hd *id);
	int     get_track_length();

protected:
	void    device_start();
	void    device_reset();
	machine_config_constructor device_mconfig_additions() const;

private:
	int     find_block(const UINT8 *buffer, int start, int stop, UINT8 byte, size_t number);
	UINT8   cylinder_to_ident(int cylinder);
	bool    harddisk_chs_to_lba(hard_disk_file *hdfile, int cylinder, int head, int sector, UINT32 *lba);

	int     m_current_cylinder;
	int     m_current_head;
	bool    m_seeking;
	int     m_status;
	int     m_id_index; /* position in track for seeking the sector; counts the sector number */

	harddisk_image_device *m_drive;
};

class ide_harddisk_legacy_device : public device_t
{
public:
	ide_harddisk_legacy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
protected:
	virtual void    device_start() { };
	virtual void    device_reset() { };
	virtual machine_config_constructor device_mconfig_additions() const;
};

#define MCFG_MFMHD_3_DRIVES_ADD()           \
	MCFG_DEVICE_ADD(MFMHD_0, TI99_MFMHD_LEG, 0)     \
	MCFG_DEVICE_ADD(MFMHD_1, TI99_MFMHD_LEG, 0)     \
	MCFG_DEVICE_ADD(MFMHD_2, TI99_MFMHD_LEG, 0)

#endif