11// license:BSD-3-Clause
2- // copyright-holders:Tomasz Slanina, David Haywood
2+ // copyright-holders: Tomasz Slanina, David Haywood
3+
34/* **************************************************************************
45
56Koi Koi Part 2
@@ -9,7 +10,8 @@ driver by
910 David Haywood
1011
1112TODO:
12- - map missing inputs (temp mapped to z-x-left shift)
13+ - map missing inputs for koikoip2 (temp mapped to z-x-left shift)
14+ - koikoi needs different inputs implementation (possibly just needs it's own input_tab[])
1315- is there (still..) some kind of protection ? timers looks weird (2nd player timer is frozen) (this seems fixed now -AS)
1416- colors (afaik color(?) prom outputs are connected to one of pals), Missing color prom apparently. Reference: https://www.youtube.com/watch?v=inc4tyuh4qk
1517
@@ -40,8 +42,10 @@ to prevent disabling inputs.
4042***************************************************************************/
4143
4244#include " emu.h"
45+
4346#include " cpu/z80/z80.h"
4447#include " sound/ay8910.h"
48+
4549#include " emupal.h"
4650#include " screen.h"
4751#include " speaker.h"
@@ -50,49 +54,52 @@ to prevent disabling inputs.
5054
5155namespace {
5256
53- #define KOIKOI_CRYSTAL 15468000
54-
5557static constexpr int input_tab[] = { 0x22 , 0x64 , 0x44 , 0x68 , 0x30 , 0x50 , 0x70 , 0x48 , 0x28 , 0x21 , 0x41 , 0x82 , 0x81 , 0x42 };
5658
5759class koikoi_state : public driver_device
5860{
5961public:
6062 koikoi_state (const machine_config &mconfig, device_type type, const char *tag) :
6163 driver_device (mconfig, type, tag),
62- m_videoram (*this , " videoram" ),
6364 m_maincpu (*this , " maincpu" ),
64- m_gfxdecode (*this , " gfxdecode" )
65+ m_gfxdecode (*this , " gfxdecode" ),
66+ m_videoram (*this , " videoram" ),
67+ m_ioram (*this , " ioram" , 0x08 , ENDIANNESS_LITTLE),
68+ m_in (*this , " IN%u" , 0 )
6569 { }
6670
67- void koikoi (machine_config &config);
71+ void koikoi (machine_config &config) ATTR_COLD;
72+
73+ protected:
74+ virtual void machine_start () override ATTR_COLD;
75+ virtual void machine_reset () override ATTR_COLD;
76+ virtual void video_start () override ATTR_COLD;
6877
6978private:
70- /* memory pointers */
79+ required_device<cpu_device> m_maincpu;
80+ required_device<gfxdecode_device> m_gfxdecode;
81+
7182 required_shared_ptr<uint8_t > m_videoram;
83+ memory_share_creator<uint8_t > m_ioram;
84+
85+ required_ioport_array<2 > m_in;
86+
87+ tilemap_t *m_tmap = nullptr ;
7288
73- /* video-related */
74- tilemap_t *m_tmap = nullptr ;
89+ int8_t m_inputcnt = 0 ;
90+ uint8_t m_inputval = 0 ;
91+ uint8_t m_inputlen = 0 ;
7592
76- /* misc */
77- int m_inputcnt = 0 ;
78- int m_inputval = 0 ;
79- int m_inputlen = 0 ;
80- int m_ioram[8 ]{};
8193 void vram_w (offs_t offset, uint8_t data);
8294 uint8_t io_r (offs_t offset);
8395 void io_w (offs_t offset, uint8_t data);
8496 uint8_t input_r ();
8597 void unknown_w (uint8_t data);
8698 TILE_GET_INFO_MEMBER (get_tile_info);
87- virtual void machine_start () override ATTR_COLD;
88- virtual void machine_reset () override ATTR_COLD;
89- virtual void video_start () override ATTR_COLD;
90- void koikoi_palette (palette_device &palette) const ;
91- uint32_t screen_update_koikoi (screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
92- required_device<cpu_device> m_maincpu;
93- required_device<gfxdecode_device> m_gfxdecode;
94- void koikoi_io_map (address_map &map) ATTR_COLD;
95- void koikoi_map (address_map &map) ATTR_COLD;
99+ void palette_init (palette_device &palette) const ATTR_COLD;
100+ uint32_t screen_update (screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
101+ void io_map (address_map &map) ATTR_COLD;
102+ void program_map (address_map &map) ATTR_COLD;
96103};
97104
98105
@@ -104,14 +111,14 @@ class koikoi_state : public driver_device
104111
105112TILE_GET_INFO_MEMBER (koikoi_state::get_tile_info)
106113{
107- int code = m_videoram[tile_index] | ((m_videoram[tile_index + 0x400 ] & 0x40 ) << 2 );
108- int color = (m_videoram[tile_index + 0x400 ] & 0x1f );
109- int flip = (m_videoram[tile_index + 0x400 ] & 0x80 ) ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0 ;
114+ int const code = m_videoram[tile_index] | ((m_videoram[tile_index + 0x400 ] & 0x40 ) << 2 );
115+ int const color = (m_videoram[tile_index + 0x400 ] & 0x1f );
116+ int const flip = (m_videoram[tile_index + 0x400 ] & 0x80 ) ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0 ;
110117
111118 tileinfo.set (0 , code, color, flip);
112119}
113120
114- void koikoi_state::koikoi_palette (palette_device &palette) const
121+ void koikoi_state::palette_init (palette_device &palette) const
115122{
116123 uint8_t const *color_prom = memregion (" proms" )->base ();
117124
@@ -157,7 +164,7 @@ void koikoi_state::video_start()
157164 m_tmap = &machine ().tilemap ().create (*m_gfxdecode, tilemap_get_info_delegate (*this , FUNC (koikoi_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8 , 8 , 32 , 32 );
158165}
159166
160- uint32_t koikoi_state::screen_update_koikoi (screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
167+ uint32_t koikoi_state::screen_update (screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
161168{
162169 m_tmap->draw (screen, bitmap, cliprect, 0 , 0 );
163170 return 0 ;
@@ -182,8 +189,8 @@ uint8_t koikoi_state::input_r()
182189
183190 if (!m_inputcnt)
184191 {
185- int key = ioport ( " IN1 " ) ->read ();
186- int keyval = 0 ; // we must return 0 (0x2 in 2nd read) to clear 4 bit at $6600 and allow next read
192+ int key = m_in[ 1 ] ->read ();
193+ int keyval = 0 ; // we must return 0 (0x2 in 2nd read) to clear 4 bit at $6600 and allow next read
187194
188195 if (key)
189196 {
@@ -198,36 +205,36 @@ uint8_t koikoi_state::input_r()
198205 m_inputlen = input_tab[keyval] >> 5 ;
199206 }
200207
201- if (m_inputlen == ++m_inputcnt) // return expected value
208+ if (m_inputlen == ++m_inputcnt) // return expected value
202209 {
203210 return m_inputval ^ 0xff ;
204211 }
205212
206- if (m_inputcnt > 4 ) // end of cycle
213+ if (m_inputcnt > 4 ) // end of cycle
207214 {
208215 m_inputcnt = -1 ;
209216 }
210217
211- return 0xff ; // return 0^ 0xff
218+ return 0xff ; // return 0 ^ 0xff
212219}
213220
214221void koikoi_state::unknown_w (uint8_t data)
215222{
216- // xor 'ed mux select, player 1 = 1,2,4,8, player 2 = 0x10, 0x20, 0x40, 0x80
223+ // XOR 'ed mux select, player 1 = 1,2,4,8, player 2 = 0x10, 0x20, 0x40, 0x80
217224}
218225
219226uint8_t koikoi_state::io_r (offs_t offset)
220227{
221228 if (!offset)
222- return ioport ( " IN0 " ) ->read () ^ m_ioram[4 ]; // coin
229+ return m_in[ 0 ] ->read () ^ m_ioram[4 ]; // coin
223230
224231 return 0 ;
225232}
226233
227234void koikoi_state::io_w (offs_t offset, uint8_t data)
228235{
229236 if (offset == 7 && data == 0 )
230- m_inputcnt = 0 ; // reset read cycle counter
237+ m_inputcnt = 0 ; // reset read cycle counter
231238
232239 m_ioram[offset] = data;
233240}
@@ -238,19 +245,19 @@ void koikoi_state::io_w(offs_t offset, uint8_t data)
238245 *
239246 *************************************/
240247
241- void koikoi_state::koikoi_map (address_map &map)
248+ void koikoi_state::program_map (address_map &map)
242249{
243250 map (0x0000 , 0x2fff ).rom ();
244251 map (0x6000 , 0x67ff ).ram ();
245- map (0x7000 , 0x77ff ).ram ().w (FUNC (koikoi_state::vram_w)).share (" videoram " );
252+ map (0x7000 , 0x77ff ).ram ().w (FUNC (koikoi_state::vram_w)).share (m_videoram );
246253 map (0x8000 , 0x8000 ).portr (" DSW" );
247254 map (0x9000 , 0x9007 ).rw (FUNC (koikoi_state::io_r), FUNC (koikoi_state::io_w));
248255}
249256
250- void koikoi_state::koikoi_io_map (address_map &map)
257+ void koikoi_state::io_map (address_map &map)
251258{
252259 map.global_mask (0xff );
253- map (0x02 , 0x02 ).nopw (); // watchdog
260+ map (0x02 , 0x02 ).nopw (); // watchdog
254261 map (0x03 , 0x03 ).r (" aysnd" , FUNC (ay8910_device::data_r));
255262 map (0x06 , 0x07 ).w (" aysnd" , FUNC (ay8910_device::data_address_w));
256263}
@@ -315,20 +322,8 @@ INPUT_PORTS_END
315322 *
316323 *************************************/
317324
318- static const gfx_layout tilelayout =
319- {
320- 8 , 8 ,
321- RGN_FRAC (1 ,3 ),
322- 3 ,
323- { RGN_FRAC (2 ,3 ), RGN_FRAC (1 ,3 ), RGN_FRAC (0 ,3 ) },
324- { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 },
325- { 0 *8 , 1 *8 , 2 *8 , 3 *8 , 4 *8 , 5 *8 , 6 *8 , 7 *8 },
326- 8 *8
327- };
328-
329-
330325static GFXDECODE_START( gfx_koikoi )
331- GFXDECODE_ENTRY( " gfx1 " , 0x0000 , tilelayout, 0 , 32 )
326+ GFXDECODE_ENTRY( " tiles " , 0x0000 , gfx_8x8x3_planar, 0 , 32 )
332327GFXDECODE_END
333328
334329
@@ -343,46 +338,41 @@ void koikoi_state::machine_start()
343338 save_item (NAME (m_inputcnt));
344339 save_item (NAME (m_inputval));
345340 save_item (NAME (m_inputlen));
346- save_item (NAME (m_ioram));
347341}
348342
349343void koikoi_state::machine_reset ()
350344{
351- int i;
352-
353345 m_inputcnt = -1 ;
354346 m_inputval = 0 ;
355347 m_inputlen = 0 ;
356-
357- for (i = 0 ; i < 8 ; i++)
358- m_ioram[i] = 0 ;
359348}
360349
350+
361351void koikoi_state::koikoi (machine_config &config)
362352{
363- /* basic machine hardware */
364- Z80 (config, m_maincpu, KOIKOI_CRYSTAL/ 4 ); /* ?? */
365- m_maincpu->set_addrmap (AS_PROGRAM, &koikoi_state::koikoi_map );
366- m_maincpu->set_addrmap (AS_IO, &koikoi_state::koikoi_io_map );
353+ // basic machine hardware
354+ Z80 (config, m_maincpu, 15 .468_MHz_XTAL / 4 ); // divider unverified
355+ m_maincpu->set_addrmap (AS_PROGRAM, &koikoi_state::program_map );
356+ m_maincpu->set_addrmap (AS_IO, &koikoi_state::io_map );
367357
368358
369- /* video hardware */
359+ // video hardware
370360 screen_device &screen (SCREEN (config, " screen" , SCREEN_TYPE_RASTER));
371361 screen.set_refresh_hz (60 );
372362 screen.set_vblank_time (ATTOSECONDS_IN_USEC (0 ));
373363 screen.set_size (32 *8 , 32 *8 );
374364 screen.set_visarea (0 *8 , 32 *8 -1 , 0 *8 , 32 *8 -1 );
375- screen.set_screen_update (FUNC (koikoi_state::screen_update_koikoi ));
365+ screen.set_screen_update (FUNC (koikoi_state::screen_update ));
376366 screen.set_palette (" palette" );
377367 screen.screen_vblank ().set_inputline (m_maincpu, INPUT_LINE_NMI);
378368
379369 GFXDECODE (config, m_gfxdecode, " palette" , gfx_koikoi);
380- PALETTE (config, " palette" , FUNC (koikoi_state::koikoi_palette ), 8 * 32 , 16 );
370+ PALETTE (config, " palette" , FUNC (koikoi_state::palette_init ), 8 * 32 , 16 );
381371
382- /* sound hardware */
372+ // sound hardware
383373 SPEAKER (config, " mono" ).front_center ();
384374
385- ay8910_device &aysnd (AY8910 (config, " aysnd" , KOIKOI_CRYSTAL/ 8 ));
375+ ay8910_device &aysnd (AY8910 (config, " aysnd" , 15 .468_MHz_XTAL / 8 )); // divider unverified
386376 aysnd.port_b_read_callback ().set (FUNC (koikoi_state::input_r));
387377 aysnd.port_a_write_callback ().set (FUNC (koikoi_state::unknown_w));
388378 aysnd.add_route (ALL_OUTPUTS, " mono" , 0.10 );
@@ -395,20 +385,20 @@ void koikoi_state::koikoi(machine_config &config)
395385 *
396386 *************************************/
397387
398- ROM_START ( koikoi )
399- ROM_REGION ( 0x10000 , " maincpu" , 0 ) /* code */
388+ ROM_START ( koikoip2 )
389+ ROM_REGION ( 0x10000 , " maincpu" , 0 )
400390 ROM_LOAD ( " ic56" , 0x0000 , 0x1000 , CRC(bdc68f9d) SHA1(c45fbc95abb37f750acc1d9f3b35ad0f41af097d) )
401391 ROM_LOAD ( " ic55" , 0x1000 , 0x1000 , CRC(fe09248a) SHA1(c192795678068e387bd406f5cd1c5aba5f5ef66a) )
402392 ROM_LOAD ( " ic54" , 0x2000 , 0x1000 , CRC(925fc57c) SHA1(4c79df92b6617fe84e61359c8e6e3b907b138777) )
403393
404- ROM_REGION ( 0x3000 , " gfx1 " , 0 ) /* gfx */
394+ ROM_REGION ( 0x3000 , " tiles " , 0 )
405395 ROM_LOAD ( " ic33" , 0x0000 , 0x1000 , CRC(9e4d563b) SHA1(63664dcffc2eb198a161c73131b95a66b2067424) )
406396 ROM_LOAD ( " ic26" , 0x1000 , 0x1000 , CRC(79cb1e93) SHA1(4d08b3d88727b437673f7a51d47396f19bbc3caa) )
407397 ROM_LOAD ( " ic18" , 0x2000 , 0x1000 , CRC(c209362d) SHA1(0620c19fe72e8407db0f487b6413c5d45ac8046c) )
408398
409399 ROM_REGION ( 0x0120 , " proms" , 0 )
410400 ROM_LOAD ( " prom.x" , 0x000 , 0x020 , NO_DUMP )
411- /* hand crafted color table */
401+ // hand crafted color table
412402 ROM_FILL ( 0x00 , 1 , 0x18 )
413403 ROM_FILL ( 0x01 , 1 , 0xff )
414404 ROM_FILL ( 0x02 , 1 , 0x06 )
@@ -435,6 +425,46 @@ ROM_START( koikoi )
435425 ROM_LOAD ( " pal16r8a_red.ic10" , 0x0800 , 0x0104 , CRC(027ad661) SHA1(fa5aafe6deb3a9865498152b92dd3776ea10a51d) )
436426ROM_END
437427
428+ ROM_START ( koikoi ) // TODO: is this a bootleg?
429+ ROM_REGION ( 0x10000 , " maincpu" , 0 )
430+ ROM_LOAD ( " ic56" , 0x0000 , 0x1000 , CRC(52cad277) SHA1(9c9b9add4be021e289049e9f72a2f67ac150b355) )
431+ ROM_LOAD ( " ic55" , 0x1000 , 0x1000 , CRC(d171dd19) SHA1(91bb98633fc06fb3b0d226af25500c0835033aff) )
432+ ROM_LOAD ( " ic54" , 0x2000 , 0x1000 , CRC(b2b90632) SHA1(f662b58114f399fd01ffbf05a532c3b1aa618273) )
433+
434+ ROM_REGION ( 0x3000 , " tiles" , 0 )
435+ ROM_LOAD ( " ka.ic33" , 0x0000 , 0x1000 , CRC(181fb265) SHA1(6ce31af8699c3304cfe6c47435dcdab0cb7a2ed8) )
436+ ROM_LOAD ( " kb.ic26" , 0x1000 , 0x1000 , CRC(6b416ee1) SHA1(039f5155128d38fd9b46914452596b2838690dd9) )
437+ ROM_LOAD ( " kc.ic18" , 0x2000 , 0x1000 , CRC(016d9b11) SHA1(0cf9d3c3d1678c3b59230212c1a135a50cbca3cd) )
438+
439+ ROM_REGION ( 0x0120 , " proms" , 0 )
440+ ROM_LOAD ( " prom.x" , 0x000 , 0x020 , NO_DUMP ) // TODO: couldn't find it on PCB pic, does it really exist?
441+ // TODO: hand crafted color table, taken from koikoip2
442+ ROM_FILL ( 0x00 , 1 , 0x18 )
443+ ROM_FILL ( 0x01 , 1 , 0xff )
444+ ROM_FILL ( 0x02 , 1 , 0x06 )
445+ ROM_FILL ( 0x03 , 1 , 0x3f )
446+ ROM_FILL ( 0x04 , 1 , 0xb6 )
447+ ROM_FILL ( 0x05 , 1 , 0x10 )
448+ ROM_FILL ( 0x06 , 1 , 0x2f )
449+ ROM_FILL ( 0x07 , 1 , 0x04 )
450+ ROM_FILL ( 0x08 , 1 , 0x8b )
451+ ROM_FILL ( 0x09 , 1 , 0x3f )
452+ ROM_FILL ( 0x0a , 1 , 0x07 )
453+ ROM_FILL ( 0x0b , 1 , 0x00 ) // unused
454+ ROM_FILL ( 0x0c , 1 , 0x2f )
455+ ROM_FILL ( 0x0d , 1 , 0xff )
456+ ROM_FILL ( 0x0e , 1 , 0x00 )
457+ ROM_FILL ( 0x0f , 1 , 0x0b )
458+ ROM_LOAD ( " prom.ic23" , 0x020 , 0x100 , CRC(de68cb19) SHA1(f23990cdf228cc79d66d5f75f88bccee0e5e5877) )
459+
460+ ROM_REGION ( 0x0a00 , " plds" , 0 ) // dumped for koikoip2, may or may not be correct
461+ ROM_LOAD ( " pal16r8-10_pink.ic9" , 0x0000 , 0x0104 , BAD_DUMP CRC (9f8fdb95) SHA1(cdcdb1a6baef18961cf6c75fba0c3aba47f3edbb) )
462+ ROM_LOAD( " pal16r8-10_green.ic15" , 0x0200 , 0x0104 , BAD_DUMP CRC (da7b8b95) SHA1(a4eb12f2365ff2b6057e4a2e225e8f879a961d45) )
463+ ROM_LOAD( " pal16r8a_yellow.ic8" , 0x0400 , 0x0104 , BAD_DUMP CRC (7d8da540) SHA1(28925d1fb4ef670e9c9d24860b67fdff8791c6a9) )
464+ ROM_LOAD( " pal16r8a_brown.ic11" , 0x0600 , 0x0104 , BAD_DUMP CRC (fff46363) SHA1(97f673c862e9d5b12cac283000a779c465c76828) )
465+ ROM_LOAD( " pal16r8a_red.ic10" , 0x0800 , 0x0104 , BAD_DUMP CRC (027ad661) SHA1(fa5aafe6deb3a9865498152b92dd3776ea10a51d) )
466+ ROM_END
467+
438468} // anonymous namespace
439469
440470
@@ -444,4 +474,5 @@ ROM_END
444474 *
445475 *************************************/
446476
447- GAME ( 1982 , koikoi, 0 , koikoi, koikoi, koikoi_state, empty_init, ROT270, " Kiwako" , " Koi Koi Part 2" , MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE )
477+ GAME ( 1982 , koikoip2, 0 , koikoi, koikoi, koikoi_state, empty_init, ROT270, " Kiwako" , " Koi Koi Part 2" , MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE )
478+ GAME( 1982 , koikoi, 0 , koikoi, koikoi, koikoi_state, empty_init, ROT270, " Chubukiko / Best Data System" , " Koi Koi" , MACHINE_NOT_WORKING | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE )
0 commit comments