summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/mpu4.cpp
blob: 16525fc4a3d7615a92d47a994820742fae44ee0a (plain) (tree)
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306










































































































































































































































































































                                                                                                                                               
         

                                                                                                                                    

                                       
                                                                          






























                                                                                   
                                                                                          



















                                                                              
                           
         
                                                                                                                              




                                    
                           
         
                                                            
         
                                                                               









































































                                                                                                                                          
                                     





































































































































                                                                                                                       
                                                                             
















                                                                                                                
                                                                                










                                                                                                                                       
                                                                                                



                                                                                                

                                                                                 

                         

                                                   
































































































                                                                                                    

                         
                                                                                                                                                                  


                                                          
                                                      
                                 
                                                                                                   
                                 
                                                                    




















































































































































                                                                                                                             
                                                                                       


                                          
                                                                                           
                         
                                                            



















                                                                     
                                                                                                                
                         
                                                                                   














































































































































































































































































































































































































                                                                                                                                            
                                                                                                              
                                   
         
                                           










































































































































                                                                                                                           
                                                    

















































































































































                                                                                                                                   



                                                  




























































































































































































































































                                                                                                                       



                                                  








































                                                                                                                          
                                                                                                                     

                                 
                                                                                      








































































                                                                                                                                                   
                                                                                      

                                                                       
                                                         


































































                                                                                                                                    
                                                                                                                     
                                 
                                                                                                

























































































                                                                                                           

                                                                                  














                                                                                                                                                                                
                          


                             
 



                                               
                                     






                             
                                        








                                                            
                                        








                                                            
                                        








                                                            
                                        































































































                                                                                                        
                                       

                                                                                       
                                      

 
                                      
 
                          

 
                                      
 
                          

 
                                      
 
                          

 
                                         
 
                                     

 
                                           
 
                                       

 
                                           
 
                                       

 
                                           
 
                                       

 
                                       



                         
                                         



                                  
                                         



                                  
                                         



                                  
                                            



                                     
                                            



                                     
                                



                                
                                



                                
                                




                                                                                         
                                  
 
                                   
                    
                               
 

                                       
 
                                   


                    
                                        
 
                                    


                    
                                        
 
                                    


                    
                                        
 
                                    


                    
                                       
 
                                   


                    
                                       
 
                                   


                    
                                     
 
                                



                    
                                    
 

                                 


                                             
                                
 

                               



                                          
                                
 
                         


                                          
                                
 
                         


                                          
                                



                                          
                                
 

                                

                                          
                             


 
                                       






                                                                          
                                     
 
                                   
                    
                               



                     
                                 
 





                               


 
                                     

                                                            


                          
 

                                                 

                                                                                                


                                       


            
                               




                                                                                                                  
                                                                                  























                                                                                            
                                

                                                            
                             












                                                                                                             






                                                                             





                                          
                               
 
                        


                                                                                  
                                
 
                        
















                                                                                                            




                                                                                                                                           
                                                                                        








                                                                                                                         








































                                                     
                                                
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   

                  
                                                
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   

                  
                                                
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   

                  
                                                
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   


                  
                                                
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                  
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   
                                         
                                                                                   

                  
                                                
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   
                                       
                                                                                   

                  
                                             





                                                                                            



                                                                         

                                              





                                                                            

                                              






                                                                            

                                              







                                                                            

                                              





                                                                            

                                              






                                                                            

                                              





                                                                            





                                            
                                              

                                                                    



                                                                            

                                                




                                                                           


                                    
                                          
 

                                                        

                                                                         
 
                            
 

                                                  






                                        

                                      
                                                              



                                                      
                               

                  

                                          
                                                              



                                                      
                                 



                  

                                         
                                                       
 
                               
 
                                                              



                                                      

                                         
                                                       
 

                               
 
                                                                                                                      



                                                      

                                             
                                                       
 

                                 
 
                                                                                                                      



                                                      

                                            
                                                       
 

                               
 
                                                                                                                      



                                                      

                                        
                                                       

                               
 
                                                                                                                      



                                                      

                                          
                                                       
 
                                       




                                                                                    
// license:BSD-3-Clause
// copyright-holders:James Wallace
// thanks-to:Chris Wren, Tony Friery, MFME
/* MPU4 hardware emulation
  for sets see the various includes prefixed 'mpu4'
*/

/* Note 19/07/11 DH
 - added lots of sets

   these are mostly unsorted and need to be split into clones
   the original source of these was a mess, assume things to be mislabled, bad, duplicated, or otherwise
   badly organized.  a lot of work is needed to sort them out, especially the Barcrest sets!  Some of this
   stuff MIGHT be in the wrong driver, or missing roms (sound roms especially)
*/

/***********************************************************************************************************
  Barcrest MPU4 highly preliminary driver.
  MAME Driver J. Wallace and Haze

  Thanks to Chris Wren and MFME for documentation.

  This is the core driver, no video specific stuff should go in here.
  This driver holds all the mechanical games.

     06-2011: Fixed boneheaded interface glitch that was causing samples to not be cancelled correctly.
              Added the ability to read each segment of an LED display separately, this may be necessary for some
              games that use them as surrogate lamp lines.
              New persistence 'hack' to stop light flicker for the small extender.
     05-2011: Add better OKI emulation
     04-2011: More accurate gamball code, fixed ROM banking (Project Amber), added BwB CHR simulator (Amber)
              This is still a hard coded system, but significantly different to Barcrest's version.
              Started adding support for the Crystal Gaming program card, and the link keys for setting parameters.
     03-2011: Lamp timing fixes, support for all known expansion cards added.
     01-2011: Adding the missing 'OKI' sound card, and documented it, but it needs a 6376 rewrite.
     09-2007: Haze: Added Deal 'Em video support.
  03-08-2007: J Wallace: Removed audio filter for now, since sound is more accurate without them.
                         Connect 4 now has the right sound.
  03-07-2007: J Wallace: Several major changes, including input relabelling, and system timer improvements.
     06-2007: Atari Ace, many cleanups and optimizations of I/O routines
  09-06-2007: J Wallace: Fixed 50Hz detection circuit.
  17-02-2007: J Wallace: Added Deal 'Em - still needs some work.
  10-02-2007: J Wallace: Improved input timing.
  30-01-2007: J Wallace: Characteriser rewritten to run the 'extra' data needed by some games.
  24-01-2007: J Wallace: With thanks to Canonman and HIGHWAYMAN/System 80, I was able to confirm a seemingly
              ghastly misuse of a PIA is actually on the real hardware. This fixes the meters.

See http://agemame.mameworld.info/techinfo/mpu4.php for Information.

--- Board Setup ---

The MPU4 BOARD is the driver board, originally designed to run Fruit Machines made by the Barcrest Group, but later
licensed to other firms as a general purpose unit (even some old Photo-Me booths used the unit).

This board uses a ~1.72 Mhz 6809B CPU, and a number of PIA6821 chips for multiplexing inputs and the like.

To some extent, the hardware feels like a revision of the MPU3 design, integrating into the base unit features that were
previously added through expansion ports. However, there is no backwards compatibility, and the entire memory map has been
reworked.

Like MPU3, a 6840PTM is used for internal timing, and other miscellaneous control functions, including as a crude analogue sound device
(a square wave from the PTM being used as the alarm sound generator). However, the main sound functionality is provided by
dedicated hardware (an AY8913).

A MPU4 GAME CARD (cartridge) plugs into the MPU4 board containing the game, and a protection PAL (the 'characteriser').
This PAL, as well as protecting the games, also controlled some of the lamp address matrix for many games, and acted as
an anti-tampering device which helped to prevent the hacking of certain titles in a manner which broke UK gaming laws.

Like MPU3, over the years developers have added more capabilities through the spare inputs and outputs provided. These provided
support for more reels, lamps and LEDs through daughtercards.
Several solutions were released depending on the manufacturer of the machine, all are emulated here.

In later revisions of the main board (MOD4 onwards), the AY8913 was removed entirely, as two official alternatives for sound had been produced.
In one, a YM2413 is built into the gameboard, and in the other an OKI MSM6376 is interfaced with a PIA and PTM to allow sophisticated
sampled sound.

The lamping and input handling side of the machine rely entirely on a column by column 'strobe' system, with lights and LEDs selected in turn.
In the inputs there are two orange connectors (sampled every 8ms) and two black ones (sampled every 16ms), giving 32 multiplexed inputs.

In addition there are two auxiliary ports that can be accessed separately to these and are bidirectional

--- Preliminary MPU4 Memorymap  ---

(NV) indicates an item which is not present on the video version, which has a Comms card instead.

   hex     |r/w| D D D D D D D D |
 location  |   | 7 6 5 4 3 2 1 0 | function
-----------+---+-----------------+--------------------------------------------------------------------------
 0000-07FF |R/W| D D D D D D D D | 2k RAM
-----------+---+-----------------+--------------------------------------------------------------------------
 0800      |R/W|                 | Characteriser (Security PAL) (NV)
-----------+---+-----------------+--------------------------------------------------------------------------
 0850 ?    | W | ??????????????? | page latch (NV)
-----------+---+-----------------+--------------------------------------------------------------------------
 0880      |R/W| D D D D D D D D | PIA6821 on soundboard (Oki MSM6376 clocked by 6840 (8C0))
           |   |                 | port A = ??
           |   |                 | port B (882)
           |   |                 |        b7 = NAR
           |   |                 |        b6 = 0 if OKI busy, 1 if OKI ready
           |   |                 |        b5 = volume control clock
           |   |                 |        b4 = volume control direction (0= up, 1 = down)
           |   |                 |        b3 = ??
           |   |                 |        b2 = ??
           |   |                 |        b1 = 2ch
           |   |                 |        b0 = ST
-----------+---+-----------------+--------------------------------------------------------------------------
 08C0      |   |                 | MC6840 on sound board
-----------+---+-----------------+--------------------------------------------------------------------------
 0900-     |R/W| D D D D D D D D | MC6840 PTM IC2


  Clock1 <--------------------------------------
     |                                          |
     V                                          |
  Output1 ---> Clock2                           |
                                                |
               Output2 --+-> Clock3             |
                         |                      |
                         |   Output3 ---> 'to audio amp' ??
                         |
                         +--------> CA1 IC3 (

IRQ line connected to CPU

-----------+---+-----------------+--------------------------------------------------------------------------
 0A00-0A03 |R/W| D D D D D D D D | PIA6821 IC3 port A Lamp Drives 1,2,3,4,6,7,8,9 (sic)(IC14)
           |   |                 |
           |   |                 |          CA1 <= output2 from PTM6840 (IC2)
           |   |                 |          CA2 => alpha data
           |   |                 |
           |   |                 |          port B Lamp Drives 10,11,12,13,14,15,16,17 (sic)(IC13)
           |   |                 |
           |   |                 |          CB2 => alpha reset (clock on Dutch systems)
           |   |                 |
-----------+---+-----------------+--------------------------------------------------------------------------
 0B00-0B03 |R/W| D D D D D D D D | PIA6821 IC4 port A = data for 7seg leds (pins 10 - 17, via IC32)
           |   |                 |
           |   |                 |             CA1 INPUT, 50 Hz input (used to generate IRQ)
           |   |                 |             CA2 OUTPUT, connected to pin2 74LS138 CE for multiplexer
           |   |                 |                        (B on LED strobe multiplexer)
           |   |                 |             IRQA connected to IRQ of CPU
           |   |                 |             port B
           |   |                 |                    PB7 = INPUT, serial port Receive data (Rx)
           |   |                 |                    PB6 = INPUT, reel A sensor
           |   |                 |                    PB5 = INPUT, reel B sensor
           |   |                 |                    PB4 = INPUT, reel C sensor
           |   |                 |                    PB3 = INPUT, reel D sensor
           |   |                 |                    PB2 = INPUT, Connected to CA1 (50Hz signal)
           |   |                 |                    PB1 = INPUT, undercurrent sense
           |   |                 |                    PB0 = INPUT, overcurrent  sense
           |   |                 |
           |   |                 |             CB1 INPUT,  used to generate IRQ on edge of serial input line
           |   |                 |             CB2 OUTPUT, enable signal for reel optics
           |   |                 |             IRQB connected to IRQ of CPU
           |   |                 |
-----------+---+-----------------+--------------------------------------------------------------------------
 0C00-0C03 |R/W| D D D D D D D D | PIA6821 IC5 port A
           |   |                 |
           |   |                 |                    PA0-PA7, INPUT AUX1 connector
           |   |                 |
           |   |                 |             CA2  OUTPUT, serial port Transmit line
           |   |                 |             CA1  not connected
           |   |                 |             IRQA connected to IRQ of CPU
           |   |                 |
           |   |                 |             port B
           |   |                 |
           |   |                 |                    PB0-PB7 INPUT, AUX2 connector
           |   |                 |
           |   |                 |             CB1  INPUT,  connected to PB7 (Aux2 connector pin 4)
           |   |                 |
           |   |                 |             CB2  OUTPUT, AY8913 chip select line
           |   |                 |             IRQB connected to IRQ of CPU
           |   |                 |
-----------+---+-----------------+--------------------------------------------------------------------------
 0D00-0D03 |R/W| D D D D D D D D | PIA6821 IC6
           |   |                 |
           |   |                 |  port A
           |   |                 |
           |   |                 |        PA0 - PA7 (INPUT/OUTPUT) data port AY8913 sound chip
           |   |                 |
           |   |                 |        CA1 INPUT,  not connected
           |   |                 |        CA2 OUTPUT, BC1 pin AY8913 sound chip
           |   |                 |        IRQA , connected to IRQ CPU
           |   |                 |
           |   |                 |  port B
           |   |                 |
           |   |                 |        PB0-PB3 OUTPUT, reel A
           |   |                 |        PB4-PB7 OUTPUT, reel B
           |   |                 |
           |   |                 |        CB1 INPUT,  not connected
           |   |                 |        CB2 OUTPUT, B01R pin AY8913 sound chip
           |   |                 |        IRQB , connected to IRQ CPU
           |   |                 |
-----------+---+-----------------+--------------------------------------------------------------------------
 0E00-0E03 |R/W| D D D D D D D D | PIA6821 IC7
           |   |                 |
           |   |                 |  port A
           |   |                 |
           |   |                 |        PA0-PA3 OUTPUT, reel C
           |   |                 |        PA4-PA7 OUTPUT, reel D
           |   |                 |        CA1     INPUT,  not connected
           |   |                 |        CA2     OUTPUT, A on LED strobe multiplexer
           |   |                 |        IRQA , connected to IRQ CPU
           |   |                 |
           |   |                 |  port B
           |   |                 |
           |   |                 |        PB0-PB6 OUTPUT mech meter 1-7 or reel E + F
           |   |                 |        PB7     Voltage drop sensor
           |   |                 |        CB1     INPUT, not connected
           |   |                 |        CB2     OUTPUT,mech meter 8
           |   |                 |        IRQB , connected to IRQ CPU
           |   |                 |
-----------+---+-----------------+--------------------------------------------------------------------------
 0F00-0F03 |R/W| D D D D D D D D | PIA6821 IC8
           |   |                 |
           |   |                 | port A
           |   |                 |
           |   |                 |        PA0-PA7 INPUT  multiplexed inputs data
           |   |                 |
           |   |                 |        CA1     INPUT, not connected
           |   |                 |        CA2    OUTPUT, C on LED strobe multiplexer
           |   |                 |        IRQA           connected to IRQ CPU
           |   |                 |
           |   |                 | port B
           |   |                 |
           |   |                 |        PB0-PB7 OUTPUT  triacs outputs connector PL6
           |   |                 |        used for slides / hoppers
           |   |                 |
           |   |                 |        CB1     INPUT, not connected
           |   |                 |        CB2    OUTPUT, pin1 alpha display PL7 (clock signal)
           |   |                 |        IRQB           connected to IRQ CPU
           |   |                 |
-----------+---+-----------------+--------------------------------------------------------------------------
 1000-FFFF | R | D D D D D D D D | ROM (can be bank switched by 0x850 in 8 banks of 64 k ) (NV)
-----------+---+-----------------+--------------------------------------------------------------------------

Additional Notes:

Games from around the era of Road Hog and Chase Invaders had sufficient additional space to store three sets of reel
start/stop sounds.

To change between them, follow these instructions:

1) Load the game.
2) Open the cashbox door and insert the refill key.
3) Use Hi/Lo to adjust volume
4) Use Hold 1/2/3 to choose between "Default", "Standard" and "Alternative" sound sets
5) Use Cancel/collect to test the sounds.
6) To return to the game, remove the refill key and close the door

TODO: - Distinguish door switches using manual
      - Complete stubs for hoppers (needs slightly better 68681 emulation, and new 'hoppers' device emulation)
      - It seems that the MPU4 core program relies on some degree of persistence when switching strobes and handling
      writes to the various hardware ports. This explains the occasional lamping/LED blackout and switching bugs
      For now, we're ignoring any extra writes to strobes, as the alternative is to assign a timer to *everything* and
      start modelling the individual hysteresis curves of filament lamps.
      - Fix BwB characteriser, need to be able to calculate stabiliser bytes. Anyone fancy reading 6809 source?
      - Strange bug in Andy's Great Escape - Mystery nudge sound effect is not played, mpu4 latches in silence instead (?)

      - Per game inputs not currently supported, may need to do something about DIPs, inverted lines etc.
***********************************************************************************************************/
#include "emu.h"
#include "includes/mpu4.h"

#include "video/awpvid.h"       //Fruit Machines Only

#include "speaker.h"

#include "mpu4.lh"
#include "mpu4ext.lh"


/*
LED Segments related to pins (5 is not connected):
Unlike the controllers emulated in the layout code, each
segment of an MPU4 LED can be set individually, even
being used as individual lamps. However, we can get away
with settings like this in the majority of cases.
   _9_
  |   |
  3   8
  |   |
   _2_
  |   |
  4   7
  |_ _|
    6  1

8 display enables (pins 10 - 17)
*/

void mpu4_state::lamp_extend_small(int data)
{
	int lamp_ext_data,column,i;
	column = data & 0x07;

	lamp_ext_data = 0x1f - ((data & 0xf8) >> 3);//remove the mux lines from the data

	if (m_lamp_strobe_ext_persistence == 0)
	{
		//One write to reset the drive lines, one with the data, one to clear the lines, so only the 2nd write does anything
		//Once again, lamp persistences would take care of this, but we can't do that
		for (i = 0; i < 5; i++)
		{
			m_lamps[(8*column)+i+128] = BIT(lamp_ext_data, i);
		}
	}
	m_lamp_strobe_ext_persistence ++;
	if ((m_lamp_strobe_ext_persistence == 3)||(m_lamp_strobe_ext!=column))
	{
		m_lamp_strobe_ext_persistence = 0;
		m_lamp_strobe_ext=column;
	}
}

void mpu4_state::lamp_extend_large(int data,int column,int active)
{
	int lampbase,i,bit7;

	m_lamp_sense = 0;
	bit7 = data & 0x80;
	if ( bit7 != m_last_b7 )
	{
		m_card_live = 1;
		//depending on bit 7, we can access one of two 'blocks' of 64 lamps
		lampbase = bit7 ? 0 : 64;
		if ( data & 0x3f )
		{
			m_lamp_sense = 1;
		}
		if ( active )
		{
			if (m_lamp_strobe_ext != column)
			{
				for (i = 0; i < 8; i++)
				{//CHECK, this includes bit 7
					m_lamps[(8*column)+i+128+lampbase] = BIT(data, i);
				}
				m_lamp_strobe_ext = column;
			}
		}
		m_last_b7 = bit7;
	}
	else
	{
		m_card_live = 0;
	}
}

void mpu4_state::led_write_latch(int latch, int data, int column)
{
	int diff,i,j;

	diff = (latch ^ m_last_latch) & latch;
	column = 7 - column; // like main board, these are wired up in reverse
	data = ~data;//inverted drive lines?

	for (i=0; i<5; i++)
	{
		// FIXME: this doesn't look like it could possibly be correct - it can produce 0..17 but with lots of aliasing
		if (diff & (1<<i))
		{
			column += i;
		}
	}
	for (j=0; j<8; j++)
	{
		m_mpu4leds[(column << 3) | j], BIT(data, j);
	}
	m_digits[column << 3] = data; // FIXME should this really be so sparse?

	m_last_latch = diff;
}


void mpu4_state::update_meters()
{
	int meter;
	int data = ((m_mmtr_data & 0x7f) | m_remote_meter);
	switch (m_reel_mux)
	{
	case STANDARD_REEL:
		// Change nothing
		break;

	case FIVE_REEL_5TO8:
		m_reel4->update(((data >> 4) & 0x0f));
		data = (data & 0x0F); //Strip reel data from meter drives, leaving active elements
		awp_draw_reel(machine(),"reel5", *m_reel4);
		break;

	case FIVE_REEL_8TO5:
		m_reel4->update((((data & 0x01) + ((data & 0x08) >> 2) + ((data & 0x20) >> 3) + ((data & 0x80) >> 4)) & 0x0f)) ;
		data = 0x00; //Strip all reel data from meter drives, nothing is connected
		awp_draw_reel(machine(),"reel5", *m_reel4);
		break;

	case FIVE_REEL_3TO6:
		m_reel4->update(((data >> 2) & 0x0f));
		data = 0x00; //Strip all reel data from meter drives
		awp_draw_reel(machine(),"reel5", *m_reel4);
		break;

	case SIX_REEL_1TO8:
		m_reel4->update( data       & 0x0f);
		m_reel5->update((data >> 4) & 0x0f);
		data = 0x00; //Strip all reel data from meter drives
		awp_draw_reel(machine(),"reel5", *m_reel4);
		awp_draw_reel(machine(),"reel6", *m_reel5);
		break;

	case SIX_REEL_5TO8:
		m_reel4->update(((data >> 4) & 0x0f));
		data = 0x00; //Strip all reel data from meter drives
		awp_draw_reel(machine(),"reel5", *m_reel4);
		break;

	case SEVEN_REEL:
		m_reel0->update((((data & 0x01) + ((data & 0x08) >> 2) + ((data & 0x20) >> 3) + ((data & 0x80) >> 4)) & 0x0f)) ;
		data = 0x00; //Strip all reel data from meter drives
		awp_draw_reel(machine(),"reel1", *m_reel0);
		break;

	case FLUTTERBOX: //The backbox fan assembly fits in a reel unit sized box, wired to the remote meter pin, so we can handle it here
		output().set_value("flutterbox", data & 0x80);
		data &= ~0x80; //Strip flutterbox data from meter drives
		break;
	}

	m_meters->update(7, (data & 0x80));
	for (meter = 0; meter < 4; meter ++)
	{
		m_meters->update(meter, (data & (1 << meter)));
	}
	if (m_reel_mux == STANDARD_REEL)
	{
		for (meter = 4; meter < 7; meter ++)
		{
			m_meters->update(meter, (data & (1 << meter)));
		}
	}
}

/* called if board is reset */
MACHINE_RESET_MEMBER(mpu4_state,mpu4)
{
	m_vfd->reset();

	m_lamp_strobe    = 0;
	m_lamp_strobe2   = 0;
	m_led_strobe     = 0;
	m_mmtr_data      = 0;
	m_remote_meter   = 0;

	m_IC23GC    = 0;
	m_IC23GB    = 0;
	m_IC23GA    = 0;
	m_IC23G1    = 1;
	m_IC23G2A   = 0;
	m_IC23G2B   = 0;

	m_prot_col  = 0;
	m_chr_counter    = 0;
	m_chr_value     = 0;


	{
		if (m_numbanks)
			m_bank1->set_entry(m_numbanks);

		m_maincpu->reset();
	}
}


/* 6809 IRQ handler */
WRITE_LINE_MEMBER(mpu4_state::cpu0_irq)
{
	/* The PIA and PTM IRQ lines are all connected to a common PCB track, leading directly to the 6809 IRQ line. */
	int combined_state = m_pia3->irq_a_state() | m_pia3->irq_b_state() |
							m_pia4->irq_a_state() | m_pia4->irq_b_state() |
							m_pia5->irq_a_state() | m_pia5->irq_b_state() |
							m_pia6->irq_a_state() | m_pia6->irq_b_state() |
							m_pia7->irq_a_state() | m_pia7->irq_b_state() |
							m_pia8->irq_a_state() | m_pia8->irq_b_state() |
							m_6840ptm->irq_state();

	if (!m_link7a_connected) //7B = IRQ, 7A = FIRQ, both = NMI
	{
		m_maincpu->set_input_line(M6809_IRQ_LINE, combined_state ? ASSERT_LINE : CLEAR_LINE);
		LOG(("6809 int%d \n", combined_state));
	}
	else
	{
		m_maincpu->set_input_line(M6809_FIRQ_LINE, combined_state ? ASSERT_LINE : CLEAR_LINE);
		LOG(("6809 fint%d \n", combined_state));
	}
}

/* Bankswitching
The MOD 4 ROM cards are set up to handle 8 separate ROM pages, arranged as 2 sets of 4.
The bankswitch selects which of the 4 pages in the set is active, while the bankset
switches between the sets.
It appears that the cards were originally intended to be used in a 'half' page setup,
where the two halves of the ROM space could be mixed and matched as appropriate.
However, there is no evidence to suggest this was ever implemented.
The controls for it exist however, in the form of the Soundboard PIA CB2 pin, which is
used in some cabinets instead of the main control.
*/
WRITE8_MEMBER(mpu4_state::bankswitch_w)
{
//  printf("bankswitch_w %02x\n", data);

	// m_pageset is never even set??
	m_pageval = (data & 0x03);
	m_bank1->set_entry((m_pageval + (m_pageset ? 4 : 0)) & m_numbanks);
}


READ8_MEMBER(mpu4_state::bankswitch_r)
{
	return m_bank1->entry();
}


WRITE8_MEMBER(mpu4_state::bankset_w)
{
//  printf("bankset_w %02x\n", data);

	// m_pageset is never even set??

	m_pageval = (data - 2);//writes 2 and 3, to represent 0 and 1 - a hangover from the half page design?
	m_bank1->set_entry((m_pageval + (m_pageset ? 4 : 0)) & m_numbanks);
}


/* IC2 6840 PTM handler */
WRITE_LINE_MEMBER(mpu4_state::ic2_o1_callback)
{
	m_6840ptm->set_c2(state);    /* copy output value to IC2 c2
	this output is the clock for timer2 */
	/* 1200Hz System interrupt timer */
}


WRITE_LINE_MEMBER(mpu4_state::ic2_o2_callback)
{
	m_pia3->ca1_w(state);    /* copy output value to IC3 ca1 */
	/* the output from timer2 is the input clock for timer3 */
	/* miscellaneous interrupts generated here */
	m_6840ptm->set_c3(state);
}


WRITE_LINE_MEMBER(mpu4_state::ic2_o3_callback)
{
	/* the output from timer3 is used as a square wave for the alarm output
	and as an external clock source for timer 1! */
	/* also runs lamp fade */
	m_6840ptm->set_c1(state);
}

/* 6821 PIA handlers */
/* IC3, lamp data lines + alpha numeric display */
WRITE8_MEMBER(mpu4_state::pia_ic3_porta_w)
{
	int i;
	LOG_IC3(("%s: IC3 PIA Port A Set to %2x (lamp strobes 1 - 9)\n", machine().describe_context(),data));

	if(m_ic23_active)
	{
		if (m_lamp_strobe != m_input_strobe)
		{
			// Because of the nature of the lamping circuit, there is an element of persistance
			// As a consequence, the lamp column data can change before the input strobe without
			// causing the relevant lamps to black out.

			for (i = 0; i < 8; i++)
			{
				m_lamps[(8*m_input_strobe)+i] = BIT(data, i);
			}
			m_lamp_strobe = m_input_strobe;
		}
	}
}

WRITE8_MEMBER(mpu4_state::pia_ic3_portb_w)
{
	int i;
	LOG_IC3(("%s: IC3 PIA Port B Set to %2x  (lamp strobes 10 - 17)\n", machine().describe_context(),data));

	if(m_ic23_active)
	{
		if (m_lamp_strobe2 != m_input_strobe)
		{
			for (i = 0; i < 8; i++)
			{
				m_lamps[(8*m_input_strobe)+i+64] = BIT(data, i);
			}
			m_lamp_strobe2 = m_input_strobe;
		}

		if (m_led_lamp)
		{
			/* Some games (like Connect 4) use 'programmable' LED displays, built from light display lines in section 2. */
			/* These are mostly low-tech machines, where such wiring proved cheaper than an extender card */
			/* TODO: replace this with 'segment' lamp masks, to make it more generic */
			uint8_t pled_segs[2] = {0,0};

			static const int lamps1[8] = { 106, 107, 108, 109, 104, 105, 110, 111 };
			static const int lamps2[8] = { 114, 115, 116, 117, 112, 113, 118, 119 };

			for (i = 0; i < 8; i++)
			{
				if (m_lamps[lamps1[i]]) pled_segs[0] |= (1 << i);
				if (m_lamps[lamps2[i]]) pled_segs[1] |= (1 << i);
			}

			m_digits[8] = pled_segs[0];
			m_digits[9] = pled_segs[1];
		}
	}
}

WRITE_LINE_MEMBER(mpu4_state::pia_ic3_ca2_w)
{
	LOG_IC3(("%s: IC3 PIA Write CA2 (alpha data), %02X\n", machine().describe_context(),state));
	m_vfd->data(state);
}


WRITE_LINE_MEMBER(mpu4_state::pia_ic3_cb2_w)
{
	LOG_IC3(("%s: IC3 PIA Write CB (alpha reset), %02X\n",machine().describe_context(),state));
// DM Data pin A
	m_vfd->por(state);
}


/*
IC23 emulation

IC23 is a 74LS138 1-of-8 Decoder

It is used as a multiplexer for the LEDs, lamp selects and inputs.*/

void mpu4_state::ic23_update()
{
	if (!m_IC23G2A)
	{
		if (!m_IC23G2B)
		{
			if (m_IC23G1)
			{
				if ( m_IC23GA ) m_input_strobe |= 0x01;
				else            m_input_strobe &= ~0x01;

				if ( m_IC23GB ) m_input_strobe |= 0x02;
				else            m_input_strobe &= ~0x02;

				if ( m_IC23GC ) m_input_strobe |= 0x04;
				else            m_input_strobe &= ~0x04;
			}
		}
	}
	else
	if ((m_IC23G2A)||(m_IC23G2B))
	{
		m_input_strobe = 0x00;
	}
}


/*
IC24 emulation

IC24 is a 74LS122 pulse generator

CLEAR and B2 are tied high and A1 and A2 tied low, meaning any pulse
on B1 will give a low pulse on the output pin.
*/
void mpu4_state::ic24_output(int data)
{
	m_IC23G2A = data;
	ic23_update();
}


void mpu4_state::ic24_setup()
{
	if (m_IC23GA)
	{
		double duration = TIME_OF_74LS123((220*1000),(0.1*0.000001));
		{
			m_ic23_active=1;
			ic24_output(0);
			m_ic24_timer->adjust(attotime::from_double(duration));
		}
	}
}


void mpu4_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch(id)
	{
	case TIMER_IC24:
		m_ic23_active=0;
		ic24_output(1);
		break;
	}
}


/* IC4, 7 seg leds, 50Hz timer reel sensors, current sensors */
WRITE8_MEMBER(mpu4_state::pia_ic4_porta_w)
{
	if(m_ic23_active)
	{
		if (((m_lamp_extender == NO_EXTENDER) || (m_lamp_extender == SMALL_CARD) || (m_lamp_extender == LARGE_CARD_C)) && (m_led_extender == NO_EXTENDER))
		{
			if(m_led_strobe != m_input_strobe)
			{
				for(int i=0; i<8; i++)
				{
					m_mpu4leds[((7 - m_input_strobe) << 3) | i] = BIT(data, i);
				}
				m_digits[7 - m_input_strobe] = data;
			}
			m_led_strobe = m_input_strobe;
		}
	}
}

WRITE8_MEMBER(mpu4_state::pia_ic4_portb_w)
{
	if (m_reel_mux)
	{
		/* A write here connects one reel (and only one)
		to the optic test circuit. This allows 8 reels
		to be supported instead of 4. */
		if (m_reel_mux == SEVEN_REEL)
		{
			m_active_reel= reel_mux_table7[(data >> 4) & 0x07];
		}
		else
		m_active_reel= reel_mux_table[(data >> 4) & 0x07];
	}
}

READ8_MEMBER(mpu4_state::pia_ic4_portb_r)
{
	/// TODO: this shouldn't be clocked from a read callback
	if ( m_serial_data )
	{
		m_ic4_input_b |=  0x80;
		m_pia4->cb1_w(1);
	}
	else
	{
		m_ic4_input_b &= ~0x80;
		m_pia4->cb1_w(0);
	}

	if (!m_reel_mux)
	{
		if ( m_optic_pattern & 0x01 ) m_ic4_input_b |=  0x40; /* reel A tab */
		else                          m_ic4_input_b &= ~0x40;

		if ( m_optic_pattern & 0x02 ) m_ic4_input_b |=  0x20; /* reel B tab */
		else                          m_ic4_input_b &= ~0x20;

		if ( m_optic_pattern & 0x04 ) m_ic4_input_b |=  0x10; /* reel C tab */
		else                          m_ic4_input_b &= ~0x10;

		if ( m_optic_pattern & 0x08 ) m_ic4_input_b |=  0x08; /* reel D tab */
		else                          m_ic4_input_b &= ~0x08;

	}
	else
	{
		if (m_optic_pattern & (1<<m_active_reel))
		{
			m_ic4_input_b |=  0x08;
		}
		else
		{
			m_ic4_input_b &= ~0x08;
		}
	}
	if ( m_signal_50hz )            m_ic4_input_b |=  0x04; /* 50 Hz */
	else                            m_ic4_input_b &= ~0x04;

	if (m_ic4_input_b & 0x02)
	{
		m_ic4_input_b &= ~0x02;
	}
	else
	{
		m_ic4_input_b |= 0x02; //Pulse the overcurrent line with every read to show the CPU each lamp has lit
	}
	#ifdef UNUSED_FUNCTION
	if ( lamp_undercurrent ) m_ic4_input_b |= 0x01;
	#endif

	LOG_IC3(("%s: IC4 PIA Read of Port B %x\n",machine().describe_context(),m_ic4_input_b));
	return m_ic4_input_b;
}


WRITE_LINE_MEMBER(mpu4_state::pia_ic4_ca2_w)
{
	LOG_IC3(("%s: IC4 PIA Write CA (input MUX strobe /LED B), %02X\n", machine().describe_context(),state));

	m_IC23GB = state;
	ic23_update();
}

WRITE_LINE_MEMBER(mpu4_state::pia_ic4_cb2_w)
{
	LOG_IC3(("%s: IC4 PIA Write CA (input MUX strobe /LED B), %02X\n", machine().describe_context(),state));
	m_reel_flag=state;
}

/* IC5, AUX ports, coin lockouts and AY sound chip select (MODs below 4 only) */
READ8_MEMBER(mpu4_state::pia_ic5_porta_r)
{
	if (m_lamp_extender == LARGE_CARD_A)
	{
		if (m_lamp_sense && m_ic23_active)
		{
			m_aux1_input |= 0x40;
		}
		else
		{
			m_aux1_input &= ~0x40; //Pulse the overcurrent line with every read to show the CPU each lamp has lit
		}
	}
	if (m_hopper == HOPPER_NONDUART_A)
	{
/*      if (hopper1_active)
        {
            m_aux1_input |= 0x04;
        }
        else
        {
            m_aux1_input &= ~0x04;
        }*/
	}
	LOG(("%s: IC5 PIA Read of Port A (AUX1)\n",machine().describe_context()));

	uint8_t tempinput = m_aux1_port->read()|m_aux1_input;
	if (m_aux1_invert)
	{
		return ~tempinput;
	}
	else
	{
		return tempinput;
	}
}

WRITE8_MEMBER(mpu4_state::pia_ic5_porta_w)
{
	int i;
	if (m_hopper == HOPPER_NONDUART_A)
	{
		//opto line
		//hopper1_drive_sensor(data&0x10);
	}
	switch (m_lamp_extender)
	{
	case NO_EXTENDER:
		if (m_led_extender == CARD_B)
		{
			led_write_latch(data & 0x1f, m_pia4->a_output(),m_input_strobe);
		}
		else if ((m_led_extender != CARD_A) && (m_led_extender != NO_EXTENDER))
		{
			for(i=0; i<8; i++)
			{
				m_mpu4leds[((m_input_strobe | 8) << 3) | i] = BIT(data, i);
			}
			m_digits[m_input_strobe | 8] = data;
		}
		break;

	case SMALL_CARD:
		if(m_ic23_active)
		{
			lamp_extend_small(data);
		}
		break;

	case LARGE_CARD_A:
		lamp_extend_large(data,m_input_strobe,m_ic23_active);
		break;

	case LARGE_CARD_B:
		lamp_extend_large(data,m_input_strobe,m_ic23_active);
		if ((m_ic23_active) && m_card_live)
		{
			for(i=0; i<8; i++)
			{
				m_mpu4leds[((m_last_b7 >> 7) << 6) | (m_input_strobe << 3) | i] = BIT(~data, i);
			}
			m_digits[((m_last_b7 >> 7) << 3) | m_input_strobe] = ~data;
		}
		break;

	case LARGE_CARD_C:
		lamp_extend_large(data,m_input_strobe,m_ic23_active);
		break;
	}
	if (m_reel_mux == SIX_REEL_5TO8)
	{
		m_reel4->update( data      &0x0F);
		m_reel5->update((data >> 4)&0x0F);
		awp_draw_reel(machine(),"reel5", *m_reel4);
		awp_draw_reel(machine(),"reel6", *m_reel5);
	}
	else
	if (m_reel_mux == SEVEN_REEL)
	{
		m_reel1->update( data      &0x0F);
		m_reel2->update((data >> 4)&0x0F);
		awp_draw_reel(machine(),"reel2", *m_reel1);
		awp_draw_reel(machine(),"reel3", *m_reel2);
	}

	if (core_stricmp(machine().system().name, "m4gambal") == 0)
	{
		/* The 'Gamball' device is a unique piece of mechanical equipment, designed to
		provide a truly fair hi-lo gamble for an AWP. Functionally, it consists of
		a ping-pong ball or similar enclosed in the machine's backbox, on a platform with 12
		holes. When the low 4 bytes of AUX1 are triggered, this fires the ball out from the
		hole it's currently in, to land in another. Landing in the same hole causes the machine to
		refire the ball. The ball detection is done by the high 4 bytes of AUX1.
		Here we call the MAME RNG, once to pick a row, once to pick from the four pockets within it. We
		then trigger the switches corresponding to the correct number. This appears to be the best way
		of making the game fair, short of simulating the physics of a bouncing ball ;)*/
		if (data & 0x0f)
		{
			switch ((machine().rand()>>5) % 0x3)
			{
			case 0x00: //Top row
				switch (machine().rand() & 0x3)
				{
				case 0x00: //7
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0xa0;
					break;

				case 0x01://4
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0xb0;
					break;

				case 0x02://9
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0xc0;
					break;

				case 0x03://8
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0xd0;
					break;
				}

			case 0x01: //Middle row - note switches don't match pattern
				switch (machine().rand() & 0x3)
				{
				case 0x00://12
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0x40;
					break;

				case 0x01://1
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0x50;
					break;

				case 0x02://11
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0x80;
					break;

				case 0x03://2
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0x90;
					break;
				}

			case 0x02: //Bottom row
				switch (machine().rand() & 0x3)
				{
				case 0x00://5
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0x00;
					break;

				case 0x01://10
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0x10;
					break;

				case 0x02://3
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0x20;
					break;

				case 0x03://6
					m_aux1_input = (m_aux1_input & 0x0f);
					m_aux1_input|= 0x30;
					break;
				}
			}
		}
	}
}

WRITE8_MEMBER(mpu4_state::pia_ic5_portb_w)
{
	if (m_hopper == HOPPER_NONDUART_B)
	{
		//hopper1_drive_motor(data &0x01) motor
		//hopper1_drive_sensor(data &0x08) opto
	}
	if (m_led_extender == CARD_A)
	{
		led_write_latch(data & 0x07, m_pia4->a_output(),m_input_strobe);
	}

}
READ8_MEMBER(mpu4_state::pia_ic5_portb_r)
{
	if (m_hopper == HOPPER_NONDUART_B)
	{/*
	    if (hopper1_active)
	    {
	        m_aux2_input |= 0x08;
	    }
	    else
	    {
	        m_aux2_input &= ~0x08;
	    }*/
	}

	LOG(("%s: IC5 PIA Read of Port B (coin input AUX2)\n",machine().describe_context()));
	machine().bookkeeping().coin_lockout_w(0, (m_pia5->b_output() & 0x01) );
	machine().bookkeeping().coin_lockout_w(1, (m_pia5->b_output() & 0x02) );
	machine().bookkeeping().coin_lockout_w(2, (m_pia5->b_output() & 0x04) );
	machine().bookkeeping().coin_lockout_w(3, (m_pia5->b_output() & 0x08) );

	uint8_t tempinput = m_aux2_port->read()|m_aux2_input;
	if (m_aux2_invert)
	{
		return ~tempinput;
	}
	else
	{
		return tempinput;
	}
}


WRITE_LINE_MEMBER(mpu4_state::pia_ic5_ca2_w)
{
	LOG(("%s: IC5 PIA Write CA2 (Serial Tx) %2x\n",machine().describe_context(),state));
	m_serial_data = state;
}


/* ---------------------------------------
   AY Chip sound function selection -
   ---------------------------------------
The databus of the AY sound chip is connected to IC6 Port A.
Data is read from/written to the AY chip through this port.

If this sounds familiar, Amstrad did something very similar with their home computers.

The PSG function, defined by the BC1,BC2 and BDIR signals, is controlled by CA2 and CB2 of IC6.

PSG function selection:
-----------------------
BDIR = IC6 CB2 and BC1 = IC6 CA2

Pin            | PSG Function
BDIR BC1       |
0    0         | Inactive
0    1         | Read from selected PSG register. When function is set, the PSG will make the register data available to Port A.
1    0         | Write to selected PSG register. When set, the PSG will take the data at Port A and write it into the selected PSG register.
1    1         | Select PSG register. When set, the PSG will take the data at Port A and select a register.
*/

/* PSG function selected */
void mpu4_state::update_ay(device_t *device)
{
	ay8910_device *ay8910 = machine().device<ay8910_device>("ay8913");
	if (!ay8910) return;

	pia6821_device *pia = downcast<pia6821_device *>(device);
	if (!pia->cb2_output())
	{
		switch (m_ay8913_address)
		{
		case 0x00:
			/* Inactive */
			break;

		case 0x01:
			/* CA2 = 1 CB2 = 0? : Read from selected PSG register and make the register data available to Port A */
			LOG(("AY8913 address = %d \n",m_pia6->a_output()&0x0f));
			break;

		case 0x02:
			/* CA2 = 0 CB2 = 1? : Write to selected PSG register and write data to Port A */
			ay8910->data_w(generic_space(), 0, m_pia6->a_output());
			LOG(("AY Chip Write \n"));
			break;

		case 0x03:
			/* CA2 = 1 CB2 = 1? : The register will now be selected and the user can read from or write to it.
			The register will remain selected until another is chosen.*/
			ay8910->address_w(generic_space(), 0, m_pia6->a_output());
			LOG(("AY Chip Select \n"));
			break;

		default:
			LOG(("AY Chip error \n"));
			break;
		}
	}
}


WRITE_LINE_MEMBER(mpu4_state::pia_ic5_cb2_w)
{
	update_ay(m_pia5);
}


/* IC6, Reel A and B and AY registers (MODs below 4 only) */
WRITE8_MEMBER(mpu4_state::pia_ic6_portb_w)
{
	LOG(("%s: IC6 PIA Port B Set to %2x (Reel A and B)\n", machine().describe_context(),data));

	if (m_reel_mux == SEVEN_REEL)
	{
		m_reel3->update( data      &0x0F);
		m_reel4->update((data >> 4)&0x0F);
		awp_draw_reel(machine(),"reel4", *m_reel3);
		awp_draw_reel(machine(),"reel5", *m_reel4);
	}
	else if (m_reels)
	{
		m_reel0->update( data      &0x0F);
		m_reel1->update((data >> 4)&0x0F);
		awp_draw_reel(machine(),"reel1", *m_reel0);
		awp_draw_reel(machine(),"reel2", *m_reel1);
	}
}


WRITE8_MEMBER(mpu4_state::pia_ic6_porta_w)
{
	LOG(("%s: IC6 PIA Write A %2x\n", machine().describe_context(),data));
	if (m_mod_number <4)
	{
		m_ay_data = data;
		update_ay(m_pia6);
	}
}


WRITE_LINE_MEMBER(mpu4_state::pia_ic6_ca2_w)
{
	LOG(("%s: IC6 PIA write CA2 %2x (AY8913 BC1)\n", machine().describe_context(),state));
	if (m_mod_number <4)
	{
		if ( state ) m_ay8913_address |=  0x01;
		else         m_ay8913_address &= ~0x01;
		update_ay(m_pia6);
	}
}


WRITE_LINE_MEMBER(mpu4_state::pia_ic6_cb2_w)
{
	LOG(("%s: IC6 PIA write CB2 %2x (AY8913 BCDIR)\n", machine().describe_context(),state));
	if (m_mod_number <4)
	{
		if ( state ) m_ay8913_address |=  0x02;
		else         m_ay8913_address &= ~0x02;
		update_ay(m_pia6);
	}
}


/* IC7 Reel C and D, mechanical meters/Reel E and F, input strobe bit A */
WRITE8_MEMBER(mpu4_state::pia_ic7_porta_w)
{
	LOG(("%s: IC7 PIA Port A Set to %2x (Reel C and D)\n", machine().describe_context(),data));
	if (m_reel_mux == SEVEN_REEL)
	{
		m_reel5->update( data      &0x0F);
		m_reel6->update((data >> 4)&0x0F);
		awp_draw_reel(machine(),"reel6", *m_reel5);
		awp_draw_reel(machine(),"reel7", *m_reel7);
	}
	else if (m_reels)
	{
		m_reel2->update( data      &0x0F);
		m_reel3->update((data >> 4)&0x0F);
		awp_draw_reel(machine(),"reel3", *m_reel2);
		awp_draw_reel(machine(),"reel4", *m_reel3);
	}
}

WRITE8_MEMBER(mpu4_state::pia_ic7_portb_w)
{
	if (m_hopper == HOPPER_DUART_A)
	{
		//duart write data
	}
	else if (m_hopper == HOPPER_NONDUART_A)
	{
		//hoppr1_drive_motor(data & 0x10);
	}

	m_mmtr_data = data;
}

READ8_MEMBER(mpu4_state::pia_ic7_portb_r)
{
/* The meters are connected to a voltage drop sensor, where current
flowing through them also passes through pin B7, meaning that when
any meter is activated, pin B7 goes high.
As for why they connected this to an output port rather than using
CB1, no idea, although it proved of benefit when the reel multiplexer was designed
as it allows a separate meter to be used when the rest of the port is blocked.
This appears to have confounded the schematic drawer, who has assumed that
all eight meters are driven from this port, giving the 8 line driver chip
9 connections in total. */

	//This may be overkill, but the meter sensing is VERY picky

	int combined_meter = m_meters->GetActivity(0) | m_meters->GetActivity(1) |
							m_meters->GetActivity(2) | m_meters->GetActivity(3) |
							m_meters->GetActivity(4) | m_meters->GetActivity(5) |
							m_meters->GetActivity(6) | m_meters->GetActivity(7);

	if(combined_meter)
	{
		return 0x80;
	}
	else
	{
		return 0x00;
	}
}

WRITE_LINE_MEMBER(mpu4_state::pia_ic7_ca2_w)
{
	LOG(("%s: IC7 PIA write CA2 %2x (input strobe bit 0 / LED A)\n", machine().describe_context(),state));

	m_IC23GA = state;
	ic24_setup();
	ic23_update();
}

WRITE_LINE_MEMBER(mpu4_state::pia_ic7_cb2_w)
{
	m_remote_meter = state?0x80:0x00;
}


/* IC8, Inputs, TRIACS, alpha clock */
READ8_MEMBER(mpu4_state::pia_ic8_porta_r)
{
	LOG_IC8(("%s: IC8 PIA Read of Port A (MUX input data)\n", machine().describe_context()));
/* The orange inputs are polled twice as often as the black ones, for reasons of efficiency.
   This is achieved via connecting every input line to an AND gate, thus allowing two strobes
   to represent each orange input bank (strobes are active low). */
	m_pia5->cb1_w(m_aux2_port->read() & 0x80);
	if ( (m_input_strobe == 2) && (m_door_invert ==1) )
	{
		return ((m_port_mux[m_input_strobe])->read() ^ 0x01);
	}
	else
	{
		return (m_port_mux[m_input_strobe])->read();
	}
}


WRITE8_MEMBER(mpu4_state::pia_ic8_portb_w)
{
	if (m_hopper == HOPPER_DUART_B)
	{
//      duart.drive_sensor(data & 0x04, data & 0x01, 0, 0);
	}
	else if (m_hopper == HOPPER_DUART_C)
	{
//      duart.drive_sensor(data & 0x04, data & 0x01, data & 0x04, data & 0x02);
	}
	LOG_IC8(("%s: IC8 PIA Port B Set to %2x (OUTPUT PORT, TRIACS)\n", machine().describe_context(),data));
	for (int i = 0; i < 8; i++)
	{
		m_triacs[i] = BIT(data, i);
	}
}

WRITE_LINE_MEMBER(mpu4_state::pia_ic8_ca2_w)
{
	LOG_IC8(("%s: IC8 PIA write CA2 (input_strobe bit 2 / LED C) %02X\n", machine().describe_context(), state & 0xFF));

	m_IC23GC = state;
	ic23_update();
}


WRITE_LINE_MEMBER(mpu4_state::pia_ic8_cb2_w)
{
	LOG_IC8(("%s: IC8 PIA write CB2 (alpha clock) %02X\n", machine().describe_context(), state & 0xFF));

	// DM Data pin B

	m_vfd->sclk(!state);
}

// universal sampled sound program card PCB 683077
// Sampled sound card, using a PIA and PTM for timing and data handling
WRITE8_MEMBER(mpu4_state::pia_gb_porta_w)
{
	LOG_SS(("%s: GAMEBOARD: PIA Port A Set to %2x\n", machine().describe_context(),data));
	m_msm6376->write(space, 0, data);
}

WRITE8_MEMBER(mpu4_state::pia_gb_portb_w)
{
	int changed = m_expansion_latch^data;

	LOG_SS(("%s: GAMEBOARD: PIA Port B Set to %2x\n", machine().describe_context(),data));

	if ( changed & 0x20)
	{ // digital volume clock line changed
		if ( !(data & 0x20) )
		{ // changed from high to low,
			if ( !(data & 0x10) )//down
			{
				if ( m_global_volume < 32 ) m_global_volume++; //steps unknown
			}
			else
			{//up
				if ( m_global_volume > 0  ) m_global_volume--;
			}

			{
				float percent = (32-m_global_volume)/32.0;
				m_msm6376->set_output_gain(0, percent);
				m_msm6376->set_output_gain(1, percent);
			}
		}
	}
	m_msm6376->ch2_w(data&0x02);
	m_msm6376->st_w(data&0x01);
}
READ8_MEMBER(mpu4_state::pia_gb_portb_r)
{
	LOG_SS(("%s: GAMEBOARD: PIA Read of Port B\n",machine().describe_context()));
	int data=0;
	// b7 NAR - we can load another address into Channel 1
	// b6, 1 = OKI ready, 0 = OKI busy
	// b5, vol clock
	// b4, 1 = Vol down, 0 = Vol up
	//

	if ( m_msm6376->nar_r() ) data |= 0x80;
	else                           data &= ~0x80;

	if ( m_msm6376->busy_r() ) data |= 0x40;
	else                            data &= ~0x40;

	return ( data | m_expansion_latch );
}

WRITE_LINE_MEMBER(mpu4_state::pia_gb_ca2_w)
{
	LOG_SS(("%s: GAMEBOARD: OKI RESET data = %02X\n", machine().describe_context(), state));

//  reset line
}

WRITE_LINE_MEMBER(mpu4_state::pia_gb_cb2_w)
{
	//Some BWB games use this to drive the bankswitching
	if (m_bwb_bank)
	{
		//printf("pia_gb_cb2_w %d\n", state);
		m_pageval = state;
		m_bank1->set_entry((m_pageval + (m_pageset ? 4 : 0)) & m_numbanks);
	}
}

//Sampled sound timer
/*
The MSM6376 sound chip is configured in a slightly strange way, to enable dynamic
sample rate changes (8Khz, 10.6 Khz, 16 KHz) by varying the clock.
According to the BwB programmer's guide, the formula is:
MSM6376 clock frequency:-
freq = (1720000/((t3L+1)(t3H+1)))*[(t3H(T3L+1)+1)/(2(t1+1))]
where [] means rounded up integer,
t3L is the LSB of Clock 3,
t3H is the MSB of Clock 3,
and t1 is the initial value in clock 1.
*/

//O3 -> G1  O1 -> c2 o2 -> c1

/* This is a bit of a cheat - since we don't clock into the OKI chip directly, we need to
calculate the oscillation frequency in advance. We're running the timer for interrupt
purposes, but the frequency calculation is done by plucking the values out as they are written.*/
WRITE8_MEMBER(mpu4_state::ic3ss_w)
{
	device_t *ic3ss = machine().device("ptm_ic3ss");
	downcast<ptm6840_device *>(ic3ss)->write(offset,data);

	if (offset == 3)
	{
		m_t1 = data;
	}
	if (offset == 6)
	{
		m_t3h = data;
	}
	if (offset == 7)
	{
		m_t3l = data;
	}

	float num = (1720000/((m_t3l + 1)*(m_t3h + 1)));
	float denom1 = ((m_t3h *(m_t3l + 1)+ 1)/(2*(m_t1 + 1)));

	int denom2 = denom1 + 0.5f;//need to round up, this gives same precision as chip
	int freq=num*denom2;

	if (freq)
	{
		m_msm6376->set_unscaled_clock(freq);
	}
}

/* input ports for MPU4 board */
INPUT_PORTS_START( mpu4 )
	PORT_START("ORANGE1")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("00")//  20p level
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("01")// 100p level
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("02")// Token 1 level
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("03")// Token 2 level
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("04")
	PORT_CONFNAME( 0xE0, 0x00, "Stake Key" )
	PORT_CONFSETTING(    0x00, "Not fitted / 5p"  )
	PORT_CONFSETTING(    0x20, "10p" )
	PORT_CONFSETTING(    0x40, "20p" )
	PORT_CONFSETTING(    0x60, "25p" )
	PORT_CONFSETTING(    0x80, "30p" )
	PORT_CONFSETTING(    0xA0, "40p" )
	PORT_CONFSETTING(    0xC0, "50p" )
	PORT_CONFSETTING(    0xE0, "1 GBP" )

	PORT_START("ORANGE2")
	PORT_CONFNAME( 0x0F, 0x00, "Jackpot / Prize Key" )
	PORT_CONFSETTING(    0x00, "Not fitted"  )
	PORT_CONFSETTING(    0x01, "3 GBP"  )
	PORT_CONFSETTING(    0x02, "4 GBP"  )
	PORT_CONFSETTING(    0x08, "5 GBP"  )
	PORT_CONFSETTING(    0x03, "6 GBP"  )
	PORT_CONFSETTING(    0x04, "6 GBP Token"  )
	PORT_CONFSETTING(    0x05, "8 GBP"  )
	PORT_CONFSETTING(    0x06, "8 GBP Token"  )
	PORT_CONFSETTING(    0x07, "10 GBP"  )
	PORT_CONFSETTING(    0x09, "15 GBP"  )
	PORT_CONFSETTING(    0x0A, "25 GBP"  )
	PORT_CONFSETTING(    0x0B, "25 GBP (Licensed Betting Office Profile)"  )
	PORT_CONFSETTING(    0x0C, "35 GBP"  )
	PORT_CONFSETTING(    0x0D, "70 GBP"  )
	PORT_CONFSETTING(    0x0E, "Reserved"  )
	PORT_CONFSETTING(    0x0F, "Reserved"  )

	PORT_CONFNAME( 0xF0, 0x00, "Percentage Key" )
	PORT_CONFSETTING(    0x00, "Not fitted / 68% (Invalid for UK Games)"  )
	PORT_CONFSETTING(    0x10, "70" )
	PORT_CONFSETTING(    0x20, "72" )
	PORT_CONFSETTING(    0x30, "74" )
	PORT_CONFSETTING(    0x40, "76" )
	PORT_CONFSETTING(    0x50, "78" )
	PORT_CONFSETTING(    0x60, "80" )
	PORT_CONFSETTING(    0x70, "82" )
	PORT_CONFSETTING(    0x80, "84" )
	PORT_CONFSETTING(    0x90, "86" )
	PORT_CONFSETTING(    0xA0, "88" )
	PORT_CONFSETTING(    0xB0, "90" )
	PORT_CONFSETTING(    0xC0, "92" )
	PORT_CONFSETTING(    0xD0, "94" )
	PORT_CONFSETTING(    0xE0, "96" )
	PORT_CONFSETTING(    0xF0, "98" )

	PORT_START("BLACK1")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Hi")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Lo")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER)   PORT_NAME("18")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER)   PORT_NAME("19")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER)   PORT_NAME("20")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_SERVICE) PORT_NAME("Test Button") PORT_CODE(KEYCODE_W)
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_SERVICE) PORT_NAME("Refill Key") PORT_CODE(KEYCODE_R) PORT_TOGGLE
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_INTERLOCK) PORT_NAME("Cashbox (Back) Door")  PORT_CODE(KEYCODE_Q) PORT_TOGGLE

	PORT_START("BLACK2")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("24")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("25")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_NAME("Cancel")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_NAME("Hold 1")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_NAME("Hold 2")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_NAME("Hold 3")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_NAME("Hold 4")
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_START1)

	PORT_START("DIL1")
	PORT_DIPNAME( 0x01, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIL1:01")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x01, DEF_STR( On  ) )
	PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIL1:02")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x02, DEF_STR( On  ) )
	PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIL1:03")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x04, DEF_STR( On  ) )
	PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIL1:04")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x08, DEF_STR( On  ) )
	PORT_DIPNAME( 0xF0, 0x00, "Target Percentage (if key not fitted)" )PORT_DIPLOCATION("DIL1:05,06,07,08")
	PORT_DIPSETTING(    0x00, "Unset (Program Optimum)"  )
	PORT_DIPSETTING(    0x10, "70" )
	PORT_DIPSETTING(    0x20, "72" )
	PORT_DIPSETTING(    0x30, "74" )
	PORT_DIPSETTING(    0x40, "76" )
	PORT_DIPSETTING(    0x50, "78" )
	PORT_DIPSETTING(    0x60, "80" )
	PORT_DIPSETTING(    0x70, "82" )
	PORT_DIPSETTING(    0x80, "84" )
	PORT_DIPSETTING(    0x90, "86" )
	PORT_DIPSETTING(    0xA0, "88" )
	PORT_DIPSETTING(    0xB0, "90" )
	PORT_DIPSETTING(    0xC0, "92" )
	PORT_DIPSETTING(    0xD0, "94" )
	PORT_DIPSETTING(    0xE0, "96" )
	PORT_DIPSETTING(    0xF0, "98" )

	PORT_START("DIL2")
	PORT_DIPNAME( 0x01, 0x00, "Token Lockout when full" ) PORT_DIPLOCATION("DIL2:01")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x01, DEF_STR( On  ) )
	PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unused )) PORT_DIPLOCATION("DIL2:02")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x02, DEF_STR( On  ) )
	PORT_DIPNAME( 0x04, 0x00, "Scottish Coin Handling" ) PORT_DIPLOCATION("DIL2:03")//20p payout
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x04, DEF_STR( On  ) )
	PORT_DIPNAME( 0x08, 0x08, "Out of Credit Display Inhibit" ) PORT_DIPLOCATION("DIL2:04")  // many games need this on to boot
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x08, DEF_STR( On  ) )
	PORT_DIPNAME( 0x10, 0x00, "OCD Audio Enable" ) PORT_DIPLOCATION("DIL2:05")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x10, DEF_STR( On  ) )
	PORT_DIPNAME( 0x20, 0x00, "Coin Alarm Inhibit" ) PORT_DIPLOCATION("DIL2:06")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x20, DEF_STR( On  ) )
	PORT_DIPNAME( 0x40, 0x00, "Token Refill Level Inhibit" ) PORT_DIPLOCATION("DIL2:07")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x40, DEF_STR( On  ) )
	PORT_DIPNAME( 0x80, 0x00, "Single Credit Entry" ) PORT_DIPLOCATION("DIL2:08")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x80, DEF_STR( On  ) )

	PORT_START("AUX1")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("0")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("1")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("2")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("3")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("4")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("5")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("6")
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("7")

	PORT_START("AUX2")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_CUSTOM)
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_CUSTOM)
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_CUSTOM)
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_CUSTOM)
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_COIN1) PORT_NAME("10p")//PORT_IMPULSE(5)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_COIN2) PORT_NAME("20p")//PORT_IMPULSE(5)
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_COIN3) PORT_NAME("50p")//PORT_IMPULSE(5)
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_COIN4) PORT_NAME("100p")//PORT_IMPULSE(5)
INPUT_PORTS_END


INPUT_PORTS_START( mpu4_cw )
//Inputs for CoinWorld games
	PORT_INCLUDE( mpu4 )
	PORT_MODIFY("DIL1")
	PORT_DIPNAME( 0x01, 0x00, "Profile Type" ) PORT_DIPLOCATION("DIL1:01")
	PORT_DIPSETTING(    0x00, "Bingo Profile" )
	PORT_DIPSETTING(    0x01, "Arcade" )
	PORT_DIPNAME( 0x02, 0x00, "Accept 2 GBP Coin?" ) PORT_DIPLOCATION("DIL1:02")
	PORT_DIPSETTING(    0x00, DEF_STR( No ) )
	PORT_DIPSETTING(    0x02, DEF_STR( Yes  ) )
	PORT_DIPNAME( 0x0C, 0x00, "Jackpot" ) PORT_DIPLOCATION("DIL1:03,04")
	PORT_DIPSETTING(    0x04, "15 GBP" )
	PORT_DIPSETTING(    0x00, "10 GBP" )
	PORT_DIPSETTING(    0x08, "5 GBP" )
	PORT_DIPNAME( 0x10, 0x00, "Hold Mode" ) PORT_DIPLOCATION("DIL1:05")
	PORT_DIPSETTING(    0x00, "Show Hints" )
	PORT_DIPSETTING(    0x10, "Auto Hold" )
	PORT_DIPNAME( 0x20, 0x00, "Coin Mech Type" ) PORT_DIPLOCATION("DIL1:05")
	PORT_DIPSETTING(    0x00, "6 Coin" )
	PORT_DIPSETTING(    0x20, "5 Coin" )
	PORT_DIPNAME( 0x40, 0x00, "Reel Motor Type" ) PORT_DIPLOCATION("DIL1:05")
	PORT_DIPSETTING(    0x00, "Slim motor" )
	PORT_DIPSETTING(    0x40, "Fat motor" )
	PORT_DIPNAME( 0x80, 0x00, "Payout Tube" ) PORT_DIPLOCATION("DIL1:05")
	PORT_DIPSETTING(    0x00, "20p" )
	PORT_DIPSETTING(    0x80, "10p" )

	PORT_MODIFY("DIL2")
	PORT_DIPNAME( 0x07, 0x00, "Stake Setting" )
	PORT_DIPSETTING(    0x00, "Not fitted / 5p"  )
	PORT_DIPSETTING(    0x01, "10p" )
	PORT_DIPSETTING(    0x02, "20p" )
	PORT_DIPSETTING(    0x03, "25p" )
	PORT_DIPSETTING(    0x04, "30p" )
	PORT_BIT(0xE0, IP_ACTIVE_HIGH, IPT_UNUSED)
	INPUT_PORTS_END

INPUT_PORTS_START( mpu4jackpot8tkn )
	PORT_INCLUDE( mpu4 )

	PORT_MODIFY("ORANGE2")
	PORT_CONFNAME( 0x0F, 0x06, "Jackpot / Prize Key" )
	PORT_CONFSETTING(    0x00, "Not fitted"  )
	PORT_CONFSETTING(    0x01, "3 GBP"  )
	PORT_CONFSETTING(    0x02, "4 GBP"  )
	PORT_CONFSETTING(    0x08, "5 GBP"  )
	PORT_CONFSETTING(    0x03, "6 GBP"  )
	PORT_CONFSETTING(    0x04, "6 GBP Token"  )
	PORT_CONFSETTING(    0x05, "8 GBP"  )
	PORT_CONFSETTING(    0x06, "8 GBP Token"  )
	PORT_CONFSETTING(    0x07, "10 GBP"  )
	PORT_CONFSETTING(    0x09, "15 GBP"  )
	PORT_CONFSETTING(    0x0A, "25 GBP"  )
	PORT_CONFSETTING(    0x0B, "25 GBP (Licensed Betting Office Profile)"  )
	PORT_CONFSETTING(    0x0C, "35 GBP"  )
	PORT_CONFSETTING(    0x0D, "70 GBP"  )
	PORT_CONFSETTING(    0x0E, "Reserved"  )
	PORT_CONFSETTING(    0x0F, "Reserved"  )
INPUT_PORTS_END

INPUT_PORTS_START( mpu4jackpot8per )
	PORT_INCLUDE( mpu4 )

	PORT_MODIFY("ORANGE2")
	PORT_CONFNAME( 0x0F, 0x06, "Jackpot / Prize Key" )
	PORT_CONFSETTING(    0x00, "Not fitted"  )
	PORT_CONFSETTING(    0x01, "3 GBP"  )
	PORT_CONFSETTING(    0x02, "4 GBP"  )
	PORT_CONFSETTING(    0x08, "5 GBP"  )
	PORT_CONFSETTING(    0x03, "6 GBP"  )
	PORT_CONFSETTING(    0x04, "6 GBP Token"  )
	PORT_CONFSETTING(    0x05, "8 GBP"  )
	PORT_CONFSETTING(    0x06, "8 GBP Token"  )
	PORT_CONFSETTING(    0x07, "10 GBP"  )
	PORT_CONFSETTING(    0x09, "15 GBP"  )
	PORT_CONFSETTING(    0x0A, "25 GBP"  )
	PORT_CONFSETTING(    0x0B, "25 GBP (Licensed Betting Office Profile)"  )
	PORT_CONFSETTING(    0x0C, "35 GBP"  )
	PORT_CONFSETTING(    0x0D, "70 GBP"  )
	PORT_CONFSETTING(    0x0E, "Reserved"  )
	PORT_CONFSETTING(    0x0F, "Reserved"  )

	PORT_CONFNAME( 0xF0, 0x10, "Percentage Key" )
	PORT_CONFSETTING(    0x00, "Not fitted / 68% (Invalid for UK Games)"  )
	PORT_CONFSETTING(    0x10, "70" )
	PORT_CONFSETTING(    0x20, "72" )
	PORT_CONFSETTING(    0x30, "74" )
	PORT_CONFSETTING(    0x40, "76" )
	PORT_CONFSETTING(    0x50, "78" )
	PORT_CONFSETTING(    0x60, "80" )
	PORT_CONFSETTING(    0x70, "82" )
	PORT_CONFSETTING(    0x80, "84" )
	PORT_CONFSETTING(    0x90, "86" )
	PORT_CONFSETTING(    0xA0, "88" )
	PORT_CONFSETTING(    0xB0, "90" )
	PORT_CONFSETTING(    0xC0, "92" )
	PORT_CONFSETTING(    0xD0, "94" )
	PORT_CONFSETTING(    0xE0, "96" )
	PORT_CONFSETTING(    0xF0, "98" )
INPUT_PORTS_END




INPUT_PORTS_START( grtecp )
	PORT_START("ORANGE1")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("00")//  20p level
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("01")// 100p level
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("02")// Token 1 level
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("03")// Token 2 level
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("04")
	PORT_CONFNAME( 0xE0, 0x00, "Stake Key" )
	PORT_CONFSETTING(    0x00, "Not fitted / 5p"  )
	PORT_CONFSETTING(    0x20, "10p" )
	PORT_CONFSETTING(    0x40, "20p" )
	PORT_CONFSETTING(    0x60, "25p" )
	PORT_CONFSETTING(    0x80, "30p" )
	PORT_CONFSETTING(    0xA0, "40p" )
	PORT_CONFSETTING(    0xC0, "50p" )
	PORT_CONFSETTING(    0xE0, "1 GBP" )

	PORT_START("ORANGE2")
	PORT_CONFNAME( 0x0F, 0x00, "Jackpot / Prize Key" )
	PORT_CONFSETTING(    0x00, "Not fitted"  )
	PORT_CONFSETTING(    0x01, "3 GBP"  )
	PORT_CONFSETTING(    0x02, "4 GBP"  )
	PORT_CONFSETTING(    0x08, "5 GBP"  )
	PORT_CONFSETTING(    0x03, "6 GBP"  )
	PORT_CONFSETTING(    0x04, "6 GBP Token"  )
	PORT_CONFSETTING(    0x05, "8 GBP"  )
	PORT_CONFSETTING(    0x06, "8 GBP Token"  )
	PORT_CONFSETTING(    0x07, "10 GBP"  )
	PORT_CONFSETTING(    0x09, "15 GBP"  )
	PORT_CONFSETTING(    0x0A, "25 GBP"  )
	PORT_CONFSETTING(    0x0B, "25 GBP (Licensed Betting Office Profile)"  )
	PORT_CONFSETTING(    0x0C, "35 GBP"  )
	PORT_CONFSETTING(    0x0D, "70 GBP"  )
	PORT_CONFSETTING(    0x0E, "Reserved"  )
	PORT_CONFSETTING(    0x0F, "Reserved"  )

	PORT_CONFNAME( 0xF0, 0x00, "Percentage Key" )
	PORT_CONFSETTING(    0x00, "As Option Switches"  )
	PORT_CONFSETTING(    0x10, "70" )
	PORT_CONFSETTING(    0x20, "72" )
	PORT_CONFSETTING(    0x30, "74" )
	PORT_CONFSETTING(    0x40, "76" )
	PORT_CONFSETTING(    0x50, "78" )
	PORT_CONFSETTING(    0x60, "80" )
	PORT_CONFSETTING(    0x70, "82" )
	PORT_CONFSETTING(    0x80, "84" )
	PORT_CONFSETTING(    0x90, "86" )
	PORT_CONFSETTING(    0xA0, "88" )
	PORT_CONFSETTING(    0xB0, "90" )
	PORT_CONFSETTING(    0xC0, "92" )
	PORT_CONFSETTING(    0xD0, "94" )
	PORT_CONFSETTING(    0xE0, "96" )
	PORT_CONFSETTING(    0xF0, "98" )

	PORT_START("BLACK1")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED)
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_UNUSED)
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED)
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED)
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_UNUSED)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_SERVICE) PORT_NAME("Test Button") PORT_CODE(KEYCODE_W)
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_SERVICE) PORT_NAME("Refill Key") PORT_CODE(KEYCODE_R) PORT_TOGGLE
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_INTERLOCK) PORT_NAME("Cashbox (Back) Door") PORT_CODE(KEYCODE_Q) PORT_TOGGLE

	PORT_START("BLACK2")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Collect/Cancel")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Hold 1")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_NAME("Hold 2")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_NAME("Hold 3")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_NAME("Hi")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_NAME("Lo")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_NAME("Exchange")
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_START1)

	PORT_START("DIL1")
	PORT_DIPNAME( 0x01, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIL1:01")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x01, DEF_STR( On  ) )
	PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIL1:02")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x02, DEF_STR( On  ) )
	PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIL1:03")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x04, DEF_STR( On  ) )
	PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIL1:04")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x08, DEF_STR( On  ) )
	PORT_DIPNAME( 0xF0, 0x00, "Target Percentage (if key not fitted)" )PORT_DIPLOCATION("DIL1:05,06,07,08")
	PORT_DIPSETTING(    0x00, "Unset (Program Optimum)"  )
	PORT_DIPSETTING(    0x10, "70" )
	PORT_DIPSETTING(    0x20, "72" )
	PORT_DIPSETTING(    0x30, "74" )
	PORT_DIPSETTING(    0x40, "76" )
	PORT_DIPSETTING(    0x50, "78" )
	PORT_DIPSETTING(    0x60, "80" )
	PORT_DIPSETTING(    0x70, "82" )
	PORT_DIPSETTING(    0x80, "84" )
	PORT_DIPSETTING(    0x90, "86" )
	PORT_DIPSETTING(    0xA0, "88" )
	PORT_DIPSETTING(    0xB0, "90" )
	PORT_DIPSETTING(    0xC0, "92" )
	PORT_DIPSETTING(    0xD0, "94" )
	PORT_DIPSETTING(    0xE0, "96" )
	PORT_DIPSETTING(    0xF0, "98" )

	PORT_START("DIL2")
	PORT_DIPNAME( 0x01, 0x00, "Token Lockout when full" ) PORT_DIPLOCATION("DIL2:01")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x01, DEF_STR( On  ) )
	PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unused )) PORT_DIPLOCATION("DIL2:02")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x02, DEF_STR( On  ) )
	PORT_DIPNAME( 0x04, 0x00, "Scottish Coin Handling" ) PORT_DIPLOCATION("DIL2:03")//20p payout
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x04, DEF_STR( On  ) )
	PORT_DIPNAME( 0x08, 0x00, "Out of Credit Display Inhibit" ) PORT_DIPLOCATION("DIL2:04")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x08, DEF_STR( On  ) )
	PORT_DIPNAME( 0x10, 0x00, "OCD Audio Enable" ) PORT_DIPLOCATION("DIL2:05")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x10, DEF_STR( On  ) )
	PORT_DIPNAME( 0x20, 0x00, "Coin Alarm Inhibit" ) PORT_DIPLOCATION("DIL2:06")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x20, DEF_STR( On  ) )
	PORT_DIPNAME( 0x40, 0x00, "Token Refill Level Inhibit" ) PORT_DIPLOCATION("DIL2:07")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x40, DEF_STR( On  ) )
	PORT_DIPNAME( 0x80, 0x00, "Single Credit Entry" ) PORT_DIPLOCATION("DIL2:08")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x80, DEF_STR( On  ) )

	PORT_START("AUX1")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("0")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("1")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("2")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("3")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("4")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("5")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("6")
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("7")

	PORT_START("AUX2")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_CUSTOM)
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_CUSTOM)
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_CUSTOM)
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_CUSTOM)
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_COIN1) PORT_NAME("10p")//PORT_IMPULSE(5)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_COIN2) PORT_NAME("20p")//PORT_IMPULSE(5)
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_COIN3) PORT_NAME("50p")//PORT_IMPULSE(5)
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_COIN4) PORT_NAME("100p")//PORT_IMPULSE(5)
INPUT_PORTS_END



/*
Characteriser (CHR)

As built, the CHR is a PAL which can perform basic bit manipulation according to
an as yet unknown unique key. However, the programmers decided to best use this protection device in read/write/compare
cycles, storing almost the entire 'hidden' data table in the ROMs in plain sight. Only later rebuilds by BwB
avoided this 'feature' of the development kit, and will need a different setup.

This information has been used to generate the CHR tables loaded by the programs, until a key can be determined.

For most Barcrest games, the following method was used:

The initial 'PALTEST' routine as found in the Barcrest programs simply writes the first 'call' to the CHR space,
to read back the 'response'. There is no attempt to alter the order or anything else, just
a simple runthrough of the entire data table. The only 'catch' in this is to note that the CHR chip always scans
through the table starting at the last accessed data value, unless 00 is used to reset to the beginning. This is obviously
a simplification, in fact the PAL does bit manipulation with some latching.

However, a final 8 byte row, that controls the lamp matrix is not tested - to date, no-one outside of Barcrest knows
how this is generated, and currently trial and error is the only sensible method. It is noted that the default,
of all 00, is sometimes the correct answer, particularly in non-Barcrest use of the CHR chip, though when used normally,
there are again fixed call values.

Apparently, just before the characteriser is checked bit 1 at 0x61DF is checked and if zero the characteriser
check is bypassed. This may be something to look at for prototype ROMs and hacks.

*/


WRITE8_MEMBER(mpu4_state::characteriser_w)
{
	int x;
	int call=data;
	LOG_CHR_FULL(("%s Characteriser write offset %02X data %02X\n", machine().describe_context(), offset, data));
	if (!m_current_chr_table)
	{
		logerror("%s No Characteriser Table\n", machine().describe_context());
		return;
	}



	if (offset == 0)
	{
		{
			if (call == 0)
			{
				m_prot_col = 0;
			}
			else
			{
				for (x = m_prot_col; x < 64; x++)
				{
					if  (m_current_chr_table[(x)].call == call)
					{
						m_prot_col = x;
						LOG_CHR(("Characteriser find column %02X\n",m_prot_col));
						break;
					}
				}
			}
		}
	}
	else if (offset == 2)
	{
		LOG_CHR(("Characteriser write 2 data %02X\n",data));
		// Rather than the search strategy, we can map the calls directly here. Note that they are hex versions of the square number series
		switch (call)
		{
		case 0x00:
			m_lamp_col = 0;
			break;

		case 0x01:
			m_lamp_col = 1;
			break;

		case 0x04:
			m_lamp_col = 2;
			break;

		case 0x09:
			m_lamp_col = 3;
			break;

		case 0x10:
			m_lamp_col = 4;
			break;

		case 0x19:
			m_lamp_col = 5;
			break;

		case 0x24:
			m_lamp_col = 6;
			break;

		case 0x31:
			m_lamp_col = 7;
			break;
		}
		LOG_CHR(("Characteriser find 2 column %02X\n",m_lamp_col));
	}
}


READ8_MEMBER(mpu4_state::characteriser_r)
{
	if (!m_current_chr_table)
	{
		logerror("%s No Characteriser Table\n", machine().describe_context());

		/* a cheat ... many early games use a standard check */
		int addr = m_maincpu->state_int(M6809_X);
		if ((addr>=0x800) && (addr<=0xfff)) return 0x00; // prevent recursion, only care about ram/rom areas for this cheat.

		uint8_t ret = space.read_byte(addr);
		logerror(" (returning %02x)",ret);

		logerror("\n");

		return ret;
	}

	LOG_CHR(("Characteriser read offset %02X \n",offset));
	if (offset == 0)
	{
		LOG_CHR(("Characteriser read data %02X \n",m_current_chr_table[m_prot_col].response));
		return m_current_chr_table[m_prot_col].response;
	}

	if (offset == 3)
	{
		LOG_CHR(("Characteriser read data off 3 %02X \n",m_current_chr_table[m_lamp_col+64].response));
		return m_current_chr_table[m_lamp_col+64].response;
	}
	return 0;
}

/*
BwB Characteriser (CHR)

The BwB method of protection is considerably different to the Barcrest one, with any
incorrect behaviour manifesting in ridiculously large payouts. The hardware is the
same, however the main weakness of the software has been eliminated.

In fact, the software seems deliberately designed to mislead, but is (fortunately for
us) prone to similar weaknesses that allow a per game solution.

Project Amber performed a source analysis (available on request) which appears to make things work.
Said weaknesses (A Cheats Guide according to Project Amber)

The common initialisation sequence is "00 04 04 0C 0C 1C 14 2C 5C 2C"
                                        0  1  2  3  4  5  6  7  8
Using debug search for the first read from said string (best to find it first).

At this point, the X index on the CPU is at the magic number address.

The subsequent calls for each can be found based on the magic address

           (0) = ( (BWBMagicAddress))
           (1) = ( (BWBMagicAddress + 1))
           (2) = ( (BWBMagicAddress + 2))
           (3) = ( (BWBMagicAddress + 4))
           (4) = ( (BWBMagicAddress - 5))
           (5) = ( (BWBMagicAddress - 4))
           (6) = ( (BWBMagicAddress - 3))
           (7) = ( (BWBMagicAddress - 2))
           (8) = ( (BWBMagicAddress - 1))

These return the standard init sequence as above.

For ease of understanding, we use three tables, one holding the common responses
and two holding the appropriate call and response pairs for the two stages of operation
*/


WRITE8_MEMBER(mpu4_state::bwb_characteriser_w)
{
	int x;
	int call=data;
	LOG_CHR_FULL(("%s Characteriser write offset %02X data %02X\n", machine().describe_context(), offset, data));
	if (!m_current_chr_table)
		fatalerror("%s No Characteriser Table\n", machine().describe_context().c_str());

	if ((offset & 0x3f)== 0)//initialisation is always at 0x800
	{
		if (!m_chr_state)
		{
			m_chr_state=1;
			m_chr_counter=0;
		}
		if (call == 0)
		{
			m_init_col ++;
		}
		else
		{
			m_init_col =0;
		}
	}

	m_chr_value = machine().rand();
	for (x = 0; x < 4; x++)
	{
		if  (m_current_chr_table[(x)].call == call)
		{
			if (x == 0) // reinit
			{
				m_bwb_return = 0;
			}
			m_chr_value = bwb_chr_table_common[(m_bwb_return)];
			m_bwb_return++;
			break;
		}
	}
}

READ8_MEMBER(mpu4_state::bwb_characteriser_r)
{
	LOG_CHR(("Characteriser read offset %02X \n",offset));


	if (offset ==0)
	{
		switch (m_chr_counter)
		{
		case 6:
		case 13:
		case 20:
		case 27:
		case 34:
			return m_bwb_chr_table1[(((m_chr_counter + 1) / 7) - 1)].response;

		default:
			if (m_chr_counter > 34)
			{
				m_chr_counter = 35;
				m_chr_state = 2;
			}
			m_chr_counter ++;
			return m_chr_value;
		}
	}
	else
	{
		return m_chr_value;
	}
}

/* Common configurations */

WRITE8_MEMBER(mpu4_state::mpu4_ym2413_w)
{
	ym2413_device *ym2413 = machine().device<ym2413_device>("ym2413");
	if (ym2413) ym2413->write(space,offset,data);
}

READ8_MEMBER(mpu4_state::mpu4_ym2413_r)
{
//  ym2413_device *ym2413 = machine().device<ym2413_device>("ym2413");
//  if (ym2413) return ym2413->read(space,offset);
	return 0xff;
}


void mpu4_state::mpu4_install_mod4yam_space(address_space &space)
{
	space.install_read_handler(0x0880, 0x0882, read8_delegate(FUNC(mpu4_state::mpu4_ym2413_r),this));
	space.install_write_handler(0x0880, 0x0881, write8_delegate(FUNC(mpu4_state::mpu4_ym2413_w),this));
}

void mpu4_state::mpu4_install_mod4oki_space(address_space &space)
{
	pia6821_device *pia_ic4ss = machine().device<pia6821_device>("pia_ic4ss");
	ptm6840_device *ptm_ic3ss = machine().device<ptm6840_device>("ptm_ic3ss");

	space.install_readwrite_handler(0x0880, 0x0883, read8_delegate(FUNC(pia6821_device::read), pia_ic4ss), write8_delegate(FUNC(pia6821_device::write), pia_ic4ss));
	space.install_read_handler(0x08c0, 0x08c7, read8_delegate(FUNC(ptm6840_device::read), ptm_ic3ss));
	space.install_write_handler(0x08c0, 0x08c7, write8_delegate(FUNC(mpu4_state::ic3ss_w),this));
}

void mpu4_state::mpu4_install_mod4bwb_space(address_space &space)
{
	space.install_readwrite_handler(0x0810, 0x0810, read8_delegate(FUNC(mpu4_state::bwb_characteriser_r),this),write8_delegate(FUNC(mpu4_state::bwb_characteriser_w),this));
	mpu4_install_mod4oki_space(space);
}


void mpu4_state::mpu4_config_common()
{
	m_lamps.resolve();
	m_mpu4leds.resolve();
	m_digits.resolve();
	m_triacs.resolve();

	m_ic24_timer = timer_alloc(TIMER_IC24);
	m_lamp_strobe_ext_persistence = 0;
}

MACHINE_START_MEMBER(mpu4_state,mod2)
{
	mpu4_config_common();

	m_link7a_connected=0;
	m_mod_number=2;
}

MACHINE_START_MEMBER(mpu4_state,mpu4yam)
{
	address_space &space = m_maincpu->space(AS_PROGRAM);
	mpu4_config_common();

	m_link7a_connected=0;
	m_mod_number=4;
	mpu4_install_mod4yam_space(space);
}

MACHINE_START_MEMBER(mpu4_state,mpu4oki)
{
	address_space &space = m_maincpu->space(AS_PROGRAM);
	mpu4_config_common();

	m_link7a_connected=0;
	m_mod_number=4;
	mpu4_install_mod4oki_space(space);
}

MACHINE_START_MEMBER(mpu4_state,mpu4bwb)
{
	address_space &space = m_maincpu->space(AS_PROGRAM);
	mpu4_config_common();

	m_link7a_connected=0;
	m_mod_number=4;
	mpu4_install_mod4bwb_space(space);
}

MACHINE_START_MEMBER(mpu4_state,mpu4cry)
{
	mpu4_config_common();

	m_link7a_connected=0;
	m_mod_number=4;
}

/* CHR Tables */

static mpu4_chr_table andycp10c_data[72] = {
{0x00, 0x00},{0x1a, 0x14},{0x04, 0x04},{0x10, 0x54},{0x18, 0x4c},{0x0f, 0x20},{0x13, 0x50},{0x1b, 0x44},
{0x03, 0x5c},{0x07, 0x78},{0x17, 0x70},{0x1d, 0x48},{0x36, 0x6c},{0x35, 0x60},{0x2b, 0x14},{0x28, 0x48},
{0x39, 0x2c},{0x21, 0x6c},{0x22, 0x6c},{0x25, 0x28},{0x2c, 0x64},{0x29, 0x10},{0x31, 0x08},{0x34, 0x6c},
{0x0a, 0x24},{0x1f, 0x5c},{0x06, 0x78},{0x0e, 0x34},{0x1c, 0x00},{0x12, 0x50},{0x1e, 0x00},{0x0d, 0x50},
{0x14, 0x0c},{0x0a, 0x6c},{0x19, 0x2c},{0x15, 0x60},{0x06, 0x54},{0x0f, 0x00},{0x08, 0x58},{0x1b, 0x74},
{0x1e, 0x00},{0x04, 0x14},{0x01, 0x4c},{0x0c, 0x60},{0x18, 0x1c},{0x1a, 0x74},{0x11, 0x4c},{0x0b, 0x64},
{0x03, 0x5c},{0x17, 0x78},{0x10, 0x78},{0x1d, 0x78},{0x0e, 0x34},{0x07, 0x44},{0x12, 0x54},{0x09, 0x40},
{0x0d, 0x50},{0x1f, 0x48},{0x16, 0x6c},{0x05, 0x28},{0x13, 0x60},{0x1c, 0x14},{0x02, 0x4c},{0x00, 0x00},
{0x00, 0x04},{0x01, 0x58},{0x04, 0x14},{0x09, 0x58},{0x10, 0x50},{0x19, 0x1c},{0x24, 0x10},{0x31, 0x10}
};

static mpu4_chr_table ccelbr_data[72] = {
{0x00, 0x00},{0x1a, 0x84},{0x04, 0x8c},{0x10, 0xb8},{0x18, 0x74},{0x0f, 0x80},{0x13, 0x1c},{0x1b, 0xb4},
{0x03, 0xd8},{0x07, 0x74},{0x17, 0x00},{0x1d, 0xd4},{0x36, 0xc8},{0x35, 0x78},{0x2b, 0xa4},{0x28, 0x4c},
{0x39, 0xe0},{0x21, 0xdc},{0x22, 0xf4},{0x25, 0x88},{0x2c, 0x78},{0x29, 0x24},{0x31, 0x84},{0x34, 0xcc},
{0x0a, 0xb8},{0x1f, 0x74},{0x06, 0x90},{0x0e, 0x48},{0x1c, 0xa0},{0x12, 0x1c},{0x1e, 0x24},{0x0d, 0x94},
{0x14, 0xc8},{0x0a, 0xb8},{0x19, 0x74},{0x15, 0x00},{0x06, 0x94},{0x0f, 0x48},{0x08, 0x30},{0x1b, 0x90},
{0x1e, 0x08},{0x04, 0x60},{0x01, 0xd4},{0x0c, 0x58},{0x18, 0xf4},{0x1a, 0x18},{0x11, 0x74},{0x0b, 0x80},
{0x03, 0xdc},{0x17, 0x74},{0x10, 0xd0},{0x1d, 0x58},{0x0e, 0x24},{0x07, 0x94},{0x12, 0xd8},{0x09, 0x34},
{0x0d, 0x90},{0x1f, 0x58},{0x16, 0xf4},{0x05, 0x88},{0x13, 0x38},{0x1c, 0x24},{0x02, 0xd4},{0x00, 0x00},
{0x00, 0x00},{0x01, 0x50},{0x04, 0x00},{0x09, 0x50},{0x10, 0x10},{0x19, 0x40},{0x24, 0x04},{0x31, 0x00}
};


static mpu4_chr_table gmball_data[72] = {
{0x00, 0x00},{0x1a, 0x0c},{0x04, 0x50},{0x10, 0x90},{0x18, 0xb0},{0x0f, 0x38},{0x13, 0xd4},{0x1b, 0xa0},
{0x03, 0xbc},{0x07, 0xd4},{0x17, 0x30},{0x1d, 0x90},{0x36, 0x38},{0x35, 0xc4},{0x2b, 0xac},{0x28, 0x70},
{0x39, 0x98},{0x21, 0xdc},{0x22, 0xdc},{0x25, 0x54},{0x2c, 0x80},{0x29, 0xb4},{0x31, 0x38},{0x34, 0xcc},
{0x0a, 0xe8},{0x1f, 0xf8},{0x06, 0xd4},{0x0e, 0x30},{0x1c, 0x00},{0x12, 0x84},{0x1e, 0x2c},{0x0d, 0xc8},
{0x14, 0xf8},{0x0a, 0x4c},{0x19, 0x58},{0x15, 0xd4},{0x06, 0xa8},{0x0f, 0x78},{0x08, 0x44},{0x1b, 0x0c},
{0x1e, 0x48},{0x04, 0x50},{0x01, 0x98},{0x0c, 0xd4},{0x18, 0xb0},{0x1a, 0xa0},{0x11, 0xa4},{0x0b, 0x3c},
{0x03, 0xdc},{0x17, 0xd4},{0x10, 0xb8},{0x1d, 0xd4},{0x0e, 0x30},{0x07, 0x88},{0x12, 0xe0},{0x09, 0x24},
{0x0d, 0x8c},{0x1f, 0xf8},{0x16, 0xcc},{0x05, 0x70},{0x13, 0x90},{0x1c, 0x20},{0x02, 0x9c},{0x00, 0x00},
{0x00, 0x00},{0x01, 0x18},{0x04, 0x08},{0x09, 0x10},{0x10, 0x00},{0x19, 0x18},{0x24, 0x08},{0x31, 0x00}
};




static mpu4_chr_table grtecp_data[72] = {
{0x00, 0x00},{0x1a, 0x84},{0x04, 0xa4},{0x10, 0xac},{0x18, 0x70},{0x0f, 0x80},{0x13, 0x2c},{0x1b, 0xc0},
{0x03, 0xbc},{0x07, 0x5c},{0x17, 0x5c},{0x1d, 0x5c},{0x36, 0xdc},{0x35, 0x5c},{0x2b, 0xcc},{0x28, 0x68},
{0x39, 0xd0},{0x21, 0xb8},{0x22, 0xdc},{0x25, 0x54},{0x2c, 0x08},{0x29, 0x58},{0x31, 0x54},{0x34, 0x90},
{0x0a, 0xb8},{0x1f, 0x5c},{0x06, 0x5c},{0x0e, 0x44},{0x1c, 0x84},{0x12, 0xac},{0x1e, 0xe0},{0x0d, 0xbc},
{0x14, 0xcc},{0x0a, 0xe8},{0x19, 0x70},{0x15, 0x00},{0x06, 0x8c},{0x0f, 0x70},{0x08, 0x00},{0x1b, 0x84},
{0x1e, 0xa4},{0x04, 0xa4},{0x01, 0xbc},{0x0c, 0xdc},{0x18, 0x5c},{0x1a, 0xcc},{0x11, 0xe8},{0x0b, 0xe0},
{0x03, 0xbc},{0x17, 0x4c},{0x10, 0xc8},{0x1d, 0xf8},{0x0e, 0xd4},{0x07, 0xa8},{0x12, 0x68},{0x09, 0x40},
{0x0d, 0x0c},{0x1f, 0xd8},{0x16, 0xdc},{0x05, 0x54},{0x13, 0x98},{0x1c, 0x44},{0x02, 0x9c},{0x00, 0x00},
{0x00, 0x00},{0x01, 0x18},{0x04, 0x00},{0x09, 0x18},{0x10, 0x08},{0x19, 0x10},{0x24, 0x00},{0x31, 0x00}
};

static mpu4_chr_table oldtmr_data[72] = {
{0x00, 0x00},{0x1a, 0x90},{0x04, 0xc0},{0x10, 0x54},{0x18, 0xa4},{0x0f, 0xf0},{0x13, 0x64},{0x1b, 0x90},
{0x03, 0xe4},{0x07, 0xd4},{0x17, 0x60},{0x1d, 0xb4},{0x36, 0xc0},{0x35, 0x70},{0x2b, 0x80},{0x28, 0x74},
{0x39, 0xa4},{0x21, 0xf4},{0x22, 0xe4},{0x25, 0xd0},{0x2c, 0x64},{0x29, 0x10},{0x31, 0x20},{0x34, 0x90},
{0x0a, 0xe4},{0x1f, 0xf4},{0x06, 0xc4},{0x0e, 0x70},{0x1c, 0x00},{0x12, 0x14},{0x1e, 0x00},{0x0d, 0x14},
{0x14, 0xa0},{0x0a, 0xf0},{0x19, 0x64},{0x15, 0x10},{0x06, 0x84},{0x0f, 0x70},{0x08, 0x00},{0x1b, 0x90},
{0x1e, 0x40},{0x04, 0x90},{0x01, 0xe4},{0x0c, 0xf4},{0x18, 0x64},{0x1a, 0x90},{0x11, 0x64},{0x0b, 0x90},
{0x03, 0xe4},{0x17, 0x50},{0x10, 0x24},{0x1d, 0xb4},{0x0e, 0xe0},{0x07, 0xd4},{0x12, 0xe4},{0x09, 0x50},
{0x0d, 0x04},{0x1f, 0xb4},{0x16, 0xc0},{0x05, 0xd0},{0x13, 0x64},{0x1c, 0x90},{0x02, 0xe4},{0x00, 0x00},
{0x00, 0x00},{0x01, 0x00},{0x04, 0x00},{0x09, 0x00},{0x10, 0x00},{0x19, 0x10},{0x24, 0x00},{0x31, 0x00}
};

static const bwb_chr_table blsbys_data1[5] = {
//Magic number 724A

// PAL Codes
// 0   1   2  3  4  5  6  7  8
// ??  ?? 20 0F 24 3C 36 27 09

	{0x67},{0x17},{0x0f},{0x24},{0x3c},
};

static mpu4_chr_table blsbys_data[8] = {
{0xEF, 0x02},{0x81, 0x00},{0xCE, 0x00},{0x00, 0x2e},
{0x06, 0x20},{0xC6, 0x0f},{0xF8, 0x24},{0x8E, 0x3c},
};

// set percentage and other options. 2e 20 0f
// PAL Codes
// 0   1   2  3  4  5  6  7  8
// 42  2E 20 0F 24 3C 36 27 09
	//      6  0  7  0  8  0  7  0  0  8
//request 36 42 27 42 09 42 27 42 42 09
//verify  00 04 04 0C 0C 1C 14 2C 5C 2C

void mpu4_state::init_m4_low_volt_alt()
{
	//Some games can't use the 50Hz circuit to check voltage issues, handle it here
	m_low_volt_detect_disable = 1;
}

void mpu4_state::init_m4_aux1_invert()
{
	m_aux1_invert = 1;
}

void mpu4_state::init_m4_aux2_invert()
{
	m_aux2_invert = 1;
}

void mpu4_state::init_m4_door_invert()
{
	m_aux2_invert = 1;
}

void mpu4_state::init_m4_small_extender()
{
	m_lamp_extender = SMALL_CARD;
}

void mpu4_state::init_m4_large_extender_a()
{
	m_lamp_extender = LARGE_CARD_A;
}

void mpu4_state::init_m4_large_extender_b()
{
	m_lamp_extender = LARGE_CARD_B;
}

void mpu4_state::init_m4_large_extender_c()
{
	m_lamp_extender = LARGE_CARD_C;
}

void mpu4_state::init_m4_hopper_tubes()
{
	m_hopper = TUBES;
}

void mpu4_state::init_m4_hopper_duart_a()
{
	m_hopper = HOPPER_DUART_A;
}

void mpu4_state::init_m4_hopper_duart_b()
{
	m_hopper = HOPPER_DUART_B;
}

void mpu4_state::init_m4_hopper_duart_c()
{
	m_hopper = HOPPER_DUART_C;
}

void mpu4_state::init_m4_hopper_nonduart_a()
{
	m_hopper = HOPPER_NONDUART_A;
}

void mpu4_state::init_m4_hopper_nonduart_b()
{
	m_hopper = HOPPER_NONDUART_B;
}

void mpu4_state::init_m4_led_a()
{
	m_led_extender = CARD_A;
}

void mpu4_state::init_m4_led_b()
{
	m_led_extender = CARD_B;
}

void mpu4_state::init_m4_led_c()
{
	m_led_extender = CARD_C;
}

//TODO: Replace with standard six reels once sets are sorted out - is really six_reel_std
void mpu4_state::init_m4altreels()
{
	m_reel_mux = SIX_REEL_1TO8;
	m_reels = 6;
	init_m4default_banks();
}

void mpu4_state::init_m4default_reels()
{
	m_reel_mux = STANDARD_REEL;
	m_reels = 4;
}

void mpu4_state::init_m4_five_reel_std()
{
	m_reel_mux = FIVE_REEL_5TO8;
	m_reels = 5;
}

void mpu4_state::init_m4_five_reel_rev()
{
	m_reel_mux = FIVE_REEL_8TO5;
	m_reels = 5;
}

void mpu4_state::init_m4_five_reel_alt()
{
	m_reel_mux = FIVE_REEL_3TO6;
	m_reels = 5;
}

void mpu4_state::init_m4_six_reel_std()
{
	m_reel_mux = SIX_REEL_1TO8;
	m_reels = 6;
}

void mpu4_state::init_m4_six_reel_alt()
{
	m_reel_mux = SIX_REEL_5TO8;
	m_reels = 6;
}

void mpu4_state::init_m4_seven_reel()
{
	m_reel_mux = SEVEN_REEL;
	m_reels = 7;
}


void mpu4_state::init_m4_andycp10c()
{
	init_m4default();
	init_m4_small_extender();
	m_current_chr_table = andycp10c_data;
}

void mpu4_state::init_m_oldtmr()
{
	init_m4_six_reel_std();
	init_m4default_banks();

	m_current_chr_table = oldtmr_data;
}

void mpu4_state::init_m_ccelbr()
{
	init_m4default();
	m_current_chr_table = ccelbr_data;
}

void mpu4_state::init_m4gambal()
{
	init_m4default();
	m_current_chr_table = gmball_data;
}

void mpu4_state::init_m_grtecp()
{
	m_current_chr_table = grtecp_data;
}

void mpu4_state::init_m_blsbys()
{
	m_bwb_bank = 1;
	init_m4_five_reel_std();
	m_bwb_chr_table1 = blsbys_data1;
	m_current_chr_table = blsbys_data;
	init_m4default_big();
}


void mpu4_state::init_m4default_banks()
{
	//Initialise paging for non-extended ROM space
	uint8_t *rom = memregion("maincpu")->base();
	membank("bank1")->configure_entries(0, 4, &rom[0x01000], 0x10000);
	membank("bank1")->set_entry(0);
}

void mpu4_state::init_m4default_alt()
{
	m_reel_mux = STANDARD_REEL;
	m_reels = 8;
	init_m4default_banks();

	m_bwb_bank=0;
}

void mpu4_state::init_m4default()
{
	init_m4default_reels();
	m_bwb_bank = 0;
	m_aux1_invert = 0;
	m_aux2_invert = 0;
	m_door_invert = 0;
	init_m4default_banks();
}


void mpu4_state::init_m4default_big()
{
	address_space &space = m_maincpu->space(AS_PROGRAM);
	m_aux1_invert = 0;
	m_aux2_invert = 0;
	m_door_invert = 0;

	int size = memregion("maincpu")->bytes();
	if (size <= 0x10000)
	{
		printf("Error: Extended banking selected on set <=0x10000 in size, ignoring\n");
		init_m4default_reels();
		m_bwb_bank = 0;
		init_m4default_banks();
	}
	else
	{
		m_bwb_bank = 1;
		space.install_write_handler(0x0858, 0x0858, write8_delegate(FUNC(mpu4_state::bankswitch_w),this));
		space.install_write_handler(0x0878, 0x0878, write8_delegate(FUNC(mpu4_state::bankset_w),this));
		uint8_t *rom = memregion("maincpu")->base();

		m_numbanks = size / 0x10000;
		m_bank1->configure_entries(0, m_numbanks, &rom[0x01000], 0x10000);
		m_numbanks--;

		// some Bwb games must default to the last bank, does anything not like this
		// behavior?
		// some Bwb games don't work anyway tho, they seem to dislike something else
		// about the way the regular banking behaves, not related to the CB2 stuff
		m_bank1->set_entry(m_numbanks);
	}
}





READ8_MEMBER(mpu4_state::crystal_sound_r)
{
	return machine().rand();
}
//this may be a YMZ280B
WRITE8_MEMBER(mpu4_state::crystal_sound_w)
{
	printf("crystal_sound_w %02x\n",data);
}

void mpu4_state::init_m_frkstn()
{
	address_space &space = m_maincpu->space(AS_PROGRAM);
	init_m4default_big();
	space.install_read_handler(0x0880, 0x0880, read8_delegate(FUNC(mpu4_state::crystal_sound_r),this));
	space.install_write_handler(0x0881, 0x0881, write8_delegate(FUNC(mpu4_state::crystal_sound_w),this));
}

// thanks to Project Amber for descramble information
static void descramble_crystal( uint8_t* region, int start, int end, uint8_t extra_xor)
{
	for (int i=start;i<end;i++)
	{
		uint8_t x = region[i];
		switch (i & 0x58)
		{
		case 0x00: // same as 0x08
		case 0x08: x = bitswap<8>( x^0xca , 3,2,1,0,7,4,6,5 ); break;
		case 0x10: x = bitswap<8>( x^0x30 , 3,0,4,6,1,5,7,2 ); break;
		case 0x18: x = bitswap<8>( x^0x89 , 4,1,2,5,7,0,6,3 ); break;
		case 0x40: x = bitswap<8>( x^0x14 , 6,1,4,3,2,5,0,7 ); break;
		case 0x48: x = bitswap<8>( x^0x40 , 1,0,3,2,5,4,7,6 ); break;
		case 0x50: x = bitswap<8>( x^0xcb , 3,2,1,0,7,6,5,4 ); break;
		case 0x58: x = bitswap<8>( x^0xc0 , 2,3,6,0,5,1,7,4 ); break;
		}
		region[i] = x ^ extra_xor;
	}
}


void mpu4_state::init_crystal()
{
	init_m_frkstn();
	descramble_crystal(memregion( "maincpu" )->base(), 0x0000, 0x10000, 0x00);
}

void mpu4_state::init_crystali()
{
	init_m_frkstn();
	descramble_crystal(memregion( "maincpu" )->base(), 0x0000, 0x10000, 0xff); // invert after decrypt?!
}

/* generate a 50 Hz signal (based on an RC time) */
TIMER_DEVICE_CALLBACK_MEMBER(mpu4_state::gen_50hz)
{
	if (!m_low_volt_detect_disable)
	{
		/* Although reported as a '50Hz' signal, the fact that both rising and
		falling edges of the pulse are used means the timer actually gives a 100Hz
		oscillating signal.*/
		m_signal_50hz = m_signal_50hz?0:1;
		m_pia4->ca1_w(m_signal_50hz);  /* signal is connected to IC4 CA1 */
	}
	update_meters();//run at 100Hz to sync with PIAs
}

void mpu4_state::mpu4_memmap(address_map &map)
{
	map(0x0000, 0x07ff).ram().share("nvram");
	map(0x0800, 0x0810).rw(this, FUNC(mpu4_state::characteriser_r), FUNC(mpu4_state::characteriser_w));
	map(0x0850, 0x0850).rw(this, FUNC(mpu4_state::bankswitch_r), FUNC(mpu4_state::bankswitch_w));    /* write bank (rom page select) */
/*  AM_RANGE(0x08e0, 0x08e7) AM_READWRITE(68681_duart_r,68681_duart_w) */ //Runs hoppers
	map(0x0900, 0x0907).rw(m_6840ptm, FUNC(ptm6840_device::read), FUNC(ptm6840_device::write));/* PTM6840 IC2 */
	map(0x0a00, 0x0a03).rw(m_pia3, FUNC(pia6821_device::read), FUNC(pia6821_device::write));        /* PIA6821 IC3 */
	map(0x0b00, 0x0b03).rw(m_pia4, FUNC(pia6821_device::read), FUNC(pia6821_device::write));        /* PIA6821 IC4 */
	map(0x0c00, 0x0c03).rw(m_pia5, FUNC(pia6821_device::read), FUNC(pia6821_device::write));        /* PIA6821 IC5 */
	map(0x0d00, 0x0d03).rw(m_pia6, FUNC(pia6821_device::read), FUNC(pia6821_device::write));        /* PIA6821 IC6 */
	map(0x0e00, 0x0e03).rw(m_pia7, FUNC(pia6821_device::read), FUNC(pia6821_device::write));        /* PIA6821 IC7 */
	map(0x0f00, 0x0f03).rw(m_pia8, FUNC(pia6821_device::read), FUNC(pia6821_device::write));        /* PIA6821 IC8 */
	map(0x1000, 0xffff).bankr("bank1");    /* 64k  paged ROM (4 pages)  */
}

#define MCFG_MPU4_STD_REEL_ADD(_tag)\
	MCFG_STEPPER_ADD(_tag)\
	MCFG_STEPPER_REEL_TYPE(BARCREST_48STEP_REEL)\
	MCFG_STEPPER_START_INDEX(1)\
	MCFG_STEPPER_END_INDEX(3)\
	MCFG_STEPPER_INDEX_PATTERN(0x00)\
	MCFG_STEPPER_INIT_PHASE(2)

#define MCFG_MPU4_TYPE2_REEL_ADD(_tag)\
	MCFG_STEPPER_ADD(_tag)\
	MCFG_STEPPER_REEL_TYPE(BARCREST_48STEP_REEL)\
	MCFG_STEPPER_START_INDEX(4)\
	MCFG_STEPPER_END_INDEX(12)\
	MCFG_STEPPER_INDEX_PATTERN(0x00)\
	MCFG_STEPPER_INIT_PHASE(2)

#define MCFG_MPU4_TYPE3_REEL_ADD(_tag)\
	MCFG_STEPPER_ADD(_tag)\
	MCFG_STEPPER_REEL_TYPE(BARCREST_48STEP_REEL)\
	MCFG_STEPPER_START_INDEX(92)\
	MCFG_STEPPER_END_INDEX(3)\
	MCFG_STEPPER_INDEX_PATTERN(0x00)\
	MCFG_STEPPER_INIT_PHASE(2)

#define MCFG_MPU4_TYPE4_REEL_ADD(_tag)\
	MCFG_STEPPER_ADD(_tag)\
	MCFG_STEPPER_REEL_TYPE(BARCREST_48STEP_REEL)\
	MCFG_STEPPER_START_INDEX(93)\
	MCFG_STEPPER_END_INDEX(2)\
	MCFG_STEPPER_INDEX_PATTERN(0x00)\
	MCFG_STEPPER_INIT_PHASE(2)

#define MCFG_MPU4_BWB_REEL_ADD(_tag)\
	MCFG_STEPPER_ADD(_tag)\
	MCFG_STEPPER_REEL_TYPE(BARCREST_48STEP_REEL)\
	MCFG_STEPPER_START_INDEX(96)\
	MCFG_STEPPER_END_INDEX(3)\
	MCFG_STEPPER_INDEX_PATTERN(0x00)\
	MCFG_STEPPER_INIT_PHASE(2)

MACHINE_CONFIG_START(mpu4_state::mpu4_std_3reel)
	MCFG_MPU4_STD_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_STD_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_STD_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type2_3reel)
	MCFG_MPU4_TYPE2_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type3_3reel)
	MCFG_MPU4_TYPE3_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type4_3reel)
	MCFG_MPU4_TYPE4_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_bwb_3reel)
	MCFG_MPU4_BWB_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_BWB_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_BWB_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_std_4reel)
	MCFG_MPU4_STD_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_STD_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_STD_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_STD_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type2_4reel)
	MCFG_MPU4_TYPE2_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type3_4reel)
	MCFG_MPU4_TYPE3_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type4_4reel)
	MCFG_MPU4_TYPE4_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_bwb_4reel)
	MCFG_MPU4_BWB_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_BWB_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_BWB_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_BWB_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_std_5reel)
	MCFG_MPU4_STD_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_STD_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_STD_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_STD_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_STD_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type2_5reel)
	MCFG_MPU4_TYPE2_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type3_5reel)
	MCFG_MPU4_TYPE3_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type4_5reel)
	MCFG_MPU4_TYPE4_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_bwb_5reel)
	MCFG_MPU4_BWB_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_BWB_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_BWB_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_BWB_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_BWB_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_std_6reel)
	MCFG_MPU4_STD_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_STD_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_STD_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_STD_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_STD_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
	MCFG_MPU4_STD_REEL_ADD("reel5")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type2_6reel)
	MCFG_MPU4_TYPE2_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel5")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<5>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type3_6reel)
	MCFG_MPU4_TYPE3_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel5")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<5>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type4_6reel)
	MCFG_MPU4_TYPE4_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel5")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<5>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_bwb_6reel)
	MCFG_MPU4_BWB_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_BWB_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_BWB_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_BWB_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_BWB_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
	MCFG_MPU4_BWB_REEL_ADD("reel5")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<5>))
MACHINE_CONFIG_END


MACHINE_CONFIG_START(mpu4_state::mpu4_std_7reel)
	MCFG_MPU4_STD_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_STD_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_STD_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_STD_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_STD_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
	MCFG_MPU4_STD_REEL_ADD("reel5")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<5>))
	MCFG_MPU4_STD_REEL_ADD("reel6")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<6>))
	MCFG_MPU4_STD_REEL_ADD("reel7")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<7>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type2_7reel)
	MCFG_MPU4_TYPE2_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel5")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<5>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel6")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<6>))
	MCFG_MPU4_TYPE2_REEL_ADD("reel7")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<7>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type3_7reel)
	MCFG_MPU4_TYPE3_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel5")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<5>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel6")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<6>))
	MCFG_MPU4_TYPE3_REEL_ADD("reel7")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<7>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_type4_7reel)
	MCFG_MPU4_TYPE4_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel5")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<5>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel6")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<6>))
	MCFG_MPU4_TYPE4_REEL_ADD("reel7")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<7>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_bwb_7reel)
	MCFG_MPU4_BWB_REEL_ADD("reel0")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<0>))
	MCFG_MPU4_BWB_REEL_ADD("reel1")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<1>))
	MCFG_MPU4_BWB_REEL_ADD("reel2")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<2>))
	MCFG_MPU4_BWB_REEL_ADD("reel3")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<3>))
	MCFG_MPU4_BWB_REEL_ADD("reel4")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<4>))
	MCFG_MPU4_BWB_REEL_ADD("reel5")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<5>))
	MCFG_MPU4_BWB_REEL_ADD("reel6")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<6>))
	MCFG_MPU4_BWB_REEL_ADD("reel7")
	MCFG_STEPPER_OPTIC_CALLBACK(WRITELINE(*this, mpu4_state, reel_optic_cb<7>))
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_common)
	MCFG_TIMER_DRIVER_ADD_PERIODIC("50hz", mpu4_state, gen_50hz, attotime::from_hz(100))

	MCFG_MSC1937_ADD("vfd",0)
	/* 6840 PTM */
	MCFG_DEVICE_ADD("ptm_ic2", PTM6840, MPU4_MASTER_CLOCK / 4)
	MCFG_PTM6840_EXTERNAL_CLOCKS(0, 0, 0)
	MCFG_PTM6840_O1_CB(WRITELINE(*this, mpu4_state, ic2_o1_callback))
	MCFG_PTM6840_O2_CB(WRITELINE(*this, mpu4_state, ic2_o2_callback))
	MCFG_PTM6840_O3_CB(WRITELINE(*this, mpu4_state, ic2_o3_callback))
	MCFG_PTM6840_IRQ_CB(WRITELINE(*this, mpu4_state, cpu0_irq))

	MCFG_DEVICE_ADD("pia_ic3", PIA6821, 0)
	MCFG_PIA_WRITEPA_HANDLER(WRITE8(*this, mpu4_state, pia_ic3_porta_w))
	MCFG_PIA_WRITEPB_HANDLER(WRITE8(*this, mpu4_state, pia_ic3_portb_w))
	MCFG_PIA_CA2_HANDLER(WRITELINE(*this, mpu4_state, pia_ic3_ca2_w))
	MCFG_PIA_CB2_HANDLER(WRITELINE(*this, mpu4_state, pia_ic3_cb2_w))
	MCFG_PIA_IRQA_HANDLER(WRITELINE(*this, mpu4_state, cpu0_irq))
	MCFG_PIA_IRQB_HANDLER(WRITELINE(*this, mpu4_state, cpu0_irq))

	MCFG_DEVICE_ADD("pia_ic4", PIA6821, 0)
	MCFG_PIA_READPB_HANDLER(READ8(*this, mpu4_state, pia_ic4_portb_r))
	MCFG_PIA_WRITEPA_HANDLER(WRITE8(*this, mpu4_state, pia_ic4_porta_w))
	MCFG_PIA_WRITEPB_HANDLER(WRITE8(*this, mpu4_state, pia_ic4_portb_w))
	MCFG_PIA_CA2_HANDLER(WRITELINE(*this, mpu4_state,pia_ic4_ca2_w))
	MCFG_PIA_CB2_HANDLER(WRITELINE(*this, mpu4_state,pia_ic4_cb2_w))
	MCFG_PIA_IRQA_HANDLER(WRITELINE(*this, mpu4_state,cpu0_irq))
	MCFG_PIA_IRQB_HANDLER(WRITELINE(*this, mpu4_state,cpu0_irq))

	MCFG_DEVICE_ADD("pia_ic5", PIA6821, 0)
	MCFG_PIA_READPA_HANDLER(READ8(*this, mpu4_state, pia_ic5_porta_r))
	MCFG_PIA_READPB_HANDLER(READ8(*this, mpu4_state, pia_ic5_portb_r))
	MCFG_PIA_WRITEPA_HANDLER(WRITE8(*this, mpu4_state, pia_ic5_porta_w))
	MCFG_PIA_WRITEPB_HANDLER(WRITE8(*this, mpu4_state, pia_ic5_portb_w))
	MCFG_PIA_CA2_HANDLER(WRITELINE(*this, mpu4_state, pia_ic5_ca2_w))
	MCFG_PIA_CB2_HANDLER(WRITELINE(*this, mpu4_state, pia_ic5_cb2_w))
	MCFG_PIA_IRQA_HANDLER(WRITELINE(*this, mpu4_state, cpu0_irq))
	MCFG_PIA_IRQB_HANDLER(WRITELINE(*this, mpu4_state, cpu0_irq))

	MCFG_DEVICE_ADD("pia_ic6", PIA6821, 0)
	MCFG_PIA_WRITEPA_HANDLER(WRITE8(*this, mpu4_state, pia_ic6_porta_w))
	MCFG_PIA_WRITEPB_HANDLER(WRITE8(*this, mpu4_state, pia_ic6_portb_w))
	MCFG_PIA_CA2_HANDLER(WRITELINE(*this, mpu4_state, pia_ic6_ca2_w))
	MCFG_PIA_CB2_HANDLER(WRITELINE(*this, mpu4_state, pia_ic6_cb2_w))
	MCFG_PIA_IRQA_HANDLER(WRITELINE(*this, mpu4_state, cpu0_irq))
	MCFG_PIA_IRQB_HANDLER(WRITELINE(*this, mpu4_state, cpu0_irq))

	MCFG_DEVICE_ADD("pia_ic7", PIA6821, 0)
	MCFG_PIA_READPB_HANDLER(READ8(*this, mpu4_state, pia_ic7_portb_r))
	MCFG_PIA_WRITEPA_HANDLER(WRITE8(*this, mpu4_state, pia_ic7_porta_w))
	MCFG_PIA_WRITEPB_HANDLER(WRITE8(*this, mpu4_state, pia_ic7_portb_w))
	MCFG_PIA_CA2_HANDLER(WRITELINE(*this, mpu4_state, pia_ic7_ca2_w))
	MCFG_PIA_CB2_HANDLER(WRITELINE(*this, mpu4_state, pia_ic7_cb2_w))
	MCFG_PIA_IRQA_HANDLER(WRITELINE(*this, mpu4_state, cpu0_irq))
	MCFG_PIA_IRQB_HANDLER(WRITELINE(*this, mpu4_state, cpu0_irq))

	MCFG_DEVICE_ADD("pia_ic8", PIA6821, 0)
	MCFG_PIA_READPA_HANDLER(READ8(*this, mpu4_state, pia_ic8_porta_r))
	MCFG_PIA_WRITEPB_HANDLER(WRITE8(*this, mpu4_state, pia_ic8_portb_w))
	MCFG_PIA_CA2_HANDLER(WRITELINE(*this, mpu4_state, pia_ic8_ca2_w))
	MCFG_PIA_CB2_HANDLER(WRITELINE(*this, mpu4_state, pia_ic8_cb2_w))
	MCFG_PIA_IRQA_HANDLER(WRITELINE(*this, mpu4_state, cpu0_irq))
	MCFG_PIA_IRQB_HANDLER(WRITELINE(*this, mpu4_state, cpu0_irq))

	MCFG_DEVICE_ADD("meters", METERS, 0)
	MCFG_METERS_NUMBER(8)

MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4_common2)
	MCFG_DEVICE_ADD("ptm_ic3ss", PTM6840, MPU4_MASTER_CLOCK / 4)
	MCFG_PTM6840_EXTERNAL_CLOCKS(0, 0, 0)
	MCFG_PTM6840_O1_CB(WRITELINE("ptm_ic3ss", ptm6840_device, set_c2))
	MCFG_PTM6840_O2_CB(WRITELINE("ptm_ic3ss", ptm6840_device, set_c1))
	//MCFG_PTM6840_O3_CB(WRITELINE("ptm_ic3ss", ptm6840_device, set_g1))
	//MCFG_PTM6840_IRQ_CB(WRITELINE(*this, mpu4_state, cpu1_ptm_irq))

	MCFG_DEVICE_ADD("pia_ic4ss", PIA6821, 0)
	MCFG_PIA_READPB_HANDLER(READ8(*this, mpu4_state, pia_gb_portb_r))
	MCFG_PIA_WRITEPA_HANDLER(WRITE8(*this, mpu4_state, pia_gb_porta_w))
	MCFG_PIA_WRITEPB_HANDLER(WRITE8(*this, mpu4_state, pia_gb_portb_w))
	MCFG_PIA_CA2_HANDLER(WRITELINE(*this, mpu4_state, pia_gb_ca2_w))
	MCFG_PIA_CB2_HANDLER(WRITELINE(*this, mpu4_state, pia_gb_cb2_w))
MACHINE_CONFIG_END

/* machine driver for MOD 2 board */
MACHINE_CONFIG_START(mpu4_state::mpu4base)

	MCFG_MACHINE_START_OVERRIDE(mpu4_state,mod2    )
	MCFG_MACHINE_RESET_OVERRIDE(mpu4_state,mpu4)
	MCFG_DEVICE_ADD("maincpu", MC6809, MPU4_MASTER_CLOCK) // MC68B09P
	MCFG_DEVICE_PROGRAM_MAP(mpu4_memmap)

	mpu4_common(config);

	SPEAKER(config, "lspeaker").front_left();
	SPEAKER(config, "rspeaker").front_right();

	MCFG_NVRAM_ADD_0FILL("nvram")

	MCFG_DEFAULT_LAYOUT(layout_mpu4)
MACHINE_CONFIG_END


MACHINE_CONFIG_START(mpu4_state::mod2)
	mpu4base(config);
	MCFG_DEVICE_ADD("ay8913", AY8913, MPU4_MASTER_CLOCK/4)
	MCFG_AY8910_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT)
	MCFG_AY8910_RES_LOADS(820, 0, 0)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
	mpu4_std_6reel(config);
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mod2_alt)
	mpu4base(config);
	MCFG_DEVICE_ADD("ay8913", AY8913, MPU4_MASTER_CLOCK/4)
	MCFG_AY8910_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT)
	MCFG_AY8910_RES_LOADS(820, 0, 0)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
	mpu4_type2_6reel(config);
MACHINE_CONFIG_END



MACHINE_CONFIG_START(mpu4_state::mod4yam)
	mpu4base(config);
	MCFG_MACHINE_START_OVERRIDE(mpu4_state,mpu4yam)

	mpu4_std_6reel(config);

	MCFG_DEVICE_ADD("ym2413", YM2413, MPU4_MASTER_CLOCK/4)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mod4oki)
	mpu4base(config);
	MCFG_MACHINE_START_OVERRIDE(mpu4_state,mpu4oki)

	mpu4_common2(config);
	mpu4_std_6reel(config);

	MCFG_DEVICE_ADD("msm6376", OKIM6376, 128000)     //16KHz sample Can also be 85430 at 10.5KHz and 64000 at 8KHz
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mod4oki_alt)
	mpu4base(config);
	MCFG_MACHINE_START_OVERRIDE(mpu4_state,mpu4oki)

	mpu4_common2(config);
	mpu4_type2_6reel(config);

	MCFG_DEVICE_ADD("msm6376", OKIM6376, 128000)     //16KHz sample Can also be 85430 at 10.5KHz and 64000 at 8KHz
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mod4oki_5r)
	mpu4base(config);
	MCFG_MACHINE_START_OVERRIDE(mpu4_state,mpu4oki)

	mpu4_common2(config);
	mpu4_std_5reel(config);

	MCFG_DEVICE_ADD("msm6376", OKIM6376, 128000)     //16KHz sample Can also be 85430 at 10.5KHz and 64000 at 8KHz
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::bwboki)
	mpu4base(config);
	MCFG_MACHINE_START_OVERRIDE(mpu4_state,mpu4bwb)
	mpu4_common2(config);
	mpu4_bwb_5reel(config);

	MCFG_DEVICE_ADD("msm6376", OKIM6376, 128000)     //16KHz sample Can also be 85430 at 10.5KHz and 64000 at 8KHz
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
MACHINE_CONFIG_END

MACHINE_CONFIG_START(mpu4_state::mpu4crys)
	mod2(config);
	MCFG_MACHINE_START_OVERRIDE(mpu4_state,mpu4cry)

	MCFG_DEVICE_ADD("upd", UPD7759)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
MACHINE_CONFIG_END

#define GAME_FLAGS (MACHINE_NOT_WORKING|MACHINE_REQUIRES_ARTWORK|MACHINE_MECHANICAL)