1 // license:BSD-3-Clause
2 // copyright-holders:F. Ulivi
3 /*********************************************************************
4 
5     hp_taco.h
6 
7     HP TApe COntroller (5006-3012)
8 
9 *********************************************************************/
10 
11 #ifndef MAME_MACHINE_HP_TACO_H
12 #define MAME_MACHINE_HP_TACO_H
13 
14 #pragma once
15 
16 #include "formats/hti_tape.h"
17 #include "machine/hp_dc100_tape.h"
18 
19 class hp_taco_device : public device_t
20 {
21 public:
22 	// construction/destruction
23 	hp_taco_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
24 
25 	// configuration helpers
irq()26 	auto irq() { return m_irq_handler.bind(); }
flg()27 	auto flg() { return m_flg_handler.bind(); }
sts()28 	auto sts() { return m_sts_handler.bind(); }
29 
30 	// Register read/write
31 	void reg_w(offs_t offset, uint16_t data);
32 	uint16_t reg_r(offs_t offset);
33 
34 	// Flag & status read
35 	DECLARE_READ_LINE_MEMBER(flg_r);
36 	DECLARE_READ_LINE_MEMBER(sts_r);
37 
38 	DECLARE_WRITE_LINE_MEMBER(cart_out_w);
39 	DECLARE_WRITE_LINE_MEMBER(hole_w);
40 	DECLARE_WRITE_LINE_MEMBER(tacho_tick_w);
41 	DECLARE_WRITE_LINE_MEMBER(motion_w);
42 	DECLARE_WRITE_LINE_MEMBER(rd_bit_w);
43 	DECLARE_READ_LINE_MEMBER(wr_bit_r);
44 
45 protected:
46 	hp_taco_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
47 
48 	// device-level overrides
49 	virtual void device_add_mconfig(machine_config &config) override;
50 	virtual void device_start() override;
51 	virtual void device_reset() override;
52 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
53 
54 private:
55 	required_device<hp_dc100_tape_device> m_tape;
56 
57 	devcb_write_line m_irq_handler;
58 	devcb_write_line m_flg_handler;
59 	devcb_write_line m_sts_handler;
60 
61 	// Registers
62 	uint16_t m_data_reg;
63 	uint16_t m_cmd_reg;
64 	uint16_t m_status_reg;
65 	uint16_t m_tach_reg;
66 	uint16_t m_checksum_reg;
67 	uint16_t m_threshold_reg;
68 
69 	// State
70 	bool m_irq;
71 	bool m_flg;
72 	bool m_sts;
73 	bool m_error;
74 	bool m_gap_in_read;
75 
76 	// Command FSM state
77 	typedef enum {
78 		CMD_IDLE,
79 		CMD_PH0,
80 		CMD_PH1,
81 		CMD_PH2,
82 		CMD_STOPPING
83 	} cmd_state_t;
84 	cmd_state_t m_cmd_state;
85 
86 	// Timers
87 	emu_timer *m_gap_timer;
88 	emu_timer *m_evd_timer;
89 	emu_timer *m_error_timer;
90 
91 	// Reading & writing
92 	uint16_t m_working_reg;
93 	unsigned m_bit_idx;
94 
95 	void clear_state();
96 	void irq_w(bool state);
97 	void sts_w(bool state);
98 	void set_error(bool error , bool gap_in_read);
99 	hti_format_t::tape_pos_t min_gap_size() const;
100 	void set_gap_timer();
101 	void set_evd_timer();
102 	void set_tape_present(bool present);
103 	void send_go();
104 	void send_stop();
105 	void end_cmd();
106 	void irq_and_end();
107 	bool is_at_slow_speed() const;
108 	void start_rd();
109 	void start_wr();
110 	void update_checksum(uint16_t data);
111 	void cmd_fsm();
112 	static uint8_t get_cmd(uint16_t cmd_reg);
113 	static bool is_cmd_rd_wr(uint16_t cmd_reg);
114 	static bool is_cmd_rd(uint16_t cmd_reg);
115 	static bool is_cmd_wr(uint16_t cmd_reg);
116 	static bool is_double_hole_cmd(uint16_t cmd_reg);
117 	void start_cmd_exec(uint16_t new_cmd_reg);
118 };
119 
120 // device type definition
121 DECLARE_DEVICE_TYPE(HP_TACO, hp_taco_device)
122 
123 #endif // MAME_MACHINE_HP_TACO_H
124