1 // license:BSD-3-Clause
2 // copyright-holders:R. Belmont, Sergey Svishchev
3 /***************************************************************************
4
5 Super Games ][
6
7 An arcade board designed to run modified games from Apple ][.
8 Most of Apple hardware is missing, keyboard port is reused for joysticks.
9
10 Only one game is known (a Mario Bros. hack/translation patch).
11
12 Info: http://agatcomp.ru/Pravetz/SuperGames.shtml
13
14 To do
15 - verify palette, pixel and cpu clocks
16
17 ************************************************************************/
18
19 #include "emu.h"
20 #include "video/apple2.h"
21
22 #include "cpu/m6502/m6502.h"
23
24 #include "machine/74259.h"
25 #include "machine/apple2common.h"
26 #include "machine/ram.h"
27 #include "machine/timer.h"
28
29 #include "sound/spkrdev.h"
30
31 #include "screen.h"
32 #include "speaker.h"
33
34
35 #define A2_CPU_TAG "maincpu"
36 #define A2_VIDEO_TAG "a2video"
37
38 class superga2_state : public driver_device
39 {
40 public:
superga2_state(const machine_config & mconfig,device_type type,const char * tag)41 superga2_state(const machine_config &mconfig, device_type type, const char *tag) :
42 driver_device(mconfig, type, tag),
43 m_maincpu(*this, A2_CPU_TAG),
44 m_screen(*this, "screen"),
45 m_ram(*this, RAM_TAG),
46 m_video(*this, A2_VIDEO_TAG),
47 m_a2common(*this, "a2common"),
48 m_speaker(*this, "speaker"),
49 m_softlatch(*this, "softlatch")
50 { }
51
imperfect_features()52 static constexpr feature_type imperfect_features() { return feature::PALETTE | feature::CONTROLS; }
53
54 required_device<cpu_device> m_maincpu;
55 required_device<screen_device> m_screen;
56 required_device<ram_device> m_ram;
57 required_device<a2_video_device> m_video;
58 required_device<apple2_common_device> m_a2common;
59 required_device<speaker_sound_device> m_speaker;
60 required_device<addressable_latch_device> m_softlatch;
61
62 virtual void machine_start() override;
63 virtual void machine_reset() override;
64
65 uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
66
67 uint8_t ram_r(offs_t offset);
68 void ram_w(offs_t offset, uint8_t data);
69 uint8_t speaker_toggle_r();
70 void speaker_toggle_w(uint8_t data);
71 uint8_t switches_r(offs_t offset);
72 uint8_t reset_r(offs_t offset);
73
74 void kuzmich(machine_config &config);
75 void kuzmich_map(address_map &map);
76
77 private:
78 int m_speaker_state;
79
80 uint8_t *m_ram_ptr;
81 int m_ram_size;
82
83 uint8_t read_floatingbus();
84 };
85
86 /***************************************************************************
87 START/RESET
88 ***************************************************************************/
89
machine_start()90 void superga2_state::machine_start()
91 {
92 m_ram_ptr = m_ram->pointer();
93 m_ram_size = m_ram->size();
94 m_speaker_state = 0;
95 m_speaker->level_w(m_speaker_state);
96
97 // setup save states
98 save_item(NAME(m_speaker_state));
99
100 // setup video pointers
101 m_video->m_ram_ptr = m_ram_ptr;
102 m_video->m_aux_ptr = m_ram_ptr;
103 m_video->m_char_ptr = memregion("gfx1")->base();
104 m_video->m_char_size = memregion("gfx1")->bytes();
105 m_video->m_sysconfig = 0;
106 }
107
machine_reset()108 void superga2_state::machine_reset()
109 {
110 uint8_t *user1 = memregion("maincpu")->base();
111
112 memcpy(&m_ram_ptr[0x1100], user1, 0x8000);
113 }
114
115 /***************************************************************************
116 VIDEO
117 ***************************************************************************/
118
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)119 uint32_t superga2_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
120 {
121 m_video->hgr_update(screen, bitmap, cliprect, 0, 191);
122
123 return 0;
124 }
125
126 /***************************************************************************
127 I/O
128 ***************************************************************************/
129
speaker_toggle_r()130 uint8_t superga2_state::speaker_toggle_r()
131 {
132 if (!machine().side_effects_disabled())
133 speaker_toggle_w(0);
134 return read_floatingbus();
135 }
136
speaker_toggle_w(uint8_t data)137 void superga2_state::speaker_toggle_w(uint8_t data)
138 {
139 m_speaker_state ^= 1;
140 m_speaker->level_w(m_speaker_state);
141 }
142
switches_r(offs_t offset)143 uint8_t superga2_state::switches_r(offs_t offset)
144 {
145 if (!machine().side_effects_disabled())
146 m_softlatch->write_bit((offset & 0x0e) >> 1, offset & 0x01);
147 return read_floatingbus();
148 }
149
reset_r(offs_t offset)150 uint8_t superga2_state::reset_r(offs_t offset)
151 {
152 switch (offset)
153 {
154 case 0: case 2: return 0x00; break;
155 case 1: case 3: return 0x11; break;
156 }
157 return 0xff;
158 }
159
read_floatingbus()160 uint8_t superga2_state::read_floatingbus()
161 {
162 return 0xff;
163 }
164
165 /***************************************************************************
166 ADDRESS MAP
167 ***************************************************************************/
168
ram_r(offs_t offset)169 uint8_t superga2_state::ram_r(offs_t offset)
170 {
171 if (offset < m_ram_size)
172 {
173 return m_ram_ptr[offset];
174 }
175
176 return 0xff;
177 }
178
ram_w(offs_t offset,uint8_t data)179 void superga2_state::ram_w(offs_t offset, uint8_t data)
180 {
181 if (offset < m_ram_size)
182 {
183 m_ram_ptr[offset] = data;
184 }
185 }
186
kuzmich_map(address_map & map)187 void superga2_state::kuzmich_map(address_map &map)
188 {
189 map(0x0000, 0xbfff).rw(FUNC(superga2_state::ram_r), FUNC(superga2_state::ram_w));
190 map(0xc000, 0xc000).mirror(0xf).portr("P1").nopw();
191 map(0xc030, 0xc030).mirror(0xf).rw(FUNC(superga2_state::speaker_toggle_r), FUNC(superga2_state::speaker_toggle_w));
192 map(0xc050, 0xc05f).r(FUNC(superga2_state::switches_r)).w(m_softlatch, FUNC(addressable_latch_device::write_a0));
193 map(0xfffc, 0xffff).r(FUNC(superga2_state::reset_r));
194 }
195
196 /***************************************************************************
197 INPUT PORTS
198 ***************************************************************************/
199
200 static INPUT_PORTS_START( kuzmich )
201 PORT_START("P1")
202 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
203 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
204 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
205 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
206 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
207 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
208 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
209 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
210 INPUT_PORTS_END
211
kuzmich(machine_config & config)212 void superga2_state::kuzmich(machine_config &config)
213 {
214 /* basic machine hardware */
215 M6502(config, m_maincpu, 1021800);
216 m_maincpu->set_addrmap(AS_PROGRAM, &superga2_state::kuzmich_map);
217
218 APPLE2_VIDEO(config, m_video, XTAL(14'318'181)).set_screen(m_screen);
219 APPLE2_COMMON(config, m_a2common, XTAL(14'318'181));
220
221 SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
222 m_screen->set_raw(1021800*14, (65*7)*2, 0, (40*7)*2, 262, 0, 192);
223 m_screen->set_screen_update(FUNC(superga2_state::screen_update));
224 m_screen->set_palette(m_video);
225
226 /* sound hardware */
227 SPEAKER(config, "mono").front_center();
228 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 1.00);
229
230 /* soft switches */
231 F9334(config, m_softlatch); // F14 (labeled 74LS259 on some boards and in the Apple ][ Reference Manual)
232 m_softlatch->q_out_cb<0>().set(m_video, FUNC(a2_video_device::txt_w));
233 m_softlatch->q_out_cb<1>().set(m_video, FUNC(a2_video_device::mix_w));
234 m_softlatch->q_out_cb<2>().set(m_video, FUNC(a2_video_device::scr_w));
235 m_softlatch->q_out_cb<3>().set(m_video, FUNC(a2_video_device::res_w));
236
237 RAM(config, RAM_TAG).set_default_size("48K").set_default_value(0x00);
238 }
239
240 /***************************************************************************
241
242 Game driver(s)
243
244 ***************************************************************************/
245
246 ROM_START(kuzmich)
247 ROM_REGION(0x0800,"gfx1",0)
248 ROM_FILL(0, 0x800, 0)
249 ROM_REGION(0x8000,"maincpu",0)
250 ROM_LOAD("ke.bin", 0x0000, 0x8000, CRC(102d246b) SHA1(492dcdf0cc31190a97057a69010e2c9c23b6e59d))
251 ROM_END
252
253 // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME
254 COMP( 199?, kuzmich, 0, 0, kuzmich, kuzmich, superga2_state, empty_init, "Nippel", "Kuzmich-Egorych", MACHINE_SUPPORTS_SAVE )
255