summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/hp_taco.h
blob: 3b926a0946a30e63f5b1576c3991e8986454c78c (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
// license:BSD-3-Clause
// copyright-holders:F. Ulivi
/*********************************************************************

    hp_taco.h

    HP TApe COntroller (5006-3012)

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

#ifndef MAME_MACHINE_HP_TACO_H
#define MAME_MACHINE_HP_TACO_H

#pragma once

#include "formats/hti_tape.h"

#define MCFG_TACO_IRQ_HANDLER(_devcb) \
	devcb = &downcast<hp_taco_device &>(*device).set_irq_handler(DEVCB_##_devcb);

#define MCFG_TACO_FLG_HANDLER(_devcb) \
	devcb = &downcast<hp_taco_device &>(*device).set_flg_handler(DEVCB_##_devcb);

#define MCFG_TACO_STS_HANDLER(_devcb) \
	devcb = &downcast<hp_taco_device &>(*device).set_sts_handler(DEVCB_##_devcb);

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

	// configuration helpers
	template <class Object> devcb_base &set_irq_handler(Object &&cb) { return m_irq_handler.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_flg_handler(Object &&cb) { return m_flg_handler.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_sts_handler(Object &&cb) { return m_sts_handler.set_callback(std::forward<Object>(cb)); }

	// Register read/write
	DECLARE_WRITE16_MEMBER(reg_w);
	DECLARE_READ16_MEMBER(reg_r);

	// Flag & status read
	DECLARE_READ_LINE_MEMBER(flg_r);
	DECLARE_READ_LINE_MEMBER(sts_r);

		// device_image_interface overrides
	virtual image_init_result call_load() override;
	virtual image_init_result call_create(int format_type, util::option_resolution *format_options) override;
	virtual void call_unload() override;
	virtual std::string call_display() override;
	virtual iodevice_t image_type() const override { return IO_MAGTAPE; }
	virtual bool is_readable() const override { return true; }
	virtual bool is_writeable() const override { return true; }
	virtual bool is_creatable() const override { return true; }
	virtual bool must_be_loaded() const override { return false; }
	virtual bool is_reset_on_load() const override { return false; }
	virtual const char *file_extensions() const override;

protected:
	hp_taco_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

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

private:
	devcb_write_line m_irq_handler;
	devcb_write_line m_flg_handler;
	devcb_write_line m_sts_handler;

	// Registers
	uint16_t m_data_reg;
	bool m_data_reg_full;
	uint16_t m_cmd_reg;
	uint16_t m_status_reg;
	uint16_t m_tach_reg;
	hti_format_t::tape_pos_t m_tach_reg_ref;
	bool m_tach_reg_frozen;
	uint16_t m_checksum_reg;
	bool m_clear_checksum_reg;
	uint16_t m_timing_reg;

	// State
	bool m_irq;
	bool m_flg;
	bool m_sts;

	// Command FSM state
	typedef enum {
		CMD_IDLE,
		CMD_INVERTING,
		CMD_PH0,
		CMD_PH1,
		CMD_PH2,
		CMD_END,
		CMD_STOPPING
	} cmd_state_t;
	cmd_state_t m_cmd_state;

	// Tape position & motion
	hti_format_t::tape_pos_t m_tape_pos;
	attotime m_start_time;  // Tape moving if != never
	bool m_tape_fwd;
	bool m_tape_fast;

	// Timers
	emu_timer *m_tape_timer;
	emu_timer *m_hole_timer;
	emu_timer *m_timeout_timer;

	// Content of tape
	hti_format_t m_image;
	bool m_image_dirty;

	// Reading & writing
	bool m_tape_wr;
	hti_format_t::tape_pos_t m_rw_pos;
	uint16_t m_next_word;
	hti_format_t::track_iterator_t m_rd_it;
	bool m_rd_it_valid;

	// Gap detection
	hti_format_t::tape_pos_t m_gap_detect_start;

	void clear_state(void);
	void irq_w(bool state);
	void set_error(bool state);
	bool is_braking(void) const;
	unsigned speed_to_tick_freq(void) const;
	hti_format_t::tape_pos_t current_tape_pos(void) const;
	void update_tape_pos(void);
	void update_tach_reg(void);
	void freeze_tach_reg(bool freeze);
	attotime time_to_distance(hti_format_t::tape_pos_t distance) const;
	attotime time_to_target(hti_format_t::tape_pos_t target) const;
	attotime time_to_stopping_pos(void) const;
	bool start_tape_cmd(uint16_t cmd_reg , uint16_t must_be_1 , uint16_t must_be_0);
	void stop_tape(void);
	unsigned current_track(void);
	attotime fetch_next_wr_word(void);
	attotime time_to_rd_next_word(hti_format_t::tape_pos_t& word_rd_pos);
	hti_format_t::tape_pos_t min_gap_size(void) const;
	void set_tape_present(bool present);
	attotime time_to_next_hole(void) const;
	attotime time_to_tach_pulses(void) const;
	void terminate_cmd_now(void);
	void set_data_timeout(bool long_timeout);
	void cmd_fsm(void);
	void start_cmd_exec(uint16_t new_cmd_reg);
	image_init_result internal_load(bool is_create);
};

// device type definition
DECLARE_DEVICE_TYPE(HP_TACO, hp_taco_device)

#endif // MAME_MACHINE_HP_TACO_H