1 // license:LGPL-2.1+
2 // copyright-holders:Michael Zapf
3 /***************************************************************************
4 
5     Geneve "Memex" memory expansion
6     may be used together with the GenMod feature to expand the memory to the
7     full 2 MiB range.
8 
9     Michael Zapf
10     February 2011
11     February 2012: rewritten as class
12 
13 ****************************************************************************/
14 
15 #include "emu.h"
16 #include "memex.h"
17 
18 #define LOG_WARN        (1U<<1)
19 #define LOG_CONFIG      (1U<<2)
20 #define LOG_READ        (1U<<3)
21 #define LOG_WRITE       (1U<<4)
22 #define LOG_BLOCK       (1U<<5)
23 
24 #define VERBOSE ( LOG_CONFIG | LOG_WARN )
25 
26 #include "logmacro.h"
27 
28 DEFINE_DEVICE_TYPE_NS(TI99_MEMEX, bus::ti99::peb, geneve_memex_device, "ti99_memex", "Geneve memory expansion card")
29 
30 namespace bus { namespace ti99 { namespace peb {
31 
32 #define RAMREGION "ram2meg"
33 
34 enum
35 {
36 	MDIP1 = 0x01,
37 	MDIP2 = 0x02,
38 	MDIP3 = 0x04,
39 	MDIP4 = 0x08,
40 	MDIP5 = 0x10,
41 	MDIP6 = 0x20,
42 	MDIP7 = 0x40,
43 	MDIP8 = 0x80
44 };
45 
geneve_memex_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)46 geneve_memex_device::geneve_memex_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
47 	device_t(mconfig, TI99_MEMEX, tag, owner, clock),
48 	device_ti99_peribox_card_interface(mconfig, *this),
49 	m_ram(*this, RAMREGION)
50 {
51 }
52 
access_enabled(offs_t offset)53 bool geneve_memex_device::access_enabled(offs_t offset)
54 {
55 	// 1 0111 .... .... .... .... p-box address block 0xxx ... fxxx
56 	// first two bits are AME, AMD bits available on Genmod only
57 	// if AMD, AME are not available we assume AMD=0, AME=1
58 	// must be set on the Geneve board
59 	// Some traditional cards will not decode the AMx lines, so
60 	// we may have to lock out those areas
61 	int page = (offset >> 13)&0xff;
62 
63 	// All mirrors of page ba via AMD/AME are blocked.
64 	// These are 3a, 7a, ba, and fa.
65 	if ((page & 0x3f)==0x3a)
66 	{
67 		LOGMASKED(LOG_BLOCK, "memex blocks page %02x\n", page);
68 		return false;
69 	}
70 
71 	// SW2: 10xxx010   locked when SW2=off
72 	//      10111010   locked when SW2=on
73 	if ((page & 0xc7)==0x82 && ((m_switches & MDIP2)==0))
74 	{
75 		LOGMASKED(LOG_BLOCK, "memex blocks page %02x; dip2=%d\n", page,  (m_switches & MDIP2)!=0);
76 		return false;
77 	}
78 
79 	// Switch  page
80 	// SW3:    111010xx    enabled for SWx=0,blocked for SWx=1
81 	// SW4:    111011xx
82 	// SW5:    111100xx
83 	// SW6:    111101xx
84 	// SW7:    111110xx
85 	// SW8:    111111xx
86 
87 	if (page >= 0xe8 && page <= 0xff)
88 	{
89 		return ((m_switches & (4<< (((page>>2) & 0x0f)-10))) == 0);
90 	}
91 	return true;
92 }
93 
94 /*
95     Memory read. The memory is at locations 0x000000-0x1fffff. Some of these
96     regions are hidden by onboard devices of the Geneve. We must block some
97     areas which would otherwise interfere with peripheral cards.
98 
99     Note that the incomplete decoding of the standard Geneve must be
100     considered.
101 */
readz(offs_t offset,uint8_t * value)102 void geneve_memex_device::readz(offs_t offset, uint8_t *value)
103 {
104 	/* If not Genmod, add the upper two address bits 10 */
105 //  if (!m_genmod) offset |= 0x100000;
106 
107 	// The card is accessed for all addresses in the address space
108 	if (access_enabled(offset))
109 	{
110 		*value = m_ram->pointer()[offset];
111 		LOGMASKED(LOG_READ, "%06x -> %02x\n", offset, *value);
112 	}
113 }
114 
115 /*
116     Memory write
117 */
write(offs_t offset,uint8_t data)118 void geneve_memex_device::write(offs_t offset, uint8_t data)
119 {
120 	/* If not Genmod, add the upper two address bits 10 */
121 //  if (!m_genmod) offset |= 0x100000;
122 
123 	// The card is accessed for all addresses in the address space
124 	if (access_enabled(offset))
125 	{
126 		LOGMASKED(LOG_WRITE, "%06x <- %02x\n", offset, data);
127 		m_ram->pointer()[offset] = data;
128 	}
129 }
130 
131 /**************************************************************************/
132 
device_start()133 void geneve_memex_device::device_start()
134 {
135 	save_item(NAME(m_switches));
136 }
137 
device_reset()138 void geneve_memex_device::device_reset()
139 {
140 	m_switches = ioport("MEMEXDIPS")->read();
141 	LOGMASKED(LOG_CONFIG, "memex dips = %02x\n", m_switches);
142 }
143 
144 INPUT_PORTS_START( memex )
145 	PORT_START( "MEMEXDIPS" )
146 	PORT_DIPNAME( MDIP1, MDIP1, "MEMEX SW1" )
147 		PORT_DIPSETTING( 0x00, "LED half-bright for 0 WS")
148 		PORT_DIPSETTING( MDIP1, "LED full-bright")
149 	PORT_DIPNAME( MDIP2, 0x00, "MEMEX SW2" )
150 		PORT_DIPSETTING( 0x00, "Lock out all BA mirrors")
151 		PORT_DIPSETTING( MDIP2, "Lock out page BA only")
152 	PORT_DIPNAME( MDIP3, 0x00, "MEMEX SW3" )
153 		PORT_DIPSETTING( 0x00, "Enable pages E8-EB")
154 		PORT_DIPSETTING( MDIP3, "Lock out pages E8-EB")
155 	PORT_DIPNAME( MDIP4, 0x00, "MEMEX SW4" )
156 		PORT_DIPSETTING( 0x00, "Enable pages EC-EF")
157 		PORT_DIPSETTING( MDIP4, "Lock out pages EC-EF")
158 	PORT_DIPNAME( MDIP5, 0x00, "MEMEX SW5" )
159 		PORT_DIPSETTING( 0x00, "Enable pages F0-F3")
160 		PORT_DIPSETTING( MDIP5, "Lock out pages F0-F3")
161 	PORT_DIPNAME( MDIP6, 0x00, "MEMEX SW6" )
162 		PORT_DIPSETTING( 0x00, "Enable pages F4-F7")
163 		PORT_DIPSETTING( MDIP6, "Lock out pages F4-F7")
164 	PORT_DIPNAME( MDIP7, 0x00, "MEMEX SW7" )
165 		PORT_DIPSETTING( 0x00, "Enable pages F8-FB")
166 		PORT_DIPSETTING( MDIP7, "Lock out pages F8-FB")
167 	PORT_DIPNAME( MDIP8, 0x00, "MEMEX SW8" )
168 		PORT_DIPSETTING( 0x00, "Enable pages FC-FF")
169 		PORT_DIPSETTING( MDIP8, "Lock out pages FC-FF")
170 INPUT_PORTS_END
171 
device_add_mconfig(machine_config & config)172 void geneve_memex_device::device_add_mconfig(machine_config &config)
173 {
174 	RAM(config, m_ram, 0);
175 	m_ram->set_default_size("2M");
176 	m_ram->set_default_value(0);
177 }
178 
device_input_ports() const179 ioport_constructor geneve_memex_device::device_input_ports() const
180 {
181 	return INPUT_PORTS_NAME( memex );
182 }
183 
184 } } } // end namespace bus::ti99::peb
185