summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/bq48x2.h
blob: ddf4505b44f8de2460e7e75b520c01d17371d60f (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
// license:BSD-3-Clause
// copyright-holders:Michael Zapf
/*
    Texas Instruments/Benchmarq BQ4842/52 Real-time clock

    See bq48x2.cpp for details.

    Michael Zapf, April 2020
*/

#ifndef MAME_MACHINE_BQ48X2_H
#define MAME_MACHINE_BQ48X2_H

#pragma once

#include "dirtc.h"

// ======================> bq48x2_device

class bq48x2_device : public device_t,
					  public device_nvram_interface,
					  public device_rtc_interface
{
public:
	auto interrupt_cb() { return m_interrupt_cb.bind(); }
	auto resetout_cb() { return m_resetout_cb.bind(); }

	virtual uint8_t read(offs_t address);
	virtual void write(offs_t address, uint8_t data);

	DECLARE_READ_LINE_MEMBER(intrq_r);

	// Mainly used to disconnect from oscillator
	void connect_osc(bool conn);

protected:
	// construction/destruction (called from the subtypes)
	bq48x2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, int memsize);

	// callback called when interrupt pin state changes (may be nullptr)
	devcb_write_line    m_interrupt_cb;

	// callback called when watchdog times out changes (may be nullptr)
	devcb_write_line    m_resetout_cb;

	// Internal memory
	std::unique_ptr<u8 []>      m_sram;

	// Internal clock registers
	// The clock operates on these registers and copies them to the
	// registers in the address space
	uint8_t     m_intreg[16];

	TIMER_CALLBACK_MEMBER(rtc_clock_cb);
	TIMER_CALLBACK_MEMBER(rtc_periodic_cb);
	TIMER_CALLBACK_MEMBER(rtc_watchdog_cb);

	void nvram_default() override;
	void nvram_read(emu_file &file) override;
	void nvram_write(emu_file &file) override;

	void device_start() override;

	void set_watchdog_timer();

private:
	// Inherited from device_rtc_interface
	void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override;
	bool rtc_feature_y2k()  const override { return false; }
	bool rtc_feature_leap_year() const override { return true; }
	bool rtc_battery_backed() const override { return true; }

	// Sanity-check BCD number
	bool valid_bcd(uint8_t value, uint8_t min, uint8_t max);

	// Increment BCD number
	bool increment_bcd(uint8_t& bcdnumber, uint8_t limit, uint8_t min);

	// Fetch register value from SRAM using register number
	uint8_t get_register(int number, uint8_t mask);

	// Set a register in SRAM using the register number
	void set_register(int number, uint8_t value);

	// Set/Reset one or more bits in the register
	void set_register(int number, uint8_t bits, bool set);

	// Check matching registers of time and alarm
	bool check_match(int regint, int regalarm, uint8_t mask);

	// Check bits in register
	bool is_set(int number, uint8_t flag);

	// Advance
	void advance_days_bcd();

	// Copy register contents from the internal registers to SRAM or back
	void transfer_to_int();
	void transfer_to_access();

	// clock timer: called every second
	emu_timer *m_clock_timer;

	// Periodic timer
	emu_timer *m_periodic_timer;

	// Watchdog timer
	emu_timer *m_watchdog_timer;

	// Set timers
	void set_periodic_timer();

	// Get the delay until the next second
	int get_delay();

	int m_memsize;
};

// Special types

class bq4842_device : public bq48x2_device
{
public:
	bq4842_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};

class bq4852_device : public bq48x2_device
{
public:
	bq4852_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};

DECLARE_DEVICE_TYPE(BQ4842, bq4842_device)
DECLARE_DEVICE_TYPE(BQ4852, bq4852_device)
#endif