1 // license:GPL-2.0+
2 // copyright-holders:Peter Trauner
3 /******************************************************************************
4  PeT mess@utanet.at 2007, 2014
5  Peter Wilhelmsen peter.wilhelmsen@gmail.com
6  Morten Shearman Kirkegaard morten+gamate@afdelingp.dk
7  Juan Felix Mateos vectrex@hackermesh.org
8 
9  A complete hardware description can be found at
10  http://blog.kevtris.org/blogfiles/Gamate%20Inside.txt
11 
12  ******************************************************************************/
13 
14 #include "emu.h"
15 #include "sound/ay8910.h"
16 #include "bus/gamate/slot.h"
17 #include "cpu/m6502/m6502.h"
18 #include "video/gamate.h"
19 #include "screen.h"
20 #include "softlist.h"
21 #include "speaker.h"
22 
23 class gamate_state : public driver_device
24 {
25 public:
gamate_state(const machine_config & mconfig,device_type type,const char * tag)26 	gamate_state(const machine_config &mconfig, device_type type, const char *tag)
27 		: driver_device(mconfig, type, tag)
28 		, m_maincpu(*this, "maincpu")
29 		, m_ay(*this, "ay8910")
30 		, m_cartslot(*this, "cartslot")
31 		, m_io_joy(*this, "JOY")
32 		, m_bios(*this, "bios")
33 		, m_ram(*this, "ram")
34 	{ }
35 
36 	void gamate(machine_config &config);
37 
38 	void init_gamate();
39 
40 private:
41 	uint8_t card_available_check();
42 	uint8_t card_available_set();
43 	void card_reset(uint8_t data);
44 
45 	uint8_t gamate_nmi_r();
46 	void sound_w(offs_t offset, uint8_t data);
47 	uint8_t sound_r(offs_t offset);
48 	void write_cart(offs_t offset, uint8_t data);
49 	uint8_t read_cart(offs_t offset);
50 
51 	TIMER_CALLBACK_MEMBER(gamate_timer);
52 	TIMER_CALLBACK_MEMBER(gamate_timer2);
53 
54 	void gamate_mem(address_map &map);
55 
56 	virtual void machine_start() override;
57 	virtual void machine_reset() override;
58 
59 	int m_card_available;
60 
61 	required_device<cpu_device> m_maincpu;
62 	required_device<ay8910_device> m_ay;
63 	required_device<gamate_cart_slot_device> m_cartslot;
64 	required_ioport m_io_joy;
65 	required_shared_ptr<uint8_t> m_bios;
66 	required_shared_ptr<uint8_t> m_ram;
67 	emu_timer *timer1;
68 	emu_timer *timer2;
69 };
70 
71 /* todo: what are these really, do they go to the cartridge slot? */
card_available_check()72 uint8_t gamate_state::card_available_check()
73 {
74 	// bits 0 and 1 checked
75 	return m_card_available ? 3: 1;
76 }
77 
card_reset(uint8_t data)78 void gamate_state::card_reset(uint8_t data)
79 {
80 	// might reset the card / protection?
81 }
82 
card_available_set()83 uint8_t gamate_state::card_available_set()
84 {
85 	if (!machine().side_effects_disabled())
86 		m_card_available = 1;
87 	return 0;
88 }
89 
90 // serial connection
gamate_nmi_r()91 uint8_t gamate_state::gamate_nmi_r()
92 {
93 	uint8_t data=0;
94 	logerror("nmi/4800 read\n");
95 	return data;
96 }
97 
sound_r(offs_t offset)98 uint8_t gamate_state::sound_r(offs_t offset)
99 {
100 	m_ay->address_w(offset);
101 	return m_ay->data_r();
102 }
103 
sound_w(offs_t offset,uint8_t data)104 void gamate_state::sound_w(offs_t offset, uint8_t data)
105 {
106 	m_ay->address_w(offset);
107 	m_ay->data_w(data);
108 }
109 
write_cart(offs_t offset,uint8_t data)110 void gamate_state::write_cart(offs_t offset, uint8_t data)
111 {
112 	m_cartslot->write_cart(offset, data);
113 }
114 
read_cart(offs_t offset)115 uint8_t gamate_state::read_cart(offs_t offset)
116 {
117 	return m_cartslot->read_cart(offset);
118 }
119 
gamate_mem(address_map & map)120 void gamate_state::gamate_mem(address_map &map)
121 {
122 	map(0x0000, 0x03ff).mirror(0x1c00).ram().share("ram");
123 	map(0x4000, 0x400f).mirror(0x03f0).rw(FUNC(gamate_state::sound_r), FUNC(gamate_state::sound_w));
124 	map(0x4400, 0x4400).mirror(0x03ff).portr("JOY");
125 	map(0x4800, 0x4800).mirror(0x03ff).r(FUNC(gamate_state::gamate_nmi_r));
126 	map(0x5000, 0x5007).mirror(0x03f8).m("video", FUNC(gamate_video_device::regs_map));
127 	map(0x5800, 0x5800).r(FUNC(gamate_state::card_available_set));
128 	map(0x5900, 0x5900).w(FUNC(gamate_state::card_reset));
129 	map(0x5a00, 0x5a00).r(FUNC(gamate_state::card_available_check));
130 	map(0x6000, 0xdfff).rw(FUNC(gamate_state::read_cart), FUNC(gamate_state::write_cart));
131 
132 	map(0xe000, 0xefff).mirror(0x1000).rom().share("bios").region("maincpu", 0);
133 }
134 
135 
136 static INPUT_PORTS_START( gamate )
137 	PORT_START("JOY")
138 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP)
139 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
140 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
141 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
142 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("A")
143 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("B")
144 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START) PORT_NAME("Start/Pause")
145 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SELECT) PORT_NAME("Select")
146 INPUT_PORTS_END
147 
init_gamate()148 void gamate_state::init_gamate()
149 {
150 	timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gamate_state::gamate_timer),this));
151 	timer2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gamate_state::gamate_timer2),this));
152 }
153 
machine_start()154 void gamate_state::machine_start()
155 {
156 	memset(m_ram, 0xff, m_ram.bytes());  /* memory seems to contain 0xff at power up */
157 	timer2->enable(true);
158 	timer2->reset(m_maincpu->cycles_to_attotime(1000));
159 
160 	save_item(NAME(m_card_available));
161 }
162 
machine_reset()163 void gamate_state::machine_reset()
164 {
165 	m_card_available = 0;
166 }
167 
TIMER_CALLBACK_MEMBER(gamate_state::gamate_timer)168 TIMER_CALLBACK_MEMBER(gamate_state::gamate_timer)
169 {
170 	m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE);
171 	timer1->enable(false);
172 }
173 
TIMER_CALLBACK_MEMBER(gamate_state::gamate_timer2)174 TIMER_CALLBACK_MEMBER(gamate_state::gamate_timer2)
175 {
176 	m_maincpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
177 	timer1->enable(true);
178 	timer1->reset(m_maincpu->cycles_to_attotime(10/* cycles short enought to clear irq line early enough*/));
179 	timer2->enable(true);
180 	timer2->reset(m_maincpu->cycles_to_attotime(32768/2));
181 }
182 
gamate(machine_config & config)183 void gamate_state::gamate(machine_config &config)
184 {
185 	M6502(config, m_maincpu, 4433000/2); // NCR 65CX02
186 	m_maincpu->set_addrmap(AS_PROGRAM, &gamate_state::gamate_mem);
187 
188 	GAMATE_VIDEO(config, "video", 0);
189 
190 	/* sound hardware */
191 	SPEAKER(config, "lspeaker").front_left(); // Stereo headphone output
192 	SPEAKER(config, "rspeaker").front_right();
193 	AY8910(config, m_ay, 4433000 / 4); // AY compatible, no actual AY chip present
194 	m_ay->add_route(0, "lspeaker", 0.5);
195 	m_ay->add_route(1, "rspeaker", 0.5);
196 	m_ay->add_route(2, "lspeaker", 0.25);
197 	m_ay->add_route(2, "rspeaker", 0.25);
198 
199 	GAMATE_CART_SLOT(config, m_cartslot, gamate_cart, nullptr);
200 
201 	SOFTWARE_LIST(config, "cart_list").set_original("gamate");
202 }
203 
204 
205 /* ROM notes:
206 gamate_bios_umc.bin is called UMC or NCR ICASC00002
207 gamate_bios_bit.bin is called BIT ICASC00001
208 So basically the UMC UA6588F and NCR 81489 CPU's contains the ICASC00002 bios
209 while the BIT branded CPU contains the ICASC00001 bios.
210 They're compatible, but for completeness its nice to have both.
211 Note i have 8 gamate consoles (dated 1990 though 1993) which has the gamate_bios_umc.bin in it
212 and only 1 dated 1994 which has the gamate_bios_bit.bin in it, so the former seems much more common.
213 We dumped the BIOS from all our Gamate consoles, and all except one were
214 identical (SHA1:ea449dc607601f9a68d855ad6ab53800d2e99297):
215 Gamate_BIOS_9027__9002008__UMC_UA6588F_9027S_606700.bin
216 Gamate_BIOS_9027__9142222__UMC_UA6588F_9027S_606700.bin
217 Gamate_BIOS_9027__unknown__UMC_UA6588F_9027S_606690.bin
218 Gamate_BIOS_9031__9009719__NCR_81489_BIT_WS39323F_ICASC00002_F841400_R9031.bin
219 Gamate_BIOS_9038__9145157__NCR_81489_BIT_WS39323F_ICASC00002_F842247_N9038.bin
220 One console, with an unknown serial number, has an updated BIOS
221 (SHA1:4e9dfbfe916ca485530ef4221593ab68738e2217):
222 This console appears to have been manufactured in 1994, based on the date markings on the RAM chips,
223 as well as the PCB.
224 */
225 ROM_START(gamate)
226 	ROM_REGION(0x1000,"maincpu", 0)
227 	ROM_SYSTEM_BIOS(0, "default", "DEFAULT")
228 	ROMX_LOAD("gamate_bios_umc.bin", 0x0000, 0x1000, CRC(07090415) SHA1(ea449dc607601f9a68d855ad6ab53800d2e99297), ROM_BIOS(0))
229 	ROM_SYSTEM_BIOS(1, "newer", "NEWER")
230 	ROMX_LOAD("gamate_bios_bit.bin", 0x0000, 0x1000, CRC(03a5f3a7) SHA1(4e9dfbfe916ca485530ef4221593ab68738e2217), ROM_BIOS(1))
231 ROM_END
232 
233 
234 //    YEAR  NAME    PARENT  COMPAT  MACHINE  INPUT   CLASS         INIT         COMPANY     FULLNAME  FLAGS
235 CONS( 1990, gamate, 0,      0,      gamate,  gamate, gamate_state, init_gamate, "Bit Corp", "Gamate", 0 )
236