summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/gmboard.h
blob: 743b61f5b26b3175f1adcd8c4d482d8805a95910 (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
// license:BSD-3-Clause
// copyright-holders:hap
/*

    Milton Bradley Grand Master motorized self-moving chessboard

*/

#ifndef MAME_MACHINE_GMBOARD_H
#define MAME_MACHINE_GMBOARD_H

#pragma once

#include "machine/sensorboard.h"

class gmboard_device : public device_t
{
public:
	gmboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);

	// configuration helpers
	template <std::size_t N> auto quad_cb() { return m_quad_cb[N].bind(); } // x/y motor quadrature encoder state
	gmboard_device &set_size(u16 width, u16 height, u16 square) { m_width = width; m_height = height; m_square = square; return *this; }
	gmboard_device &set_offsets(u16 x_offset, u16 y_offset) { m_x_offset = x_offset; m_y_offset = y_offset; return *this; }
	gmboard_device &set_speed(attotime speed) { m_speed = speed; return *this; }

	sensorboard_device &get() { return *m_board; }

	// external read/write handlers
	void magnet_w(int state);
	int magnet_r();
	void motor_w(offs_t offset, u8 data);
	u8 quad_r(offs_t offset) { return m_motor_quad[offset & 1]; }

	u16 read_file(u8 x, bool reverse = false) { return m_board->read_file(x, reverse); }
	u16 read_rank(u8 y, bool reverse = false) { return m_board->read_rank(y, reverse); }

protected:
	// device-level overrides
	virtual void device_start() override ATTR_COLD;
	virtual void device_reset() override ATTR_COLD;
	virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;

private:
	required_device<sensorboard_device> m_board;
	output_finder<> m_piece_hand;
	output_finder<5> m_out_motor;
	output_finder<2> m_out_pos;

	u8 m_magnet;
	u8 m_pieces_map[0x40][0x40];

	u8 m_motor_dir[2];
	u32 m_motor_max[2];
	u32 m_motor_pos[2];
	u8 m_motor_quad[2];
	s32 m_motor_drift[2]; // diagnostics

	attotime m_motor_period;
	attotime m_motor_remain[2];
	emu_timer *m_motor_timer[2];

	u16 m_width;          // motor range
	u16 m_height;         // "
	u16 m_square;         // number of quarter rotation steps per square
	u16 m_x_offset;       // unscaled offset relative to the bottom-left corner
	u16 m_y_offset;       // "
	attotime m_speed;     // time per square at full speed

	devcb_write8::array<2> m_quad_cb;

	void init_board(u8 data);
	void clear_board(u8 data);
	void init_motors();

	void get_scaled_pos(double *x, double *y);
	void output_magnet_pos();
	void realign_magnet_pos();
	int check_board(bool magnet, bool sensor);

	TIMER_CALLBACK_MEMBER(motor_count);
};


DECLARE_DEVICE_TYPE(MB_GMBOARD, gmboard_device)

#endif // MAME_MACHINE_GMBOARD_H