summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/bus/ti99_peb/samsmem.c
blob: 20d387d53856e856aa1ad3370ef87f2df788a7c5 (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
// license:MAME|LGPL-2.1+
// copyright-holders:Michael Zapf
/****************************************************************************

    TI-99 SuperAMS Memory Expansion Card. Uses a 74LS612 memory mapper.
    The card can be equipped with up to 1 MiB of static CMOS memory; it is
    not buffered, however.

    SAMS organizes memory in 4 KiB blocks which are mapped into the address
    space by a memory mapper. The mapper can be configured via a sequence of
    addresses at 4000, 4002, ..., 401e, which correspond to memory locations
    0000-0fff, 1000-1fff, ..., f000-ffff.

    Michael Zapf

    February 2012: Rewritten as class

*****************************************************************************/

#include "samsmem.h"
#define RAMREGION "ram"

#define SAMS_CRU_BASE 0x1e00

#define VERBOSE 1
#define LOG logerror

sams_memory_expansion_device::sams_memory_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ti_expansion_card_device(mconfig, TI99_SAMSMEM, "SuperAMS memory expansion card", tag, owner, clock, "ti99_sams", __FILE__)
{
}

/*
    Memory read. The SAMS card has two address areas: The memory is at locations
    0x2000-0x3fff and 0xa000-0xffff, and the mapper area is at 0x4000-0x401e
    (only even addresses).
*/
READ8Z_MEMBER(sams_memory_expansion_device::readz)
{
	int base = 0;

	if (m_access_mapper && ((offset & 0xe000)==0x4000))
	{
		*value = m_mapper[(offset>>1)&0x000f];
	}

	if (((offset & 0xe000)==0x2000) || ((offset & 0xe000)==0xa000) || ((offset & 0xe000)==0xc000) || ((offset & 0xe000)==0xe000))
	{
		if (!m_map_mode)
		{
			// transparent mode
			*value = m_ram[offset & 0xffff];
		}
		else
		{
			base = (m_mapper[(offset & 0xf000)>>12] << 12);
			*value = m_ram[base | (offset & 0x0fff)];
		}
	}
}

WRITE8_MEMBER(sams_memory_expansion_device::write)
{
	int base = 0;

	if (m_access_mapper && ((offset & 0xe000)==0x4000))
	{
		m_mapper[(offset>>1)&0x000f] = data;
	}

	if (((offset & 0xe000)==0x2000) || ((offset & 0xe000)==0xa000) || ((offset & 0xe000)==0xc000) || ((offset & 0xe000)==0xe000))
	{
		if (!m_map_mode)
		{
			// transparent mode
			m_ram[offset & 0xffff] = data;
		}
		else
		{
			base = (m_mapper[(offset & 0xf000)>>12] << 12);
			m_ram[base | (offset & 0x0fff)] = data;
		}
	}
}

/*
    CRU read. None here.
*/
READ8Z_MEMBER(sams_memory_expansion_device::crureadz)
{
}

/*
    CRU write. Turns on the mapper and allows to change it.
*/
WRITE8_MEMBER(sams_memory_expansion_device::cruwrite)
{
	if ((offset & 0xff00)==SAMS_CRU_BASE)
	{
		if (VERBOSE>7) LOG("cru address %04x = %02x\n", offset&0xffff, data);

		if ((offset & 0x000e)==0) m_access_mapper = (data!=0);
		if ((offset & 0x000e)==2) m_map_mode = (data!=0);
	}
}


ROM_START( sams_card )
	ROM_REGION(0x100000, RAMREGION, 0)
	ROM_FILL(0x0000, 0x100000, 0x00)
ROM_END

void sams_memory_expansion_device::device_start()
{
	if (VERBOSE>5) LOG("SuperAMS: start\n");
	m_ram = memregion(RAMREGION)->base();
}

void sams_memory_expansion_device::device_reset()
{
	if (VERBOSE>5) LOG("SuperAMS: reset\n");
	// Resetting values
	m_map_mode = false;
	m_access_mapper = false;
	for (int i=0; i < 16; i++) m_mapper[i] = 0;
}

const rom_entry *sams_memory_expansion_device::device_rom_region() const
{
	return ROM_NAME( sams_card );
}

const device_type TI99_SAMSMEM = &device_creator<sams_memory_expansion_device>;