summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/mc88200.h
blob: ecf5f541c2b925ad385eff5981e641e4d9697676 (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
// license:BSD-3-Clause
// copyright-holders:Patrick Mackinlay

#ifndef MAME_MACHINE_MC88200_H
#define MAME_MACHINE_MC88200_H

#pragma once

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

	template <typename T> void set_mbus(T &&tag, int spacenum) { m_mbus.set_tag(std::forward<T>(tag), spacenum); }

	bool translate(int intention, u32 &address, bool supervisor);

	template <typename T> std::optional<T> read(u32 virtual_address, bool supervisor);
	template <typename T> bool write(u32 virtual_address, T data, bool supervisor);
	void bus_error_w(int state) { if (!machine().side_effects_disabled()) m_bus_error = true; }

protected:
	virtual void device_start() override ATTR_COLD;
	virtual void device_reset() override ATTR_COLD;

	void map(address_map &map) ATTR_COLD;

	u32 idr_r() { return m_idr; }
	u32 scr_r() { return m_scr; }
	u32 ssr_r() { return m_ssr; }
	u32 sar_r() { return m_sar; }
	u32 sctr_r() { return m_sctr; }

	u32 pfsr_r() { return m_pfsr; }
	u32 pfar_r() { return m_pfar; }
	u32 sapr_r() { return m_sapr; }
	u32 uapr_r() { return m_uapr; }

	u32 cdp_r(offs_t offset) { return m_cache[BIT(m_sar, 4, 8)].line[offset].data[BIT(m_sar, 2, 2)]; }
	u32 ctp_r(offs_t offset) { return m_cache[BIT(m_sar, 4, 8)].line[offset].tag; }
	u32 cssp_r() { return m_cache[BIT(m_sar, 4, 8)].status; }

	void idr_w(u32 data);
	void scr_w(u32 data);
	void ssr_w(u32 data);
	void sar_w(u32 data);
	void sctr_w(u32 data);

	void pfsr_w(u32 data);
	void pfar_w(u32 data);
	void sapr_w(u32 data);
	void uapr_w(u32 data);

	void bwp_w(offs_t offset, u32 data);
	void cdp_w(offs_t offset, u32 data);
	void ctp_w(offs_t offset, u32 data);
	void cssp_w(u32 data);

	struct translate_result
	{
		translate_result(u32 address, bool ci, bool g, bool wt)
			: address(address)
			, ci(ci)
			, g(g)
			, wt(wt)
		{}

		u32 const address;
		bool const ci; // cache inhibit
		bool const g;  // global
		bool const wt; // writethrough
	};
	std::optional<translate_result> translate(u32 virtual_address, bool supervisor, bool write);

	struct cache_set
	{
		void set_mru(unsigned const line);

		void set_unmodified(unsigned const line);
		void set_modified(unsigned const line);
		void set_shared(unsigned const line);
		void set_invalid(unsigned const line);

		bool modified(unsigned const line) const;
		bool shared(unsigned const line) const;
		bool invalid(unsigned const line) const;

		bool enabled(unsigned const line) const;

		u32 status;

		struct cache_line
		{
			bool match_segment(u32 const address) const;
			bool match_page(u32 const address) const;

			bool load_line(mc88200_device &cmmu, u32 const address);
			bool copy_back(mc88200_device &cmmu, u32 const address, bool const flush = false);

			u32 tag;
			u32 data[4];
		}
		line[4];
	};
	typedef bool (mc88200_device::cache_set::cache_line::* match_function)(u32 const) const;

	std::optional<unsigned> cache_replace(cache_set const &cs);
	void cache_flush(unsigned const start, unsigned const limit, match_function match, bool const copyback, bool const invalidate);

	template <typename T> std::optional<T> mbus_read(u32 address);
	template <typename T> bool mbus_write(u32 address, T data, bool flush = false);

private:
	required_address_space m_mbus;

	u32 m_idr;  // identification register
	u32 m_scr;  // system command register
	u32 m_ssr;  // system status register
	u32 m_sar;  // system address register
	u32 m_sctr; // system control register
	u32 m_pfsr; // p bus fault status register
	u32 m_pfar; // p bus fault address register
	u32 m_sapr; // supervisor area pointer register
	u32 m_uapr; // user area pointer register

	u32 m_batc[10]; // block address translation cache
	u64 m_patc[56]; // page address translation cache
	u32 m_patc_ptr;

	bool m_bus_error;

	static constexpr unsigned CACHE_SETS = 256;
	std::unique_ptr<cache_set[]> m_cache; // data cache

	u32 const m_id;
};

DECLARE_DEVICE_TYPE(MC88200, mc88200_device)

#endif // MAME_MACHINE_MC88200_H