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