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
|
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
nvram.c
Generic non-volatile RAM.
***************************************************************************/
#include "emu.h"
#include "machine/nvram.h"
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
// device type definition
DEFINE_DEVICE_TYPE(NVRAM, nvram_device, "nvram", "NVRAM")
//-------------------------------------------------
// nvram_device - constructor
//-------------------------------------------------
nvram_device::nvram_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock)
: device_t(mconfig, NVRAM, tag, owner, clock),
device_nvram_interface(mconfig, *this),
m_region(*this, DEVICE_SELF),
m_default_value(DEFAULT_ALL_1),
m_custom_handler(*this),
m_base(nullptr),
m_length(0)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void nvram_device::device_start()
{
// bind our handler
m_custom_handler.resolve();
}
//-------------------------------------------------
// nvram_default - called to initialize NVRAM to
// its default state
//-------------------------------------------------
void nvram_device::nvram_default()
{
// make sure we have a valid base pointer
determine_final_base();
// region always wins
if (m_region.found())
{
memcpy(m_base, m_region->base(), m_length);
return;
}
// default values for other cases
switch (m_default_value)
{
// all-0's
case DEFAULT_ALL_0:
memset(m_base, 0, m_length);
break;
// all 1's
default:
case DEFAULT_ALL_1:
memset(m_base, 0xff, m_length);
break;
// random values
case DEFAULT_RANDOM:
{
uint8_t *nvram = reinterpret_cast<uint8_t *>(m_base);
for (int index = 0; index < m_length; index++)
nvram[index] = machine().rand();
break;
}
// custom handler
case DEFAULT_CUSTOM:
m_custom_handler(*this, m_base, m_length);
break;
// none - do nothing
case DEFAULT_NONE:
break;
}
}
//-------------------------------------------------
// nvram_read - called to read NVRAM from the
// .nv file
//-------------------------------------------------
bool nvram_device::nvram_read(util::read_stream &file)
{
// make sure we have a valid base pointer
determine_final_base();
size_t actual;
return !file.read(m_base, m_length, actual) && actual == m_length;
}
//-------------------------------------------------
// nvram_write - called to write NVRAM to the
// .nv file
//-------------------------------------------------
bool nvram_device::nvram_write(util::write_stream &file)
{
size_t actual;
return !file.write(m_base, m_length, actual) && actual == m_length;
}
//-------------------------------------------------
// determine_final_base - get the final base
// pointer by looking up the memory share, unless
// a pointer was provided to us
//-------------------------------------------------
void nvram_device::determine_final_base()
{
// find our shared pointer with the target RAM
if (m_base == nullptr)
{
memory_share *share = owner()->memshare(tag());
if (share == nullptr)
throw emu_fatalerror("NVRAM device '%s' has no corresponding share() region", tag());
m_base = share->ptr();
m_length = share->bytes();
}
// if we are region-backed for the default, find it now and make sure it's the right size
if (m_region.found() && m_region->bytes() != m_length)
throw emu_fatalerror("%s",string_format("NVRAM device '%s' has a default region, but it should be 0x%X bytes", tag(), m_length).c_str());
}
|