summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/drivers/subsino2.c
blob: a4cc253f7815504fbe06bd92b045731e72842b3f (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003















                                                                                                             
                                                                                                            

























                                                                                                                 
                            

                           













                  
 
         
              










                             




                                           

                                                                                        
 















                                            
  

 




                                                                            
                                                                                                                                         













                                                                                                                                                                                                      

                                              
                                                                      
                                                                                        

 
          

                                              
                                                                      
                                                                                        
 

 

                                         
                                                                               
                                       
 

                                          
                                                                               
                                        





























                                                                                                       

                                               
                                                                               
                                                                             



                                               
                                                                               
                                                                             



                                                  
                                                                               

                                                                                                



                                                   
                                                                               

                                                                                                 



                                              
                                                                               
                                                             



                                              
                                                                               
                                                             
 

          

                                               
                                                                               
                                                                             



                                               
                                                                               
                                                                             



                                                  
                                                                               

                                                                                                



                                                   
                                                                               

                                                                                                 



                                              
                                                                               
                                                             



                                              
                                                                               
                                                             
 

                


                                               
                                                                               

                                                                            


                                           
                                                                               
                                                         


                                           
                                                                               
                                                         








                                                                            


                                                                               


       






                                                                                                                          


      




                                                                                                                                                                         


        


                                                                                                            


        



                                                                                                




                                               

                                            
 

                                            
 









                                            
                                                               























                                            

                    
                                            
 














                                                                            

                                            
                                                                               
                                          

 

                                          
                                                                               
                                        






















                                              
                                                                                                                      





                                                                  
                                                 














                                                                            
                                                                               
                                          
















                                                                                                                                        

                                                
                                                                               
                                                              



                                                
                                                                               
                                                              



                                                   
                                                                               

                                                                                 



                                                
                                                                               
                                                              



                                                
                                                                               
                                                              
 

          

                                                
                                                                               
                                                              



                                                
                                                                               
                                                              



                                                   
                                                                               

                                                                                 



                                                
                                                                               
                                                              



                                                
                                                                               
                                                              
 





                                                                            

                                         
                                                                               
                                       
















                                                                                                                                  
                                                                      
                                                                            


                       


                                                                                                     




                                   
                                                 


















                                                                                                                                          




                                                                                     

  

                                                                                           
 

                                                                                               
 

                                                                                               




                            
                                                                      
                                     
                                                     



                            
                                                                      
                                     
                                                     

 
                                
 
                                                                                
                                                   


                 
                                                              

                            

                                                                                 






                                                 
                                             

















                                            
                                                 
















                                                                                                                                 
                                                                      


                            
                                                 







                                                            
                                                                                 






                                                                                         
                                                                                                                                                             




































                                                                                                                                                    
                                                                                             
 
                                                                                                                                                                                                                                                                              







                                                                            


                                           
                                                                               


                       
                                                         


                              




                                                                                                  
                          
                                                                                    















                                                                            

                                   
                                                                               
                                 



                             
                                                                               



                                                                                                        

 


                                     
                                                                               


                                     
                                                                       






















                                                                            








                                      
                                                                               
                                             



                                       
                                                                               
                                             



                               
                                                                      
                                       



                                                      



                                        
                                                                                

                                                                                                 
                                                                                                                       



                                                  
                                                                              
                                                                                   
                                                                                                   








                                                                            
                                                                                          










                                                                            


                                       
                                                                               
                                
                                                 



                                         
                                                                               
              
                                                                                               
                                                                   

                                                                              




                                         
                                                                               
                                
                                                   



                                        
                                                                               




                                                                                               
                                                      
                                                                         

                                                                                                            

                                                                                                                               




                                           
                                                                               
                                          






                                                                

                                                                                                                                 



                              
                                                 


 
                                                       











































                                                                                                                              
                                                                                                                                       







                                                                            
                                                                               
                                        







                                                        
                                                                                        


                              



                                                                                                                  


                              

                                                                                          
 
                                                                                        


                              
                                                                                                                                            







                                                                            
                                                                               
                                        



                       



                                                                                          


                              




                                                                                                              








                              
                                                                                                                                            



                                          
                                                                               

                                                                           
         

                                                                                                                              
 

                                                                                                                              
 
                                                                                      




                                          
                                                                               
                                        

















                                             
                                                                                                                      





                                                                  
                                                 













                                                              
                                                     










                                                                          
                                                                                                            



















                                                                                                                             
                                               








                                                                            
                                                                               
                                        



                       

                                                                                          












                                  
                                                                                                                                            

 
                                                      























                                                                                                    
                                                











                                                                                            
                                                                                                         










                                                                                               
                                                                                                                               







                                                                            
                                                                               
                                        







                                                        
                                                                                        


                              




                                                                                                     


                              

                                                                              
 
                                                                                               


                              
                                                                                                                                            

 
                                                    
































                                                                                                     
                                              























                                                                                               
                                                                                                       

                                   
                                                                                                                               







                                                                            
                                                                               
                                        







                                                        

                                                                                              


                              




                                                                                                 


                              

                                                                                          
 
                                                                                        


                              
                                                                                                                                            

 
                                                
                                             
                                                                                                         



                                  
                                               
                                             
                                                                                                        



































































































































































































































































































































































































































































































































































































































                                                                                                                                                                                            


















































































































































                                                                                                                                           








                                                                            
                                                      


                                                         
                                                                                             









                                                                                                    
                                      




                                    








                                                                            
                                                     












                                                                                                          
                                      




                                  











                                                                                           
                                                      


                                                                             
                                                                                                      










                                                                                                          
                                      




                                    














                                                                                   
                                                    



                                                                             
                                                                                                      










                                                                                                          
                                      




                                    






















































































                                                                                                                               
                                                                 






























































                                                                                                                                      
                                                       

































































                                                                                                                      






                                                     



                                                                            
                                         





                             


                                               
              
                                  


                                                                            




                                                                                      
                                                       




















































                                                                                                                   
                                                       


























































                                                                                                                                   
                                                       


























































                                                                                                                                   
                                                       




                                                                               




















































                                                                                                                                             
/************************************************************************************************************

                                 -= Subsino (Newer) Tilemaps Hardware =-

                                  driver by   Luca Elia (l.elia@tin.it)


Two 1024x512 tilemaps. 256 color tiles. Tiles are 8x8 or a multiple (dynamic tile size).
There is RAM for 512 scroll values (line scroll). Video RAM is mirrored on multiple ranges.
One peculiarity is that video RAM access is split into high and low byte. The former is mapped
in program space, the latter in I/O space.

-------------------------------------------------------------------------------------------------------------
Year  Game            CPU         Sound            Custom                            Other
-------------------------------------------------------------------------------------------------------------
1996  Magic Train     HD647180*   U6295            SS9601, SS9602                    HM86171 RAMDAC, Battery
1996  Water-Nymph     HD647180*   U6295            SS9601, SS9602                    HM86171 RAMDAC, Battery
1998  Express Card    AM188-EM    M6295            SS9601, SS9802, SS9803            HM86171 RAMDAC, Battery
1998  Ying Hua Lian   AM188-EM    M6295 + YM3812?  SS9601, SS9602                    HM86171 RAMDAC, Battery
1999  Bishou Jan      H8/3044     SS9904?          SS9601, SS9802, SS9803            HM86171 RAMDAC, Battery
1999  X-Train         AM188-EM    M6295            SS9601, SS9802, SS9803            HM86171 RAMDAC, Battery
2006  X-Plan          AM188-EM    M6295            SS9601, SS9802, SS9803            HM86171 RAMDAC, Battery
-------------------------------------------------------------------------------------------------------------
*SS9600

To do:

- Implement serial communication (used for protection).
- saklove, xplan: remove IRQ hacks (when an AM188-EM core will be available).
- bishjan, saklove: game is sometimes too fast (can bishjan read the VBLANK state? saklove and xplan can).
- bishjan: add sound (does it send sound commands to another device? SS9904?).
- xtrain: it runs faster than a video from the real thing. It doesn't use vblank irqs (but reads the vblank bit).
- mtrain: implement hopper. Double up does not work?

************************************************************************************************************/

#include "emu.h"
#include "cpu/h83002/h8.h"
#include "cpu/i86/i86.h"
#include "cpu/z180/z180.h"
#include "sound/3812intf.h"
#include "sound/okim6295.h"
#include "machine/nvram.h"
#include "machine/subsino.h"
#include "machine/ticket.h"


enum tilesize_t
{
	TILE_8x8,
	TILE_8x32,
	TILE_64x32
};

enum vram_t
{
	VRAM_LO,
	VRAM_HI
};


// Layers
struct layer_t
{

	UINT8 *videorams[2];

	UINT8 *scrollrams[2];
	int scroll_x;
	int scroll_y;

	tilemap_t *tmap;
	tilesize_t tilesize;

};

class subsino2_state : public driver_device
{
public:
	subsino2_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag) { }

	UINT8 *m_hm86171_colorram;
	layer_t m_layers[2];
	UINT8 m_ss9601_byte_lo;
	UINT8 m_ss9601_byte_lo2;
	UINT8 *m_ss9601_reelrams[2];
	const rectangle *m_ss9601_reelrects;
	UINT8 m_ss9601_scrollctrl;
	UINT8 m_ss9601_tilesize;
	UINT8 m_ss9601_disable;
	int m_hm86171_offs;
	UINT8 m_dsw_mask;
	UINT8 *m_outputs;
	UINT16 *m_outputs16;
	UINT8 *m_am188em_regs;
	UINT16 m_bishjan_sel;
	UINT16 m_bishjan_input;
};



/***************************************************************************
                              Tilemaps Access
***************************************************************************/

INLINE void ss9601_get_tile_info(layer_t *l, running_machine &machine, tile_data *tileinfo, tilemap_memory_index tile_index, void *param)
{
	int addr;
	UINT16 offs;
	switch (l->tilesize)
	{
		default:
		case TILE_8x8:		addr = tile_index;				offs = 0;												break;
		case TILE_8x32:		addr = tile_index & (~0x180);	offs = (tile_index/0x80) & 3;							break;
		case TILE_64x32:	addr = tile_index & (~0x187);	offs = ((tile_index/0x80) & 3) + (tile_index & 7) * 4;	break;
	}
	SET_TILE_INFO(0, (l->videorams[VRAM_HI][addr] << 8) + l->videorams[VRAM_LO][addr] + offs, 0, 0);
}

// Layer 0
static TILE_GET_INFO( ss9601_get_tile_info_0 )
{
	subsino2_state *state = machine.driver_data<subsino2_state>();
	ss9601_get_tile_info(&state->m_layers[0], machine, tileinfo, tile_index, param);
}

// Layer 1
static TILE_GET_INFO( ss9601_get_tile_info_1 )
{
	subsino2_state *state = machine.driver_data<subsino2_state>();
	ss9601_get_tile_info(&state->m_layers[1], machine, tileinfo, tile_index, param);
}


static WRITE8_HANDLER( ss9601_byte_lo_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_ss9601_byte_lo = data;
}
static WRITE8_HANDLER( ss9601_byte_lo2_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_ss9601_byte_lo2 = data;
}


INLINE void ss9601_videoram_w(layer_t *l, vram_t vram, address_space *space, offs_t offset, UINT8 data)
{
	l->videorams[vram][offset] = data;

	switch (l->tilesize)
	{
		default:
		case TILE_8x8:
			tilemap_mark_tile_dirty(l->tmap, offset);
			break;

		case TILE_8x32:
			offset &= ~0x180;
			for (int y = 0; y < 0x80*4; y += 0x80)
				tilemap_mark_tile_dirty(l->tmap, offset + y);
			break;

		case TILE_64x32:
			offset &= ~0x187;
			for (int x = 0; x < 8; x++)
				for (int y = 0; y < 0x80*4; y += 0x80)
					tilemap_mark_tile_dirty(l->tmap, offset + y + x);
			break;
	}
}

// Layer 0
static WRITE8_HANDLER( ss9601_videoram_0_hi_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	ss9601_videoram_w(&state->m_layers[0], VRAM_HI, space, offset, data);
}

static WRITE8_HANDLER( ss9601_videoram_0_lo_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	ss9601_videoram_w(&state->m_layers[0], VRAM_LO, space, offset, data);
}

static WRITE8_HANDLER( ss9601_videoram_0_hi_lo_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	ss9601_videoram_w(&state->m_layers[0], VRAM_HI, space, offset, data);
	ss9601_videoram_w(&state->m_layers[0], VRAM_LO, space, offset, state->m_ss9601_byte_lo);
}

static WRITE8_HANDLER( ss9601_videoram_0_hi_lo2_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	ss9601_videoram_w(&state->m_layers[0], VRAM_HI, space, offset, data);
	ss9601_videoram_w(&state->m_layers[0], VRAM_LO, space, offset, state->m_ss9601_byte_lo2);
}

static READ8_HANDLER( ss9601_videoram_0_hi_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return state->m_layers[0].videorams[VRAM_HI][offset];
}

static READ8_HANDLER( ss9601_videoram_0_lo_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return state->m_layers[0].videorams[VRAM_LO][offset];
}

// Layer 1
static WRITE8_HANDLER( ss9601_videoram_1_hi_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	ss9601_videoram_w(&state->m_layers[1], VRAM_HI, space, offset, data);
}

static WRITE8_HANDLER( ss9601_videoram_1_lo_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	ss9601_videoram_w(&state->m_layers[1], VRAM_LO, space, offset, data);
}

static WRITE8_HANDLER( ss9601_videoram_1_hi_lo_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	ss9601_videoram_w(&state->m_layers[1], VRAM_HI, space, offset, data);
	ss9601_videoram_w(&state->m_layers[1], VRAM_LO, space, offset, state->m_ss9601_byte_lo);
}

static WRITE8_HANDLER( ss9601_videoram_1_hi_lo2_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	ss9601_videoram_w(&state->m_layers[1], VRAM_HI, space, offset, data);
	ss9601_videoram_w(&state->m_layers[1], VRAM_LO, space, offset, state->m_ss9601_byte_lo2);
}

static READ8_HANDLER( ss9601_videoram_1_hi_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return state->m_layers[1].videorams[VRAM_HI][offset];
}

static READ8_HANDLER( ss9601_videoram_1_lo_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return state->m_layers[1].videorams[VRAM_LO][offset];
}

// Layer 0 Reels

static WRITE8_HANDLER( ss9601_reelram_hi_lo_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_ss9601_reelrams[VRAM_HI][offset] = data;
	state->m_ss9601_reelrams[VRAM_LO][offset] = state->m_ss9601_byte_lo;
}
static READ8_HANDLER( ss9601_reelram_hi_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return state->m_ss9601_reelrams[VRAM_HI][offset];
}
static READ8_HANDLER( ss9601_reelram_lo_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return state->m_ss9601_reelrams[VRAM_LO][offset];
}


/***************************************************************************
                              Tilemaps Tile Size


mtrain:

80 = 00     40 = -      L0 = 8x8    L1 = 8x8    ; title screen
80 = 01     40 = -      L0 = REEL   L1 = 8x8    ; gameplay (center reel)
80 = 01     40 = -      L0 = REEL   L1 = 8x8    ; girl slot (top, bottom reels)

xtrain:

80 = 00     40 = FD     L0 = -      L1 = 8x8    ; ram test (disable = 01 -> L0 disabled)
80 = 40     40 = FD     L0 = REEL   L1 = 8x8    ; game play (center reel) as well as "BONUS" screen (top reel)
80 = 40     40 = FD     L0 = REEL   L1 = 8x8    ; lose/treasure slot (center reel)
80 = 00     40 = BF     L0 = 8x8    L1 = 8x8    ; car screen [L0 line scroll every 32]
80 = 00     40 = EF     L0 = 8x8    L1 = 8x8    ; title screen, L0 normal scroll (scrollram is 0) [L1 line scroll every 8]
80 = 40     40 = 00     L0 = 8x16?  L1 = 8x8    ; girl dancing
80 = 00     40 = FF     L0 = 8x8    L1 = 8x8    ; soft dsw screen

xplan:

80 = 00     40 = FD     L0 = -      L1 = 8x8    ; ram test (disable = 01 -> L0 disabled)
80 = 40     40 = BF     L0 = 8x32   L1 = 8x8    ; title screen [L0 line scroll every 32, L1 line scroll disabled?] / 3 planes with scrolling clouds (before title screen)
80 = 00     40 = EF     L0 = 8x8    L1 = 8x8    ; parachutist and cars demo [L1 line scroll every 8]
80 = 70     40 = FF     L0 = 64x32  L1 = 8x8    ; shoot'em up demo / gambling demo
80 = 00     40 = FF     L0 = 8x8    L1 = 8x8    ; test mode and stat screens

bishjan:

80 = 00     40 = FD     L0 = -      L1 = 8x8    ; ram test (disable = 01 -> L0 disabled)
80 = 00     40 = 0F     L0 = 8x8    L1 = 8x8    ; soft dsw screen
80 = 00     40 = 0x     L0 = 8x8    L1 = 8x8    ; stat screens and gameplay (40 = 07/0d, seems a don't care)

saklove:

80 = 00     40 = 0D     L0 = -      L1 = 8x8    ; ram test (disable = 01 -> L0 disabled)
80 = 00     40 = 0D     L0 = 8x8    L1 = 8x8    ; gameplay / square of tiles screen
80 = 00     40 = 0F     L0 = 8x8    L1 = 8x8    ; title screen / instructions / double up screen
80 = 00     40 = 07     L0 = 8x8    L1 = 8x8    ; pool [L0 line scroll]

-----

More registers, at boot (never changed AFAICT):

mtrain,     saklove     xtrain,      expcard
wtrnymph                xplan

                         C0 = 0A     C0 = 0A
                         E0 = 18     E0 = 18

9100 = 13   200 = 13    200 = 13    200 = 13
9101 = 20   201 = 20    201 = 20    201 = 20
9102 = 20   202 = 20    202 = 20    202 = 20
9103 = 33   203 = 33    203 = 33    203 = 33
9104 = DC   204 = DC    204 = DC    204 = DC
9105 = A0   205 = A0    205 = A0    205 = A0
9106 = FA   206 = FA    206 = FA    206 = FA
9107 = 00   207 = 00    207 = 00    207 = 00
9108 = 33   208 = 33    208 = 33    208 = 33
9109 = 16   209 = 0E    209 = 0E    209 = 0E
910A = F6   20A = FD    20A = FD    20A = FD    *F5 in wtrnymph
910B = 22   20B = 22    20B = 22    20B = 22
910C = FE   20C = FE    20C = FE    20C = FE
910D = FB   20D = FB    20D = FB    20D = FB
910E = F8   20E = F8    20E = F8    20E = F8
910F = 02   20F = 02    20F = 02    20F = 02
9110 = 13   210 = 13    210 = 13    210 = 13
9111 = 10   211 = 00    211 = 00    211 = 00
9112 = 62   212 = 82    212 = 82    212 = 82
9113 = 13   213 = 33    213 = 33    213 = 33
9114 = 80   214 = 0E    214 = 0E    214 = 0E
9115 = 80   215 = FD    215 = FD    215 = FD
9116 = 13   216 = 13    216 = 13    216 = 13
9117 = 42   217 = 42    217 = 42    217 = 42
9118 = 42   218 = 42    218 = 42    218 = 42
9119 = 13   219 = 13    219 = 13    219 = 13
911A = 20   21A = 20    21A = 20    21A = 20
911B = 42   21B = 62    21B = 62    21B = 62
9126 = 0C   226 = 08    226 = 08    226 = 08
9127 = 0C   227 = 0C    227 = 0C    227 = 0C
9130 = 00   230 = 00    230 = 00    230 = 00
9131 = 00   231 = 00    231 = 00    231 = 00
9132 = 00   232 = FB    232 = FB    232 = FB
9133 = 00   233 = FF    233 = FF    233 = FF
9134 = 00   234 = 22    234 = 20    234 = 20
9135 = 00   235 = 02
9136 = 00
9137 = 00   237 = 00    237 = 00    237 = 00

9149 = FF   312 = FF    309 = FF    312 = FF
914A = FF   311 = FF    30A = FF    311 = FF
914B = FF   310 = FF    30B = FF    310 = FF
914C = 47   30F = 47    30C = 47    30F = 47
914D = 00   30E = 00    30D = 00    30E = 00
914E = 00   30D = 00    30E = 00    30D = 00
914F = 00   30C = 00    30F = 00    30C = 00
9150 = C0   30B = C0    310 = C0    30B = C0
9151 = FF   30A = FF    311 = FF    30A = FF
9153 = 00               313 = 00

***************************************************************************/

// These are written in sequence

static WRITE8_HANDLER( ss9601_scrollctrl_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_ss9601_scrollctrl = data;
}

static WRITE8_HANDLER( ss9601_tilesize_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_ss9601_tilesize = data;

	tilesize_t sizes[2];
	switch (data)
	{
		case 0x00:
			sizes[0] = TILE_8x8;
			sizes[1] = TILE_8x8;
			break;

		case 0x40:
			sizes[0] = TILE_8x32;
			sizes[1] = TILE_8x8;
			break;

		case 0x70:
			sizes[0] = TILE_64x32;
			sizes[1] = TILE_8x8;
			break;

		default:
			sizes[0] = TILE_8x8;
			sizes[1] = TILE_8x8;

			logerror("%s: warning, unknown tilesize = %02x\n", space->machine().describe_context(), data);
			popmessage("UNKNOWN TILESIZE %02X", data);
			break;
	}

	for (int i = 0; i < 2; i++)
	{
		layer_t *l = &state->m_layers[i];

		if (l->tilesize != sizes[i])
		{
			l->tilesize = sizes[i];
			tilemap_mark_all_tiles_dirty(l->tmap);
		}
	}
}

/***************************************************************************
                              Tilemaps Scroll
***************************************************************************/

static WRITE8_HANDLER( ss9601_scroll_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	layer_t *layers = state->m_layers;
	switch ( offset )
	{
		// Layer 0
		case 0:	layers[0].scroll_x = (layers[0].scroll_x & 0xf00) | data;					break;	// x low
		case 1:	layers[0].scroll_y = (layers[0].scroll_y & 0xf00) | data;					break;	// y low
		case 2:	layers[0].scroll_x = (layers[0].scroll_x & 0x0ff) | ((data & 0x0f) << 8);			// y|x high bits
				layers[0].scroll_y = (layers[0].scroll_y & 0x0ff) | ((data & 0xf0) << 4);	break;

		// Layer 1
		case 3:	layers[1].scroll_x = (layers[1].scroll_x & 0xf00) | data;					break;	// x low
		case 4:	layers[1].scroll_y = (layers[1].scroll_y & 0xf00) | data;					break;	// y low
		case 5:	layers[1].scroll_x = (layers[1].scroll_x & 0x0ff) | ((data & 0x0f) << 8);			// y|x high bits
				layers[1].scroll_y = (layers[1].scroll_y & 0x0ff) | ((data & 0xf0) << 4);	break;
	}
}

// Layer 0
static WRITE8_HANDLER( ss9601_scrollram_0_hi_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_layers[0].scrollrams[VRAM_HI][offset] = data;
}

static WRITE8_HANDLER( ss9601_scrollram_0_lo_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_layers[0].scrollrams[VRAM_LO][offset] = data;
}

static WRITE8_HANDLER( ss9601_scrollram_0_hi_lo_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_layers[0].scrollrams[VRAM_HI][offset] = data;
	state->m_layers[0].scrollrams[VRAM_LO][offset] = state->m_ss9601_byte_lo;
}

static READ8_HANDLER ( ss9601_scrollram_0_hi_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return state->m_layers[0].scrollrams[VRAM_HI][offset];
}

static READ8_HANDLER ( ss9601_scrollram_0_lo_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return state->m_layers[0].scrollrams[VRAM_LO][offset];
}

// Layer 1
static WRITE8_HANDLER( ss9601_scrollram_1_hi_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_layers[1].scrollrams[VRAM_HI][offset] = data;
}

static WRITE8_HANDLER( ss9601_scrollram_1_lo_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_layers[1].scrollrams[VRAM_LO][offset] = data;
}

static WRITE8_HANDLER( ss9601_scrollram_1_hi_lo_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_layers[1].scrollrams[VRAM_HI][offset] = data;
	state->m_layers[1].scrollrams[VRAM_LO][offset] = state->m_ss9601_byte_lo;
}

static READ8_HANDLER ( ss9601_scrollram_1_hi_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return state->m_layers[1].scrollrams[VRAM_HI][offset];
}

static READ8_HANDLER ( ss9601_scrollram_1_lo_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return state->m_layers[1].scrollrams[VRAM_LO][offset];
}


/***************************************************************************
                              Tilemaps Disable
***************************************************************************/

static WRITE8_HANDLER( ss9601_disable_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_ss9601_disable = data;
}


/***************************************************************************
                                Video Update
***************************************************************************/

static const rectangle mtrain_reelrects[3] = {	{ 0, 0, 0x00*8, 0x09*8-1 },
												{ 0, 0, 0x09*8, 0x10*8-1 },
												{ 0, 0, 0x10*8, 256-16-1 }	};

static const rectangle xtrain_reelrects[3] = {	{ 0, 0, 0x00*8, 0x08*8-1 },
												{ 0, 0, 0x08*8, 0x18*8-1 },
												{ 0, 0, 0x18*8, 256-16-1 }	};

static VIDEO_START( subsino2 )
{
	subsino2_state *state = machine.driver_data<subsino2_state>();
	state->m_hm86171_colorram = auto_alloc_array(machine, UINT8, 256*3);

	// SS9601 Regs:

	state->m_ss9601_tilesize		=	TILE_8x8;
	state->m_ss9601_scrollctrl	=	0xfd;	// not written by mtrain, default to reels on
	state->m_ss9601_disable		=	0x00;

	// SS9601 Layers:

	for (int i = 0; i < 2; i++)
	{
		layer_t *l = &state->m_layers[i];

		l->tmap = tilemap_create(machine, i ? ss9601_get_tile_info_1 : ss9601_get_tile_info_0, tilemap_scan_rows, 8,8, 0x80,0x40);

		tilemap_set_transparent_pen(l->tmap, 0);

		// line scroll
		tilemap_set_scroll_rows(l->tmap, 0x200);

		l->videorams[VRAM_HI] = auto_alloc_array(machine, UINT8, 0x80 * 0x40);
		l->videorams[VRAM_LO] = auto_alloc_array(machine, UINT8, 0x80 * 0x40);

		l->scrollrams[VRAM_HI] = auto_alloc_array(machine, UINT8, 0x200);
		l->scrollrams[VRAM_LO] = auto_alloc_array(machine, UINT8, 0x200);
		memset(l->scrollrams[VRAM_HI], 0, 0x200);
		memset(l->scrollrams[VRAM_LO], 0, 0x200);
	}

	// SS9601 Reels:

	state->m_ss9601_reelrams[VRAM_HI] = auto_alloc_array(machine, UINT8, 0x2000);
	state->m_ss9601_reelrams[VRAM_LO] = auto_alloc_array(machine, UINT8, 0x2000);
	memset(state->m_ss9601_reelrams[VRAM_HI], 0, 0x2000);
	memset(state->m_ss9601_reelrams[VRAM_LO], 0, 0x2000);
	state->m_ss9601_reelrects = mtrain_reelrects;

/*
    state_save_register_global_pointer(machine, state->m_ss9601_reelrams[VRAM_HI], 0x2000);
    state_save_register_global_pointer(machine, state->m_ss9601_reelrams[VRAM_LO], 0x2000);

    state_save_register_global_pointer(machine, state->m_layers[0].scrollrams[VRAM_HI], 0x200);
    state_save_register_global_pointer(machine, state->m_layers[0].scrollrams[VRAM_LO], 0x200);

    state_save_register_global_pointer(machine, state->m_layers[1].scrollrams[VRAM_HI], 0x200);
    state_save_register_global_pointer(machine, state->m_layers[1].scrollrams[VRAM_LO], 0x200);
*/
}

static VIDEO_START( mtrain )
{
	subsino2_state *state = machine.driver_data<subsino2_state>();
	VIDEO_START_CALL( subsino2 );
	state->m_ss9601_reelrects = mtrain_reelrects;
}

static VIDEO_START( xtrain )
{
	subsino2_state *state = machine.driver_data<subsino2_state>();
	VIDEO_START_CALL( subsino2 );
	state->m_ss9601_reelrects = xtrain_reelrects;
}

static SCREEN_UPDATE( subsino2 )
{
	subsino2_state *state = screen->machine().driver_data<subsino2_state>();
	int layers_ctrl = ~state->m_ss9601_disable;
	int y;

#ifdef MAME_DEBUG
	if (screen->machine().input().code_pressed(KEYCODE_Z))
	{
		int msk = 0;
		if (screen->machine().input().code_pressed(KEYCODE_Q))	msk |= 1;
		if (screen->machine().input().code_pressed(KEYCODE_W))	msk |= 2;
		if (msk != 0) layers_ctrl &= msk;
	}
#endif

	// Line Scroll / Reel Control
	int mask_y[2] = {0, 0};
	bool l0_reel = false;
	switch ( state->m_ss9601_scrollctrl )
	{
		case 0xbf:
			mask_y[0] = ~(32-1);
			break;
		case 0xef:
			mask_y[1] = ~(8-1);
			break;
		case 0x07:
			mask_y[0] = ~(8-1);
			break;
		case 0xfd:
			l0_reel = true;
			break;
	}

	// Scroll
	for (int i = 0; i < 2; i++)
	{
		layer_t *l = &state->m_layers[i];

		tilemap_set_scroll_cols(l->tmap, 1);
		tilemap_set_scroll_rows(l->tmap, 0x200);
		tilemap_set_scrolly(l->tmap, 0, l->scroll_y + 1);

		// line scroll

		UINT16 scroll_dx = 0;
		for (y = 0; y < 0x200; y++)
		{
			if (mask_y[i])
				scroll_dx = (l->scrollrams[VRAM_HI][y & mask_y[i]] << 8) + l->scrollrams[VRAM_LO][y & mask_y[i]];

			tilemap_set_scrollx(l->tmap, y, l->scroll_x + scroll_dx);
		}
	}

	bitmap_fill(bitmap,cliprect,get_black_pen(screen->machine()));

	if (layers_ctrl & 1)
	{
		layer_t *l = &state->m_layers[0];

		if (l0_reel)
		{
			tilemap_set_scroll_rows(l->tmap, 1);
			tilemap_set_scroll_cols(l->tmap, 1);

			for (int r = 0; r < 3; r++)
			{
				rectangle visible = state->m_ss9601_reelrects[r];

				for (int x = 0; x < 0x40; x++)
				{
					visible.min_x = 8 * x;
					visible.max_x = 8 * (x+1) - 1;

					int reeladdr = (visible.min_y / 0x10) * 0x80 + x;
					UINT16 reelscroll = (state->m_ss9601_reelrams[VRAM_HI][reeladdr] << 8) + state->m_ss9601_reelrams[VRAM_LO][reeladdr];

					tilemap_set_scrollx(l->tmap, 0, (reelscroll >> 9) * 8 + l->scroll_x - visible.min_x);

					// wrap around at half tilemap (0x100)
					int reelscroll_y = (reelscroll & 0x100) + ((reelscroll + l->scroll_y - visible.min_y/0x10*0x10 + 1) & 0xff);
					int reelwrap_y = 0x100 - (reelscroll_y & 0xff);

					rectangle tmp = visible;

					// draw above the wrap around y
					if ( reelwrap_y-1 >= visible.min_y )
					{
						if ( reelwrap_y-1 <= visible.max_y )
							tmp.max_y = reelwrap_y-1;
						tilemap_set_scrolly(l->tmap, 0, reelscroll_y);
						tilemap_draw(bitmap, &tmp, l->tmap, 0, 0);
						tmp.max_y = visible.max_y;
					}

					// draw below the wrap around y
					if ( reelwrap_y <= visible.max_y )
					{
						if ( reelwrap_y >= visible.min_y )
							tmp.min_y = reelwrap_y;
						tilemap_set_scrolly(l->tmap, 0, -((reelwrap_y &0xff) | (reelscroll_y & 0x100)));
						tilemap_draw(bitmap, &tmp, l->tmap, 0, 0);
						tmp.min_y = visible.min_y;
					}
				}
			}
		}
		else
		{
			tilemap_draw(bitmap,cliprect, l->tmap, 0, 0);
		}
	}

	if (layers_ctrl & 2)	tilemap_draw(bitmap,cliprect, state->m_layers[1].tmap, 0, 0);

//  popmessage("scrl: %03x,%03x - %03x,%03x dis: %02x siz: %02x ctrl: %02x", state->m_layers[0].scroll_x,state->m_layers[0].scroll_y, state->m_layers[1].scroll_x,state->m_layers[1].scroll_y, state->m_ss9601_disable, state->m_ss9601_tilesize, state->m_ss9601_scrollctrl);

	return 0;
}

/***************************************************************************
                Palette: HMC HM86171 VGA 256 colour RAMDAC
***************************************************************************/


static WRITE8_HANDLER( hm86171_colorram_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	switch (offset)
	{
		case 0:
			state->m_hm86171_offs = data * 3;
			break;

		case 1:
			state->m_hm86171_colorram[state->m_hm86171_offs] = data;
			palette_set_color_rgb(space->machine(), state->m_hm86171_offs/3,
				pal6bit(state->m_hm86171_colorram[(state->m_hm86171_offs/3)*3+0]),
				pal6bit(state->m_hm86171_colorram[(state->m_hm86171_offs/3)*3+1]),
				pal6bit(state->m_hm86171_colorram[(state->m_hm86171_offs/3)*3+2])
			);
			state->m_hm86171_offs = (state->m_hm86171_offs+1) % (256*3);
			break;

		case 2:
			// ff?
			break;

		case 3:
			break;
	}
}


/***************************************************************************
                                Input / Output
***************************************************************************/

static WRITE8_HANDLER( dsw_mask_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_dsw_mask = data;
}

static READ8_HANDLER( dsw_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return	( (input_port_read(space->machine(), "DSW1") & state->m_dsw_mask) ? 0x01 : 0 ) |
			( (input_port_read(space->machine(), "DSW2") & state->m_dsw_mask) ? 0x02 : 0 ) |
			( (input_port_read(space->machine(), "DSW3") & state->m_dsw_mask) ? 0x04 : 0 ) |
			( (input_port_read(space->machine(), "DSW4") & state->m_dsw_mask) ? 0x08 : 0 ) ;
}


static READ8_HANDLER( vblank_bit2_r )
{
		return space->machine().primary_screen->vblank() ? 0x04 : 0x00;
}
static READ8_HANDLER( vblank_bit6_r )
{
	return space->machine().primary_screen->vblank() ? 0x40 : 0x00;
}

static WRITE8_DEVICE_HANDLER( oki_bank_bit0_w )
{
	// it writes 0x32 or 0x33
	okim6295_device *oki = downcast<okim6295_device *>(device);
	oki->set_bank_base((data & 1) * 0x40000);
}

static WRITE8_DEVICE_HANDLER( oki_bank_bit4_w )
{
	// it writes 0x23 or 0x33
	okim6295_device *oki = downcast<okim6295_device *>(device);
	oki->set_bank_base(((data >> 4) & 1) * 0x40000);
}


/***************************************************************************
                              AM188-EM Functions
***************************************************************************/

// To be moved to a cpu core


enum
{
	AM188EM_IMASK = 0x28,
	AM188EM_I0CON = 0x38
};

static READ8_HANDLER( am188em_regs_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return state->m_am188em_regs[offset];
}

static WRITE8_HANDLER( am188em_regs_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_am188em_regs[offset] = data;
}

static MACHINE_RESET( am188em )
{
	subsino2_state *state = machine.driver_data<subsino2_state>();
	// start with masked interrupts
	state->m_am188em_regs[AM188EM_IMASK+0] = 0xfd;
	state->m_am188em_regs[AM188EM_IMASK+1] = 0x07;
	state->m_am188em_regs[AM188EM_I0CON+0] = 0x0f;
	state->m_am188em_regs[AM188EM_I0CON+1] = 0x00;
}

static INTERRUPT_GEN( am188em_int0_irq )
{
	subsino2_state *state = device->machine().driver_data<subsino2_state>();
	if ( ((state->m_am188em_regs[AM188EM_IMASK+0] & 0x10) == 0) ||	// IMASK.I0 mask
		 ((state->m_am188em_regs[AM188EM_I0CON+0] & 0x08) == 0) )	// I0CON.MSK mask
		device_set_input_line_and_vector(device, 0, HOLD_LINE, 0x0c);	// INT0 (background scrolling in xplan)
}

static TIMER_DEVICE_CALLBACK( am188em_timer2_irq )
{
	subsino2_state *state = timer.machine().driver_data<subsino2_state>();
	if ((state->m_am188em_regs[AM188EM_IMASK+0] & 0x01) == 0)	// TMR mask
		cputag_set_input_line_and_vector(timer.machine(), "maincpu", 0, HOLD_LINE, 0x4c/4);
}

/***************************************************************************
                             H8/3044  Functions
***************************************************************************/

// To be removed when cpu core is updated
static TIMER_DEVICE_CALLBACK( h8_timer_irq )
{
	cputag_set_input_line(timer.machine(), "maincpu", H8_METRO_TIMER_HACK, HOLD_LINE);
}


/***************************************************************************
                                Memory Maps
***************************************************************************/

/***************************************************************************
                                Bishou Jan
***************************************************************************/


static WRITE16_HANDLER( bishjan_sel_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	if (ACCESSING_BITS_8_15)
		state->m_bishjan_sel = data >> 8;
}

static READ16_HANDLER( bishjan_serial_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	return
		(space->machine().rand() & 0x9800)	|	// bit 7 - serial communication
		(((state->m_bishjan_sel==0x12) ? 0x40:0x00) << 8) |
//      (machine.rand() & 0xff);
//      (((space->machine().primary_screen->frame_number()%60)==0)?0x18:0x00);
		0x18;
}

static WRITE16_HANDLER( bishjan_input_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	if (ACCESSING_BITS_8_15)
		state->m_bishjan_input = data >> 8;
}

static READ16_HANDLER( bishjan_input_r )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	int i;
	UINT16 res = 0xff;
	static const char *const port[] = { "KEYB_0", "KEYB_1", "KEYB_2", "KEYB_3", "KEYB_4" };

	for (i = 0; i < 5; i++)
		if (state->m_bishjan_input & (1 << i))
			res = input_port_read(space->machine(), port[i]);

	return	(res << 8) |									// high byte
			input_port_read(space->machine(), "SYSTEM") |		// low byte
			(ticket_dispenser_r(space->machine().device("hopper"), 0) ? 0x00 : 0x04)	// bit 2: hopper sensor
	;
}

static WRITE16_HANDLER( bishjan_outputs_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_outputs16[offset] = data;

	switch (offset)
	{
		case 0:
			if (ACCESSING_BITS_0_7)
			{
				// coin out         data & 0x01;
				ticket_dispenser_w(space->machine().device("hopper"), 0, (data & 0x0002) ? 0x80 : 0);	// hopper
				coin_counter_w(space->machine(), 0,	data & 0x0010 );
			}
			break;
	}

//  popmessage("0: %04x", state->m_outputs16[0]);
}


static ADDRESS_MAP_START( bishjan_map, AS_PROGRAM, 16 )
	ADDRESS_MAP_GLOBAL_MASK(0xffffff)

	AM_RANGE( 0x000000, 0x07ffff ) AM_ROM AM_REGION("maincpu", 0)
	AM_RANGE( 0x080000, 0x0fffff ) AM_ROM AM_REGION("maincpu", 0)

	AM_RANGE( 0x200000, 0x207fff ) AM_RAM AM_SHARE("nvram")	// battery

	// read lo (L1)   (only half tilemap?)
	AM_RANGE( 0x412000, 0x412fff ) AM_READ8( ss9601_videoram_1_lo_r, 0xffff )
	AM_RANGE( 0x413000, 0x4131ff ) AM_READWRITE8( ss9601_scrollram_1_lo_r, ss9601_scrollram_1_lo_w, 0xffff )
	// read lo (REEL)
	AM_RANGE( 0x416000, 0x416fff ) AM_READ8( ss9601_reelram_lo_r, 0xffff )
	AM_RANGE( 0x417000, 0x4171ff ) AM_READWRITE8( ss9601_scrollram_0_lo_r, ss9601_scrollram_0_lo_w, 0xffff )

	// read hi (L1)
	AM_RANGE( 0x422000, 0x422fff ) AM_READ8( ss9601_videoram_1_hi_r, 0xffff )
	AM_RANGE( 0x423000, 0x4231ff ) AM_READWRITE8( ss9601_scrollram_1_hi_r, ss9601_scrollram_1_hi_w, 0xffff )
	// read hi (REEL)
	AM_RANGE( 0x426000, 0x426fff ) AM_READ8( ss9601_reelram_hi_r, 0xffff )
	AM_RANGE( 0x427000, 0x4271ff ) AM_READWRITE8( ss9601_scrollram_0_hi_r, ss9601_scrollram_0_hi_w, 0xffff )

	// write both (L1)
	AM_RANGE( 0x430000, 0x431fff ) AM_WRITE8( ss9601_videoram_1_hi_lo_w, 0xffff )
	AM_RANGE( 0x432000, 0x432fff ) AM_WRITE8( ss9601_videoram_1_hi_lo_w, 0xffff )
	AM_RANGE( 0x433000, 0x4331ff ) AM_WRITE8( ss9601_scrollram_1_hi_lo_w, 0xffff )
	// write both (L0 & REEL)
	AM_RANGE( 0x434000, 0x435fff ) AM_WRITE8( ss9601_videoram_0_hi_lo_w, 0xffff )
	AM_RANGE( 0x436000, 0x436fff ) AM_WRITE8( ss9601_reelram_hi_lo_w, 0xffff )
	AM_RANGE( 0x437000, 0x4371ff ) AM_WRITE8( ss9601_scrollram_0_hi_lo_w, 0xffff )

	AM_RANGE( 0x600000, 0x600001 ) AM_READNOP AM_WRITE( bishjan_sel_w )
	AM_RANGE( 0x600040, 0x600041 ) AM_WRITE8( ss9601_scrollctrl_w, 0xff00 )
	AM_RANGE( 0x600060, 0x600063 ) AM_WRITE8( hm86171_colorram_w, 0xffff )
	AM_RANGE( 0x600080, 0x600081 ) AM_WRITE8( ss9601_tilesize_w, 0xff00 )
	AM_RANGE( 0x6000a0, 0x6000a1 ) AM_WRITE8( ss9601_byte_lo_w, 0xff00 )

	AM_RANGE( 0xa0001e, 0xa0001f ) AM_WRITE8( ss9601_disable_w, 0x00ff )

	AM_RANGE( 0xa00020, 0xa00025 ) AM_WRITE8( ss9601_scroll_w, 0xffff )

	AM_RANGE( 0xc00000, 0xc00001 ) AM_READ_PORT("DSW")								// SW1
	AM_RANGE( 0xc00002, 0xc00003 ) AM_READ_PORT("JOY") AM_WRITE( bishjan_input_w )	// IN C
	AM_RANGE( 0xc00004, 0xc00005 ) AM_READ( bishjan_input_r )						// IN A & B
	AM_RANGE( 0xc00006, 0xc00007 ) AM_READ( bishjan_serial_r )						// IN D
	AM_RANGE( 0xc00008, 0xc00009 ) AM_READ_PORT("RESET") AM_WRITE( bishjan_outputs_w ) AM_BASE_MEMBER(subsino2_state, m_outputs16 )
ADDRESS_MAP_END

/***************************************************************************
                       Express Card / Top Card
***************************************************************************/

static WRITE8_HANDLER( expcard_outputs_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_outputs[offset] = data;

	switch (offset)
	{
		case 0:	// D
			// 0x40 = serial out ? (at boot)
			break;

		case 1:	// C
			set_led_status(space->machine(), 0,	data & 0x02);	// raise
			break;

		case 2:	// B
			set_led_status(space->machine(), 1,	data & 0x04);	// hold 4 / small & hold 5 / big ?
			set_led_status(space->machine(), 2,	data & 0x08);	// hold 1 / bet
			set_led_status(space->machine(), 3,	data & 0x10);	// hold 2 / take ?
			set_led_status(space->machine(), 4,	data & 0x20);	// hold 3 / double up ?
			break;

		case 3:	// A
			coin_counter_w(space->machine(), 0,	data & 0x01 );	// coin in
			coin_counter_w(space->machine(), 1,	data & 0x02 );	// key in

			set_led_status(space->machine(), 5,	data & 0x10);	// start
			break;
	}

//  popmessage("0: %02x - 1: %02x - 2: %02x - 3: %02x", state->m_outputs[0], state->m_outputs[1], state->m_outputs[2], state->m_outputs[3]);
}

/***************************************************************************
                                Magic Train
***************************************************************************/

static WRITE8_HANDLER( mtrain_outputs_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_outputs[offset] = data;

	switch (offset)
	{
		case 0:
			coin_counter_w(space->machine(), 0,	data & 0x01 );	// key in
			coin_counter_w(space->machine(), 1,	data & 0x02 );	// coin in
			coin_counter_w(space->machine(), 2,	data & 0x10 );	// pay out
//          coin_counter_w(space->machine(), 3,   data & 0x20 );  // hopper motor
			break;

		case 1:
			set_led_status(space->machine(), 0,	data & 0x01);	// stop reel?
			set_led_status(space->machine(), 1,	data & 0x02);	// stop reel? (double or take)
			set_led_status(space->machine(), 2,	data & 0x04);	// start all
			set_led_status(space->machine(), 3,	data & 0x08);	// bet / stop all
			set_led_status(space->machine(), 4,	data & 0x20);	// stop reel? (double or take)
			break;

		case 2:
			break;

		case 3:
			break;
	}

//  popmessage("0: %02x - 1: %02x - 2: %02x - 3: %02x", state->m_outputs[0], state->m_outputs[1], state->m_outputs[2], state->m_outputs[3]);
}

static WRITE8_HANDLER( mtrain_videoram_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	vram_t vram = (state->m_ss9601_byte_lo & 0x08) ? VRAM_HI : VRAM_LO;
	switch (state->m_ss9601_byte_lo & (~0x08))
	{
		case 0x00:	ss9601_videoram_w(&state->m_layers[1], vram, space, offset,        data);
					ss9601_videoram_w(&state->m_layers[1], vram, space, offset+0x1000, data);	break;

		case 0x04:	ss9601_videoram_w(&state->m_layers[0], vram, space, offset,        data);
					ss9601_videoram_w(&state->m_layers[0], vram, space, offset+0x1000, data);	break;

		case 0x06:	state->m_ss9601_reelrams[vram][offset] = data;	break;
	}
}

static WRITE8_HANDLER( mtrain_tilesize_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_ss9601_tilesize = data;

	tilesize_t sizes[2];
	switch (data)
	{
		case 0x00:
			sizes[0] = TILE_8x8;
			sizes[1] = TILE_8x8;
			break;

		case 0x01:
			sizes[0] = TILE_8x32;
			sizes[1] = TILE_8x8;
			break;

		default:
			sizes[0] = TILE_8x8;
			sizes[1] = TILE_8x8;

			logerror("%s: warning, unknown tilesize = %02x\n", space->machine().describe_context(), data);
			popmessage("UNKNOWN TILESIZE %02X", data);
			break;
	}

	for (int i = 0; i < 2; i++)
	{
		layer_t *l = &state->m_layers[i];

		if (l->tilesize != sizes[i])
		{
			l->tilesize = sizes[i];
			tilemap_mark_all_tiles_dirty(l->tmap);
		}
	}
}

static READ8_HANDLER( mtrain_prot_r )
{
	return "SUBSION"[offset];
}

static ADDRESS_MAP_START( mtrain_map, AS_PROGRAM, 8 )
	AM_RANGE( 0x00000, 0x06fff ) AM_ROM

	AM_RANGE( 0x07800, 0x07fff ) AM_RAM AM_SHARE("nvram")	// battery

	AM_RANGE( 0x08000, 0x08fff ) AM_WRITE( mtrain_videoram_w )

	AM_RANGE( 0x0911f, 0x0911f ) AM_WRITE( ss9601_disable_w )
	AM_RANGE( 0x09120, 0x09125 ) AM_WRITE( ss9601_scroll_w )

	AM_RANGE( 0x0912f, 0x0912f ) AM_WRITE( ss9601_byte_lo_w )

	AM_RANGE( 0x09140, 0x09142 ) AM_WRITE( mtrain_outputs_w ) AM_BASE_MEMBER(subsino2_state, m_outputs )
	AM_RANGE( 0x09143, 0x09143 ) AM_READ_PORT( "IN D" )	// (not shown in system test) 0x40 serial out, 0x80 serial in
	AM_RANGE( 0x09144, 0x09144 ) AM_READ_PORT( "IN A" )	// A
	AM_RANGE( 0x09145, 0x09145 ) AM_READ_PORT( "IN B" )	// B
	AM_RANGE( 0x09146, 0x09146 ) AM_READ_PORT( "IN C" )	// C
	AM_RANGE( 0x09147, 0x09147 ) AM_READ ( dsw_r )
	AM_RANGE( 0x09148, 0x09148 ) AM_WRITE( dsw_mask_w )

	AM_RANGE( 0x09152, 0x09152 ) AM_WRITE( vblank_bit2_r ) AM_DEVWRITE( "oki", oki_bank_bit0_w )

	AM_RANGE( 0x09158, 0x0915e ) AM_READ( mtrain_prot_r )

	AM_RANGE( 0x09160, 0x09163 ) AM_WRITE( hm86171_colorram_w )
	AM_RANGE( 0x09164, 0x09164 ) AM_DEVREADWRITE_MODERN("oki", okim6295_device, read, write)
	AM_RANGE( 0x09168, 0x09168 ) AM_WRITE( mtrain_tilesize_w )

	AM_RANGE( 0x09800, 0x09fff ) AM_RAM

	AM_RANGE( 0x0a000, 0x0ffff ) AM_ROM
ADDRESS_MAP_END

static ADDRESS_MAP_START( mtrain_io, AS_IO, 8 )
	AM_RANGE( 0x0000, 0x003f ) AM_RAM // internal regs
ADDRESS_MAP_END

/***************************************************************************
                          Sakura Love - Ying Hua Lian
***************************************************************************/

static WRITE8_HANDLER( saklove_outputs_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_outputs[offset] = data;

	switch (offset)
	{
		case 0:
			coin_counter_w(space->machine(), 0,	data & 0x01 );	// coin in
			coin_counter_w(space->machine(), 1,	data & 0x02 );	// key in
			break;

		case 1:
			break;

		case 2:
			break;

		case 3:
			// 1, 2, 4
			break;
	}

//  popmessage("0: %02x - 1: %02x - 2: %02x - 3: %02x", state->m_outputs[0], state->m_outputs[1], state->m_outputs[2], state->m_outputs[3]);
}

static ADDRESS_MAP_START( saklove_map, AS_PROGRAM, 8 )
	AM_RANGE(0x00000, 0x07fff) AM_RAM AM_SHARE("nvram")	// battery

	// read lo (L1)   (only half tilemap?)
	AM_RANGE(0x12000, 0x12fff) AM_READWRITE( ss9601_videoram_1_lo_r,  ss9601_videoram_1_lo_w )
	AM_RANGE(0x13000, 0x131ff) AM_READWRITE( ss9601_scrollram_1_lo_r, ss9601_scrollram_1_lo_w )
	// read lo (L0)
	AM_RANGE(0x16000, 0x16fff) AM_READWRITE( ss9601_videoram_0_lo_r,  ss9601_videoram_0_lo_w )
	AM_RANGE(0x17000, 0x171ff) AM_READWRITE( ss9601_scrollram_0_lo_r, ss9601_scrollram_0_lo_w )

	// read hi (L1)
	AM_RANGE(0x22000, 0x22fff) AM_READWRITE( ss9601_videoram_1_hi_r,  ss9601_videoram_1_hi_w )
	AM_RANGE(0x23000, 0x231ff) AM_READWRITE( ss9601_scrollram_1_hi_r, ss9601_scrollram_1_hi_w )
	// read hi (L0)
	AM_RANGE(0x26000, 0x26fff) AM_READWRITE( ss9601_videoram_0_hi_r,  ss9601_videoram_0_hi_w )
	AM_RANGE(0x27000, 0x271ff) AM_READWRITE( ss9601_scrollram_0_hi_r, ss9601_scrollram_0_hi_w )

	// write both (L1)
	AM_RANGE(0x30000, 0x31fff) AM_READWRITE( ss9601_videoram_1_hi_r, ss9601_videoram_1_hi_lo_w )
	// write both (L0)
	AM_RANGE(0x34000, 0x35fff) AM_READWRITE( ss9601_videoram_0_hi_r, ss9601_videoram_0_hi_lo_w )

	AM_RANGE(0xe0000, 0xfffff) AM_ROM AM_REGION("maincpu",0)
ADDRESS_MAP_END

static ADDRESS_MAP_START( saklove_io, AS_IO, 8 )
	AM_RANGE(0x0000, 0x0000) AM_WRITE( ss9601_scrollctrl_w )

	AM_RANGE(0x0020, 0x0020) AM_DEVREADWRITE_MODERN("oki", okim6295_device, read, write)
	AM_RANGE(0x0040, 0x0041) AM_DEVWRITE( "ymsnd", ym3812_w )

	AM_RANGE(0x0060, 0x0063) AM_WRITE( hm86171_colorram_w )

	AM_RANGE(0x0080, 0x0080) AM_WRITE( ss9601_tilesize_w )
	AM_RANGE(0x00a0, 0x00a0) AM_WRITE( ss9601_byte_lo_w )
	AM_RANGE(0x021f, 0x021f) AM_WRITE( ss9601_disable_w )
	AM_RANGE(0x0220, 0x0225) AM_WRITE( ss9601_scroll_w )

	AM_RANGE(0x0300, 0x0303) AM_WRITE( saklove_outputs_w ) AM_BASE_MEMBER(subsino2_state, m_outputs )
	AM_RANGE(0x0303, 0x0303) AM_READ_PORT( "IN D" )	// 0x40 serial out, 0x80 serial in
	AM_RANGE(0x0304, 0x0304) AM_READ_PORT( "IN A" )
	AM_RANGE(0x0305, 0x0305) AM_READ_PORT( "IN B" )
	AM_RANGE(0x0306, 0x0306) AM_READ_PORT( "IN C" )

	AM_RANGE(0x0307, 0x0307) AM_READ ( dsw_r )
	AM_RANGE(0x0308, 0x0308) AM_WRITE( dsw_mask_w )

	AM_RANGE(0x0312, 0x0312) AM_READ( vblank_bit2_r ) AM_DEVWRITE( "oki", oki_bank_bit0_w )

	// Peripheral Control Block
	AM_RANGE(0xff00, 0xffff) AM_READWRITE( am188em_regs_r, am188em_regs_w ) AM_BASE_MEMBER(subsino2_state, m_am188em_regs )
ADDRESS_MAP_END

/***************************************************************************
                                X-Plan
***************************************************************************/

static WRITE8_HANDLER( xplan_outputs_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_outputs[offset] = data;

	switch (offset)
	{
		case 0:
			// 0x40 = serial out ? (at boot)
			break;

		case 1:
			set_led_status(space->machine(), 0,	data & 0x02);	// raise
			break;

		case 2:	// B
			set_led_status(space->machine(), 1,	data & 0x04);	// hold 1 / big ?
			set_led_status(space->machine(), 2,	data & 0x08);	// hold 5 / bet
			set_led_status(space->machine(), 3,	data & 0x10);	// hold 4 ?
			set_led_status(space->machine(), 4,	data & 0x20);	// hold 2 / double up
			set_led_status(space->machine(), 5,	data & 0x40);	// hold 3 / small ?
			break;

		case 3:	// A
			coin_counter_w(space->machine(), 0,	data & 0x01 );
			coin_counter_w(space->machine(), 1,	data & 0x02 );

			set_led_status(space->machine(), 6,	data & 0x10);	// start / take
			break;
	}

//  popmessage("0: %02x - 1: %02x - 2: %02x - 3: %02x", state->m_outputs[0], state->m_outputs[1], state->m_outputs[2], state->m_outputs[3]);
}

static ADDRESS_MAP_START( xplan_map, AS_PROGRAM, 8 )
	AM_RANGE(0x00000, 0x07fff) AM_RAM AM_SHARE("nvram")	// battery

	// write both (L1, byte_lo2)
	AM_RANGE( 0x10000, 0x11fff ) AM_WRITE( ss9601_videoram_1_hi_lo2_w )
	// read lo (L1)   (only half tilemap?)
	AM_RANGE( 0x12000, 0x12fff ) AM_READ( ss9601_videoram_1_lo_r )
	AM_RANGE( 0x13000, 0x131ff ) AM_READWRITE( ss9601_scrollram_1_lo_r, ss9601_scrollram_1_lo_w )

	// write both (L0, byte_lo2)
	AM_RANGE( 0x14000, 0x15fff ) AM_WRITE( ss9601_videoram_0_hi_lo2_w )
	// read lo (REEL)
	AM_RANGE( 0x16000, 0x16fff ) AM_READ( ss9601_reelram_lo_r )
	AM_RANGE( 0x17000, 0x171ff ) AM_READWRITE( ss9601_scrollram_0_lo_r, ss9601_scrollram_0_lo_w )

	// read hi (L1)
	AM_RANGE( 0x22000, 0x22fff ) AM_READ( ss9601_videoram_1_hi_r )
	AM_RANGE( 0x23000, 0x231ff ) AM_READWRITE( ss9601_scrollram_1_hi_r, ss9601_scrollram_1_hi_w )
	// read hi (REEL)
	AM_RANGE( 0x26000, 0x26fff ) AM_READ( ss9601_reelram_hi_r )
	AM_RANGE( 0x27000, 0x271ff ) AM_READWRITE( ss9601_scrollram_0_hi_r, ss9601_scrollram_0_hi_w )

	// write both (L1, byte_lo)
	AM_RANGE( 0x30000, 0x31fff ) AM_WRITE( ss9601_videoram_1_hi_lo_w )
	AM_RANGE( 0x32000, 0x32fff ) AM_WRITE( ss9601_videoram_1_hi_lo_w )
	AM_RANGE( 0x33000, 0x331ff ) AM_WRITE( ss9601_scrollram_1_hi_lo_w )
	// write both (L0 & REEL, byte_lo)
	AM_RANGE( 0x34000, 0x35fff ) AM_WRITE( ss9601_videoram_0_hi_lo_w )
	AM_RANGE( 0x36000, 0x36fff ) AM_WRITE( ss9601_reelram_hi_lo_w )
	AM_RANGE( 0x37000, 0x371ff ) AM_WRITE( ss9601_scrollram_0_hi_lo_w )

	AM_RANGE(0xc0000, 0xfffff) AM_ROM AM_REGION("maincpu",0)
ADDRESS_MAP_END

static ADDRESS_MAP_START( xplan_io, AS_IO, 8 )
	AM_RANGE(0x0000, 0x0000) AM_DEVREADWRITE_MODERN("oki", okim6295_device, read, write)

	AM_RANGE(0x0020, 0x0020) AM_WRITE( ss9601_byte_lo2_w )

	AM_RANGE(0x0040, 0x0040) AM_WRITE( ss9601_scrollctrl_w )

	AM_RANGE(0x0060, 0x0063) AM_WRITE( hm86171_colorram_w )
	AM_RANGE(0x0080, 0x0080) AM_WRITE( ss9601_tilesize_w )
	AM_RANGE(0x00a0, 0x00a0) AM_WRITE( ss9601_byte_lo_w )

	AM_RANGE(0x021f, 0x021f) AM_WRITE( ss9601_disable_w )
	AM_RANGE(0x0220, 0x0225) AM_WRITE( ss9601_scroll_w )

	AM_RANGE(0x0235, 0x0235) AM_NOP	// INT0 Ack.?

	AM_RANGE(0x0300, 0x0300) AM_READ( vblank_bit6_r ) AM_DEVWRITE( "oki", oki_bank_bit4_w )
	AM_RANGE(0x0301, 0x0301) AM_WRITE( dsw_mask_w )
	AM_RANGE(0x0302, 0x0302) AM_READ ( dsw_r )
	AM_RANGE(0x0303, 0x0303) AM_READ_PORT( "IN C" )
	AM_RANGE(0x0304, 0x0304) AM_READ_PORT( "IN B" )
	AM_RANGE(0x0305, 0x0305) AM_READ_PORT( "IN A" )
	AM_RANGE(0x0306, 0x0306) AM_READ_PORT( "IN D" )	// 0x40 serial out, 0x80 serial in

	// 306 = d, 307 = c, 308 = b, 309 = a
	AM_RANGE(0x0306, 0x0309) AM_WRITE( xplan_outputs_w ) AM_BASE_MEMBER(subsino2_state, m_outputs )

	// Peripheral Control Block
	AM_RANGE(0xff00, 0xffff) AM_READWRITE( am188em_regs_r, am188em_regs_w ) AM_BASE_MEMBER(subsino2_state, m_am188em_regs )
ADDRESS_MAP_END

/***************************************************************************
                                X-Train
***************************************************************************/

static WRITE8_HANDLER( xtrain_outputs_w )
{
	subsino2_state *state = space->machine().driver_data<subsino2_state>();
	state->m_outputs[offset] = data;

	switch (offset)
	{
		case 0:	// D
			// 0x40 = serial out ? (at boot)
			break;

		case 1:	// C
			set_led_status(space->machine(), 0,	data & 0x02);	// re-double
			set_led_status(space->machine(), 1,	data & 0x04);	// half double
			break;

		case 2:	// B
			set_led_status(space->machine(), 2,	data & 0x02);	// hold 3 / small
			set_led_status(space->machine(), 3,	data & 0x04);	// hold 2 / big
			set_led_status(space->machine(), 4,	data & 0x08);	// bet
			set_led_status(space->machine(), 5,	data & 0x10);	// hold1 / take
			set_led_status(space->machine(), 6,	data & 0x20);	// double up
			break;

		case 3:	// A
			coin_counter_w(space->machine(), 0,	data & 0x01 );	// coin in
			coin_counter_w(space->machine(), 1,	data & 0x02 );	// key in

			set_led_status(space->machine(), 7,	data & 0x10);	// start
			break;
	}

//  popmessage("0: %02x - 1: %02x - 2: %02x - 3: %02x", state->m_outputs[0], state->m_outputs[1], state->m_outputs[2], state->m_outputs[3]);
}

static ADDRESS_MAP_START( expcard_io, AS_IO, 8 )
	// 306 = d, 307 = c, 308 = b, 309 = a
	AM_RANGE(0x0306, 0x0309) AM_WRITE( expcard_outputs_w ) AM_BASE_MEMBER(subsino2_state, m_outputs )

	AM_IMPORT_FROM( xplan_io )
ADDRESS_MAP_END

static ADDRESS_MAP_START( xtrain_io, AS_IO, 8 )
	// 306 = d, 307 = c, 308 = b, 309 = a
	AM_RANGE(0x0306, 0x0309) AM_WRITE( xtrain_outputs_w ) AM_BASE_MEMBER(subsino2_state, m_outputs )

	AM_IMPORT_FROM( xplan_io )
ADDRESS_MAP_END


/***************************************************************************
                                Graphics Layout
***************************************************************************/

static const gfx_layout ss9601_8x8_layout =
{
	8,8,
	RGN_FRAC(1,1),
	8,
	{ STEP8(0,1) },
	{ STEP8(0,8) },
	{ STEP8(0,8*8) },
	8*8*8
};

static GFXDECODE_START( ss9601 )
	GFXDECODE_ENTRY( "tilemap", 0, ss9601_8x8_layout, 0, 1 )
GFXDECODE_END


/***************************************************************************
                                Input Ports
***************************************************************************/

/***************************************************************************
                                Bishou Jan
***************************************************************************/

static INPUT_PORTS_START( bishjan )
	PORT_START("RESET")
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)

	PORT_START("DSW")	// SW1
	PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Controls ) )
	PORT_DIPSETTING(      0x0001, "Keyboard" )
	PORT_DIPSETTING(      0x0000, DEF_STR( Joystick ) )
	PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x0002, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x0004, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x0008, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x0010, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x0020, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x0040, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x0080, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )

	PORT_START("JOY")	// IN C
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_START1			) PORT_NAME("1 Player Start (Joy Mode)")	// start (joy)
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN	)	// down (joy)
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT	)	// left (joy)
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT	)	// right (joy)
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON1		)	// n (joy)
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_MAHJONG_BET	) PORT_NAME("P1 Mahjong Bet (Joy Mode)")	// bet (joy)
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON2		)	// select (joy)

	PORT_START("SYSTEM") // IN A
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_SERVICE		) PORT_IMPULSE(1)	// service mode
	PORT_BIT( 0x0004, IP_ACTIVE_HIGH,IPT_SPECIAL		)	// hopper sensor
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_SERVICE1		)	// stats
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_SERVICE2		)	// pay out? "hopper empty"
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_COIN1			)	PORT_IMPULSE(2)	// coin
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_SERVICE3		)	// pay out? "hopper empty"
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_COIN2			)	PORT_IMPULSE(2)	// coin

	PORT_START("KEYB_0")	// IN B(0)
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_MAHJONG_A		)	// a
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_MAHJONG_E		)	// e
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_MAHJONG_I		)	// i
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_MAHJONG_M		)	// m
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN		)	// i2
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_START1			)	// b2 (start)
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN		)

	PORT_START("KEYB_1")	// IN B(1)
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_MAHJONG_B		)	// b
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_MAHJONG_F		)	// f
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_MAHJONG_J		)	// j
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_MAHJONG_N		)	// n
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN		)	// l2
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_MAHJONG_BET	)	// c2 (bet)
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN		)

	PORT_START("KEYB_2")	// IN B(2)
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_MAHJONG_C		)	// c
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_MAHJONG_G		)	// g
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_MAHJONG_K		)	// k
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN		)	// k2
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN		)	// m2
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN		)

	PORT_START("KEYB_3")	// IN B(3)
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_MAHJONG_D		)	// d
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_MAHJONG_H		)	// h
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_MAHJONG_L		)	// l
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN		)	// j2
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN		)

	PORT_START("KEYB_4")	// IN B(4)
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN		)	// g2
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN		)	// e2
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN		)	// d2
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN		)	// f2
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN		)
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN		)
INPUT_PORTS_END

/***************************************************************************
                       Express Card / Top Card
***************************************************************************/

static INPUT_PORTS_START( expcard )
	PORT_START("DSW1")
	// unused?
	PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x01, "SW1:1" )
	PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW1:2" )
	PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW1:3" )
	PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW1:4" )
	PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "SW1:5" )
	PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW1:6" )
	PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW1:7" )
	PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW1:8" )

	PORT_START("DSW2")
	// not populated

	PORT_START("DSW3")
	// not populated

	PORT_START("DSW4")
	// not populated

	PORT_START("IN A")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN     )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN     )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN     )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN     ) PORT_NAME("Raise") PORT_CODE(KEYCODE_M)	// raise
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN     )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1      ) PORT_NAME("Start")					// start
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_POKER_HOLD4 ) PORT_NAME("Hold 4 / Small")		// hold 4 / small / decrease sample in test mode
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) PORT_NAME("Hold 1 / Bet")			// hold 1 / bet

	PORT_START("IN B")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD2 ) PORT_NAME("Hold 2 / Take" )		// hold 2 / take
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD3 ) PORT_NAME("Hold 3 / Double Up" )	// hold 3 / double up
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN     )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN     )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD5 ) PORT_NAME("Hold 5 / Big")			// hold 5 / big / increase sample in test mode
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN     )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1       )									// coin in
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN     )

	PORT_START("IN C")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK  )									// stats (keep pressed during boot for service mode)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_POKER_CANCEL )									// cancel?
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN      )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN      )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN )									// key in
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN      )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE      ) PORT_IMPULSE(1)					// service mode
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN      )

	PORT_START("IN D")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN      )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN      )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN      )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN      )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER        ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)	// reset
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN      )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN      )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL      )									// serial in?
INPUT_PORTS_END

/***************************************************************************
                               Magic Train
***************************************************************************/

static INPUT_PORTS_START( mtrain )
	PORT_START("DSW1")
	PORT_DIPNAME( 0x07, 0x00, DEF_STR( Coinage ) )		PORT_DIPLOCATION("SW1:1,2,3")
	PORT_DIPSETTING(    0x01, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(    0x02, DEF_STR( 1C_2C ) )
	PORT_DIPSETTING(    0x03, DEF_STR( 1C_5C ) )
	PORT_DIPSETTING(    0x00, "1 Coin / 10 Credits" )
	PORT_DIPSETTING(    0x04, "1 Coin / 20 Credits" )
	PORT_DIPSETTING(    0x05, "1 Coin / 25 Credits" )
	PORT_DIPSETTING(    0x06, "1 Coin / 50 Credits" )
	PORT_DIPSETTING(    0x07, "1 Coin / 100 Credits" )
	PORT_DIPNAME( 0x38, 0x00, "Key Coinage" )			PORT_DIPLOCATION("SW1:4,5,6")
	PORT_DIPSETTING(    0x08, "1 Key / 1 Credits" )
	PORT_DIPSETTING(    0x10, "1 Key / 2 Credits" )
	PORT_DIPSETTING(    0x18, "1 Key / 5 Credits" )
	PORT_DIPSETTING(    0x00, "1 Key / 10 Credits" )
	PORT_DIPSETTING(    0x20, "1 Key / 20 Credits" )
	PORT_DIPSETTING(    0x28, "1 Key / 25 Credits" )
	PORT_DIPSETTING(    0x30, "1 Key / 50 Credits" )
	PORT_DIPSETTING(    0x38, "1 Key / 100 Credits" )
	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW1:7")
	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW1:8")
	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )

	PORT_START("DSW2")
	PORT_DIPNAME( 0x03, 0x00, "Minimum Bet" )			PORT_DIPLOCATION("SW2:1,2")
	PORT_DIPSETTING(    0x01, "1" )
	PORT_DIPSETTING(    0x00, "8" )
	PORT_DIPSETTING(    0x02, "20" )
	PORT_DIPSETTING(    0x03, "40" )
	PORT_DIPNAME( 0x0c, 0x0c, "Max Bet" )				PORT_DIPLOCATION("SW2:3,4")
	PORT_DIPSETTING(    0x08, "20" )
	PORT_DIPSETTING(    0x04, "40" )
	PORT_DIPSETTING(    0x00, "60" )
	PORT_DIPSETTING(    0x0c, "80" )
	PORT_DIPNAME( 0x10, 0x10, DEF_STR( Demo_Sounds ) )	PORT_DIPLOCATION("SW2:5")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x10, DEF_STR( On ) )
	PORT_DIPNAME( 0x60, 0x60, "Game Limit" )			PORT_DIPLOCATION("SW2:6,7")
	PORT_DIPSETTING(    0x20, "10k" )
	PORT_DIPSETTING(    0x00, "20k" )
	PORT_DIPSETTING(    0x40, "30k" )
	PORT_DIPSETTING(    0x60, "60k" )
	PORT_DIPNAME( 0x80, 0x80, "Double Up" )				PORT_DIPLOCATION("SW2:8")
	PORT_DIPSETTING(    0x00, DEF_STR( No ) )
	PORT_DIPSETTING(    0x80, DEF_STR( Yes ) )

	PORT_START("DSW3")
	PORT_DIPNAME( 0x07, 0x07, "Win Rate" )		PORT_DIPLOCATION("SW3:1,2,3")
	PORT_DIPSETTING(    0x07, "55%" )
	PORT_DIPSETTING(    0x06, "60%" )
	PORT_DIPSETTING(    0x05, "65%" )
	PORT_DIPSETTING(    0x04, "70%" )
	PORT_DIPSETTING(    0x03, "75%" )
	PORT_DIPSETTING(    0x00, "80%" )
	PORT_DIPSETTING(    0x02, "85%" )
	PORT_DIPSETTING(    0x01, "90%" )
	PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW3:4")
	PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW3:5")	// used
	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW3:6")
	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW3:7")
	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW3:8")
	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )

	PORT_START("DSW4")
	PORT_DIPNAME( 0x07, 0x07, "Double-Up Rate" )		PORT_DIPLOCATION("SW4:1,2,3")
	PORT_DIPSETTING(    0x00, "82%" )
	PORT_DIPSETTING(    0x01, "84%" )
	PORT_DIPSETTING(    0x02, "86%" )
	PORT_DIPSETTING(    0x03, "88%" )
	PORT_DIPSETTING(    0x04, "90%" )
	PORT_DIPSETTING(    0x05, "92%" )
	PORT_DIPSETTING(    0x06, "94%" )
	PORT_DIPSETTING(    0x07, "96%" )
	PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW4:4")
	PORT_DIPSETTING(    0x00, "5k" )
	PORT_DIPSETTING(    0x08, "10k" )
	PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW4:6")
	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW4:6")
	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW4:7")
	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW4:8")
	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )

	PORT_START("IN A")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START      )	PORT_CODE(KEYCODE_N)	PORT_NAME("Start All")
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_BET )	PORT_NAME("Bet / Stop All")
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER      ) PORT_CODE(KEYCODE_Z)	PORT_NAME("Info / Double?")
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN    )

	PORT_START("IN B")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN  ) PORT_IMPULSE(5)			// key in
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1         )							// coin in
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK   )	// stats
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE       )	// service mode
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )	// payout (hopper error)
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT )	// key out

	PORT_START("IN C")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SLOT_STOP3 )	PORT_NAME("Stop 3")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SLOT_STOP2 )	PORT_NAME("Stop 2")
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SLOT_STOP1 )	PORT_NAME("Stop 1 / Take")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN    )

	PORT_START("IN D")	// not shown in test mode
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER    ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL  )	// serial in?
INPUT_PORTS_END

/***************************************************************************
                          Sakura Love - Ying Hua Lian
***************************************************************************/

static INPUT_PORTS_START( saklove )
	PORT_START("DSW1")
	PORT_DIPNAME( 0x07, 0x00, "Coin" )
	PORT_DIPSETTING(    0x01, "1" )
	PORT_DIPSETTING(    0x02, "5" )
	PORT_DIPSETTING(    0x00, "10" )
	PORT_DIPSETTING(    0x03, "20" )
	PORT_DIPSETTING(    0x04, "25" )
	PORT_DIPSETTING(    0x05, "50" )
	PORT_DIPSETTING(    0x06, "100" )
	PORT_DIPSETTING(    0x07, "300" )
	PORT_DIPNAME( 0x38, 0x00, "Key In" )
	PORT_DIPSETTING(    0x08, "10" )
	PORT_DIPSETTING(    0x10, "20" )
	PORT_DIPSETTING(    0x18, "25" )
	PORT_DIPSETTING(    0x20, "50" )
	PORT_DIPSETTING(    0x00, "100" )
	PORT_DIPSETTING(    0x28, "300" )
	PORT_DIPSETTING(    0x30, "500" )
	PORT_DIPSETTING(    0x38, "1000" )
	PORT_DIPNAME( 0x40, 0x00, "Pay Out" )
	PORT_DIPSETTING(    0x00, "Coin" )
	PORT_DIPSETTING(    0x40, "Key In" )
	PORT_DIPNAME( 0x80, 0x00, "Key Out" )
	PORT_DIPSETTING(    0x80, "Coin" )
	PORT_DIPSETTING(    0x00, "Key In" )

	PORT_START("DSW2")
	PORT_DIPNAME( 0x03, 0x00, "Min Bet" )
	PORT_DIPSETTING(    0x00, "1" )
	PORT_DIPSETTING(    0x01, "5" )
	PORT_DIPSETTING(    0x02, "10" )
	PORT_DIPSETTING(    0x03, "20" )
	PORT_DIPNAME( 0x0c, 0x00, "Max Bet" )
	PORT_DIPSETTING(    0x0c, "10" )
	PORT_DIPSETTING(    0x08, "20" )
	PORT_DIPSETTING(    0x04, "40" )
	PORT_DIPSETTING(    0x00, "50" )
	PORT_DIPUNKNOWN( 0x10, 0x00 )
	PORT_DIPUNKNOWN( 0x20, 0x00 )
	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Demo_Sounds ) )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x40, DEF_STR( On ) )
	PORT_DIPNAME( 0x80, 0x00, "Double Up" )
	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )

	PORT_START("DSW3")
	PORT_DIPNAME( 0x07, 0x00, "Win Rate (%)" )
	PORT_DIPSETTING(    0x01, "55" )
	PORT_DIPSETTING(    0x02, "60" )
	PORT_DIPSETTING(    0x03, "65" )
	PORT_DIPSETTING(    0x04, "70" )
	PORT_DIPSETTING(    0x05, "75" )
	PORT_DIPSETTING(    0x00, "80" )
	PORT_DIPSETTING(    0x06, "85" )
	PORT_DIPSETTING(    0x07, "90" )
	PORT_DIPNAME( 0x18, 0x00, "Game Limit" )
	PORT_DIPSETTING(    0x08, "10k" )
	PORT_DIPSETTING(    0x00, "20k" )
	PORT_DIPSETTING(    0x10, "60k" )
	PORT_DIPSETTING(    0x18, "80k" )
	PORT_DIPUNKNOWN( 0x20, 0x00 )
	PORT_DIPUNKNOWN( 0x40, 0x00 )
	PORT_DIPUNKNOWN( 0x80, 0x00 )

	PORT_START("DSW4")
	PORT_DIPNAME( 0x03, 0x00, "Double Up Level" )
	PORT_DIPSETTING(    0x03, "0" )
	PORT_DIPSETTING(    0x02, "1" )
	PORT_DIPSETTING(    0x01, "2" )
	PORT_DIPSETTING(    0x00, "3" )
	PORT_DIPNAME( 0x0c, 0x00, "Double Up Limit" )
	PORT_DIPSETTING(    0x00, "5k" )
	PORT_DIPSETTING(    0x04, "10k" )
	PORT_DIPSETTING(    0x08, "20k" )
	PORT_DIPSETTING(    0x0c, "30k" )
	PORT_DIPUNKNOWN( 0x10, 0x10 )
	PORT_DIPNAME( 0x20, 0x00, "Coin Type" )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x20, DEF_STR( On ) )
	PORT_DIPUNKNOWN( 0x40, 0x40 )
	PORT_DIPNAME( 0x80, 0x00, "JAMMA" )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x80, DEF_STR( On ) )

	PORT_START("IN A")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1  ) PORT_NAME("Bet 1")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2  ) PORT_NAME("Bet 2")
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3  ) PORT_NAME("Bet 3")
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1   ) PORT_NAME("Play")
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON5  ) PORT_NAME("Big or Small 1")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON4  ) PORT_NAME("Bet Amount")	// 1-5-10

	PORT_START("IN B")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START2   )			// selects music in system test / exit
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_DOUBLE_UP )	// top 10? / double up?
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN  )	// used?
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON6  ) PORT_NAME("Big or Small 2")	// plays sample or advances music in system test / big or small?
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN  )	// used?
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1    )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN  )	// used?

	PORT_START("IN C")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Statistics")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN  )	// used?
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN  )	// used?
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN2    )	// key in
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN  )	// used?
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE  ) PORT_IMPULSE(2)	// service mode
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN  )	// used?

	PORT_START("IN D")	// bits 3 and 4 shown in test mode
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN  ) // used?
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER    ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN  )
INPUT_PORTS_END

/***************************************************************************
                                X-Plan
***************************************************************************/

static INPUT_PORTS_START( xplan )
	PORT_START("DSW1")
	PORT_DIPNAME( 0x01, 0x01, "Pinout" ) PORT_DIPLOCATION("SW1:1")
	PORT_DIPSETTING(    0x01, "JAMMA (28 pin)" )
	PORT_DIPSETTING(    0x00, "Lucky 8 Liner (36 pin & 10 pin)" )		// not implemented
	PORT_DIPUNUSED_DIPLOC( 0x02, 0x02, "SW1:2" )
	PORT_DIPUNUSED_DIPLOC( 0x04, 0x04, "SW1:3" )
	PORT_DIPUNUSED_DIPLOC( 0x08, 0x08, "SW1:4" )
	PORT_DIPUNUSED_DIPLOC( 0x10, 0x10, "SW1:5" )
	PORT_DIPUNUSED_DIPLOC( 0x20, 0x20, "SW1:6" )
	PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SW1:7" )
	PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW1:8" )

	PORT_START("DSW2")
	// not populated

	PORT_START("DSW3")
	// not populated

	PORT_START("DSW4")
	// not populated

	// JAMMA inputs:
	PORT_START("IN A")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1       ) PORT_NAME("A / Play Gambling 1")			// A \__ play gambling game
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2       ) PORT_NAME("C / Play Gambling 2")			// C /
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3       ) PORT_NAME("B / Play Shoot'Em Up")		// B ___ play shoot'em up game
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1        ) PORT_NAME("Start / Take")				// start / take
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_POKER_HOLD3   ) PORT_NAME("Hold 3 / Small")				// hold 3 / small / decrease sample in test mode
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_POKER_HOLD5   ) PORT_NAME("Hold 5 / Bet")				// hold 5 / bet

	PORT_START("IN B")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD4   ) PORT_NAME("Hold 4 / Re-Double" )			// hold 4 / re-double?
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD2   ) PORT_NAME("Hold 2 / Double Up / Right")	// hold 2 / double up? / right
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER         ) PORT_NAME("Raise") PORT_CODE(KEYCODE_N)	// raise
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD1   ) PORT_NAME("Hold 1 / Big / Left")			// hold 1 / big / increase sample in test mode / left
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1         )											// coin in
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN       )

	PORT_START("IN C")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK   )						// stats (keep pressed during boot for service mode)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN  )						// key in
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE       )  PORT_IMPULSE(1)		// service mode
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )						// pay-out

	PORT_START("IN D")	// bits 3 and 4 shown in test mode
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN       )						// used?
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER         ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL       )						// serial in?
INPUT_PORTS_END

/***************************************************************************
                                X-Train
***************************************************************************/

static INPUT_PORTS_START( xtrain )
	PORT_START("DSW1")
	PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x01, "SW1:1" )
	PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW1:2" )
	PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW1:3" )
	PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW1:4" )
	PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "SW1:5" )
	PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW1:6" )
	PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW1:7" )
	PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW1:8" )

	PORT_START("DSW2")
	// not populated

	PORT_START("DSW3")
	// not populated

	PORT_START("DSW4")
	// not populated

	// JAMMA inputs:
	PORT_START("IN A")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER         ) PORT_NAME("Re-Double") PORT_CODE(KEYCODE_N)	// re-double
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_HALF   ) PORT_NAME("Half Double")				// half double
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1        ) PORT_NAME("Start")					// start
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_POKER_HOLD3   ) PORT_NAME("Hold 3 / Small")			// hold 3 / small / decrease sample in test mode
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_GAMBLE_BET    ) PORT_NAME("Bet")						// bet

	PORT_START("IN B")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD1   ) PORT_NAME("Hold 1 / Take" )			// hold 1 / take
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP   ) PORT_NAME("Double Up / Help")		// double up / help
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD2   ) PORT_NAME("Hold 2 / Big")			// hold 2 / big / increase sample in test mode
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1         )										// coin in
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN       )

	PORT_START("IN C")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK   )										// stats (keep pressed during boot for service mode)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN  )										// key in
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE       )  PORT_IMPULSE(1)						// service mode
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )										// pay-out

	PORT_START("IN D")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER         ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)	// reset
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL       )										// serial in?
INPUT_PORTS_END

/***************************************************************************
                               Water-Nymph
***************************************************************************/

static INPUT_PORTS_START( wtrnymph )
	PORT_START("DSW1")
	PORT_DIPNAME( 0x07, 0x00, DEF_STR( Coinage ) )		PORT_DIPLOCATION("SW1:1,2,3")
	PORT_DIPSETTING(    0x01, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(    0x02, DEF_STR( 1C_2C ) )
	PORT_DIPSETTING(    0x03, DEF_STR( 1C_5C ) )
	PORT_DIPSETTING(    0x00, "1 Coin / 10 Credits" )
	PORT_DIPSETTING(    0x04, "1 Coin / 20 Credits" )
	PORT_DIPSETTING(    0x05, "1 Coin / 25 Credits" )
	PORT_DIPSETTING(    0x06, "1 Coin / 50 Credits" )
	PORT_DIPSETTING(    0x07, "1 Coin / 100 Credits" )
	PORT_DIPNAME( 0x38, 0x00, "Key Coinage" )			PORT_DIPLOCATION("SW1:4,5,6")
	PORT_DIPSETTING(    0x08, "1 Key / 1 Credits" )
	PORT_DIPSETTING(    0x10, "1 Key / 2 Credits" )
	PORT_DIPSETTING(    0x18, "1 Key / 5 Credits" )
	PORT_DIPSETTING(    0x00, "1 Key / 10 Credits" )
	PORT_DIPSETTING(    0x20, "1 Key / 20 Credits" )
	PORT_DIPSETTING(    0x28, "1 Key / 25 Credits" )
	PORT_DIPSETTING(    0x30, "1 Key / 50 Credits" )
	PORT_DIPSETTING(    0x38, "1 Key / 100 Credits" )
	PORT_DIPNAME( 0x40, 0x40, "Pay Out" )				PORT_DIPLOCATION("SW1:7")
	PORT_DIPSETTING(    0x40, "Coin" )
	PORT_DIPSETTING(    0x00, "Key" )
	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW1:8")
	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )

	PORT_START("DSW2")
	PORT_DIPNAME( 0x03, 0x00, "Minimum Bet" )			PORT_DIPLOCATION("SW2:1,2")
	PORT_DIPSETTING(    0x01, "1" )
	PORT_DIPSETTING(    0x00, "8" )
	PORT_DIPSETTING(    0x02, "16" )
	PORT_DIPSETTING(    0x03, "20" )
	PORT_DIPNAME( 0x0c, 0x0c, "Max Bet" )				PORT_DIPLOCATION("SW2:3,4")
	PORT_DIPSETTING(    0x08, "10" )
	PORT_DIPSETTING(    0x04, "20" )
	PORT_DIPSETTING(    0x00, "40" )
	PORT_DIPSETTING(    0x0c, "60" )
	PORT_DIPNAME( 0x10, 0x10, DEF_STR( Demo_Sounds ) )	PORT_DIPLOCATION("SW2:5")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x10, DEF_STR( On ) )
	PORT_DIPNAME( 0x60, 0x60, "Game Limit" )			PORT_DIPLOCATION("SW2:6,7")
	PORT_DIPSETTING(    0x20, "10k" )
	PORT_DIPSETTING(    0x00, "20k" )
	PORT_DIPSETTING(    0x40, "30k" )
	PORT_DIPSETTING(    0x60, "40k" )
	PORT_DIPNAME( 0x80, 0x80, "Double Up" )				PORT_DIPLOCATION("SW2:8")
	PORT_DIPSETTING(    0x00, DEF_STR( No ) )
	PORT_DIPSETTING(    0x80, DEF_STR( Yes ) )

	PORT_START("DSW3")
	PORT_DIPNAME( 0x07, 0x07, "Win Rate" )		PORT_DIPLOCATION("SW3:1,2,3")
	PORT_DIPSETTING(    0x07, "55%" )
	PORT_DIPSETTING(    0x06, "60%" )
	PORT_DIPSETTING(    0x05, "65%" )
	PORT_DIPSETTING(    0x04, "70%" )
	PORT_DIPSETTING(    0x03, "75%" )
	PORT_DIPSETTING(    0x00, "80%" )
	PORT_DIPSETTING(    0x02, "85%" )
	PORT_DIPSETTING(    0x01, "90%" )
	PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW3:4")
	PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW3:5")
	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW3:6")
	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW3:7")
	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW3:8")
	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )

	PORT_START("DSW4")
	PORT_DIPNAME( 0x07, 0x07, "Double-Up Rate" )		PORT_DIPLOCATION("SW4:1,2,3")
	PORT_DIPSETTING(    0x00, "82%" )
	PORT_DIPSETTING(    0x01, "84%" )
	PORT_DIPSETTING(    0x02, "88%" )
	PORT_DIPSETTING(    0x03, "90%" )
	PORT_DIPSETTING(    0x04, "92%" )
	PORT_DIPSETTING(    0x05, "94%" )
	PORT_DIPSETTING(    0x06, "96%" )
	PORT_DIPSETTING(    0x07, "98%" )
	PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW4:4")
	PORT_DIPSETTING(    0x00, "5k" )
	PORT_DIPSETTING(    0x08, "10k" )
	PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW4:6")
	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW4:6")
	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW4:7")
	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )		PORT_DIPLOCATION("SW4:8")
	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )

	PORT_START("IN A")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START      )	PORT_CODE(KEYCODE_N)	PORT_NAME("Start All")
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_BET )	PORT_NAME("Bet / Stop All")
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER      ) PORT_CODE(KEYCODE_Z)	PORT_NAME("Info / Double?")	// down
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN    )

	PORT_START("IN B")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN  ) PORT_IMPULSE(5)			// key in
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1         )							// coin in
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN       )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK   )	// stats
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE       )	// service mode
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )	// payout (hopper error)
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT )	// key out

	PORT_START("IN C")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SLOT_STOP3 )	PORT_NAME("Stop 3 / Right")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SLOT_STOP2 )	PORT_NAME("Stop 2 / Left / Play Gambling 1")		// C \__ play gambling game
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER      )	PORT_NAME("Play Gambling 2") PORT_CODE(KEYCODE_D)	// D /
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN    )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SLOT_STOP1 )	PORT_NAME("Stop 1 / Take / Rotate")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER      ) PORT_NAME("Play Tetris")     PORT_CODE(KEYCODE_T)	// T |__ play Tetris game

	PORT_START("IN D")	// not shown in test mode
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER    ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN  )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL  )	// serial in?
INPUT_PORTS_END


/***************************************************************************
                                Machine Drivers
***************************************************************************/

/***************************************************************************
                                Bishou Jan
***************************************************************************/

static MACHINE_CONFIG_START( bishjan, subsino2_state )
	MCFG_CPU_ADD("maincpu", H83044, XTAL_44_1MHz / 3)
	MCFG_CPU_PROGRAM_MAP( bishjan_map )
	MCFG_CPU_VBLANK_INT( "screen", irq0_line_hold )
	MCFG_TIMER_ADD_PERIODIC("timer", h8_timer_irq, attotime::from_hz(60)) // timer, ?? Hz

	MCFG_NVRAM_ADD_0FILL("nvram")
	MCFG_TICKET_DISPENSER_ADD("hopper", 200, TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_LOW)

	// video hardware
	MCFG_SCREEN_ADD("screen", RASTER)
	MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
	MCFG_SCREEN_SIZE( 512, 256 )
	MCFG_SCREEN_VISIBLE_AREA( 0, 512-1, 0, 256-16-1 )
	MCFG_SCREEN_REFRESH_RATE( 60 )
	MCFG_SCREEN_UPDATE( subsino2 )

	MCFG_GFXDECODE( ss9601 )
	MCFG_PALETTE_LENGTH( 256 )

	MCFG_VIDEO_START( subsino2 )

	// sound hardware
	// SS9904?
MACHINE_CONFIG_END

/***************************************************************************
                                Magic Train
***************************************************************************/

static MACHINE_CONFIG_START( mtrain, subsino2_state )
	MCFG_CPU_ADD("maincpu", Z180, XTAL_12MHz / 8)	/* Unknown clock */
	MCFG_CPU_PROGRAM_MAP( mtrain_map )
	MCFG_CPU_IO_MAP( mtrain_io )

	MCFG_NVRAM_ADD_0FILL("nvram")

	// video hardware
	MCFG_SCREEN_ADD("screen", RASTER)
	MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
	MCFG_SCREEN_SIZE( 512, 256 )
	MCFG_SCREEN_VISIBLE_AREA( 0, 512-1, 0, 256-32-1 )
	MCFG_SCREEN_REFRESH_RATE( 58.7270 )
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)	// game reads vblank state
	MCFG_SCREEN_UPDATE( subsino2 )

	MCFG_GFXDECODE( ss9601 )
	MCFG_PALETTE_LENGTH( 256 )

	MCFG_VIDEO_START( mtrain )

	// sound hardware
	MCFG_SPEAKER_STANDARD_MONO("mono")

	MCFG_OKIM6295_ADD("oki", XTAL_8_4672MHz / 8, OKIM6295_PIN7_HIGH)	// probably
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_CONFIG_END

/***************************************************************************
                          Sakura Love - Ying Hua Lian
***************************************************************************/

static MACHINE_CONFIG_START( saklove, subsino2_state )
	MCFG_CPU_ADD("maincpu", I80188, XTAL_20MHz )	// !! AMD AM188-EM !!
	MCFG_CPU_PROGRAM_MAP( saklove_map )
	MCFG_CPU_IO_MAP( saklove_io )
	MCFG_TIMER_ADD_PERIODIC("timer2", am188em_timer2_irq, attotime::from_hz(60)) // timer 2, ?? Hz

	MCFG_MACHINE_RESET(am188em)
	MCFG_NVRAM_ADD_0FILL("nvram")

	// video hardware
	MCFG_SCREEN_ADD("screen", RASTER)
	MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
	MCFG_SCREEN_SIZE( 512, 256 )
	MCFG_SCREEN_VISIBLE_AREA( 0, 512-1, 0, 256-16-1 )
	MCFG_SCREEN_REFRESH_RATE( 58.7270 )
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)	// game reads vblank state
	MCFG_SCREEN_UPDATE( subsino2 )

	MCFG_GFXDECODE( ss9601 )
	MCFG_PALETTE_LENGTH( 256 )

	MCFG_VIDEO_START( subsino2 )

	// sound hardware
	MCFG_SPEAKER_STANDARD_MONO("mono")

	MCFG_OKIM6295_ADD("oki", XTAL_8_4672MHz / 8, OKIM6295_PIN7_HIGH)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80)

	MCFG_SOUND_ADD("ymsnd", YM3812, XTAL_12MHz / 4)	// ? chip and clock unknown
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80)
MACHINE_CONFIG_END

/***************************************************************************
                                X-Plan
***************************************************************************/

static MACHINE_CONFIG_START( xplan, subsino2_state )
	MCFG_CPU_ADD("maincpu", I80188, XTAL_20MHz )	// !! AMD AM188-EM !!
	MCFG_CPU_PROGRAM_MAP( xplan_map )
	MCFG_CPU_IO_MAP( xplan_io )
	MCFG_CPU_VBLANK_INT( "screen", am188em_int0_irq )
	MCFG_TIMER_ADD_PERIODIC("timer2", am188em_timer2_irq, attotime::from_hz(60)) // timer 2, ?? Hz

	MCFG_MACHINE_RESET(am188em)
	MCFG_NVRAM_ADD_0FILL("nvram")

	// video hardware
	MCFG_SCREEN_ADD("screen", RASTER)
	MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
	MCFG_SCREEN_SIZE( 512, 256 )
	MCFG_SCREEN_VISIBLE_AREA( 0, 512-1, 0, 256-16-1 )
	MCFG_SCREEN_REFRESH_RATE( 58.7270 )
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)	// game reads vblank state
	MCFG_SCREEN_UPDATE( subsino2 )

	MCFG_GFXDECODE( ss9601 )
	MCFG_PALETTE_LENGTH( 256 )

	MCFG_VIDEO_START( subsino2 )

	// sound hardware
	MCFG_SPEAKER_STANDARD_MONO("mono")

	MCFG_OKIM6295_ADD("oki", XTAL_8_4672MHz / 8, OKIM6295_PIN7_HIGH)	// probably
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_CONFIG_END

static MACHINE_CONFIG_DERIVED( xtrain, xplan )
	MCFG_CPU_MODIFY("maincpu")
	MCFG_CPU_IO_MAP(xtrain_io)

	MCFG_VIDEO_START( xtrain )
MACHINE_CONFIG_END

static MACHINE_CONFIG_DERIVED( expcard, xplan )
	MCFG_CPU_MODIFY("maincpu")
	MCFG_CPU_IO_MAP(expcard_io)
MACHINE_CONFIG_END


/***************************************************************************
                                ROMs Loading
***************************************************************************/

/***************************************************************************

Bishou Jan (Laugh World)
(C)1999 Subsino

PCB Layout
----------

|------------------------------------------------------|
|TDA1519A           28-WAY                             |
|     VOL                                              |
|                HM86171                       ULN2003 |
|   LM324                                              |
|           S-1                                ULN2003 |
|                                                      |
|                                   |-------|  DSW1(8) |
|                       |-------|   |SUBSINO|          |
|            2-V201.U9  |SUBSINO|   |SS9802 |          |
|                       |SS9904 |   |       |          |
|                       |       |   |-------|          |
|                       |-------|                      |
|                                                      |
|                         44.1MHz             CXK58257 |
|  3-V201.U25                                          |
|                                  1-V203.U21          |
|  4-V201.U26                                       SW1|
|             |-------|    |-------|   |-----|         |
|  5-V201.U27 |SUBSINO|    |SUBSINO|   |H8   |         |
|             |SS9601 |    |SS9803 |   |3044 |         |
|  6-V201.U28 |       |    |       |   |-----|         |
|             |-------|    |-------|                   |
|          62256  62256   BATTERY                      |
|------------------------------------------------------|
Notes:
      H8/3044 - Subsino re-badged Hitachi H8/3044 HD6433044A22F Microcontroller (QFP100)
                The H8/3044 is a H8/3002 with 24bit address bus and has 32k MASKROM and 2k RAM, clock input is 14.7MHz [44.1/3]
                MD0,MD1 & MD2 are configured to MODE 6 16MByte Expanded Mode with the on-chip 32k MASKROM enabled.
     CXK58257 - Sony CXK58257 32k x8 SRAM (SOP28)
      HM86171 - Hualon Microelectronics HMC HM86171 VGA 256 colour RAMDAC (DIP28)
          S-1 - ?? Probably some kind of audio OP AMP or DAC? (DIP8)
          SW1 - Push Button Test Switch
        HSync - 15.75kHz
        VSync - 60Hz

***************************************************************************/

ROM_START( bishjan )
	ROM_REGION( 0x100000, "maincpu", 0 )	// H8/3044
	ROM_LOAD( "1-v203.u21", 0x000000, 0x080000, CRC(1f891d48) SHA1(0b6a5aa8b781ba8fc133289790419aa8ea21c400) )

	ROM_REGION( 0x400000, "tilemap", 0 )
	ROM_LOAD32_BYTE( "3-v201.u25", 0x000000, 0x100000, CRC(e013e647) SHA1(a5b0f82f3454393c1ea5e635b0d37735a25e2ea5) )
	ROM_LOAD32_BYTE( "4-v201.u26", 0x000001, 0x100000, CRC(e0d40ef1) SHA1(95f80889103a7b93080b46387274cb1ffe0c8768) )
	ROM_LOAD32_BYTE( "5-v201.u27", 0x000002, 0x100000, CRC(85067d40) SHA1(3ecf7851311a77a0dfca90775fcbf6faabe9c2ab) )
	ROM_LOAD32_BYTE( "6-v201.u28", 0x000003, 0x100000, CRC(430bd9d7) SHA1(dadf5a7eb90cf2dc20f97dbf20a4b6c8e7734fb1) )

	ROM_REGION( 0x100000, "samples", 0 )	// SS9904?
	ROM_LOAD( "2-v201.u9", 0x000000, 0x100000, CRC(ea42764d) SHA1(13fe1cd30e474f4b092949c440068e9ddca79976) )
ROM_END

static DRIVER_INIT( bishjan )
{
	UINT16 *rom = (UINT16*)machine.region("maincpu")->base();

	// patch serial protection test (it always enters test mode on boot otherwise)
	rom[0x042EA/2] = 0x4008;

	// rts -> rte
	rom[0x33386/2] = 0x5670;
	rom[0x0CC5C/2] = 0x5670;
}

/***************************************************************************

Express Card / Top Card
(c) 1998 American Alpha

PCB:
  SUBSINO SFWO2

CPU:
  AMD Am188 EM-20KC? (@U10)
  Osc. 20.000000 MHz (@OSC20)
  ?????              (@U13) - 32k x 8 Bit High Speed CMOS Static RAM?

Video:
  Subsino SS9601? (@U16)
  Subsino SS9802  (@U1)
  Subsino SS9803? (@U29)
  HM86171-80 (@U26) - RAMDAC
  2 x HMC HM62H256AK-15 (@U21-U22) - 32k x 8 Low Voltage CMOS Static RAM

Sound:
  U6295 9838 (@U6)
  Osc. 8.4672 MHz (@X1)
  Philips TDA1519A (@U9) - 22 W BTL or 2 x 11 W stereo power amplifier

Other:
  Osc. 12.000 MHz (@OSC12)
  Battery (button cell)
  Reset switch (@SW5)
  Volume trimmer (@VR1)
  4 x DSW8 (@SW1-SW4, only SW1 is populated)
  4 x Toshiba TD62003A (@U3-U5) - High Voltage, High Current Darlington Transistor Arrays
  10 pin edge connector
  36 pin edge connector
  28 pin JAMMA connector

***************************************************************************/

ROM_START( expcard )
	ROM_REGION( 0x40000, "maincpu", 0 )
	ROM_LOAD( "top_card_alpha_1_v1.5.u14", 0x00000, 0x40000, CRC(c6de12fb) SHA1(e807880809dd71243caf993216d8d0baf5f678df) )

	ROM_REGION( 0x200000, "tilemap", 0 )
	ROM_LOAD32_BYTE( "top_card_alpha_3_v1.4.u20", 0x00000, 0x80000, CRC(6e666d51) SHA1(924ac4fefa30cbe8bebe4f0d8ba6fff42fdd233e) )
	ROM_LOAD32_BYTE( "top_card_alpha_4_v1.4.u19", 0x00001, 0x80000, CRC(1382fd45) SHA1(1d81b7e72e702f5a254e1ec5ec6adb5d8af5d467) )
	ROM_LOAD32_BYTE( "top_card_alpha_5_v1.4.u18", 0x00002, 0x80000, CRC(bbe465ac) SHA1(7a5ee6f7696e5f768ac56ccfaf0914dd56a83339) )
	ROM_LOAD32_BYTE( "top_card_alpha_6_v1.4.u17", 0x00003, 0x80000, CRC(315d7a81) SHA1(8dafa1d422d8fe306765413084e35f16e4c17d27) )

	ROM_REGION( 0x80000, "oki", 0 )
	ROM_LOAD( "top_card-ve1.u7", 0x00000, 0x80000, CRC(0ca9bd18) SHA1(af791c78ae321104afa738564bc23f520f37e7d5) )
ROM_END

static DRIVER_INIT( expcard )
{
	UINT8 *rom = machine.region("maincpu")->base();

	// patch protection test (it always enters test mode on boot otherwise)
	rom[0xed4dc-0xc0000] = 0xeb;
}

/***************************************************************************

  Magic Train
  -----------

  Board silkscreened: "SUBSINO" (logo), "CS186P012". Stickered "1056439".

  CPU:   1x Hitachi HD647180X0CP6 - 6D1R (Subsino - SS9600) (U23).
  SND:   1x U6295 (OKI compatible) (U25).
         1x TDA1519A (PHILIPS, 22W BTL or 2x 11W stereo car radio power amplifier (U34).

  NVRAM:     1x SANYO LC36256AML (SMD) (U16).
  VRAM:      2x UMC UM62256E-70LL (U7-U8, next to gfx ROMs).
  Other RAM: 1x HMC HM86171-80 (U29, next to sound ROM).

  Video: Subsino (SMD-40PX40P) SS9601 - 9732WX011 (U1).
  I/O:   Subsino (SMD-30PX20P) SS9602 - 9732LX006 (U11).

  PRG ROM:  Stickered "M-TRAIN-N OUT_1 V1.31".

  GFX ROMs: 1x 27C2000DC-12  Stickered "M-TRAIN-N ROM_1 V1.0" (U5).
            1x 27C2000DC-12  Stickered "M-TRAIN-N ROM_2 V1.0" (U4).
            1x 27C2000DC-12  Stickered "M-TRAIN-N ROM_3 V1.0" (U3).
            1x 27C2000DC-12  Stickered "M-TRAIN-N ROM_4 V1.0" (U2).

  SND ROM:  1x 27C2000DC-12 (U27, no sticker).

  PLDs: 1x GAL16V8D (U31, next to sound ROM).
        3x GAL16V8D (U18-U19-U6, next to CPU, program ROM and NVRAM).
        1x GAL16V8D (U26, near sound amp)

  Battery: 1x VARTA 3.6v, 60mAh.

  Xtal: 12 MHz.

  4x 8 DIP switches banks (SW1-SW2-SW3-SW4).
  1x Push button (S1, next to battery).

  1x 2x36 Edge connector.
  1x 2x10 Edge connector.

  U12, U13 & U14 are Darlington arrays.

***************************************************************************/

ROM_START( mtrain )
	ROM_REGION( 0x10000, "maincpu", 0 )
	// code starts at 0x8100!
	ROM_LOAD( "out_1v131.u17", 0x0000, 0x8100, CRC(6761be7f) SHA1(a492f8179d461a454516dde33ff04473d4cfbb27) )
	ROM_CONTINUE(              0x0000, 0x7f00 )
	ROM_RELOAD(                0xa000, 0x6000 )

	ROM_REGION( 0x100000, "tilemap", 0 )
	ROM_LOAD32_BYTE( "rom_4.u02", 0x00000, 0x40000, CRC(b7e65d04) SHA1(5eea1b8c1129963b3b83a59410cd0e1de70621e4) )
	ROM_LOAD32_BYTE( "rom_3.u03", 0x00001, 0x40000, CRC(cef2c079) SHA1(9ee54a08ef8db90a80a4b3568bb82ce09ee41e65) )
	ROM_LOAD32_BYTE( "rom_2.u04", 0x00002, 0x40000, CRC(a794f287) SHA1(7b9c0d57224a700f49e55ba5aeb7ed9d35a71e02) )
	ROM_LOAD32_BYTE( "rom_1.u05", 0x00003, 0x40000, CRC(96067e95) SHA1(bec7dffaf6920ff2bd85a43fb001a997583e25ee) )

	ROM_REGION( 0x80000, "oki", 0 )
	ROM_LOAD( "rom_5.u27", 0x00000, 0x40000, CRC(51cae476) SHA1(d1da4e5c3d53d18d8b69dfb57796d0ae311d99bf) )
	ROM_RELOAD(            0x40000, 0x40000 )

    ROM_REGION( 0x117, "plds", 0 )
    ROM_LOAD( "gal16v8d.u6",  0x000, 0x117, NO_DUMP )
    ROM_LOAD( "gal16v8d.u18", 0x000, 0x117, NO_DUMP )
    ROM_LOAD( "gal16v8d.u19", 0x000, 0x117, NO_DUMP )
    ROM_LOAD( "gal16v8d.u26", 0x000, 0x117, NO_DUMP )
    ROM_LOAD( "gal16v8d.u31", 0x000, 0x117, NO_DUMP )
ROM_END

/***************************************************************************

  Decryption of mtrain (same as crsbingo)

  Notes:

  0000-8100? is not encrypted

  rom     addr
  8100 -> 0000  ; after decryption (code start)
  8200 -> 0100  ; after decryption
  8d97 -> 0c97  ; after decryption
  1346 -> b346
  ec40 -> 6b40  ; after decryption

***************************************************************************/

DRIVER_INIT( mtrain )
{
	subsino_decrypt(machine, crsbingo_bitswaps, crsbingo_xors, 0x8000);

	// patch serial protection test (it always enters test mode on boot otherwise)
	UINT8 *rom = machine.region("maincpu")->base();
	rom[0x0cec] = 0x18;
	rom[0xb037] = 0x18;

}

/***************************************************************************

Sakura Love
Subsino, 1998

PCB Layout
----------

|------------------------------------|
|     ULN2003 ULN2003 ULN2003 ULN2003|
|LM358     HM86171     |-----|    PAL|
| M6295       8.4672MHz|SS9602    PAL|
| LM324                |-----|    PAL|
|J              |-------|         PAL|
|A              |SUBSINO|         PAL|
|M  2   12MHz   |SS9601 |         SW5|
|M  3   20MHz   |       |            |
|A  4           |-------|            |
|   5        1  LC36256              |
|   6      AM188-EM    62256  SW3 SW4|
|BATTERY               62256  SW1 SW2|
|------------------------------------|
Notes:
      AM188-EM - AMD AM188 Main CPU (QFP100) Clock 20.0MHz
      M6295    - clock 1.0584MHz [8.4672/8]. Pin 7 HIGH
      SW1-SW4  - Dip switches with 8 positions
      SW5      - Reset switch
      VSync    - 58.7270Hz
      HSync    - 15.3234kHz

***************************************************************************/

ROM_START( saklove )
	ROM_REGION( 0x20000, "maincpu", 0 )	// AM188-EM
	ROM_LOAD( "1.u23", 0x00000, 0x20000, CRC(02319bfb) SHA1(1a425dcdeecae92d8b7457d1897c700ac7856a9d) )

	ROM_REGION( 0x200000, "tilemap", 0 )
	ROM_LOAD32_BYTE( "3.u27", 0x000000, 0x80000, CRC(01aa8fbd) SHA1(d1d19ef52c8077ccf17cc2fde96fd56c626e33db) )
	ROM_LOAD32_BYTE( "4.u28", 0x000001, 0x80000, CRC(f8db7ab6) SHA1(3af4e92ab27edc980eccecdbbbb431e1d2101059) )
	ROM_LOAD32_BYTE( "5.u29", 0x000002, 0x80000, CRC(c6ca1764) SHA1(92bfa19e116d358b03164f2448a28e7524e3cc62) )
	ROM_LOAD32_BYTE( "6.u30", 0x000003, 0x80000, CRC(5823c39e) SHA1(257e862ac736ff403ce9c70bbdeed340dfe168af) )

	ROM_REGION( 0x80000, "oki", 0 )
	ROM_LOAD( "2.u10", 0x00000, 0x80000, CRC(4f70125c) SHA1(edd5e6bd47b9a4fa3c4057cb4a85544241fe483d) )
ROM_END

static DRIVER_INIT( saklove )
{
	UINT8 *rom = machine.region("maincpu")->base();

	// patch serial protection test (it always enters test mode on boot otherwise)
	rom[0x0e029] = 0xeb;
}

/***************************************************************************

X-Plan
(c) 2006 Subsino

PCB:
  SUBSINO SFWO2

CPU:
  AMD Am188 EM-20KC F 9912F6B (@U10)
  Osc. 20.00000 MHz (@OSC20)
  Sony CXK58257AM-10L (@U13) - 32k x 8 Bit High Speed CMOS Static RAM

Video:
  Subsino SS9601 0035WK007 (@U16)
  Subsino SS9802 0448 (@U1)
  Subsino SS9803 0020 (@U29)
  HM86171-80 (@U26) - RAMDAC
  2 x Winbond W24M257AK-15 (@U21-U22) - 32k x 8 Low Voltage CMOS Static RAM

Sound:
  U6295 0214 B923826 (@U6)
  Osc. 8.4672 MHz (@X1)
  Philips TDA1519A? (@U9) - 22 W BTL or 2 x 11 W stereo power amplifier

Other:
  Osc. 12.000 MHz (@OSC12)
  Battery (button cell)
  Reset switch (@SW5)
  Volume trimmer (@VR1)
  4 x DSW8 (@SW1-SW4, only SW1 is populated)
  4 x ULN2003A (@U3-U5) - High Voltage, High Current Darlington Transistor Arrays
  10 pin edge connector
  36 pin edge connector
  28 pin JAMMA connector

***************************************************************************/

ROM_START( xplan )
	ROM_REGION( 0x40000, "maincpu", 0 )
	ROM_LOAD( "x-plan_v101.u14", 0x00000, 0x40000, CRC(5a05fcb3) SHA1(9dffffd868e777f9436c38df76fa5247f4dd6daf) )

	ROM_REGION( 0x200000, "tilemap", 0 )
	ROM_LOAD32_BYTE( "x-plan_rom_3_v102b.u20", 0x00000, 0x80000, CRC(a027cbd1) SHA1(dac4226014794ef5bff84ddafee7da6691c00ece) )
	ROM_LOAD32_BYTE( "x-plan_rom_4_v102b.u19", 0x00001, 0x80000, CRC(744be318) SHA1(1c1f2a9e1da77d9bc1bf897072df44a681a53079) )
	ROM_LOAD32_BYTE( "x-plan_rom_5_v102b.u18", 0x00002, 0x80000, CRC(7e89c9b3) SHA1(9e3fea0d74cac48c068a15595f2342a2b0b3f747) )
	ROM_LOAD32_BYTE( "x-plan_rom_6_v102b.u17", 0x00003, 0x80000, CRC(a86ca3b9) SHA1(46aa86b9c62aa0a4e519eb06c72c2d540489afee) )

	ROM_REGION( 0x80000, "oki", 0 )
	ROM_LOAD( "x-plan_rom_2_v100.u7", 0x00000, 0x80000, CRC(c742b5c8) SHA1(646960508be738824bfc578c1b21355c17e05010) )
ROM_END

static DRIVER_INIT( xplan )
{
	UINT8 *rom = machine.region("maincpu")->base();

	// patch protection test (it always enters test mode on boot otherwise)
	rom[0xeded9-0xc0000] = 0xeb;
}

/***************************************************************************

X-Train
(c) 1999 Subsino

PCB:
  SUBSINO

CPU:
  AMD Am188 EM-20KC (@U10)
  Osc. 20.000 MHz (@OSC20)
  Sony CXK58257AM-10L (@U13) - 32k x 8 Bit High Speed CMOS Static RAM

Video:
  Subsino SS9601 9948WK007 (@U16)
  Subsino SS9802 9933 (@U1)
  Subsino SS9803 9933 (@U29)
  HM86171-80 (@U26) - RAMDAC
  2 x Alliance AS7C256-15PC (@U21-U22) - High Performance 32Kx8 CMOS SRAM

Sound:
  U6295 (@U6)
  Osc. 8.4672 MHz (@X1)
  Philips TDA1519A (@U9) - 22 W BTL or 2 x 11 W stereo power amplifier

Other:
  Osc. 12.000 MHz (@OSC12)
  Battery (button cell)
  Reset switch (@SW5)
  Volume trimmer (@VR1)
  4 x DSW8 (@SW1-SW4, only SW1 is populated)
  4 x ULN2003A? (@U3-U5) - High Voltage, High Current Darlington Transistor Arrays
  10 pin edge connector
  36 pin edge connector
  28 pin JAMMA connector

***************************************************************************/

ROM_START( xtrain )
	ROM_REGION( 0x40000, "maincpu", 0 )
	ROM_LOAD( "x-train(top)_out_1_v1.3.u14", 0x00000, 0x40000, CRC(019812b4) SHA1(33c73c53f8cf730c35fa310868f5b8360dfaad9e) )

	ROM_REGION( 0x200000, "tilemap", 0 )
	ROM_LOAD32_BYTE( "x-train_rom_3_v1.2.u20", 0x00000, 0x80000, CRC(0e18ca82) SHA1(8fbc62a16ab109994086f58c9b9915a92bda0448) )
	ROM_LOAD32_BYTE( "x-train_rom_4_v1.2.u19", 0x00001, 0x80000, CRC(959fa749) SHA1(d39fcedd1d13d9f86c1915d7dcff7d024739a6fa) )
	ROM_LOAD32_BYTE( "x-train_rom_5_v1.2.u18", 0x00002, 0x80000, CRC(d0e8279f) SHA1(174483871c9e98936b37cc6cede71b64e19cae90) )
	ROM_LOAD32_BYTE( "x-train_rom_6_v1.2.u17", 0x00003, 0x80000, CRC(289ae881) SHA1(b3f8db43d86078688ad56a04d1e7d7a825df60d7) )

	ROM_REGION( 0x80000, "oki", 0 )
	ROM_LOAD( "x-train_rom_2_v1.2.u7", 0x00000, 0x80000, CRC(aae563ff) SHA1(97db845d7e3d343bd70352371cb27b16faacca7f) )
ROM_END

static DRIVER_INIT( xtrain )
{
	UINT8 *rom = machine.region("maincpu")->base();

	// patch protection test (it always enters test mode on boot otherwise)
	rom[0xe190f-0xc0000] = 0xeb;
}

/***************************************************************************

Water-Nymph (Ver. 1.4)
(c) 1996 Subsino

Same PCB as Magic Train

***************************************************************************/

ROM_START( wtrnymph )
	ROM_REGION( 0x10000, "maincpu", 0 )
	// code starts at 0x8100!
	ROM_LOAD( "ocean-n tetris_1 v1.4.u17", 0x0000, 0x8100, CRC(c7499123) SHA1(39a9ea6d927ee839cfb127747e5e3df3535af098) )
	ROM_CONTINUE(                          0x0000, 0x7f00 )
	ROM_RELOAD(                            0xa000, 0x6000 )

	ROM_REGION( 0x100000, "tilemap", 0 )
	ROM_LOAD32_BYTE( "ocean-n tetris_2 v1.21.u2", 0x00000, 0x40000, CRC(813aac90) SHA1(4555adf8dc363359b10f1d5cfae2dcebed411679) )
	ROM_LOAD32_BYTE( "ocean-n tetris_3 v1.21.u3", 0x00001, 0x40000, CRC(83c39379) SHA1(e7f9315d19370c18b664b759e433052a88f8c146) )
	ROM_LOAD32_BYTE( "ocean-n tetris_4 v1.21.u4", 0x00002, 0x40000, CRC(6fc64b42) SHA1(80110d7dae28cca5e39c8a7c2ceebf589116ae23) )
	ROM_LOAD32_BYTE( "ocean-n tetris_5 v1.21.u5", 0x00003, 0x40000, CRC(8c7515ee) SHA1(a67b21c1e8ca8a098fe558c73561bca13962893e) )

	ROM_REGION( 0x80000, "oki", 0 )
	ROM_LOAD( "ocean-n tetris_6 v1.21.u27", 0x00000, 0x40000, CRC(1c8a886d) SHA1(faa983801b368a6d04ef80e359c6fb67b240c60d) )
	ROM_RELOAD(                             0x40000, 0x40000 )

    ROM_REGION( 0x117, "plds", 0 )
    ROM_LOAD( "gal16v8d.u6",  0x000, 0x117, NO_DUMP )
    ROM_LOAD( "gal16v8d.u18", 0x000, 0x117, NO_DUMP )
    ROM_LOAD( "gal16v8d.u19", 0x000, 0x117, NO_DUMP )
    ROM_LOAD( "gal16v8d.u26", 0x000, 0x117, NO_DUMP )
    ROM_LOAD( "gal16v8d.u31", 0x000, 0x117, NO_DUMP )
ROM_END

DRIVER_INIT( wtrnymph )
{
	subsino_decrypt(machine, victor5_bitswaps, victor5_xors, 0x8000);

	// patch serial protection test (it always enters test mode on boot otherwise)
	UINT8 *rom = machine.region("maincpu")->base();
	rom[0x0d79] = 0x18;
	rom[0xc1cf] = 0x18;
	rom[0xc2a9] = 0x18;
	rom[0xc2d7] = 0x18;
}

GAME( 1996, mtrain,   0,        mtrain,   mtrain,   mtrain,   ROT0, "Subsino",        "Magic Train (Ver. 1.31)",              0 )
GAME( 1996, wtrnymph, 0,        mtrain,   wtrnymph, wtrnymph, ROT0, "Subsino",        "Water-Nymph (Ver. 1.4)",               0 )
GAME( 1998, expcard,  0,        expcard,  expcard,  expcard,  ROT0, "American Alpha", "Express Card / Top Card (Ver. 1.5)",   0 )
GAME( 1998, saklove,  0,        saklove,  saklove,  saklove,  ROT0, "Subsino",        "Ying Hua Lian 2.0 (China, Ver. 1.02)", 0 )
GAME( 1999, xtrain,   0,        xtrain,   xtrain,   xtrain,   ROT0, "Subsino",        "X-Train (Ver. 1.3)",                   0 )
GAME( 1999, bishjan,  0,        bishjan,  bishjan,  bishjan,  ROT0, "Subsino",        "Bishou Jan (Japan, Ver. 2.03)",        GAME_NO_SOUND )
GAME( 2006, xplan,    0,        xplan,    xplan,    xplan,    ROT0, "Subsino",        "X-Plan (Ver. 1.01)",                   0 )