1 // license:BSD-3-Clause
2 // copyright-holders:Tomasz Slanina
3 /*********************************************
4  Quiz Olympic (c)1985 Seoul Coin Corp.
5 
6  driver by Tomasz Slanina
7 
8  ROMs contains strings:
9 
10     QUIZ OLYMPIC Ver 1.0
11     PROGRAMMED BY  K.ISHIDA
12     AT 1984.10.26
13     TAITO CORP.
14     KUMAGAYA-TSC
15 
16 
17 --
18 
19 Z80 @ 4.0MHz [8/2]
20 AY-3-8910 @ 1.3423MHz [21.47727/16]
21 1x 2016 RAM
22 4x 4416 RAM
23 Xtals 8MHz, 21.47727MHz
24 1x 82S123 PROM
25 
26 **********************************************/
27 
28 #include "emu.h"
29 #include "cpu/z80/z80.h"
30 #include "sound/ay8910.h"
31 #include "emupal.h"
32 #include "screen.h"
33 #include "speaker.h"
34 
35 
36 class quizo_state : public driver_device
37 {
38 public:
quizo_state(const machine_config & mconfig,device_type type,const char * tag)39 	quizo_state(const machine_config &mconfig, device_type type, const char *tag)
40 		: driver_device(mconfig, type, tag)
41 		, m_maincpu(*this, "maincpu")
42 		, m_palette(*this, "palette")
43 		, m_rombank(*this, "rom")
44 		, m_vrambank(*this, "vram")
45 	{ }
46 
47 	void quizo(machine_config &config);
48 
49 protected:
50 	virtual void machine_start() override;
51 
52 private:
53 	required_device<cpu_device> m_maincpu;
54 	required_device<palette_device> m_palette;
55 	required_memory_bank m_rombank;
56 	required_memory_bank m_vrambank;
57 
58 	std::unique_ptr<uint8_t[]> m_vram;
59 
60 	void rombank_w(uint8_t data);
61 	void vrambank_w(uint8_t data);
62 
63 	void quizo_palette(palette_device &palette) const;
64 
65 	uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
66 
67 	void memmap(address_map &map);
68 	void portmap(address_map &map);
69 };
70 
quizo_palette(palette_device & palette) const71 void quizo_state::quizo_palette(palette_device &palette) const
72 {
73 	uint8_t const *const color_prom = memregion("proms")->base();
74 	for (int i = 0; i < 16; i++)
75 	{
76 		int bit0, bit1, bit2;
77 
78 		bit0 = 0;
79 		bit1 = BIT(color_prom[i], 0);
80 		bit2 = BIT(color_prom[i], 1);
81 		int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
82 
83 		bit0 = BIT(color_prom[i], 2);
84 		bit1 = BIT(color_prom[i], 3);
85 		bit2 = BIT(color_prom[i], 4);
86 		int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
87 
88 		bit0 = BIT(color_prom[i], 5);
89 		bit1 = BIT(color_prom[i], 6);
90 		bit2 = BIT(color_prom[i], 7);
91 		int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
92 
93 		palette.set_pen_color(i, rgb_t(r, g, b));
94 	}
95 }
96 
screen_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)97 uint32_t quizo_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
98 {
99 	for (int y = 0; y < 200; y++)
100 	{
101 		for (int x = 0; x < 80; x++)
102 		{
103 			uint8_t data1 = m_vram[y * 80 + x];
104 			uint8_t data2 = m_vram[y * 80 + x + 0x4000];
105 
106 			// draw 4 pixels
107 			bitmap.pix(y, x * 4 + 0) = m_palette->pen((BIT(data2, 7) << 3) | (BIT(data2, 3) << 2) | (BIT(data1, 7) << 1) | BIT(data1, 3));
108 			bitmap.pix(y, x * 4 + 1) = m_palette->pen((BIT(data2, 6) << 3) | (BIT(data2, 2) << 2) | (BIT(data1, 6) << 1) | BIT(data1, 2));
109 			bitmap.pix(y, x * 4 + 2) = m_palette->pen((BIT(data2, 5) << 3) | (BIT(data2, 1) << 2) | (BIT(data1, 5) << 1) | BIT(data1, 1));
110 			bitmap.pix(y, x * 4 + 3) = m_palette->pen((BIT(data2, 4) << 3) | (BIT(data2, 0) << 2) | (BIT(data1, 4) << 1) | BIT(data1, 0));
111 		}
112 	}
113 
114 	return 0;
115 }
116 
rombank_w(uint8_t data)117 void quizo_state::rombank_w(uint8_t data)
118 {
119 	m_rombank->set_entry(data & 0x0f);
120 }
121 
vrambank_w(uint8_t data)122 void quizo_state::vrambank_w(uint8_t data)
123 {
124 	m_vrambank->set_entry(BIT(data, 3));
125 }
126 
machine_start()127 void quizo_state::machine_start()
128 {
129 	m_rombank->configure_entries(0, 16, memregion("user1")->base(), 0x4000);
130 
131 	m_vram = std::make_unique<uint8_t[]>(0x8000);
132 	m_vrambank->configure_entries(0, 2, &m_vram[0], 0x4000);
133 
134 	save_pointer(NAME(m_vram), 0x8000);
135 }
136 
memmap(address_map & map)137 void quizo_state::memmap(address_map &map)
138 {
139 	map(0x0000, 0x3fff).rom();
140 	map(0x4000, 0x47ff).ram();
141 	map(0x8000, 0xbfff).bankr("rom");
142 	map(0xc000, 0xffff).bankw("vram");
143 }
144 
portmap(address_map & map)145 void quizo_state::portmap(address_map &map)
146 {
147 	map.global_mask(0xff);
148 	map(0x00, 0x00).portr("IN0");
149 	map(0x10, 0x10).portr("IN1");
150 	map(0x40, 0x40).portr("IN2");
151 	map(0x50, 0x51).w("aysnd", FUNC(ay8910_device::address_data_w));
152 	map(0x60, 0x60).w(FUNC(quizo_state::rombank_w));
153 	map(0x70, 0x70).w(FUNC(quizo_state::vrambank_w));
154 }
155 
156 static INPUT_PORTS_START( quizo )
157 	PORT_START("IN0")
158 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
159 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 )
160 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SERVICE1 )
161 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_TILT )
162 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 )
DEF_STR(Unknown)163 	PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown) )
164 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
165 	PORT_DIPSETTING(    0x20, DEF_STR( On ) )
166 	PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown) ) // enable this and IN2 bit 5 to get a message
167 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
168 	PORT_DIPSETTING(    0x40, DEF_STR( On ) )
169 	PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown) )
170 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
171 	PORT_DIPSETTING(    0x80, DEF_STR( On ) )
172 
173 	PORT_START("IN1")
174 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 )
175 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 )
176 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 )
177 	PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNUSED )
178 
179 	PORT_START("IN2")
180 	PORT_DIPNAME( 0x01, 0x00, DEF_STR( Unknown) )
181 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
182 	PORT_DIPSETTING(    0x01, DEF_STR( On ) )
183 	PORT_DIPNAME( 0x02, 0x00, "Timer" )
184 	PORT_DIPSETTING(    0x00, "Slow" ) // 7 seconds
185 	PORT_DIPSETTING(    0x02, "Fast" ) // 5 seconds
186 	PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown) )
187 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
188 	PORT_DIPSETTING(    0x04, DEF_STR( On ) )
189 	PORT_DIPNAME( 0x08, 0x00, "Test Mode" ) // test mode + timer freeze during game
190 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
191 	PORT_DIPSETTING(    0x08, DEF_STR( On ) )
192 	PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown) )
193 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
194 	PORT_DIPSETTING(    0x10, DEF_STR( On ) )
195 	PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown) ) // connected to IN0 bit 6
196 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
197 	PORT_DIPSETTING(    0x20, DEF_STR( On ) )
198 	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Coinage ) )
199 	PORT_DIPSETTING(    0x00, "A 2 Coin/1 Credit, B 1 Coin/1 Credit" )
200 	PORT_DIPSETTING(    0x40, "A 1 Coin/1 Credit, B 1 Coin/2 Credit" )
201 	PORT_DIPNAME( 0x80, 0x00, DEF_STR( Coin_B ) )
202 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
203 	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
204 INPUT_PORTS_END
205 
206 void quizo_state::quizo(machine_config &config)
207 {
208 	Z80(config, m_maincpu, 8_MHz_XTAL / 2);
209 	m_maincpu->set_addrmap(AS_PROGRAM, &quizo_state::memmap);
210 	m_maincpu->set_addrmap(AS_IO, &quizo_state::portmap);
211 	m_maincpu->set_vblank_int("screen", FUNC(quizo_state::irq0_line_hold));
212 
213 	// video hardware
214 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
215 	screen.set_refresh_hz(60);
216 	screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
217 	screen.set_size(320, 200);
218 	screen.set_visarea(0*8, 320-1, 0*8, 200-1);
219 	screen.set_screen_update(FUNC(quizo_state::screen_update));
220 
221 	PALETTE(config, m_palette, FUNC(quizo_state::quizo_palette), 16);
222 
223 	// sound hardware
224 	SPEAKER(config, "mono").front_center();
225 	AY8910(config, "aysnd", 21.477272_MHz_XTAL / 16).add_route(ALL_OUTPUTS, "mono", 1.0);
226 }
227 
228 
229 ROM_START( quizo )
230 	ROM_REGION(0x4000, "maincpu", 0)
231 	ROM_LOAD("rom1", 0x0000, 0x4000, CRC(6731735f) SHA1(7dbf48f833c7b7cde77df2a10781e5a8b6ae0533))
232 	ROM_CONTINUE(    0x0000, 0x4000)
233 
234 	ROM_REGION(0x40000, "user1", 0)
235 	ROM_LOAD("rom3", 0x00000, 0x8000, CRC(d344f97e) SHA1(3d669a56f084f2a7a50d7d211b84a50d35de66ac))
236 	ROM_LOAD("rom4", 0x18000, 0x8000, CRC(ab1eb174) SHA1(7d7a935aa7196a814c15f13444b88e770678b672))
237 	ROM_LOAD("rom2", 0x20000, 0x8000, CRC(a700eb30) SHA1(7800b3d2b7992c67c91cfb7e02c7cfc313b0ed5d))
238 
239 	ROM_REGION(0x20, "proms", 0)
240 	ROM_LOAD("82s123", 0x00, 0x20, CRC(c3f15914) SHA1(19fd8e6f2a1256ae51c500a3bf1d7358810ef97e))
241 ROM_END
242 
243 ROM_START( quizoa )
244 	ROM_REGION(0x4000, "maincpu", 0)
245 	ROM_LOAD("7.bin", 0x0000, 0x4000, CRC(1579ae31) SHA1(b23539413d108223001a9fe827ea151d20682b7b))
246 
247 	ROM_REGION(0x40000, "user1", 0)
248 	ROM_LOAD("4.bin", 0x00000, 0x4000, CRC(a977bd3a) SHA1(22f1158253a31cf5513eed3537a6096b993b0919))
249 	ROM_LOAD("3.bin", 0x04000, 0x4000, CRC(4411bcff) SHA1(2f6692e082b335c3af8b92108f757d333599dd29))
250 	ROM_LOAD("2.bin", 0x08000, 0x4000, CRC(4a0df776) SHA1(4a7dc2347b33843c0a6bb497be56ccae1af1dae0))
251 	ROM_LOAD("1.bin", 0x1c000, 0x4000, CRC(d9566c1a) SHA1(2495c071d077e5a359c2d7541d8b7c175b398b56))
252 	ROM_LOAD("6.bin", 0x20000, 0x4000, CRC(f00f6356) SHA1(f306ec26ddbb503214e266cc9b74304af86bdbc6))
253 	ROM_LOAD("5.bin", 0x24000, 0x4000, CRC(39e577e3) SHA1(430d9fe916dfeecdb94c23be89f79a6408ff444e))
254 
255 	ROM_REGION(0x20, "proms", 0)
256 	ROM_LOAD("82s123", 0x00, 0x20, CRC(c3f15914) SHA1(19fd8e6f2a1256ae51c500a3bf1d7358810ef97e))
257 ROM_END
258 
259 GAME( 1985, quizo,  0,       quizo,  quizo, quizo_state, empty_init, ROT0, "Seoul Coin Corp.", "Quiz Olympic (set 1)", MACHINE_SUPPORTS_SAVE )
260 GAME( 1985, quizoa, quizo,   quizo,  quizo, quizo_state, empty_init, ROT0, "Seoul Coin Corp.", "Quiz Olympic (set 2)", MACHINE_SUPPORTS_SAVE )
261